Compare commits
204 Commits
master
...
release-0.
Author | SHA1 | Date |
---|---|---|
Nick Mathewson | 14ec62f064 | |
Nick Mathewson | 432620e44e | |
Roger Dingledine | f3b53391e8 | |
Nick Mathewson | 79bee260ee | |
Nick Mathewson | e8edd97c1c | |
Nick Mathewson | e935e27676 | |
Nick Mathewson | 34d418009d | |
Nick Mathewson | a15009bd38 | |
Nick Mathewson | 7e1102ff25 | |
Nick Mathewson | a1243864f2 | |
Nick Mathewson | 4b14ff45fd | |
Nick Mathewson | fb4307bf22 | |
Nick Mathewson | 7a55efbd59 | |
Nick Mathewson | 31e69ac222 | |
Nick Mathewson | 3abd57fa0a | |
Nick Mathewson | ecb51bf9f3 | |
Nick Mathewson | 65fd973754 | |
Nick Mathewson | 677789b680 | |
Nick Mathewson | a6f21a61d1 | |
Nick Mathewson | bc250fcabd | |
Nick Mathewson | 955a7f52d3 | |
Nick Mathewson | 70bd4aae67 | |
Nick Mathewson | 6170f87e01 | |
Nick Mathewson | 7dbaaba3d2 | |
Nick Mathewson | 109c555e9d | |
Nick Mathewson | 36154c13f4 | |
Nick Mathewson | 75b544d64d | |
Nick Mathewson | 2f397236b2 | |
Nick Mathewson | 4b067f8b12 | |
Nick Mathewson | 4a03851e42 | |
Nick Mathewson | 2d42648eaf | |
Nick Mathewson | 31cc63deb6 | |
Nick Mathewson | 8231cc868e | |
Nick Mathewson | a9769b78f0 | |
Nick Mathewson | 499bdd81a7 | |
Nick Mathewson | bc8b5fb559 | |
Nick Mathewson | 43d44c04ff | |
Nick Mathewson | 3acf6cafbb | |
Nick Mathewson | 1c56181983 | |
Nick Mathewson | 434942ea59 | |
Nick Mathewson | cc17922645 | |
Nick Mathewson | 7e664bf74f | |
Nick Mathewson | 4bfbce9de7 | |
Nick Mathewson | 6a35e7d69a | |
Nick Mathewson | 3fda19ef24 | |
Nick Mathewson | 1a877693da | |
Nick Mathewson | 2a24ce9656 | |
Nick Mathewson | 9e81221c96 | |
Nick Mathewson | cb3c1f2e54 | |
Nick Mathewson | 67127dca57 | |
Nick Mathewson | f5e37b2eb6 | |
Nick Mathewson | 90716e3f9c | |
Nick Mathewson | 1a4876587e | |
Nick Mathewson | df37b93336 | |
Nick Mathewson | a877241e6c | |
Nick Mathewson | 2485f8dea4 | |
Nick Mathewson | c35416ab8f | |
Nick Mathewson | 8dc3b5ff3a | |
Nick Mathewson | da2daa8e5e | |
Nick Mathewson | 3d7f134bea | |
Nick Mathewson | 6b629d3095 | |
Nick Mathewson | 677bebda70 | |
Nick Mathewson | 03eb2037d1 | |
Nick Mathewson | 698334eee7 | |
Nick Mathewson | c9b4ddc882 | |
Nick Mathewson | 4bfc355799 | |
Nick Mathewson | b1267114cf | |
Nick Mathewson | 7e96767825 | |
Nick Mathewson | dbea64aab6 | |
Nick Mathewson | 01d6e23f76 | |
Nick Mathewson | 9e8b762fce | |
Nick Mathewson | 02c5ca6ace | |
Nick Mathewson | e985afa43c | |
Nick Mathewson | b70f303207 | |
Nick Mathewson | ece3e77066 | |
Nick Mathewson | 971d634b63 | |
Nick Mathewson | 474d4006ab | |
Nick Mathewson | ea6f3e329d | |
Nick Mathewson | 58474f7bb1 | |
Nick Mathewson | 5ff2d8d770 | |
Nick Mathewson | efba81e3bb | |
Roger Dingledine | 0d172c1182 | |
Nick Mathewson | 8edc0be74b | |
Nick Mathewson | c7c043d2b6 | |
Nick Mathewson | 1a070767de | |
Nick Mathewson | 99b4f86833 | |
Nick Mathewson | fd46d8d0ad | |
Nick Mathewson | 11336cfa09 | |
Nick Mathewson | 63b84335dc | |
Nick Mathewson | afacaa02a5 | |
Nick Mathewson | 9be4b91760 | |
Nick Mathewson | 0d1a2e366a | |
Nick Mathewson | 29e23e62c9 | |
Nick Mathewson | 88642bbdc7 | |
Nick Mathewson | 2a7cad9572 | |
Nick Mathewson | c2b64ad096 | |
Nick Mathewson | 748f0abc2d | |
Nick Mathewson | 2824413f40 | |
Nick Mathewson | 64c88c7199 | |
Nick Mathewson | 4f8a0ed62d | |
Nick Mathewson | 0f105d69fc | |
Nick Mathewson | 2b48b5363f | |
Nick Mathewson | 304e2151ac | |
Nick Mathewson | 6ff333f627 | |
Nick Mathewson | 0834f4d93d | |
Nick Mathewson | 4c015d9fe4 | |
Nick Mathewson | 37fba82c15 | |
Nick Mathewson | dc9f2cdf73 | |
Nick Mathewson | dd5ca25055 | |
Nick Mathewson | 706e6893d1 | |
Nick Mathewson | 58f974818c | |
Nick Mathewson | 2cfb7b0413 | |
Nick Mathewson | a14ff6b9c7 | |
Nick Mathewson | d77e827693 | |
Nick Mathewson | ca554b22f8 | |
Nick Mathewson | fdd13697d5 | |
Nick Mathewson | 4fc402496e | |
Nick Mathewson | 68ec14dc18 | |
Nick Mathewson | cd084c2036 | |
Nick Mathewson | 0c7a540ba2 | |
Nick Mathewson | 92d45086f5 | |
Nick Mathewson | bc30d30534 | |
Nick Mathewson | 19e01f0cbc | |
Nick Mathewson | fe12c9756a | |
Nick Mathewson | e0d1ab4172 | |
Nick Mathewson | 87012d076e | |
Nick Mathewson | 26f5da96b2 | |
Nick Mathewson | c66ce3419d | |
Nick Mathewson | 9eb17cb7ba | |
Nick Mathewson | c981cd4311 | |
Nick Mathewson | 500975da96 | |
Nick Mathewson | 1e715efb77 | |
Nick Mathewson | 9a9d32fabc | |
Nick Mathewson | fa72612540 | |
Nick Mathewson | 36806e9830 | |
Nick Mathewson | d084d3246b | |
Nick Mathewson | d499a5a708 | |
Roger Dingledine | 8ecb170c17 | |
Nick Mathewson | 0fc65a33f7 | |
Nick Mathewson | e4b68abd5a | |
Nick Mathewson | c6365055a1 | |
Nick Mathewson | b9be385fd6 | |
Nick Mathewson | e343cb8f63 | |
Nick Mathewson | 1bd83c2ec8 | |
Nick Mathewson | 9096454492 | |
Nick Mathewson | e74229efc4 | |
Nick Mathewson | 41a3eaf2fc | |
Nick Mathewson | 9afa661924 | |
Nick Mathewson | cf92667b9f | |
Nick Mathewson | 330ccb699e | |
Nick Mathewson | b2e1910017 | |
Nick Mathewson | 00aeecb397 | |
Nick Mathewson | b9826ba451 | |
Nick Mathewson | 066904e758 | |
Nick Mathewson | 2367b1ed31 | |
Nick Mathewson | 01c5d4583f | |
Nick Mathewson | 7d1e47559a | |
Nick Mathewson | 349a92bf3f | |
Nick Mathewson | 8473424ede | |
Nick Mathewson | ab8013391e | |
Nick Mathewson | 08d933a794 | |
Nick Mathewson | a71552268d | |
Nick Mathewson | 5ea9a48ae7 | |
Nick Mathewson | 4bd9c53237 | |
Nick Mathewson | a8c388b0e2 | |
Nick Mathewson | ad90a136b2 | |
Nick Mathewson | 55aafbf7ba | |
Nick Mathewson | 6a8c1667df | |
Nick Mathewson | 57deb20f35 | |
Nick Mathewson | 7cbda1181d | |
Nick Mathewson | 940308f493 | |
Roger Dingledine | edbf6a62aa | |
Nick Mathewson | c5b16c1413 | |
Nick Mathewson | 388b1d0fab | |
Nick Mathewson | c99fec4999 | |
Nick Mathewson | d37bc72873 | |
Nick Mathewson | 04714df9cc | |
Nick Mathewson | e50da3327f | |
Nick Mathewson | b4b2459de0 | |
Nick Mathewson | 94752b3fa6 | |
Nick Mathewson | 059c441d27 | |
Nick Mathewson | 6d6cd2060f | |
Nick Mathewson | 0c8eebd90c | |
Nick Mathewson | 89ed93e468 | |
Nick Mathewson | bd432bbac5 | |
Nick Mathewson | d05780c1bb | |
Nick Mathewson | 8c9b5bfb8c | |
Nick Mathewson | 6bc1632b72 | |
Nick Mathewson | ed10b34efe | |
Nick Mathewson | 3d966f57a4 | |
Nick Mathewson | 6688091928 | |
Nick Mathewson | 33652fce62 | |
Nick Mathewson | aed642a4b2 | |
Nick Mathewson | 588be5b028 | |
Nick Mathewson | 8a8b5d590e | |
Nick Mathewson | 0f47507fe2 | |
Nick Mathewson | c5bb554e77 | |
Nick Mathewson | 68181dc263 | |
Nick Mathewson | a99ca9313a | |
Nick Mathewson | dbd4b2be5d | |
Nick Mathewson | 080bcfa239 | |
Nick Mathewson | 023d756bfc | |
Nick Mathewson | 325549d2e7 | |
Nick Mathewson | 5a65695149 |
|
@ -1,62 +0,0 @@
|
|||
version: 1.0.{build}
|
||||
|
||||
clone_depth: 50
|
||||
|
||||
environment:
|
||||
compiler: mingw
|
||||
|
||||
matrix:
|
||||
- target: i686-w64-mingw32
|
||||
compiler_path: mingw32
|
||||
openssl_path: /c/OpenSSL-Win32
|
||||
- target: x86_64-w64-mingw32
|
||||
compiler_path: mingw64
|
||||
openssl_path: /c/OpenSSL-Win64
|
||||
|
||||
install:
|
||||
- ps: >-
|
||||
Function Execute-Command ($commandPath)
|
||||
{
|
||||
& $commandPath $args 2>&1
|
||||
if ( $LastExitCode -ne 0 ) {
|
||||
$host.SetShouldExit( $LastExitCode )
|
||||
}
|
||||
}
|
||||
Function Execute-Bash ()
|
||||
{
|
||||
Execute-Command 'c:\msys64\usr\bin\bash' '-e' '-c' $args
|
||||
}
|
||||
Execute-Command "C:\msys64\usr\bin\pacman" -Sy --noconfirm openssl-devel openssl libevent-devel libevent mingw-w64-i686-libevent mingw-w64-x86_64-libevent mingw-w64-i686-openssl mingw-w64-x86_64-openssl mingw-w64-i686-zstd mingw-w64-x86_64-zstd
|
||||
|
||||
build_script:
|
||||
- ps: >-
|
||||
if ($env:compiler -eq "mingw") {
|
||||
$oldpath = ${env:Path} -split ';'
|
||||
$buildpath = @("C:\msys64\${env:compiler_path}\bin", "C:\msys64\usr\bin") + $oldpath
|
||||
$env:Path = @($buildpath) -join ';'
|
||||
$env:build = @("${env:APPVEYOR_BUILD_FOLDER}", $env:target) -join '\'
|
||||
Set-Location "${env:APPVEYOR_BUILD_FOLDER}"
|
||||
Execute-Bash 'autoreconf -i'
|
||||
mkdir "${env:build}"
|
||||
Set-Location "${env:build}"
|
||||
Execute-Bash "../configure --prefix=/${env:compiler_path} --build=${env:target} --host=${env:target} --disable-asciidoc --enable-fatal-warnings --with-openssl-dir=${env:openssl_path}"
|
||||
Execute-Bash "V=1 make -j2"
|
||||
Execute-Bash "V=1 make -j2 install"
|
||||
}
|
||||
|
||||
test_script:
|
||||
- ps: >-
|
||||
if ($env:compiler -eq "mingw") {
|
||||
$oldpath = ${env:Path} -split ';'
|
||||
$buildpath = @("C:\msys64\${env:compiler_path}\bin") + $oldpath
|
||||
$env:Path = $buildpath -join ';'
|
||||
Set-Location "${env:build}"
|
||||
Execute-Bash "VERBOSE=1 make -j2 check"
|
||||
}
|
||||
|
||||
on_success:
|
||||
- cmd: C:\Python27\python.exe %APPVEYOR_BUILD_FOLDER%\scripts\test\appveyor-irc-notify.py irc.oftc.net:6697 tor-ci success
|
||||
|
||||
on_failure:
|
||||
- cmd: C:\Python27\python.exe %APPVEYOR_BUILD_FOLDER%\scripts\test\appveyor-irc-notify.py irc.oftc.net:6697 tor-ci failure
|
||||
|
|
@ -212,7 +212,6 @@ uptime-*.json
|
|||
/src/test/fuzz/lf-fuzz-*
|
||||
|
||||
# /src/tools/
|
||||
/src/tools/libtorrunner.a
|
||||
/src/tools/tor-checkkey
|
||||
/src/tools/tor-resolve
|
||||
/src/tools/tor-cov-resolve
|
||||
|
|
|
@ -26,7 +26,7 @@ update:
|
|||
- ssh-add <(echo "$DEPLOY_KEY")
|
||||
|
||||
# For Docker builds disable host key checking. Be aware that by adding that
|
||||
# you are susceptible to man-in-the-middle attacks.
|
||||
# you are suspectible to man-in-the-middle attacks.
|
||||
# WARNING: Use this only with the Docker executor, if you use it with shell
|
||||
# you will overwrite your user's SSH config.
|
||||
- mkdir -p ~/.ssh
|
||||
|
|
19
.travis.yml
19
.travis.yml
|
@ -66,7 +66,6 @@ env:
|
|||
## more than one entry causes unwanted matrix entries with
|
||||
## unspecified compilers.
|
||||
- RUST_OPTIONS="--enable-rust --enable-cargo-online-mode"
|
||||
# - RUST_OPTIONS="--enable-rust" TOR_RUST_DEPENDENCIES=true
|
||||
# - RUST_OPTIONS=""
|
||||
|
||||
matrix:
|
||||
|
@ -96,33 +95,21 @@ matrix:
|
|||
## entry under that key outside the "include" clause.
|
||||
include:
|
||||
- compiler: gcc
|
||||
- compiler: gcc
|
||||
env: RUST_OPTIONS="--enable-rust" TOR_RUST_DEPENDENCIES=true
|
||||
- compiler: gcc
|
||||
env: RUST_OPTIONS=""
|
||||
- compiler: gcc
|
||||
env: COVERAGE_OPTIONS="--enable-coverage"
|
||||
- compiler: gcc
|
||||
env: DISTCHECK="yes" RUST_OPTIONS=""
|
||||
- compiler: gcc
|
||||
env: DISTCHECK="yes" RUST_OPTIONS="--enable-rust --enable-cargo-online-mode"
|
||||
- compiler: gcc
|
||||
env: MODULES_OPTIONS="--disable-module-dirauth"
|
||||
env: DISTCHECK="yes"
|
||||
## The "sudo: required" forces non-containerized builds, working
|
||||
## around a Travis CI environment issue: clang LeakAnalyzer fails
|
||||
## because it requires ptrace and the containerized environment no
|
||||
## longer allows ptrace.
|
||||
- compiler: clang
|
||||
sudo: required
|
||||
- compiler: clang
|
||||
sudo: required
|
||||
env: RUST_OPTIONS="--enable-rust" TOR_RUST_DEPENDENCIES=true
|
||||
- compiler: clang
|
||||
sudo: required
|
||||
env: RUST_OPTIONS=""
|
||||
- compiler: clang
|
||||
sudo: required
|
||||
env: MODULES_OPTIONS="--disable-module-dirauth"
|
||||
|
||||
before_install:
|
||||
## If we're on OSX, homebrew usually needs to updated first
|
||||
|
@ -148,12 +135,10 @@ install:
|
|||
- if [[ "$RUST_OPTIONS" != "" ]]; then which cargo; fi
|
||||
- if [[ "$RUST_OPTIONS" != "" ]]; then rustc --version; fi
|
||||
- if [[ "$RUST_OPTIONS" != "" ]]; then cargo --version; fi
|
||||
## If we're testing rust builds in offline-mode, then set up our vendored dependencies
|
||||
- if [[ "$TOR_RUST_DEPENDENCIES" == "true" ]]; then export TOR_RUST_DEPENDENCIES=$PWD/src/ext/rust/crates; fi
|
||||
|
||||
script:
|
||||
- ./autogen.sh
|
||||
- ./configure $RUST_OPTIONS $COVERAGE_OPTIONS $MODULES_OPTIONS --disable-asciidoc --enable-fatal-warnings --disable-silent-rules --enable-fragile-hardening
|
||||
- ./configure $RUST_OPTIONS $COVERAGE_OPTIONS --disable-asciidoc --enable-fatal-warnings --disable-silent-rules --enable-fragile-hardening
|
||||
## We run `make check` because that's what https://jenkins.torproject.org does.
|
||||
- if [[ "$DISTCHECK" == "" ]]; then make check; fi
|
||||
- if [[ "$DISTCHECK" != "" ]]; then make distcheck DISTCHECK_CONFIGURE_FLAGS="$RUST_OPTIONS $COVERAGE_OPTIONS --disable-asciidoc --enable-fatal-warnings --disable-silent-rules --enable-fragile-hardening"; fi
|
||||
|
|
39
CONTRIBUTING
39
CONTRIBUTING
|
@ -1,39 +0,0 @@
|
|||
Contributing to Tor
|
||||
-------------------
|
||||
|
||||
### Getting started
|
||||
|
||||
Welcome!
|
||||
|
||||
We have a bunch of documentation about how to develop Tor in the
|
||||
doc/HACKING/ directory. We recommend that you start with
|
||||
doc/HACKING/README.1st.md , and then go from there. It will tell
|
||||
you how to find your way around the source code, how to get
|
||||
involved with the Tor community, how to write patches, and much
|
||||
more!
|
||||
|
||||
You don't have to be a C developer to help with Tor: have a look
|
||||
at https://www.torproject.org/getinvolved/volunteer !
|
||||
|
||||
The Tor Project is committed to fostering a inclusive community
|
||||
where people feel safe to engage, share their points of view, and
|
||||
participate. For the latest version of our Code of Conduct, please
|
||||
see
|
||||
|
||||
https://gitweb.torproject.org/community/policies.git/plain/code_of_conduct.txt
|
||||
|
||||
|
||||
|
||||
### License issues
|
||||
|
||||
Tor is distributed under the license terms in the LICENSE -- in
|
||||
brief, the "3-clause BSD license". If you send us code to
|
||||
distribute with Tor, it needs to be code that we can distribute
|
||||
under those terms. Please don't send us patches unless you agree
|
||||
to allow this.
|
||||
|
||||
Some compatible licenses include:
|
||||
|
||||
- 3-clause BSD
|
||||
- 2-clause BSD
|
||||
- CC0 Public Domain Dedication
|
43
Makefile.am
43
Makefile.am
|
@ -26,7 +26,7 @@ TESTING_TOR_BINARY=$(top_builddir)/src/or/tor$(EXEEXT)
|
|||
endif
|
||||
|
||||
if USE_RUST
|
||||
rust_ldadd=$(top_builddir)/src/rust/target/release/@TOR_RUST_STATIC_NAME@ \
|
||||
rust_ldadd=$(top_builddir)/src/rust/target/release/@TOR_RUST_UTIL_STATIC_NAME@ \
|
||||
@TOR_RUST_EXTRA_LIBS@
|
||||
else
|
||||
rust_ldadd=
|
||||
|
@ -38,7 +38,6 @@ include contrib/include.am
|
|||
|
||||
EXTRA_DIST+= \
|
||||
ChangeLog \
|
||||
CONTRIBUTING \
|
||||
INSTALL \
|
||||
LICENSE \
|
||||
Makefile.nmake \
|
||||
|
@ -52,14 +51,14 @@ AM_ETAGSFLAGS=--regex='{c}/MOCK_IMPL([^,]+,\W*\([a-zA-Z0-9_]+\)\W*,/\1/s'
|
|||
if COVERAGE_ENABLED
|
||||
TEST_CFLAGS=-fno-inline -fprofile-arcs -ftest-coverage
|
||||
if DISABLE_ASSERTS_IN_UNIT_TESTS
|
||||
TEST_CPPFLAGS=-DTOR_UNIT_TESTS -DTOR_COVERAGE -DDISABLE_ASSERTS_IN_UNIT_TESTS @TOR_MODULES_ALL_ENABLED@
|
||||
TEST_CPPFLAGS=-DTOR_UNIT_TESTS -DTOR_COVERAGE -DDISABLE_ASSERTS_IN_UNIT_TESTS
|
||||
else
|
||||
TEST_CPPFLAGS=-DTOR_UNIT_TESTS -DTOR_COVERAGE @TOR_MODULES_ALL_ENABLED@
|
||||
TEST_CPPFLAGS=-DTOR_UNIT_TESTS -DTOR_COVERAGE
|
||||
endif
|
||||
TEST_NETWORK_FLAGS=--coverage --hs-multi-client 1
|
||||
else
|
||||
TEST_CFLAGS=
|
||||
TEST_CPPFLAGS=-DTOR_UNIT_TESTS @TOR_MODULES_ALL_ENABLED@
|
||||
TEST_CPPFLAGS=-DTOR_UNIT_TESTS
|
||||
TEST_NETWORK_FLAGS=--hs-multi-client 1
|
||||
endif
|
||||
TEST_NETWORK_WARNING_FLAGS=--quiet --only-warnings
|
||||
|
@ -119,19 +118,17 @@ test-network: need-chutney-path $(TESTING_TOR_BINARY) src/tools/tor-gencert
|
|||
|
||||
# Run all available tests using automake's test-driver
|
||||
# only run IPv6 tests if we can ping6 ::1 (localhost)
|
||||
# only run IPv6 tests if we can ping ::1 (localhost)
|
||||
# some IPv6 tests will fail without an IPv6 DNS server (see #16971 and #17011)
|
||||
# only run mixed tests if we have a tor-stable binary
|
||||
# Try the syntax for BSD ping6, Linux ping6, and Linux ping -6,
|
||||
# because they're incompatible
|
||||
# Try both the BSD and the Linux ping6 syntax, because they're incompatible
|
||||
test-network-all: need-chutney-path test-driver $(TESTING_TOR_BINARY) src/tools/tor-gencert
|
||||
mkdir -p $(TEST_NETWORK_ALL_LOG_DIR)
|
||||
@flavors="$(TEST_CHUTNEY_FLAVORS)"; \
|
||||
if ping6 -q -c 1 -o ::1 >/dev/null 2>&1 || ping6 -q -c 1 -W 1 ::1 >/dev/null 2>&1 || ping -6 -c 1 -W 1 ::1 >/dev/null 2>&1; then \
|
||||
echo "ping6 ::1 or ping ::1 succeeded, running IPv6 flavors: $(TEST_CHUTNEY_FLAVORS_IPV6)."; \
|
||||
if ping6 -q -c 1 -o ::1 >/dev/null 2>&1 || ping6 -q -c 1 -W 1 ::1 >/dev/null 2>&1; then \
|
||||
echo "ping6 ::1 succeeded, running IPv6 flavors: $(TEST_CHUTNEY_FLAVORS_IPV6)."; \
|
||||
flavors="$$flavors $(TEST_CHUTNEY_FLAVORS_IPV6)"; \
|
||||
else \
|
||||
echo "ping6 ::1 and ping ::1 failed, skipping IPv6 flavors: $(TEST_CHUTNEY_FLAVORS_IPV6)."; \
|
||||
echo "ping6 ::1 failed, skipping IPv6 flavors: $(TEST_CHUTNEY_FLAVORS_IPV6)."; \
|
||||
skip_flavors="$$skip_flavors $(TEST_CHUTNEY_FLAVORS_IPV6)"; \
|
||||
fi; \
|
||||
if command -v tor-stable >/dev/null 2>&1; then \
|
||||
|
@ -218,26 +215,6 @@ check-logs:
|
|||
$(top_srcdir)/scripts/maint/checkLogs.pl \
|
||||
$(top_srcdir)/src/*/*.[ch] | sort -n
|
||||
|
||||
.PHONY: check-typos
|
||||
check-typos:
|
||||
@if test -x "`which misspell 2>&1;true`"; then \
|
||||
echo "Checking for Typos ..."; \
|
||||
(misspell \
|
||||
$(top_srcdir)/src/[^e]*/*.[ch] \
|
||||
$(top_srcdir)/doc \
|
||||
$(top_srcdir)/contrib \
|
||||
$(top_srcdir)/scripts \
|
||||
$(top_srcdir)/README \
|
||||
$(top_srcdir)/ChangeLog \
|
||||
$(top_srcdir)/INSTALL \
|
||||
$(top_srcdir)/ReleaseNotes \
|
||||
$(top_srcdir)/LICENSE); \
|
||||
else \
|
||||
echo "Tor can use misspell to check for typos."; \
|
||||
echo "It seems that you don't have misspell installed."; \
|
||||
echo "You can install the latest version of misspell here: https://github.com/client9/misspell#install"; \
|
||||
fi
|
||||
|
||||
.PHONY: check-changes
|
||||
check-changes:
|
||||
if USEPYTHON
|
||||
|
@ -271,10 +248,6 @@ clean-local:
|
|||
rm -rf $(top_builddir)/src/rust/target
|
||||
rm -rf $(top_builddir)/src/rust/.cargo/registry
|
||||
|
||||
if USE_RUST
|
||||
distclean-local: distclean-rust
|
||||
endif
|
||||
|
||||
# This relies on some internal details of how automake implements
|
||||
# distcheck. We check two directories because automake-1.15 changed
|
||||
# from $(distdir)/_build to $(distdir)/_build/sub.
|
||||
|
|
1712
ReleaseNotes
1712
ReleaseNotes
File diff suppressed because it is too large
Load Diff
|
@ -1,6 +0,0 @@
|
|||
o Major bugfixes (security, directory authority, denial-of-service):
|
||||
- Fix a bug that could have allowed an attacker to force a
|
||||
directory authority to use up all its RAM by passing it a
|
||||
maliciously crafted protocol versions string. Fixes bug 25517;
|
||||
bugfix on 0.2.9.4-alpha. This issue is also tracked as
|
||||
TROVE-2018-005.
|
|
@ -0,0 +1,4 @@
|
|||
o Minor bugfixes (relay, crash):
|
||||
- Avoid a crash when running with DirPort set but ORPort tuned off.
|
||||
Fixes a case of bug 23693; bugfix on 0.3.1.1-alpha.
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
o Code simplification and refactoring:
|
||||
- Move the list of default directory authorities to their own file for
|
||||
inclusion using the C preprocessor. Closes ticket 24854. Patch by "beastr0".
|
|
@ -0,0 +1,3 @@
|
|||
o Minor bugfixes (Linux seccomp2 sandbox):
|
||||
- Allow the nanosleep() system call, which glibc uses to implement
|
||||
sleep() and usleep(). Fixes bug 24969; bugfix on 0.2.5.1-alpha.
|
|
@ -0,0 +1,5 @@
|
|||
o Minor bugfixes (documentation):
|
||||
- Document that the PerConnBW{Rate,Burst} options will fall back to their
|
||||
corresponding consensus parameters only if those parameters are
|
||||
set. Previously we had claimed that these values would always be
|
||||
set in the consensus. Fixes bug 25296; bugfix on 0.2.2.7-alpha.
|
|
@ -0,0 +1,8 @@
|
|||
o Minor bugfixes (testing):
|
||||
- Avoid intermittent test failures due to relying on hidden service
|
||||
introductory point creation within 5 seconds of real clock time. The
|
||||
time limit for the test has been increased to 500 seconds, which may
|
||||
still result in intermittent failures (e.g. if the system doing the
|
||||
testing enters sleep/hibernation or experiences some other clock jump).
|
||||
However, this should elliminate test failures currently happening on
|
||||
developer and CI systems. Fixes bug 25450; bugfix on 0.3.1.3-alpha.
|
|
@ -0,0 +1,5 @@
|
|||
o Minor bugfixes (compilation):
|
||||
- Fix a c99 compliance issue in our configuration script that was
|
||||
causing compilation issues when compiling Tor with certain
|
||||
versions of xtools. Fixes bug 25474; bugfix on 0.3.2.5-alpha.
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
o Minor bugfixes (C correctness):
|
||||
- Fix a very unlikely null pointer dereference. Fixes bug 25629;
|
||||
bugfix on 0.2.9.15. Found by Coverity; this is CID 1430932.
|
|
@ -0,0 +1,3 @@
|
|||
o Major bugfixes (onion service):
|
||||
- Correctly detect when onion services get disabled after HUP.
|
||||
Fixes bug 25761; bugfix on 0.3.2.1.
|
|
@ -0,0 +1,3 @@
|
|||
o Minor bugfixes (hidden service v3):
|
||||
- Fix a memory leak when an hidden service v3 is configured and gets a
|
||||
SIGHUP signal. Fixes bug 25901; bugfix on 0.3.2.1-alpha.
|
|
@ -1,3 +0,0 @@
|
|||
o Minor bugfixes (onion services):
|
||||
- Fix a bug that blocked the creation of ephemeral v3 onion services. Fixes
|
||||
bug 25939; bugfix on 0.3.4.1-alpha.
|
|
@ -0,0 +1,5 @@
|
|||
o Major bugfixes (directory authorities, security):
|
||||
- When directory authorities read a zero-byte bandwidth file, they log
|
||||
a warning with the contents of an uninitialised buffer. Log a warning
|
||||
about the empty file instead.
|
||||
Fixes bug 26007; bugfix on 0.2.2.1-alpha.
|
|
@ -0,0 +1,5 @@
|
|||
o Minor bugfixes (hidden service v3):
|
||||
- When parsing the descriptor signature, look for the token plus an extra
|
||||
white-space at the end. This is more correct but also will allow us to
|
||||
support new fields that might start with "signature". Fixes bug 26069;
|
||||
bugfix on 0.3.0.1-alpha.
|
|
@ -0,0 +1,5 @@
|
|||
o Minor bugfixes (correctness, client):
|
||||
- Upon receiving a malformed connected cell, stop processing the cell
|
||||
immediately. Previously we would mark the connection for close, but
|
||||
continue processing the cell as if the connection were open. Fixes bug
|
||||
26072; bugfix on 0.2.4.7-alpha.
|
|
@ -1,5 +0,0 @@
|
|||
o Minor bugfixes (test coverage tools):
|
||||
- Update our "cov-diff" script to handle output from the latest
|
||||
version of gcov, and to remove extraneous timestamp information
|
||||
from its output. Fixes bugs 26101 and 26102; bugfix on
|
||||
0.2.5.1-alpha.
|
|
@ -1,6 +0,0 @@
|
|||
o Minor bugfixes (controller):
|
||||
- Improve accuracy of the BUILDTIMEOUT_SET control port event's
|
||||
TIMEOUT_RATE and CLOSE_RATE fields. (We were previously miscounting
|
||||
the total number of circuits for these field values.) Fixes bug
|
||||
26121; bugfix on 0.3.3.1-alpha.
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
o Minor bugfixes (compilation):
|
||||
- Fix compilation when building with OpenSSL 1.1.0 with the
|
||||
"no-deprecated" flag enabled. Fixes bug 26156; bugfix on 0.3.4.1-alpha.
|
|
@ -1,4 +0,0 @@
|
|||
o Minor bugfixes (control port):
|
||||
- Do not count 0-length RELAY_COMMAND_DATA cells as valid data in CIRC_BW
|
||||
events. Previously, such cells were counted entirely in the OVERHEAD
|
||||
field. Now they are not. Fixes bug 26259; bugfix on 0.3.4.1-alpha.
|
|
@ -0,0 +1,3 @@
|
|||
o Minor features (continuous integration):
|
||||
- Our Travis CI configuration now integrates with the Coveralls coverage
|
||||
analysis tool. Closes ticket 25818.
|
|
@ -1,4 +0,0 @@
|
|||
o Documentation:
|
||||
- In code comment, point the reader to the exact section
|
||||
in Tor specification that specifies circuit close error
|
||||
code values. Resolves ticket 25237.
|
|
@ -0,0 +1,4 @@
|
|||
o Minor features (sandbox):
|
||||
- Explicitly permit the poll() system call when the Linux seccomp2-based
|
||||
sandbox is enabled: apparently, some versions of libc use poll() when
|
||||
calling getpwnam(). Closes ticket 25313.
|
|
@ -0,0 +1,4 @@
|
|||
o Minor features (geoip):
|
||||
- Update geoip and geoip6 to the March 8 2018 Maxmind GeoLite2
|
||||
Country database. Closes ticket 25469.
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
o Minor features (geoip):
|
||||
- Update geoip and geoip6 to the April 3 2018 Maxmind GeoLite2
|
||||
Country database. Closes ticket 25718.
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
o Minor features (geoip):
|
||||
- Update geoip and geoip6 to the May 1 2018 Maxmind GeoLite2
|
||||
Country database. Closes ticket 26104.
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
o Minor features (continuous integration):
|
||||
- Add the necessary configuration files for continuous integration
|
||||
testing on Windows, via the Appveyor platform. Closes ticket 25549.
|
||||
Patches from Marcin Cieślak and Isis Lovecruft.
|
|
@ -0,0 +1,4 @@
|
|||
o Minor feature (continuous integration):
|
||||
- Update the Travis CI configuration to use the stable Rust
|
||||
channel, now that we have decided to require that. Closes
|
||||
ticket 25714.
|
|
@ -0,0 +1,3 @@
|
|||
o Minor bugfixes (client):
|
||||
- Don't consider Tor running as a client if the ControlPort is open. Fixes
|
||||
bug 26062; bugfix on 0.2.9.4-alpha.
|
|
@ -0,0 +1,4 @@
|
|||
o Minor features (continuous integration):
|
||||
- Our .travis.yml configuration now includes support for testing
|
||||
the results of "make distcheck". (It's not uncommon for "make check" to
|
||||
pass but "make distcheck" to fail.) Closes ticket 25814.
|
166
configure.ac
166
configure.ac
|
@ -4,7 +4,7 @@ dnl Copyright (c) 2007-2017, The Tor Project, Inc.
|
|||
dnl See LICENSE for licensing information
|
||||
|
||||
AC_PREREQ([2.63])
|
||||
AC_INIT([tor],[0.3.4.1-alpha-dev])
|
||||
AC_INIT([tor],[0.3.2.10-dev])
|
||||
AC_CONFIG_SRCDIR([src/or/main.c])
|
||||
AC_CONFIG_MACRO_DIR([m4])
|
||||
|
||||
|
@ -59,10 +59,6 @@ AC_ARG_ENABLE(rust,
|
|||
AS_HELP_STRING(--enable-rust, [enable rust integration]))
|
||||
AC_ARG_ENABLE(cargo-online-mode,
|
||||
AS_HELP_STRING(--enable-cargo-online-mode, [Allow cargo to make network requests to fetch crates. For builds with rust only.]))
|
||||
AC_ARG_ENABLE(restart-debugging,
|
||||
AS_HELP_STRING(--enable-restart-debugging, [Build Tor with support for debugging in-process restart. Developers only.]))
|
||||
AC_ARG_ENABLE(zstd-advanced-apis,
|
||||
AS_HELP_STRING(--disable-zstd-advanced-apis, [Build without support for zstd's "static-only" APIs.]))
|
||||
|
||||
if test "x$enable_coverage" != "xyes" -a "x$enable_asserts_in_tests" = "xno" ; then
|
||||
AC_MSG_ERROR([Can't disable assertions outside of coverage build])
|
||||
|
@ -111,15 +107,7 @@ AC_ARG_ENABLE(systemd,
|
|||
* ) AC_MSG_ERROR(bad value for --enable-systemd) ;;
|
||||
esac], [systemd=auto])
|
||||
|
||||
if test "$enable_restart_debugging" = "yes"; then
|
||||
AC_DEFINE(ENABLE_RESTART_DEBUGGING, 1,
|
||||
[Defined if we're building with support for in-process restart debugging.])
|
||||
fi
|
||||
|
||||
if test "$enable_zstd_advanced_apis" != "no"; then
|
||||
AC_DEFINE(ENABLE_ZSTD_ADVANCED_APIS, 1,
|
||||
[Defined if we're going to try to use zstd's "static-only" APIs.])
|
||||
fi
|
||||
|
||||
# systemd support
|
||||
if test "x$enable_systemd" = "xno"; then
|
||||
|
@ -216,45 +204,6 @@ if test x$enable_event_tracing_debug = xyes; then
|
|||
AC_DEFINE([TOR_EVENT_TRACING_ENABLED], [1], [Compile the event tracing instrumentation])
|
||||
fi
|
||||
|
||||
dnl Enable Android only features.
|
||||
AC_ARG_ENABLE(android,
|
||||
AS_HELP_STRING(--enable-android, [build with Android features enabled]))
|
||||
AM_CONDITIONAL([USE_ANDROID], [test "x$enable_android" = "xyes"])
|
||||
|
||||
if test "x$enable_android" = "xyes"; then
|
||||
AC_DEFINE([USE_ANDROID], [1], [Compile with Android specific features enabled])
|
||||
|
||||
dnl Check if the Android log library is available.
|
||||
AC_CHECK_HEADERS([android/log.h])
|
||||
AC_SEARCH_LIBS(__android_log_write, [log])
|
||||
|
||||
fi
|
||||
|
||||
dnl ---
|
||||
dnl Tor modules options. These options are namespaced with --disable-module-XXX
|
||||
dnl ---
|
||||
|
||||
dnl All our modules.
|
||||
m4_define(MODULES, dirauth)
|
||||
|
||||
dnl Directory Authority module.
|
||||
AC_ARG_ENABLE([module-dirauth],
|
||||
AS_HELP_STRING([--disable-module-dirauth],
|
||||
[Do not build tor with the dirauth module]),
|
||||
[], dnl Action if-given
|
||||
AC_DEFINE([HAVE_MODULE_DIRAUTH], [1],
|
||||
[Compile with Directory Authority feature support]))
|
||||
AM_CONDITIONAL(BUILD_MODULE_DIRAUTH, [test "x$enable_module_dirauth" != "xno"])
|
||||
|
||||
dnl Helper variables.
|
||||
TOR_MODULES_ALL_ENABLED=
|
||||
AC_DEFUN([ADD_MODULE], [
|
||||
MODULE=m4_toupper($1)
|
||||
TOR_MODULES_ALL_ENABLED="${TOR_MODULES_ALL_ENABLED} -DHAVE_MODULE_${MODULE}=1"
|
||||
])
|
||||
m4_foreach_w([module], MODULES, [ADD_MODULE([module])])
|
||||
AC_SUBST(TOR_MODULES_ALL_ENABLED)
|
||||
|
||||
dnl check for the correct "ar" when cross-compiling.
|
||||
dnl (AM_PROG_AR was new in automake 1.11.2, which we do not yet require,
|
||||
dnl so kludge up a replacement for the case where it isn't there yet.)
|
||||
|
@ -306,10 +255,7 @@ fi
|
|||
AM_CONDITIONAL(USEPYTHON, [test "x$PYTHON" != "x"])
|
||||
|
||||
dnl List all external rust crates we depend on here. Include the version
|
||||
rust_crates=" \
|
||||
digest-0.7.2 \
|
||||
libc-0.2.39 \
|
||||
"
|
||||
rust_crates="libc-0.2.22"
|
||||
AC_SUBST(rust_crates)
|
||||
|
||||
ifdef([AC_C_FLEXIBLE_ARRAY_MEMBER], [
|
||||
|
@ -429,7 +375,6 @@ AH_BOTTOM([
|
|||
|
||||
|
||||
AM_CONDITIONAL(BUILD_NT_SERVICES, test "x$bwin32" = "xtrue")
|
||||
AM_CONDITIONAL(BUILD_LIBTORRUNNER, test "x$bwin32" != "xtrue")
|
||||
|
||||
dnl Enable C99 when compiling with MIPSpro
|
||||
AC_MSG_CHECKING([for MIPSpro compiler])
|
||||
|
@ -472,27 +417,22 @@ if test "x$enable_rust" = "xyes"; then
|
|||
dnl When we're not allowed to touch the network, we need crate dependencies
|
||||
dnl locally available.
|
||||
AC_MSG_CHECKING([rust crate dependencies])
|
||||
AC_ARG_VAR([TOR_RUST_DEPENDENCIES], [path to directory with local crate mirror])
|
||||
if test "x$TOR_RUST_DEPENDENCIES" = "x"; then
|
||||
TOR_RUST_DEPENDENCIES="${srcdir}/src/ext/rust/crates"
|
||||
AC_ARG_VAR([RUST_DEPENDENCIES], [path to directory with local crate mirror])
|
||||
if test "x$RUST_DEPENDENCIES" = "x"; then
|
||||
RUST_DEPENDENCIES="$srcdir/src/ext/rust/"
|
||||
NEED_MOD=1
|
||||
fi
|
||||
dnl Check whether the path exists before we try to cd into it.
|
||||
if test ! -d "$TOR_RUST_DEPENDENCIES"; then
|
||||
AC_MSG_ERROR([Rust dependency directory $TOR_RUST_DEPENDENCIES does not exist. Specify a dependency directory using the TOR_RUST_DEPENDENCIES variable or allow cargo to fetch crates using --enable-cargo-online-mode.])
|
||||
ERRORED=1
|
||||
if test ! -d "$RUST_DEPENDENCIES"; then
|
||||
AC_MSG_ERROR([Rust dependency directory $RUST_DEPENDENCIES does not exist. Specify a dependency directory using the RUST_DEPENDENCIES variable or allow cargo to fetch crates using --enable-cargo-online-mode.])
|
||||
fi
|
||||
dnl Make the path absolute, since we'll be using it from within a
|
||||
dnl subdirectory.
|
||||
TOR_RUST_DEPENDENCIES=$(cd "$TOR_RUST_DEPENDENCIES" ; pwd)
|
||||
|
||||
for dep in $rust_crates; do
|
||||
if test ! -d "$TOR_RUST_DEPENDENCIES"/"$dep"; then
|
||||
AC_MSG_ERROR([Failure to find rust dependency $TOR_RUST_DEPENDENCIES/$dep. Specify a dependency directory using the TOR_RUST_DEPENDENCIES variable or allow cargo to fetch crates using --enable-cargo-online-mode.])
|
||||
ERRORED=1
|
||||
if test ! -d "$RUST_DEPENDENCIES"/"$dep"; then
|
||||
AC_MSG_ERROR([Failure to find rust dependency $RUST_DEPENDENCIES/$dep. Specify a dependency directory using the RUST_DEPENDENCIES variable or allow cargo to fetch crates using --enable-cargo-online-mode.])
|
||||
fi
|
||||
done
|
||||
if test "x$ERRORED" = "x"; then
|
||||
AC_MSG_RESULT([yes])
|
||||
if test "x$NEED_MOD" = "x1"; then
|
||||
dnl When looking for dependencies from cargo, pick right directory
|
||||
RUST_DEPENDENCIES="../../src/ext/rust"
|
||||
fi
|
||||
fi
|
||||
|
||||
|
@ -508,18 +448,17 @@ if test "x$enable_rust" = "xyes"; then
|
|||
dnl For now both MSVC and MinGW rust libraries will output static libs with
|
||||
dnl the MSVC naming convention.
|
||||
if test "$bwin32" = "true"; then
|
||||
TOR_RUST_STATIC_NAME=tor_rust.lib
|
||||
TOR_RUST_UTIL_STATIC_NAME=tor_util.lib
|
||||
else
|
||||
TOR_RUST_STATIC_NAME=libtor_rust.a
|
||||
TOR_RUST_UTIL_STATIC_NAME=libtor_util.a
|
||||
fi
|
||||
|
||||
AC_SUBST(TOR_RUST_STATIC_NAME)
|
||||
AC_SUBST(TOR_RUST_UTIL_STATIC_NAME)
|
||||
AC_SUBST(CARGO_ONLINE)
|
||||
AC_SUBST(RUST_DL)
|
||||
|
||||
dnl Let's check the rustc version, too
|
||||
AC_MSG_CHECKING([rust version])
|
||||
RUSTC_VERSION=`$RUSTC --version`
|
||||
RUSTC_VERSION_MAJOR=`$RUSTC --version | cut -d ' ' -f 2 | cut -d '.' -f 1`
|
||||
RUSTC_VERSION_MINOR=`$RUSTC --version | cut -d ' ' -f 2 | cut -d '.' -f 2`
|
||||
if test "x$RUSTC_VERSION_MAJOR" = "x" -o "x$RUSTC_VERSION_MINOR" = "x"; then
|
||||
|
@ -528,7 +467,6 @@ if test "x$enable_rust" = "xyes"; then
|
|||
if test "$RUSTC_VERSION_MAJOR" -lt 2 -a "$RUSTC_VERSION_MINOR" -lt 14; then
|
||||
AC_MSG_ERROR([rustc must be at least version 1.14])
|
||||
fi
|
||||
AC_MSG_RESULT([$RUSTC_VERSION])
|
||||
fi
|
||||
|
||||
AC_SUBST(TOR_RUST_EXTRA_LIBS)
|
||||
|
@ -578,10 +516,8 @@ AC_CHECK_FUNCS(
|
|||
llround \
|
||||
localtime_r \
|
||||
lround \
|
||||
mach_approximate_time \
|
||||
memmem \
|
||||
memset_s \
|
||||
mmap \
|
||||
pipe \
|
||||
pipe2 \
|
||||
prctl \
|
||||
|
@ -608,7 +544,7 @@ AC_CHECK_FUNCS(
|
|||
# Apple messed up when they added two functions functions in Sierra: they
|
||||
# forgot to decorate them with appropriate AVAILABLE_MAC_OS_VERSION
|
||||
# checks. So we should only probe for those functions if we are sure that we
|
||||
# are not targeting OSX 10.11 or earlier.
|
||||
# are not targetting OSX 10.11 or earlier.
|
||||
AC_MSG_CHECKING([for a pre-Sierra OSX build target])
|
||||
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
|
||||
#ifdef __APPLE__
|
||||
|
@ -650,21 +586,6 @@ fi
|
|||
AM_CONDITIONAL(BUILD_READPASSPHRASE_C,
|
||||
test "x$ac_cv_func_readpassphrase" = "xno" && test "$bwin32" = "false")
|
||||
|
||||
AC_MSG_CHECKING([whether free(NULL) works])
|
||||
AC_RUN_IFELSE([AC_LANG_PROGRAM([
|
||||
#include <stdlib.h>
|
||||
], [
|
||||
char *p = NULL;
|
||||
free(p);
|
||||
])],
|
||||
[free_null_ok=true; AC_MSG_RESULT(yes)],
|
||||
[free_null_ok=false; AC_MSG_RESULT(no)],
|
||||
[free_null_ok=cross; AC_MSG_RESULT(cross)])
|
||||
|
||||
if test "$free_null_ok" = "false"; then
|
||||
AC_MSG_ERROR([Your libc implementation doesn't allow free(NULL), as required by C99.])
|
||||
fi
|
||||
|
||||
dnl ------------------------------------------------------
|
||||
dnl Where do you live, libevent? And how do we call you?
|
||||
|
||||
|
@ -816,19 +737,10 @@ AC_ARG_WITH(ssl-dir,
|
|||
|
||||
AC_MSG_NOTICE([Now, we'll look for OpenSSL >= 1.0.1])
|
||||
TOR_SEARCH_LIBRARY(openssl, $tryssldir, [-lssl -lcrypto $TOR_LIB_GDI $TOR_LIB_WS32],
|
||||
[#include <openssl/ssl.h>
|
||||
char *getenv(const char *);],
|
||||
[struct ssl_cipher_st;
|
||||
unsigned SSL_CIPHER_get_id(const struct ssl_cipher_st *);
|
||||
char *getenv(const char *);],
|
||||
dnl This funny-looking test program calls getenv, so that the compiler
|
||||
dnl will neither make code that call SSL_CIPHER_get_id(NULL) [producing
|
||||
dnl a crash], nor optimize out the call to SSL_CIPHER_get_id().
|
||||
dnl We look for SSL_cipher_get_id() because it is present in
|
||||
dnl OpenSSL >=1.0.1, because it is not deprecated, and because Tor
|
||||
dnl depends on it.
|
||||
[if (getenv("THIS_SHOULDNT_BE_SET_X201803")) SSL_CIPHER_get_id((void *)0);], [],
|
||||
[/usr/local/opt/openssl /usr/local/openssl /usr/lib/openssl /usr/local/ssl /usr/lib/ssl /usr/local /opt/openssl])
|
||||
[#include <openssl/ssl.h>],
|
||||
[struct ssl_method_st; const struct ssl_method_st *TLSv1_1_method(void);],
|
||||
[TLSv1_1_method();], [],
|
||||
[/usr/local/opt/openssl /usr/local/openssl /usr/lib/openssl /usr/local/ssl /usr/lib/ssl /usr/local /usr/athena /opt/openssl])
|
||||
|
||||
dnl XXXX check for OPENSSL_VERSION_NUMBER == SSLeay()
|
||||
|
||||
|
@ -894,10 +806,6 @@ AC_CHECK_MEMBERS([SSL.state], , ,
|
|||
[#include <openssl/ssl.h>
|
||||
])
|
||||
|
||||
AC_CHECK_SIZEOF(SHA_CTX, , [AC_INCLUDES_DEFAULT()
|
||||
#include <openssl/sha.h>
|
||||
])
|
||||
|
||||
dnl Define the set of checks for KIST scheduler support.
|
||||
AC_DEFUN([CHECK_KIST_SUPPORT],[
|
||||
dnl KIST needs struct tcp_info and for certain members to exist.
|
||||
|
@ -1016,16 +924,6 @@ if test "x$have_zstd" = "xyes"; then
|
|||
AC_DEFINE(HAVE_ZSTD,1,[Have Zstd])
|
||||
TOR_ZSTD_CFLAGS="${ZSTD_CFLAGS}"
|
||||
TOR_ZSTD_LIBS="${ZSTD_LIBS}"
|
||||
|
||||
dnl now check for zstd functions
|
||||
save_LIBS="$LIBS"
|
||||
save_CFLAGS="$CFLAGS"
|
||||
LIBS="$LIBS $ZSTD_LIBS"
|
||||
CFLAGS="$CFLAGS $ZSTD_CFLAGS"
|
||||
AC_CHECK_FUNCS(ZSTD_estimateCStreamSize \
|
||||
ZSTD_estimateDCtxSize)
|
||||
LIBS="$save_LIBS"
|
||||
CFLAGS="$save_CFLAGS"
|
||||
fi
|
||||
AC_SUBST(TOR_ZSTD_CFLAGS)
|
||||
AC_SUBST(TOR_ZSTD_LIBS)
|
||||
|
@ -1100,12 +998,12 @@ if test "$fragile_hardening" = "yes"; then
|
|||
|
||||
TOR_TRY_COMPILE_WITH_CFLAGS([-fsanitize=address], also_link, CFLAGS_ASAN="-fsanitize=address", true)
|
||||
if test "$tor_cv_cflags__fsanitize_address" = "yes" && test "$tor_can_link__fsanitize_address" != "yes"; then
|
||||
AC_MSG_ERROR([The compiler supports -fsanitize=address, but for some reason I was not able to link when using it. Are you missing run-time support? With GCC you need libubsan.*, and with Clang you need libclang_rt.ubsan*])
|
||||
AC_MSG_ERROR([The compiler supports -fsanitize=address, but for some reason I was not able to link when using it. Are you missing run-time support? With GCC you need libubsan.so, and with Clang you need libclang_rt.ubsan*])
|
||||
fi
|
||||
|
||||
TOR_TRY_COMPILE_WITH_CFLAGS([-fsanitize=undefined], also_link, CFLAGS_UBSAN="-fsanitize=undefined", true)
|
||||
if test "$tor_cv_cflags__fsanitize_address" = "yes" && test "$tor_can_link__fsanitize_address" != "yes"; then
|
||||
AC_MSG_ERROR([The compiler supports -fsanitize=undefined, but for some reason I was not able to link when using it. Are you missing run-time support? With GCC you need libasan.*, and with Clang you need libclang_rt.ubsan*])
|
||||
AC_MSG_ERROR([The compiler supports -fsanitize=undefined, but for some reason I was not able to link when using it. Are you missing run-time support? With GCC you need libasan.so, and with Clang you need libclang_rt.ubsan*])
|
||||
fi
|
||||
|
||||
TOR_CHECK_CFLAGS([-fno-omit-frame-pointer])
|
||||
|
@ -1346,7 +1244,6 @@ AC_CHECK_HEADERS([assert.h \
|
|||
pwd.h \
|
||||
readpassphrase.h \
|
||||
stdint.h \
|
||||
stdatomic.h \
|
||||
sys/eventfd.h \
|
||||
sys/file.h \
|
||||
sys/ioctl.h \
|
||||
|
@ -1778,6 +1675,14 @@ AC_CHECK_DECLS([mlockall], , , [
|
|||
#include <sys/mman.h>
|
||||
#endif])
|
||||
|
||||
# Some MinGW environments don't have getpagesize in unistd.h. We don't use
|
||||
# AC_CHECK_FUNCS(getpagesize), because other environments rename getpagesize
|
||||
# using macros
|
||||
AC_CHECK_DECLS([getpagesize], , , [
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif])
|
||||
|
||||
# Allow user to specify an alternate syslog facility
|
||||
AC_ARG_WITH(syslog-facility,
|
||||
AS_HELP_STRING(--with-syslog-facility=LOG, [syslog facility to use (default=LOG_DAEMON)]),
|
||||
|
@ -1915,12 +1820,6 @@ AC_SUBST(BUILDDIR)
|
|||
AH_TEMPLATE([BUILDDIR],[tor's build directory])
|
||||
AC_DEFINE_UNQUOTED(BUILDDIR,"$BUILDDIR")
|
||||
|
||||
if test "x$SRCDIR" = "x"; then
|
||||
SRCDIR=$(cd "$srcdir"; pwd)
|
||||
fi
|
||||
AH_TEMPLATE([SRCDIR],[tor's sourcedir directory])
|
||||
AC_DEFINE_UNQUOTED(SRCDIR,"$SRCDIR")
|
||||
|
||||
if test "x$CONFDIR" = "x"; then
|
||||
CONFDIR=`eval echo $sysconfdir/tor`
|
||||
fi
|
||||
|
@ -2102,6 +2001,7 @@ if test "x$enable_gcc_warnings_advisory" != "xno"; then
|
|||
-Winvalid-source-encoding
|
||||
-Winvalid-token-paste
|
||||
-Wknr-promoted-parameter
|
||||
-Wlanguage-extension-token
|
||||
-Wlarge-by-value-copy
|
||||
-Wliteral-conversion
|
||||
-Wliteral-range
|
||||
|
@ -2127,7 +2027,7 @@ if test "x$enable_gcc_warnings_advisory" != "xno"; then
|
|||
-Wnon-literal-null-conversion
|
||||
-Wnon-pod-varargs
|
||||
-Wnonportable-cfstrings
|
||||
-Wnormalized=nfkc
|
||||
-Wnormalized=id
|
||||
-Wnull-arithmetic
|
||||
-Wnull-character
|
||||
-Wnull-conversion
|
||||
|
|
|
@ -87,7 +87,7 @@ RATE_UP=5000
|
|||
# machine does any other network activity. That is not very fun.
|
||||
RATE_UP_TOR=1500
|
||||
|
||||
# RATE_UP_TOR_CEIL is the maximum rate allowed for all Tor traffic in
|
||||
# RATE_UP_TOR_CEIL is the maximum rate allowed for all Tor trafic in
|
||||
# kbits/sec.
|
||||
RATE_UP_TOR_CEIL=5000
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
!include "LogicLib.nsh"
|
||||
!include "FileFunc.nsh"
|
||||
!insertmacro GetParameters
|
||||
!define VERSION "0.3.4.1-alpha-dev"
|
||||
!define VERSION "0.3.2.10-dev"
|
||||
!define INSTALLER "tor-${VERSION}-win32.exe"
|
||||
!define WEBSITE "https://www.torproject.org/"
|
||||
!define LICENSE "LICENSE"
|
||||
|
|
|
@ -42,23 +42,6 @@ If you have changed build system components:
|
|||
- For example, if you have changed Makefiles, autoconf files, or anything
|
||||
else that affects the build system.
|
||||
|
||||
License issues
|
||||
==============
|
||||
|
||||
Tor is distributed under the license terms in the LICENSE -- in
|
||||
brief, the "3-clause BSD license". If you send us code to
|
||||
distribute with Tor, it needs to be code that we can distribute
|
||||
under those terms. Please don't send us patches unless you agree
|
||||
to allow this.
|
||||
|
||||
Some compatible licenses include:
|
||||
|
||||
- 3-clause BSD
|
||||
- 2-clause BSD
|
||||
- CC0 Public Domain Dedication
|
||||
|
||||
|
||||
|
||||
How we use Git branches
|
||||
=======================
|
||||
|
||||
|
@ -363,46 +346,6 @@ macro, as in:
|
|||
if (BUG(ptr == NULL))
|
||||
return -1;
|
||||
|
||||
Allocator conventions
|
||||
---------------------
|
||||
|
||||
By convention, any tor type with a name like `abc_t` should be allocated
|
||||
by a function named `abc_new()`. This function should never return
|
||||
NULL.
|
||||
|
||||
Also, a type named `abc_t` should be freed by a function named `abc_free_()`.
|
||||
Don't call this `abc_free_()` function directly -- instead, wrap it in a
|
||||
macro called `abc_free()`, using the `FREE_AND_NULL` macro:
|
||||
|
||||
void abc_free_(abc_t *obj);
|
||||
#define abc_free(obj) FREE_AND_NULL(abc_t, abc_free_, (obj))
|
||||
|
||||
This macro will free the underlying `abc_t` object, and will also set
|
||||
the object pointer to NULL.
|
||||
|
||||
You should define all `abc_free_()` functions to accept NULL inputs:
|
||||
|
||||
void
|
||||
abc_free_(abc_t *obj)
|
||||
{
|
||||
if (!obj)
|
||||
return;
|
||||
tor_free(obj->name);
|
||||
thing_free(obj->thing);
|
||||
tor_free(obj);
|
||||
}
|
||||
|
||||
If you need a free function that takes a `void *` argument (for example,
|
||||
to use it as a function callback), define it with a name like
|
||||
`abc_free_void()`:
|
||||
|
||||
static void
|
||||
abc_free_void_(void *obj)
|
||||
{
|
||||
abc_free_(obj);
|
||||
}
|
||||
|
||||
|
||||
Doxygen comment conventions
|
||||
---------------------------
|
||||
|
||||
|
@ -434,4 +377,3 @@ the functions that call your function rely on it doing something, then your
|
|||
function should mention that it does that something in the documentation. If
|
||||
you rely on a function doing something beyond what is in its documentation,
|
||||
then you should watch out, or it might do something else later.
|
||||
|
||||
|
|
|
@ -54,53 +54,13 @@ If you have any external modules as dependencies (e.g. `extern crate
|
|||
libc;`), you MUST declare them in your crate's `lib.rs` and NOT in any
|
||||
other module.
|
||||
|
||||
Dependencies and versions
|
||||
---------------------------
|
||||
Dependencies
|
||||
--------------
|
||||
|
||||
In general, we use modules from only the Rust standard library
|
||||
whenever possible. We will review including external crates on a
|
||||
case-by-case basis.
|
||||
|
||||
If a crate only contains traits meant for compatibility between Rust
|
||||
crates, such as [the digest crate](https://crates.io/crates/digest) or
|
||||
[the failure crate](https://crates.io/crates/failure), it is very likely
|
||||
permissible to add it as a dependency. However, a brief review should
|
||||
be conducted as to the usefulness of implementing external traits
|
||||
(i.e. how widespread is the usage, how many other crates either
|
||||
implement the traits or have trait bounds based upon them), as well as
|
||||
the stability of the traits (i.e. if the trait is going to change, we'll
|
||||
potentially have to re-do all our implementations of it).
|
||||
|
||||
For large external libraries, especially which implement features which
|
||||
would be labour-intensive to reproduce/maintain ourselves, such as
|
||||
cryptographic or mathematical/statistics libraries, only crates which
|
||||
have stabilised to 1.0.0 should be considered, however, again, we may
|
||||
make exceptions on a case-by-case basis.
|
||||
|
||||
Currently, Tor requires that you use the latest stable Rust version. At
|
||||
some point in the future, we will freeze on a given stable Rust version,
|
||||
to ensure backward compatibility with stable distributions that ship it.
|
||||
|
||||
Updating/Adding Dependencies
|
||||
------------------------------
|
||||
|
||||
To add/remove/update dependencies, first add your dependencies,
|
||||
exactly specifying their versions, into the appropriate *crate-level*
|
||||
`Cargo.toml` in `src/rust/` (i.e. *not* `/src/rust/Cargo.toml`, but
|
||||
instead the one for your crate). Also, investigate whether your
|
||||
dependency has any optional dependencies which are unnecessary but are
|
||||
enabled by default. If so, you'll likely be able to enable/disable
|
||||
them via some feature, e.g.:
|
||||
|
||||
```toml
|
||||
[dependencies]
|
||||
foo = { version = "1.0.0", default-features = false }
|
||||
```
|
||||
|
||||
Next, run `/scripts/maint/updateRustDependencies.sh`. Then, go into
|
||||
`src/ext/rust` and commit the changes to the `tor-rust-dependencies`
|
||||
repo.
|
||||
|
||||
Documentation
|
||||
---------------
|
||||
|
||||
|
@ -324,26 +284,12 @@ Here are some additional bits of advice and rules:
|
|||
}
|
||||
}
|
||||
|
||||
3. Pass only C-compatible primitive types and bytes over the boundary
|
||||
3. Pass only integer types and bytes over the boundary
|
||||
|
||||
Rust's C-compatible primitive types are integers and floats.
|
||||
These types are declared in the [libc crate](https://doc.rust-lang.org/libc/x86_64-unknown-linux-gnu/libc/index.html#types).
|
||||
Most Rust objects have different [representations](https://doc.rust-lang.org/libc/x86_64-unknown-linux-gnu/libc/index.html#types)
|
||||
in C and Rust, so they can't be passed using FFI.
|
||||
|
||||
Tor currently uses the following Rust primitive types from libc for FFI:
|
||||
* defined-size integers: `uint32_t`
|
||||
* native-sized integers: `c_int`
|
||||
* native-sized floats: `c_double`
|
||||
* native-sized raw pointers: `* c_void`, `* c_char`, `** c_char`
|
||||
|
||||
TODO: C smartlist to Stringlist conversion using FFI
|
||||
|
||||
The only non-primitive type which may cross the FFI boundary is
|
||||
The only non-integer type which may cross the FFI boundary is
|
||||
bytes, e.g. `&[u8]`. This SHOULD be done on the Rust side by
|
||||
passing a pointer (`*mut libc::c_char`). The length can be passed
|
||||
explicitly (`libc::size_t`), or the string can be NUL-byte terminated
|
||||
C string.
|
||||
passing a pointer (`*mut libc::c_char`) and a length
|
||||
(`libc::size_t`).
|
||||
|
||||
One might be tempted to do this via doing
|
||||
`CString::new("blah").unwrap().into_raw()`. This has several problems:
|
||||
|
|
|
@ -9,19 +9,17 @@ Please read or review our documentation on Rust coding standards
|
|||
(`.../doc/HACKING/CodingStandardsRust.md`) before doing anything.
|
||||
|
||||
Please also read
|
||||
[the Rust Code of Conduct](https://www.rust-lang.org/en-US/conduct.html). We
|
||||
aim to follow the good example set by the Rust community and be
|
||||
excellent to one another. Let's be careful with each other, so we can
|
||||
be memory-safe together!
|
||||
[the Rust Code of Conduct](https://www.rust-lang.org/en-US/conduct.html). We aim
|
||||
to follow the good example set by the Rust community and be excellent to one
|
||||
another. Let's be careful with each other, so we can be memory-safe together!
|
||||
|
||||
Next, please contact us before rewriting anything! Rust in Tor is still
|
||||
an experiment. It is an experiment that we very much want to see
|
||||
succeed, so we're going slowly and carefully. For the moment, it's also
|
||||
a completely volunteer-driven effort: while many, if not most, of us are
|
||||
paid to work on Tor, we are not yet funded to write Rust code for Tor.
|
||||
Please be patient with the other people who are working on getting more
|
||||
Rust code into Tor, because they are graciously donating their free time
|
||||
to contribute to this effort.
|
||||
Next, please contact us before rewriting anything! Rust in Tor is still an
|
||||
experiment. It is an experiment that we very much want to see succeed, so we're
|
||||
going slowly and carefully. For the moment, it's also a completely
|
||||
volunteer-driven effort: while many, if not most, of us are paid to work on Tor,
|
||||
we are not yet funded to write Rust code for Tor. Please be patient with the
|
||||
other people who are working on getting more Rust code into Tor, because they
|
||||
are graciously donating their free time to contribute to this effort.
|
||||
|
||||
Resources for learning Rust
|
||||
-----------------------------
|
||||
|
@ -35,15 +33,14 @@ Rust immediately, without waiting for anything to install, there is
|
|||
|
||||
**Advanced resources**
|
||||
|
||||
If you're interested in playing with various Rust compilers and viewing
|
||||
a very nicely displayed output of the generated assembly, there is
|
||||
If you're interested in playing with various Rust compilers and viewing a very
|
||||
nicely displayed output of the generated assembly, there is
|
||||
[the Godbolt compiler explorer](https://rust.godbolt.org/)
|
||||
|
||||
For learning how to write unsafe Rust, read
|
||||
[The Rustonomicon](https://doc.rust-lang.org/nomicon/).
|
||||
|
||||
For learning everything you ever wanted to know about Rust macros, there
|
||||
is
|
||||
For learning everything you ever wanted to know about Rust macros, there is
|
||||
[The Little Book of Rust Macros](https://danielkeep.github.io/tlborm/book/index.html).
|
||||
|
||||
For learning more about FFI and Rust, see Jake Goulding's
|
||||
|
@ -52,10 +49,10 @@ For learning more about FFI and Rust, see Jake Goulding's
|
|||
Compiling Tor with Rust enabled
|
||||
---------------------------------
|
||||
|
||||
You will need to run the `configure` script with the `--enable-rust`
|
||||
flag to explicitly build with Rust. Additionally, you will need to
|
||||
specify where to fetch Rust dependencies, as we allow for either
|
||||
fetching dependencies from Cargo or specifying a local directory.
|
||||
You will need to run the `configure` script with the `--enable-rust` flag to
|
||||
explicitly build with Rust. Additionally, you will need to specify where to
|
||||
fetch Rust dependencies, as we allow for either fetching dependencies from Cargo
|
||||
or specifying a local directory.
|
||||
|
||||
**Fetch dependencies from Cargo**
|
||||
|
||||
|
@ -63,48 +60,48 @@ fetching dependencies from Cargo or specifying a local directory.
|
|||
|
||||
**Using a local dependency cache**
|
||||
|
||||
**NOTE**: local dependency caches which were not *originally* created via
|
||||
`--enable-cargo-online-mode` are broken. See https://bugs.torproject.org/22907
|
||||
|
||||
To specify a local directory:
|
||||
|
||||
RUST_DEPENDENCIES='path_to_dependencies_directory' ./configure --enable-rust
|
||||
|
||||
(Note that RUST_DEPENDENCIES must be the full path to the directory; it cannot
|
||||
be relative.)
|
||||
|
||||
You'll need the following Rust dependencies (as of this writing):
|
||||
|
||||
libc==0.2.39
|
||||
libc==0.2.22
|
||||
|
||||
We vendor our Rust dependencies in a separate repo using
|
||||
[cargo-vendor](https://github.com/alexcrichton/cargo-vendor). To use
|
||||
them, do:
|
||||
To get them, do:
|
||||
|
||||
git submodule init
|
||||
git submodule update
|
||||
|
||||
To specify the local directory containing the dependencies, (assuming
|
||||
you are in the top level of the repository) configure tor with:
|
||||
|
||||
TOR_RUST_DEPENDENCIES='path_to_dependencies_directory' ./configure --enable-rust
|
||||
|
||||
(Note that TOR_RUST_DEPENDENCIES must be the full path to the directory; it
|
||||
cannot be relative.)
|
||||
|
||||
Assuming you used the above `git submodule` commands and you're in the
|
||||
topmost directory of the repository, this would be:
|
||||
|
||||
TOR_RUST_DEPENDENCIES=`pwd`/src/ext/rust/crates ./configure --enable-rust
|
||||
mkdir path_to_dependencies_directory
|
||||
cd path_to_dependencies_directory
|
||||
git clone https://github.com/rust-lang/libc
|
||||
cd libc
|
||||
git checkout 0.2.22
|
||||
cargo package
|
||||
cd ..
|
||||
ln -s libc/target/package/libc-0.2.22 libc-0.2.22
|
||||
|
||||
|
||||
Identifying which modules to rewrite
|
||||
======================================
|
||||
|
||||
The places in the Tor codebase that are good candidates for porting to
|
||||
Rust are:
|
||||
The places in the Tor codebase that are good candidates for porting to Rust are:
|
||||
|
||||
1. loosely coupled to other Tor submodules,
|
||||
2. have high test coverage, and
|
||||
3. would benefit from being implemented in a memory safe language.
|
||||
|
||||
Help in either identifying places such as this, or working to improve
|
||||
existing areas of the C codebase by adding regression tests and
|
||||
simplifying dependencies, would be really helpful.
|
||||
Help in either identifying places such as this, or working to improve existing
|
||||
areas of the C codebase by adding regression tests and simplifying dependencies,
|
||||
would be really helpful.
|
||||
|
||||
Furthermore, as submodules in C are implemented in Rust, this is a good
|
||||
opportunity to refactor, add more tests, and split modules into smaller
|
||||
areas of responsibility.
|
||||
opportunity to refactor, add more tests, and split modules into smaller areas of
|
||||
responsibility.
|
||||
|
||||
A good first step is to build a module-level callgraph to understand how
|
||||
interconnected your target module is.
|
||||
|
@ -122,22 +119,11 @@ the module calls. Modules which call fewer other modules are better targets.
|
|||
|
||||
Strive to change the C API as little as possible.
|
||||
|
||||
We are currently targeting Rust nightly, *for now*. We expect this to
|
||||
change moving forward, as we understand more about which nightly
|
||||
features we need. It is on our TODO list to try to cultivate good
|
||||
standing with various distro maintainers of `rustc` and `cargo`, in
|
||||
order to ensure that whatever version we solidify on is readily
|
||||
available.
|
||||
|
||||
If parts of your Rust code needs to stay in sync with C code (such as
|
||||
handling enums across the FFI boundary), annonotate these places in a
|
||||
comment structured as follows:
|
||||
|
||||
/// C_RUST_COUPLED: <path_to_file> `<name_of_c_object>`
|
||||
|
||||
Where <name_of_c_object> can be an enum, struct, constant, etc. Then,
|
||||
do the same in the C code, to note that rust will need to be changed
|
||||
when the C does.
|
||||
We are currently targetting Rust nightly, *for now*. We expect this to change
|
||||
moving forward, as we understand more about which nightly features we need. It
|
||||
is on our TODO list to try to cultivate good standing with various distro
|
||||
maintainers of `rustc` and `cargo`, in order to ensure that whatever version we
|
||||
solidify on is readily available.
|
||||
|
||||
Adding your Rust module to Tor's build system
|
||||
-----------------------------------------------
|
||||
|
@ -146,22 +132,16 @@ when the C does.
|
|||
in the `.../tor/src/rust/` directory.
|
||||
1. Add your crate to `.../tor/src/rust/Cargo.toml`, in the
|
||||
`[workspace.members]` section.
|
||||
2. Add your crate's files to src/rust/include.am
|
||||
|
||||
If your crate should be available to C (rather than just being included as a
|
||||
dependency of other Rust modules):
|
||||
0. Declare the crate as a dependency of tor_rust in
|
||||
`src/rust/tor_util/Cargo.toml` and include it in
|
||||
`src/rust/tor_rust/lib.rs`
|
||||
2. Append your crate's static library to the `rust_ldadd` definition
|
||||
(underneath `if USE_RUST`) in `.../tor/Makefile.am`.
|
||||
|
||||
How to test your Rust code
|
||||
----------------------------
|
||||
|
||||
Everything should be tested full stop. Even non-public functionality.
|
||||
|
||||
Be sure to edit `.../tor/src/test/test_rust.sh` to add the name of your
|
||||
crate to the `crates` variable! This will ensure that `cargo test` is
|
||||
run on your crate.
|
||||
Be sure to edit `.../tor/src/test/test_rust.sh` to add the name of your crate to
|
||||
the `crates` variable! This will ensure that `cargo test` is run on your crate.
|
||||
|
||||
Configure Tor's build system to build with Rust enabled:
|
||||
|
||||
|
|
|
@ -4,22 +4,6 @@ Useful tools
|
|||
These aren't strictly necessary for hacking on Tor, but they can help track
|
||||
down bugs.
|
||||
|
||||
Travis CI
|
||||
---------
|
||||
It's CI. Looks like this: https://travis-ci.org/torproject/tor.
|
||||
|
||||
Runs automatically on Pull Requests sent to torproject/tor. You can set it up
|
||||
for your fork to build commits outside of PRs too:
|
||||
|
||||
1. sign up for GitHub: https://github.com/join
|
||||
2. fork https://github.com/torproject/tor:
|
||||
https://help.github.com/articles/fork-a-repo/
|
||||
3. follow https://docs.travis-ci.com/user/getting-started/#To-get-started-with-Travis-CI.
|
||||
skip steps involving `.travis.yml` (we already have one).
|
||||
|
||||
Builds should show up on the web at travis-ci.com and on IRC at #tor-ci on
|
||||
OFTC. If they don't, ask #tor-dev (also on OFTC).
|
||||
|
||||
Jenkins
|
||||
-------
|
||||
|
||||
|
|
|
@ -1,111 +0,0 @@
|
|||
# Modules in Tor #
|
||||
|
||||
This document describes the build system and coding standards when writing a
|
||||
module in Tor.
|
||||
|
||||
## What is a module? ##
|
||||
|
||||
In the context of the tor code base, a module is a subsystem that we can
|
||||
selectively enable or disable, at `configure` time.
|
||||
|
||||
Currently, there is only one module:
|
||||
|
||||
- Directory Authority subsystem (dirauth)
|
||||
|
||||
It is located in its own directory in `src/or/dirauth/`. To disable it, one
|
||||
need to pass `--disable-module-dirauth` at configure time. All modules are
|
||||
currently enabled by default.
|
||||
|
||||
## Build System ##
|
||||
|
||||
The changes to the build system are pretty straightforward.
|
||||
|
||||
1. Locate in the `configure.ac` file this define: `m4_define(MODULES`. It
|
||||
contains a list (white-space separated) of the module in tor. Add yours to
|
||||
the list.
|
||||
|
||||
2. Use the `AC_ARG_ENABLE([module-dirauth]` template for your new module. We
|
||||
use the "disable module" approach instead of enabling them one by one. So,
|
||||
by default, tor will build all the modules.
|
||||
|
||||
This will define the `HAVE_MODULE_<name>` statement which can be used in
|
||||
the C code to conditionally compile things for your module. And the
|
||||
`BUILD_MODULE_<name>` is also defined for automake files (e.g: include.am).
|
||||
|
||||
3. In the `src/or/include.am` file, locate the `MODULE_DIRAUTH_SOURCES` value.
|
||||
You need to create your own `_SOURCES` variable for your module and then
|
||||
conditionally add the it to `LIBTOR_A_SOURCES` if you should build the
|
||||
module.
|
||||
|
||||
It is then **very** important to add your SOURCES variable to
|
||||
`src_or_libtor_testing_a_SOURCES` so the tests can build it.
|
||||
|
||||
4. Do the same for header files, locate `ORHEADERS +=` which always add all
|
||||
headers of all modules so the symbol can be found for the module entry
|
||||
points.
|
||||
|
||||
Finally, your module will automatically be included in the
|
||||
`TOR_MODULES_ALL_ENABLED` variable which is used to build the unit tests. They
|
||||
always build everything in order to tests everything.
|
||||
|
||||
## Coding ##
|
||||
|
||||
As mentioned above, a module must be isolated in its own directory (name of
|
||||
the module) in `src/or/`.
|
||||
|
||||
There are couples of "rules" you want to follow:
|
||||
|
||||
* Minimize as much as you can the number of entry points into your module.
|
||||
Less is always better but of course that doesn't work out for every use
|
||||
case. However, it is a good thing to always keep that in mind.
|
||||
|
||||
* Do **not** use the `HAVE_MODULE_<name>` define outside of the module code
|
||||
base. Every entry point should have a second definition if the module is
|
||||
disabled. For instance:
|
||||
|
||||
```
|
||||
#ifdef HAVE_MODULE_DIRAUTH
|
||||
|
||||
int sr_init(int save_to_disk);
|
||||
|
||||
#else /* HAVE_MODULE_DIRAUTH */
|
||||
|
||||
static inline int
|
||||
sr_init(int save_to_disk)
|
||||
{
|
||||
(void) save_to_disk;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* HAVE_MODULE_DIRAUTH */
|
||||
|
||||
```
|
||||
|
||||
The main reason for this approach is to avoid having conditional code
|
||||
everywhere in the code base. It should be centralized as much as possible
|
||||
which helps maintainability but also avoids conditional spaghetti code
|
||||
making the code much more difficult to follow/understand.
|
||||
|
||||
* It is possible that you end up with code that needs to be used by the rest
|
||||
of the code base but is still part of your module. As a good example, if you
|
||||
look at `src/or/shared_random_client.c`: it contains code needed by the hidden
|
||||
service subsystem but mainly related to the shared random subsystem very
|
||||
specific to the dirauth module.
|
||||
|
||||
This is fine but try to keep it as lean as possible and never use the same
|
||||
filename as the one in the module. For example, this is a bad idea and
|
||||
should never be done:
|
||||
|
||||
- `src/or/shared_random.c`
|
||||
- `src/or/dirauth/shared_random.c`
|
||||
|
||||
* When you include headers from the module, **always** use the full module
|
||||
path in your statement. Example:
|
||||
|
||||
`#include "dirauth/dirvote.h"`
|
||||
|
||||
The main reason is that we do **not** add the module include path by default
|
||||
so it needs to be specified. But also, it helps our human brain understand
|
||||
which part comes from a module or not.
|
||||
|
||||
Even **in** the module itself, use the full include path like above.
|
|
@ -14,9 +14,6 @@ new Tor release:
|
|||
2. If this is going to be an important security release, give the packagers
|
||||
some advance warning: See this list of packagers in IV.3 below.
|
||||
|
||||
3. Given the release date for Tor, ask the TB team about the likely release
|
||||
date of a TB that contains it. See note below in "commit, upload,
|
||||
announce".
|
||||
|
||||
=== I. Make sure it works
|
||||
|
||||
|
@ -25,7 +22,6 @@ new Tor release:
|
|||
resolve those.
|
||||
|
||||
As applicable, merge the `maint-X` branch into the `release-X` branch.
|
||||
But you've been doing that all along, right?
|
||||
|
||||
2. Are all of the jenkins builders happy? See jenkins.torproject.org.
|
||||
|
||||
|
@ -34,7 +30,7 @@ new Tor release:
|
|||
|
||||
What about Coverity Scan?
|
||||
|
||||
What about clang scan-build?
|
||||
What about clan scan-build?
|
||||
|
||||
Does 'make distcheck' complain?
|
||||
|
||||
|
@ -138,9 +134,6 @@ new Tor release:
|
|||
either `make`, or `perl scripts/maint/updateVersions.pl`, depending on
|
||||
your version.)
|
||||
|
||||
When you merge the maint branch forward to the next maint branch, or into
|
||||
master, merge it with "-s ours" to avoid a needless version bump.
|
||||
|
||||
2. Make distcheck, put the tarball up in somewhere (how about your
|
||||
homedir on your homedir on people.torproject.org?) , and tell `#tor`
|
||||
about it. Wait a while to see if anybody has problems building it.
|
||||
|
@ -154,9 +147,6 @@ new Tor release:
|
|||
git tag -u <keyid> tor-0.3.x.y-status
|
||||
git push origin tag tor-0.3.x.y-status
|
||||
|
||||
(You must do this before you update the website: it relies on finding
|
||||
the version by tag.)
|
||||
|
||||
2. scp the tarball and its sig to the dist website, i.e.
|
||||
`/srv/dist-master.torproject.org/htdocs/` on dist-master. When you want
|
||||
it to go live, you run "static-update-component dist.torproject.org"
|
||||
|
@ -181,10 +171,7 @@ new Tor release:
|
|||
- {mike} at tig dot as
|
||||
- {tails-rm} at boum dot org
|
||||
- {simon} at sdeziel.info
|
||||
- {yuri} at freebsd.org
|
||||
- {mh+tor} at scrit.ch
|
||||
|
||||
Also, email tor-packagers@lists.torproject.org.
|
||||
- {yuri} at rawbw.com
|
||||
|
||||
4. Add the version number to Trac. To do this, go to Trac, log in,
|
||||
select "Admin" near the top of the screen, then select "Versions" from
|
||||
|
@ -193,11 +180,7 @@ new Tor release:
|
|||
0.2.2.23-alpha" (or whatever the version is), and we select the date as
|
||||
the date in the ChangeLog.
|
||||
|
||||
5. Double-check: did the version get recommended in the consensus yet? Is
|
||||
the website updated? If not, don't announce until they have the
|
||||
up-to-date versions, or people will get confused.
|
||||
|
||||
6. Mail the release blurb and ChangeLog to tor-talk (development release) or
|
||||
5. Mail the release blurb and ChangeLog to tor-talk (development release) or
|
||||
tor-announce (stable).
|
||||
|
||||
Post the changelog on the blog as well. You can generate a
|
||||
|
|
|
@ -6,7 +6,7 @@ tracing framework.
|
|||
|
||||
## Basics ###
|
||||
|
||||
Event tracing is separated in two concepts, trace events and a tracer. The
|
||||
Event tracing is seperated in two concepts, trace events and a tracer. The
|
||||
tracing subsystem can be found in `src/trace`. The `events.h` header file is
|
||||
the main file that maps the different tracers to trace events.
|
||||
|
||||
|
|
|
@ -1,98 +0,0 @@
|
|||
# Using `simpleperf` to collect CPU profiling on Android
|
||||
|
||||
This document describes how you can use Android's `simpleperf`
|
||||
command-line tool to get CPU profiling information from Tor via the
|
||||
Orbot application. The tool is particularly useful for Tor development
|
||||
because it is able to profile native applications on the platform
|
||||
whereas a lot of the normal tooling for the Android platform is only
|
||||
able to collect information from Java-based applications.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
Before using `simpleperf` there is a couple of steps that must be
|
||||
followed. You should make sure you have both a recent installation of
|
||||
the Android Software Development Kit (SDK) and Native Development Kit
|
||||
(NDK) installed. These can be found on the Android Developers website.
|
||||
|
||||
1. Follow the build instructions from the `BUILD` file in the Orbot
|
||||
repository and build an Orbot APK (Android Package) file with
|
||||
debugging enabled. Make sure that when you build the native content of
|
||||
the Orbot application that you run the `make -C external` command with
|
||||
an additional `DEBUG=1` as parameter to ensure that the Orbot build
|
||||
process does not strip the debug symbols from the Tor binary.
|
||||
|
||||
2. (Optional) Uninstall and clean-up your old Orbot installation that
|
||||
is most likely downloaded from Google's Play Store or via fdroid:
|
||||
|
||||
$ adb shell pm clear org.torproject.android
|
||||
$ adb uninstall org.torproject.android
|
||||
|
||||
3. Install the Android Package you generated in step 1:
|
||||
|
||||
$ adb install /path/to/your/app-fullperm-debug.apk
|
||||
|
||||
4. Check on your device that the newly installed Orbot actually works
|
||||
and behaves in the way you expect it to.
|
||||
|
||||
## Profiling using `simpleperf`
|
||||
|
||||
The `simpleperf` tool can be found in the `simpleperf/` directory in
|
||||
the directory where you installed the Android NDK to. In this
|
||||
directory there is a set of Python files that will help you deploy the
|
||||
tool to a device and collect the measurement data such that you can
|
||||
analyze the results on your computer rather than on your phone.
|
||||
|
||||
1. Change directory to the location of the `simpleperf` directory.
|
||||
2. Open the `app_profiler.config` file and change
|
||||
`app_package_name` to `org.torproject.android`, `apk_file_path` to
|
||||
the path of your Orbot Android Package (APK file).
|
||||
3. Optionally change the duration parameter in the `record_options`
|
||||
variable in `app_profiler.config` to the duration which you would like
|
||||
to collect samples in. The value is specified in seconds.
|
||||
4. Run the app profiler using `python app_profiler.py`. This helper
|
||||
script will push the `simpleperf` tool to your device, start the
|
||||
profiler, and once it has completed copy the generated `perf.data`
|
||||
file over to your computer with the results.
|
||||
|
||||
### Analyzing the results
|
||||
|
||||
You can inspect your resulting `perf.data` file via a simple GUI
|
||||
program `python report.py` or via the command-line tool `simpleperf
|
||||
report`. I've found the GUI tool to be easier to navigate around with
|
||||
than the command-line tool.
|
||||
|
||||
The `-g` option can be passed to the command line `simpleperf report`
|
||||
tool allows you to see the call graph of functions and how much time
|
||||
was spend on the call.
|
||||
|
||||
## Tips & Tricks
|
||||
|
||||
- When you have installed Orbot the first time, you will notice that
|
||||
if you get a shell on the Android device that there is no Tor binary
|
||||
available. This is because Orbot unpacks the Tor binary first time it
|
||||
is executed and places it under the `app_bin/` directory on the
|
||||
device.
|
||||
|
||||
To access binaries, `torrc` files, and other useful information on
|
||||
the device do the following:
|
||||
|
||||
$ adb shell
|
||||
(device):/ $ run-as org.torproject.android
|
||||
(device):/data/data/org.torproject.android $ ls
|
||||
app_bin app_data cache databases files lib shared_prefs
|
||||
|
||||
Descriptors, control authentication cookie, state, and other files can be
|
||||
found in the `app_data` directory. The `torrc` can be found in the `app_bin/`
|
||||
directory.
|
||||
|
||||
- You can enable logging in Tor via the syslog (or android) log
|
||||
mechanism with:
|
||||
|
||||
$ adb shell
|
||||
(device):/ $ run-as org.torproject.android
|
||||
(device):/data/data/org.torproject.android $ echo -e "\nLog info syslog" >> app_bin/torrc
|
||||
|
||||
Start Tor the normal way via Orbot and collect the logs from your computer using
|
||||
|
||||
$ adb logcat
|
||||
|
|
@ -35,15 +35,10 @@ EXTRA_DIST+= doc/asciidoc-helper.sh \
|
|||
doc/TUNING \
|
||||
doc/HACKING/README.1st.md \
|
||||
doc/HACKING/CodingStandards.md \
|
||||
doc/HACKING/CodingStandardsRust.md \
|
||||
doc/HACKING/Fuzzing.md \
|
||||
doc/HACKING/GettingStarted.md \
|
||||
doc/HACKING/GettingStartedRust.md \
|
||||
doc/HACKING/HelpfulTools.md \
|
||||
doc/HACKING/HowToReview.md \
|
||||
doc/HACKING/Module.md \
|
||||
doc/HACKING/ReleasingTor.md \
|
||||
doc/HACKING/Tracing.md \
|
||||
doc/HACKING/WritingTests.md
|
||||
|
||||
docdir = @docdir@
|
||||
|
|
844
doc/tor.1.txt
844
doc/tor.1.txt
File diff suppressed because it is too large
Load Diff
|
@ -9,7 +9,7 @@ FUZZERS = """
|
|||
hsdescv2
|
||||
hsdescv3
|
||||
http
|
||||
http-connect
|
||||
http-connect
|
||||
iptsv2
|
||||
microdesc
|
||||
vrs
|
||||
|
|
|
@ -3,8 +3,6 @@
|
|||
# Format:
|
||||
# [ IPv4[:DirPort] ] [ orport=<ORPort> ] [ id=<ID> ] ...
|
||||
# [ ipv6=<IPv6>[:<IPv6 ORPort>] ]
|
||||
# or use:
|
||||
# scripts/maint/generateFallbackDirLine.py fingerprint ...
|
||||
#
|
||||
# If a sufficiently specific group of attributes matches, the directory mirror
|
||||
# will be excluded: (each group is listed on its own line)
|
||||
|
@ -37,6 +35,14 @@
|
|||
62.210.207.124:9030 orport=9001 id=58938B1A5C4029B4415D38A4F36B7724273F4755 ipv6=[2001:bc8:31eb:100::1]:9001
|
||||
62.210.207.124:9130 orport=9101 id=338D0AB6DBAB7B529B9C91B2FD770658000693C4 ipv6=[2001:bc8:31eb:100::1]:9101
|
||||
|
||||
# these fallback candidates fail the consensus download test in a way that
|
||||
# causes stem to hang (and not respond to ^C, at least on OS X)
|
||||
# (Is something sending weird responses to DirPort traffic?)
|
||||
#217.23.14.190:1194
|
||||
#151.80.164.147:80
|
||||
#148.251.255.92:80
|
||||
#78.142.19.59:80
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
216.17.99.183:80 orport=443 id=D52CD431CEF28E01B11F545A84347EE45524BCA7
|
||||
216.17.99.183:8080 orport=9001 id=EE21F83AB6F76E3B3FFCBA5C2496F789CB84E7C6
|
||||
|
@ -68,6 +74,9 @@
|
|||
# Email sent directly to teor, verified using relay contact info
|
||||
185.21.216.140:9030 orport=9001 id=921DA852C95141F8964B359F774B35502E489869
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
62.210.82.44:143 orport=21 id=1C90D3AEADFF3BCD079810632C8B85637924A58E ipv6=[2001:bc8:3d7c::]:21
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
46.101.220.161:80 orport=443 id=7DDFE5B2C306B19A79832FBE581EAA245BAE90C6 ipv6=[2a03:b0c0:3:d0::8b:3001]:443
|
||||
|
||||
|
@ -191,12 +200,45 @@
|
|||
# Email sent directly to teor, verified using relay contact info
|
||||
88.190.208.4:30555 orport=30556 id=030A6EB24725C05D8E0FCE21923CBA5223E75E0E
|
||||
|
||||
# Fallback was on 0.2.8.2-alpha list, but changed fingerprint before 0.2.8.5
|
||||
46.101.102.71:80 orport=443 id=9504CB22EEB25D344DE63CB7A6F2C46F895C3686 ipv6=[2a03:b0c0:3:d0::2ed:7001]:9050
|
||||
# Also blacklist anything with the new fingerprint
|
||||
id=9C8A123081EFBE022EF795630F447839DDFDDDEC
|
||||
|
||||
# Fallbacks were on 0.2.8.2-alpha list, but downloads were slow before 0.2.8.5
|
||||
185.96.88.29:80 orport=443 id=86C281AD135058238D7A337D546C902BE8505DDE
|
||||
178.62.36.64:9030 orport=9001 id=B87C84E38DAECFFFFDE98E5AEE5786AFDC748F2C
|
||||
|
||||
# Fallback was on 0.2.8.2-alpha list, but changed address before 0.2.8.5
|
||||
84.219.173.60:9030 orport=443 id=855BC2DABE24C861CD887DB9B2E950424B49FC34
|
||||
# Also blacklist anything with the new address
|
||||
84.216.235.55:9030 orport=443
|
||||
|
||||
# Fallbacks were on 0.2.8.2-alpha list, but disappeared before 0.2.8.5
|
||||
81.7.17.171:80 orport=443 id=CFECDDCA990E3EF7B7EC958B22441386B6B8D820 ipv6=[2a02:180:1:1::517:11ab]:443
|
||||
51.254.215.121:80 orport=443 id=262B66AD25C79588AD1FC8ED0E966395B47E5C1D
|
||||
185.100.85.138:80 orport=46356 id=5C4DF16A0029CC4F67D3E127356E68F219269859
|
||||
|
||||
# Fallback was on 0.2.8.2-alpha list, but opted-out before 0.2.8.6
|
||||
37.187.1.149:9030 orport=9001 id=08DC0F3C6E3D9C527C1FC8745D35DD1B0DE1875D ipv6=[2001:41d0:a:195::1]:9001
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
195.154.15.227:9030 orport=9001 id=6C3E3AB2F5F03CD71B637D433BAD924A1ECC5796
|
||||
|
||||
# Fallback was on 0.2.8.6 list, but changed IPv4 before 0.2.9
|
||||
195.154.8.111:80 orport=443 id=FCB6695F8F2DC240E974510A4B3A0F2B12AB5B64
|
||||
# Same operator, not on 0.2.8.6 list, also changed IPv4
|
||||
51.255.235.246:80 orport=443 id=9B99C72B02AF8E3E5BE3596964F9CACD0090D132
|
||||
|
||||
# Fallback was on 0.2.8.6 list, but changed IPv4 before 0.2.9
|
||||
5.175.233.86:80 orport=443 id=5525D0429BFE5DC4F1B0E9DE47A4CFA169661E33
|
||||
|
||||
# Fallbacks were on 0.2.8.6 list, but went down before 0.2.9
|
||||
194.150.168.79:11112 orport=11111 id=29F1020B94BE25E6BE1AD13E93CE19D2131B487C
|
||||
94.126.23.174:9030 orport=9001 id=6FC6F08270D565BE89B7C819DD8E2D487397C073
|
||||
195.191.233.221:80 orport=443 id=DE134FC8E5CC4EC8A5DE66934E70AC9D70267197
|
||||
176.31.180.157:143 orport=22 id=E781F4EC69671B3F1864AE2753E0890351506329 ipv6=[2001:41d0:8:eb9d::1]:22
|
||||
|
||||
# Fallback was on 0.2.8.6 list, but opted-out before 0.2.9
|
||||
144.76.73.140:9030 orport=9001 id=6A640018EABF3DA9BAD9321AA37C2C87BBE1F907
|
||||
|
||||
|
@ -214,6 +256,9 @@
|
|||
# Email sent directly to teor, verified using relay contact info
|
||||
104.243.35.196:9030 orport=9001 id=FA3415659444AE006E7E9E5375E82F29700CFDFD
|
||||
|
||||
# Relay changed IPv4 address, operator uncontactable
|
||||
138.201.130.32:9030 orport=9001 id=52AEA31188331F421B2EDB494DB65CD181E5B257
|
||||
|
||||
# Emails sent directly to teor, verified using relay contact info
|
||||
217.12.199.208:80 orport=443 id=DF3AED4322B1824BF5539AE54B2D1B38E080FF05 ipv6=[2a02:27a8:0:2::7e]:443
|
||||
|
||||
|
@ -224,9 +269,6 @@
|
|||
# Email sent directly to teor, verified using relay contact info
|
||||
5.35.251.247:9030 orport=9001 id=9B1F5187DFBA89DC24B37EA7BF896C12B43A27AE
|
||||
|
||||
#https://lists.torproject.org/pipermail/tor-relays/2017-May/012281.html
|
||||
#https://lists.torproject.org/pipermail/tor-relays/2017-May/012281.html
|
||||
62.210.124.124:9030 orport=9001 id=86E78DD3720C78DA8673182EF96C54B162CD660C ipv6=[2001:bc8:3f23:100::1]:9001
|
||||
62.210.124.124:9130 orport=9101 id=2EBD117806EE43C3CC885A8F1E4DC60F207E7D3E ipv6=[2001:bc8:3f23:100::1]:9101
|
||||
|
||||
# Email sent directly to teor
|
||||
212.51.156.193:995 orport=110 id=32E7AAF1F602814D699BEF6761AD03E387758D49 ipv6=[2a02:168:4a01::49]:110
|
||||
|
|
|
@ -2,8 +2,6 @@
|
|||
#
|
||||
# Format:
|
||||
# IPv4:DirPort orport=<ORPort> id=<ID> [ ipv6=<IPv6>:<IPv6 ORPort> ]
|
||||
# or use:
|
||||
# scripts/maint/generateFallbackDirLine.py fingerprint ...
|
||||
#
|
||||
# All attributes must match for the directory mirror to be included.
|
||||
# If the fallback has an ipv6 key, the whitelist line must also have
|
||||
|
@ -30,9 +28,8 @@
|
|||
# <IPv4>:<DirPort> orport=<ORPort> id=<ID> [ ipv6=<IPv6>:<IPv6 ORPort> ]
|
||||
|
||||
# https://lists.torproject.org/pipermail/tor-relays/2015-December/008362.html
|
||||
# https://trac.torproject.org/projects/tor/ticket/22321#comment:22
|
||||
78.47.18.110:443 orport=80 id=F8D27B163B9247B232A2EEE68DD8B698695C28DE ipv6=[2a01:4f8:120:4023::110]:80 # fluxe3
|
||||
131.188.40.188:1443 orport=80 id=EBE718E1A49EE229071702964F8DB1F318075FF8 ipv6=[2001:638:a000:4140::ffff:188]:80 # fluxe4
|
||||
78.47.18.110:443 orport=80 id=F8D27B163B9247B232A2EEE68DD8B698695C28DE
|
||||
131.188.40.188:443 orport=80 id=EBE718E1A49EE229071702964F8DB1F318075FF8
|
||||
|
||||
# https://lists.torproject.org/pipermail/tor-relays/2015-December/008366.html
|
||||
5.39.88.19:9030 orport=9001 id=7CB8C31432A796731EA7B6BF4025548DFEB25E0C ipv6=[2001:41d0:8:9a13::1]:9050
|
||||
|
@ -55,21 +52,17 @@
|
|||
|
||||
# https://lists.torproject.org/pipermail/tor-relays/2015-December/008379.html
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
91.121.84.137:4951 orport=4051 id=6DE61A6F72C1E5418A66BFED80DFB63E4C77668F
|
||||
91.121.84.137:4952 orport=4052 id=9FBEB75E8BC142565F12CBBE078D63310236A334
|
||||
91.121.84.137:4951 orport=4051 id=6DE61A6F72C1E5418A66BFED80DFB63E4C77668F ipv6=[2001:41d0:1:8989::1]:4051
|
||||
91.121.84.137:4952 orport=4052 id=9FBEB75E8BC142565F12CBBE078D63310236A334 ipv6=[2001:41d0:1:8989::1]:4052
|
||||
|
||||
# https://lists.torproject.org/pipermail/tor-relays/2015-December/008381.html
|
||||
# Sent additional emails to teor with updated relays
|
||||
81.7.11.96:9030 orport=9001 id=8FA37B93397015B2BC5A525C908485260BE9F422 # Doedel22
|
||||
# 9F5068310818ED7C70B0BC4087AB55CB12CB4377 not found in current consensus
|
||||
178.254.19.101:80 orport=443 id=F9246DEF2B653807236DA134F2AEAB103D58ABFE # Freebird31
|
||||
178.254.19.101:9030 orport=9001 id=0C475BA4D3AA3C289B716F95954CAD616E50C4E5 # Freebird32
|
||||
81.7.14.253:9001 orport=443 id=1AE039EE0B11DB79E4B4B29CBA9F752864A0259E # Ichotolot60
|
||||
81.7.11.186:1080 orport=443 id=B86137AE9681701901C6720E55C16805B46BD8E3 # BeastieJoy60
|
||||
85.25.213.211:465 orport=80 id=CE47F0356D86CF0A1A2008D97623216D560FB0A8 # BeastieJoy61
|
||||
85.25.159.65:995 orport=80 id=52BFADA8BEAA01BA46C8F767F83C18E2FE50C1B9 # BeastieJoy63
|
||||
81.7.3.67:993 orport=443 id=A2E6BB5C391CD46B38C55B4329C35304540771F1 # BeastieJoy62
|
||||
81.7.14.31:9001 orport=443 id=7600680249A22080ECC6173FBBF64D6FCF330A61 # Ichotolot62
|
||||
# Sent additional email to teor with more relays
|
||||
178.254.44.135:9030 orport=9001 id=8FA37B93397015B2BC5A525C908485260BE9F422
|
||||
178.254.20.134:80 orport=443 id=9F5068310818ED7C70B0BC4087AB55CB12CB4377
|
||||
178.254.20.134:9030 orport=9001 id=2CE96A8A1DA032664C90F574AFFBECE18A6E8DFC
|
||||
178.254.44.135:80 orport=443 id=AE6A8C18E7499B586CD36246AC4BCAFFBBF93AB2
|
||||
178.254.13.126:80 orport=443 id=F9246DEF2B653807236DA134F2AEAB103D58ABFE
|
||||
178.254.13.126:9030 orport=9001 id=0C475BA4D3AA3C289B716F95954CAD616E50C4E5
|
||||
|
||||
# https://lists.torproject.org/pipermail/tor-relays/2015-December/008382.html
|
||||
51.255.33.237:9091 orport=9001 id=A360C21FA87FFA2046D92C17086A6B47E5C68109
|
||||
|
@ -104,9 +97,12 @@
|
|||
# Email sent directly to teor, verified using relay contact info
|
||||
171.25.193.77:80 orport=443 id=A10C4F666D27364036B562823E5830BC448E046A ipv6=[2001:67c:289c:3::77]:443
|
||||
171.25.193.78:80 orport=443 id=A478E421F83194C114F41E94F95999672AED51FE ipv6=[2001:67c:289c:3::78]:443
|
||||
171.25.193.131:80 orport=443 id=79861CF8522FC637EF046F7688F5289E49D94576
|
||||
171.25.193.20:80 orport=443 id=DD8BD7307017407FCC36F8D04A688F74A0774C02 ipv6=[2001:67c:289c::20]:443
|
||||
# same machine as DD8BD7307017407FCC36F8D04A688F74A0774C02
|
||||
171.25.193.25:80 orport=443 id=185663B7C12777F052B2C2D23D7A239D8DA88A0F ipv6=[2001:67c:289c::25]:443
|
||||
# OK, but same machine as 79861CF8522FC637EF046F7688F5289E49D94576
|
||||
#171.25.193.132:80 orport=443 id=01C67E0CA8F97111E652C7564CB3204361FFFAB8
|
||||
# OK, but same machine as DD8BD7307017407FCC36F8D04A688F74A0774C02
|
||||
#171.25.193.25:80 orport=443 id=185663B7C12777F052B2C2D23D7A239D8DA88A0F ipv6=[2001:67c:289c::25]:443
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
212.47.229.2:9030 orport=9001 id=20462CBA5DA4C2D963567D17D0B7249718114A68 ipv6=[2001:bc8:4400:2100::f03]:9001
|
||||
|
@ -114,12 +110,8 @@
|
|||
46.28.109.231:9030 orport=9001 id=F70B7C5CD72D74C7F9F2DC84FA9D20D51BA13610 ipv6=[2a02:2b88:2:1::4205:1]:9001
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
85.235.250.88:80 orport=443 id=72B2B12A3F60408BDBC98C6DF53988D3A0B3F0EE # TykRelay01
|
||||
185.96.88.29:80 orport=443 id=86C281AD135058238D7A337D546C902BE8505DDE # TykRelay051
|
||||
# This fallback opted-in in previous releases, then changed its details,
|
||||
# and so we blacklisted it. Now we want to whitelist changes.
|
||||
# Assume details update is permanent
|
||||
185.96.180.29:80 orport=443 id=F93D8F37E35C390BCAD9F9069E13085B745EC216 # TykRelay06
|
||||
85.235.250.88:80 orport=443 id=72B2B12A3F60408BDBC98C6DF53988D3A0B3F0EE
|
||||
185.96.180.29:80 orport=443 id=F93D8F37E35C390BCAD9F9069E13085B745EC216
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
185.11.180.67:80 orport=9001 id=794D8EA8343A4E820320265D05D4FA83AB6D1778
|
||||
|
@ -159,10 +151,9 @@
|
|||
109.163.234.8:80 orport=443 id=0818DAE0E2DDF795AEDEAC60B15E71901084F281
|
||||
109.163.234.9:80 orport=443 id=ABF7FBF389C9A747938B639B20E80620B460B2A9
|
||||
62.102.148.67:80 orport=443 id=4A0C3E177AF684581EF780981AEAF51A98A6B5CF
|
||||
# Assume details update is permanent
|
||||
77.247.181.166:80 orport=443 id=77131D7E2EC1CA9B8D737502256DA9103599CE51 # CriticalMass
|
||||
77.247.181.164:80 orport=443 id=204DFD2A2C6A0DC1FA0EACB495218E0B661704FD # HaveHeart
|
||||
77.247.181.162:80 orport=443 id=7BFB908A3AA5B491DA4CA72CCBEE0E1F2A939B55 # sofia
|
||||
77.247.181.162:80 orport=443 id=7BB160A8F54BD74F3DA5F2CE701E8772B841859D
|
||||
77.247.181.164:80 orport=443 id=10E13E340651D0EF66B4DEBF610B3C0981168107
|
||||
77.247.181.166:80 orport=443 id=06E123865C590189B3181114F23F0F13A7BC0E69
|
||||
|
||||
# https://twitter.com/biotimylated/status/718994247500718080
|
||||
212.47.252.149:9030 orport=9001 id=2CAC39BAA996791CEFAADC9D4754D65AF5EB77C0
|
||||
|
@ -214,19 +205,20 @@
|
|||
# Email sent directly to teor, verified using relay contact info
|
||||
89.187.142.208:80 orport=443 id=64186650FFE4469EBBE52B644AE543864D32F43C
|
||||
|
||||
# Email sent directly to teor
|
||||
# Assume details update is permanent
|
||||
212.51.134.123:9030 orport=9001 id=50586E25BE067FD1F739998550EDDCB1A14CA5B2 # Jans
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
212.51.134.123:9030 orport=9001 id=50586E25BE067FD1F739998550EDDCB1A14CA5B2 ipv6=[2a02:168:6e00:0:3a60:77ff:fe9c:8bd1]:9001
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
46.101.143.173:80 orport=443 id=F960DF50F0FD4075AC9B505C1D4FFC8384C490FB
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
217.79.190.25:9030 orport=9090 id=361D33C96D0F161275EE67E2C91EE10B276E778B
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
193.171.202.146:9030 orport=9001 id=01A9258A46E97FF8B2CAC7910577862C14F2C524
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
# Assume details update is permanent
|
||||
197.231.221.211:9030 orport=443 id=BC630CBBB518BE7E9F4E09712AB0269E9DC7D626 # IPredator
|
||||
197.231.221.211:9030 orport=9001 id=BC630CBBB518BE7E9F4E09712AB0269E9DC7D626
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
185.61.138.18:8080 orport=4443 id=2541759BEC04D37811C2209A88E863320271EC9C
|
||||
|
@ -237,7 +229,7 @@
|
|||
193.11.114.46:9032 orport=9003 id=B83DC1558F0D34353BB992EF93AFEAFDB226A73E
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
138.201.250.33:9012 orport=9011 id=2BA2C8E96B2590E1072AECE2BDB5C48921BF8510
|
||||
144.76.26.175:9012 orport=9011 id=2BA2C8E96B2590E1072AECE2BDB5C48921BF8510
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
37.221.162.226:9030 orport=9001 id=D64366987CB39F61AD21DBCF8142FA0577B92811
|
||||
|
@ -255,7 +247,7 @@
|
|||
134.119.3.164:9030 orport=9001 id=D1B8AAA98C65F3DF7D8BB3AF881CAEB84A33D8EE
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
173.212.254.192:31336 orport=31337 id=99E246DB480B313A3012BC3363093CC26CD209C7
|
||||
81.7.10.93:31336 orport=31337 id=99E246DB480B313A3012BC3363093CC26CD209C7
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
178.62.22.36:80 orport=443 id=A0766C0D3A667A3232C7D569DE94A28F9922FCB1 ipv6=[2a03:b0c0:1:d0::174:1]:9050
|
||||
|
@ -306,15 +298,14 @@
|
|||
46.148.18.74:8080 orport=443 id=6CACF0B5F03C779672F3C5C295F37C8D234CA3F7
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
37.187.102.108:80 orport=443 id=F4263275CF54A6836EE7BD527B1328836A6F06E1 ipv6=[2001:41d0:a:266c::1]:443 # EvilMoe
|
||||
212.47.241.21:80 orport=443 id=892F941915F6A0C6E0958E52E0A9685C190CF45C # EvilMoe
|
||||
37.187.102.108:9090 orport=5550 id=F4263275CF54A6836EE7BD527B1328836A6F06E1
|
||||
212.47.241.21:80 orport=443 id=892F941915F6A0C6E0958E52E0A9685C190CF45C
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
212.129.38.254:9030 orport=9001 id=FDF845FC159C0020E2BDDA120C30C5C5038F74B4
|
||||
|
||||
# Email sent directly to teor
|
||||
37.157.195.87:8030 orport=443 id=12FD624EE73CEF37137C90D38B2406A66F68FAA2 # thanatosCZ
|
||||
5.189.169.190:8030 orport=8080 id=8D79F73DCD91FC4F5017422FAC70074D6DB8DD81 # thanatosDE
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
37.157.195.87:8030 orport=443 id=12FD624EE73CEF37137C90D38B2406A66F68FAA2
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
37.187.7.74:80 orport=443 id=AEA43CB1E47BE5F8051711B2BF01683DB1568E05 ipv6=[2001:41d0:a:74a::1]:443
|
||||
|
@ -377,6 +368,14 @@
|
|||
# Email sent directly to teor, verified using relay contact info
|
||||
91.219.237.229:80 orport=443 id=1ECD73B936CB6E6B3CD647CC204F108D9DF2C9F7
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
212.47.240.10:82 orport=443 id=2A4C448784F5A83AFE6C78DA357D5E31F7989DEB
|
||||
# Ok, but on the same machine as 2A4C448784F5A83AFE6C78DA357D5E31F7989DEB
|
||||
#212.47.240.10:81 orport=993 id=72527E3242CB15AADE28374AE0D35833FC083F60
|
||||
163.172.131.88:80 orport=443 id=AD253B49E303C6AB1E048B014392AC569E8A7DAE ipv6=[2001:bc8:4400:2100::2:1009]:443
|
||||
# Ok, but on the same machine as AD253B49E303C6AB1E048B014392AC569E8A7DAE
|
||||
#163.172.131.88:81 orport=993 id=D5F3FB17504744FB7ECEF46F4B1D155258A6D942 ipv6=[2001:bc8:4400:2100::2:1009]:993
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
46.101.151.222:80 orport=443 id=1DBAED235E3957DE1ABD25B4206BE71406FB61F8
|
||||
178.62.60.37:80 orport=443 id=175921396C7C426309AB03775A9930B6F611F794
|
||||
|
@ -405,8 +404,8 @@
|
|||
# Email sent directly to teor, verified using relay contact info
|
||||
5.199.142.236:9030 orport=9001 id=F4C0EDAA0BF0F7EC138746F8FEF1CE26C7860265
|
||||
|
||||
# Email sent directly to teor
|
||||
188.166.133.133:9030 orport=9001 id=774555642FDC1E1D4FDF2E0C31B7CA9501C5C9C7 ipv6=[2a03:b0c0:2:d0::26c0:1]:9001 # dropsy
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
188.166.133.133:9030 orport=9001 id=774555642FDC1E1D4FDF2E0C31B7CA9501C5C9C7 ipv6=[2a03:b0c0:2:d0::5:f001]:9001
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
46.8.249.10:80 orport=443 id=31670150090A7C3513CB7914B9610E786391A95D
|
||||
|
@ -477,6 +476,9 @@
|
|||
# Email sent directly to teor, verified using relay contact info
|
||||
95.130.11.147:9030 orport=443 id=6B697F3FF04C26123466A5C0E5D1F8D91925967A
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
176.31.191.26:80 orport=443 id=7350AB9ED7568F22745198359373C04AC783C37C
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
128.199.55.207:9030 orport=9001 id=BCEF908195805E03E92CCFE669C48738E556B9C5 ipv6=[2a03:b0c0:2:d0::158:3001]:9001
|
||||
|
||||
|
@ -495,8 +497,8 @@
|
|||
# Email sent directly to teor, verified using relay contact info
|
||||
185.97.32.18:9030 orport=9001 id=04250C3835019B26AA6764E85D836088BE441088
|
||||
|
||||
# Email sent directly to teor
|
||||
149.56.45.200:9030 orport=9001 id=FE296180018833AF03A8EACD5894A614623D3F76 ipv6=[2607:5300:201:3000::17d3]:9002 # PiotrTorpotkinOne
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
149.56.45.200:9030 orport=9001 id=FE296180018833AF03A8EACD5894A614623D3F76
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
81.2.209.10:443 orport=80 id=B6904ADD4C0D10CDA7179E051962350A69A63243 ipv6=[2001:15e8:201:1::d10a]:80
|
||||
|
@ -534,8 +536,8 @@
|
|||
# Email sent directly to teor, verified using relay contact info
|
||||
212.238.208.48:9030 orport=9001 id=F406219CDD339026D160E53FCA0EF6857C70F109 ipv6=[2001:984:a8fb:1:ba27:ebff:feac:c109]:9001
|
||||
|
||||
# Email sent directly to teor
|
||||
176.158.236.102:9030 orport=9001 id=DC163DDEF4B6F0C6BC226F9F6656A5A30C5C5686 # Underworld
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
176.158.132.12:9030 orport=9001 id=DC163DDEF4B6F0C6BC226F9F6656A5A30C5C5686
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
91.229.20.27:9030 orport=9001 id=9A0D54D3A6D2E0767596BF1515E6162A75B3293F
|
||||
|
@ -543,8 +545,8 @@
|
|||
# Email sent directly to teor, verified using relay contact info
|
||||
80.127.137.19:80 orport=443 id=6EF897645B79B6CB35E853B32506375014DE3621 ipv6=[2001:981:47c1:1::6]:443
|
||||
|
||||
# Email sent directly to teor
|
||||
163.172.138.22:80 orport=443 id=16102E458460349EE45C0901DAA6C30094A9BBEA ipv6=[2001:bc8:4400:2100::1:3]:443 # mkultra
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
163.172.138.22:80 orport=443 id=8664DC892540F3C789DB37008236C096C871734D ipv6=[2001:bc8:4400:2100::1:3]:443
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
97.74.237.196:9030 orport=9001 id=2F0F32AB1E5B943CA7D062C03F18960C86E70D94
|
||||
|
@ -578,8 +580,7 @@
|
|||
167.114.113.48:9030 orport=403 id=2EC0C66EA700C44670444280AABAB1EC78B722A0
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
# Assume details update is permanent
|
||||
213.141.138.174:9030 orport=9001 id=BD552C165E2ED2887D3F1CCE9CFF155DDA2D86E6 # Schakalium
|
||||
79.120.16.42:9030 orport=9001 id=BD552C165E2ED2887D3F1CCE9CFF155DDA2D86E6
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
95.128.43.164:80 orport=443 id=616081EC829593AF4232550DE6FFAA1D75B37A90 ipv6=[2a02:ec0:209:10::4]:443
|
||||
|
@ -608,13 +609,10 @@
|
|||
# Email sent directly to teor, verified using relay contact info
|
||||
31.31.78.49:80 orport=443 id=46791D156C9B6C255C2665D4D8393EC7DBAA7798
|
||||
|
||||
# Email sent directly to teor
|
||||
192.160.102.169:80 orport=9001 id=C0192FF43E777250084175F4E59AC1BA2290CE38 ipv6=[2620:132:300c:c01d::9]:9002 # manipogo
|
||||
192.160.102.166:80 orport=9001 id=547DA56F6B88B6C596B3E3086803CDA4F0EF8F21 ipv6=[2620:132:300c:c01d::6]:9002 # chaucer
|
||||
192.160.102.170:80 orport=9001 id=557ACEC850F54EEE65839F83CACE2B0825BE811E ipv6=[2620:132:300c:c01d::a]:9002 # ogopogo
|
||||
192.160.102.164:80 orport=9001 id=823AA81E277F366505545522CEDC2F529CE4DC3F ipv6=[2620:132:300c:c01d::4]:9002 # snowfall
|
||||
192.160.102.165:80 orport=9001 id=C90CA3B7FE01A146B8268D56977DC4A2C024B9EA ipv6=[2620:132:300c:c01d::5]:9002 # cowcat
|
||||
192.160.102.168:80 orport=9001 id=F6A358DD367B3282D6EF5824C9D45E1A19C7E815 ipv6=[2620:132:300c:c01d::8]:9002 # prawksi
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
96.47.231.214:9030 orport=8080 id=F843CB5729575D76FF1FFBB2179BDCF52C0C6387
|
||||
192.99.246.48:9030 orport=9001 id=CD6B149BED1BB254EF6DFF9D75DDB11E7F8A38A4 ipv6=[2607:5300:100:200::de3]:9002
|
||||
192.160.102.164:80 orport=9001 id=823AA81E277F366505545522CEDC2F529CE4DC3F ipv6=[2605:e200:d00c:c01d::1111]:9002
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
136.243.214.137:80 orport=443 id=B291D30517D23299AD7CEE3E60DFE60D0E3A4664
|
||||
|
@ -625,8 +623,8 @@
|
|||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
192.87.28.28:9030 orport=9001 id=ED2338CAC2711B3E331392E1ED2831219B794024
|
||||
# same machine as ED2338CAC2711B3E331392E1ED2831219B794024
|
||||
192.87.28.82:9030 orport=9001 id=844AE9CAD04325E955E2BE1521563B79FE7094B7
|
||||
# OK, but same machine as ED2338CAC2711B3E331392E1ED2831219B794024
|
||||
#192.87.28.82:9030 orport=9001 id=844AE9CAD04325E955E2BE1521563B79FE7094B7
|
||||
|
||||
# https://twitter.com/kosjoli/status/719507270904758272
|
||||
85.10.202.87:9030 orport=9001 id=971AFB23C168DCD8EDA17473C1C452B359DE3A5A
|
||||
|
@ -682,8 +680,7 @@
|
|||
213.239.217.18:1338 orport=1337 id=C37BC191AC389179674578C3E6944E925FE186C2 ipv6=[2a01:4f8:a0:746a:101:1:1:1]:1337
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
# Assume details update is permanent
|
||||
188.40.128.246:9030 orport=9001 id=AD19490C7DBB26D3A68EFC824F67E69B0A96E601 ipv6=[2a01:4f8:221:1ac1:dead:beef:7005:9001]:9001 # sputnik
|
||||
188.40.128.246:9030 orport=9001 id=AD19490C7DBB26D3A68EFC824F67E69B0A96E601
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
88.198.253.13:9030 orport=9001 id=DF924196D69AAE3C00C115A9CCDF7BB62A175310 ipv6=[2a01:4f8:11a:b1f::2]:9001
|
||||
|
@ -701,44 +698,19 @@
|
|||
# Email sent directly to teor, verified using relay contact info
|
||||
107.170.101.39:9030 orport=443 id=30973217E70AF00EBE51797FF6D9AA720A902EAA
|
||||
|
||||
# Email sent directly to teor
|
||||
193.70.112.165:80 orport=443 id=F10BDE279AE71515DDCCCC61DC19AC8765F8A3CC # ParkBenchInd001
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
192.99.212.139:80 orport=443 id=F10BDE279AE71515DDCCCC61DC19AC8765F8A3CC
|
||||
|
||||
# Email sent directly to teor
|
||||
185.220.101.6:10006 orport=20006 id=C08DE49658E5B3CFC6F2A952B453C4B608C9A16A # niftyvolcanorabbit
|
||||
185.220.101.13:10013 orport=20013 id=71AB4726D830FAE776D74AEF790CF04D8E0151B4 # niftycottontail
|
||||
185.220.101.5:10005 orport=20005 id=1084200B44021D308EA4253F256794671B1D099A # niftyhedgehog
|
||||
185.220.101.9:10009 orport=20009 id=14877C6384A9E793F422C8D1DDA447CACA4F7C4B # niftywoodmouse
|
||||
185.220.101.8:10008 orport=20008 id=24E91955D969AEA1D80413C64FE106FAE7FD2EA9 # niftymouse
|
||||
185.220.101.1:10001 orport=20001 id=28F4F392F8F19E3FBDE09616D9DB8143A1E2DDD3 # niftycottonmouse
|
||||
185.220.101.21:10021 orport=20021 id=348B89013EDDD99E4755951D1EC284D9FED71226 # niftysquirrel
|
||||
185.220.101.10:10010 orport=20010 id=4031460683AE9E0512D3620C2758D98758AC6C93 # niftyeuropeanrabbit
|
||||
185.220.101.34:10034 orport=20034 id=47C42E2094EE482E7C9B586B10BABFB67557030B # niftyquokka
|
||||
185.220.101.18:10018 orport=20018 id=5D5006E4992F2F97DF4F8B926C3688870EB52BD8 # niftyplagiodontia
|
||||
185.220.101.28:10028 orport=20028 id=609E598FB6A00BCF7872906B602B705B64541C50 # niftychipmunk
|
||||
185.220.101.20:10020 orport=20020 id=619349D82424C601CAEB94161A4CF778993DAEE7 # niftytucotuco
|
||||
185.220.101.17:10017 orport=20017 id=644DECC5A1879C0FE23DE927DD7049F58BBDF349 # niftyhutia
|
||||
185.220.101.0:10000 orport=20000 id=6E94866ED8CA098BACDFD36D4E8E2B459B8A734E # niftybeaver
|
||||
185.220.101.30:10030 orport=20030 id=71CFDEB4D9E00CCC3E31EC4E8A29E109BBC1FB36 # niftypedetidae
|
||||
185.220.101.29:10029 orport=20029 id=7DC52AE6667A30536BA2383CD102CFC24F20AD71 # niftyllipika
|
||||
185.220.101.41:10041 orport=20041 id=7E281CD2C315C4F7A84BC7C8721C3BC974DDBFA3 # niftyporcupine
|
||||
185.220.101.25:10025 orport=20025 id=8EE0534532EA31AA5172B1892F53B2F25C76EB02 # niftyjerboa
|
||||
185.220.101.33:10033 orport=20033 id=906DCB390F2BA987AE258D745E60BAAABAD31DE8 # niftyquokka
|
||||
185.220.101.26:10026 orport=20026 id=92A6085EABAADD928B6F8E871540A1A41CBC08BA # niftypedetes
|
||||
185.220.101.40:10040 orport=20040 id=9A857254F379194D1CD76F4A79A20D2051BEDA3F # niftynutria
|
||||
185.220.101.42:10042 orport=20042 id=9B816A5B3EB20B8E4E9B9D1FBA299BD3F40F0320 # niftypygmyjerboa
|
||||
185.220.101.2:10002 orport=20002 id=B740BCECC4A9569232CDD45C0E1330BA0D030D33 # niftybunny
|
||||
185.220.101.32:10032 orport=20032 id=B771AA877687F88E6F1CA5354756DF6C8A7B6B24 # niftypika
|
||||
185.220.101.12:10012 orport=20012 id=BC82F2190DE2E97DE65F49B4A95572374BDC0789 # niftycapybara
|
||||
185.220.101.22:10022 orport=20022 id=CA37CD46799449D83B6B98B8C22C649906307888 # niftyjackrabbit
|
||||
185.220.101.4:10004 orport=20004 id=CDA2EA326E2272C57ACB26773D7252C211795B78 # niftygerbil
|
||||
185.220.101.14:10014 orport=20014 id=E7EBA5D8A4E09684D11A1DF24F75362817333768 # niftyhare
|
||||
185.220.101.16:10016 orport=20016 id=EC1997D51892E4607C68E800549A1E7E4694005A # niftyguineapig
|
||||
185.220.101.24:10024 orport=20024 id=FDA70EC93DB01E3CB418CB6943B0C68464B18B4C # niftyrat
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
163.172.35.249:80 orport=443 id=C08DE49658E5B3CFC6F2A952B453C4B608C9A16A
|
||||
163.172.35.247:80 orport=443 id=71AB4726D830FAE776D74AEF790CF04D8E0151B4
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
64.113.32.29:9030 orport=9001 id=30C19B81981F450C402306E2E7CFB6C3F79CB6B2
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
212.51.156.193:995 orport=110 id=32E7AAF1F602814D699BEF6761AD03E387758D49 ipv6=[2a02:168:4a01::49]:110
|
||||
|
||||
# Emails sent directly to teor, verified using relay contact info
|
||||
51.254.101.242:9002 orport=9001 id=4CC9CC9195EC38645B699A33307058624F660CCF
|
||||
|
||||
|
@ -795,17 +767,17 @@
|
|||
178.33.183.251:80 orport=443 id=DD823AFB415380A802DCAEB9461AE637604107FB ipv6=[2001:41d0:2:a683::251]:443
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
31.185.104.19:80 orport=443 id=9EAD5B2D3DBD96DBC80DCE423B0C345E920A758D
|
||||
# same machine as 9EAD5B2D3DBD96DBC80DCE423B0C345E920A758D
|
||||
#31.185.104.19:80 orport=443 id=9EAD5B2D3DBD96DBC80DCE423B0C345E920A758D
|
||||
# OK, but on same machine as 9EAD5B2D3DBD96DBC80DCE423B0C345E920A758D
|
||||
31.185.104.20:80 orport=443 id=ADB2C26629643DBB9F8FE0096E7D16F9414B4F8D
|
||||
31.185.104.21:80 orport=443 id=C2AAB088555850FC434E68943F551072042B85F1
|
||||
31.185.104.22:80 orport=443 id=5BA3A52760A0EABF7E7C3ED3048A77328FF0F148
|
||||
#31.185.104.21:80 orport=443 id=C2AAB088555850FC434E68943F551072042B85F1
|
||||
#31.185.104.22:80 orport=443 id=5BA3A52760A0EABF7E7C3ED3048A77328FF0F148
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
185.34.60.114:80 orport=443 id=7F7A695DF6F2B8640A70B6ADD01105BC2EBC5135
|
||||
|
||||
# https://lists.torproject.org/pipermail/tor-relays/2017-December/013939.html
|
||||
94.142.242.84:80 orport=443 id=AA0D167E03E298F9A8CD50F448B81FBD7FA80D56 ipv6=[2a02:898:24:84::1]:443 # rejozenger
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
94.142.242.84:80 orport=443 id=AA0D167E03E298F9A8CD50F448B81FBD7FA80D56 ipv6=[2a02:898:24:84::1]:443
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
185.129.62.62:9030 orport=9001 id=ACDD9E85A05B127BA010466C13C8C47212E8A38F ipv6=[2a06:d380:0:3700::62]:9001
|
||||
|
@ -846,151 +818,12 @@
|
|||
# Email sent directly to teor, verified using relay contact info
|
||||
85.214.151.72:9030 orport=9001 id=722D365140C8C52DBB3C9FF6986E3CEFFE2BA812
|
||||
|
||||
# email sent directly to teor
|
||||
72.52.75.27:9030 orport=9001 id=8567AD0A6369ED08527A8A8533A5162AC00F7678 # piecoopdotnet
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
72.52.75.27:9030 orport=9001 id=1220F0F20E80D348244C5F3B6D126DAA0A446DFD
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
5.9.146.203:80 orport=443 id=1F45542A24A61BF9408F1C05E0DCE4E29F2CBA11
|
||||
5.9.159.14:9030 orport=9001 id=0F100F60C7A63BED90216052324D29B08CFCF797
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
# Assume details update is permanent
|
||||
5.9.147.226:9030 orport=9001 id=B0553175AADB0501E5A61FC61CEA3970BE130FF2 ipv6=[2a01:4f8:190:30e1::2]:9001 # zwiubel
|
||||
|
||||
# https://trac.torproject.org/projects/tor/ticket/22527#comment:1
|
||||
199.184.246.250:80 orport=443 id=1F6ABD086F40B890A33C93CC4606EE68B31C9556 ipv6=[2620:124:1009:1::171]:443
|
||||
|
||||
# https://trac.torproject.org/projects/tor/ticket/24695
|
||||
163.172.53.84:143 orport=21 id=1C90D3AEADFF3BCD079810632C8B85637924A58E ipv6=[2001:bc8:24f8::]:21 # Multivac
|
||||
|
||||
# Email sent directly to teor
|
||||
54.36.237.163:80 orport=443 id=DB2682153AC0CCAECD2BD1E9EBE99C6815807A1E # GermanCraft2
|
||||
|
||||
# Email sent directly to teor
|
||||
62.138.7.171:9030 orport=9001 id=9844B981A80B3E4B50897098E2D65167E6AEF127 # 0x3d004
|
||||
62.138.7.171:8030 orport=8001 id=9285B22F7953D7874604EEE2B470609AD81C74E9 # 0x3d005
|
||||
91.121.23.100:9030 orport=9001 id=3711E80B5B04494C971FB0459D4209AB7F2EA799 # 0x3d002
|
||||
91.121.23.100:8030 orport=8001 id=CFBBA0D858F02E40B1432A65F6D13C9BDFE7A46B # 0x3d001
|
||||
51.15.13.245:9030 orport=9001 id=CED527EAC230E7B56E5B363F839671829C3BA01B # 0x3d006
|
||||
51.15.13.245:8030 orport=8001 id=8EBB8D1CF48FE2AB95C451DA8F10DB6235F40F8A # 0x3d007
|
||||
|
||||
# Email sent directly to teor
|
||||
104.192.5.248:9030 orport=9001 id=BF735F669481EE1CCC348F0731551C933D1E2278 # Freeway11
|
||||
|
||||
# Email sent directly to teor
|
||||
# https://lists.torproject.org/pipermail/tor-relays/2017-December/013961.html
|
||||
178.17.174.14:9030 orport=9001 id=B06F093A3D4DFAD3E923F4F28A74901BD4F74EB1 # TorExitMoldova
|
||||
178.17.170.156:9030 orport=9001 id=41C59606AFE1D1AA6EC6EF6719690B856F0B6587 # TorExitMoldova2
|
||||
|
||||
# Email sent directly to teor
|
||||
163.172.221.44:59030 orport=59001 id=164604F5C86FC8CC9C0288BD9C02311958427597 # altego
|
||||
|
||||
# Email sent directly to teor
|
||||
46.38.237.221:9030 orport=9001 id=D30E9D4D639068611D6D96861C95C2099140B805 # mine
|
||||
|
||||
# https://lists.torproject.org/pipermail/tor-relays/2017-December/013911.html
|
||||
# https://lists.torproject.org/pipermail/tor-relays/2017-December/013912.html
|
||||
199.249.223.62:80 orport=443 id=0077BCBA7244DB3E6A5ED2746E86170066684887 # Quintex13
|
||||
199.249.224.45:80 orport=443 id=041646640AB306EA74B001966E86169B04CC88D2 # QuintexAirVPN26
|
||||
199.249.223.67:80 orport=443 id=155D6F57425F16C0624D77777641E4EB1B47C6F0 # Quintex18
|
||||
199.249.223.45:80 orport=443 id=1AE949967F82BBE7534A3D6BA77A7EBE1CED4369 # Quintex36
|
||||
199.249.223.63:80 orport=443 id=1DB25DF59DAA01B5BE3D3CEB8AFED115940EBE8B # Quintex14
|
||||
199.249.224.63:80 orport=443 id=1E5136DDC52FAE1219208F0A6BADB0BA62587EE6 # Quintex43
|
||||
199.249.224.46:80 orport=443 id=2ED4D25766973713EB8C56A290BF07E06B85BF12 # QuintexAirVPN27
|
||||
199.249.223.42:80 orport=443 id=3687FEC7E73F61AC66F7AE251E7DEE6BBD8C0252 # Quintex33
|
||||
199.249.223.49:80 orport=443 id=36D68478366CB8627866757EBCE7FB3C17FC1CB8 # Quintex40
|
||||
199.249.224.49:80 orport=443 id=3CA0D15567024D2E0B557DC0CF3E962B37999A79 # QuintexAirVPN30
|
||||
199.249.223.61:80 orport=443 id=40E7D6CE5085E4CDDA31D51A29D1457EB53F12AD # Quintex12
|
||||
199.249.223.76:80 orport=443 id=43209F6D50C657A56FE79AF01CA69F9EF19BD338 # QuintexAirVPN5
|
||||
199.249.224.41:80 orport=443 id=54A4820B46E65509BF3E2B892E66930A41759DE9 # QuintexAirVPN22
|
||||
199.249.223.73:80 orport=443 id=5649CB2158DA94FB747415F26628BEC07FA57616 # QuintexAirVPN8
|
||||
199.249.223.74:80 orport=443 id=5F4CD12099AF20FAF9ADFDCEC65316A376D0201C # QuintexAirVPN7
|
||||
199.249.223.75:80 orport=443 id=60D3667F56AEC5C69CF7E8F557DB21DDF6C36060 # QuintexAirVPN6
|
||||
199.249.223.46:80 orport=443 id=66E19E8C4773086F669A1E06A3F8C23B6C079129 # Quintex37
|
||||
199.249.224.65:80 orport=443 id=764BF8A03868F84C8F323C1A676AA254B80DC3BF # Quintex45
|
||||
199.249.223.48:80 orport=443 id=7A3DD280EA4CD4DD16EF8C67B93D9BDE184D1A81 # Quintex39
|
||||
199.249.224.68:80 orport=443 id=7E6E9A6FDDB8DC7C92F0CFCC3CBE76C29F061799 # Quintex48
|
||||
199.249.223.69:80 orport=443 id=7FA8E7E44F1392A4E40FFC3B69DB3B00091B7FD3 # Quintex20
|
||||
199.249.223.44:80 orport=443 id=8B80169BEF71450FC4069A190853523B7AEA45E1 # Quintex35
|
||||
199.249.224.60:80 orport=443 id=9314BD9503B9014261A65C221D77E57389DBCCC1 # Quintex50
|
||||
199.249.224.40:80 orport=443 id=9C1E7D92115D431385B8CAEA6A7C15FB89CE236B # QuintexAirVPN21
|
||||
199.249.223.65:80 orport=443 id=9D21F034C3BFF4E7737D08CF775DC1745706801F # Quintex16
|
||||
199.249.224.67:80 orport=443 id=9E2D7C6981269404AA1970B53891701A20424EF8 # Quintex47
|
||||
199.249.223.64:80 orport=443 id=9F2856F6D2B89AD4EF6D5723FAB167DB5A53519A # Quintex15
|
||||
199.249.224.48:80 orport=443 id=A0DB820FEC87C0405F7BF05DEE5E4ADED2BB9904 # QuintexAirVPN29
|
||||
199.249.224.64:80 orport=443 id=A4A393FEF48640961AACE92D041934B55348CEF9 # Quintex44
|
||||
199.249.223.72:80 orport=443 id=B028707969D8ED84E6DEA597A884F78AAD471971 # QuintexAirVPN9
|
||||
199.249.223.40:80 orport=443 id=B0CD9F9B5B60651ADC5919C0F1EAA87DBA1D9249 # Quintex31
|
||||
199.249.224.61:80 orport=443 id=B2197C23A4FF5D1C49EE45BA7688BA8BCCD89A0B # Quintex41
|
||||
199.249.223.71:80 orport=443 id=B6320E44A230302C7BF9319E67597A9B87882241 # QuintexAirVPN10
|
||||
199.249.223.60:80 orport=443 id=B7047FBDE9C53C39011CA84E5CB2A8E3543066D0 # Quintex11
|
||||
199.249.224.66:80 orport=443 id=C78AFFEEE320EA0F860961763E613FD2FAC855F5 # Quintex46
|
||||
199.249.224.44:80 orport=443 id=CB7C0D841FE376EF43F7845FF201B0290C0A239E # QuintexAirVPN25
|
||||
199.249.223.47:80 orport=443 id=CC14C97F1D23EE97766828FC8ED8582E21E11665 # Quintex38
|
||||
199.249.223.77:80 orport=443 id=CC4A3AE960E3617F49BF9887B79186C14CBA6813 # QuintexAirVPN4
|
||||
199.249.223.41:80 orport=443 id=D25210CE07C49F2A4F2BC7A506EB0F5EA7F5E2C2 # Quintex32
|
||||
199.249.223.79:80 orport=443 id=D33292FEDE24DD40F2385283E55C87F85C0943B6 # QuintexAirVPN2
|
||||
199.249.224.47:80 orport=443 id=D6FF2697CEA5C0C7DA84797C2E71163814FC2466 # QuintexAirVPN28
|
||||
199.249.223.68:80 orport=443 id=DF20497E487A979995D851A5BCEC313DF7E5BC51 # Quintex19
|
||||
199.249.223.43:80 orport=443 id=E480D577F58E782A5BC4FA6F49A6650E9389302F # Quintex34
|
||||
199.249.224.69:80 orport=443 id=EABC2DD0D47B5DB11F2D37EB3C60C2A4D91C10F2 # Quintex49
|
||||
199.249.223.78:80 orport=443 id=EC15DB62D9101481F364DE52EB8313C838BDDC29 # QuintexAirVPN3
|
||||
199.249.224.42:80 orport=443 id=F21DE9C7DE31601D9716781E17E24380887883D1 # QuintexAirVPN23
|
||||
199.249.223.81:80 orport=443 id=F7447E99EB5CBD4D5EB913EE0E35AC642B5C1EF3 # QuintexAirVPN1
|
||||
199.249.224.43:80 orport=443 id=FDD700C791CC6BB0AC1C2099A82CBC367AD4B764 # QuintexAirVPN24
|
||||
199.249.224.62:80 orport=443 id=FE00A3A835680E67FBBC895A724E2657BB253E97 # Quintex42
|
||||
199.249.223.66:80 orport=443 id=C5A53BCC174EF8FD0DCB223E4AA929FA557DEDB2 # Quintex17
|
||||
|
||||
# https://lists.torproject.org/pipermail/tor-relays/2017-December/013914.html
|
||||
5.196.23.64:9030 orport=9001 id=775B0FAFDE71AADC23FFC8782B7BEB1D5A92733E # Aerodynamik01
|
||||
217.182.75.181:9030 orport=9001 id=EFEACD781604EB80FBC025EDEDEA2D523AEAAA2F # Aerodynamik02
|
||||
193.70.43.76:9030 orport=9001 id=484A10BA2B8D48A5F0216674C8DD50EF27BC32F3 # Aerodynamik03
|
||||
149.56.141.138:9030 orport=9001 id=1938EBACBB1A7BFA888D9623C90061130E63BB3F # Aerodynamik04
|
||||
|
||||
# https://lists.torproject.org/pipermail/tor-relays/2017-December/013917.html
|
||||
104.200.20.46:80 orport=9001 id=78E2BE744A53631B4AAB781468E94C52AB73968B # bynumlawtor
|
||||
|
||||
# https://lists.torproject.org/pipermail/tor-relays/2017-December/013929.html
|
||||
139.99.130.178:80 orport=443 id=867B95CACD64653FEEC4D2CEFC5C49B4620307A7 # coffswifi2
|
||||
|
||||
# https://lists.torproject.org/pipermail/tor-relays/2017-December/013946.html
|
||||
172.98.193.43:80 orport=443 id=5E56738E7F97AA81DEEF59AF28494293DFBFCCDF # Backplane
|
||||
|
||||
# Email sent directly to teor
|
||||
62.210.254.132:80 orport=443 id=8456DFA94161CDD99E480C2A2992C366C6564410 # turingmachine
|
||||
|
||||
# Email sent directly to teor
|
||||
80.127.117.180:80 orport=443 id=328E54981C6DDD7D89B89E418724A4A7881E3192 ipv6=[2001:985:e77:10::4]:443 # sjc01
|
||||
|
||||
# https://lists.torproject.org/pipermail/tor-relays/2017-December/013960.html
|
||||
51.15.205.214:9030 orport=9001 id=8B6556601612F1E2AFCE2A12FFFAF8482A76DD1F ipv6=[2001:bc8:4400:2500::5:b07]:9001 # titania1
|
||||
51.15.205.214:9031 orport=9002 id=5E363D72488276160D062DDD2DFA25CFEBAF5EA9 ipv6=[2001:bc8:4400:2500::5:b07]:9002 # titania2
|
||||
|
||||
# Email sent directly to teor
|
||||
185.129.249.124:9030 orport=9001 id=1FA8F638298645BE58AC905276680889CB795A94 # treadstone
|
||||
|
||||
# https://lists.torproject.org/pipermail/tor-relays/2017-December/014000.html
|
||||
24.117.231.229:34175 orport=45117 id=CE24412AD69444954B4015E293AE53DDDAFEA3D6 # Anosognosia
|
||||
|
||||
# https://lists.torproject.org/pipermail/tor-relays/2018-January/014012.html
|
||||
128.31.0.13:80 orport=443 id=A53C46F5B157DD83366D45A8E99A244934A14C46 # csailmitexit
|
||||
|
||||
# Email sent directly to teor
|
||||
82.247.103.117:110 orport=995 id=C9B3C1661A9577BA24C1C2C6123918921A495509 # Casper01
|
||||
109.238.2.79:110 orport=995 id=7520892E3DD133D0B0464D01A158B54B8E2A8B75 # Casper02
|
||||
51.15.179.153:110 orport=995 id=BB60F5BA113A0B8B44B7B37DE3567FE561E92F78 # Casper04
|
||||
|
||||
# Email sent directly to teor
|
||||
80.127.107.179:80 orport=443 id=BC6B2E2F62ACC5EDECBABE64DA1E48F84DD98B78 ipv6=[2001:981:4a22:c::6]:443 # TVISION02
|
||||
|
||||
# https://lists.torproject.org/pipermail/tor-relays/2018-January/014020.html
|
||||
37.120.174.249:80 orport=443 id=11DF0017A43AF1F08825CD5D973297F81AB00FF3 ipv6=[2a03:4000:6:724c:df98:15f9:b34d:443]:443 # gGDHjdcC6zAlM8k08lX
|
||||
|
||||
# These fallbacks opted-in in previous releases, then changed their details,
|
||||
# and so we blacklisted them. Now we want to whitelist changes.
|
||||
# Assume details update is permanent
|
||||
85.230.184.93:9030 orport=443 id=855BC2DABE24C861CD887DB9B2E950424B49FC34 # Logforme
|
||||
176.31.180.157:143 orport=22 id=E781F4EC69671B3F1864AE2753E0890351506329 ipv6=[2001:41d0:8:eb9d::1]:22 # armbrust
|
||||
|
||||
# https://lists.torproject.org/pipermail/tor-relays/2018-January/014024.html
|
||||
82.161.212.209:9030 orport=9001 id=4E8CE6F5651E7342C1E7E5ED031E82078134FB0D ipv6=[2001:980:d7ed:1:ff:b0ff:fe00:d0b]:9001 # ymkeo
|
||||
5.9.147.226:9030 orport=9001 id=B0553175AADB0501E5A61FC61CEA3970BE130FF2
|
||||
|
|
|
@ -1,38 +0,0 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
# Generate a fallback directory whitelist/blacklist line for every fingerprint
|
||||
# passed as an argument.
|
||||
#
|
||||
# Usage:
|
||||
# generateFallbackDirLine.py fingerprint ...
|
||||
|
||||
import sys
|
||||
import urllib2
|
||||
|
||||
import stem.descriptor.remote
|
||||
import stem.util.tor_tools
|
||||
|
||||
if len(sys.argv) <= 1:
|
||||
print('Usage: %s fingerprint ...' % sys.argv[0])
|
||||
sys.exit(1)
|
||||
|
||||
for fingerprint in sys.argv[1:]:
|
||||
if not stem.util.tor_tools.is_valid_fingerprint(fingerprint):
|
||||
print("'%s' isn't a valid relay fingerprint" % fingerprint)
|
||||
sys.exit(1)
|
||||
|
||||
try:
|
||||
desc = stem.descriptor.remote.get_server_descriptors(fingerprint).run()[0]
|
||||
except urllib2.HTTPError as exc:
|
||||
if exc.code == 404:
|
||||
print('# %s not found in recent descriptors' % fingerprint)
|
||||
continue
|
||||
else:
|
||||
raise
|
||||
|
||||
if not desc.dir_port:
|
||||
print("# %s needs a DirPort" % fingerprint)
|
||||
else:
|
||||
ipv6_addresses = [(address, port) for address, port, is_ipv6 in desc.or_addresses if is_ipv6]
|
||||
ipv6_field = ' ipv6=[%s]:%s' % ipv6_addresses[0] if ipv6_addresses else ''
|
||||
print('%s:%s orport=%s id=%s%s # %s' % (desc.address, desc.dir_port, desc.or_port, fingerprint, ipv6_field, desc.nickname))
|
|
@ -1,28 +0,0 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
# Lookup fallback directory contact lines for every fingerprint passed as an
|
||||
# argument.
|
||||
#
|
||||
# Usage:
|
||||
# lookupFallbackDirContact.py fingerprint ...
|
||||
|
||||
import sys
|
||||
|
||||
import stem.descriptor.remote as remote
|
||||
|
||||
if len(sys.argv) <= 1:
|
||||
print "Usage: {} fingerprint ...".format(sys.argv[0])
|
||||
sys.exit(-1)
|
||||
|
||||
# we need descriptors, because the consensus does not have contact infos
|
||||
descriptor_list = remote.get_server_descriptors(fingerprints=sys.argv[1:]).run()
|
||||
|
||||
descriptor_list_fingerprints = []
|
||||
for d in descriptor_list:
|
||||
assert d.fingerprint in sys.argv[1:]
|
||||
descriptor_list_fingerprints.append(d.fingerprint)
|
||||
print "{} {}".format(d.fingerprint, d.contact)
|
||||
|
||||
for fingerprint in sys.argv[1:]:
|
||||
if fingerprint not in descriptor_list_fingerprints:
|
||||
print "{} not found in current descriptors".format(fingerprint)
|
|
@ -101,7 +101,7 @@ def read():
|
|||
|
||||
def findline(lines, lineno, ident):
|
||||
"""Given a list of all the lines in the file (adjusted so 1-indexing works),
|
||||
a line number that ident is allegedly on, and ident, I figure out
|
||||
a line number that ident is alledgedly on, and ident, I figure out
|
||||
the line where ident was really declared."""
|
||||
lno = lineno
|
||||
for lineno in xrange(lineno, 0, -1):
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
#!/usr/bin/env python
|
||||
#!/usr/bin/python
|
||||
|
||||
# Usage:
|
||||
#
|
||||
# Regenerate the list:
|
||||
# scripts/maint/updateFallbackDirs.py > src/or/fallback_dirs.inc 2> fallback_dirs.log
|
||||
# scripts/maint/updateFallbackDirs.py > src/or/fallback_dirs.inc
|
||||
#
|
||||
# Check the existing list:
|
||||
# scripts/maint/updateFallbackDirs.py check_existing > fallback_dirs.inc.ok 2> fallback_dirs.log
|
||||
# scripts/maint/updateFallbackDirs.py check_existing > fallback_dirs.inc.ok
|
||||
# mv fallback_dirs.inc.ok src/or/fallback_dirs.inc
|
||||
#
|
||||
# This script should be run from a stable, reliable network connection,
|
||||
|
@ -14,12 +14,14 @@
|
|||
# If this is not possible, please disable:
|
||||
# PERFORM_IPV4_DIRPORT_CHECKS and PERFORM_IPV6_DIRPORT_CHECKS
|
||||
#
|
||||
# Needs dateutil, stem, and potentially other python packages.
|
||||
# Needs dateutil (and potentially other python packages)
|
||||
# Needs stem available in your PYTHONPATH, or just ln -s ../stem/stem .
|
||||
# Optionally uses ipaddress (python 3 builtin) or py2-ipaddress (package)
|
||||
# for netblock analysis.
|
||||
# for netblock analysis, in PYTHONPATH, or just
|
||||
# ln -s ../py2-ipaddress-3.4.1/ipaddress.py .
|
||||
#
|
||||
# Then read the logs to make sure the fallbacks aren't dominated by a single
|
||||
# netblock or port.
|
||||
# netblock or port
|
||||
|
||||
# Script by weasel, April 2015
|
||||
# Portions by gsathya & karsten, 2013
|
||||
|
@ -45,7 +47,7 @@ import copy
|
|||
import re
|
||||
|
||||
from stem.descriptor import DocumentHandler
|
||||
from stem.descriptor.remote import get_consensus, get_server_descriptors, MAX_FINGERPRINTS
|
||||
from stem.descriptor.remote import get_consensus
|
||||
|
||||
import logging
|
||||
logging.root.name = ''
|
||||
|
@ -66,17 +68,6 @@ except ImportError:
|
|||
|
||||
## Top-Level Configuration
|
||||
|
||||
# We use semantic versioning: https://semver.org
|
||||
# In particular:
|
||||
# * major changes include removing a mandatory field, or anything else that
|
||||
# would break an appropriately tolerant parser,
|
||||
# * minor changes include adding a field,
|
||||
# * patch changes include changing header comments or other unstructured
|
||||
# content
|
||||
FALLBACK_FORMAT_VERSION = '2.0.0'
|
||||
SECTION_SEPARATOR_BASE = '====='
|
||||
SECTION_SEPARATOR_COMMENT = '/* ' + SECTION_SEPARATOR_BASE + ' */'
|
||||
|
||||
# Output all candidate fallbacks, or only output selected fallbacks?
|
||||
OUTPUT_CANDIDATES = False
|
||||
|
||||
|
@ -107,12 +98,11 @@ DOWNLOAD_MICRODESC_CONSENSUS = True
|
|||
# reject consensuses that are older than REASONABLY_LIVE_TIME.
|
||||
# For the consensus expiry check to be accurate, the machine running this
|
||||
# script needs an accurate clock.
|
||||
#
|
||||
# Relays on 0.3.0 and later return a 404 when they are about to serve an
|
||||
# expired consensus. This makes them fail the download check.
|
||||
# We use a tolerance of 0, so that 0.2.x series relays also fail the download
|
||||
# check if they serve an expired consensus.
|
||||
CONSENSUS_EXPIRY_TOLERANCE = 0
|
||||
# We use 24 hours to compensate for #20909, where relays on 0.2.9.5-alpha and
|
||||
# 0.3.0.0-alpha-dev and later deliver stale consensuses, but typically recover
|
||||
# after ~12 hours.
|
||||
# We should make this lower when #20909 is fixed, see #20942.
|
||||
CONSENSUS_EXPIRY_TOLERANCE = 24*60*60
|
||||
|
||||
# Output fallback name, flags, bandwidth, and ContactInfo in a C comment?
|
||||
OUTPUT_COMMENTS = True if OUTPUT_CANDIDATES else False
|
||||
|
@ -170,24 +160,25 @@ MAX_LIST_FILE_SIZE = 1024 * 1024
|
|||
|
||||
# Require fallbacks to have the same address and port for a set amount of time
|
||||
# We used to have this at 1 week, but that caused many fallback failures, which
|
||||
# meant that we had to rebuild the list more often. We want fallbacks to be
|
||||
# stable for 2 years, so we set it to a few months.
|
||||
# meant that we had to rebuild the list more often.
|
||||
#
|
||||
# If a relay changes address or port, that's it, it's not useful any more,
|
||||
# because clients can't find it
|
||||
ADDRESS_AND_PORT_STABLE_DAYS = 90
|
||||
# There was a bug in Tor 0.2.8.1-alpha and earlier where a relay temporarily
|
||||
# submits a 0 DirPort when restarted.
|
||||
# This causes OnionOO to (correctly) reset its stability timer.
|
||||
# Affected relays should upgrade to Tor 0.2.8.7 or later, which has a fix
|
||||
# for this issue.
|
||||
ADDRESS_AND_PORT_STABLE_DAYS = 30
|
||||
# We ignore relays that have been down for more than this period
|
||||
MAX_DOWNTIME_DAYS = 0 if MUST_BE_RUNNING_NOW else 7
|
||||
# FallbackDirs must have a time-weighted-fraction that is greater than or
|
||||
# equal to:
|
||||
# Mirrors that are down half the time are still useful half the time
|
||||
CUTOFF_RUNNING = .50
|
||||
CUTOFF_V2DIR = .50
|
||||
# Guard flags are removed for some time after a relay restarts, so we ignore
|
||||
# the guard flag.
|
||||
CUTOFF_GUARD = .00
|
||||
# FallbackDirs must have a time-weighted-fraction that is less than or equal
|
||||
# to:
|
||||
# What time-weighted-fraction of these flags must FallbackDirs
|
||||
# Equal or Exceed?
|
||||
CUTOFF_RUNNING = .90
|
||||
CUTOFF_V2DIR = .90
|
||||
# Tolerate lower guard flag averages, as guard flags are removed for some time
|
||||
# after a relay restarts
|
||||
CUTOFF_GUARD = .80
|
||||
# What time-weighted-fraction of these flags must FallbackDirs
|
||||
# Equal or Fall Under?
|
||||
# .00 means no bad exits
|
||||
PERMITTED_BADEXIT = .00
|
||||
|
||||
|
@ -210,23 +201,17 @@ MAX_FALLBACK_COUNT = None if OUTPUT_CANDIDATES else 200
|
|||
MIN_FALLBACK_COUNT = 0 if OUTPUT_CANDIDATES else MAX_FALLBACK_COUNT*0.5
|
||||
|
||||
# The maximum number of fallbacks on the same address, contact, or family
|
||||
#
|
||||
# With 150 fallbacks, this means each operator sees 5% of client bootstraps.
|
||||
# For comparison:
|
||||
# - We try to limit guard and exit operators to 5% of the network
|
||||
# - The directory authorities used to see 11% of client bootstraps each
|
||||
#
|
||||
# We also don't want too much of the list to go down if a single operator
|
||||
# has to move all their relays.
|
||||
# With 200 fallbacks, this means each operator can see 1% of client bootstraps
|
||||
# (The directory authorities used to see ~12% of client bootstraps each.)
|
||||
MAX_FALLBACKS_PER_IP = 1
|
||||
MAX_FALLBACKS_PER_IPV4 = MAX_FALLBACKS_PER_IP
|
||||
MAX_FALLBACKS_PER_IPV6 = MAX_FALLBACKS_PER_IP
|
||||
MAX_FALLBACKS_PER_CONTACT = 7
|
||||
MAX_FALLBACKS_PER_FAMILY = 7
|
||||
MAX_FALLBACKS_PER_CONTACT = 3
|
||||
MAX_FALLBACKS_PER_FAMILY = 3
|
||||
|
||||
## Fallback Bandwidth Requirements
|
||||
|
||||
# Any fallback with the Exit flag has its bandwidth multiplied by this fraction
|
||||
# Any fallback with the Exit flag has its bandwidth multipled by this fraction
|
||||
# to make sure we aren't further overloading exits
|
||||
# (Set to 1.0, because we asked that only lightly loaded exits opt-in,
|
||||
# and the extra load really isn't that much for large relays.)
|
||||
|
@ -234,11 +219,11 @@ EXIT_BANDWIDTH_FRACTION = 1.0
|
|||
|
||||
# If a single fallback's bandwidth is too low, it's pointless adding it
|
||||
# We expect fallbacks to handle an extra 10 kilobytes per second of traffic
|
||||
# Make sure they can support fifty times the expected extra load
|
||||
#
|
||||
# Make sure they can support a hundred times the expected extra load
|
||||
# (Use 102.4 to make it come out nicely in MByte/s)
|
||||
# We convert this to a consensus weight before applying the filter,
|
||||
# because all the bandwidth amounts are specified by the relay
|
||||
MIN_BANDWIDTH = 50.0 * 10.0 * 1024.0
|
||||
MIN_BANDWIDTH = 102.4 * 10.0 * 1024.0
|
||||
|
||||
# Clients will time out after 30 seconds trying to download a consensus
|
||||
# So allow fallback directories half that to deliver a consensus
|
||||
|
@ -250,6 +235,21 @@ CONSENSUS_DOWNLOAD_SPEED_MAX = 15.0
|
|||
# This avoids delisting a relay due to transient network conditions
|
||||
CONSENSUS_DOWNLOAD_RETRY = True
|
||||
|
||||
## Fallback Weights for Client Selection
|
||||
|
||||
# All fallback weights are equal, and set to the value below
|
||||
# Authorities are weighted 1.0 by default
|
||||
# Clients use these weights to select fallbacks and authorities at random
|
||||
# If there are 100 fallbacks and 9 authorities:
|
||||
# - each fallback is chosen with probability 10.0/(10.0*100 + 1.0*9) ~= 0.99%
|
||||
# - each authority is chosen with probability 1.0/(10.0*100 + 1.0*9) ~= 0.09%
|
||||
# A client choosing a bootstrap directory server will choose a fallback for
|
||||
# 10.0/(10.0*100 + 1.0*9) * 100 = 99.1% of attempts, and an authority for
|
||||
# 1.0/(10.0*100 + 1.0*9) * 9 = 0.9% of attempts.
|
||||
# (This disregards the bootstrap schedules, where clients start by choosing
|
||||
# from fallbacks & authoritites, then later choose from only authorities.)
|
||||
FALLBACK_OUTPUT_WEIGHT = 10.0
|
||||
|
||||
## Parsing Functions
|
||||
|
||||
def parse_ts(t):
|
||||
|
@ -289,10 +289,6 @@ def cleanse_c_multiline_comment(raw_string):
|
|||
bad_char_list = '*/'
|
||||
# Prevent a malicious string from using C nulls
|
||||
bad_char_list += '\0'
|
||||
# Avoid confusing parsers by making sure there is only one comma per fallback
|
||||
bad_char_list += ','
|
||||
# Avoid confusing parsers by making sure there is only one equals per field
|
||||
bad_char_list += '='
|
||||
# Be safer by removing bad characters entirely
|
||||
cleansed_string = remove_bad_chars(cleansed_string, bad_char_list)
|
||||
# Some compilers may further process the content of comments
|
||||
|
@ -313,10 +309,6 @@ def cleanse_c_string(raw_string):
|
|||
bad_char_list += '\\'
|
||||
# Prevent a malicious string from using C nulls
|
||||
bad_char_list += '\0'
|
||||
# Avoid confusing parsers by making sure there is only one comma per fallback
|
||||
bad_char_list += ','
|
||||
# Avoid confusing parsers by making sure there is only one equals per field
|
||||
bad_char_list += '='
|
||||
# Be safer by removing bad characters entirely
|
||||
cleansed_string = remove_bad_chars(cleansed_string, bad_char_list)
|
||||
# Some compilers may further process the content of strings
|
||||
|
@ -555,7 +547,7 @@ class Candidate(object):
|
|||
details['flags'] = []
|
||||
if (not 'advertised_bandwidth' in details
|
||||
or details['advertised_bandwidth'] is None):
|
||||
# relays without advertised bandwidth have it calculated from their
|
||||
# relays without advertised bandwdith have it calculated from their
|
||||
# consensus weight
|
||||
details['advertised_bandwidth'] = 0
|
||||
if (not 'effective_family' in details
|
||||
|
@ -578,7 +570,6 @@ class Candidate(object):
|
|||
if not self.has_ipv6():
|
||||
logging.debug("Failed to get an ipv6 address for %s."%(self._fpr,))
|
||||
self._compute_version()
|
||||
self._extra_info_cache = None
|
||||
|
||||
def _stable_sort_or_addresses(self):
|
||||
# replace self._data['or_addresses'] with a stable ordering,
|
||||
|
@ -1344,14 +1335,8 @@ class Candidate(object):
|
|||
# comment-out the returned string
|
||||
def fallbackdir_info(self, dl_speed_ok):
|
||||
# "address:dirport orport=port id=fingerprint"
|
||||
# (insert additional madatory fields here)
|
||||
# "[ipv6=addr:orport]"
|
||||
# (insert additional optional fields here)
|
||||
# /* nickname=name */
|
||||
# /* extrainfo={0,1} */
|
||||
# (insert additional comment fields here)
|
||||
# /* ===== */
|
||||
# ,
|
||||
# "weight=FALLBACK_OUTPUT_WEIGHT",
|
||||
#
|
||||
# Do we want a C string, or a commented-out string?
|
||||
c_string = dl_speed_ok
|
||||
|
@ -1372,34 +1357,10 @@ class Candidate(object):
|
|||
self.orport,
|
||||
cleanse_c_string(self._fpr))
|
||||
s += '\n'
|
||||
# (insert additional madatory fields here)
|
||||
if self.has_ipv6():
|
||||
s += '" ipv6=%s:%d"'%(cleanse_c_string(self.ipv6addr), self.ipv6orport)
|
||||
s += '\n'
|
||||
# (insert additional optional fields here)
|
||||
if not comment_string:
|
||||
s += '/* '
|
||||
s += 'nickname=%s'%(cleanse_c_string(self._data['nickname']))
|
||||
if not comment_string:
|
||||
s += ' */'
|
||||
s += '\n'
|
||||
# if we know that the fallback is an extrainfo cache, flag it
|
||||
# and if we don't know, assume it is not
|
||||
if not comment_string:
|
||||
s += '/* '
|
||||
s += 'extrainfo=%d'%(1 if self._extra_info_cache else 0)
|
||||
if not comment_string:
|
||||
s += ' */'
|
||||
s += '\n'
|
||||
# (insert additional comment fields here)
|
||||
# The terminator and comma must be the last line in each fallback entry
|
||||
if not comment_string:
|
||||
s += '/* '
|
||||
s += SECTION_SEPARATOR_BASE
|
||||
if not comment_string:
|
||||
s += ' */'
|
||||
s += '\n'
|
||||
s += ','
|
||||
s += '" weight=%d",'%(FALLBACK_OUTPUT_WEIGHT)
|
||||
if comment_string:
|
||||
s += '\n'
|
||||
s += '*/'
|
||||
|
@ -1589,7 +1550,7 @@ class CandidateList(dict):
|
|||
excluded_count, initial_count)
|
||||
|
||||
# calculate each fallback's measured bandwidth based on the median
|
||||
# consensus weight to advertised bandwidth ratio
|
||||
# consensus weight to advertised bandwdith ratio
|
||||
def calculate_measured_bandwidth(self):
|
||||
self.sort_fallbacks_by_cw_to_bw_factor()
|
||||
median_fallback = self.fallback_median(True)
|
||||
|
@ -1784,53 +1745,6 @@ class CandidateList(dict):
|
|||
self.fallbacks = family_limit_fallbacks
|
||||
return original_count - len(self.fallbacks)
|
||||
|
||||
# try once to get the descriptors for fingerprint_list using stem
|
||||
# returns an empty list on exception
|
||||
@staticmethod
|
||||
def get_fallback_descriptors_once(fingerprint_list):
|
||||
desc_list = get_server_descriptors(fingerprints=fingerprint_list).run(suppress=True)
|
||||
return desc_list
|
||||
|
||||
# try up to max_retries times to get the descriptors for fingerprint_list
|
||||
# using stem. Stops retrying when all descriptors have been retrieved.
|
||||
# returns a list containing the descriptors that were retrieved
|
||||
@staticmethod
|
||||
def get_fallback_descriptors(fingerprint_list, max_retries=5):
|
||||
# we can't use stem's retries=, because we want to support more than 96
|
||||
# descriptors
|
||||
#
|
||||
# add an attempt for every MAX_FINGERPRINTS (or part thereof) in the list
|
||||
max_retries += (len(fingerprint_list) + MAX_FINGERPRINTS - 1) / MAX_FINGERPRINTS
|
||||
remaining_list = fingerprint_list
|
||||
desc_list = []
|
||||
for _ in xrange(max_retries):
|
||||
if len(remaining_list) == 0:
|
||||
break
|
||||
new_desc_list = CandidateList.get_fallback_descriptors_once(remaining_list[0:MAX_FINGERPRINTS])
|
||||
for d in new_desc_list:
|
||||
try:
|
||||
remaining_list.remove(d.fingerprint)
|
||||
except ValueError:
|
||||
# warn and ignore if a directory mirror returned a bad descriptor
|
||||
logging.warning("Directory mirror returned unwanted descriptor %s, ignoring",
|
||||
d.fingerprint)
|
||||
continue
|
||||
desc_list.append(d)
|
||||
return desc_list
|
||||
|
||||
# find the fallbacks that cache extra-info documents
|
||||
# Onionoo doesn't know this, so we have to use stem
|
||||
def mark_extra_info_caches(self):
|
||||
fingerprint_list = [ f._fpr for f in self.fallbacks ]
|
||||
logging.info("Downloading fallback descriptors to find extra-info caches")
|
||||
desc_list = CandidateList.get_fallback_descriptors(fingerprint_list)
|
||||
for d in desc_list:
|
||||
self[d.fingerprint]._extra_info_cache = d.extra_info_cache
|
||||
missing_descriptor_list = [ f._fpr for f in self.fallbacks
|
||||
if f._extra_info_cache is None ]
|
||||
for f in missing_descriptor_list:
|
||||
logging.warning("No descriptor for {}. Assuming extrainfo=0.".format(f))
|
||||
|
||||
# try a download check on each fallback candidate in order
|
||||
# stop after max_count successful downloads
|
||||
# but don't remove any candidates from the array
|
||||
|
@ -1990,7 +1904,7 @@ class CandidateList(dict):
|
|||
# this doesn't actually tell us anything useful
|
||||
#self.describe_fallback_ipv4_netblock_mask(8)
|
||||
self.describe_fallback_ipv4_netblock_mask(16)
|
||||
#self.describe_fallback_ipv4_netblock_mask(24)
|
||||
self.describe_fallback_ipv4_netblock_mask(24)
|
||||
|
||||
# log a message about the proportion of fallbacks in each IPv6 /12 (RIR),
|
||||
# /23 (smaller RIR blocks), /32 (LIR), /48 (Customer), and /64 (Host)
|
||||
|
@ -2000,7 +1914,7 @@ class CandidateList(dict):
|
|||
#self.describe_fallback_ipv6_netblock_mask(12)
|
||||
#self.describe_fallback_ipv6_netblock_mask(23)
|
||||
self.describe_fallback_ipv6_netblock_mask(32)
|
||||
#self.describe_fallback_ipv6_netblock_mask(48)
|
||||
self.describe_fallback_ipv6_netblock_mask(48)
|
||||
self.describe_fallback_ipv6_netblock_mask(64)
|
||||
|
||||
# log a message about the proportion of fallbacks in each IPv4 and IPv6
|
||||
|
@ -2078,18 +1992,6 @@ class CandidateList(dict):
|
|||
CandidateList.describe_percentage(dir_count,
|
||||
fallback_count)))
|
||||
|
||||
# return a list of fallbacks which cache extra-info documents
|
||||
def fallbacks_with_extra_info_cache(self):
|
||||
return filter(lambda x: x._extra_info_cache, self.fallbacks)
|
||||
|
||||
# log a message about the proportion of fallbacks that cache extra-info docs
|
||||
def describe_fallback_extra_info_caches(self):
|
||||
extra_info_falback_count = len(self.fallbacks_with_extra_info_cache())
|
||||
fallback_count = len(self.fallbacks)
|
||||
logging.warning('%s of fallbacks cache extra-info documents'%(
|
||||
CandidateList.describe_percentage(extra_info_falback_count,
|
||||
fallback_count)))
|
||||
|
||||
# return a list of fallbacks which have the Exit flag
|
||||
def fallbacks_with_exit(self):
|
||||
return filter(lambda x: x.is_exit(), self.fallbacks)
|
||||
|
@ -2117,6 +2019,10 @@ class CandidateList(dict):
|
|||
def summarise_fallbacks(self, eligible_count, operator_count, failed_count,
|
||||
guard_count, target_count):
|
||||
s = ''
|
||||
s += '/* To comment-out entries in this file, use C comments, and add *'
|
||||
s += ' to the start of each line. (stem finds fallback entries using "'
|
||||
s += ' at the start of a line.) */'
|
||||
s += '\n'
|
||||
# Report:
|
||||
# whether we checked consensus download times
|
||||
# the number of fallback directories (and limits/exclusions, if relevant)
|
||||
|
@ -2217,16 +2123,6 @@ def list_fallbacks(whitelist, blacklist):
|
|||
""" Fetches required onionoo documents and evaluates the
|
||||
fallback directory criteria for each of the relays """
|
||||
|
||||
print "/* type=fallback */"
|
||||
print ("/* version={} */"
|
||||
.format(cleanse_c_multiline_comment(FALLBACK_FORMAT_VERSION)))
|
||||
now = datetime.datetime.utcnow()
|
||||
timestamp = now.strftime('%Y%m%d%H%M%S')
|
||||
print ("/* timestamp={} */"
|
||||
.format(cleanse_c_multiline_comment(timestamp)))
|
||||
# end the header with a separator, to make it easier for parsers
|
||||
print SECTION_SEPARATOR_COMMENT
|
||||
|
||||
logging.warning('Downloading and parsing Onionoo data. ' +
|
||||
'This may take some time.')
|
||||
# find relays that could be fallbacks
|
||||
|
@ -2292,9 +2188,6 @@ def list_fallbacks(whitelist, blacklist):
|
|||
'This may take some time.')
|
||||
failed_count = candidates.perform_download_consensus_checks(max_count)
|
||||
|
||||
# work out which fallbacks cache extra-infos
|
||||
candidates.mark_extra_info_caches()
|
||||
|
||||
# analyse and log interesting diversity metrics
|
||||
# like netblock, ports, exit, IPv4-only
|
||||
# (we can't easily analyse AS, and it's hard to accurately analyse country)
|
||||
|
@ -2303,7 +2196,6 @@ def list_fallbacks(whitelist, blacklist):
|
|||
if HAVE_IPADDRESS:
|
||||
candidates.describe_fallback_netblocks()
|
||||
candidates.describe_fallback_ports()
|
||||
candidates.describe_fallback_extra_info_caches()
|
||||
candidates.describe_fallback_exit_flag()
|
||||
|
||||
# output C comments summarising the fallback selection process
|
||||
|
@ -2318,9 +2210,6 @@ def list_fallbacks(whitelist, blacklist):
|
|||
for s in fetch_source_list():
|
||||
print describe_fetch_source(s)
|
||||
|
||||
# start the list with a separator, to make it easy for parsers
|
||||
print SECTION_SEPARATOR_COMMENT
|
||||
|
||||
# sort the list differently depending on why we've created it:
|
||||
# if we're outputting the final fallback list, sort by fingerprint
|
||||
# this makes diffs much more stable
|
||||
|
|
|
@ -1,45 +0,0 @@
|
|||
#!/usr/bin/env bash
|
||||
#
|
||||
# Copyright (c) 2018 The Tor Project, Inc.
|
||||
# Copyright (c) 2018 isis agora lovecruft
|
||||
# See LICENSE for license information
|
||||
#
|
||||
# updateRustDependencies.sh
|
||||
# -------------------------
|
||||
# Update our vendored Rust dependencies, either adding/removing
|
||||
# dependencies and/or upgrading current dependencies to newer
|
||||
# versions.
|
||||
#
|
||||
# To use this script, first add your dependencies, exactly specifying
|
||||
# their versions, into the appropriate *crate-level* Cargo.toml in
|
||||
# src/rust/ (i.e. *not* /src/rust/Cargo.toml, but instead the one for
|
||||
# your crate).
|
||||
#
|
||||
# Next, run this script. Then, go into src/ext/rust and commit the
|
||||
# changes to the tor-rust-dependencies repo.
|
||||
|
||||
set -e
|
||||
|
||||
HERE=`dirname $(realpath $0)`
|
||||
TOPLEVEL=`dirname $(dirname $HERE)`
|
||||
TOML="$TOPLEVEL/src/rust/Cargo.toml"
|
||||
VENDORED="$TOPLEVEL/src/ext/rust/crates"
|
||||
CARGO=`which cargo`
|
||||
|
||||
if ! test -f "$TOML" ; then
|
||||
printf "Error: Couldn't find workspace Cargo.toml in expected location: %s\n" "$TOML"
|
||||
fi
|
||||
|
||||
if ! test -d "$VENDORED" ; then
|
||||
printf "Error: Couldn't find directory for Rust dependencies! Expected location: %s\n" "$VENDORED"
|
||||
fi
|
||||
|
||||
if test -z "$CARGO" ; then
|
||||
printf "Error: cargo must be installed and in your \$PATH\n"
|
||||
fi
|
||||
|
||||
if test -z `cargo --list | grep vendor` ; then
|
||||
printf "Error: cargo-vendor not installed\n"
|
||||
fi
|
||||
|
||||
$CARGO vendor -v --locked --explicit-version --no-delete --sync $TOML $VENDORED
|
|
@ -1,192 +0,0 @@
|
|||
# coding=utf8
|
||||
# Copyright (C) 2015-2016 Christopher R. Wood
|
||||
# Copyright (c) 2018 The Tor Project
|
||||
# Copyright (c) 2018 isis agora lovecruft
|
||||
#
|
||||
# From: https://raw.githubusercontent.com/gridsync/gridsync/def54f8166089b733d166665fdabcad4cdc526d8/misc/irc-notify.py
|
||||
# and: https://github.com/gridsync/gridsync
|
||||
#
|
||||
# Modified by nexB on October 2016:
|
||||
# - rework the handling of environment variables.
|
||||
# - made the script use functions
|
||||
# - support only Appveyor loading its environment variable to craft IRC notices.
|
||||
#
|
||||
# Modified by isis agora lovecruft <isis@torproject.org> in 2018:
|
||||
# - Make IRC server configurable.
|
||||
# - Make bot IRC nick deterministic.
|
||||
# - Make bot join the channel rather than sending NOTICE messages externally.
|
||||
# - Fix a bug which always caused sys.exit() to be logged as a traceback.
|
||||
# - Actually reset the IRC colour codes after printing.
|
||||
#
|
||||
# Modified by Marcin Cieślak in 2018:
|
||||
# - Accept UTF-8
|
||||
# - only guess github URLs
|
||||
# - stop using ANSI colors
|
||||
|
||||
# This program is free software; you can redistribute it and/or modify it under the
|
||||
# terms of the GNU General Public License as published by the Free Software Foundation;
|
||||
# either version 2 of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
# PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along with this
|
||||
# program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street,
|
||||
# Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
"""Simple AppVeyor IRC notification script.
|
||||
|
||||
The first argument is an IRC server and port; the second is the channel. Other
|
||||
arguments passed to the script will be sent as notice messages content and any
|
||||
{var}-formatted environment variables will be expanded automatically, replaced
|
||||
with a corresponding Appveyor environment variable value. Use commas to
|
||||
delineate multiple messages.
|
||||
|
||||
|
||||
Example:
|
||||
export APPVEYOR_URL=https://ci.appveyor.com
|
||||
export APPVEYOR_PROJECT_NAME=tor
|
||||
export APPVEYOR_REPO_COMMIT_AUTHOR=isislovecruft
|
||||
export APPVEYOR_REPO_COMMIT_TIMESTAMP=2018-04-23
|
||||
export APPVEYOR_REPO_PROVIDER=gihub
|
||||
export APPVEYOR_REPO_BRANCH=repo_branch
|
||||
export APPVEYOR_PULL_REQUEST_TITLE=pull_request_title
|
||||
export APPVEYOR_BUILD_VERSION=1
|
||||
export APPVEYOR_REPO_COMMIT=22c95b72e29248dc4de9b85e590ee18f6f587de8
|
||||
export APPVEYOR_REPO_COMMIT_MESSAGE="some IRC test"
|
||||
export APPVEYOR_ACCOUNT_NAME=isislovecruft
|
||||
export APPVEYOR_PULL_REQUEST_NUMBER=pull_request_number
|
||||
export APPVEYOR_REPO_NAME=isislovecruft/tor
|
||||
python ./appveyor-irc-notify.py irc.oftc.net:6697 tor-ci '{repo_name} {repo_branch} {short_commit} - {repo_commit_author}: {repo_commit_message}','Build #{build_version} passed. Details: {build_url} | Commit: {commit_url}
|
||||
|
||||
See also https://github.com/gridsync/gridsync/blob/master/appveyor.yml for examples
|
||||
in Appveyor's YAML:
|
||||
|
||||
on_success:
|
||||
- "python scripts/test/appveyor-irc-notify.py irc.oftc.net:6697 tor-ci success
|
||||
on_failure:
|
||||
- "python scripts/test/appveyor-irc-notify.py irc.oftc.net:6697 tor-ci failure
|
||||
"""
|
||||
|
||||
from __future__ import print_function
|
||||
from __future__ import absolute_import
|
||||
|
||||
import os
|
||||
import random
|
||||
import socket
|
||||
import ssl
|
||||
import sys
|
||||
import time
|
||||
|
||||
|
||||
def appveyor_vars():
|
||||
"""
|
||||
Return a dict of key value carfted from appveyor environment variables.
|
||||
"""
|
||||
|
||||
vars = dict([
|
||||
(
|
||||
v.replace('APPVEYOR_', '').lower(),
|
||||
os.getenv(v, '').decode('utf-8')
|
||||
) for v in [
|
||||
'APPVEYOR_URL',
|
||||
'APPVEYOR_REPO_COMMIT_MESSAGE_EXTENDED',
|
||||
'APPVEYOR_REPO_BRANCH',
|
||||
'APPVEYOR_REPO_COMMIT_AUTHOR',
|
||||
'APPVEYOR_REPO_COMMIT_AUTHOR_EMAIL',
|
||||
'APPVEYOR_REPO_COMMIT_TIMESTAMP',
|
||||
'APPVEYOR_REPO_PROVIDER',
|
||||
'APPVEYOR_PROJECT_NAME',
|
||||
'APPVEYOR_PULL_REQUEST_TITLE',
|
||||
'APPVEYOR_BUILD_VERSION',
|
||||
'APPVEYOR_REPO_COMMIT',
|
||||
'APPVEYOR_REPO_COMMIT_MESSAGE',
|
||||
'APPVEYOR_ACCOUNT_NAME',
|
||||
'APPVEYOR_PULL_REQUEST_NUMBER',
|
||||
'APPVEYOR_REPO_NAME'
|
||||
]
|
||||
])
|
||||
|
||||
BUILD_FMT = u'{url}/project/{account_name}/{project_name}/build/{build_version}'
|
||||
|
||||
if vars["repo_provider"] == 'github':
|
||||
COMMIT_FMT = u'https://{repo_provider}.com/{repo_name}/commit/{repo_commit}'
|
||||
vars.update(commit_url=COMMIT_FMT.format(**vars))
|
||||
|
||||
vars.update(
|
||||
build_url=BUILD_FMT.format(**vars),
|
||||
short_commit=vars["repo_commit"][:7],
|
||||
)
|
||||
return vars
|
||||
|
||||
|
||||
def notify():
|
||||
"""
|
||||
Send IRC notification
|
||||
"""
|
||||
apvy_vars = appveyor_vars()
|
||||
|
||||
server, port = sys.argv[1].rsplit(":", 1)
|
||||
channel = sys.argv[2]
|
||||
success = sys.argv[3] == "success"
|
||||
failure = sys.argv[3] == "failure"
|
||||
|
||||
if success or failure:
|
||||
messages = []
|
||||
messages.append(u"{repo_name} {repo_branch} {short_commit} - {repo_commit_author}: {repo_commit_message}")
|
||||
|
||||
if success:
|
||||
m = u"Build #{build_version} passed. Details: {build_url}"
|
||||
if failure:
|
||||
m = u"Build #{build_version} failed. Details: {build_url}"
|
||||
|
||||
if "commit_url" in apvy_vars:
|
||||
m += " Commit: {commit_url}"
|
||||
|
||||
messages.append(m)
|
||||
else:
|
||||
messages = sys.argv[3:]
|
||||
messages = ' '.join(messages)
|
||||
messages = messages.decode("utf-8").split(',')
|
||||
|
||||
print(repr(apvy_vars))
|
||||
messages = [msg.format(**apvy_vars).strip() for msg in messages]
|
||||
|
||||
irc_username = 'appveyor-ci'
|
||||
irc_nick = irc_username
|
||||
|
||||
# establish connection
|
||||
irc_sock = ssl.wrap_socket(socket.socket(socket.AF_INET, socket.SOCK_STREAM))
|
||||
irc_sock.connect((socket.gethostbyname(server), int(port)))
|
||||
irc_sock.send('NICK {0}\r\nUSER {0} * 0 :{0}\r\n'.format(irc_username).encode())
|
||||
irc_sock.send('JOIN #{0}\r\n'.format(channel).encode())
|
||||
irc_file = irc_sock.makefile()
|
||||
|
||||
while irc_file:
|
||||
line = irc_file.readline()
|
||||
print(line.rstrip())
|
||||
response = line.split()
|
||||
|
||||
if response[0] == 'PING':
|
||||
irc_file.send('PONG {}\r\n'.format(response[1]).encode())
|
||||
|
||||
elif response[1] == '433':
|
||||
irc_sock.send('NICK {}\r\n'.format(irc_nick).encode())
|
||||
|
||||
elif response[1] == '001':
|
||||
time.sleep(5)
|
||||
# send notification
|
||||
for msg in messages:
|
||||
print(u'PRIVMSG #{} :{}'.format(channel, msg).encode("utf-8"))
|
||||
irc_sock.send(u'PRIVMSG #{} :{}\r\n'.format(channel, msg).encode("utf-8"))
|
||||
time.sleep(5)
|
||||
return
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
try:
|
||||
notify()
|
||||
except:
|
||||
import traceback
|
||||
print('ERROR: Failed to send notification: \n' + traceback.format_exc())
|
|
@ -10,12 +10,12 @@ DIRB="$2"
|
|||
for B in $DIRB/*; do
|
||||
A=$DIRA/`basename $B`
|
||||
if [ -f $A ]; then
|
||||
perl -pe 's/^\s*\!*\d+(\*?):/ 1$1:/; s/^([^:]+:)[\d\s]+:/$1/; s/^ *-:(Runs|Programs):.*//;' "$A" > "$A.tmp"
|
||||
perl -pe 's/^\s*\!*\d+:/ 1:/; s/^([^:]+:)[\d\s]+:/$1/; s/^ *-:(Runs|Programs):.*//;' "$A" > "$A.tmp"
|
||||
else
|
||||
cat /dev/null > "$A.tmp"
|
||||
fi
|
||||
perl -pe 's/^\s*\!*\d+(\*?):/ 1$1:/; s/^([^:]+:)[\d\s]+:/$1/; s/^ *-:(Runs|Programs):.*//;' "$B" > "$B.tmp"
|
||||
diff -u "$A.tmp" "$B.tmp" |perl -pe 's/^((?:\+\+\+|---)(?:.*tmp))\s+.*/$1/;'
|
||||
perl -pe 's/^\s*\!*\d+:/ 1:/; s/^([^:]+:)[\d\s]+:/$1/; s/^ *-:(Runs|Programs):.*//;' "$B" > "$B.tmp"
|
||||
diff -u "$A.tmp" "$B.tmp"
|
||||
rm "$A.tmp" "$B.tmp"
|
||||
done
|
||||
|
||||
|
|
|
@ -26,9 +26,9 @@ CHECKERS="\
|
|||
-enable-checker alpha.unix.Stream \
|
||||
-enable-checker alpha.unix.cstring.BufferOverlap \
|
||||
-enable-checker alpha.unix.cstring.NotNullTerminated \
|
||||
-enable-checker valist.CopyToSelf \
|
||||
-enable-checker valist.Uninitialized \
|
||||
-enable-checker valist.Unterminated \
|
||||
-enable-checker alpha.valist.CopyToSelf \
|
||||
-enable-checker alpha.valist.Uninitialized \
|
||||
-enable-checker alpha.valist.Unterminated \
|
||||
-enable-checker security.FloatLoopCounter \
|
||||
-enable-checker security.insecureAPI.strcpy \
|
||||
"
|
||||
|
|
|
@ -1125,7 +1125,7 @@ tor_addr_compare_masked(const tor_addr_t *addr1, const tor_addr_t *addr2,
|
|||
case AF_UNIX:
|
||||
/* HACKHACKHACKHACKHACK:
|
||||
* tor_addr_t doesn't contain a copy of sun_path, so it's not
|
||||
* possible to compare this at all.
|
||||
* possible to comapre this at all.
|
||||
*
|
||||
* Since the only time we currently actually should be comparing
|
||||
* 2 AF_UNIX addresses is when dealing with ISO_CLIENTADDR (which
|
||||
|
@ -1540,18 +1540,6 @@ get_interface_addresses_win32(int severity, sa_family_t family)
|
|||
#define _SIZEOF_ADDR_IFREQ sizeof
|
||||
#endif
|
||||
|
||||
/* Free ifc->ifc_buf safely. */
|
||||
static void
|
||||
ifconf_free_ifc_buf(struct ifconf *ifc)
|
||||
{
|
||||
/* On macOS, tor_free() takes the address of ifc.ifc_buf, which leads to
|
||||
* undefined behaviour, because pointer-to-pointers are expected to be
|
||||
* aligned at 8-bytes, but the ifconf structure is packed. So we use
|
||||
* raw_free() instead. */
|
||||
raw_free(ifc->ifc_buf);
|
||||
ifc->ifc_buf = NULL;
|
||||
}
|
||||
|
||||
/** Convert <b>*buf</b>, an ifreq structure array of size <b>buflen</b>,
|
||||
* into smartlist of <b>tor_addr_t</b> structures.
|
||||
*/
|
||||
|
@ -1638,7 +1626,7 @@ get_interface_addresses_ioctl(int severity, sa_family_t family)
|
|||
done:
|
||||
if (fd >= 0)
|
||||
close(fd);
|
||||
ifconf_free_ifc_buf(&ifc);
|
||||
tor_free(ifc.ifc_buf);
|
||||
return result;
|
||||
}
|
||||
#endif /* defined(HAVE_IFCONF_TO_SMARTLIST) */
|
||||
|
@ -1697,7 +1685,7 @@ get_interface_address6_via_udp_socket_hack,(int severity,
|
|||
sa_family_t family,
|
||||
tor_addr_t *addr))
|
||||
{
|
||||
struct sockaddr_storage target_addr;
|
||||
struct sockaddr_storage my_addr, target_addr;
|
||||
int sock=-1, r=-1;
|
||||
socklen_t addr_len;
|
||||
|
||||
|
@ -1740,19 +1728,21 @@ get_interface_address6_via_udp_socket_hack,(int severity,
|
|||
goto err;
|
||||
}
|
||||
|
||||
if (tor_addr_from_getsockname(addr, sock) < 0) {
|
||||
if (tor_getsockname(sock,(struct sockaddr*)&my_addr, &addr_len)) {
|
||||
int e = tor_socket_errno(sock);
|
||||
log_fn(severity, LD_NET, "getsockname() to determine interface failed: %s",
|
||||
tor_socket_strerror(e));
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (tor_addr_is_loopback(addr) || tor_addr_is_multicast(addr)) {
|
||||
log_fn(severity, LD_NET, "Address that we determined via UDP socket"
|
||||
" magic is unsuitable for public comms.");
|
||||
} else {
|
||||
r=0;
|
||||
}
|
||||
if (tor_addr_from_sockaddr(addr, (struct sockaddr*)&my_addr, NULL) == 0) {
|
||||
if (tor_addr_is_loopback(addr) || tor_addr_is_multicast(addr)) {
|
||||
log_fn(severity, LD_NET, "Address that we determined via UDP socket"
|
||||
" magic is unsuitable for public comms.");
|
||||
} else {
|
||||
r=0;
|
||||
}
|
||||
}
|
||||
|
||||
err:
|
||||
if (sock >= 0)
|
||||
|
@ -1794,14 +1784,14 @@ get_interface_address6,(int severity, sa_family_t family, tor_addr_t *addr))
|
|||
break;
|
||||
} SMARTLIST_FOREACH_END(a);
|
||||
|
||||
interface_address6_list_free(addrs);
|
||||
free_interface_address6_list(addrs);
|
||||
return rv;
|
||||
}
|
||||
|
||||
/** Free a smartlist of IP addresses returned by get_interface_address6_list.
|
||||
*/
|
||||
void
|
||||
interface_address6_list_free_(smartlist_t *addrs)
|
||||
free_interface_address6_list(smartlist_t *addrs)
|
||||
{
|
||||
if (addrs != NULL) {
|
||||
SMARTLIST_FOREACH(addrs, tor_addr_t *, a, tor_free(a));
|
||||
|
@ -1816,7 +1806,7 @@ interface_address6_list_free_(smartlist_t *addrs)
|
|||
* An empty smartlist means that there are no addresses of the selected type
|
||||
* matching these criteria.
|
||||
* Returns NULL on failure.
|
||||
* Use interface_address6_list_free to free the returned list.
|
||||
* Use free_interface_address6_list to free the returned list.
|
||||
*/
|
||||
MOCK_IMPL(smartlist_t *,
|
||||
get_interface_address6_list,(int severity,
|
||||
|
|
|
@ -206,9 +206,7 @@ const char * fmt_addr32(uint32_t addr);
|
|||
|
||||
MOCK_DECL(int,get_interface_address6,(int severity, sa_family_t family,
|
||||
tor_addr_t *addr));
|
||||
void interface_address6_list_free_(smartlist_t * addrs);// XXXX
|
||||
#define interface_address6_list_free(addrs) \
|
||||
FREE_AND_NULL(smartlist_t, interface_address6_list_free_, (addrs))
|
||||
void free_interface_address6_list(smartlist_t * addrs);
|
||||
MOCK_DECL(smartlist_t *,get_interface_address6_list,(int severity,
|
||||
sa_family_t family,
|
||||
int include_internal));
|
||||
|
@ -325,8 +323,13 @@ int addr_mask_get_bits(uint32_t mask);
|
|||
int tor_inet_ntoa(const struct in_addr *in, char *buf, size_t buf_len);
|
||||
char *tor_dup_ip(uint32_t addr) ATTR_MALLOC;
|
||||
MOCK_DECL(int,get_interface_address,(int severity, uint32_t *addr));
|
||||
#define interface_address_list_free(lst)\
|
||||
interface_address6_list_free(lst)
|
||||
/** Free a smartlist of IP addresses returned by get_interface_address_list.
|
||||
*/
|
||||
static inline void
|
||||
free_interface_address_list(smartlist_t *addrs)
|
||||
{
|
||||
free_interface_address6_list(addrs);
|
||||
}
|
||||
/** Return a smartlist of the IPv4 addresses of all interfaces on the server.
|
||||
* Excludes loopback and multicast addresses. Only includes internal addresses
|
||||
* if include_internal is true. (Note that a relay behind NAT may use an
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
#include "address.h"
|
||||
#include "compat.h"
|
||||
#include "container.h"
|
||||
#include "crypto_rand.h"
|
||||
#include "crypto.h"
|
||||
#include "util.h"
|
||||
#include "siphash.h"
|
||||
|
||||
|
@ -34,7 +34,7 @@
|
|||
* independent siphashes rather than messing around with bit-shifts. The
|
||||
* approach here is probably more sound, and we should prefer it if&when we
|
||||
* unify the implementations.
|
||||
*/
|
||||
**/
|
||||
|
||||
struct address_set_t {
|
||||
/** siphash keys to make N_HASHES independent hashes for each address. */
|
||||
|
@ -63,7 +63,7 @@ address_set_new(int max_addresses_guess)
|
|||
}
|
||||
|
||||
/**
|
||||
* Release all storage associated with <b>set</b>.
|
||||
* Release all storage associated with <b>set</b>
|
||||
*/
|
||||
void
|
||||
address_set_free(address_set_t *set)
|
||||
|
@ -107,7 +107,7 @@ address_set_add_ipv4h(address_set_t *set, uint32_t addr)
|
|||
}
|
||||
|
||||
/**
|
||||
* Return true if <b>addr</b> is a member of <b>set</b>. (And probably,
|
||||
* Return true if <b>addr</b> if a member of <b>set</b>. (And probably,
|
||||
* return false if <b>addr</b> is not a member of set.)
|
||||
*/
|
||||
int
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
/* See LICENSE for licensing information */
|
||||
|
||||
/**
|
||||
* \file address_set.h
|
||||
* \file addressset.h
|
||||
* \brief Types to handle sets of addresses.
|
||||
*
|
||||
* This module was first written on a semi-emergency basis to improve the
|
||||
|
|
|
@ -16,9 +16,8 @@
|
|||
#include <ws2tcpip.h>
|
||||
#endif
|
||||
|
||||
#include "compat_openssl.h"
|
||||
#include <openssl/opensslv.h>
|
||||
#include "crypto_openssl_mgt.h"
|
||||
#include "crypto.h"
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER < OPENSSL_V_SERIES(1,0,0)
|
||||
#error "We require OpenSSL >= 1.0.0"
|
||||
|
@ -111,16 +110,12 @@ aes_new_cipher(const uint8_t *key, const uint8_t *iv, int key_bits)
|
|||
return (aes_cnt_cipher_t *) cipher;
|
||||
}
|
||||
void
|
||||
aes_cipher_free_(aes_cnt_cipher_t *cipher_)
|
||||
aes_cipher_free(aes_cnt_cipher_t *cipher_)
|
||||
{
|
||||
if (!cipher_)
|
||||
return;
|
||||
EVP_CIPHER_CTX *cipher = (EVP_CIPHER_CTX *) cipher_;
|
||||
#ifdef OPENSSL_1_1_API
|
||||
EVP_CIPHER_CTX_reset(cipher);
|
||||
#else
|
||||
EVP_CIPHER_CTX_cleanup(cipher);
|
||||
#endif
|
||||
EVP_CIPHER_CTX_free(cipher);
|
||||
}
|
||||
void
|
||||
|
@ -259,7 +254,7 @@ evaluate_ctr_for_aes(void)
|
|||
/* LCOV_EXCL_START */
|
||||
log_err(LD_CRYPTO, "This OpenSSL has a buggy version of counter mode; "
|
||||
"quitting tor.");
|
||||
exit(1); // exit ok: openssl is broken.
|
||||
exit(1);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
return 0;
|
||||
|
@ -329,7 +324,7 @@ aes_set_key(aes_cnt_cipher_t *cipher, const uint8_t *key, int key_bits)
|
|||
/** Release storage held by <b>cipher</b>
|
||||
*/
|
||||
void
|
||||
aes_cipher_free_(aes_cnt_cipher_t *cipher)
|
||||
aes_cipher_free(aes_cnt_cipher_t *cipher)
|
||||
{
|
||||
if (!cipher)
|
||||
return;
|
||||
|
|
|
@ -17,9 +17,7 @@ typedef struct aes_cnt_cipher aes_cnt_cipher_t;
|
|||
|
||||
aes_cnt_cipher_t* aes_new_cipher(const uint8_t *key, const uint8_t *iv,
|
||||
int key_bits);
|
||||
void aes_cipher_free_(aes_cnt_cipher_t *cipher);
|
||||
#define aes_cipher_free(cipher) \
|
||||
FREE_AND_NULL(aes_cnt_cipher_t, aes_cipher_free_, (cipher))
|
||||
void aes_cipher_free(aes_cnt_cipher_t *cipher);
|
||||
void aes_crypt_inplace(aes_cnt_cipher_t *cipher, char *data, size_t len);
|
||||
|
||||
int evaluate_evp_for_aes(int force_value);
|
||||
|
|
|
@ -409,7 +409,7 @@ buf_slack(const buf_t *buf)
|
|||
|
||||
/** Release storage held by <b>buf</b>. */
|
||||
void
|
||||
buf_free_(buf_t *buf)
|
||||
buf_free(buf_t *buf)
|
||||
{
|
||||
if (!buf)
|
||||
return;
|
||||
|
@ -472,7 +472,7 @@ buf_add_chunk_with_capacity(buf_t *buf, size_t capacity, int capped)
|
|||
chunk = chunk_new_with_alloc_size(buf_preferred_chunk_size(capacity));
|
||||
}
|
||||
|
||||
chunk->inserted_time = monotime_coarse_get_stamp();
|
||||
chunk->inserted_time = (uint32_t)monotime_coarse_absolute_msec();
|
||||
|
||||
if (buf->tail) {
|
||||
tor_assert(buf->head);
|
||||
|
@ -487,8 +487,8 @@ buf_add_chunk_with_capacity(buf_t *buf, size_t capacity, int capped)
|
|||
}
|
||||
|
||||
/** Return the age of the oldest chunk in the buffer <b>buf</b>, in
|
||||
* timestamp units. Requires the current monotonic timestamp as its
|
||||
* input <b>now</b>.
|
||||
* milliseconds. Requires the current monotonic time, in truncated msec,
|
||||
* as its input <b>now</b>.
|
||||
*/
|
||||
uint32_t
|
||||
buf_get_oldest_chunk_timestamp(const buf_t *buf, uint32_t now)
|
||||
|
@ -714,53 +714,6 @@ buf_add(buf_t *buf, const char *string, size_t string_len)
|
|||
return (int)buf->datalen;
|
||||
}
|
||||
|
||||
/** Add a nul-terminated <b>string</b> to <b>buf</b>, not including the
|
||||
* terminating NUL. */
|
||||
void
|
||||
buf_add_string(buf_t *buf, const char *string)
|
||||
{
|
||||
buf_add(buf, string, strlen(string));
|
||||
}
|
||||
|
||||
/** As tor_snprintf, but write the results into a buf_t */
|
||||
void
|
||||
buf_add_printf(buf_t *buf, const char *format, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap,format);
|
||||
buf_add_vprintf(buf, format, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
/** As tor_vsnprintf, but write the results into a buf_t. */
|
||||
void
|
||||
buf_add_vprintf(buf_t *buf, const char *format, va_list args)
|
||||
{
|
||||
/* XXXX Faster implementations are easy enough, but let's optimize later */
|
||||
char *tmp;
|
||||
tor_vasprintf(&tmp, format, args);
|
||||
buf_add(buf, tmp, strlen(tmp));
|
||||
tor_free(tmp);
|
||||
}
|
||||
|
||||
/** Return a heap-allocated string containing the contents of <b>buf</b>, plus
|
||||
* a NUL byte. If <b>sz_out</b> is provided, set *<b>sz_out</b> to the length
|
||||
* of the returned string, not including the terminating NUL. */
|
||||
char *
|
||||
buf_extract(buf_t *buf, size_t *sz_out)
|
||||
{
|
||||
tor_assert(buf);
|
||||
|
||||
size_t sz = buf_datalen(buf);
|
||||
char *result;
|
||||
result = tor_malloc(sz+1);
|
||||
buf_peek(buf, result, sz);
|
||||
result[sz] = 0;
|
||||
if (sz_out)
|
||||
*sz_out = sz;
|
||||
return result;
|
||||
}
|
||||
|
||||
/** Helper: copy the first <b>string_len</b> bytes from <b>buf</b>
|
||||
* onto <b>string</b>.
|
||||
*/
|
||||
|
@ -842,28 +795,6 @@ buf_move_to_buf(buf_t *buf_out, buf_t *buf_in, size_t *buf_flushlen)
|
|||
return (int)cp;
|
||||
}
|
||||
|
||||
/** Moves all data from <b>buf_in</b> to <b>buf_out</b>, without copying.
|
||||
*/
|
||||
void
|
||||
buf_move_all(buf_t *buf_out, buf_t *buf_in)
|
||||
{
|
||||
tor_assert(buf_out);
|
||||
if (!buf_in)
|
||||
return;
|
||||
|
||||
if (buf_out->head == NULL) {
|
||||
buf_out->head = buf_in->head;
|
||||
buf_out->tail = buf_in->tail;
|
||||
} else {
|
||||
buf_out->tail->next = buf_in->head;
|
||||
buf_out->tail = buf_in->tail;
|
||||
}
|
||||
|
||||
buf_out->datalen += buf_in->datalen;
|
||||
buf_in->head = buf_in->tail = NULL;
|
||||
buf_in->datalen = 0;
|
||||
}
|
||||
|
||||
/** Internal structure: represents a position in a buffer. */
|
||||
typedef struct buf_pos_t {
|
||||
const chunk_t *chunk; /**< Which chunk are we pointing to? */
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#ifndef TOR_BUFFERS_H
|
||||
#define TOR_BUFFERS_H
|
||||
|
||||
#include "compat.h"
|
||||
#include "compat.h"
|
||||
#include "torint.h"
|
||||
#include "testsupport.h"
|
||||
|
@ -23,8 +24,7 @@ struct tor_compress_state_t;
|
|||
buf_t *buf_new(void);
|
||||
buf_t *buf_new_with_capacity(size_t size);
|
||||
size_t buf_get_default_chunk_size(const buf_t *buf);
|
||||
void buf_free_(buf_t *buf);
|
||||
#define buf_free(b) FREE_AND_NULL(buf_t, buf_free_, (b))
|
||||
void buf_free(buf_t *buf);
|
||||
void buf_clear(buf_t *buf);
|
||||
buf_t *buf_copy(const buf_t *buf);
|
||||
|
||||
|
@ -43,15 +43,9 @@ int buf_flush_to_socket(buf_t *buf, tor_socket_t s, size_t sz,
|
|||
size_t *buf_flushlen);
|
||||
|
||||
int buf_add(buf_t *buf, const char *string, size_t string_len);
|
||||
void buf_add_string(buf_t *buf, const char *string);
|
||||
void buf_add_printf(buf_t *buf, const char *format, ...)
|
||||
CHECK_PRINTF(2, 3);
|
||||
void buf_add_vprintf(buf_t *buf, const char *format, va_list args)
|
||||
CHECK_PRINTF(2, 0);
|
||||
int buf_add_compress(buf_t *buf, struct tor_compress_state_t *state,
|
||||
const char *data, size_t data_len, int done);
|
||||
int buf_move_to_buf(buf_t *buf_out, buf_t *buf_in, size_t *buf_flushlen);
|
||||
void buf_move_all(buf_t *buf_out, buf_t *buf_in);
|
||||
void buf_peek(const buf_t *buf, char *string, size_t string_len);
|
||||
void buf_drain(buf_t *buf, size_t n);
|
||||
int buf_get_bytes(buf_t *buf, char *string, size_t string_len);
|
||||
|
@ -68,7 +62,6 @@ void buf_assert_ok(buf_t *buf);
|
|||
int buf_find_string_offset(const buf_t *buf, const char *s, size_t n);
|
||||
void buf_pullup(buf_t *buf, size_t bytes,
|
||||
const char **head_out, size_t *len_out);
|
||||
char *buf_extract(buf_t *buf, size_t *sz_out);
|
||||
|
||||
#ifdef BUFFERS_PRIVATE
|
||||
#ifdef TOR_UNIT_TESTS
|
||||
|
@ -86,7 +79,8 @@ typedef struct chunk_t {
|
|||
size_t DBG_alloc;
|
||||
#endif
|
||||
char *data; /**< A pointer to the first byte of data stored in <b>mem</b>. */
|
||||
uint32_t inserted_time; /**< Timestamp when this chunk was inserted. */
|
||||
uint32_t inserted_time; /**< Timestamp in truncated ms since epoch
|
||||
* when this chunk was inserted. */
|
||||
char mem[FLEXIBLE_ARRAY_MEMBER]; /**< The actual memory used for storage in
|
||||
* this chunk. */
|
||||
} chunk_t;
|
||||
|
|
|
@ -100,6 +100,7 @@ SecureZeroMemory(PVOID ptr, SIZE_T cnt)
|
|||
/* Only use the linux prctl; the IRIX prctl is totally different */
|
||||
#include <sys/prctl.h>
|
||||
#elif defined(__APPLE__)
|
||||
#include <sys/types.h>
|
||||
#include <sys/ptrace.h>
|
||||
#endif /* defined(HAVE_SYS_PRCTL_H) && defined(__linux__) || ... */
|
||||
|
||||
|
@ -115,7 +116,7 @@ SecureZeroMemory(PVOID ptr, SIZE_T cnt)
|
|||
#ifdef HAVE_SIGNAL_H
|
||||
#include <signal.h>
|
||||
#endif
|
||||
#ifdef HAVE_MMAP
|
||||
#ifdef HAVE_SYS_MMAN_H
|
||||
#include <sys/mman.h>
|
||||
#endif
|
||||
#ifdef HAVE_SYS_SYSLIMITS_H
|
||||
|
@ -203,17 +204,25 @@ tor_rename(const char *path_old, const char *path_new)
|
|||
sandbox_intern_string(path_new));
|
||||
}
|
||||
|
||||
#if defined(HAVE_MMAP) || defined(RUNNING_DOXYGEN)
|
||||
/* Some MinGW builds have sys/mman.h, but not the corresponding symbols.
|
||||
* Other configs rename the symbols using macros (including getpagesize).
|
||||
* So check for sys/mman.h and unistd.h, and a getpagesize declaration. */
|
||||
#if (defined(HAVE_SYS_MMAN_H) && defined(HAVE_UNISTD_H) && \
|
||||
defined(HAVE_DECL_GETPAGESIZE))
|
||||
#define COMPAT_HAS_MMAN_AND_PAGESIZE
|
||||
#endif
|
||||
|
||||
#if defined(COMPAT_HAS_MMAN_AND_PAGESIZE) || \
|
||||
defined(RUNNING_DOXYGEN)
|
||||
/** Try to create a memory mapping for <b>filename</b> and return it. On
|
||||
* failure, return NULL. Sets errno properly, using ERANGE to mean
|
||||
* "empty file". Must only be called on trusted Tor-owned files, as changing
|
||||
* the underlying file's size causes unspecified behavior. */
|
||||
* failure, return NULL. Sets errno properly, using ERANGE to mean
|
||||
* "empty file". */
|
||||
tor_mmap_t *
|
||||
tor_mmap_file(const char *filename)
|
||||
{
|
||||
int fd; /* router file */
|
||||
char *string;
|
||||
int result;
|
||||
int page_size, result;
|
||||
tor_mmap_t *res;
|
||||
size_t size, filesize;
|
||||
struct stat st;
|
||||
|
@ -242,6 +251,13 @@ tor_mmap_file(const char *filename)
|
|||
return NULL;
|
||||
}
|
||||
size = filesize = (size_t)(st.st_size);
|
||||
/*
|
||||
* Should we check for weird crap like mmapping a named pipe here,
|
||||
* or just wait for if (!size) below to fail?
|
||||
*/
|
||||
/* ensure page alignment */
|
||||
page_size = getpagesize();
|
||||
size += (size%page_size) ? page_size-(size%page_size) : 0;
|
||||
|
||||
if (st.st_size > SSIZE_T_CEILING || (off_t)size < st.st_size) {
|
||||
log_warn(LD_FS, "File \"%s\" is too large. Ignoring.",filename);
|
||||
|
@ -402,8 +418,40 @@ tor_munmap_file(tor_mmap_t *handle)
|
|||
return 0;
|
||||
}
|
||||
#else
|
||||
#error "cannot implement tor_mmap_file"
|
||||
#endif /* defined(HAVE_MMAP) || ... || ... */
|
||||
tor_mmap_t *
|
||||
tor_mmap_file(const char *filename)
|
||||
{
|
||||
struct stat st;
|
||||
char *res = read_file_to_str(filename, RFTS_BIN|RFTS_IGNORE_MISSING, &st);
|
||||
tor_mmap_t *handle;
|
||||
if (! res)
|
||||
return NULL;
|
||||
handle = tor_malloc_zero(sizeof(tor_mmap_t));
|
||||
handle->data = res;
|
||||
handle->size = st.st_size;
|
||||
return handle;
|
||||
}
|
||||
|
||||
/** Unmap the file mapped with tor_mmap_file(), and return 0 for success
|
||||
* or -1 for failure.
|
||||
*/
|
||||
|
||||
int
|
||||
tor_munmap_file(tor_mmap_t *handle)
|
||||
{
|
||||
char *d = NULL;
|
||||
if (handle == NULL)
|
||||
return 0;
|
||||
|
||||
d = (char*)handle->data;
|
||||
tor_free(d);
|
||||
memwipe(handle, 0, sizeof(tor_mmap_t));
|
||||
tor_free(handle);
|
||||
|
||||
/* Can't fail in this mmap()/munmap()-free case */
|
||||
return 0;
|
||||
}
|
||||
#endif /* defined(COMPAT_HAS_MMAN_AND_PAGESIZE) || ... || ... */
|
||||
|
||||
/** Replacement for snprintf. Differs from platform snprintf in two
|
||||
* ways: First, always NUL-terminates its output. Second, always
|
||||
|
@ -1138,7 +1186,7 @@ mark_socket_open(tor_socket_t s)
|
|||
bitarray_set(open_sockets, s);
|
||||
}
|
||||
#else /* !(defined(DEBUG_SOCKET_COUNTING)) */
|
||||
#define mark_socket_open(s) ((void) (s))
|
||||
#define mark_socket_open(s) STMT_NIL
|
||||
#endif /* defined(DEBUG_SOCKET_COUNTING) */
|
||||
/** @} */
|
||||
|
||||
|
@ -1225,22 +1273,11 @@ tor_open_socket_with_extensions(int domain, int type, int protocol,
|
|||
goto socket_ok; /* So that socket_ok will not be unused. */
|
||||
|
||||
socket_ok:
|
||||
tor_take_socket_ownership(s);
|
||||
return s;
|
||||
}
|
||||
|
||||
/**
|
||||
* For socket accounting: remember that we are the owner of the socket
|
||||
* <b>s</b>. This will prevent us from overallocating sockets, and prevent us
|
||||
* from asserting later when we close the socket <b>s</b>.
|
||||
*/
|
||||
void
|
||||
tor_take_socket_ownership(tor_socket_t s)
|
||||
{
|
||||
socket_accounting_lock();
|
||||
++n_sockets_open;
|
||||
mark_socket_open(s);
|
||||
socket_accounting_unlock();
|
||||
return s;
|
||||
}
|
||||
|
||||
/** As accept(), but counts the number of open sockets. */
|
||||
|
@ -1321,7 +1358,10 @@ tor_accept_socket_with_extensions(tor_socket_t sockfd, struct sockaddr *addr,
|
|||
goto socket_ok; /* So that socket_ok will not be unused. */
|
||||
|
||||
socket_ok:
|
||||
tor_take_socket_ownership(s);
|
||||
socket_accounting_lock();
|
||||
++n_sockets_open;
|
||||
mark_socket_open(s);
|
||||
socket_accounting_unlock();
|
||||
return s;
|
||||
}
|
||||
|
||||
|
@ -1344,24 +1384,6 @@ tor_getsockname,(tor_socket_t sock, struct sockaddr *address,
|
|||
return getsockname(sock, address, address_len);
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the local address associated with the socket <b>sock</b>, and
|
||||
* place it in *<b>addr_out</b>. Return 0 on success, -1 on failure.
|
||||
*
|
||||
* (As tor_getsockname, but instead places the result in a tor_addr_t.) */
|
||||
int
|
||||
tor_addr_from_getsockname(tor_addr_t *addr_out, tor_socket_t sock)
|
||||
{
|
||||
struct sockaddr_storage ss;
|
||||
socklen_t ss_len = sizeof(ss);
|
||||
memset(&ss, 0, sizeof(ss));
|
||||
|
||||
if (tor_getsockname(sock, (struct sockaddr *) &ss, &ss_len) < 0)
|
||||
return -1;
|
||||
|
||||
return tor_addr_from_sockaddr(addr_out, (struct sockaddr *)&ss, NULL);
|
||||
}
|
||||
|
||||
/** Turn <b>socket</b> into a nonblocking socket. Return 0 on success, -1
|
||||
* on failure.
|
||||
*/
|
||||
|
@ -1875,12 +1897,9 @@ tor_passwd_dup(const struct passwd *pw)
|
|||
return new_pw;
|
||||
}
|
||||
|
||||
#define tor_passwd_free(pw) \
|
||||
FREE_AND_NULL(struct passwd, tor_passwd_free_, (pw))
|
||||
|
||||
/** Helper: free one of our cached 'struct passwd' values. */
|
||||
static void
|
||||
tor_passwd_free_(struct passwd *pw)
|
||||
tor_passwd_free(struct passwd *pw)
|
||||
{
|
||||
if (!pw)
|
||||
return;
|
||||
|
@ -2425,7 +2444,7 @@ get_environment(void)
|
|||
|
||||
/** Get name of current host and write it to <b>name</b> array, whose
|
||||
* length is specified by <b>namelen</b> argument. Return 0 upon
|
||||
* successful completion; otherwise return return -1. (Currently,
|
||||
* successfull completion; otherwise return return -1. (Currently,
|
||||
* this function is merely a mockable wrapper for POSIX gethostname().)
|
||||
*/
|
||||
MOCK_IMPL(int,
|
||||
|
@ -2860,7 +2879,7 @@ compute_num_cpus(void)
|
|||
/** Helper: Deal with confused or out-of-bounds values from localtime_r and
|
||||
* friends. (On some platforms, they can give out-of-bounds values or can
|
||||
* return NULL.) If <b>islocal</b>, this is a localtime result; otherwise
|
||||
* it's from gmtime. The function returns <b>r</b>, when given <b>timep</b>
|
||||
* it's from gmtime. The function returned <b>r</b>, when given <b>timep</b>
|
||||
* as its input. If we need to store new results, store them in
|
||||
* <b>resultbuf</b>. */
|
||||
static struct tm *
|
||||
|
@ -3379,8 +3398,8 @@ get_total_system_memory_impl(void)
|
|||
* Try to find out how much physical memory the system has. On success,
|
||||
* return 0 and set *<b>mem_out</b> to that value. On failure, return -1.
|
||||
*/
|
||||
MOCK_IMPL(int,
|
||||
get_total_system_memory, (size_t *mem_out))
|
||||
int
|
||||
get_total_system_memory(size_t *mem_out)
|
||||
{
|
||||
static size_t mem_cached=0;
|
||||
uint64_t m = get_total_system_memory_impl();
|
||||
|
|
|
@ -10,9 +10,6 @@
|
|||
#ifdef _WIN32
|
||||
#include <winsock2.h>
|
||||
#include <ws2tcpip.h>
|
||||
#ifndef SIO_IDEAL_SEND_BACKLOG_QUERY
|
||||
#define SIO_IDEAL_SEND_BACKLOG_QUERY 0x4004747b
|
||||
#endif
|
||||
#endif
|
||||
#include "torint.h"
|
||||
#include "testsupport.h"
|
||||
|
@ -318,12 +315,12 @@ typedef struct tor_mmap_t {
|
|||
size_t size; /**< Size of the file. */
|
||||
|
||||
/* None of the fields below should be accessed from outside compat.c */
|
||||
#ifdef HAVE_MMAP
|
||||
#ifdef HAVE_SYS_MMAN_H
|
||||
size_t mapping_size; /**< Size of the actual mapping. (This is this file
|
||||
* size, rounded up to the nearest page.) */
|
||||
#elif defined _WIN32
|
||||
HANDLE mmap_handle;
|
||||
#endif /* defined(HAVE_MMAP) || ... */
|
||||
#endif /* defined(HAVE_SYS_MMAN_H) || ... */
|
||||
|
||||
} tor_mmap_t;
|
||||
|
||||
|
@ -486,7 +483,6 @@ typedef int socklen_t;
|
|||
|
||||
int tor_close_socket_simple(tor_socket_t s);
|
||||
MOCK_DECL(int, tor_close_socket, (tor_socket_t s));
|
||||
void tor_take_socket_ownership(tor_socket_t s);
|
||||
tor_socket_t tor_open_socket_with_extensions(
|
||||
int domain, int type, int protocol,
|
||||
int cloexec, int nonblock);
|
||||
|
@ -510,8 +506,6 @@ int get_n_open_sockets(void);
|
|||
MOCK_DECL(int,
|
||||
tor_getsockname,(tor_socket_t socket, struct sockaddr *address,
|
||||
socklen_t *address_len));
|
||||
struct tor_addr_t;
|
||||
int tor_addr_from_getsockname(struct tor_addr_t *addr_out, tor_socket_t sock);
|
||||
|
||||
#define tor_socket_send(s, buf, len, flags) send(s, buf, len, flags)
|
||||
#define tor_socket_recv(s, buf, len, flags) recv(s, buf, len, flags)
|
||||
|
@ -701,7 +695,7 @@ char *make_path_absolute(char *fname);
|
|||
|
||||
char **get_environment(void);
|
||||
|
||||
MOCK_DECL(int, get_total_system_memory, (size_t *mem_out));
|
||||
int get_total_system_memory(size_t *mem_out);
|
||||
|
||||
int compute_num_cpus(void);
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
#define COMPAT_LIBEVENT_PRIVATE
|
||||
#include "compat_libevent.h"
|
||||
|
||||
#include "crypto_rand.h"
|
||||
#include "crypto.h"
|
||||
|
||||
#include "util.h"
|
||||
#include "torlog.h"
|
||||
|
@ -69,7 +69,7 @@ suppress_libevent_log_msg(const char *msg)
|
|||
|
||||
/* Wrapper for event_free() that tolerates tor_event_free(NULL) */
|
||||
void
|
||||
tor_event_free_(struct event *ev)
|
||||
tor_event_free(struct event *ev)
|
||||
{
|
||||
if (ev == NULL)
|
||||
return;
|
||||
|
@ -79,43 +79,6 @@ tor_event_free_(struct event *ev)
|
|||
/** Global event base for use by the main thread. */
|
||||
static struct event_base *the_event_base = NULL;
|
||||
|
||||
/**
|
||||
* @defgroup postloop post-loop event helpers
|
||||
*
|
||||
* If we're not careful, Libevent can susceptible to infinite event chains:
|
||||
* one event can activate another, whose callback activates another, whose
|
||||
* callback activates another, ad infinitum. While this is happening,
|
||||
* Libevent won't be checking timeouts, socket-based events, signals, and so
|
||||
* on.
|
||||
*
|
||||
* We solve this problem by marking some events as "post-loop". A post-loop
|
||||
* event behaves like any ordinary event, but any events that _it_ activates
|
||||
* cannot run until Libevent has checked for other events at least once.
|
||||
*
|
||||
* @{ */
|
||||
|
||||
/**
|
||||
* An event that stops Libevent from running any more events on the current
|
||||
* iteration of its loop, until it has re-checked for socket events, signal
|
||||
* events, timeouts, etc.
|
||||
*/
|
||||
static struct event *rescan_mainloop_ev = NULL;
|
||||
|
||||
/**
|
||||
* Callback to implement rescan_mainloop_ev: it simply exits the mainloop,
|
||||
* and relies on Tor to re-enter the mainloop since no error has occurred.
|
||||
*/
|
||||
static void
|
||||
rescan_mainloop_cb(evutil_socket_t fd, short events, void *arg)
|
||||
{
|
||||
(void)fd;
|
||||
(void)events;
|
||||
struct event_base *the_base = arg;
|
||||
event_base_loopbreak(the_base);
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
||||
/* This is what passes for version detection on OSX. We set
|
||||
* MACOSX_KQUEUE_IS_BROKEN to true iff we're on a version of OSX before
|
||||
* 10.4.0 (aka 1040). */
|
||||
|
@ -163,16 +126,7 @@ tor_libevent_initialize(tor_libevent_cfg *torcfg)
|
|||
if (!the_event_base) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_err(LD_GENERAL, "Unable to initialize Libevent: cannot continue.");
|
||||
exit(1); // exit ok: libevent is broken.
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
rescan_mainloop_ev = event_new(the_event_base, -1, 0,
|
||||
rescan_mainloop_cb, the_event_base);
|
||||
if (!rescan_mainloop_ev) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_err(LD_GENERAL, "Unable to create rescan event: cannot continue.");
|
||||
exit(1); // exit ok: libevent is broken.
|
||||
exit(1);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
|
@ -253,42 +207,13 @@ periodic_timer_new(struct event_base *base,
|
|||
}
|
||||
timer->cb = cb;
|
||||
timer->data = data;
|
||||
periodic_timer_launch(timer, tv);
|
||||
event_add(timer->ev, (struct timeval *)tv); /*drop const for old libevent*/
|
||||
return timer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Launch the timer <b>timer</b> to run at <b>tv</b> from now, and every
|
||||
* <b>tv</b> thereafter.
|
||||
*
|
||||
* If the timer is already enabled, this function does nothing.
|
||||
*/
|
||||
void
|
||||
periodic_timer_launch(periodic_timer_t *timer, const struct timeval *tv)
|
||||
{
|
||||
tor_assert(timer);
|
||||
if (event_pending(timer->ev, EV_TIMEOUT, NULL))
|
||||
return;
|
||||
event_add(timer->ev, tv);
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable the provided <b>timer</b>, but do not free it.
|
||||
*
|
||||
* You can reenable the same timer later with periodic_timer_launch.
|
||||
*
|
||||
* If the timer is already disabled, this function does nothing.
|
||||
*/
|
||||
void
|
||||
periodic_timer_disable(periodic_timer_t *timer)
|
||||
{
|
||||
tor_assert(timer);
|
||||
(void) event_del(timer->ev);
|
||||
}
|
||||
|
||||
/** Stop and free a periodic timer */
|
||||
void
|
||||
periodic_timer_free_(periodic_timer_t *timer)
|
||||
periodic_timer_free(periodic_timer_t *timer)
|
||||
{
|
||||
if (!timer)
|
||||
return;
|
||||
|
@ -296,173 +221,6 @@ periodic_timer_free_(periodic_timer_t *timer)
|
|||
tor_free(timer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Type used to represent events that run directly from the main loop,
|
||||
* either because they are activated from elsewhere in the code, or
|
||||
* because they have a simple timeout.
|
||||
*
|
||||
* We use this type to avoid exposing Libevent's API throughout the rest
|
||||
* of the codebase.
|
||||
*
|
||||
* This type can't be used for all events: it doesn't handle events that
|
||||
* are triggered by signals or by sockets.
|
||||
*/
|
||||
struct mainloop_event_t {
|
||||
struct event *ev;
|
||||
void (*cb)(mainloop_event_t *, void *);
|
||||
void *userdata;
|
||||
};
|
||||
|
||||
/**
|
||||
* Internal: Implements mainloop event using a libevent event.
|
||||
*/
|
||||
static void
|
||||
mainloop_event_cb(evutil_socket_t fd, short what, void *arg)
|
||||
{
|
||||
(void)fd;
|
||||
(void)what;
|
||||
mainloop_event_t *mev = arg;
|
||||
mev->cb(mev, mev->userdata);
|
||||
}
|
||||
|
||||
/**
|
||||
* As mainloop_event_cb, but implements a post-loop event.
|
||||
*/
|
||||
static void
|
||||
mainloop_event_postloop_cb(evutil_socket_t fd, short what, void *arg)
|
||||
{
|
||||
(void)fd;
|
||||
(void)what;
|
||||
|
||||
/* Note that if rescan_mainloop_ev is already activated,
|
||||
* event_active() will do nothing: only the first post-loop event that
|
||||
* happens each time through the event loop will cause it to be
|
||||
* activated.
|
||||
*
|
||||
* Because event_active() puts events on a FIFO queue, every event
|
||||
* that is made active _after_ rescan_mainloop_ev will get its
|
||||
* callback run after rescan_mainloop_cb is called -- that is, on the
|
||||
* next iteration of the loop.
|
||||
*/
|
||||
event_active(rescan_mainloop_ev, EV_READ, 1);
|
||||
|
||||
mainloop_event_t *mev = arg;
|
||||
mev->cb(mev, mev->userdata);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper for mainloop_event_new() and mainloop_event_postloop_new().
|
||||
*/
|
||||
static mainloop_event_t *
|
||||
mainloop_event_new_impl(int postloop,
|
||||
void (*cb)(mainloop_event_t *, void *),
|
||||
void *userdata)
|
||||
{
|
||||
tor_assert(cb);
|
||||
|
||||
struct event_base *base = tor_libevent_get_base();
|
||||
mainloop_event_t *mev = tor_malloc_zero(sizeof(mainloop_event_t));
|
||||
mev->ev = tor_event_new(base, -1, 0,
|
||||
postloop ? mainloop_event_postloop_cb : mainloop_event_cb,
|
||||
mev);
|
||||
tor_assert(mev->ev);
|
||||
mev->cb = cb;
|
||||
mev->userdata = userdata;
|
||||
return mev;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create and return a new mainloop_event_t to run the function <b>cb</b>.
|
||||
*
|
||||
* When run, the callback function will be passed the mainloop_event_t
|
||||
* and <b>userdata</b> as its arguments. The <b>userdata</b> pointer
|
||||
* must remain valid for as long as the mainloop_event_t event exists:
|
||||
* it is your responsibility to free it.
|
||||
*
|
||||
* The event is not scheduled by default: Use mainloop_event_activate()
|
||||
* or mainloop_event_schedule() to make it run.
|
||||
*/
|
||||
mainloop_event_t *
|
||||
mainloop_event_new(void (*cb)(mainloop_event_t *, void *),
|
||||
void *userdata)
|
||||
{
|
||||
return mainloop_event_new_impl(0, cb, userdata);
|
||||
}
|
||||
|
||||
/**
|
||||
* As mainloop_event_new(), but create a post-loop event.
|
||||
*
|
||||
* A post-loop event behaves like any ordinary event, but any events
|
||||
* that _it_ activates cannot run until Libevent has checked for other
|
||||
* events at least once.
|
||||
*/
|
||||
mainloop_event_t *
|
||||
mainloop_event_postloop_new(void (*cb)(mainloop_event_t *, void *),
|
||||
void *userdata)
|
||||
{
|
||||
return mainloop_event_new_impl(1, cb, userdata);
|
||||
}
|
||||
|
||||
/**
|
||||
* Schedule <b>event</b> to run in the main loop, immediately. If it is
|
||||
* not scheduled, it will run anyway. If it is already scheduled to run
|
||||
* later, it will run now instead. This function will have no effect if
|
||||
* the event is already scheduled to run.
|
||||
*
|
||||
* This function may only be called from the main thread.
|
||||
*/
|
||||
void
|
||||
mainloop_event_activate(mainloop_event_t *event)
|
||||
{
|
||||
tor_assert(event);
|
||||
event_active(event->ev, EV_READ, 1);
|
||||
}
|
||||
|
||||
/** Schedule <b>event</b> to run in the main loop, after a delay of <b>tv</b>.
|
||||
*
|
||||
* If the event is scheduled for a different time, cancel it and run
|
||||
* after this delay instead. If the event is currently pending to run
|
||||
* <em>now</b>, has no effect.
|
||||
*
|
||||
* Do not call this function with <b>tv</b> == NULL -- use
|
||||
* mainloop_event_activate() instead.
|
||||
*
|
||||
* This function may only be called from the main thread.
|
||||
*/
|
||||
int
|
||||
mainloop_event_schedule(mainloop_event_t *event, const struct timeval *tv)
|
||||
{
|
||||
tor_assert(event);
|
||||
if (BUG(tv == NULL)) {
|
||||
// LCOV_EXCL_START
|
||||
mainloop_event_activate(event);
|
||||
return 0;
|
||||
// LCOV_EXCL_STOP
|
||||
}
|
||||
return event_add(event->ev, tv);
|
||||
}
|
||||
|
||||
/** Cancel <b>event</b> if it is currently active or pending. (Do nothing if
|
||||
* the event is not currently active or pending.) */
|
||||
void
|
||||
mainloop_event_cancel(mainloop_event_t *event)
|
||||
{
|
||||
if (!event)
|
||||
return;
|
||||
(void) event_del(event->ev);
|
||||
}
|
||||
|
||||
/** Cancel <b>event</b> and release all storage associated with it. */
|
||||
void
|
||||
mainloop_event_free_(mainloop_event_t *event)
|
||||
{
|
||||
if (!event)
|
||||
return;
|
||||
tor_event_free(event->ev);
|
||||
memset(event, 0xb8, sizeof(*event));
|
||||
tor_free(event);
|
||||
}
|
||||
|
||||
int
|
||||
tor_init_libevent_rng(void)
|
||||
{
|
||||
|
@ -479,51 +237,51 @@ tor_init_libevent_rng(void)
|
|||
return rv;
|
||||
}
|
||||
|
||||
/**
|
||||
* Un-initialize libevent in preparation for an exit
|
||||
*/
|
||||
#if defined(LIBEVENT_VERSION_NUMBER) && \
|
||||
LIBEVENT_VERSION_NUMBER >= V(2,1,1) && \
|
||||
!defined(TOR_UNIT_TESTS)
|
||||
void
|
||||
tor_libevent_free_all(void)
|
||||
tor_gettimeofday_cached(struct timeval *tv)
|
||||
{
|
||||
tor_event_free(rescan_mainloop_ev);
|
||||
if (the_event_base)
|
||||
event_base_free(the_event_base);
|
||||
the_event_base = NULL;
|
||||
event_base_gettimeofday_cached(the_event_base, tv);
|
||||
}
|
||||
|
||||
/**
|
||||
* Run the event loop for the provided event_base, handling events until
|
||||
* something stops it. If <b>once</b> is set, then just poll-and-run
|
||||
* once, then exit. Return 0 on success, -1 if an error occurred, or 1
|
||||
* if we exited because no events were pending or active.
|
||||
*
|
||||
* This isn't reentrant or multithreaded.
|
||||
*/
|
||||
int
|
||||
tor_libevent_run_event_loop(struct event_base *base, int once)
|
||||
{
|
||||
const int flags = once ? EVLOOP_ONCE : 0;
|
||||
return event_base_loop(base, flags);
|
||||
}
|
||||
|
||||
/** Tell the event loop to exit after <b>delay</b>. If <b>delay</b> is NULL,
|
||||
* instead exit after we're done running the currently active events. */
|
||||
void
|
||||
tor_libevent_exit_loop_after_delay(struct event_base *base,
|
||||
const struct timeval *delay)
|
||||
tor_gettimeofday_cache_clear(void)
|
||||
{
|
||||
event_base_loopexit(base, delay);
|
||||
event_base_update_cache_time(the_event_base);
|
||||
}
|
||||
#else /* !(defined(LIBEVENT_VERSION_NUMBER) && ...) */
|
||||
/** Cache the current hi-res time; the cache gets reset when libevent
|
||||
* calls us. */
|
||||
static struct timeval cached_time_hires = {0, 0};
|
||||
|
||||
/** Tell the event loop to exit after running whichever callback is currently
|
||||
* active. */
|
||||
/** Return a fairly recent view of the current time. */
|
||||
void
|
||||
tor_libevent_exit_loop_after_callback(struct event_base *base)
|
||||
tor_gettimeofday_cached(struct timeval *tv)
|
||||
{
|
||||
event_base_loopbreak(base);
|
||||
if (cached_time_hires.tv_sec == 0) {
|
||||
tor_gettimeofday(&cached_time_hires);
|
||||
}
|
||||
*tv = cached_time_hires;
|
||||
}
|
||||
|
||||
/** Reset the cached view of the current time, so that the next time we try
|
||||
* to learn it, we will get an up-to-date value. */
|
||||
void
|
||||
tor_gettimeofday_cache_clear(void)
|
||||
{
|
||||
cached_time_hires.tv_sec = 0;
|
||||
}
|
||||
|
||||
#ifdef TOR_UNIT_TESTS
|
||||
/** For testing: force-update the cached time to a given value. */
|
||||
void
|
||||
tor_gettimeofday_cache_set(const struct timeval *tv)
|
||||
{
|
||||
tor_assert(tv);
|
||||
memcpy(&cached_time_hires, tv, sizeof(*tv));
|
||||
}
|
||||
|
||||
#if defined(TOR_UNIT_TESTS)
|
||||
/** For testing: called post-fork to make libevent reinitialize
|
||||
* kernel structures. */
|
||||
void
|
||||
|
@ -533,4 +291,5 @@ tor_libevent_postfork(void)
|
|||
tor_assert(r == 0);
|
||||
}
|
||||
#endif /* defined(TOR_UNIT_TESTS) */
|
||||
#endif /* defined(LIBEVENT_VERSION_NUMBER) && ... */
|
||||
|
||||
|
|
|
@ -7,6 +7,8 @@
|
|||
#include "orconfig.h"
|
||||
#include "testsupport.h"
|
||||
|
||||
#include <event2/event.h>
|
||||
|
||||
void configure_libevent_logging(void);
|
||||
void suppress_libevent_log_msg(const char *msg);
|
||||
|
||||
|
@ -17,12 +19,7 @@ void suppress_libevent_log_msg(const char *msg);
|
|||
evdns_add_server_port_with_base(tor_libevent_get_base(), \
|
||||
(sock),(tcp),(cb),(data));
|
||||
|
||||
struct event;
|
||||
struct event_base;
|
||||
|
||||
void tor_event_free_(struct event *ev);
|
||||
#define tor_event_free(ev) \
|
||||
FREE_AND_NULL(struct event, tor_event_free_, (ev))
|
||||
void tor_event_free(struct event *ev);
|
||||
|
||||
typedef struct periodic_timer_t periodic_timer_t;
|
||||
|
||||
|
@ -30,25 +27,9 @@ periodic_timer_t *periodic_timer_new(struct event_base *base,
|
|||
const struct timeval *tv,
|
||||
void (*cb)(periodic_timer_t *timer, void *data),
|
||||
void *data);
|
||||
void periodic_timer_free_(periodic_timer_t *);
|
||||
void periodic_timer_launch(periodic_timer_t *, const struct timeval *tv);
|
||||
void periodic_timer_disable(periodic_timer_t *);
|
||||
#define periodic_timer_free(t) \
|
||||
FREE_AND_NULL(periodic_timer_t, periodic_timer_free_, (t))
|
||||
void periodic_timer_free(periodic_timer_t *);
|
||||
|
||||
typedef struct mainloop_event_t mainloop_event_t;
|
||||
mainloop_event_t *mainloop_event_new(void (*cb)(mainloop_event_t *, void *),
|
||||
void *userdata);
|
||||
mainloop_event_t * mainloop_event_postloop_new(
|
||||
void (*cb)(mainloop_event_t *, void *),
|
||||
void *userdata);
|
||||
void mainloop_event_activate(mainloop_event_t *event);
|
||||
int mainloop_event_schedule(mainloop_event_t *event,
|
||||
const struct timeval *delay);
|
||||
void mainloop_event_cancel(mainloop_event_t *event);
|
||||
void mainloop_event_free_(mainloop_event_t *event);
|
||||
#define mainloop_event_free(event) \
|
||||
FREE_AND_NULL(mainloop_event_t, mainloop_event_free_, (event))
|
||||
#define tor_event_base_loopexit event_base_loopexit
|
||||
|
||||
/** Defines a configuration for using libevent with Tor: passed as an argument
|
||||
* to tor_libevent_initialize() to describe how we want to set up. */
|
||||
|
@ -66,19 +47,16 @@ const char *tor_libevent_get_method(void);
|
|||
void tor_check_libevent_header_compatibility(void);
|
||||
const char *tor_libevent_get_version_str(void);
|
||||
const char *tor_libevent_get_header_version_str(void);
|
||||
void tor_libevent_free_all(void);
|
||||
|
||||
int tor_init_libevent_rng(void);
|
||||
|
||||
void tor_gettimeofday_cached(struct timeval *tv);
|
||||
void tor_gettimeofday_cache_clear(void);
|
||||
#ifdef TOR_UNIT_TESTS
|
||||
void tor_gettimeofday_cache_set(const struct timeval *tv);
|
||||
void tor_libevent_postfork(void);
|
||||
#endif
|
||||
|
||||
int tor_libevent_run_event_loop(struct event_base *base, int once);
|
||||
void tor_libevent_exit_loop_after_delay(struct event_base *base,
|
||||
const struct timeval *delay);
|
||||
void tor_libevent_exit_loop_after_callback(struct event_base *base);
|
||||
|
||||
#ifdef COMPAT_LIBEVENT_PRIVATE
|
||||
|
||||
/** Macro: returns the number of a Libevent version as a 4-byte number,
|
||||
|
|
|
@ -8,12 +8,11 @@
|
|||
#define TOR_COMPAT_OPENSSL_H
|
||||
|
||||
#include <openssl/opensslv.h>
|
||||
#include "crypto_openssl_mgt.h"
|
||||
|
||||
/**
|
||||
* \file compat_openssl.h
|
||||
*
|
||||
* \brief compatibility definitions for working with different openssl forks
|
||||
* \brief compatability definitions for working with different openssl forks
|
||||
**/
|
||||
|
||||
#if !defined(LIBRESSL_VERSION_NUMBER) && \
|
||||
|
@ -28,11 +27,8 @@
|
|||
#define OPENSSL_1_1_API
|
||||
#endif /* OPENSSL_VERSION_NUMBER >= OPENSSL_V_SERIES(1,1,0) && ... */
|
||||
|
||||
#ifndef OPENSSL_VERSION
|
||||
#define OPENSSL_VERSION SSLEAY_VERSION
|
||||
#endif
|
||||
|
||||
#ifndef OPENSSL_1_1_API
|
||||
#define OPENSSL_VERSION SSLEAY_VERSION
|
||||
#define OpenSSL_version(v) SSLeay_version(v)
|
||||
#define OpenSSL_version_num() SSLeay()
|
||||
#define RAND_OpenSSL() RAND_SSLeay()
|
||||
|
|
|
@ -0,0 +1,39 @@
|
|||
/* Copyright (c) 2017, The Tor Project, Inc. */
|
||||
/* See LICENSE for licensing information */
|
||||
|
||||
/**
|
||||
* \file rust_compat.c
|
||||
* \brief Rust FFI compatibility functions and helpers. This file is only built
|
||||
* if Rust is not used.
|
||||
**/
|
||||
|
||||
#include "compat_rust.h"
|
||||
#include "util.h"
|
||||
|
||||
/**
|
||||
* Free storage pointed to by <b>str</b>, and itself.
|
||||
*/
|
||||
void
|
||||
rust_str_free(rust_str_t str)
|
||||
{
|
||||
char *s = (char *)str;
|
||||
tor_free(s);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return zero-terminated contained string.
|
||||
*/
|
||||
const char *
|
||||
rust_str_get(const rust_str_t str)
|
||||
{
|
||||
return (const char *)str;
|
||||
}
|
||||
|
||||
/* If we were using Rust, we'd say so on startup. */
|
||||
rust_str_t
|
||||
rust_welcome_string(void)
|
||||
{
|
||||
char *s = tor_malloc_zero(1);
|
||||
return (rust_str_t)s;
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
/* Copyright (c) 2017, The Tor Project, Inc. */
|
||||
/* See LICENSE for licensing information */
|
||||
|
||||
/**
|
||||
* \file rust_compat.h
|
||||
* \brief Headers for rust_compat.c
|
||||
**/
|
||||
|
||||
#ifndef TOR_RUST_COMPAT_H
|
||||
#define TOR_RUST_COMPAT_H
|
||||
|
||||
#include "torint.h"
|
||||
|
||||
/**
|
||||
* Strings allocated in Rust must be freed from Rust code again. Let's make
|
||||
* it less likely to accidentally mess up and call tor_free() on it, because
|
||||
* currently it'll just work but might break at any time.
|
||||
*/
|
||||
typedef uintptr_t rust_str_t;
|
||||
|
||||
void rust_str_free(rust_str_t);
|
||||
|
||||
const char *rust_str_get(const rust_str_t);
|
||||
|
||||
rust_str_t rust_welcome_string(void);
|
||||
|
||||
#endif /* !defined(TOR_RUST_COMPAT_H) */
|
||||
|
|
@ -48,7 +48,7 @@ tor_mutex_new_nonrecursive(void)
|
|||
}
|
||||
/** Release all storage and system resources held by <b>m</b>. */
|
||||
void
|
||||
tor_mutex_free_(tor_mutex_t *m)
|
||||
tor_mutex_free(tor_mutex_t *m)
|
||||
{
|
||||
if (!m)
|
||||
return;
|
||||
|
@ -68,7 +68,7 @@ tor_cond_new(void)
|
|||
|
||||
/** Free all storage held in <b>c</b>. */
|
||||
void
|
||||
tor_cond_free_(tor_cond_t *c)
|
||||
tor_cond_free(tor_cond_t *c)
|
||||
{
|
||||
if (!c)
|
||||
return;
|
||||
|
@ -352,7 +352,12 @@ alert_sockets_close(alert_sockets_t *socks)
|
|||
socks->read_fd = socks->write_fd = -1;
|
||||
}
|
||||
|
||||
#ifndef HAVE_STDATOMIC_H
|
||||
/*
|
||||
* XXXX We might be smart to move to compiler intrinsics or real atomic
|
||||
* XXXX operations at some point. But not yet.
|
||||
*
|
||||
*/
|
||||
|
||||
/** Initialize a new atomic counter with the value 0 */
|
||||
void
|
||||
atomic_counter_init(atomic_counter_t *counter)
|
||||
|
@ -392,16 +397,4 @@ atomic_counter_get(atomic_counter_t *counter)
|
|||
tor_mutex_release(&counter->mutex);
|
||||
return val;
|
||||
}
|
||||
/** Replace the value of an atomic counter; return the old one. */
|
||||
size_t
|
||||
atomic_counter_exchange(atomic_counter_t *counter, size_t newval)
|
||||
{
|
||||
size_t oldval;
|
||||
tor_mutex_acquire(&counter->mutex);
|
||||
oldval = counter->val;
|
||||
counter->val = newval;
|
||||
tor_mutex_release(&counter->mutex);
|
||||
return oldval;
|
||||
}
|
||||
#endif /* !defined(HAVE_STDATOMIC_H) */
|
||||
|
||||
|
|
|
@ -14,10 +14,6 @@
|
|||
#include <pthread.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_STDATOMIC_H
|
||||
#include <stdatomic.h>
|
||||
#endif
|
||||
|
||||
#if defined(_WIN32)
|
||||
#define USE_WIN32_THREADS
|
||||
#elif defined(HAVE_PTHREAD_H) && defined(HAVE_PTHREAD_CREATE)
|
||||
|
@ -54,8 +50,7 @@ void tor_mutex_init(tor_mutex_t *m);
|
|||
void tor_mutex_init_nonrecursive(tor_mutex_t *m);
|
||||
void tor_mutex_acquire(tor_mutex_t *m);
|
||||
void tor_mutex_release(tor_mutex_t *m);
|
||||
void tor_mutex_free_(tor_mutex_t *m);
|
||||
#define tor_mutex_free(m) FREE_AND_NULL(tor_mutex_t, tor_mutex_free_, (m))
|
||||
void tor_mutex_free(tor_mutex_t *m);
|
||||
void tor_mutex_uninit(tor_mutex_t *m);
|
||||
unsigned long tor_get_thread_id(void);
|
||||
void tor_threads_init(void);
|
||||
|
@ -82,8 +77,7 @@ typedef struct tor_cond_t {
|
|||
} tor_cond_t;
|
||||
|
||||
tor_cond_t *tor_cond_new(void);
|
||||
void tor_cond_free_(tor_cond_t *cond);
|
||||
#define tor_cond_free(c) FREE_AND_NULL(tor_cond_t, tor_cond_free_, (c))
|
||||
void tor_cond_free(tor_cond_t *cond);
|
||||
int tor_cond_init(tor_cond_t *cond);
|
||||
void tor_cond_uninit(tor_cond_t *cond);
|
||||
int tor_cond_wait(tor_cond_t *cond, tor_mutex_t *mutex,
|
||||
|
@ -156,68 +150,16 @@ void tor_threadlocal_set(tor_threadlocal_t *threadlocal, void *value);
|
|||
/**
|
||||
* Atomic counter type; holds a size_t value.
|
||||
*/
|
||||
#ifdef HAVE_STDATOMIC_H
|
||||
typedef struct atomic_counter_t {
|
||||
atomic_size_t val;
|
||||
} atomic_counter_t;
|
||||
#define ATOMIC_LINKAGE static
|
||||
#else /* !(defined(HAVE_STDATOMIC_H)) */
|
||||
typedef struct atomic_counter_t {
|
||||
tor_mutex_t mutex;
|
||||
size_t val;
|
||||
} atomic_counter_t;
|
||||
#define ATOMIC_LINKAGE
|
||||
#endif /* defined(HAVE_STDATOMIC_H) */
|
||||
|
||||
ATOMIC_LINKAGE void atomic_counter_init(atomic_counter_t *counter);
|
||||
ATOMIC_LINKAGE void atomic_counter_destroy(atomic_counter_t *counter);
|
||||
ATOMIC_LINKAGE void atomic_counter_add(atomic_counter_t *counter, size_t add);
|
||||
ATOMIC_LINKAGE void atomic_counter_sub(atomic_counter_t *counter, size_t sub);
|
||||
ATOMIC_LINKAGE size_t atomic_counter_get(atomic_counter_t *counter);
|
||||
ATOMIC_LINKAGE size_t atomic_counter_exchange(atomic_counter_t *counter,
|
||||
size_t newval);
|
||||
#undef ATOMIC_LINKAGE
|
||||
|
||||
#ifdef HAVE_STDATOMIC_H
|
||||
/** Initialize a new atomic counter with the value 0 */
|
||||
static inline void
|
||||
atomic_counter_init(atomic_counter_t *counter)
|
||||
{
|
||||
atomic_init(&counter->val, 0);
|
||||
}
|
||||
/** Clean up all resources held by an atomic counter. */
|
||||
static inline void
|
||||
atomic_counter_destroy(atomic_counter_t *counter)
|
||||
{
|
||||
(void)counter;
|
||||
}
|
||||
/** Add a value to an atomic counter. */
|
||||
static inline void
|
||||
atomic_counter_add(atomic_counter_t *counter, size_t add)
|
||||
{
|
||||
(void) atomic_fetch_add(&counter->val, add);
|
||||
}
|
||||
/** Subtract a value from an atomic counter. */
|
||||
static inline void
|
||||
atomic_counter_sub(atomic_counter_t *counter, size_t sub)
|
||||
{
|
||||
(void) atomic_fetch_sub(&counter->val, sub);
|
||||
}
|
||||
/** Return the current value of an atomic counter */
|
||||
static inline size_t
|
||||
atomic_counter_get(atomic_counter_t *counter)
|
||||
{
|
||||
return atomic_load(&counter->val);
|
||||
}
|
||||
/** Replace the value of an atomic counter; return the old one. */
|
||||
static inline size_t
|
||||
atomic_counter_exchange(atomic_counter_t *counter, size_t newval)
|
||||
{
|
||||
return atomic_exchange(&counter->val, newval);
|
||||
}
|
||||
|
||||
#else /* !(defined(HAVE_STDATOMIC_H)) */
|
||||
#endif /* defined(HAVE_STDATOMIC_H) */
|
||||
void atomic_counter_init(atomic_counter_t *counter);
|
||||
void atomic_counter_destroy(atomic_counter_t *counter);
|
||||
void atomic_counter_add(atomic_counter_t *counter, size_t add);
|
||||
void atomic_counter_sub(atomic_counter_t *counter, size_t sub);
|
||||
size_t atomic_counter_get(atomic_counter_t *counter);
|
||||
|
||||
#endif /* !defined(TOR_COMPAT_THREADS_H) */
|
||||
|
||||
|
|
|
@ -71,8 +71,8 @@ tor_sleep_msec(int msec)
|
|||
/** Set *timeval to the current time of day. On error, log and terminate.
|
||||
* (Same as gettimeofday(timeval,NULL), but never returns -1.)
|
||||
*/
|
||||
MOCK_IMPL(void,
|
||||
tor_gettimeofday, (struct timeval *timeval))
|
||||
void
|
||||
tor_gettimeofday(struct timeval *timeval)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
/* Epoch bias copied from perl: number of units between windows epoch and
|
||||
|
@ -90,7 +90,7 @@ tor_gettimeofday, (struct timeval *timeval))
|
|||
if (ft.ft_64 < EPOCH_BIAS) {
|
||||
/* LCOV_EXCL_START */
|
||||
log_err(LD_GENERAL,"System time is before 1970; failing.");
|
||||
exit(1); // exit ok: system clock is broken.
|
||||
exit(1);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
ft.ft_64 -= EPOCH_BIAS;
|
||||
|
@ -102,7 +102,7 @@ tor_gettimeofday, (struct timeval *timeval))
|
|||
log_err(LD_GENERAL,"gettimeofday failed.");
|
||||
/* If gettimeofday dies, we have either given a bad timezone (we didn't),
|
||||
or segfaulted.*/
|
||||
exit(1); // exit ok: gettimeofday failed.
|
||||
exit(1);
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
#elif defined(HAVE_FTIME)
|
||||
|
@ -279,8 +279,6 @@ monotime_reset_ratchets_for_testing(void)
|
|||
* nanoseconds.
|
||||
*/
|
||||
static struct mach_timebase_info mach_time_info;
|
||||
static struct mach_timebase_info mach_time_info_msec_cvt;
|
||||
static int monotime_shift = 0;
|
||||
|
||||
static void
|
||||
monotime_init_internal(void)
|
||||
|
@ -289,22 +287,6 @@ monotime_init_internal(void)
|
|||
int r = mach_timebase_info(&mach_time_info);
|
||||
tor_assert(r == 0);
|
||||
tor_assert(mach_time_info.denom != 0);
|
||||
|
||||
{
|
||||
// approximate only.
|
||||
uint64_t ns_per_tick = mach_time_info.numer / mach_time_info.denom;
|
||||
uint64_t ms_per_tick = ns_per_tick * ONE_MILLION;
|
||||
// requires that tor_log2(0) == 0.
|
||||
monotime_shift = tor_log2(ms_per_tick);
|
||||
}
|
||||
{
|
||||
// For converting ticks to milliseconds in a 32-bit-friendly way, we
|
||||
// will first right-shift by 20, and then multiply by 20/19, since
|
||||
// (1<<20) * 19/20 is about 1e6. We precompute a new numerate and
|
||||
// denominator here to avoid multiple multiplies.
|
||||
mach_time_info_msec_cvt.numer = mach_time_info.numer * 20;
|
||||
mach_time_info_msec_cvt.denom = mach_time_info.denom * 19;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -323,21 +305,6 @@ monotime_get(monotime_t *out)
|
|||
out->abstime_ = mach_absolute_time();
|
||||
}
|
||||
|
||||
#if defined(HAVE_MACH_APPROXIMATE_TIME)
|
||||
void
|
||||
monotime_coarse_get(monotime_coarse_t *out)
|
||||
{
|
||||
#ifdef TOR_UNIT_TESTS
|
||||
if (monotime_mocking_enabled) {
|
||||
out->abstime_ = (mock_time_nsec_coarse * mach_time_info.denom)
|
||||
/ mach_time_info.numer;
|
||||
return;
|
||||
}
|
||||
#endif /* defined(TOR_UNIT_TESTS) */
|
||||
out->abstime_ = mach_approximate_time();
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Return the number of nanoseconds between <b>start</b> and <b>end</b>.
|
||||
*/
|
||||
|
@ -354,42 +321,6 @@ monotime_diff_nsec(const monotime_t *start,
|
|||
return diff_nsec;
|
||||
}
|
||||
|
||||
int32_t
|
||||
monotime_coarse_diff_msec32_(const monotime_coarse_t *start,
|
||||
const monotime_coarse_t *end)
|
||||
{
|
||||
if (BUG(mach_time_info.denom == 0)) {
|
||||
monotime_init();
|
||||
}
|
||||
const int64_t diff_ticks = end->abstime_ - start->abstime_;
|
||||
|
||||
/* We already require in di_ops.c that right-shift performs a sign-extend. */
|
||||
const int32_t diff_microticks = (int32_t)(diff_ticks >> 20);
|
||||
|
||||
return (diff_microticks * mach_time_info_msec_cvt.numer) /
|
||||
mach_time_info_msec_cvt.denom;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
monotime_coarse_to_stamp(const monotime_coarse_t *t)
|
||||
{
|
||||
return (uint32_t)(t->abstime_ >> monotime_shift);
|
||||
}
|
||||
|
||||
int
|
||||
monotime_is_zero(const monotime_t *val)
|
||||
{
|
||||
return val->abstime_ == 0;
|
||||
}
|
||||
|
||||
void
|
||||
monotime_add_msec(monotime_t *out, const monotime_t *val, uint32_t msec)
|
||||
{
|
||||
const uint64_t nsec = msec * ONE_MILLION;
|
||||
const uint64_t ticks = (nsec * mach_time_info.denom) / mach_time_info.numer;
|
||||
out->abstime_ = val->abstime_ + ticks;
|
||||
}
|
||||
|
||||
/* end of "__APPLE__" */
|
||||
#elif defined(HAVE_CLOCK_GETTIME)
|
||||
|
||||
|
@ -468,46 +399,6 @@ monotime_diff_nsec(const monotime_t *start,
|
|||
return diff_nsec;
|
||||
}
|
||||
|
||||
int32_t
|
||||
monotime_coarse_diff_msec32_(const monotime_coarse_t *start,
|
||||
const monotime_coarse_t *end)
|
||||
{
|
||||
const int32_t diff_sec = (int32_t)(end->ts_.tv_sec - start->ts_.tv_sec);
|
||||
const int32_t diff_nsec = (int32_t)(end->ts_.tv_nsec - start->ts_.tv_nsec);
|
||||
return diff_sec * 1000 + diff_nsec / ONE_MILLION;
|
||||
}
|
||||
|
||||
/* This value is ONE_BILLION >> 20. */
|
||||
static const uint32_t STAMP_TICKS_PER_SECOND = 953;
|
||||
|
||||
uint32_t
|
||||
monotime_coarse_to_stamp(const monotime_coarse_t *t)
|
||||
{
|
||||
uint32_t nsec = (uint32_t)t->ts_.tv_nsec;
|
||||
uint32_t sec = (uint32_t)t->ts_.tv_sec;
|
||||
|
||||
return (sec * STAMP_TICKS_PER_SECOND) + (nsec >> 20);
|
||||
}
|
||||
|
||||
int
|
||||
monotime_is_zero(const monotime_t *val)
|
||||
{
|
||||
return val->ts_.tv_sec == 0 && val->ts_.tv_nsec == 0;
|
||||
}
|
||||
|
||||
void
|
||||
monotime_add_msec(monotime_t *out, const monotime_t *val, uint32_t msec)
|
||||
{
|
||||
const uint32_t sec = msec / 1000;
|
||||
const uint32_t msec_remainder = msec % 1000;
|
||||
out->ts_.tv_sec = val->ts_.tv_sec + sec;
|
||||
out->ts_.tv_nsec = val->ts_.tv_nsec + (msec_remainder * ONE_MILLION);
|
||||
if (out->ts_.tv_nsec > ONE_BILLION) {
|
||||
out->ts_.tv_nsec -= ONE_BILLION;
|
||||
out->ts_.tv_sec += 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* end of "HAVE_CLOCK_GETTIME" */
|
||||
#elif defined (_WIN32)
|
||||
|
||||
|
@ -626,13 +517,6 @@ monotime_coarse_diff_msec(const monotime_coarse_t *start,
|
|||
return diff_ticks;
|
||||
}
|
||||
|
||||
int32_t
|
||||
monotime_coarse_diff_msec32_(const monotime_coarse_t *start,
|
||||
const monotime_coarse_t *end)
|
||||
{
|
||||
return (int32_t)monotime_coarse_diff_msec(start, end);
|
||||
}
|
||||
|
||||
int64_t
|
||||
monotime_coarse_diff_usec(const monotime_coarse_t *start,
|
||||
const monotime_coarse_t *end)
|
||||
|
@ -647,41 +531,6 @@ monotime_coarse_diff_nsec(const monotime_coarse_t *start,
|
|||
return monotime_coarse_diff_msec(start, end) * ONE_MILLION;
|
||||
}
|
||||
|
||||
static const uint32_t STAMP_TICKS_PER_SECOND = 1000;
|
||||
|
||||
uint32_t
|
||||
monotime_coarse_to_stamp(const monotime_coarse_t *t)
|
||||
{
|
||||
return (uint32_t) t->tick_count_;
|
||||
}
|
||||
|
||||
int
|
||||
monotime_is_zero(const monotime_t *val)
|
||||
{
|
||||
return val->pcount_ == 0;
|
||||
}
|
||||
|
||||
int
|
||||
monotime_coarse_is_zero(const monotime_coarse_t *val)
|
||||
{
|
||||
return val->tick_count_ == 0;
|
||||
}
|
||||
|
||||
void
|
||||
monotime_add_msec(monotime_t *out, const monotime_t *val, uint32_t msec)
|
||||
{
|
||||
const uint64_t nsec = msec * ONE_MILLION;
|
||||
const uint64_t ticks = (nsec * nsec_per_tick_denom) / nsec_per_tick_numer;
|
||||
out->pcount_ = val->pcount_ + ticks;
|
||||
}
|
||||
|
||||
void
|
||||
monotime_coarse_add_msec(monotime_coarse_t *out, const monotime_coarse_t *val,
|
||||
uint32_t msec)
|
||||
{
|
||||
out->tick_count_ = val->tick_count_ + msec;
|
||||
}
|
||||
|
||||
/* end of "_WIN32" */
|
||||
#elif defined(MONOTIME_USING_GETTIMEOFDAY)
|
||||
|
||||
|
@ -718,45 +567,6 @@ monotime_diff_nsec(const monotime_t *start,
|
|||
return (diff.tv_sec * ONE_BILLION + diff.tv_usec * 1000);
|
||||
}
|
||||
|
||||
int32_t
|
||||
monotime_coarse_diff_msec32_(const monotime_coarse_t *start,
|
||||
const monotime_coarse_t *end)
|
||||
{
|
||||
struct timeval diff;
|
||||
timersub(&end->tv_, &start->tv_, &diff);
|
||||
return diff.tv_sec * 1000 + diff.tv_usec / 1000;
|
||||
}
|
||||
|
||||
/* This value is ONE_MILLION >> 10. */
|
||||
static const uint32_t STAMP_TICKS_PER_SECOND = 976;
|
||||
|
||||
uint32_t
|
||||
monotime_coarse_to_stamp(const monotime_coarse_t *t)
|
||||
{
|
||||
const uint32_t usec = (uint32_t)t->tv_.tv_usec;
|
||||
const uint32_t sec = (uint32_t)t->tv_.tv_sec;
|
||||
return (sec * STAMP_TICKS_PER_SECOND) | (nsec >> 10);
|
||||
}
|
||||
|
||||
int
|
||||
monotime_is_zero(const monotime_t *val)
|
||||
{
|
||||
return val->tv_.tv_sec == 0 && val->tv_.tv_usec == 0;
|
||||
}
|
||||
|
||||
void
|
||||
monotime_add_msec(monotime_t *out, const monotime_t *val, uint32_t msec)
|
||||
{
|
||||
const uint32_t sec = msec / 1000;
|
||||
const uint32_t msec_remainder = msec % 1000;
|
||||
out->tv_.tv_sec = val->tv_.tv_sec + sec;
|
||||
out->tv_.tv_usec = val->tv_.tv_nsec + (msec_remainder * 1000);
|
||||
if (out->tv_.tv_usec > ONE_MILLION) {
|
||||
out->tv_.tv_usec -= ONE_MILLION;
|
||||
out->tv_.tv_sec += 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* end of "MONOTIME_USING_GETTIMEOFDAY" */
|
||||
#else
|
||||
#error "No way to implement monotonic timers."
|
||||
|
@ -779,19 +589,6 @@ monotime_init(void)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
monotime_zero(monotime_t *out)
|
||||
{
|
||||
memset(out, 0, sizeof(*out));
|
||||
}
|
||||
#ifdef MONOTIME_COARSE_TYPE_IS_DIFFERENT
|
||||
void
|
||||
monotime_coarse_zero(monotime_coarse_t *out)
|
||||
{
|
||||
memset(out, 0, sizeof(*out));
|
||||
}
|
||||
#endif
|
||||
|
||||
int64_t
|
||||
monotime_diff_usec(const monotime_t *start,
|
||||
const monotime_t *end)
|
||||
|
@ -856,48 +653,5 @@ monotime_coarse_absolute_msec(void)
|
|||
{
|
||||
return monotime_coarse_absolute_nsec() / ONE_MILLION;
|
||||
}
|
||||
#else
|
||||
#define initialized_at_coarse initialized_at
|
||||
#endif /* defined(MONOTIME_COARSE_FN_IS_DIFFERENT) */
|
||||
|
||||
/**
|
||||
* Return the current time "stamp" as described by monotime_coarse_to_stamp.
|
||||
*/
|
||||
uint32_t
|
||||
monotime_coarse_get_stamp(void)
|
||||
{
|
||||
monotime_coarse_t now;
|
||||
monotime_coarse_get(&now);
|
||||
return monotime_coarse_to_stamp(&now);
|
||||
}
|
||||
|
||||
#ifdef __APPLE__
|
||||
uint64_t
|
||||
monotime_coarse_stamp_units_to_approx_msec(uint64_t units)
|
||||
{
|
||||
/* Recover as much precision as we can. */
|
||||
uint64_t abstime_diff = (units << monotime_shift);
|
||||
return (abstime_diff * mach_time_info.numer) /
|
||||
(mach_time_info.denom * ONE_MILLION);
|
||||
}
|
||||
uint64_t
|
||||
monotime_msec_to_approx_coarse_stamp_units(uint64_t msec)
|
||||
{
|
||||
uint64_t abstime_val =
|
||||
(((uint64_t)msec) * ONE_MILLION * mach_time_info.denom) /
|
||||
mach_time_info.numer;
|
||||
return abstime_val >> monotime_shift;
|
||||
}
|
||||
#else
|
||||
uint64_t
|
||||
monotime_coarse_stamp_units_to_approx_msec(uint64_t units)
|
||||
{
|
||||
return (units * 1000) / STAMP_TICKS_PER_SECOND;
|
||||
}
|
||||
uint64_t
|
||||
monotime_msec_to_approx_coarse_stamp_units(uint64_t msec)
|
||||
{
|
||||
return (msec * STAMP_TICKS_PER_SECOND) / 1000;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
@ -65,9 +65,6 @@ typedef struct monotime_t {
|
|||
typedef struct monotime_coarse_t {
|
||||
uint64_t tick_count_;
|
||||
} monotime_coarse_t;
|
||||
#elif defined(__APPLE__) && defined(HAVE_MACH_APPROXIMATE_TIME)
|
||||
#define MONOTIME_COARSE_FN_IS_DIFFERENT
|
||||
#define monotime_coarse_t monotime_t
|
||||
#else
|
||||
#define monotime_coarse_t monotime_t
|
||||
#endif /* defined(CLOCK_MONOTONIC_COARSE) && ... || ... */
|
||||
|
@ -105,21 +102,6 @@ uint64_t monotime_absolute_usec(void);
|
|||
*/
|
||||
uint64_t monotime_absolute_msec(void);
|
||||
|
||||
/**
|
||||
* Set <b>out</b> to zero.
|
||||
*/
|
||||
void monotime_zero(monotime_t *out);
|
||||
/**
|
||||
* Return true iff <b>out</b> is zero
|
||||
*/
|
||||
int monotime_is_zero(const monotime_t *out);
|
||||
|
||||
/**
|
||||
* Set <b>out</b> to N milliseconds after <b>val</b>.
|
||||
*/
|
||||
/* XXXX We should add a more generic function here if we ever need to */
|
||||
void monotime_add_msec(monotime_t *out, const monotime_t *val, uint32_t msec);
|
||||
|
||||
#if defined(MONOTIME_COARSE_FN_IS_DIFFERENT)
|
||||
/**
|
||||
* Set <b>out</b> to the current coarse time.
|
||||
|
@ -135,24 +117,6 @@ uint64_t monotime_coarse_absolute_msec(void);
|
|||
#define monotime_coarse_absolute_msec monotime_absolute_msec
|
||||
#endif /* defined(MONOTIME_COARSE_FN_IS_DIFFERENT) */
|
||||
|
||||
/**
|
||||
* Return a "timestamp" approximation for a coarse monotonic timer.
|
||||
* This timestamp is meant to be fast to calculate and easy to
|
||||
* compare, and have a unit of something roughly around 1 msec.
|
||||
*
|
||||
* It will wrap over from time to time.
|
||||
*
|
||||
* It has no defined zero point.
|
||||
*/
|
||||
uint32_t monotime_coarse_to_stamp(const monotime_coarse_t *t);
|
||||
/**
|
||||
* Convert a difference, expressed in the units of monotime_coarse_to_stamp,
|
||||
* into an approximate number of milliseconds.
|
||||
*/
|
||||
uint64_t monotime_coarse_stamp_units_to_approx_msec(uint64_t units);
|
||||
uint64_t monotime_msec_to_approx_coarse_stamp_units(uint64_t msec);
|
||||
uint32_t monotime_coarse_get_stamp(void);
|
||||
|
||||
#if defined(MONOTIME_COARSE_TYPE_IS_DIFFERENT)
|
||||
int64_t monotime_coarse_diff_nsec(const monotime_coarse_t *start,
|
||||
const monotime_coarse_t *end);
|
||||
|
@ -160,47 +124,13 @@ int64_t monotime_coarse_diff_usec(const monotime_coarse_t *start,
|
|||
const monotime_coarse_t *end);
|
||||
int64_t monotime_coarse_diff_msec(const monotime_coarse_t *start,
|
||||
const monotime_coarse_t *end);
|
||||
void monotime_coarse_zero(monotime_coarse_t *out);
|
||||
int monotime_coarse_is_zero(const monotime_coarse_t *val);
|
||||
void monotime_coarse_add_msec(monotime_coarse_t *out,
|
||||
const monotime_coarse_t *val, uint32_t msec);
|
||||
#else /* !(defined(MONOTIME_COARSE_TYPE_IS_DIFFERENT)) */
|
||||
#define monotime_coarse_diff_nsec monotime_diff_nsec
|
||||
#define monotime_coarse_diff_usec monotime_diff_usec
|
||||
#define monotime_coarse_diff_msec monotime_diff_msec
|
||||
#define monotime_coarse_zero monotime_zero
|
||||
#define monotime_coarse_is_zero monotime_is_zero
|
||||
#define monotime_coarse_add_msec monotime_add_msec
|
||||
#endif /* defined(MONOTIME_COARSE_TYPE_IS_DIFFERENT) */
|
||||
|
||||
/**
|
||||
* As monotime_coarse_diff_msec, but avoid 64-bit division.
|
||||
*
|
||||
* Requires that the difference fit into an int32_t; not for use with
|
||||
* large time differences.
|
||||
*/
|
||||
int32_t monotime_coarse_diff_msec32_(const monotime_coarse_t *start,
|
||||
const monotime_coarse_t *end);
|
||||
|
||||
/**
|
||||
* As monotime_coarse_diff_msec, but avoid 64-bit division if it is expensive.
|
||||
*
|
||||
* Requires that the difference fit into an int32_t; not for use with
|
||||
* large time differences.
|
||||
*/
|
||||
static inline int32_t
|
||||
monotime_coarse_diff_msec32(const monotime_coarse_t *start,
|
||||
const monotime_coarse_t *end)
|
||||
{
|
||||
#if SIZEOF_VOID_P == 8
|
||||
// on a 64-bit platform, let's assume 64/64 division is cheap.
|
||||
return (int32_t) monotime_coarse_diff_msec(start, end);
|
||||
#else
|
||||
return monotime_coarse_diff_msec32_(start, end);
|
||||
#endif
|
||||
}
|
||||
|
||||
MOCK_DECL(void, tor_gettimeofday, (struct timeval *timeval));
|
||||
void tor_gettimeofday(struct timeval *timeval);
|
||||
|
||||
#ifdef TOR_UNIT_TESTS
|
||||
void tor_sleep_msec(int msec);
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include "util.h"
|
||||
#include "container.h"
|
||||
#include "torlog.h"
|
||||
#include <process.h>
|
||||
|
||||
/* This value is more or less total cargo-cult */
|
||||
#define SPIN_COUNT 2000
|
||||
|
@ -47,12 +48,10 @@ void
|
|||
spawn_exit(void)
|
||||
{
|
||||
_endthread();
|
||||
// LCOV_EXCL_START
|
||||
//we should never get here. my compiler thinks that _endthread returns, this
|
||||
//is an attempt to fool it.
|
||||
tor_assert(0);
|
||||
_exit(0); // exit ok: unreachable.
|
||||
// LCOV_EXCL_STOP
|
||||
_exit(0);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -598,7 +598,7 @@ tor_compress_process(tor_compress_state_t *state,
|
|||
|
||||
/** Deallocate <b>state</b>. */
|
||||
void
|
||||
tor_compress_free_(tor_compress_state_t *state)
|
||||
tor_compress_free(tor_compress_state_t *state)
|
||||
{
|
||||
if (state == NULL)
|
||||
return;
|
||||
|
@ -663,13 +663,3 @@ tor_compress_init(void)
|
|||
tor_zstd_init();
|
||||
}
|
||||
|
||||
/** Warn if we had any problems while setting up our compression libraries.
|
||||
*
|
||||
* (This isn't part of tor_compress_init, since the logs aren't set up yet.)
|
||||
*/
|
||||
void
|
||||
tor_compress_log_init_warnings(void)
|
||||
{
|
||||
tor_zstd_warn_if_version_mismatched();
|
||||
}
|
||||
|
||||
|
|
|
@ -80,14 +80,11 @@ tor_compress_output_t tor_compress_process(tor_compress_state_t *state,
|
|||
char **out, size_t *out_len,
|
||||
const char **in, size_t *in_len,
|
||||
int finish);
|
||||
void tor_compress_free_(tor_compress_state_t *state);
|
||||
#define tor_compress_free(st) \
|
||||
FREE_AND_NULL(tor_compress_state_t, tor_compress_free_, (st))
|
||||
void tor_compress_free(tor_compress_state_t *state);
|
||||
|
||||
size_t tor_compress_state_size(const tor_compress_state_t *state);
|
||||
|
||||
void tor_compress_init(void);
|
||||
void tor_compress_log_init_warnings(void);
|
||||
|
||||
#endif /* !defined(TOR_COMPRESS_H) */
|
||||
|
||||
|
|
|
@ -323,7 +323,7 @@ tor_lzma_compress_process(tor_lzma_compress_state_t *state,
|
|||
|
||||
/** Deallocate <b>state</b>. */
|
||||
void
|
||||
tor_lzma_compress_free_(tor_lzma_compress_state_t *state)
|
||||
tor_lzma_compress_free(tor_lzma_compress_state_t *state)
|
||||
{
|
||||
if (state == NULL)
|
||||
return;
|
||||
|
|
|
@ -31,10 +31,7 @@ tor_lzma_compress_process(tor_lzma_compress_state_t *state,
|
|||
const char **in, size_t *in_len,
|
||||
int finish);
|
||||
|
||||
void tor_lzma_compress_free_(tor_lzma_compress_state_t *state);
|
||||
#define tor_lzma_compress_free(st) \
|
||||
FREE_AND_NULL(tor_lzma_compress_state_t, \
|
||||
tor_lzma_compress_free_, (st))
|
||||
void tor_lzma_compress_free(tor_lzma_compress_state_t *state);
|
||||
|
||||
size_t tor_lzma_compress_state_size(const tor_lzma_compress_state_t *state);
|
||||
|
||||
|
|
|
@ -265,7 +265,7 @@ tor_zlib_compress_process(tor_zlib_compress_state_t *state,
|
|||
|
||||
/** Deallocate <b>state</b>. */
|
||||
void
|
||||
tor_zlib_compress_free_(tor_zlib_compress_state_t *state)
|
||||
tor_zlib_compress_free(tor_zlib_compress_state_t *state)
|
||||
{
|
||||
if (state == NULL)
|
||||
return;
|
||||
|
|
|
@ -31,10 +31,7 @@ tor_zlib_compress_process(tor_zlib_compress_state_t *state,
|
|||
const char **in, size_t *in_len,
|
||||
int finish);
|
||||
|
||||
void tor_zlib_compress_free_(tor_zlib_compress_state_t *state);
|
||||
#define tor_zlib_compress_free(st) \
|
||||
FREE_AND_NULL(tor_zlib_compress_state_t, \
|
||||
tor_zlib_compress_free_, (st))
|
||||
void tor_zlib_compress_free(tor_zlib_compress_state_t *state);
|
||||
|
||||
size_t tor_zlib_compress_state_size(const tor_zlib_compress_state_t *state);
|
||||
|
||||
|
|
|
@ -18,13 +18,6 @@
|
|||
#include "compress.h"
|
||||
#include "compress_zstd.h"
|
||||
|
||||
#ifdef ENABLE_ZSTD_ADVANCED_APIS
|
||||
/* This is a lie, but we make sure it doesn't get us in trouble by wrapping
|
||||
* all invocations of zstd's static-only functions in a check to make sure
|
||||
* that the compile-time version matches the run-time version. */
|
||||
#define ZSTD_STATIC_LINKING_ONLY
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_ZSTD
|
||||
#include <zstd.h>
|
||||
#endif
|
||||
|
@ -58,31 +51,21 @@ tor_zstd_method_supported(void)
|
|||
#endif
|
||||
}
|
||||
|
||||
#ifdef HAVE_ZSTD
|
||||
/** Format a zstd version number as a string in <b>buf</b>. */
|
||||
static void
|
||||
tor_zstd_format_version(char *buf, size_t buflen, unsigned version_number)
|
||||
{
|
||||
tor_snprintf(buf, buflen,
|
||||
"%u.%u.%u",
|
||||
version_number / 10000 % 100,
|
||||
version_number / 100 % 100,
|
||||
version_number % 100);
|
||||
}
|
||||
#endif
|
||||
|
||||
#define VERSION_STR_MAX_LEN 16 /* more than enough space for 99.99.99 */
|
||||
|
||||
/** Return a string representation of the version of the currently running
|
||||
* version of libzstd. Returns NULL if Zstandard is unsupported. */
|
||||
const char *
|
||||
tor_zstd_get_version_str(void)
|
||||
{
|
||||
#ifdef HAVE_ZSTD
|
||||
static char version_str[VERSION_STR_MAX_LEN];
|
||||
static char version_str[16];
|
||||
size_t version_number;
|
||||
|
||||
tor_zstd_format_version(version_str, sizeof(version_str),
|
||||
ZSTD_versionNumber());
|
||||
version_number = ZSTD_versionNumber();
|
||||
tor_snprintf(version_str, sizeof(version_str),
|
||||
"%d.%d.%d",
|
||||
(int) version_number / 10000 % 100,
|
||||
(int) version_number / 100 % 100,
|
||||
(int) version_number % 100);
|
||||
|
||||
return version_str;
|
||||
#else /* !(defined(HAVE_ZSTD)) */
|
||||
|
@ -102,26 +85,6 @@ tor_zstd_get_header_version_str(void)
|
|||
#endif
|
||||
}
|
||||
|
||||
#ifdef TOR_UNIT_TESTS
|
||||
static int static_apis_disable_for_testing = 0;
|
||||
#endif
|
||||
|
||||
/** Return true iff we can use the "static-only" APIs. */
|
||||
int
|
||||
tor_zstd_can_use_static_apis(void)
|
||||
{
|
||||
#if defined(ZSTD_STATIC_LINKING_ONLY) && defined(HAVE_ZSTD)
|
||||
#ifdef TOR_UNIT_TESTS
|
||||
if (static_apis_disable_for_testing) {
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
return (ZSTD_VERSION_NUMBER == ZSTD_versionNumber());
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
/** Internal Zstandard state for incremental compression/decompression.
|
||||
* The body of this struct is not exposed. */
|
||||
struct tor_zstd_compress_state_t {
|
||||
|
@ -149,11 +112,9 @@ struct tor_zstd_compress_state_t {
|
|||
|
||||
#ifdef HAVE_ZSTD
|
||||
/** Return an approximate number of bytes stored in memory to hold the
|
||||
* Zstandard compression/decompression state. This is a fake estimate
|
||||
* based on inspecting the zstd source: tor_zstd_state_size_precalc() is
|
||||
* more accurate when it's allowed to use "static-only" functions */
|
||||
* Zstandard compression/decompression state. */
|
||||
static size_t
|
||||
tor_zstd_state_size_precalc_fake(int compress, int preset)
|
||||
tor_zstd_state_size_precalc(int compress, int preset)
|
||||
{
|
||||
tor_assert(preset > 0);
|
||||
|
||||
|
@ -210,28 +171,6 @@ tor_zstd_state_size_precalc_fake(int compress, int preset)
|
|||
|
||||
return memory_usage;
|
||||
}
|
||||
|
||||
/** Return an approximate number of bytes stored in memory to hold the
|
||||
* Zstandard compression/decompression state. */
|
||||
static size_t
|
||||
tor_zstd_state_size_precalc(int compress, int preset)
|
||||
{
|
||||
#ifdef ZSTD_STATIC_LINKING_ONLY
|
||||
if (tor_zstd_can_use_static_apis()) {
|
||||
if (compress) {
|
||||
#ifdef HAVE_ZSTD_ESTIMATECSTREAMSIZE
|
||||
return ZSTD_estimateCStreamSize(preset);
|
||||
#endif
|
||||
} else {
|
||||
#ifdef HAVE_ZSTD_ESTIMATEDCTXSIZE
|
||||
/* Could use DStream, but that takes a windowSize. */
|
||||
return ZSTD_estimateDCtxSize();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return tor_zstd_state_size_precalc_fake(compress, preset);
|
||||
}
|
||||
#endif /* defined(HAVE_ZSTD) */
|
||||
|
||||
/** Construct and return a tor_zstd_compress_state_t object using
|
||||
|
@ -460,7 +399,7 @@ tor_zstd_compress_process(tor_zstd_compress_state_t *state,
|
|||
|
||||
/** Deallocate <b>state</b>. */
|
||||
void
|
||||
tor_zstd_compress_free_(tor_zstd_compress_state_t *state)
|
||||
tor_zstd_compress_free(tor_zstd_compress_state_t *state)
|
||||
{
|
||||
if (state == NULL)
|
||||
return;
|
||||
|
@ -501,34 +440,3 @@ tor_zstd_init(void)
|
|||
atomic_counter_init(&total_zstd_allocation);
|
||||
}
|
||||
|
||||
/** Warn if the header and library versions don't match. */
|
||||
void
|
||||
tor_zstd_warn_if_version_mismatched(void)
|
||||
{
|
||||
#if defined(HAVE_ZSTD) && defined(ENABLE_ZSTD_ADVANCED_APIS)
|
||||
if (! tor_zstd_can_use_static_apis()) {
|
||||
char header_version[VERSION_STR_MAX_LEN];
|
||||
char runtime_version[VERSION_STR_MAX_LEN];
|
||||
tor_zstd_format_version(header_version, sizeof(header_version),
|
||||
ZSTD_VERSION_NUMBER);
|
||||
tor_zstd_format_version(runtime_version, sizeof(runtime_version),
|
||||
ZSTD_versionNumber());
|
||||
|
||||
log_warn(LD_GENERAL,
|
||||
"Tor was compiled with zstd %s, but is running with zstd %s. "
|
||||
"For safety, we'll avoid using advanced zstd functionality.",
|
||||
header_version, runtime_version);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef TOR_UNIT_TESTS
|
||||
/** Testing only: disable usage of static-only APIs, so we can make sure that
|
||||
* we still work without them. */
|
||||
void
|
||||
tor_zstd_set_static_apis_disabled_for_testing(int disabled)
|
||||
{
|
||||
static_apis_disable_for_testing = disabled;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
@ -17,8 +17,6 @@ const char *tor_zstd_get_version_str(void);
|
|||
|
||||
const char *tor_zstd_get_header_version_str(void);
|
||||
|
||||
int tor_zstd_can_use_static_apis(void);
|
||||
|
||||
/** Internal state for an incremental Zstandard compression/decompression. */
|
||||
typedef struct tor_zstd_compress_state_t tor_zstd_compress_state_t;
|
||||
|
||||
|
@ -33,21 +31,13 @@ tor_zstd_compress_process(tor_zstd_compress_state_t *state,
|
|||
const char **in, size_t *in_len,
|
||||
int finish);
|
||||
|
||||
void tor_zstd_compress_free_(tor_zstd_compress_state_t *state);
|
||||
#define tor_zstd_compress_free(st) \
|
||||
FREE_AND_NULL(tor_zstd_compress_state_t, \
|
||||
tor_zstd_compress_free_, (st))
|
||||
void tor_zstd_compress_free(tor_zstd_compress_state_t *state);
|
||||
|
||||
size_t tor_zstd_compress_state_size(const tor_zstd_compress_state_t *state);
|
||||
|
||||
size_t tor_zstd_get_total_allocation(void);
|
||||
|
||||
void tor_zstd_init(void);
|
||||
void tor_zstd_warn_if_version_mismatched(void);
|
||||
|
||||
#ifdef TOR_UNIT_TESTS
|
||||
void tor_zstd_set_static_apis_disabled_for_testing(int disabled);
|
||||
#endif
|
||||
|
||||
#endif /* !defined(TOR_COMPRESS_ZSTD_H) */
|
||||
|
||||
|
|
|
@ -12,18 +12,15 @@
|
|||
|
||||
static int config_get_lines_aux(const char *string, config_line_t **result,
|
||||
int extended, int allow_include,
|
||||
int *has_include, smartlist_t *opened_lst,
|
||||
int recursion_level, config_line_t **last);
|
||||
static smartlist_t *config_get_file_list(const char *path,
|
||||
smartlist_t *opened_files);
|
||||
static int config_get_included_config(const char *path, int recursion_level,
|
||||
int extended, config_line_t **config,
|
||||
config_line_t **config_last,
|
||||
smartlist_t *opened_lst);
|
||||
int *has_include, int recursion_level,
|
||||
config_line_t **last);
|
||||
static smartlist_t *config_get_file_list(const char *path);
|
||||
static int config_get_included_list(const char *path, int recursion_level,
|
||||
int extended, config_line_t **list,
|
||||
config_line_t **list_last);
|
||||
static int config_process_include(const char *path, int recursion_level,
|
||||
int extended, config_line_t **list,
|
||||
config_line_t **list_last,
|
||||
smartlist_t *opened_lst);
|
||||
config_line_t **list_last);
|
||||
|
||||
/** Helper: allocate a new configuration option mapping 'key' to 'val',
|
||||
* append it to *<b>lst</b>. */
|
||||
|
@ -83,13 +80,11 @@ config_line_find(const config_line_t *lines,
|
|||
|
||||
/** Auxiliary function that does all the work of config_get_lines.
|
||||
* <b>recursion_level</b> is the count of how many nested %includes we have.
|
||||
* <b>opened_lst</b> will have a list of opened files if provided.
|
||||
* Returns the a pointer to the last element of the <b>result</b> in
|
||||
* <b>last</b>. */
|
||||
static int
|
||||
config_get_lines_aux(const char *string, config_line_t **result, int extended,
|
||||
int allow_include, int *has_include,
|
||||
smartlist_t *opened_lst, int recursion_level,
|
||||
int allow_include, int *has_include, int recursion_level,
|
||||
config_line_t **last)
|
||||
{
|
||||
config_line_t *list = NULL, **next, *list_last = NULL;
|
||||
|
@ -139,7 +134,7 @@ config_get_lines_aux(const char *string, config_line_t **result, int extended,
|
|||
|
||||
config_line_t *include_list;
|
||||
if (config_process_include(v, recursion_level, extended, &include_list,
|
||||
&list_last, opened_lst) < 0) {
|
||||
&list_last) < 0) {
|
||||
log_warn(LD_CONFIG, "Error reading included configuration "
|
||||
"file or directory: \"%s\".", v);
|
||||
config_free_lines(list);
|
||||
|
@ -181,27 +176,24 @@ config_get_lines_aux(const char *string, config_line_t **result, int extended,
|
|||
/** Helper: parse the config string and strdup into key/value
|
||||
* strings. Set *result to the list, or NULL if parsing the string
|
||||
* failed. Set *has_include to 1 if <b>result</b> has values from
|
||||
* %included files. <b>opened_lst</b> will have a list of opened files if
|
||||
* provided. Return 0 on success, -1 on failure. Warn and ignore any
|
||||
* %included files. Return 0 on success, -1 on failure. Warn and ignore any
|
||||
* misformatted lines.
|
||||
*
|
||||
* If <b>extended</b> is set, then treat keys beginning with / and with + as
|
||||
* indicating "clear" and "append" respectively. */
|
||||
int
|
||||
config_get_lines_include(const char *string, config_line_t **result,
|
||||
int extended, int *has_include,
|
||||
smartlist_t *opened_lst)
|
||||
int extended, int *has_include)
|
||||
{
|
||||
return config_get_lines_aux(string, result, extended, 1, has_include,
|
||||
opened_lst, 1, NULL);
|
||||
return config_get_lines_aux(string, result, extended, 1, has_include, 1,
|
||||
NULL);
|
||||
}
|
||||
|
||||
/** Same as config_get_lines_include but does not allow %include */
|
||||
int
|
||||
config_get_lines(const char *string, config_line_t **result, int extended)
|
||||
{
|
||||
return config_get_lines_aux(string, result, extended, 0, NULL, NULL, 1,
|
||||
NULL);
|
||||
return config_get_lines_aux(string, result, extended, 0, NULL, 1, NULL);
|
||||
}
|
||||
|
||||
/** Adds a list of configuration files present on <b>path</b> to
|
||||
|
@ -209,18 +201,12 @@ config_get_lines(const char *string, config_line_t **result, int extended)
|
|||
* only that file will be added to <b>file_list</b>. If it is a directory,
|
||||
* all paths for files on that directory root (no recursion) except for files
|
||||
* whose name starts with a dot will be added to <b>file_list</b>.
|
||||
* <b>opened_files</b> will have a list of files opened by this function
|
||||
* if provided. Return 0 on success, -1 on failure. Ignores empty files.
|
||||
* Return 0 on success, -1 on failure. Ignores empty files.
|
||||
*/
|
||||
static smartlist_t *
|
||||
config_get_file_list(const char *path, smartlist_t *opened_files)
|
||||
config_get_file_list(const char *path)
|
||||
{
|
||||
smartlist_t *file_list = smartlist_new();
|
||||
|
||||
if (opened_files) {
|
||||
smartlist_add_strdup(opened_files, path);
|
||||
}
|
||||
|
||||
file_status_t file_type = file_status(path);
|
||||
if (file_type == FN_FILE) {
|
||||
smartlist_add_strdup(file_list, path);
|
||||
|
@ -242,10 +228,6 @@ config_get_file_list(const char *path, smartlist_t *opened_files)
|
|||
tor_asprintf(&fullname, "%s"PATH_SEPARATOR"%s", path, f);
|
||||
tor_free(f);
|
||||
|
||||
if (opened_files) {
|
||||
smartlist_add_strdup(opened_files, fullname);
|
||||
}
|
||||
|
||||
if (file_status(fullname) != FN_FILE) {
|
||||
tor_free(fullname);
|
||||
continue;
|
||||
|
@ -263,21 +245,19 @@ config_get_file_list(const char *path, smartlist_t *opened_files)
|
|||
}
|
||||
|
||||
/** Creates a list of config lines present on included <b>path</b>.
|
||||
* Set <b>config</b> to the list and <b>config_last</b> to the last element of
|
||||
* <b>config</b>. <b>opened_lst</b> will have a list of opened files if
|
||||
* provided. Return 0 on success, -1 on failure. */
|
||||
* Set <b>list</b> to the list and <b>list_last</b> to the last element of
|
||||
* <b>list</b>. Return 0 on success, -1 on failure. */
|
||||
static int
|
||||
config_get_included_config(const char *path, int recursion_level, int extended,
|
||||
config_line_t **config, config_line_t **config_last,
|
||||
smartlist_t *opened_lst)
|
||||
config_get_included_list(const char *path, int recursion_level, int extended,
|
||||
config_line_t **list, config_line_t **list_last)
|
||||
{
|
||||
char *included_conf = read_file_to_str(path, 0, NULL);
|
||||
if (!included_conf) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (config_get_lines_aux(included_conf, config, extended, 1, NULL,
|
||||
opened_lst, recursion_level+1, config_last) < 0) {
|
||||
if (config_get_lines_aux(included_conf, list, extended, 1, NULL,
|
||||
recursion_level+1, list_last) < 0) {
|
||||
tor_free(included_conf);
|
||||
return -1;
|
||||
}
|
||||
|
@ -288,31 +268,41 @@ config_get_included_config(const char *path, int recursion_level, int extended,
|
|||
|
||||
/** Process an %include <b>path</b> in a config file. Set <b>list</b> to the
|
||||
* list of configuration settings obtained and <b>list_last</b> to the last
|
||||
* element of the same list. <b>opened_lst</b> will have a list of opened
|
||||
* files if provided. Return 0 on success, -1 on failure. */
|
||||
* element of the same list. Return 0 on success, -1 on failure. */
|
||||
static int
|
||||
config_process_include(const char *path, int recursion_level, int extended,
|
||||
config_line_t **list, config_line_t **list_last,
|
||||
smartlist_t *opened_lst)
|
||||
config_line_t **list, config_line_t **list_last)
|
||||
{
|
||||
config_line_t *ret_list = NULL;
|
||||
config_line_t **next = &ret_list;
|
||||
#if 0
|
||||
// Disabled -- we already unescape_string() on the result. */
|
||||
char *unquoted_path = get_unquoted_path(path);
|
||||
if (!unquoted_path) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
smartlist_t *config_files = config_get_file_list(path, opened_lst);
|
||||
smartlist_t *config_files = config_get_file_list(unquoted_path);
|
||||
if (!config_files) {
|
||||
tor_free(unquoted_path);
|
||||
return -1;
|
||||
}
|
||||
tor_free(unquoted_path);
|
||||
#endif /* 0 */
|
||||
smartlist_t *config_files = config_get_file_list(path);
|
||||
if (!config_files) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
int rv = -1;
|
||||
SMARTLIST_FOREACH_BEGIN(config_files, const char *, config_file) {
|
||||
config_line_t *included_config = NULL;
|
||||
if (config_get_included_config(config_file, recursion_level, extended,
|
||||
&included_config, list_last,
|
||||
opened_lst) < 0) {
|
||||
config_line_t *included_list = NULL;
|
||||
if (config_get_included_list(config_file, recursion_level, extended,
|
||||
&included_list, list_last) < 0) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
*next = included_config;
|
||||
*next = included_list;
|
||||
if (*list_last)
|
||||
next = &(*list_last)->next;
|
||||
|
||||
|
@ -330,7 +320,7 @@ config_process_include(const char *path, int recursion_level, int extended,
|
|||
* Free all the configuration lines on the linked list <b>front</b>.
|
||||
*/
|
||||
void
|
||||
config_free_lines_(config_line_t *front)
|
||||
config_free_lines(config_line_t *front)
|
||||
{
|
||||
config_line_t *tmp;
|
||||
|
||||
|
|
|
@ -7,8 +7,6 @@
|
|||
#ifndef TOR_CONFLINE_H
|
||||
#define TOR_CONFLINE_H
|
||||
|
||||
#include "container.h"
|
||||
|
||||
/** Ordinary configuration line. */
|
||||
#define CONFIG_LINE_NORMAL 0
|
||||
/** Appends to previous configuration for the same option, even if we
|
||||
|
@ -46,14 +44,8 @@ int config_lines_eq(config_line_t *a, config_line_t *b);
|
|||
int config_count_key(const config_line_t *a, const char *key);
|
||||
int config_get_lines(const char *string, config_line_t **result, int extended);
|
||||
int config_get_lines_include(const char *string, config_line_t **result,
|
||||
int extended, int *has_include,
|
||||
smartlist_t *opened_lst);
|
||||
void config_free_lines_(config_line_t *front);
|
||||
#define config_free_lines(front) \
|
||||
do { \
|
||||
config_free_lines_(front); \
|
||||
(front) = NULL; \
|
||||
} while (0)
|
||||
int extended, int *has_include);
|
||||
void config_free_lines(config_line_t *front);
|
||||
const char *parse_config_line_from_str_verbose(const char *line,
|
||||
char **key_out, char **value_out,
|
||||
const char **err_out);
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
#include "util.h"
|
||||
#include "torlog.h"
|
||||
#include "container.h"
|
||||
#include "crypto_digest.h"
|
||||
#include "crypto.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
@ -42,7 +42,7 @@ smartlist_new,(void))
|
|||
* list's elements.
|
||||
*/
|
||||
MOCK_IMPL(void,
|
||||
smartlist_free_,(smartlist_t *sl))
|
||||
smartlist_free,(smartlist_t *sl))
|
||||
{
|
||||
if (!sl)
|
||||
return;
|
||||
|
@ -1163,26 +1163,19 @@ HT_GENERATE2(digest256map_impl, digest256map_entry_t, node,
|
|||
digest256map_entry_hash,
|
||||
digest256map_entries_eq, 0.6, tor_reallocarray_, tor_free_)
|
||||
|
||||
#define strmap_entry_free(ent) \
|
||||
FREE_AND_NULL(strmap_entry_t, strmap_entry_free_, (ent))
|
||||
#define digestmap_entry_free(ent) \
|
||||
FREE_AND_NULL(digestmap_entry_t, digestmap_entry_free_, (ent))
|
||||
#define digest256map_entry_free(ent) \
|
||||
FREE_AND_NULL(digest256map_entry_t, digest256map_entry_free_, (ent))
|
||||
|
||||
static inline void
|
||||
strmap_entry_free_(strmap_entry_t *ent)
|
||||
strmap_entry_free(strmap_entry_t *ent)
|
||||
{
|
||||
tor_free(ent->key);
|
||||
tor_free(ent);
|
||||
}
|
||||
static inline void
|
||||
digestmap_entry_free_(digestmap_entry_t *ent)
|
||||
digestmap_entry_free(digestmap_entry_t *ent)
|
||||
{
|
||||
tor_free(ent);
|
||||
}
|
||||
static inline void
|
||||
digest256map_entry_free_(digest256map_entry_t *ent)
|
||||
digest256map_entry_free(digest256map_entry_t *ent)
|
||||
{
|
||||
tor_free(ent);
|
||||
}
|
||||
|
@ -1342,7 +1335,7 @@ digest256map_assign_key(digest256map_entry_t *ent, const uint8_t *key)
|
|||
* those entries. If free_val is provided, invoked it every value in \
|
||||
* <b>map</b>. */ \
|
||||
MOCK_IMPL(void, \
|
||||
prefix##_free_, (maptype *map, void (*free_val)(void*))) \
|
||||
prefix##_free, (maptype *map, void (*free_val)(void*))) \
|
||||
{ \
|
||||
prefix##_entry_t **ent, **next, *this; \
|
||||
if (!map) \
|
||||
|
@ -1532,7 +1525,7 @@ digestset_new(int max_elements)
|
|||
|
||||
/** Free all storage held in <b>set</b>. */
|
||||
void
|
||||
digestset_free_(digestset_t *set)
|
||||
digestset_free(digestset_t *set)
|
||||
{
|
||||
if (!set)
|
||||
return;
|
||||
|
|
|
@ -28,9 +28,7 @@ typedef struct smartlist_t {
|
|||
} smartlist_t;
|
||||
|
||||
MOCK_DECL(smartlist_t *, smartlist_new, (void));
|
||||
MOCK_DECL(void, smartlist_free_, (smartlist_t *sl));
|
||||
#define smartlist_free(sl) FREE_AND_NULL(smartlist_t, smartlist_free_, (sl))
|
||||
|
||||
MOCK_DECL(void, smartlist_free, (smartlist_t *sl));
|
||||
void smartlist_clear(smartlist_t *sl);
|
||||
void smartlist_add(smartlist_t *sl, void *element);
|
||||
void smartlist_add_all(smartlist_t *sl, const smartlist_t *s2);
|
||||
|
@ -352,7 +350,7 @@ char *smartlist_join_strings2(smartlist_t *sl, const char *join,
|
|||
void* prefix##set(maptype *map, keytype key, void *val); \
|
||||
void* prefix##get(const maptype *map, keytype key); \
|
||||
void* prefix##remove(maptype *map, keytype key); \
|
||||
MOCK_DECL(void, prefix##free_, (maptype *map, void (*free_val)(void*))); \
|
||||
MOCK_DECL(void, prefix##free, (maptype *map, void (*free_val)(void*))); \
|
||||
int prefix##isempty(const maptype *map); \
|
||||
int prefix##size(const maptype *map); \
|
||||
prefix##iter_t *prefix##iter_init(maptype *map); \
|
||||
|
@ -370,16 +368,6 @@ DECLARE_MAP_FNS(digestmap_t, const char *, digestmap_);
|
|||
* table. */
|
||||
DECLARE_MAP_FNS(digest256map_t, const uint8_t *, digest256map_);
|
||||
|
||||
#define MAP_FREE_AND_NULL(maptype, map, fn) \
|
||||
do { \
|
||||
maptype ## _free_((map), (fn)); \
|
||||
(map) = NULL; \
|
||||
} while (0)
|
||||
|
||||
#define strmap_free(map, fn) MAP_FREE_AND_NULL(strmap, (map), (fn))
|
||||
#define digestmap_free(map, fn) MAP_FREE_AND_NULL(digestmap, (map), (fn))
|
||||
#define digest256map_free(map, fn) MAP_FREE_AND_NULL(digest256map, (map), (fn))
|
||||
|
||||
#undef DECLARE_MAP_FNS
|
||||
|
||||
/** Iterates over the key-value pairs in a map <b>map</b> in order.
|
||||
|
@ -540,9 +528,9 @@ void* strmap_remove_lc(strmap_t *map, const char *key);
|
|||
return (valtype*)digestmap_remove((digestmap_t*)map, key); \
|
||||
} \
|
||||
ATTR_UNUSED static inline void \
|
||||
prefix##f##ree_(maptype *map, void (*free_val)(void*)) \
|
||||
prefix##f##ree(maptype *map, void (*free_val)(void*)) \
|
||||
{ \
|
||||
digestmap_free_((digestmap_t*)map, free_val); \
|
||||
digestmap_free((digestmap_t*)map, free_val); \
|
||||
} \
|
||||
ATTR_UNUSED static inline int \
|
||||
prefix##isempty(maptype *map) \
|
||||
|
@ -626,12 +614,10 @@ bitarray_expand(bitarray_t *ba,
|
|||
}
|
||||
/** Free the bit array <b>ba</b>. */
|
||||
static inline void
|
||||
bitarray_free_(bitarray_t *ba)
|
||||
bitarray_free(bitarray_t *ba)
|
||||
{
|
||||
tor_free(ba);
|
||||
}
|
||||
#define bitarray_free(ba) FREE_AND_NULL(bitarray_t, bitarray_free_, (ba))
|
||||
|
||||
/** Set the <b>bit</b>th bit in <b>b</b> to 1. */
|
||||
static inline void
|
||||
bitarray_set(bitarray_t *b, int bit)
|
||||
|
@ -693,8 +679,7 @@ digestset_contains(const digestset_t *set, const char *digest)
|
|||
#undef BIT
|
||||
|
||||
digestset_t *digestset_new(int max_elements);
|
||||
void digestset_free_(digestset_t* set);
|
||||
#define digestset_free(set) FREE_AND_NULL(digestset_t, digestset_free_, (set))
|
||||
void digestset_free(digestset_t* set);
|
||||
|
||||
/* These functions, given an <b>array</b> of <b>n_elements</b>, return the
|
||||
* <b>nth</b> lowest element. <b>nth</b>=0 gives the lowest element;
|
||||
|
|
2463
src/common/crypto.c
2463
src/common/crypto.c
File diff suppressed because it is too large
Load Diff
|
@ -17,28 +17,122 @@
|
|||
|
||||
#include <stdio.h>
|
||||
#include "torint.h"
|
||||
#include "testsupport.h"
|
||||
#include "compat.h"
|
||||
#include "util.h"
|
||||
#include "crypto_rsa.h"
|
||||
|
||||
#include <openssl/engine.h>
|
||||
#include "keccak-tiny/keccak-tiny.h"
|
||||
|
||||
/*
|
||||
Macro to create an arbitrary OpenSSL version number as used by
|
||||
OPENSSL_VERSION_NUMBER or SSLeay(), since the actual numbers are a bit hard
|
||||
to read.
|
||||
|
||||
Don't use this directly, instead use one of the other OPENSSL_V macros
|
||||
below.
|
||||
|
||||
The format is: 4 bits major, 8 bits minor, 8 bits fix, 8 bits patch, 4 bit
|
||||
status.
|
||||
*/
|
||||
#define OPENSSL_VER(a,b,c,d,e) \
|
||||
(((a)<<28) | \
|
||||
((b)<<20) | \
|
||||
((c)<<12) | \
|
||||
((d)<< 4) | \
|
||||
(e))
|
||||
/** An openssl release number. For example, OPENSSL_V(0,9,8,'j') is the
|
||||
* version for the released version of 0.9.8j */
|
||||
#define OPENSSL_V(a,b,c,d) \
|
||||
OPENSSL_VER((a),(b),(c),(d)-'a'+1,0xf)
|
||||
/** An openssl release number for the first release in the series. For
|
||||
* example, OPENSSL_V_NOPATCH(1,0,0) is the first released version of OpenSSL
|
||||
* 1.0.0. */
|
||||
#define OPENSSL_V_NOPATCH(a,b,c) \
|
||||
OPENSSL_VER((a),(b),(c),0,0xf)
|
||||
/** The first version that would occur for any alpha or beta in an openssl
|
||||
* series. For example, OPENSSL_V_SERIES(0,9,8) is greater than any released
|
||||
* 0.9.7, and less than any released 0.9.8. */
|
||||
#define OPENSSL_V_SERIES(a,b,c) \
|
||||
OPENSSL_VER((a),(b),(c),0,0)
|
||||
|
||||
/** Length of the output of our message digest. */
|
||||
#define DIGEST_LEN 20
|
||||
/** Length of the output of our second (improved) message digests. (For now
|
||||
* this is just sha256, but it could be any other 256-bit digest.) */
|
||||
#define DIGEST256_LEN 32
|
||||
/** Length of the output of our 64-bit optimized message digests (SHA512). */
|
||||
#define DIGEST512_LEN 64
|
||||
/** Length of our symmetric cipher's keys of 128-bit. */
|
||||
#define CIPHER_KEY_LEN 16
|
||||
/** Length of our symmetric cipher's IV of 128-bit. */
|
||||
#define CIPHER_IV_LEN 16
|
||||
/** Length of our symmetric cipher's keys of 256-bit. */
|
||||
#define CIPHER256_KEY_LEN 32
|
||||
/** Length of our public keys. */
|
||||
#define PK_BYTES (1024/8)
|
||||
/** Length of our DH keys. */
|
||||
#define DH_BYTES (1024/8)
|
||||
|
||||
/** Length of a sha1 message digest when encoded in base32 with trailing =
|
||||
* signs removed. */
|
||||
#define BASE32_DIGEST_LEN 32
|
||||
/** Length of a sha1 message digest when encoded in base64 with trailing =
|
||||
* signs removed. */
|
||||
#define BASE64_DIGEST_LEN 27
|
||||
/** Length of a sha256 message digest when encoded in base64 with trailing =
|
||||
* signs removed. */
|
||||
#define BASE64_DIGEST256_LEN 43
|
||||
/** Length of a sha512 message digest when encoded in base64 with trailing =
|
||||
* signs removed. */
|
||||
#define BASE64_DIGEST512_LEN 86
|
||||
|
||||
/** Constant used to indicate OAEP padding for public-key encryption */
|
||||
#define PK_PKCS1_OAEP_PADDING 60002
|
||||
|
||||
/** Number of bytes added for PKCS1-OAEP padding. */
|
||||
#define PKCS1_OAEP_PADDING_OVERHEAD 42
|
||||
|
||||
/** Length of encoded public key fingerprints, including space; but not
|
||||
* including terminating NUL. */
|
||||
#define FINGERPRINT_LEN 49
|
||||
/** Length of hex encoding of SHA1 digest, not including final NUL. */
|
||||
#define HEX_DIGEST_LEN 40
|
||||
/** Length of hex encoding of SHA256 digest, not including final NUL. */
|
||||
#define HEX_DIGEST256_LEN 64
|
||||
/** Length of hex encoding of SHA512 digest, not including final NUL. */
|
||||
#define HEX_DIGEST512_LEN 128
|
||||
|
||||
typedef enum {
|
||||
DIGEST_SHA1 = 0,
|
||||
DIGEST_SHA256 = 1,
|
||||
DIGEST_SHA512 = 2,
|
||||
DIGEST_SHA3_256 = 3,
|
||||
DIGEST_SHA3_512 = 4,
|
||||
} digest_algorithm_t;
|
||||
#define N_DIGEST_ALGORITHMS (DIGEST_SHA3_512+1)
|
||||
#define N_COMMON_DIGEST_ALGORITHMS (DIGEST_SHA256+1)
|
||||
|
||||
/** A set of all the digests we commonly compute, taken on a single
|
||||
* string. Any digests that are shorter than 512 bits are right-padded
|
||||
* with 0 bits.
|
||||
*
|
||||
* Note that this representation wastes 44 bytes for the SHA1 case, so
|
||||
* don't use it for anything where we need to allocate a whole bunch at
|
||||
* once.
|
||||
**/
|
||||
typedef struct {
|
||||
char d[N_COMMON_DIGEST_ALGORITHMS][DIGEST256_LEN];
|
||||
} common_digests_t;
|
||||
|
||||
typedef struct crypto_pk_t crypto_pk_t;
|
||||
typedef struct aes_cnt_cipher crypto_cipher_t;
|
||||
typedef struct crypto_digest_t crypto_digest_t;
|
||||
typedef struct crypto_xof_t crypto_xof_t;
|
||||
typedef struct crypto_dh_t crypto_dh_t;
|
||||
|
||||
/* global state */
|
||||
int crypto_init_siphash_key(void);
|
||||
const char * crypto_openssl_get_version_str(void);
|
||||
const char * crypto_openssl_get_header_version_str(void);
|
||||
int crypto_early_init(void) ATTR_WUR;
|
||||
int crypto_global_init(int hardwareAccel,
|
||||
const char *accelName,
|
||||
|
@ -51,6 +145,9 @@ void crypto_thread_cleanup(void);
|
|||
int crypto_global_cleanup(void);
|
||||
|
||||
/* environment setup */
|
||||
MOCK_DECL(crypto_pk_t *,crypto_pk_new,(void));
|
||||
void crypto_pk_free(crypto_pk_t *env);
|
||||
|
||||
void crypto_set_tls_dh_prime(void);
|
||||
crypto_cipher_t *crypto_cipher_new(const char *key);
|
||||
crypto_cipher_t *crypto_cipher_new_with_bits(const char *key, int bits);
|
||||
|
@ -58,9 +155,70 @@ crypto_cipher_t *crypto_cipher_new_with_iv(const char *key, const char *iv);
|
|||
crypto_cipher_t *crypto_cipher_new_with_iv_and_bits(const uint8_t *key,
|
||||
const uint8_t *iv,
|
||||
int bits);
|
||||
void crypto_cipher_free_(crypto_cipher_t *env);
|
||||
#define crypto_cipher_free(c) \
|
||||
FREE_AND_NULL(crypto_cipher_t, crypto_cipher_free_, (c))
|
||||
void crypto_cipher_free(crypto_cipher_t *env);
|
||||
|
||||
/* public key crypto */
|
||||
MOCK_DECL(int, crypto_pk_generate_key_with_bits,(crypto_pk_t *env, int bits));
|
||||
#define crypto_pk_generate_key(env) \
|
||||
crypto_pk_generate_key_with_bits((env), (PK_BYTES*8))
|
||||
|
||||
int crypto_pk_read_private_key_from_filename(crypto_pk_t *env,
|
||||
const char *keyfile);
|
||||
int crypto_pk_write_public_key_to_string(crypto_pk_t *env,
|
||||
char **dest, size_t *len);
|
||||
int crypto_pk_write_private_key_to_string(crypto_pk_t *env,
|
||||
char **dest, size_t *len);
|
||||
int crypto_pk_read_public_key_from_string(crypto_pk_t *env,
|
||||
const char *src, size_t len);
|
||||
int crypto_pk_read_private_key_from_string(crypto_pk_t *env,
|
||||
const char *s, ssize_t len);
|
||||
int crypto_pk_write_private_key_to_filename(crypto_pk_t *env,
|
||||
const char *fname);
|
||||
|
||||
int crypto_pk_check_key(crypto_pk_t *env);
|
||||
int crypto_pk_cmp_keys(const crypto_pk_t *a, const crypto_pk_t *b);
|
||||
int crypto_pk_eq_keys(const crypto_pk_t *a, const crypto_pk_t *b);
|
||||
size_t crypto_pk_keysize(const crypto_pk_t *env);
|
||||
int crypto_pk_num_bits(crypto_pk_t *env);
|
||||
crypto_pk_t *crypto_pk_dup_key(crypto_pk_t *orig);
|
||||
crypto_pk_t *crypto_pk_copy_full(crypto_pk_t *orig);
|
||||
int crypto_pk_key_is_private(const crypto_pk_t *key);
|
||||
int crypto_pk_public_exponent_ok(crypto_pk_t *env);
|
||||
|
||||
int crypto_pk_public_encrypt(crypto_pk_t *env, char *to, size_t tolen,
|
||||
const char *from, size_t fromlen, int padding);
|
||||
int crypto_pk_private_decrypt(crypto_pk_t *env, char *to, size_t tolen,
|
||||
const char *from, size_t fromlen,
|
||||
int padding, int warnOnFailure);
|
||||
MOCK_DECL(int, crypto_pk_public_checksig,(const crypto_pk_t *env,
|
||||
char *to, size_t tolen,
|
||||
const char *from, size_t fromlen));
|
||||
MOCK_DECL(int, crypto_pk_public_checksig_digest,(crypto_pk_t *env,
|
||||
const char *data, size_t datalen,
|
||||
const char *sig, size_t siglen));
|
||||
int crypto_pk_private_sign(const crypto_pk_t *env, char *to, size_t tolen,
|
||||
const char *from, size_t fromlen);
|
||||
int crypto_pk_private_sign_digest(crypto_pk_t *env, char *to, size_t tolen,
|
||||
const char *from, size_t fromlen);
|
||||
int crypto_pk_obsolete_public_hybrid_encrypt(crypto_pk_t *env, char *to,
|
||||
size_t tolen,
|
||||
const char *from, size_t fromlen,
|
||||
int padding, int force);
|
||||
int crypto_pk_obsolete_private_hybrid_decrypt(crypto_pk_t *env, char *to,
|
||||
size_t tolen,
|
||||
const char *from, size_t fromlen,
|
||||
int padding, int warnOnFailure);
|
||||
|
||||
int crypto_pk_asn1_encode(crypto_pk_t *pk, char *dest, size_t dest_len);
|
||||
crypto_pk_t *crypto_pk_asn1_decode(const char *str, size_t len);
|
||||
int crypto_pk_get_digest(const crypto_pk_t *pk, char *digest_out);
|
||||
int crypto_pk_get_common_digests(crypto_pk_t *pk,
|
||||
common_digests_t *digests_out);
|
||||
int crypto_pk_get_fingerprint(crypto_pk_t *pk, char *fp_out,int add_space);
|
||||
int crypto_pk_get_hashed_fingerprint(crypto_pk_t *pk, char *fp_out);
|
||||
|
||||
int crypto_pk_base64_encode(const crypto_pk_t *pk, char **priv_out);
|
||||
crypto_pk_t *crypto_pk_base64_decode(const char *str, size_t len);
|
||||
|
||||
/* symmetric crypto */
|
||||
const char *crypto_cipher_get_key(crypto_cipher_t *env);
|
||||
|
@ -78,6 +236,48 @@ int crypto_cipher_decrypt_with_iv(const char *key,
|
|||
char *to, size_t tolen,
|
||||
const char *from, size_t fromlen);
|
||||
|
||||
/* SHA-1 and other digests. */
|
||||
int crypto_digest(char *digest, const char *m, size_t len);
|
||||
int crypto_digest256(char *digest, const char *m, size_t len,
|
||||
digest_algorithm_t algorithm);
|
||||
int crypto_digest512(char *digest, const char *m, size_t len,
|
||||
digest_algorithm_t algorithm);
|
||||
int crypto_common_digests(common_digests_t *ds_out, const char *m, size_t len);
|
||||
struct smartlist_t;
|
||||
void crypto_digest_smartlist_prefix(char *digest_out, size_t len_out,
|
||||
const char *prepend,
|
||||
const struct smartlist_t *lst,
|
||||
const char *append,
|
||||
digest_algorithm_t alg);
|
||||
void crypto_digest_smartlist(char *digest_out, size_t len_out,
|
||||
const struct smartlist_t *lst, const char *append,
|
||||
digest_algorithm_t alg);
|
||||
const char *crypto_digest_algorithm_get_name(digest_algorithm_t alg);
|
||||
size_t crypto_digest_algorithm_get_length(digest_algorithm_t alg);
|
||||
int crypto_digest_algorithm_parse_name(const char *name);
|
||||
crypto_digest_t *crypto_digest_new(void);
|
||||
crypto_digest_t *crypto_digest256_new(digest_algorithm_t algorithm);
|
||||
crypto_digest_t *crypto_digest512_new(digest_algorithm_t algorithm);
|
||||
void crypto_digest_free(crypto_digest_t *digest);
|
||||
void crypto_digest_add_bytes(crypto_digest_t *digest, const char *data,
|
||||
size_t len);
|
||||
void crypto_digest_get_digest(crypto_digest_t *digest,
|
||||
char *out, size_t out_len);
|
||||
crypto_digest_t *crypto_digest_dup(const crypto_digest_t *digest);
|
||||
void crypto_digest_assign(crypto_digest_t *into,
|
||||
const crypto_digest_t *from);
|
||||
void crypto_hmac_sha256(char *hmac_out,
|
||||
const char *key, size_t key_len,
|
||||
const char *msg, size_t msg_len);
|
||||
void crypto_mac_sha3_256(uint8_t *mac_out, size_t len_out,
|
||||
const uint8_t *key, size_t key_len,
|
||||
const uint8_t *msg, size_t msg_len);
|
||||
|
||||
crypto_xof_t *crypto_xof_new(void);
|
||||
void crypto_xof_add_bytes(crypto_xof_t *xof, const uint8_t *data, size_t len);
|
||||
void crypto_xof_squeeze_bytes(crypto_xof_t *xof, uint8_t *out, size_t len);
|
||||
void crypto_xof_free(crypto_xof_t *xof);
|
||||
|
||||
/* Key negotiation */
|
||||
#define DH_TYPE_CIRCUIT 1
|
||||
#define DH_TYPE_REND 2
|
||||
|
@ -91,8 +291,7 @@ int crypto_dh_get_public(crypto_dh_t *dh, char *pubkey_out,
|
|||
ssize_t crypto_dh_compute_secret(int severity, crypto_dh_t *dh,
|
||||
const char *pubkey, size_t pubkey_len,
|
||||
char *secret_out, size_t secret_out_len);
|
||||
void crypto_dh_free_(crypto_dh_t *dh);
|
||||
#define crypto_dh_free(dh) FREE_AND_NULL(crypto_dh_t, crypto_dh_free_, (dh))
|
||||
void crypto_dh_free(crypto_dh_t *dh);
|
||||
|
||||
int crypto_expand_key_material_TAP(const uint8_t *key_in,
|
||||
size_t key_in_len,
|
||||
|
@ -103,12 +302,59 @@ int crypto_expand_key_material_rfc5869_sha256(
|
|||
const uint8_t *info_in, size_t info_in_len,
|
||||
uint8_t *key_out, size_t key_out_len);
|
||||
|
||||
/* random numbers */
|
||||
int crypto_seed_rng(void) ATTR_WUR;
|
||||
MOCK_DECL(void,crypto_rand,(char *to, size_t n));
|
||||
void crypto_rand_unmocked(char *to, size_t n);
|
||||
void crypto_strongest_rand(uint8_t *out, size_t out_len);
|
||||
int crypto_rand_int(unsigned int max);
|
||||
int crypto_rand_int_range(unsigned int min, unsigned int max);
|
||||
uint64_t crypto_rand_uint64_range(uint64_t min, uint64_t max);
|
||||
time_t crypto_rand_time_range(time_t min, time_t max);
|
||||
uint64_t crypto_rand_uint64(uint64_t max);
|
||||
double crypto_rand_double(void);
|
||||
struct tor_weak_rng_t;
|
||||
void crypto_seed_weak_rng(struct tor_weak_rng_t *rng);
|
||||
int crypto_init_siphash_key(void);
|
||||
|
||||
char *crypto_random_hostname(int min_rand_len, int max_rand_len,
|
||||
const char *prefix, const char *suffix);
|
||||
|
||||
struct smartlist_t;
|
||||
void *smartlist_choose(const struct smartlist_t *sl);
|
||||
void smartlist_shuffle(struct smartlist_t *sl);
|
||||
|
||||
/** OpenSSL-based utility functions. */
|
||||
void memwipe(void *mem, uint8_t byte, size_t sz);
|
||||
|
||||
/* Prototypes for private functions only used by tortls.c, crypto.c, and the
|
||||
* unit tests. */
|
||||
struct rsa_st;
|
||||
struct evp_pkey_st;
|
||||
struct dh_st;
|
||||
struct rsa_st *crypto_pk_get_rsa_(crypto_pk_t *env);
|
||||
crypto_pk_t *crypto_new_pk_from_rsa_(struct rsa_st *rsa);
|
||||
MOCK_DECL(struct evp_pkey_st *, crypto_pk_get_evp_pkey_,(crypto_pk_t *env,
|
||||
int private));
|
||||
struct dh_st *crypto_dh_get_dh_(crypto_dh_t *dh);
|
||||
|
||||
void crypto_add_spaces_to_fp(char *out, size_t outlen, const char *in);
|
||||
|
||||
#ifdef CRYPTO_PRIVATE
|
||||
|
||||
STATIC int crypto_force_rand_ssleay(void);
|
||||
STATIC int crypto_strongest_rand_raw(uint8_t *out, size_t out_len);
|
||||
|
||||
#ifdef TOR_UNIT_TESTS
|
||||
extern int break_strongest_rng_syscall;
|
||||
extern int break_strongest_rng_fallback;
|
||||
#endif
|
||||
#endif /* defined(CRYPTO_PRIVATE) */
|
||||
|
||||
#ifdef TOR_UNIT_TESTS
|
||||
void crypto_pk_assign_(crypto_pk_t *dest, const crypto_pk_t *src);
|
||||
digest_algorithm_t crypto_digest_get_algorithm(crypto_digest_t *digest);
|
||||
#endif
|
||||
|
||||
#endif /* !defined(TOR_CRYPTO_H) */
|
||||
|
||||
|
|
|
@ -21,11 +21,9 @@
|
|||
#include <sys/stat.h>
|
||||
#endif
|
||||
#include "container.h"
|
||||
#include "crypto.h"
|
||||
#include "crypto_curve25519.h"
|
||||
#include "crypto_digest.h"
|
||||
#include "crypto_format.h"
|
||||
#include "crypto_rand.h"
|
||||
#include "crypto_util.h"
|
||||
#include "util.h"
|
||||
#include "torlog.h"
|
||||
|
||||
|
|
|
@ -6,8 +6,6 @@
|
|||
|
||||
#include "testsupport.h"
|
||||
#include "torint.h"
|
||||
#include "crypto_digest.h"
|
||||
#include "crypto_openssl_mgt.h"
|
||||
|
||||
/** Length of a curve25519 public key when encoded. */
|
||||
#define CURVE25519_PUBKEY_LEN 32
|
||||
|
|
|
@ -1,583 +0,0 @@
|
|||
/* Copyright (c) 2001, Matej Pfajfar.
|
||||
* Copyright (c) 2001-2004, Roger Dingledine.
|
||||
* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
|
||||
* Copyright (c) 2007-2017, The Tor Project, Inc. */
|
||||
/* See LICENSE for licensing information */
|
||||
|
||||
/**
|
||||
* \file crypto_digest.c
|
||||
* \brief Block of functions related with digest and xof utilities and
|
||||
* operations.
|
||||
**/
|
||||
|
||||
#include "container.h"
|
||||
#include "crypto_digest.h"
|
||||
#include "crypto_openssl_mgt.h"
|
||||
#include "crypto_util.h"
|
||||
#include "torlog.h"
|
||||
|
||||
#include "keccak-tiny/keccak-tiny.h"
|
||||
|
||||
DISABLE_GCC_WARNING(redundant-decls)
|
||||
|
||||
#include <openssl/hmac.h>
|
||||
#include <openssl/sha.h>
|
||||
|
||||
ENABLE_GCC_WARNING(redundant-decls)
|
||||
|
||||
/* Crypto digest functions */
|
||||
|
||||
/** Compute the SHA1 digest of the <b>len</b> bytes on data stored in
|
||||
* <b>m</b>. Write the DIGEST_LEN byte result into <b>digest</b>.
|
||||
* Return 0 on success, -1 on failure.
|
||||
*/
|
||||
int
|
||||
crypto_digest(char *digest, const char *m, size_t len)
|
||||
{
|
||||
tor_assert(m);
|
||||
tor_assert(digest);
|
||||
if (SHA1((const unsigned char*)m,len,(unsigned char*)digest) == NULL)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** Compute a 256-bit digest of <b>len</b> bytes in data stored in <b>m</b>,
|
||||
* using the algorithm <b>algorithm</b>. Write the DIGEST_LEN256-byte result
|
||||
* into <b>digest</b>. Return 0 on success, -1 on failure. */
|
||||
int
|
||||
crypto_digest256(char *digest, const char *m, size_t len,
|
||||
digest_algorithm_t algorithm)
|
||||
{
|
||||
tor_assert(m);
|
||||
tor_assert(digest);
|
||||
tor_assert(algorithm == DIGEST_SHA256 || algorithm == DIGEST_SHA3_256);
|
||||
|
||||
int ret = 0;
|
||||
if (algorithm == DIGEST_SHA256)
|
||||
ret = (SHA256((const uint8_t*)m,len,(uint8_t*)digest) != NULL);
|
||||
else
|
||||
ret = (sha3_256((uint8_t *)digest, DIGEST256_LEN,(const uint8_t *)m, len)
|
||||
> -1);
|
||||
|
||||
if (!ret)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** Compute a 512-bit digest of <b>len</b> bytes in data stored in <b>m</b>,
|
||||
* using the algorithm <b>algorithm</b>. Write the DIGEST_LEN512-byte result
|
||||
* into <b>digest</b>. Return 0 on success, -1 on failure. */
|
||||
int
|
||||
crypto_digest512(char *digest, const char *m, size_t len,
|
||||
digest_algorithm_t algorithm)
|
||||
{
|
||||
tor_assert(m);
|
||||
tor_assert(digest);
|
||||
tor_assert(algorithm == DIGEST_SHA512 || algorithm == DIGEST_SHA3_512);
|
||||
|
||||
int ret = 0;
|
||||
if (algorithm == DIGEST_SHA512)
|
||||
ret = (SHA512((const unsigned char*)m,len,(unsigned char*)digest)
|
||||
!= NULL);
|
||||
else
|
||||
ret = (sha3_512((uint8_t*)digest, DIGEST512_LEN, (const uint8_t*)m, len)
|
||||
> -1);
|
||||
|
||||
if (!ret)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** Set the common_digests_t in <b>ds_out</b> to contain every digest on the
|
||||
* <b>len</b> bytes in <b>m</b> that we know how to compute. Return 0 on
|
||||
* success, -1 on failure. */
|
||||
int
|
||||
crypto_common_digests(common_digests_t *ds_out, const char *m, size_t len)
|
||||
{
|
||||
tor_assert(ds_out);
|
||||
memset(ds_out, 0, sizeof(*ds_out));
|
||||
if (crypto_digest(ds_out->d[DIGEST_SHA1], m, len) < 0)
|
||||
return -1;
|
||||
if (crypto_digest256(ds_out->d[DIGEST_SHA256], m, len, DIGEST_SHA256) < 0)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** Return the name of an algorithm, as used in directory documents. */
|
||||
const char *
|
||||
crypto_digest_algorithm_get_name(digest_algorithm_t alg)
|
||||
{
|
||||
switch (alg) {
|
||||
case DIGEST_SHA1:
|
||||
return "sha1";
|
||||
case DIGEST_SHA256:
|
||||
return "sha256";
|
||||
case DIGEST_SHA512:
|
||||
return "sha512";
|
||||
case DIGEST_SHA3_256:
|
||||
return "sha3-256";
|
||||
case DIGEST_SHA3_512:
|
||||
return "sha3-512";
|
||||
// LCOV_EXCL_START
|
||||
default:
|
||||
tor_fragile_assert();
|
||||
return "??unknown_digest??";
|
||||
// LCOV_EXCL_STOP
|
||||
}
|
||||
}
|
||||
|
||||
/** Given the name of a digest algorithm, return its integer value, or -1 if
|
||||
* the name is not recognized. */
|
||||
int
|
||||
crypto_digest_algorithm_parse_name(const char *name)
|
||||
{
|
||||
if (!strcmp(name, "sha1"))
|
||||
return DIGEST_SHA1;
|
||||
else if (!strcmp(name, "sha256"))
|
||||
return DIGEST_SHA256;
|
||||
else if (!strcmp(name, "sha512"))
|
||||
return DIGEST_SHA512;
|
||||
else if (!strcmp(name, "sha3-256"))
|
||||
return DIGEST_SHA3_256;
|
||||
else if (!strcmp(name, "sha3-512"))
|
||||
return DIGEST_SHA3_512;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
/** Given an algorithm, return the digest length in bytes. */
|
||||
size_t
|
||||
crypto_digest_algorithm_get_length(digest_algorithm_t alg)
|
||||
{
|
||||
switch (alg) {
|
||||
case DIGEST_SHA1:
|
||||
return DIGEST_LEN;
|
||||
case DIGEST_SHA256:
|
||||
return DIGEST256_LEN;
|
||||
case DIGEST_SHA512:
|
||||
return DIGEST512_LEN;
|
||||
case DIGEST_SHA3_256:
|
||||
return DIGEST256_LEN;
|
||||
case DIGEST_SHA3_512:
|
||||
return DIGEST512_LEN;
|
||||
default:
|
||||
tor_assert(0); // LCOV_EXCL_LINE
|
||||
return 0; /* Unreachable */ // LCOV_EXCL_LINE
|
||||
}
|
||||
}
|
||||
|
||||
/** Intermediate information about the digest of a stream of data. */
|
||||
struct crypto_digest_t {
|
||||
digest_algorithm_t algorithm; /**< Which algorithm is in use? */
|
||||
/** State for the digest we're using. Only one member of the
|
||||
* union is usable, depending on the value of <b>algorithm</b>. Note also
|
||||
* that space for other members might not even be allocated!
|
||||
*/
|
||||
union {
|
||||
SHA_CTX sha1; /**< state for SHA1 */
|
||||
SHA256_CTX sha2; /**< state for SHA256 */
|
||||
SHA512_CTX sha512; /**< state for SHA512 */
|
||||
keccak_state sha3; /**< state for SHA3-[256,512] */
|
||||
} d;
|
||||
};
|
||||
|
||||
#ifdef TOR_UNIT_TESTS
|
||||
|
||||
digest_algorithm_t
|
||||
crypto_digest_get_algorithm(crypto_digest_t *digest)
|
||||
{
|
||||
tor_assert(digest);
|
||||
|
||||
return digest->algorithm;
|
||||
}
|
||||
|
||||
#endif /* defined(TOR_UNIT_TESTS) */
|
||||
|
||||
/**
|
||||
* Return the number of bytes we need to malloc in order to get a
|
||||
* crypto_digest_t for <b>alg</b>, or the number of bytes we need to wipe
|
||||
* when we free one.
|
||||
*/
|
||||
static size_t
|
||||
crypto_digest_alloc_bytes(digest_algorithm_t alg)
|
||||
{
|
||||
/* Helper: returns the number of bytes in the 'f' field of 'st' */
|
||||
#define STRUCT_FIELD_SIZE(st, f) (sizeof( ((st*)0)->f ))
|
||||
/* Gives the length of crypto_digest_t through the end of the field 'd' */
|
||||
#define END_OF_FIELD(f) (offsetof(crypto_digest_t, f) + \
|
||||
STRUCT_FIELD_SIZE(crypto_digest_t, f))
|
||||
switch (alg) {
|
||||
case DIGEST_SHA1:
|
||||
return END_OF_FIELD(d.sha1);
|
||||
case DIGEST_SHA256:
|
||||
return END_OF_FIELD(d.sha2);
|
||||
case DIGEST_SHA512:
|
||||
return END_OF_FIELD(d.sha512);
|
||||
case DIGEST_SHA3_256:
|
||||
case DIGEST_SHA3_512:
|
||||
return END_OF_FIELD(d.sha3);
|
||||
default:
|
||||
tor_assert(0); // LCOV_EXCL_LINE
|
||||
return 0; // LCOV_EXCL_LINE
|
||||
}
|
||||
#undef END_OF_FIELD
|
||||
#undef STRUCT_FIELD_SIZE
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal function: create and return a new digest object for 'algorithm'.
|
||||
* Does not typecheck the algorithm.
|
||||
*/
|
||||
static crypto_digest_t *
|
||||
crypto_digest_new_internal(digest_algorithm_t algorithm)
|
||||
{
|
||||
crypto_digest_t *r = tor_malloc(crypto_digest_alloc_bytes(algorithm));
|
||||
r->algorithm = algorithm;
|
||||
|
||||
switch (algorithm)
|
||||
{
|
||||
case DIGEST_SHA1:
|
||||
SHA1_Init(&r->d.sha1);
|
||||
break;
|
||||
case DIGEST_SHA256:
|
||||
SHA256_Init(&r->d.sha2);
|
||||
break;
|
||||
case DIGEST_SHA512:
|
||||
SHA512_Init(&r->d.sha512);
|
||||
break;
|
||||
case DIGEST_SHA3_256:
|
||||
keccak_digest_init(&r->d.sha3, 256);
|
||||
break;
|
||||
case DIGEST_SHA3_512:
|
||||
keccak_digest_init(&r->d.sha3, 512);
|
||||
break;
|
||||
default:
|
||||
tor_assert_unreached();
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
/** Allocate and return a new digest object to compute SHA1 digests.
|
||||
*/
|
||||
crypto_digest_t *
|
||||
crypto_digest_new(void)
|
||||
{
|
||||
return crypto_digest_new_internal(DIGEST_SHA1);
|
||||
}
|
||||
|
||||
/** Allocate and return a new digest object to compute 256-bit digests
|
||||
* using <b>algorithm</b>.
|
||||
*
|
||||
* C_RUST_COUPLED: `external::crypto_digest::crypto_digest256_new`
|
||||
* C_RUST_COUPLED: `crypto::digest::Sha256::default`
|
||||
*/
|
||||
crypto_digest_t *
|
||||
crypto_digest256_new(digest_algorithm_t algorithm)
|
||||
{
|
||||
tor_assert(algorithm == DIGEST_SHA256 || algorithm == DIGEST_SHA3_256);
|
||||
return crypto_digest_new_internal(algorithm);
|
||||
}
|
||||
|
||||
/** Allocate and return a new digest object to compute 512-bit digests
|
||||
* using <b>algorithm</b>. */
|
||||
crypto_digest_t *
|
||||
crypto_digest512_new(digest_algorithm_t algorithm)
|
||||
{
|
||||
tor_assert(algorithm == DIGEST_SHA512 || algorithm == DIGEST_SHA3_512);
|
||||
return crypto_digest_new_internal(algorithm);
|
||||
}
|
||||
|
||||
/** Deallocate a digest object.
|
||||
*/
|
||||
void
|
||||
crypto_digest_free_(crypto_digest_t *digest)
|
||||
{
|
||||
if (!digest)
|
||||
return;
|
||||
size_t bytes = crypto_digest_alloc_bytes(digest->algorithm);
|
||||
memwipe(digest, 0, bytes);
|
||||
tor_free(digest);
|
||||
}
|
||||
|
||||
/** Add <b>len</b> bytes from <b>data</b> to the digest object.
|
||||
*
|
||||
* C_RUST_COUPLED: `external::crypto_digest::crypto_digest_add_bytess`
|
||||
* C_RUST_COUPLED: `crypto::digest::Sha256::process`
|
||||
*/
|
||||
void
|
||||
crypto_digest_add_bytes(crypto_digest_t *digest, const char *data,
|
||||
size_t len)
|
||||
{
|
||||
tor_assert(digest);
|
||||
tor_assert(data);
|
||||
/* Using the SHA*_*() calls directly means we don't support doing
|
||||
* SHA in hardware. But so far the delay of getting the question
|
||||
* to the hardware, and hearing the answer, is likely higher than
|
||||
* just doing it ourselves. Hashes are fast.
|
||||
*/
|
||||
switch (digest->algorithm) {
|
||||
case DIGEST_SHA1:
|
||||
SHA1_Update(&digest->d.sha1, (void*)data, len);
|
||||
break;
|
||||
case DIGEST_SHA256:
|
||||
SHA256_Update(&digest->d.sha2, (void*)data, len);
|
||||
break;
|
||||
case DIGEST_SHA512:
|
||||
SHA512_Update(&digest->d.sha512, (void*)data, len);
|
||||
break;
|
||||
case DIGEST_SHA3_256: /* FALLSTHROUGH */
|
||||
case DIGEST_SHA3_512:
|
||||
keccak_digest_update(&digest->d.sha3, (const uint8_t *)data, len);
|
||||
break;
|
||||
default:
|
||||
/* LCOV_EXCL_START */
|
||||
tor_fragile_assert();
|
||||
break;
|
||||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
}
|
||||
|
||||
/** Compute the hash of the data that has been passed to the digest
|
||||
* object; write the first out_len bytes of the result to <b>out</b>.
|
||||
* <b>out_len</b> must be \<= DIGEST512_LEN.
|
||||
*
|
||||
* C_RUST_COUPLED: `external::crypto_digest::crypto_digest_get_digest`
|
||||
* C_RUST_COUPLED: `impl digest::FixedOutput for Sha256`
|
||||
*/
|
||||
void
|
||||
crypto_digest_get_digest(crypto_digest_t *digest,
|
||||
char *out, size_t out_len)
|
||||
{
|
||||
unsigned char r[DIGEST512_LEN];
|
||||
crypto_digest_t tmpenv;
|
||||
tor_assert(digest);
|
||||
tor_assert(out);
|
||||
tor_assert(out_len <= crypto_digest_algorithm_get_length(digest->algorithm));
|
||||
|
||||
/* The SHA-3 code handles copying into a temporary ctx, and also can handle
|
||||
* short output buffers by truncating appropriately. */
|
||||
if (digest->algorithm == DIGEST_SHA3_256 ||
|
||||
digest->algorithm == DIGEST_SHA3_512) {
|
||||
keccak_digest_sum(&digest->d.sha3, (uint8_t *)out, out_len);
|
||||
return;
|
||||
}
|
||||
|
||||
const size_t alloc_bytes = crypto_digest_alloc_bytes(digest->algorithm);
|
||||
/* memcpy into a temporary ctx, since SHA*_Final clears the context */
|
||||
memcpy(&tmpenv, digest, alloc_bytes);
|
||||
switch (digest->algorithm) {
|
||||
case DIGEST_SHA1:
|
||||
SHA1_Final(r, &tmpenv.d.sha1);
|
||||
break;
|
||||
case DIGEST_SHA256:
|
||||
SHA256_Final(r, &tmpenv.d.sha2);
|
||||
break;
|
||||
case DIGEST_SHA512:
|
||||
SHA512_Final(r, &tmpenv.d.sha512);
|
||||
break;
|
||||
//LCOV_EXCL_START
|
||||
case DIGEST_SHA3_256: /* FALLSTHROUGH */
|
||||
case DIGEST_SHA3_512:
|
||||
default:
|
||||
log_warn(LD_BUG, "Handling unexpected algorithm %d", digest->algorithm);
|
||||
/* This is fatal, because it should never happen. */
|
||||
tor_assert_unreached();
|
||||
break;
|
||||
//LCOV_EXCL_STOP
|
||||
}
|
||||
memcpy(out, r, out_len);
|
||||
memwipe(r, 0, sizeof(r));
|
||||
}
|
||||
|
||||
/** Allocate and return a new digest object with the same state as
|
||||
* <b>digest</b>
|
||||
*
|
||||
* C_RUST_COUPLED: `external::crypto_digest::crypto_digest_dup`
|
||||
* C_RUST_COUPLED: `impl Clone for crypto::digest::Sha256`
|
||||
*/
|
||||
crypto_digest_t *
|
||||
crypto_digest_dup(const crypto_digest_t *digest)
|
||||
{
|
||||
tor_assert(digest);
|
||||
const size_t alloc_bytes = crypto_digest_alloc_bytes(digest->algorithm);
|
||||
return tor_memdup(digest, alloc_bytes);
|
||||
}
|
||||
|
||||
/** Temporarily save the state of <b>digest</b> in <b>checkpoint</b>.
|
||||
* Asserts that <b>digest</b> is a SHA1 digest object.
|
||||
*/
|
||||
void
|
||||
crypto_digest_checkpoint(crypto_digest_checkpoint_t *checkpoint,
|
||||
const crypto_digest_t *digest)
|
||||
{
|
||||
const size_t bytes = crypto_digest_alloc_bytes(digest->algorithm);
|
||||
tor_assert(bytes <= sizeof(checkpoint->mem));
|
||||
memcpy(checkpoint->mem, digest, bytes);
|
||||
}
|
||||
|
||||
/** Restore the state of <b>digest</b> from <b>checkpoint</b>.
|
||||
* Asserts that <b>digest</b> is a SHA1 digest object. Requires that the
|
||||
* state was previously stored with crypto_digest_checkpoint() */
|
||||
void
|
||||
crypto_digest_restore(crypto_digest_t *digest,
|
||||
const crypto_digest_checkpoint_t *checkpoint)
|
||||
{
|
||||
const size_t bytes = crypto_digest_alloc_bytes(digest->algorithm);
|
||||
memcpy(digest, checkpoint->mem, bytes);
|
||||
}
|
||||
|
||||
/** Replace the state of the digest object <b>into</b> with the state
|
||||
* of the digest object <b>from</b>. Requires that 'into' and 'from'
|
||||
* have the same digest type.
|
||||
*/
|
||||
void
|
||||
crypto_digest_assign(crypto_digest_t *into,
|
||||
const crypto_digest_t *from)
|
||||
{
|
||||
tor_assert(into);
|
||||
tor_assert(from);
|
||||
tor_assert(into->algorithm == from->algorithm);
|
||||
const size_t alloc_bytes = crypto_digest_alloc_bytes(from->algorithm);
|
||||
memcpy(into,from,alloc_bytes);
|
||||
}
|
||||
|
||||
/** Given a list of strings in <b>lst</b>, set the <b>len_out</b>-byte digest
|
||||
* at <b>digest_out</b> to the hash of the concatenation of those strings,
|
||||
* plus the optional string <b>append</b>, computed with the algorithm
|
||||
* <b>alg</b>.
|
||||
* <b>out_len</b> must be \<= DIGEST512_LEN. */
|
||||
void
|
||||
crypto_digest_smartlist(char *digest_out, size_t len_out,
|
||||
const smartlist_t *lst,
|
||||
const char *append,
|
||||
digest_algorithm_t alg)
|
||||
{
|
||||
crypto_digest_smartlist_prefix(digest_out, len_out, NULL, lst, append, alg);
|
||||
}
|
||||
|
||||
/** Given a list of strings in <b>lst</b>, set the <b>len_out</b>-byte digest
|
||||
* at <b>digest_out</b> to the hash of the concatenation of: the
|
||||
* optional string <b>prepend</b>, those strings,
|
||||
* and the optional string <b>append</b>, computed with the algorithm
|
||||
* <b>alg</b>.
|
||||
* <b>len_out</b> must be \<= DIGEST512_LEN. */
|
||||
void
|
||||
crypto_digest_smartlist_prefix(char *digest_out, size_t len_out,
|
||||
const char *prepend,
|
||||
const smartlist_t *lst,
|
||||
const char *append,
|
||||
digest_algorithm_t alg)
|
||||
{
|
||||
crypto_digest_t *d = crypto_digest_new_internal(alg);
|
||||
if (prepend)
|
||||
crypto_digest_add_bytes(d, prepend, strlen(prepend));
|
||||
SMARTLIST_FOREACH(lst, const char *, cp,
|
||||
crypto_digest_add_bytes(d, cp, strlen(cp)));
|
||||
if (append)
|
||||
crypto_digest_add_bytes(d, append, strlen(append));
|
||||
crypto_digest_get_digest(d, digest_out, len_out);
|
||||
crypto_digest_free(d);
|
||||
}
|
||||
|
||||
/** Compute the HMAC-SHA-256 of the <b>msg_len</b> bytes in <b>msg</b>, using
|
||||
* the <b>key</b> of length <b>key_len</b>. Store the DIGEST256_LEN-byte
|
||||
* result in <b>hmac_out</b>. Asserts on failure.
|
||||
*/
|
||||
void
|
||||
crypto_hmac_sha256(char *hmac_out,
|
||||
const char *key, size_t key_len,
|
||||
const char *msg, size_t msg_len)
|
||||
{
|
||||
unsigned char *rv = NULL;
|
||||
/* If we've got OpenSSL >=0.9.8 we can use its hmac implementation. */
|
||||
tor_assert(key_len < INT_MAX);
|
||||
tor_assert(msg_len < INT_MAX);
|
||||
tor_assert(hmac_out);
|
||||
rv = HMAC(EVP_sha256(), key, (int)key_len, (unsigned char*)msg, (int)msg_len,
|
||||
(unsigned char*)hmac_out, NULL);
|
||||
tor_assert(rv);
|
||||
}
|
||||
|
||||
/** Compute a MAC using SHA3-256 of <b>msg_len</b> bytes in <b>msg</b> using a
|
||||
* <b>key</b> of length <b>key_len</b> and a <b>salt</b> of length
|
||||
* <b>salt_len</b>. Store the result of <b>len_out</b> bytes in in
|
||||
* <b>mac_out</b>. This function can't fail. */
|
||||
void
|
||||
crypto_mac_sha3_256(uint8_t *mac_out, size_t len_out,
|
||||
const uint8_t *key, size_t key_len,
|
||||
const uint8_t *msg, size_t msg_len)
|
||||
{
|
||||
crypto_digest_t *digest;
|
||||
|
||||
const uint64_t key_len_netorder = tor_htonll(key_len);
|
||||
|
||||
tor_assert(mac_out);
|
||||
tor_assert(key);
|
||||
tor_assert(msg);
|
||||
|
||||
digest = crypto_digest256_new(DIGEST_SHA3_256);
|
||||
|
||||
/* Order matters here that is any subsystem using this function should
|
||||
* expect this very precise ordering in the MAC construction. */
|
||||
crypto_digest_add_bytes(digest, (const char *) &key_len_netorder,
|
||||
sizeof(key_len_netorder));
|
||||
crypto_digest_add_bytes(digest, (const char *) key, key_len);
|
||||
crypto_digest_add_bytes(digest, (const char *) msg, msg_len);
|
||||
crypto_digest_get_digest(digest, (char *) mac_out, len_out);
|
||||
crypto_digest_free(digest);
|
||||
}
|
||||
|
||||
/* xof functions */
|
||||
|
||||
/** Internal state for a eXtendable-Output Function (XOF). */
|
||||
struct crypto_xof_t {
|
||||
keccak_state s;
|
||||
};
|
||||
|
||||
/** Allocate a new XOF object backed by SHAKE-256. The security level
|
||||
* provided is a function of the length of the output used. Read and
|
||||
* understand FIPS-202 A.2 "Additional Consideration for Extendable-Output
|
||||
* Functions" before using this construct.
|
||||
*/
|
||||
crypto_xof_t *
|
||||
crypto_xof_new(void)
|
||||
{
|
||||
crypto_xof_t *xof;
|
||||
xof = tor_malloc(sizeof(crypto_xof_t));
|
||||
keccak_xof_init(&xof->s, 256);
|
||||
return xof;
|
||||
}
|
||||
|
||||
/** Absorb bytes into a XOF object. Must not be called after a call to
|
||||
* crypto_xof_squeeze_bytes() for the same instance, and will assert
|
||||
* if attempted.
|
||||
*/
|
||||
void
|
||||
crypto_xof_add_bytes(crypto_xof_t *xof, const uint8_t *data, size_t len)
|
||||
{
|
||||
int i = keccak_xof_absorb(&xof->s, data, len);
|
||||
tor_assert(i == 0);
|
||||
}
|
||||
|
||||
/** Squeeze bytes out of a XOF object. Calling this routine will render
|
||||
* the XOF instance ineligible to absorb further data.
|
||||
*/
|
||||
void
|
||||
crypto_xof_squeeze_bytes(crypto_xof_t *xof, uint8_t *out, size_t len)
|
||||
{
|
||||
int i = keccak_xof_squeeze(&xof->s, out, len);
|
||||
tor_assert(i == 0);
|
||||
}
|
||||
|
||||
/** Cleanse and deallocate a XOF object. */
|
||||
void
|
||||
crypto_xof_free_(crypto_xof_t *xof)
|
||||
{
|
||||
if (!xof)
|
||||
return;
|
||||
memwipe(xof, 0, sizeof(crypto_xof_t));
|
||||
tor_free(xof);
|
||||
}
|
||||
|
|
@ -1,136 +0,0 @@
|
|||
/* Copyright (c) 2001, Matej Pfajfar.
|
||||
* Copyright (c) 2001-2004, Roger Dingledine.
|
||||
* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
|
||||
* Copyright (c) 2007-2017, The Tor Project, Inc. */
|
||||
/* See LICENSE for licensing information */
|
||||
|
||||
/**
|
||||
* \file crypto_digest.h
|
||||
*
|
||||
* \brief Headers for crypto_digest.c
|
||||
**/
|
||||
|
||||
#ifndef TOR_CRYPTO_DIGEST_H
|
||||
#define TOR_CRYPTO_DIGEST_H
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "container.h"
|
||||
#include "torint.h"
|
||||
|
||||
/** Length of the output of our message digest. */
|
||||
#define DIGEST_LEN 20
|
||||
/** Length of the output of our second (improved) message digests. (For now
|
||||
* this is just sha256, but it could be any other 256-bit digest.) */
|
||||
#define DIGEST256_LEN 32
|
||||
/** Length of the output of our 64-bit optimized message digests (SHA512). */
|
||||
#define DIGEST512_LEN 64
|
||||
|
||||
/** Length of a sha1 message digest when encoded in base32 with trailing =
|
||||
* signs removed. */
|
||||
#define BASE32_DIGEST_LEN 32
|
||||
/** Length of a sha1 message digest when encoded in base64 with trailing =
|
||||
* signs removed. */
|
||||
#define BASE64_DIGEST_LEN 27
|
||||
/** Length of a sha256 message digest when encoded in base64 with trailing =
|
||||
* signs removed. */
|
||||
#define BASE64_DIGEST256_LEN 43
|
||||
/** Length of a sha512 message digest when encoded in base64 with trailing =
|
||||
* signs removed. */
|
||||
#define BASE64_DIGEST512_LEN 86
|
||||
|
||||
/** Length of hex encoding of SHA1 digest, not including final NUL. */
|
||||
#define HEX_DIGEST_LEN 40
|
||||
/** Length of hex encoding of SHA256 digest, not including final NUL. */
|
||||
#define HEX_DIGEST256_LEN 64
|
||||
/** Length of hex encoding of SHA512 digest, not including final NUL. */
|
||||
#define HEX_DIGEST512_LEN 128
|
||||
|
||||
typedef enum {
|
||||
DIGEST_SHA1 = 0,
|
||||
DIGEST_SHA256 = 1,
|
||||
DIGEST_SHA512 = 2,
|
||||
DIGEST_SHA3_256 = 3,
|
||||
DIGEST_SHA3_512 = 4,
|
||||
} digest_algorithm_t;
|
||||
#define N_DIGEST_ALGORITHMS (DIGEST_SHA3_512+1)
|
||||
#define N_COMMON_DIGEST_ALGORITHMS (DIGEST_SHA256+1)
|
||||
|
||||
#define DIGEST_CHECKPOINT_BYTES (SIZEOF_VOID_P + 512)
|
||||
/** Structure used to temporarily save the a digest object. Only implemented
|
||||
* for SHA1 digest for now. */
|
||||
typedef struct crypto_digest_checkpoint_t {
|
||||
uint8_t mem[DIGEST_CHECKPOINT_BYTES];
|
||||
} crypto_digest_checkpoint_t;
|
||||
|
||||
/** A set of all the digests we commonly compute, taken on a single
|
||||
* string. Any digests that are shorter than 512 bits are right-padded
|
||||
* with 0 bits.
|
||||
*
|
||||
* Note that this representation wastes 44 bytes for the SHA1 case, so
|
||||
* don't use it for anything where we need to allocate a whole bunch at
|
||||
* once.
|
||||
**/
|
||||
typedef struct {
|
||||
char d[N_COMMON_DIGEST_ALGORITHMS][DIGEST256_LEN];
|
||||
} common_digests_t;
|
||||
|
||||
typedef struct crypto_digest_t crypto_digest_t;
|
||||
typedef struct crypto_xof_t crypto_xof_t;
|
||||
|
||||
/* SHA-1 and other digests */
|
||||
int crypto_digest(char *digest, const char *m, size_t len);
|
||||
int crypto_digest256(char *digest, const char *m, size_t len,
|
||||
digest_algorithm_t algorithm);
|
||||
int crypto_digest512(char *digest, const char *m, size_t len,
|
||||
digest_algorithm_t algorithm);
|
||||
int crypto_common_digests(common_digests_t *ds_out, const char *m, size_t len);
|
||||
void crypto_digest_smartlist_prefix(char *digest_out, size_t len_out,
|
||||
const char *prepend,
|
||||
const struct smartlist_t *lst,
|
||||
const char *append,
|
||||
digest_algorithm_t alg);
|
||||
void crypto_digest_smartlist(char *digest_out, size_t len_out,
|
||||
const struct smartlist_t *lst, const char *append,
|
||||
digest_algorithm_t alg);
|
||||
const char *crypto_digest_algorithm_get_name(digest_algorithm_t alg);
|
||||
size_t crypto_digest_algorithm_get_length(digest_algorithm_t alg);
|
||||
int crypto_digest_algorithm_parse_name(const char *name);
|
||||
crypto_digest_t *crypto_digest_new(void);
|
||||
crypto_digest_t *crypto_digest256_new(digest_algorithm_t algorithm);
|
||||
crypto_digest_t *crypto_digest512_new(digest_algorithm_t algorithm);
|
||||
void crypto_digest_free_(crypto_digest_t *digest);
|
||||
#define crypto_digest_free(d) \
|
||||
FREE_AND_NULL(crypto_digest_t, crypto_digest_free_, (d))
|
||||
void crypto_digest_add_bytes(crypto_digest_t *digest, const char *data,
|
||||
size_t len);
|
||||
void crypto_digest_get_digest(crypto_digest_t *digest,
|
||||
char *out, size_t out_len);
|
||||
crypto_digest_t *crypto_digest_dup(const crypto_digest_t *digest);
|
||||
void crypto_digest_checkpoint(crypto_digest_checkpoint_t *checkpoint,
|
||||
const crypto_digest_t *digest);
|
||||
void crypto_digest_restore(crypto_digest_t *digest,
|
||||
const crypto_digest_checkpoint_t *checkpoint);
|
||||
void crypto_digest_assign(crypto_digest_t *into,
|
||||
const crypto_digest_t *from);
|
||||
void crypto_hmac_sha256(char *hmac_out,
|
||||
const char *key, size_t key_len,
|
||||
const char *msg, size_t msg_len);
|
||||
void crypto_mac_sha3_256(uint8_t *mac_out, size_t len_out,
|
||||
const uint8_t *key, size_t key_len,
|
||||
const uint8_t *msg, size_t msg_len);
|
||||
|
||||
/* xof functions*/
|
||||
crypto_xof_t *crypto_xof_new(void);
|
||||
void crypto_xof_add_bytes(crypto_xof_t *xof, const uint8_t *data, size_t len);
|
||||
void crypto_xof_squeeze_bytes(crypto_xof_t *xof, uint8_t *out, size_t len);
|
||||
void crypto_xof_free_(crypto_xof_t *xof);
|
||||
#define crypto_xof_free(xof) \
|
||||
FREE_AND_NULL(crypto_xof_t, crypto_xof_free_, (xof))
|
||||
|
||||
#ifdef TOR_UNIT_TESTS
|
||||
digest_algorithm_t crypto_digest_get_algorithm(crypto_digest_t *digest);
|
||||
#endif
|
||||
|
||||
#endif /* !defined(TOR_CRYPTO_DIGEST_H) */
|
||||
|
|
@ -21,12 +21,11 @@
|
|||
#include <sys/stat.h>
|
||||
#endif
|
||||
|
||||
#include "crypto.h"
|
||||
|
||||
#include "crypto_curve25519.h"
|
||||
#include "crypto_digest.h"
|
||||
#include "crypto_ed25519.h"
|
||||
#include "crypto_format.h"
|
||||
#include "crypto_rand.h"
|
||||
#include "crypto_util.h"
|
||||
#include "torlog.h"
|
||||
#include "util.h"
|
||||
#include "util_format.h"
|
||||
|
@ -226,8 +225,8 @@ ed25519_public_key_is_zero(const ed25519_public_key_t *pubkey)
|
|||
|
||||
/* Return a heap-allocated array that contains <b>msg</b> prefixed by the
|
||||
* string <b>prefix_str</b>. Set <b>final_msg_len_out</b> to the size of the
|
||||
* final array. If an error occurred, return NULL. It's the responsibility of
|
||||
* the caller to free the returned array. */
|
||||
* final array. If an error occured, return NULL. It's the resonsibility of the
|
||||
* caller to free the returned array. */
|
||||
static uint8_t *
|
||||
get_prefixed_msg(const uint8_t *msg, size_t msg_len,
|
||||
const char *prefix_str,
|
||||
|
@ -260,7 +259,7 @@ get_prefixed_msg(const uint8_t *msg, size_t msg_len,
|
|||
* Set <b>signature_out</b> to a signature of the <b>len</b>-byte message
|
||||
* <b>msg</b>, using the secret and public key in <b>keypair</b>.
|
||||
*
|
||||
* Return 0 if we successfully signed the message, otherwise return -1.
|
||||
* Return 0 if we successfuly signed the message, otherwise return -1.
|
||||
*/
|
||||
int
|
||||
ed25519_sign(ed25519_signature_t *signature_out,
|
||||
|
@ -530,7 +529,7 @@ ed25519_keypair_blind(ed25519_keypair_t *out,
|
|||
/**
|
||||
* Given an ed25519 public key in <b>inp</b>, generate a corresponding blinded
|
||||
* public key in <b>out</b>, blinded with the 32-byte parameter in
|
||||
* <b>param</b>. Return 0 on success, -1 on railure.
|
||||
* <b>param</b>. Return 0 on sucess, -1 on railure.
|
||||
*/
|
||||
int
|
||||
ed25519_public_blind(ed25519_public_key_t *out,
|
||||
|
@ -623,7 +622,7 @@ ed25519_pubkey_read_from_file(ed25519_public_key_t *pubkey_out,
|
|||
|
||||
/** Release all storage held for <b>kp</b>. */
|
||||
void
|
||||
ed25519_keypair_free_(ed25519_keypair_t *kp)
|
||||
ed25519_keypair_free(ed25519_keypair_t *kp)
|
||||
{
|
||||
if (! kp)
|
||||
return;
|
||||
|
@ -720,7 +719,7 @@ ed25519_impl_spot_check,(void))
|
|||
return -1;
|
||||
|
||||
/* XXX/yawning: Someone that's more paranoid than I am, can write "Assume
|
||||
* ref0 is canonical, and fuzz impl against it" if they want, but I doubt
|
||||
* ref0 is cannonical, and fuzz impl against it" if they want, but I doubt
|
||||
* that will catch anything that the known answer tests won't.
|
||||
*/
|
||||
goto end;
|
||||
|
@ -763,7 +762,7 @@ pick_ed25519_impl(void)
|
|||
/* LCOV_EXCL_STOP */
|
||||
}
|
||||
|
||||
/* Initialize the Ed25519 implementation. This is necessary if you're
|
||||
/* Initialize the Ed25519 implementation. This is neccessary if you're
|
||||
* going to use them in a multithreaded setting, and not otherwise. */
|
||||
void
|
||||
ed25519_init(void)
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
#include "testsupport.h"
|
||||
#include "torint.h"
|
||||
#include "crypto_curve25519.h"
|
||||
#include "util.h"
|
||||
|
||||
#define ED25519_PUBKEY_LEN 32
|
||||
#define ED25519_SECKEY_LEN 64
|
||||
|
@ -118,9 +117,7 @@ int ed25519_pubkey_read_from_file(ed25519_public_key_t *pubkey_out,
|
|||
char **tag_out,
|
||||
const char *filename);
|
||||
|
||||
void ed25519_keypair_free_(ed25519_keypair_t *kp);
|
||||
#define ed25519_keypair_free(kp) \
|
||||
FREE_AND_NULL(ed25519_keypair_t, ed25519_keypair_free_, (kp))
|
||||
void ed25519_keypair_free(ed25519_keypair_t *kp);
|
||||
|
||||
int ed25519_pubkey_eq(const ed25519_public_key_t *key1,
|
||||
const ed25519_public_key_t *key2);
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue