Compare commits
214 Commits
master
...
release-0.
Author | SHA1 | Date |
---|---|---|
Nick Mathewson | 4843d5349d | |
Nick Mathewson | 3f8fe441cf | |
Nick Mathewson | 12e465344e | |
Nick Mathewson | 90e7364e7e | |
Nick Mathewson | d47da40058 | |
Nick Mathewson | 5fd8f3b71d | |
Nick Mathewson | 9ca9e6a1f7 | |
Nick Mathewson | 8ddd84707e | |
Nick Mathewson | 3bf89fb85f | |
Nick Mathewson | edf721f8f0 | |
Nick Mathewson | beaaeecd20 | |
Nick Mathewson | 3f2cf1c0f5 | |
Nick Mathewson | 28dc7a519c | |
Nick Mathewson | 02ac1822ab | |
Nick Mathewson | ae0ee02026 | |
Nick Mathewson | 8eb9aaf4f6 | |
Nick Mathewson | 347b38d6d9 | |
Nick Mathewson | 04007557fb | |
Nick Mathewson | cbea95ae67 | |
Nick Mathewson | e9ec63d1ac | |
Nick Mathewson | 72db4f836a | |
Nick Mathewson | 35179a8c05 | |
Nick Mathewson | 1eb7041ef1 | |
Nick Mathewson | e3966d47c7 | |
Nick Mathewson | 21cea2c9de | |
Nick Mathewson | 19602bffbe | |
Nick Mathewson | babd102f0b | |
Nick Mathewson | b6b239ce0c | |
Nick Mathewson | ce9df228a5 | |
Nick Mathewson | ff679ee066 | |
Nick Mathewson | 60d3a3c754 | |
Nick Mathewson | 7e2e8ac245 | |
Nick Mathewson | 7e4623a235 | |
Nick Mathewson | f0f22ad92c | |
Nick Mathewson | b9b7013062 | |
Nick Mathewson | 0f4b1020af | |
Nick Mathewson | 97c988c431 | |
Nick Mathewson | c93f69af58 | |
Nick Mathewson | cf55f0516c | |
Nick Mathewson | ed13a7f625 | |
Nick Mathewson | abd6205384 | |
Nick Mathewson | 6f238a44d8 | |
Nick Mathewson | 6d0309e48b | |
Nick Mathewson | d83d1c7a89 | |
Nick Mathewson | 76b73013e2 | |
Nick Mathewson | 0e0baad5e8 | |
Nick Mathewson | c30d2daae0 | |
Nick Mathewson | 256cd9d877 | |
Nick Mathewson | 83648ef077 | |
Nick Mathewson | f9fe48989b | |
Nick Mathewson | 0e5140320b | |
Nick Mathewson | e9a102ff5e | |
Nick Mathewson | ed304a052f | |
Nick Mathewson | a8a060cdb3 | |
Nick Mathewson | 45b1c6bc8b | |
Nick Mathewson | 40faebd45b | |
Nick Mathewson | 1723138fcd | |
Nick Mathewson | bda3c54447 | |
Nick Mathewson | ee1bbe21ab | |
Nick Mathewson | b63cbec65e | |
Nick Mathewson | 74ce41d4d4 | |
Nick Mathewson | 2edad42fd8 | |
Nick Mathewson | fbb74fb37c | |
Nick Mathewson | 24f7698320 | |
Nick Mathewson | d3048a8f5b | |
Nick Mathewson | 9703b41480 | |
Nick Mathewson | 727d3f1b5e | |
Nick Mathewson | 94ad23deb2 | |
Nick Mathewson | d8d52f2b73 | |
Nick Mathewson | 14746dfba2 | |
Nick Mathewson | 7c548437cc | |
Nick Mathewson | bedd32e5d1 | |
Nick Mathewson | 3c0150aa46 | |
Nick Mathewson | 70fcbd5f83 | |
Nick Mathewson | d96f7f38e8 | |
Nick Mathewson | 5355b99dc0 | |
Nick Mathewson | 5c98411663 | |
Nick Mathewson | fe5d607d6b | |
Nick Mathewson | ba1db0c797 | |
Nick Mathewson | fb1c191e54 | |
Nick Mathewson | 6155f76691 | |
Nick Mathewson | 987f628b73 | |
Nick Mathewson | ad5027f7dc | |
Nick Mathewson | 4a49e134bc | |
Nick Mathewson | ee70e2ed6d | |
Nick Mathewson | af51ac47e0 | |
Nick Mathewson | d5e3b6e6b7 | |
Nick Mathewson | ce8d60674d | |
Nick Mathewson | ebedb5e06f | |
Nick Mathewson | 602f9565a9 | |
Nick Mathewson | 5f78775a8a | |
Nick Mathewson | 11abdccc75 | |
Nick Mathewson | 2fee12a96a | |
Nick Mathewson | 919286be05 | |
Nick Mathewson | adb7b92ca3 | |
Nick Mathewson | af5454e01c | |
Nick Mathewson | ecc84d8780 | |
Nick Mathewson | db4651469d | |
Nick Mathewson | 29b459a637 | |
Nick Mathewson | 2074984c34 | |
Nick Mathewson | e2ddc8b547 | |
Nick Mathewson | 5bf84b1f00 | |
Nick Mathewson | 7ef22d0bf0 | |
Nick Mathewson | 61d0f65cf0 | |
Nick Mathewson | 1115200d97 | |
Nick Mathewson | ac21fb8c68 | |
Nick Mathewson | 6babd3d9ba | |
Nick Mathewson | 9d35ddf110 | |
Nick Mathewson | 17e67dce81 | |
Nick Mathewson | ee2e3e852a | |
Nick Mathewson | d7eef61147 | |
Nick Mathewson | b05226f05c | |
Nick Mathewson | fd8d526f0d | |
Nick Mathewson | 2894ac304c | |
Nick Mathewson | dc01695810 | |
Nick Mathewson | 5e37c7d780 | |
Nick Mathewson | 44c2973224 | |
Nick Mathewson | 3c6034eaac | |
Nick Mathewson | 8230b0768b | |
Nick Mathewson | c61e919ec2 | |
Nick Mathewson | a040b05890 | |
Nick Mathewson | 3747807333 | |
Nick Mathewson | 931b2dbae5 | |
Nick Mathewson | 77a848b9d4 | |
Nick Mathewson | 8b4ff0168a | |
Nick Mathewson | 4d4e2fc224 | |
Nick Mathewson | 6108499c99 | |
Nick Mathewson | 636b5d19ae | |
Nick Mathewson | f0fa7a3420 | |
Nick Mathewson | c4ecb8f867 | |
Nick Mathewson | efc306c59a | |
Nick Mathewson | cf0124b238 | |
Nick Mathewson | b9c29105f1 | |
Nick Mathewson | bebf7eb54e | |
Nick Mathewson | c515fbc732 | |
Nick Mathewson | 3a5cf9aa2f | |
Nick Mathewson | faa28d40ec | |
Nick Mathewson | 1da84c63eb | |
Nick Mathewson | 526211949e | |
Nick Mathewson | 7ed8037495 | |
Nick Mathewson | ff2c31093a | |
Nick Mathewson | 51d14b3d47 | |
Nick Mathewson | 1dd0be75c2 | |
Nick Mathewson | 882dd4de0b | |
Nick Mathewson | 9944fd92ce | |
Nick Mathewson | 4d5e8378be | |
Nick Mathewson | 47e7a167d2 | |
Nick Mathewson | cbcff6759d | |
Nick Mathewson | f248a4a38e | |
Nick Mathewson | 8e451c5c7c | |
Nick Mathewson | e084fa419a | |
Nick Mathewson | 3938692f32 | |
Nick Mathewson | 4872c28afa | |
Nick Mathewson | 9409d98ee9 | |
Nick Mathewson | ef592d1331 | |
Nick Mathewson | 83389502ee | |
Nick Mathewson | c1b411109e | |
Nick Mathewson | 6ddc4d5e27 | |
Nick Mathewson | 026882fa3d | |
Nick Mathewson | 61ceb26229 | |
Nick Mathewson | 883d1957f6 | |
Nick Mathewson | 09f5077d48 | |
Nick Mathewson | 72aa33c017 | |
Nick Mathewson | 949c62c771 | |
Nick Mathewson | 31417631cb | |
Nick Mathewson | 66801bc90c | |
Nick Mathewson | 2faee019e2 | |
Nick Mathewson | 2e166d8684 | |
Nick Mathewson | 75eaca4e81 | |
Nick Mathewson | 3205700bc4 | |
Nick Mathewson | 8c2ccf9370 | |
Nick Mathewson | a2a5bd83f0 | |
Nick Mathewson | 180e21fbc0 | |
Nick Mathewson | a2d7033195 | |
Nick Mathewson | 4557f3f908 | |
Nick Mathewson | 3ada086d38 | |
Nick Mathewson | 745ffd6d3a | |
Nick Mathewson | f1431f4393 | |
Nick Mathewson | 4db33ecc04 | |
Nick Mathewson | 5eefa43137 | |
Nick Mathewson | 05ca8ab5b6 | |
Nick Mathewson | 11b2d36db3 | |
Nick Mathewson | 4d52b740f9 | |
Nick Mathewson | d5c1b7f185 | |
Nick Mathewson | 9665bad777 | |
Nick Mathewson | 47982cdc09 | |
Nick Mathewson | 0be10dde5a | |
Nick Mathewson | ab1c182127 | |
Nick Mathewson | 251316c5d8 | |
Nick Mathewson | f6a36996db | |
Nick Mathewson | 02030009c5 | |
Nick Mathewson | adae5d3b69 | |
Nick Mathewson | c8e6b2e4bf | |
Nick Mathewson | d9663a2513 | |
Nick Mathewson | fe2a9cb389 | |
Nick Mathewson | 402f4bcef1 | |
Nick Mathewson | ba45eec743 | |
Nick Mathewson | 26c9afc386 | |
Nick Mathewson | fab91a290d | |
Nick Mathewson | 26fd00418c | |
Nick Mathewson | 7377c0bc06 | |
Nick Mathewson | 01de8edd27 | |
Nick Mathewson | 2b393776cf | |
Nick Mathewson | 07862d8435 | |
Nick Mathewson | d9c230e712 | |
Nick Mathewson | 173dc174bf | |
Nick Mathewson | 20a46bdce6 | |
Nick Mathewson | b2ae5fc96b | |
Nick Mathewson | 62c87f857b | |
Nick Mathewson | ce64ab2f09 | |
Nick Mathewson | 27688994a9 | |
Nick Mathewson | 1bf3ef1c28 | |
Nick Mathewson | 403969a3a7 | |
Nick Mathewson | ac89262b1c |
|
@ -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
|
||||
|
|
@ -3,7 +3,6 @@
|
|||
.#*
|
||||
*~
|
||||
*.swp
|
||||
*.swo
|
||||
# C stuff
|
||||
*.o
|
||||
*.obj
|
||||
|
@ -71,7 +70,6 @@ uptime-*.json
|
|||
/Tor*Bundle.dmg
|
||||
/tor-*-win32.exe
|
||||
/coverage_html/
|
||||
/callgraph/
|
||||
|
||||
# /contrib/
|
||||
/contrib/dist/tor.sh
|
||||
|
@ -212,7 +210,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
|
||||
|
|
|
@ -1,45 +0,0 @@
|
|||
before_script:
|
||||
- apt-get update -qq
|
||||
- apt-get upgrade -qy
|
||||
|
||||
build:
|
||||
script:
|
||||
- apt-get install -qy --fix-missing automake build-essential
|
||||
libevent-dev libssl-dev zlib1g-dev
|
||||
libseccomp-dev liblzma-dev libscrypt-dev
|
||||
- ./autogen.sh
|
||||
- ./configure --disable-asciidoc --enable-fatal-warnings
|
||||
--disable-silent-rules
|
||||
- make check || (e=$?; cat test-suite.log; exit $e)
|
||||
- make install
|
||||
|
||||
update:
|
||||
only:
|
||||
- schedules
|
||||
script:
|
||||
- "apt-get install -y --fix-missing git openssh-client"
|
||||
|
||||
# Run ssh-agent (inside the build environment)
|
||||
- eval $(ssh-agent -s)
|
||||
|
||||
# Add the SSH key stored in SSH_PRIVATE_KEY variable to the agent store
|
||||
- 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.
|
||||
# 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
|
||||
- '[[ -f /.dockerenv ]] && echo -e "Host *\n\tStrictHostKeyChecking no\n\n" > ~/.ssh/config'
|
||||
# In order to properly check the server's host key, assuming you created the
|
||||
# SSH_SERVER_HOSTKEYS variable previously, uncomment the following two lines
|
||||
# instead.
|
||||
- mkdir -p ~/.ssh
|
||||
- '[[ -f /.dockerenv ]] && echo "$SSH_SERVER_HOSTKEYS" > ~/.ssh/known_hosts'
|
||||
- echo "merging from torgit"
|
||||
- git config --global user.email "labadmin@oniongit.eu"
|
||||
- git config --global user.name "gitadmin"
|
||||
- "mkdir tor"
|
||||
- "cd tor"
|
||||
- git clone --bare https://git.torproject.org/tor.git
|
||||
- git push --mirror git@oniongit.eu:network/tor.git
|
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
|
54
Makefile.am
54
Makefile.am
|
@ -26,8 +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@ \
|
||||
@TOR_RUST_EXTRA_LIBS@
|
||||
rust_ldadd=$(top_builddir)/src/rust/target/release/libtor_util.a
|
||||
else
|
||||
rust_ldadd=
|
||||
endif
|
||||
|
@ -38,7 +37,6 @@ include contrib/include.am
|
|||
|
||||
EXTRA_DIST+= \
|
||||
ChangeLog \
|
||||
CONTRIBUTING \
|
||||
INSTALL \
|
||||
LICENSE \
|
||||
Makefile.nmake \
|
||||
|
@ -52,14 +50,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
|
||||
|
@ -98,7 +96,7 @@ doxygen:
|
|||
test: all
|
||||
$(top_builddir)/src/test/test
|
||||
|
||||
check-local: check-spaces check-changes
|
||||
check-local: check-spaces
|
||||
|
||||
need-chutney-path:
|
||||
@if test ! -d "$$CHUTNEY_PATH"; then \
|
||||
|
@ -119,19 +117,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,42 +214,16 @@ 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
|
||||
@if test -d "$(top_srcdir)/changes"; then \
|
||||
$(PYTHON) $(top_srcdir)/scripts/maint/lintChanges.py $(top_srcdir)/changes; \
|
||||
$(PYTHON) $(top_srcdir)/scripts/maint/lintChanges.py $(top_srcdir)/changes/*; \
|
||||
fi
|
||||
endif
|
||||
|
||||
.PHONY: update-versions
|
||||
update-versions:
|
||||
$(PERL) $(top_builddir)/scripts/maint/updateVersions.pl
|
||||
|
||||
.PHONY: callgraph
|
||||
callgraph:
|
||||
$(top_builddir)/scripts/maint/run_calltool.sh
|
||||
|
||||
version:
|
||||
@echo "Tor @VERSION@"
|
||||
@if test -d "$(top_srcdir)/.git" && test -x "`which git 2>&1;true`"; then \
|
||||
|
@ -271,10 +241,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.
|
||||
|
|
3
README
3
README
|
@ -27,6 +27,3 @@ Frequently Asked Questions:
|
|||
|
||||
To get started working on Tor development:
|
||||
See the doc/HACKING directory.
|
||||
|
||||
Release timeline:
|
||||
https://trac.torproject.org/projects/tor/wiki/org/teams/NetworkTeam/CoreTorReleases
|
||||
|
|
2592
ReleaseNotes
2592
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,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.
|
|
@ -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.
|
334
configure.ac
334
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.1.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,12 +255,67 @@ 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)
|
||||
|
||||
if test "x$enable_rust" = "xyes"; then
|
||||
AC_ARG_VAR([RUSTC], [path to the rustc binary])
|
||||
AC_CHECK_PROG([RUSTC], [rustc], [rustc],[no])
|
||||
if test "x$RUSTC" = "xno"; then
|
||||
AC_MSG_ERROR([rustc unavailable but rust integration requested.])
|
||||
fi
|
||||
|
||||
AC_ARG_VAR([CARGO], [path to the cargo binary])
|
||||
AC_CHECK_PROG([CARGO], [cargo], [cargo],[no])
|
||||
if test "x$CARGO" = "xno"; then
|
||||
AC_MSG_ERROR([cargo unavailable but rust integration requested.])
|
||||
fi
|
||||
|
||||
AC_DEFINE([HAVE_RUST], 1, [have Rust])
|
||||
if test "x$enable_cargo_online_mode" = "xyes"; then
|
||||
CARGO_ONLINE=
|
||||
RUST_DL=#
|
||||
else
|
||||
CARGO_ONLINE=--frozen
|
||||
RUST_DL=
|
||||
|
||||
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([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
|
||||
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
|
||||
for dep in $rust_crates; do
|
||||
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$NEED_MOD" = "x1"; then
|
||||
dnl When looking for dependencies from cargo, pick right directory
|
||||
RUST_DEPENDENCIES="../../src/ext/rust"
|
||||
fi
|
||||
fi
|
||||
|
||||
AC_SUBST(CARGO_ONLINE)
|
||||
AC_SUBST(RUST_DL)
|
||||
|
||||
dnl Let's check the rustc version, too
|
||||
AC_MSG_CHECKING([rust 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
|
||||
AC_MSG_ERROR([rustc version couldn't be identified])
|
||||
fi
|
||||
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
|
||||
fi
|
||||
|
||||
ifdef([AC_C_FLEXIBLE_ARRAY_MEMBER], [
|
||||
AC_C_FLEXIBLE_ARRAY_MEMBER
|
||||
], [
|
||||
|
@ -429,7 +433,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])
|
||||
|
@ -448,91 +451,6 @@ fi
|
|||
|
||||
AC_C_BIGENDIAN
|
||||
|
||||
if test "x$enable_rust" = "xyes"; then
|
||||
AC_ARG_VAR([RUSTC], [path to the rustc binary])
|
||||
AC_CHECK_PROG([RUSTC], [rustc], [rustc],[no])
|
||||
if test "x$RUSTC" = "xno"; then
|
||||
AC_MSG_ERROR([rustc unavailable but rust integration requested.])
|
||||
fi
|
||||
|
||||
AC_ARG_VAR([CARGO], [path to the cargo binary])
|
||||
AC_CHECK_PROG([CARGO], [cargo], [cargo],[no])
|
||||
if test "x$CARGO" = "xno"; then
|
||||
AC_MSG_ERROR([cargo unavailable but rust integration requested.])
|
||||
fi
|
||||
|
||||
AC_DEFINE([HAVE_RUST], 1, [have Rust])
|
||||
if test "x$enable_cargo_online_mode" = "xyes"; then
|
||||
CARGO_ONLINE=
|
||||
RUST_DL=#
|
||||
else
|
||||
CARGO_ONLINE=--frozen
|
||||
RUST_DL=
|
||||
|
||||
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"
|
||||
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
|
||||
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
|
||||
fi
|
||||
done
|
||||
if test "x$ERRORED" = "x"; then
|
||||
AC_MSG_RESULT([yes])
|
||||
fi
|
||||
fi
|
||||
|
||||
dnl This is a workaround for #46797
|
||||
dnl (a.k.a https://github.com/rust-lang/rust/issues/46797 ). Once the
|
||||
dnl upstream bug is fixed, we can remove this workaround.
|
||||
case "$host_os" in
|
||||
darwin*)
|
||||
TOR_RUST_EXTRA_LIBS="-lresolv"
|
||||
;;
|
||||
esac
|
||||
|
||||
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
|
||||
else
|
||||
TOR_RUST_STATIC_NAME=libtor_rust.a
|
||||
fi
|
||||
|
||||
AC_SUBST(TOR_RUST_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
|
||||
AC_MSG_ERROR([rustc version couldn't be identified])
|
||||
fi
|
||||
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)
|
||||
|
||||
AC_SEARCH_LIBS(socket, [socket network])
|
||||
AC_SEARCH_LIBS(gethostbyname, [nsl])
|
||||
AC_SEARCH_LIBS(dlopen, [dl])
|
||||
|
@ -563,7 +481,6 @@ AC_CHECK_FUNCS(
|
|||
timingsafe_memcmp \
|
||||
flock \
|
||||
ftime \
|
||||
get_current_dir_name \
|
||||
getaddrinfo \
|
||||
getifaddrs \
|
||||
getpass \
|
||||
|
@ -578,10 +495,8 @@ AC_CHECK_FUNCS(
|
|||
llround \
|
||||
localtime_r \
|
||||
lround \
|
||||
mach_approximate_time \
|
||||
memmem \
|
||||
memset_s \
|
||||
mmap \
|
||||
pipe \
|
||||
pipe2 \
|
||||
prctl \
|
||||
|
@ -608,7 +523,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 +565,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?
|
||||
|
||||
|
@ -674,16 +574,13 @@ if test "$bwin32" = "true"; then
|
|||
# Some of the cargo-cults recommend -lwsock32 as well, but I don't
|
||||
# think it's actually necessary.
|
||||
TOR_LIB_GDI=-lgdi32
|
||||
TOR_LIB_USERENV=-luserenv
|
||||
else
|
||||
TOR_LIB_WS32=
|
||||
TOR_LIB_GDI=
|
||||
TOR_LIB_USERENV=
|
||||
fi
|
||||
AC_SUBST(TOR_LIB_WS32)
|
||||
AC_SUBST(TOR_LIB_GDI)
|
||||
AC_SUBST(TOR_LIB_IPHLPAPI)
|
||||
AC_SUBST(TOR_LIB_USERENV)
|
||||
|
||||
tor_libevent_pkg_redhat="libevent"
|
||||
tor_libevent_pkg_debian="libevent-dev"
|
||||
|
@ -710,13 +607,12 @@ TOR_SEARCH_LIBRARY(libevent, $trylibeventdir, [-levent $STATIC_LIBEVENT_FLAGS $T
|
|||
#include <winsock2.h>
|
||||
#endif
|
||||
struct event_base;
|
||||
struct event_base *event_base_new(void);
|
||||
void event_base_free(struct event_base *);],
|
||||
struct event_base *event_base_new(void);],
|
||||
[
|
||||
#ifdef _WIN32
|
||||
{WSADATA d; WSAStartup(0x101,&d); }
|
||||
#endif
|
||||
event_base_free(event_base_new());
|
||||
event_base_new();
|
||||
], [--with-libevent-dir], [/opt/libevent])
|
||||
|
||||
dnl Determine the incantation needed to link libevent.
|
||||
|
@ -814,21 +710,11 @@ AC_ARG_WITH(ssl-dir,
|
|||
fi
|
||||
])
|
||||
|
||||
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])
|
||||
TOR_SEARCH_LIBRARY(openssl, $tryssldir, [-lssl -lcrypto $TOR_LIB_GDI],
|
||||
[#include <openssl/rand.h>],
|
||||
[void RAND_add(const void *buf, int num, double entropy);],
|
||||
[RAND_add((void*)0,0,0);], [],
|
||||
[/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,38 +780,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.
|
||||
AC_CHECK_MEMBERS(
|
||||
[struct tcp_info.tcpi_unacked, struct tcp_info.tcpi_snd_mss],
|
||||
, ,[[#include <netinet/tcp.h>]])
|
||||
dnl KIST needs SIOCOUTQNSD to exist for an ioctl call.
|
||||
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([], [
|
||||
#include <linux/sockios.h>
|
||||
#ifndef SIOCOUTQNSD
|
||||
#error
|
||||
#endif
|
||||
])], have_siocoutqnsd=yes, have_siocoutqnsd=no)
|
||||
if test "x$have_siocoutqnsd" = "xyes"; then
|
||||
if test "x$ac_cv_member_struct_tcp_info_tcpi_unacked" = "xyes"; then
|
||||
if test "x$ac_cv_member_struct_tcp_info_tcpi_snd_mss" = "xyes"; then
|
||||
have_kist_support=yes
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
])
|
||||
dnl Now, trigger the check.
|
||||
CHECK_KIST_SUPPORT
|
||||
AS_IF([test "x$have_kist_support" = "xyes"],
|
||||
[AC_DEFINE(HAVE_KIST_SUPPORT, 1, [Defined if KIST scheduler is supported
|
||||
on this system])],
|
||||
[AC_MSG_NOTICE([KIST scheduler can't be used. Missing support.])])
|
||||
|
||||
LIBS="$save_LIBS"
|
||||
LDFLAGS="$save_LDFLAGS"
|
||||
CPPFLAGS="$save_CPPFLAGS"
|
||||
|
@ -1016,16 +870,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)
|
||||
|
@ -1050,7 +894,7 @@ dnl since sometimes the linker will like an option but not be willing to
|
|||
dnl use it with a build of a library.
|
||||
|
||||
all_ldflags_for_check="$TOR_LDFLAGS_zlib $TOR_LDFLAGS_openssl $TOR_LDFLAGS_libevent"
|
||||
all_libs_for_check="$TOR_ZLIB_LIBS $TOR_LIB_MATH $TOR_LIBEVENT_LIBS $TOR_OPENSSL_LIBS $TOR_SYSTEMD_LIBS $TOR_LIB_WS32 $TOR_LIB_GDI $TOR_LIB_USERENV $TOR_CAP_LIBS"
|
||||
all_libs_for_check="$TOR_ZLIB_LIBS $TOR_LIB_MATH $TOR_LIBEVENT_LIBS $TOR_OPENSSL_LIBS $TOR_SYSTEMD_LIBS $TOR_LIB_WS32 $TOR_LIB_GDI $TOR_CAP_LIBS"
|
||||
|
||||
CFLAGS_FTRAPV=
|
||||
CFLAGS_FWRAPV=
|
||||
|
@ -1100,12 +944,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 +1190,6 @@ AC_CHECK_HEADERS([assert.h \
|
|||
pwd.h \
|
||||
readpassphrase.h \
|
||||
stdint.h \
|
||||
stdatomic.h \
|
||||
sys/eventfd.h \
|
||||
sys/file.h \
|
||||
sys/ioctl.h \
|
||||
|
@ -1711,24 +1554,6 @@ if test "$tor_cv_sign_extend" != "no"; then
|
|||
[Define to 1 iff right-shifting a negative value performs sign-extension])
|
||||
fi
|
||||
|
||||
# Is uint8_t the same type as unsigned char?
|
||||
AC_CACHE_CHECK([whether uint8_t is the same type as unsigned char], tor_cv_uint8_uchar,
|
||||
[AC_COMPILE_IFELSE([AC_LANG_SOURCE([[
|
||||
#include <stdint.h>
|
||||
extern uint8_t c;
|
||||
unsigned char c;]])],
|
||||
[tor_cv_uint8_uchar=yes],
|
||||
[tor_cv_uint8_uchar=no],
|
||||
[tor_cv_uint8_uchar=cross])])
|
||||
|
||||
if test "$tor_cv_uint8_uchar" = "cross"; then
|
||||
AC_MSG_NOTICE([Cross-compiling: we'll assume that uint8_t is the same type as unsigned char])
|
||||
fi
|
||||
|
||||
if test "$tor_cv_uint8_uchar" = "no"; then
|
||||
AC_MSG_ERROR([We assume that uint8_t is the same type as unsigned char, but your compiler disagrees.])
|
||||
fi
|
||||
|
||||
# Whether we should use the dmalloc memory allocation debugging library.
|
||||
AC_MSG_CHECKING(whether to use dmalloc (debug memory allocation library))
|
||||
AC_ARG_WITH(dmalloc,
|
||||
|
@ -1778,6 +1603,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 +1748,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 +1929,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 +1955,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.1.10-dev"
|
||||
!define INSTALLER "tor-${VERSION}-win32.exe"
|
||||
!define WEBSITE "https://www.torproject.org/"
|
||||
!define LICENSE "LICENSE"
|
||||
|
|
|
@ -6,8 +6,8 @@ tl;dr:
|
|||
- Run configure with `--enable-fatal-warnings`
|
||||
- Document your functions
|
||||
- Write unit tests
|
||||
- Run `make check` before submitting a patch
|
||||
- Run `make distcheck` if you have made changes to build system components
|
||||
- Run `make test-full` to test against all unit and integration tests.
|
||||
- Run `make distcheck` to ensure the distribution works
|
||||
- Add a file in `changes` for your branch.
|
||||
|
||||
Patch checklist
|
||||
|
@ -32,33 +32,6 @@ Did you remember...
|
|||
- To base your code on the appropriate branch?
|
||||
- To include a file in the `changes` directory as appropriate?
|
||||
|
||||
If you are submitting a major patch or new feature, or want to in the future...
|
||||
|
||||
- Set up Chutney and Stem, see HACKING/WritingTests.md
|
||||
- Run `make test-full` to test against all unit and integration tests.
|
||||
|
||||
If you have changed build system components:
|
||||
- Please run `make distcheck`
|
||||
- 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
|
||||
=======================
|
||||
|
||||
|
@ -79,17 +52,8 @@ before it gets merged into maint, but that's rare.
|
|||
|
||||
If you're working on a bugfix for a bug that occurs in a particular version,
|
||||
base your bugfix branch on the "maint" branch for the first supported series
|
||||
that has that bug. (As of June 2013, we're supporting 0.2.3 and later.)
|
||||
|
||||
If you're working on a new feature, base it on the master branch. If you're
|
||||
working on a new feature and it will take a while to implement and/or you'd
|
||||
like to avoid the possibility of unrelated bugs in Tor while you're
|
||||
implementing your feature, consider branching off of the latest maint- branch.
|
||||
_Never_ branch off a relase- branch. Don't branch off a tag either: they come
|
||||
from release branches. Doing so will likely produce a nightmare of merge
|
||||
conflicts in the ChangeLog when it comes time to merge your branch into Tor.
|
||||
Best advice: don't try to keep an independent branch forked for more than 6
|
||||
months and expect it to merge cleanly. Try to merge pieces early and often.
|
||||
that has that bug. (As of June 2013, we're supporting 0.2.3 and later.) If
|
||||
you're working on a new feature, base it on the master branch.
|
||||
|
||||
|
||||
How we log changes
|
||||
|
@ -113,34 +77,17 @@ you can use `git describe --contains <sha1 of commit>`.
|
|||
If at all possible, try to create this file in the same commit where you are
|
||||
making the change. Please give it a distinctive name that no other branch will
|
||||
use for the lifetime of your change. To verify the format of the changes file,
|
||||
you can use `make check-changes`. This is run automatically as part of
|
||||
`make check` -- if it fails, we must fix it before we release. These
|
||||
checks are implemented in `scripts/maint/lintChanges.py`.
|
||||
|
||||
Changes file style guide:
|
||||
* Changes files begin with " o Header (subheading):". The header
|
||||
should usually be "Minor/Major bugfixes/features". The subheading is a
|
||||
particular area within Tor. See the ChangeLog for examples.
|
||||
|
||||
* Make everything terse.
|
||||
|
||||
* Write from the user's point of view: describe the user-visible changes
|
||||
right away.
|
||||
|
||||
* Mention configuration options by name. If they're rare or unusual,
|
||||
remind people what they're for.
|
||||
|
||||
* Describe changes in the present tense and in the imperative: not past.
|
||||
|
||||
* Every bugfix should have a sentence of the form "Fixes bug 1234; bugfix
|
||||
on 0.1.2.3-alpha", describing what bug was fixed and where it came from.
|
||||
|
||||
* "Relays", not "servers", "nodes", or "Tor relays".
|
||||
you can use `make check-changes`.
|
||||
|
||||
When we go to make a release, we will concatenate all the entries
|
||||
in changes to make a draft changelog, and clear the directory. We'll
|
||||
then edit the draft changelog into a nice readable format.
|
||||
|
||||
To make sure that stuff is in the right format, we use
|
||||
scripts/maint/lintChanges.py to check the changes files for
|
||||
(superficial) validity. You can run this script on your own changes
|
||||
files!
|
||||
|
||||
What needs a changes file?
|
||||
|
||||
* A not-exhaustive list: Anything that might change user-visible
|
||||
|
@ -209,79 +156,6 @@ old C functions. Use `strlcat`, `strlcpy`, or `tor_snprintf/tor_asprintf` inste
|
|||
We don't call `memcmp()` directly. Use `fast_memeq()`, `fast_memneq()`,
|
||||
`tor_memeq()`, or `tor_memneq()` for most purposes.
|
||||
|
||||
Also see a longer list of functions to avoid in:
|
||||
https://people.torproject.org/~nickm/tor-auto/internal/this-not-that.html
|
||||
|
||||
Floating point math is hard
|
||||
---------------------------
|
||||
|
||||
Floating point arithmetic as typically implemented by computers is
|
||||
very counterintuitive. Failure to adequately analyze floating point
|
||||
usage can result in surprising behavior and even security
|
||||
vulnerabilities!
|
||||
|
||||
General advice:
|
||||
|
||||
- Don't use floating point.
|
||||
- If you must use floating point, document how the limits of
|
||||
floating point precision and calculation accuracy affect function
|
||||
outputs.
|
||||
- Try to do as much as possible of your calculations using integers
|
||||
(possibly acting as fixed-point numbers) and convert to floating
|
||||
point for display.
|
||||
- If you must send floating point numbers on the wire, serialize
|
||||
them in a platform-independent way. Tor avoids exchanging
|
||||
floating-point values, but when it does, it uses ASCII numerals,
|
||||
with a decimal point (".").
|
||||
- Binary fractions behave very differently from decimal fractions.
|
||||
Make sure you understand how these differences affect your
|
||||
calculations.
|
||||
- Every floating point arithmetic operation is an opportunity to
|
||||
lose precision, overflow, underflow, or otherwise produce
|
||||
undesired results. Addition and subtraction tend to be worse
|
||||
than multiplication and division (due to things like catastrophic
|
||||
cancellation). Try to arrange your calculations to minimize such
|
||||
effects.
|
||||
- Changing the order of operations changes the results of many
|
||||
floating-point calculations. Be careful when you simplify
|
||||
calculations! If the order is significant, document it using a
|
||||
code comment.
|
||||
- Comparing most floating point values for equality is unreliable.
|
||||
Avoid using `==`, instead, use `>=` or `<=`. If you use an
|
||||
epsilon value, make sure it's appropriate for the ranges in
|
||||
question.
|
||||
- Different environments (including compiler flags and per-thread
|
||||
state on a single platform!) can get different results from the
|
||||
same floating point calculations. This means you can't use
|
||||
floats in anything that needs to be deterministic, like consensus
|
||||
generation. This also makes reliable unit tests of
|
||||
floating-point outputs hard to write.
|
||||
|
||||
For additional useful advice (and a little bit of background), see
|
||||
[What Every Programmer Should Know About Floating-Point
|
||||
Arithmetic](http://floating-point-gui.de/).
|
||||
|
||||
A list of notable (and surprising) facts about floating point
|
||||
arithmetic is at [Floating-point
|
||||
complexities](https://randomascii.wordpress.com/2012/04/05/floating-point-complexities/).
|
||||
Most of that [series of posts on floating
|
||||
point](https://randomascii.wordpress.com/category/floating-point/) is
|
||||
helpful.
|
||||
|
||||
For more detailed (and math-intensive) background, see [What Every
|
||||
Computer Scientist Should Know About Floating-Point
|
||||
Arithmetic](https://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html).
|
||||
|
||||
Other C conventions
|
||||
-------------------
|
||||
|
||||
The `a ? b : c` trinary operator only goes inside other expressions;
|
||||
don't use it as a replacement for if. (You can ignore this inside macro
|
||||
definitions when necessary.)
|
||||
|
||||
Assignment operators shouldn't nest inside other expressions. (You can
|
||||
ignore this inside macro definitions when necessary.)
|
||||
|
||||
Functions not to write
|
||||
----------------------
|
||||
|
||||
|
@ -343,64 +217,6 @@ end-users that they aren't expected to understand the message (perhaps
|
|||
with a string like "internal error"). Option (A) is to be preferred to
|
||||
option (B).
|
||||
|
||||
Assertions In Tor
|
||||
-----------------
|
||||
|
||||
Assertions should be used for bug-detection only. Don't use assertions to
|
||||
detect bad user inputs, network errors, resource exhaustion, or similar
|
||||
issues.
|
||||
|
||||
Tor is always built with assertions enabled, so try to only use
|
||||
`tor_assert()` for cases where you are absolutely sure that crashing is the
|
||||
least bad option. Many bugs have been caused by use of `tor_assert()` when
|
||||
another kind of check would have been safer.
|
||||
|
||||
If you're writing an assertion to test for a bug that you _can_ recover from,
|
||||
use `tor_assert_nonfatal()` in place of `tor_assert()`. If you'd like to
|
||||
write a conditional that incorporates a nonfatal assertion, use the `BUG()`
|
||||
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 +250,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.
|
||||
|
||||
|
|
|
@ -1,523 +0,0 @@
|
|||
|
||||
Rust Coding Standards
|
||||
=======================
|
||||
|
||||
You MUST follow the standards laid out in `.../doc/HACKING/CodingStandards.md`,
|
||||
where applicable.
|
||||
|
||||
Module/Crate Declarations
|
||||
---------------------------
|
||||
|
||||
Each Tor C module which is being rewritten MUST be in its own crate.
|
||||
See the structure of `.../src/rust` for examples.
|
||||
|
||||
In your crate, you MUST use `lib.rs` ONLY for pulling in external
|
||||
crates (e.g. `extern crate libc;`) and exporting public objects from
|
||||
other Rust modules (e.g. `pub use mymodule::foo;`). For example, if
|
||||
you create a crate in `.../src/rust/yourcrate`, your Rust code should
|
||||
live in `.../src/rust/yourcrate/yourcode.rs` and the public interface
|
||||
to it should be exported in `.../src/rust/yourcrate/lib.rs`.
|
||||
|
||||
If your code is to be called from Tor C code, you MUST define a safe
|
||||
`ffi.rs`. See the "Safety" section further down for more details.
|
||||
|
||||
For example, in a hypothetical `tor_addition` Rust module:
|
||||
|
||||
In `.../src/rust/tor_addition/addition.rs`:
|
||||
|
||||
pub fn get_sum(a: i32, b: i32) -> i32 {
|
||||
a + b
|
||||
}
|
||||
|
||||
In `.../src/rust/tor_addition/lib.rs`:
|
||||
|
||||
pub use addition::*;
|
||||
|
||||
In `.../src/rust/tor_addition/ffi.rs`:
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn tor_get_sum(a: c_int, b: c_int) -> c_int {
|
||||
get_sum(a, b)
|
||||
}
|
||||
|
||||
If your Rust code must call out to parts of Tor's C code, you must
|
||||
declare the functions you are calling in the `external` crate, located
|
||||
at `.../src/rust/external`.
|
||||
|
||||
<!-- XXX get better examples of how to declare these externs, when/how they -->
|
||||
<!-- XXX are unsafe, what they are expected to do —isis -->
|
||||
|
||||
Modules should strive to be below 500 lines (tests excluded). Single
|
||||
responsibility and limited dependencies should be a guiding standard.
|
||||
|
||||
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
|
||||
---------------------------
|
||||
|
||||
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
|
||||
---------------
|
||||
|
||||
You MUST include `#[deny(missing_docs)]` in your crate.
|
||||
|
||||
For function/method comments, you SHOULD include a one-sentence, "first person"
|
||||
description of function behaviour (see requirements for documentation as
|
||||
described in `.../src/HACKING/CodingStandards.md`), then an `# Inputs` section
|
||||
for inputs or initialisation values, a `# Returns` section for return
|
||||
values/types, a `# Warning` section containing warnings for unsafe behaviours or
|
||||
panics that could happen. For publicly accessible
|
||||
types/constants/objects/functions/methods, you SHOULD also include an
|
||||
`# Examples` section with runnable doctests.
|
||||
|
||||
You MUST document your module with _module docstring_ comments,
|
||||
i.e. `//!` at the beginning of each line.
|
||||
|
||||
Style
|
||||
-------
|
||||
|
||||
You SHOULD consider breaking up large literal numbers with `_` when it makes it
|
||||
more human readable to do so, e.g. `let x: u64 = 100_000_000_000`.
|
||||
|
||||
Testing
|
||||
---------
|
||||
|
||||
All code MUST be unittested and integration tested.
|
||||
|
||||
Public functions/objects exported from a crate SHOULD include doctests
|
||||
describing how the function/object is expected to be used.
|
||||
|
||||
Integration tests SHOULD go into a `tests/` directory inside your
|
||||
crate. Unittests SHOULD go into their own module inside the module
|
||||
they are testing, e.g. in `.../src/rust/tor_addition/addition.rs` you
|
||||
should put:
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn addition_with_zero() {
|
||||
let sum: i32 = get_sum(5i32, 0i32);
|
||||
assert_eq!(sum, 5);
|
||||
}
|
||||
}
|
||||
|
||||
Benchmarking
|
||||
--------------
|
||||
|
||||
The external `test` crate can be used for most benchmarking. However, using
|
||||
this crate requires nightly Rust. Since we may want to switch to a more
|
||||
stable Rust compiler eventually, we shouldn't do things which will automatically
|
||||
break builds for stable compilers. Therefore, you MUST feature-gate your
|
||||
benchmarks in the following manner.
|
||||
|
||||
If you wish to benchmark some of your Rust code, you MUST put the
|
||||
following in the `[features]` section of your crate's `Cargo.toml`:
|
||||
|
||||
[features]
|
||||
bench = []
|
||||
|
||||
Next, in your crate's `lib.rs` you MUST put:
|
||||
|
||||
#[cfg(all(test, feature = "bench"))]
|
||||
extern crate test;
|
||||
|
||||
This ensures that the external crate `test`, which contains utilities
|
||||
for basic benchmarks, is only used when running benchmarks via `cargo
|
||||
bench --features bench`.
|
||||
|
||||
Finally, to write your benchmark code, in
|
||||
`.../src/rust/tor_addition/addition.rs` you SHOULD put:
|
||||
|
||||
#[cfg(all(test, features = "bench"))]
|
||||
mod bench {
|
||||
use test::Bencher;
|
||||
use super::*;
|
||||
|
||||
#[bench]
|
||||
fn addition_small_integers(b: &mut Bencher) {
|
||||
b.iter(| | get_sum(5i32, 0i32));
|
||||
}
|
||||
}
|
||||
|
||||
Fuzzing
|
||||
---------
|
||||
|
||||
If you wish to fuzz parts of your code, please see the
|
||||
[`cargo fuzz`](https://github.com/rust-fuzz/cargo-fuzz) crate, which uses
|
||||
[libfuzzer-sys](https://github.com/rust-fuzz/libfuzzer-sys).
|
||||
|
||||
Whitespace & Formatting
|
||||
-------------------------
|
||||
|
||||
You MUST run `rustfmt` (https://github.com/rust-lang-nursery/rustfmt)
|
||||
on your code before your code will be merged. You can install rustfmt
|
||||
by doing `cargo install rustfmt-nightly` and then run it with `cargo
|
||||
fmt`.
|
||||
|
||||
Safety
|
||||
--------
|
||||
|
||||
You SHOULD read [the nomicon](https://doc.rust-lang.org/nomicon/) before writing
|
||||
Rust FFI code. It is *highly advised* that you read and write normal Rust code
|
||||
before attempting to write FFI or any other unsafe code.
|
||||
|
||||
Here are some additional bits of advice and rules:
|
||||
|
||||
0. Any behaviours which Rust considers to be undefined are forbidden
|
||||
|
||||
From https://doc.rust-lang.org/reference/behavior-considered-undefined.html:
|
||||
|
||||
> Behavior considered undefined
|
||||
>
|
||||
> The following is a list of behavior which is forbidden in all Rust code,
|
||||
> including within unsafe blocks and unsafe functions. Type checking provides the
|
||||
> guarantee that these issues are never caused by safe code.
|
||||
>
|
||||
> * Data races
|
||||
> * Dereferencing a null/dangling raw pointer
|
||||
> * Reads of [undef](http://llvm.org/docs/LangRef.html#undefined-values)
|
||||
> (uninitialized) memory
|
||||
> * Breaking the
|
||||
> [pointer aliasing rules](http://llvm.org/docs/LangRef.html#pointer-aliasing-rules)
|
||||
> with raw pointers (a subset of the rules used by C)
|
||||
> * `&mut T` and `&T` follow LLVM’s scoped noalias model, except if the `&T`
|
||||
> contains an `UnsafeCell<U>`. Unsafe code must not violate these aliasing
|
||||
> guarantees.
|
||||
> * Mutating non-mutable data (that is, data reached through a shared
|
||||
> reference or data owned by a `let` binding), unless that data is
|
||||
> contained within an `UnsafeCell<U>`.
|
||||
> * Invoking undefined behavior via compiler intrinsics:
|
||||
> - Indexing outside of the bounds of an object with
|
||||
> `std::ptr::offset` (`offset` intrinsic), with the exception of
|
||||
> one byte past the end which is permitted.
|
||||
> - Using `std::ptr::copy_nonoverlapping_memory` (`memcpy32`/`memcpy64`
|
||||
> intrinsics) on overlapping buffers
|
||||
> * Invalid values in primitive types, even in private fields/locals:
|
||||
> - Dangling/null references or boxes
|
||||
> - A value other than `false` (0) or `true` (1) in a `bool`
|
||||
> - A discriminant in an `enum` not included in the type definition
|
||||
> - A value in a `char` which is a surrogate or above `char::MAX`
|
||||
> - Non-UTF-8 byte sequences in a `str`
|
||||
> * Unwinding into Rust from foreign code or unwinding from Rust into foreign
|
||||
> code. Rust's failure system is not compatible with exception handling in other
|
||||
> languages. Unwinding must be caught and handled at FFI boundaries.
|
||||
|
||||
1. `unwrap()`
|
||||
|
||||
If you call `unwrap()`, anywhere, even in a test, you MUST include
|
||||
an inline comment stating how the unwrap will either 1) never fail,
|
||||
or 2) should fail (i.e. in a unittest).
|
||||
|
||||
You SHOULD NOT use `unwrap()` anywhere in which it is possible to handle the
|
||||
potential error with either `expect()` or the eel operator, `?`.
|
||||
For example, consider a function which parses a string into an integer:
|
||||
|
||||
fn parse_port_number(config_string: &str) -> u16 {
|
||||
u16::from_str_radix(config_string, 10).unwrap()
|
||||
}
|
||||
|
||||
There are numerous ways this can fail, and the `unwrap()` will cause the
|
||||
whole program to byte the dust! Instead, either you SHOULD use `expect()`
|
||||
(or another equivalent function which will return an `Option` or a `Result`)
|
||||
and change the return type to be compatible:
|
||||
|
||||
fn parse_port_number(config_string: &str) -> Option<u16> {
|
||||
u16::from_str_radix(config_string, 10).expect("Couldn't parse port into a u16")
|
||||
}
|
||||
|
||||
or you SHOULD use `or()` (or another similar method):
|
||||
|
||||
fn parse_port_number(config_string: &str) -> Option<u16> {
|
||||
u16::from_str_radix(config_string, 10).or(Err("Couldn't parse port into a u16")
|
||||
}
|
||||
|
||||
Using methods like `or()` can be particularly handy when you must do
|
||||
something afterwards with the data, for example, if we wanted to guarantee
|
||||
that the port is high. Combining these methods with the eel operator (`?`)
|
||||
makes this even easier:
|
||||
|
||||
fn parse_port_number(config_string: &str) -> Result<u16, Err> {
|
||||
let port = u16::from_str_radix(config_string, 10).or(Err("Couldn't parse port into a u16"))?;
|
||||
|
||||
if port > 1024 {
|
||||
return Ok(port);
|
||||
} else {
|
||||
return Err("Low ports not allowed");
|
||||
}
|
||||
}
|
||||
|
||||
2. `unsafe`
|
||||
|
||||
If you use `unsafe`, you MUST describe a contract in your
|
||||
documentation which describes how and when the unsafe code may
|
||||
fail, and what expectations are made w.r.t. the interfaces to
|
||||
unsafe code. This is also REQUIRED for major pieces of FFI between
|
||||
C and Rust.
|
||||
|
||||
When creating an FFI in Rust for C code to call, it is NOT REQUIRED
|
||||
to declare the entire function `unsafe`. For example, rather than doing:
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn increment_and_combine_numbers(mut numbers: [u8; 4]) -> u32 {
|
||||
for number in &mut numbers {
|
||||
*number += 1;
|
||||
}
|
||||
std::mem::transmute::<[u8; 4], u32>(numbers)
|
||||
}
|
||||
|
||||
You SHOULD instead do:
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn increment_and_combine_numbers(mut numbers: [u8; 4]) -> u32 {
|
||||
for index in 0..numbers.len() {
|
||||
numbers[index] += 1;
|
||||
}
|
||||
unsafe {
|
||||
std::mem::transmute::<[u8; 4], u32>(numbers)
|
||||
}
|
||||
}
|
||||
|
||||
3. Pass only C-compatible primitive 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
|
||||
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.
|
||||
|
||||
One might be tempted to do this via doing
|
||||
`CString::new("blah").unwrap().into_raw()`. This has several problems:
|
||||
|
||||
a) If you do `CString::new("bl\x00ah")` then the unwrap() will fail
|
||||
due to the additional NULL terminator, causing a dangling
|
||||
pointer to be returned (as well as a potential use-after-free).
|
||||
|
||||
b) Returning the raw pointer will cause the CString to run its deallocator,
|
||||
which causes any C code which tries to access the contents to dereference a
|
||||
NULL pointer.
|
||||
|
||||
c) If we were to do `as_raw()` this would result in a potential double-free
|
||||
since the Rust deallocator would run and possibly Tor's deallocator.
|
||||
|
||||
d) Calling `into_raw()` without later using the same pointer in Rust to call
|
||||
`from_raw()` and then deallocate in Rust can result in a
|
||||
[memory leak](https://doc.rust-lang.org/std/ffi/struct.CString.html#method.into_raw).
|
||||
|
||||
[It was determined](https://github.com/rust-lang/rust/pull/41074) that this
|
||||
is safe to do if you use the same allocator in C and Rust and also specify
|
||||
the memory alignment for CString (except that there is no way to specify
|
||||
the alignment for CString). It is believed that the alignment is always 1,
|
||||
which would mean it's safe to dealloc the resulting `*mut c_char` in Tor's
|
||||
C code. However, the Rust developers are not willing to guarantee the
|
||||
stability of, or a contract for, this behaviour, citing concerns that this
|
||||
is potentially extremely and subtly unsafe.
|
||||
|
||||
4. Perform an allocation on the other side of the boundary
|
||||
|
||||
After crossing the boundary, the other side MUST perform an
|
||||
allocation to copy the data and is therefore responsible for
|
||||
freeing that memory later.
|
||||
|
||||
5. No touching other language's enums
|
||||
|
||||
Rust enums should never be touched from C (nor can they be safely
|
||||
`#[repr(C)]`) nor vice versa:
|
||||
|
||||
> "The chosen size is the default enum size for the target platform's C
|
||||
> ABI. Note that enum representation in C is implementation defined, so this is
|
||||
> really a "best guess". In particular, this may be incorrect when the C code
|
||||
> of interest is compiled with certain flags."
|
||||
|
||||
(from https://gankro.github.io/nomicon/other-reprs.html)
|
||||
|
||||
6. Type safety
|
||||
|
||||
Wherever possible and sensical, you SHOULD create new types in a
|
||||
manner which prevents type confusion or misuse. For example,
|
||||
rather than using an untyped mapping between strings and integers
|
||||
like so:
|
||||
|
||||
use std::collections::HashMap;
|
||||
|
||||
pub fn get_elements_with_over_9000_points(map: &HashMap<String, usize>) -> Vec<String> {
|
||||
...
|
||||
}
|
||||
|
||||
It would be safer to define a new type, such that some other usage
|
||||
of `HashMap<String, usize>` cannot be confused for this type:
|
||||
|
||||
pub struct DragonBallZPowers(pub HashMap<String, usize>);
|
||||
|
||||
impl DragonBallZPowers {
|
||||
pub fn over_nine_thousand<'a>(&'a self) -> Vec<&'a String> {
|
||||
let mut powerful_enough: Vec<&'a String> = Vec::with_capacity(5);
|
||||
|
||||
for (character, power) in &self.0 {
|
||||
if *power > 9000 {
|
||||
powerful_enough.push(character);
|
||||
}
|
||||
}
|
||||
powerful_enough
|
||||
}
|
||||
}
|
||||
|
||||
Note the following code, which uses Rust's type aliasing, is valid
|
||||
but it does NOT meet the desired type safety goals:
|
||||
|
||||
pub type Power = usize;
|
||||
|
||||
pub fn over_nine_thousand(power: &Power) -> bool {
|
||||
if *power > 9000 {
|
||||
return true;
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
// We can still do the following:
|
||||
let his_power: usize = 9001;
|
||||
over_nine_thousand(&his_power);
|
||||
|
||||
7. Unsafe mucking around with lifetimes
|
||||
|
||||
Because lifetimes are technically, in type theory terms, a kind, i.e. a
|
||||
family of types, individual lifetimes can be treated as types. For example,
|
||||
one can arbitrarily extend and shorten lifetime using `std::mem::transmute`:
|
||||
|
||||
struct R<'a>(&'a i32);
|
||||
|
||||
unsafe fn extend_lifetime<'b>(r: R<'b>) -> R<'static> {
|
||||
std::mem::transmute::<R<'b>, R<'static>>(r)
|
||||
}
|
||||
|
||||
unsafe fn shorten_invariant_lifetime<'b, 'c>(r: &'b mut R<'static>) -> &'b mut R<'c> {
|
||||
std::mem::transmute::<&'b mut R<'static>, &'b mut R<'c>>(r)
|
||||
}
|
||||
|
||||
Calling `extend_lifetime()` would cause an `R` passed into it to live forever
|
||||
for the life of the program (the `'static` lifetime). Similarly,
|
||||
`shorten_invariant_lifetime()` could be used to take something meant to live
|
||||
forever, and cause it to disappear! This is incredibly unsafe. If you're
|
||||
going to be mucking around with lifetimes like this, first, you better have
|
||||
an extremely good reason, and second, you may as be honest and explicit about
|
||||
it, and for ferris' sake just use a raw pointer.
|
||||
|
||||
In short, just because lifetimes can be treated like types doesn't mean you
|
||||
should do it.
|
||||
|
||||
8. Doing excessively unsafe things when there's a safer alternative
|
||||
|
||||
Similarly to #7, often there are excessively unsafe ways to do a task and a
|
||||
simpler, safer way. You MUST choose the safer option where possible.
|
||||
|
||||
For example, `std::mem::transmute` can be abused in ways where casting with
|
||||
`as` would be both simpler and safer:
|
||||
|
||||
// Don't do this
|
||||
let ptr = &0;
|
||||
let ptr_num_transmute = unsafe { std::mem::transmute::<&i32, usize>(ptr)};
|
||||
|
||||
// Use an `as` cast instead
|
||||
let ptr_num_cast = ptr as *const i32 as usize;
|
||||
|
||||
In fact, using `std::mem::transmute` for *any* reason is a code smell and as
|
||||
such SHOULD be avoided.
|
||||
|
||||
9. Casting integers with `as`
|
||||
|
||||
This is generally fine to do, but it has some behaviours which you should be
|
||||
aware of. Casting down chops off the high bits, e.g.:
|
||||
|
||||
let x: u32 = 4294967295;
|
||||
println!("{}", x as u16); // prints 65535
|
||||
|
||||
Some cases which you MUST NOT do include:
|
||||
|
||||
* Casting an `u128` down to an `f32` or vice versa (e.g.
|
||||
`u128::MAX as f32` but this isn't only a problem with overflowing
|
||||
as it is also undefined behaviour for `42.0f32 as u128`),
|
||||
|
||||
* Casting between integers and floats when the thing being cast
|
||||
cannot fit into the type it is being casted into, e.g.:
|
||||
|
||||
println!("{}", 42949.0f32 as u8); // prints 197 in debug mode and 0 in release
|
||||
println!("{}", 1.04E+17 as u8); // prints 0 in both modes
|
||||
println!("{}", (0.0/0.0) as i64); // prints whatever the heck LLVM wants
|
||||
|
||||
Because this behaviour is undefined, it can even produce segfaults in
|
||||
safe Rust code. For example, the following program built in release
|
||||
mode segfaults:
|
||||
|
||||
#[inline(never)]
|
||||
pub fn trigger_ub(sl: &[u8; 666]) -> &[u8] {
|
||||
// Note that the float is out of the range of `usize`, invoking UB when casting.
|
||||
let idx = 1e99999f64 as usize;
|
||||
&sl[idx..] // The bound check is elided due to `idx` being of an undefined value.
|
||||
}
|
||||
|
||||
fn main() {
|
||||
println!("{}", trigger_ub(&[1; 666])[999999]); // ~ out of bound
|
||||
}
|
||||
|
||||
And in debug mode panics with:
|
||||
|
||||
thread 'main' panicked at 'slice index starts at 140721821254240 but ends at 666', /checkout/src/libcore/slice/mod.rs:754:4
|
|
@ -11,9 +11,8 @@ whole Tor ecosystem.)
|
|||
|
||||
|
||||
If you are looking for a more bare-bones, less user-friendly information
|
||||
dump of important information, you might like reading the "torguts"
|
||||
documents linked to below. You should probably read it before you write
|
||||
your first patch.
|
||||
dump of important information, you might like reading doc/HACKING
|
||||
instead. You should probably read it before you write your first patch.
|
||||
|
||||
|
||||
Required background
|
||||
|
|
|
@ -1,181 +0,0 @@
|
|||
|
||||
Hacking on Rust in Tor
|
||||
========================
|
||||
|
||||
Getting Started
|
||||
-----------------
|
||||
|
||||
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!
|
||||
|
||||
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
|
||||
-----------------------------
|
||||
|
||||
**Beginning resources**
|
||||
|
||||
The primary resource for learning Rust is
|
||||
[The Book](https://doc.rust-lang.org/book/). If you'd like to start writing
|
||||
Rust immediately, without waiting for anything to install, there is
|
||||
[an interactive browser-based playground](https://play.rust-lang.org/).
|
||||
|
||||
**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
|
||||
[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
|
||||
[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
|
||||
[Rust FFI Omnibus](http://jakegoulding.com/rust-ffi-omnibus/).
|
||||
|
||||
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.
|
||||
|
||||
**Fetch dependencies from Cargo**
|
||||
|
||||
./configure --enable-rust --enable-cargo-online-mode
|
||||
|
||||
**Using a local dependency cache**
|
||||
|
||||
You'll need the following Rust dependencies (as of this writing):
|
||||
|
||||
libc==0.2.39
|
||||
|
||||
We vendor our Rust dependencies in a separate repo using
|
||||
[cargo-vendor](https://github.com/alexcrichton/cargo-vendor). To use
|
||||
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
|
||||
|
||||
|
||||
Identifying which modules to rewrite
|
||||
======================================
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
|
||||
A good first step is to build a module-level callgraph to understand how
|
||||
interconnected your target module is.
|
||||
|
||||
git clone https://git.torproject.org/user/nickm/calltool.git
|
||||
cd tor
|
||||
CFLAGS=0 ./configure
|
||||
../calltool/src/main.py module_callgraph
|
||||
|
||||
The output will tell you each module name, along with a set of every module that
|
||||
the module calls. Modules which call fewer other modules are better targets.
|
||||
|
||||
Writing your Rust module
|
||||
==========================
|
||||
|
||||
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.
|
||||
|
||||
Adding your Rust module to Tor's build system
|
||||
-----------------------------------------------
|
||||
|
||||
0. Your translation of the C module should live in its own crate(s)
|
||||
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`
|
||||
|
||||
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.
|
||||
|
||||
Configure Tor's build system to build with Rust enabled:
|
||||
|
||||
./configure --enable-fatal-warnings --enable-rust --enable-cargo-online-mode
|
||||
|
||||
Tor's test should be run by doing:
|
||||
|
||||
make check
|
||||
|
||||
Tor's integration tests should also pass:
|
||||
|
||||
make test-stem
|
||||
|
||||
Submitting a patch
|
||||
=====================
|
||||
|
||||
Please follow the instructions in `.../doc/HACKING/GettingStarted.md`.
|
|
@ -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
|
||||
-------
|
||||
|
||||
|
@ -127,18 +111,14 @@ Running gcov for unit test coverage
|
|||
|
||||
(On OSX, you'll need to start with `--enable-coverage CC=clang`.)
|
||||
|
||||
If that doesn't work:
|
||||
|
||||
* Try configuring Tor with `--disable-gcc-hardening`
|
||||
* You might need to run `make clean` after you run `./configure`.
|
||||
|
||||
Then, look at the .gcov files in `coverage-output`. '-' before a line means
|
||||
that the compiler generated no code for that line. '######' means that the
|
||||
line was never reached. Lines with numbers were called that number of times.
|
||||
|
||||
For more details about how to read gcov output, see the [Invoking
|
||||
gcov](https://gcc.gnu.org/onlinedocs/gcc/Invoking-Gcov.html) chapter
|
||||
of the GCC manual.
|
||||
If that doesn't work:
|
||||
|
||||
* Try configuring Tor with `--disable-gcc-hardening`
|
||||
* You might need to run `make clean` after you run `./configure`.
|
||||
|
||||
If you make changes to Tor and want to get another set of coverage results,
|
||||
you can run `make reset-gcov` to clear the intermediary gcov output.
|
||||
|
@ -148,13 +128,9 @@ a meaningful diff between them, you can run:
|
|||
|
||||
./scripts/test/cov-diff coverage-output1 coverage-output2 | less
|
||||
|
||||
In this diff, any lines that were visited at least once will have coverage "1",
|
||||
and line numbers are deleted. This lets you inspect what you (probably) really
|
||||
want to know: which untested lines were changed? Are there any new untested
|
||||
lines?
|
||||
|
||||
If you run ./scripts/test/cov-exclude, it marks excluded unreached
|
||||
lines with 'x', and excluded reached lines with '!!!'.
|
||||
In this diff, any lines that were visited at least once will have coverage
|
||||
"1". This lets you inspect what you (probably) really want to know: which
|
||||
untested lines were changed? Are there any new untested lines?
|
||||
|
||||
Running integration tests
|
||||
-------------------------
|
||||
|
|
|
@ -19,8 +19,6 @@ Top-level smell-checks
|
|||
|
||||
- Does `make check-spaces` pass?
|
||||
|
||||
- Does `make check-changes` pass?
|
||||
|
||||
- Does it have a reasonable amount of tests? Do they pass? Do they leak
|
||||
memory?
|
||||
|
||||
|
@ -34,7 +32,6 @@ Top-level smell-checks
|
|||
|
||||
- If this changes Tor's behavior on the wire, is there a design proposal?
|
||||
|
||||
- If this changes anything in the code, is there a "changes" file?
|
||||
|
||||
|
||||
Let's look at the code!
|
||||
|
|
|
@ -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.
|
|
@ -8,15 +8,8 @@ new Tor release:
|
|||
=== 0. Preliminaries
|
||||
|
||||
1. Get at least three of weasel/arma/Sebastian/Sina to put the new
|
||||
version number in their approved versions list. Give them a few
|
||||
days to do this if you can.
|
||||
version number in their approved versions list.
|
||||
|
||||
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 +18,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,24 +26,19 @@ new Tor release:
|
|||
|
||||
What about Coverity Scan?
|
||||
|
||||
What about clang scan-build?
|
||||
|
||||
Does 'make distcheck' complain?
|
||||
|
||||
How about 'make test-stem' and 'make test-network' and
|
||||
`make test-network-full`?
|
||||
How about 'make test-stem' and 'make test-network'?
|
||||
|
||||
- Are all those tests still happy with --enable-expensive-hardening ?
|
||||
|
||||
Any memory leaks?
|
||||
|
||||
|
||||
=== II. Write a changelog
|
||||
=== II. Write a changelog.
|
||||
|
||||
|
||||
1a. (Alpha release variant)
|
||||
|
||||
Gather the `changes/*` files into a changelog entry, rewriting many
|
||||
1. Gather the `changes/*` files into a changelog entry, rewriting many
|
||||
of them and reordering to focus on what users and funders would find
|
||||
interesting and understandable.
|
||||
|
||||
|
@ -96,15 +83,6 @@ new Tor release:
|
|||
|
||||
4. Run `./scripts/maint/format_changelog.py --inplace` to make it prettier
|
||||
|
||||
1b. (old-stable release variant)
|
||||
|
||||
For stable releases that backport things from later, we try to compose
|
||||
their releases, we try to make sure that we keep the changelog entries
|
||||
identical to their original versions, with a 'backport from 0.x.y.z'
|
||||
note added to each section. So in this case, once you have the items
|
||||
from the changes files copied together, don't use them to build a new
|
||||
changelog: instead, look up the corrected versions that were merged
|
||||
into ChangeLog in the master branch, and use those.
|
||||
|
||||
2. Compose a short release blurb to highlight the user-facing
|
||||
changes. Insert said release blurb into the ChangeLog stanza. If it's
|
||||
|
@ -131,16 +109,13 @@ new Tor release:
|
|||
=== III. Making the source release.
|
||||
|
||||
1. In `maint-0.?.x`, bump the version number in `configure.ac` and run
|
||||
`perl scripts/maint/updateVersions.pl` to update version numbers in other
|
||||
`scripts/maint/updateVersions.pl` to update version numbers in other
|
||||
places, and commit. Then merge `maint-0.?.x` into `release-0.?.x`.
|
||||
|
||||
(NOTE: To bump the version number, edit `configure.ac`, and then run
|
||||
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 +129,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"
|
||||
|
@ -175,16 +147,10 @@ new Tor release:
|
|||
- {weasel,gk,mikeperry} at torproject dot org
|
||||
- {blueness} at gentoo dot org
|
||||
- {paul} at invizbox dot io
|
||||
- {vincent} at invizbox dot com
|
||||
- {lfleischer} at archlinux dot org
|
||||
- {Nathan} at freitas dot net
|
||||
- {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.
|
||||
|
||||
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,14 +159,10 @@ 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
|
||||
Post the changelog on the the blog as well. You can generate a
|
||||
blog-formatted version of the changelog with the -B option to
|
||||
format-changelog.
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
||||
|
|
|
@ -91,9 +91,6 @@ coverage percentage.
|
|||
For a summary of the test coverage for each _function_, run
|
||||
`./scripts/test/cov-display -f ${TMPDIR}/*`.
|
||||
|
||||
For more details on using gcov, including the helper scripts in
|
||||
scripts/test, see HelpfulTools.md.
|
||||
|
||||
### Comparing test coverage
|
||||
|
||||
Sometimes it's useful to compare test coverage for a branch you're writing to
|
||||
|
@ -120,8 +117,7 @@ with LCOV_EXCL_START... LCOV_EXCL_STOP. Note that older versions of
|
|||
lcov don't understand these lines.
|
||||
|
||||
You can post-process .gcov files to make these lines 'unreached' by
|
||||
running ./scripts/test/cov-exclude on them. It marks excluded
|
||||
unreached lines with 'x', and excluded reached lines with '!!!'.
|
||||
running ./scripts/test/cov-exclude on them.
|
||||
|
||||
Note: you should never do this unless the line is meant to 100%
|
||||
unreachable by actual code.
|
||||
|
|
|
@ -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@
|
||||
|
|
1066
doc/tor.1.txt
1066
doc/tor.1.txt
File diff suppressed because it is too large
Load Diff
|
@ -18,10 +18,9 @@ does, not what it should do.
|
|||
; specified in RFC5234.
|
||||
|
||||
; A file is interpreted as every Entry in the file, in order.
|
||||
TorrcFile = *Line [ UnterminatedLine ]
|
||||
TorrcFile = *Line
|
||||
|
||||
Line = BlankLine LF / Entry LF
|
||||
UnterminatedLine = BlankLine / Entry
|
||||
Line = BlankLine / Entry
|
||||
|
||||
BlankLine = *WSP OptComment LF
|
||||
BlankLine =/ *WSP LF
|
||||
|
@ -70,12 +69,6 @@ does, not what it should do.
|
|||
; Anything besides NUL and LF
|
||||
NonLF = %x01-%x09 / %x0b - %xff
|
||||
|
||||
; Note that on windows, we open our configuration files in "text" mode,
|
||||
; which causes CRLF pairs to be interpreted as LF. So, on windows:
|
||||
; LF = [ %x0d ] %x0a
|
||||
; but everywhere else,
|
||||
LF = %0x0a
|
||||
|
||||
OCTDIG = '0' - '7'
|
||||
|
||||
KC = Any character except an isspace() character or '#' or NUL
|
||||
|
|
|
@ -1,6 +0,0 @@
|
|||
@@
|
||||
expression n, d;
|
||||
@@
|
||||
|
||||
- (((n) + (d) - 1) / (d))
|
||||
+ CEIL_DIV(n, d)
|
|
@ -1,11 +0,0 @@
|
|||
#!/usr/bin/perl -w -p -i
|
||||
|
||||
next if m#^ */\*# or m#^ *\* #;
|
||||
|
||||
s/<([,)])/OP_LT$1/;
|
||||
s/(?<=[\s,])>([,)])/OP_GT$1/;
|
||||
#s/>([,)])/OP_GT$1/;
|
||||
s/==([,)])/OP_EQ$1/;
|
||||
s/>=([,)])/OP_GE$1/;
|
||||
s/<=([,)])/OP_LE$1/;
|
||||
s/!=([,)])/OP_NE$1/;
|
|
@ -1,49 +0,0 @@
|
|||
@@
|
||||
int e;
|
||||
constant c;
|
||||
@@
|
||||
|
||||
(
|
||||
- tt_assert(e == c)
|
||||
+ tt_int_op(e, OP_EQ, c)
|
||||
|
|
||||
- tt_assert(e != c)
|
||||
+ tt_int_op(e, OP_NE, c)
|
||||
|
|
||||
- tt_assert(e < c)
|
||||
+ tt_int_op(e, OP_LT, c)
|
||||
|
|
||||
- tt_assert(e <= c)
|
||||
+ tt_int_op(e, OP_LE, c)
|
||||
|
|
||||
- tt_assert(e > c)
|
||||
+ tt_int_op(e, OP_GT, c)
|
||||
|
|
||||
- tt_assert(e >= c)
|
||||
+ tt_int_op(e, OP_GE, c)
|
||||
)
|
||||
|
||||
@@
|
||||
unsigned int e;
|
||||
constant c;
|
||||
@@
|
||||
|
||||
(
|
||||
- tt_assert(e == c)
|
||||
+ tt_uint_op(e, OP_EQ, c)
|
||||
|
|
||||
- tt_assert(e != c)
|
||||
+ tt_uint_op(e, OP_NE, c)
|
||||
|
|
||||
- tt_assert(e < c)
|
||||
+ tt_uint_op(e, OP_LT, c)
|
||||
|
|
||||
- tt_assert(e <= c)
|
||||
+ tt_uint_op(e, OP_LE, c)
|
||||
|
|
||||
- tt_assert(e > c)
|
||||
+ tt_uint_op(e, OP_GT, c)
|
||||
|
|
||||
- tt_assert(e >= c)
|
||||
+ tt_uint_op(e, OP_GE, c)
|
||||
)
|
|
@ -1,11 +0,0 @@
|
|||
@@
|
||||
expression * e;
|
||||
@@
|
||||
|
||||
(
|
||||
- tt_assert(e != NULL)
|
||||
+ tt_ptr_op(e, OP_NE, NULL)
|
||||
|
|
||||
- tt_assert(e == NULL)
|
||||
+ tt_ptr_op(e, OP_EQ, NULL)
|
||||
)
|
|
@ -1,5 +0,0 @@
|
|||
@@
|
||||
@@
|
||||
|
||||
- tt_assert(0)
|
||||
+ tt_abort()
|
|
@ -7,9 +7,7 @@ FUZZERS = """
|
|||
diff-apply
|
||||
extrainfo
|
||||
hsdescv2
|
||||
hsdescv3
|
||||
http
|
||||
http-connect
|
||||
iptsv2
|
||||
microdesc
|
||||
vrs
|
||||
|
@ -32,14 +30,13 @@ FUZZING_LIBS = \
|
|||
src/common/libor-ctime-testing.a \
|
||||
src/common/libor-event-testing.a \
|
||||
src/trunnel/libor-trunnel-testing.a \
|
||||
$(rust_ldadd) \
|
||||
@TOR_ZLIB_LIBS@ @TOR_LIB_MATH@ \
|
||||
@TOR_LIBEVENT_LIBS@ \
|
||||
@TOR_OPENSSL_LIBS@ @TOR_LIB_WS32@ @TOR_LIB_GDI@ @TOR_LIB_USERENV@ \
|
||||
@CURVE25519_LIBS@ \
|
||||
@TOR_OPENSSL_LIBS@ @TOR_LIB_WS32@ @TOR_LIB_GDI@ @CURVE25519_LIBS@ \
|
||||
@TOR_SYSTEMD_LIBS@ \
|
||||
@TOR_LZMA_LIBS@ \
|
||||
@TOR_ZSTD_LIBS@
|
||||
@TOR_ZSTD_LIBS@ \
|
||||
$(rust_ldadd)
|
||||
|
||||
oss-fuzz-prereqs: \
|
||||
src/or/libtor-testing.a \
|
||||
|
|
|
@ -1,74 +0,0 @@
|
|||
#!/usr/bin/python
|
||||
# Copyright (c) 2017, The Tor Project, Inc.
|
||||
# See LICENSE for licensing information
|
||||
|
||||
import re
|
||||
|
||||
LINE_OBVIOUSNESS_LIMIT = 4
|
||||
|
||||
class Problem(Exception):
|
||||
pass
|
||||
|
||||
def uncomment(s):
|
||||
s = re.sub(r'//.*','',s)
|
||||
s = re.sub(r'/\*.*','',s)
|
||||
return s.strip()
|
||||
|
||||
def translate(f_in, f_out):
|
||||
whole_file = []
|
||||
stack = []
|
||||
cur_level = whole_file
|
||||
lineno = 0
|
||||
for line in f_in:
|
||||
lineno += 1
|
||||
m = re.match(r'\s*#\s*(if|ifdef|ifndef|else|endif|elif)\b\s*(.*)',
|
||||
line)
|
||||
if not m:
|
||||
f_out.write(line)
|
||||
continue
|
||||
command,rest = m.groups()
|
||||
if command in ("if", "ifdef", "ifndef"):
|
||||
# The #if directive pushes us one level lower on the stack.
|
||||
if command == 'ifdef':
|
||||
rest = "defined(%s)"%uncomment(rest)
|
||||
elif command == 'ifndef':
|
||||
rest = "!defined(%s)"%uncomment(rest)
|
||||
elif rest.endswith("\\"):
|
||||
rest = rest[:-1]+"..."
|
||||
|
||||
rest = uncomment(rest)
|
||||
|
||||
new_level = [ (command, rest, lineno) ]
|
||||
stack.append(cur_level)
|
||||
cur_level = new_level
|
||||
f_out.write(line)
|
||||
elif command in ("else", "elif"):
|
||||
if len(cur_level) == 0 or cur_level[-1][0] == 'else':
|
||||
raise Problem("Unexpected #%s on %d"% (command,lineno))
|
||||
if (len(cur_level) == 1 and command == 'else' and
|
||||
lineno > cur_level[0][2] + LINE_OBVIOUSNESS_LIMIT):
|
||||
f_out.write("#else /* !(%s) */\n"%cur_level[0][1])
|
||||
else:
|
||||
f_out.write(line)
|
||||
cur_level.append((command, rest, lineno))
|
||||
else:
|
||||
assert command == 'endif'
|
||||
if len(stack) == 0:
|
||||
raise Problem("Unmatched #%s on %s"% (command,lineno))
|
||||
if lineno <= cur_level[0][2] + LINE_OBVIOUSNESS_LIMIT:
|
||||
f_out.write(line)
|
||||
elif len(cur_level) == 1 or (
|
||||
len(cur_level) == 2 and cur_level[1][0] == 'else'):
|
||||
f_out.write("#endif /* %s */\n"%cur_level[0][1])
|
||||
else:
|
||||
f_out.write("#endif /* %s || ... */\n"%cur_level[0][1])
|
||||
cur_level = stack.pop()
|
||||
if len(stack) or cur_level != whole_file:
|
||||
raise Problem("Missing #endif")
|
||||
|
||||
import sys,os
|
||||
for fn in sys.argv[1:]:
|
||||
with open(fn+"_OUT", 'w') as output_file:
|
||||
translate(open(fn, 'r'), output_file)
|
||||
os.rename(fn+"_OUT", fn)
|
||||
|
|
@ -123,10 +123,6 @@ for my $fn (@ARGV) {
|
|||
if (/([^\s'])\{/) {
|
||||
msg " $1\{:$fn:$.\n";
|
||||
}
|
||||
## Warn about double semi-colons at the end of a line.
|
||||
if (/;;$/) {
|
||||
msg " double semi-colons at the end of $. in $fn\n"
|
||||
}
|
||||
## Warn about multiple internal spaces.
|
||||
#if (/[^\s,:]\s{2,}[^\s\\=]/) {
|
||||
# msg " X X:$fn:$.\n";
|
||||
|
@ -144,7 +140,7 @@ for my $fn (@ARGV) {
|
|||
$1 ne "switch" and $1 ne "return" and $1 ne "int" and
|
||||
$1 ne "elsif" and $1 ne "WINAPI" and $2 ne "WINAPI" and
|
||||
$1 ne "void" and $1 ne "__attribute__" and $1 ne "op" and
|
||||
$1 ne "size_t" and $1 ne "double" and $1 ne "uint64_t" and
|
||||
$1 ne "size_t" and $1 ne "double" and
|
||||
$1 ne "workqueue_reply_t") {
|
||||
msg " fn ():$fn:$.\n";
|
||||
}
|
||||
|
|
|
@ -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))
|
|
@ -17,23 +17,12 @@ KNOWN_GROUPS = set([
|
|||
"Major feature",
|
||||
"Major features",
|
||||
"New system requirements",
|
||||
"New dependencies",
|
||||
"Testing",
|
||||
"Documentation",
|
||||
"Code simplification and refactoring",
|
||||
"Removed features",
|
||||
"Deprecated features",
|
||||
"Directory authority changes"])
|
||||
"Removed features"])
|
||||
|
||||
NEEDS_SUBCATEGORIES = set([
|
||||
"Minor bugfix",
|
||||
"Minor bugfixes",
|
||||
"Major bugfix",
|
||||
"Major bugfixes",
|
||||
"Minor feature",
|
||||
"Minor features",
|
||||
"Major feature",
|
||||
"Major features",
|
||||
])
|
||||
|
||||
def lintfile(fname):
|
||||
have_warned = []
|
||||
|
@ -58,11 +47,13 @@ def lintfile(fname):
|
|||
|
||||
m = re.match(r'^[ ]{2}o ([^\(:]*)([^:]*):', contents)
|
||||
if not m:
|
||||
warn("Header not in format expected. (' o Foo:' or ' o Foo (Bar):')")
|
||||
warn("header not in format expected")
|
||||
elif m.group(1).strip() not in KNOWN_GROUPS:
|
||||
warn("Unrecognized header: %r" % m.group(1))
|
||||
elif (m.group(1) in NEEDS_SUBCATEGORIES and '(' not in m.group(2)):
|
||||
warn("Missing subcategory on %r" % m.group(1))
|
||||
warn("Weird header: %r" % m.group(1))
|
||||
elif (("bugfix" in m.group(1) or "feature" in m.group(1)) and
|
||||
("Removed" not in m.group(1)) and
|
||||
'(' not in m.group(2)):
|
||||
warn("Missing subcategory on %s" % m.group(1))
|
||||
|
||||
if m:
|
||||
isBug = ("bug" in m.group(1).lower() or "fix" in m.group(1).lower())
|
||||
|
@ -72,46 +63,25 @@ def lintfile(fname):
|
|||
contents = " ".join(contents.split())
|
||||
|
||||
if re.search(r'\#\d{2,}', contents):
|
||||
warn("Don't use a # before ticket numbers. ('bug 1234' not '#1234')")
|
||||
warn("don't use a # before ticket numbers")
|
||||
|
||||
if isBug and not re.search(r'(\d+)', contents):
|
||||
warn("Ticket marked as bugfix, but does not mention a number.")
|
||||
elif isBug and not re.search(r'Fixes ([a-z ]*)bugs? (\d+)', contents):
|
||||
warn("Ticket marked as bugfix, but does not say 'Fixes bug XXX'")
|
||||
warn("bugfix does not mention a number")
|
||||
elif isBug and not re.search(r'Fixes ([a-z ]*)bug (\d+)', contents):
|
||||
warn("bugfix does not say 'Fixes bug XXX'")
|
||||
|
||||
if re.search(r'[bB]ug (\d+)', contents):
|
||||
if not re.search(r'[Bb]ugfix on ', contents):
|
||||
warn("Bugfix does not say 'bugfix on X.Y.Z'")
|
||||
elif not re.search('[fF]ixes ([a-z ]*)bugs? (\d+)((, \d+)* and \d+)?; bugfix on ',
|
||||
warn("bugfix does not say 'bugfix on X.Y.Z'")
|
||||
elif not re.search('[fF]ixes ([a-z ]*)bug (\d+); bugfix on ',
|
||||
contents):
|
||||
warn("Bugfix does not say 'Fixes bug X; bugfix on Y'")
|
||||
warn("bugfix incant is not semicoloned")
|
||||
elif re.search('tor-([0-9]+)', contents):
|
||||
warn("Do not prefix versions with 'tor-'. ('0.1.2', not 'tor-0.1.2'.)")
|
||||
warn("do not prefix versions with 'tor-'")
|
||||
|
||||
return have_warned != []
|
||||
|
||||
def files(args):
|
||||
"""Walk through the arguments: for directories, yield their contents;
|
||||
for files, just yield the files. Only search one level deep, because
|
||||
that's how the changes directory is laid out."""
|
||||
for f in args:
|
||||
if os.path.isdir(f):
|
||||
for item in os.listdir(f):
|
||||
if item.startswith("."): #ignore dotfiles
|
||||
continue
|
||||
yield os.path.join(f, item)
|
||||
else:
|
||||
yield f
|
||||
|
||||
if __name__ == '__main__':
|
||||
problems = 0
|
||||
for fname in files(sys.argv[1:]):
|
||||
for fname in sys.argv[1:]:
|
||||
if fname.endswith("~"):
|
||||
continue
|
||||
if lintfile(fname):
|
||||
problems += 1
|
||||
|
||||
if problems:
|
||||
sys.exit(1)
|
||||
else:
|
||||
sys.exit(0)
|
||||
lintfile(fname)
|
||||
|
|
|
@ -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,29 +0,0 @@
|
|||
#!/bin/sh
|
||||
|
||||
# You can find calltool at https://gitweb.torproject.org/user/nickm/calltool.git
|
||||
|
||||
set -e
|
||||
|
||||
if test "x$CALLTOOL_PATH" != "x"; then
|
||||
PYTHONPATH="${CALLTOOL_PATH}:${PYTHONPATH}"
|
||||
export PYTHONPATH
|
||||
fi
|
||||
|
||||
mkdir -p callgraph
|
||||
|
||||
SUBITEMS="fn_graph fn_invgraph fn_scc fn_scc_weaklinks module_graph module_invgraph module_scc module_scc_weaklinks"
|
||||
|
||||
for calculation in $SUBITEMS; do
|
||||
echo "======== $calculation"
|
||||
python -m calltool $calculation > callgraph/$calculation
|
||||
done
|
||||
|
||||
echo <<EOF > callgraph/README
|
||||
This directory holds output from calltool, as run on Tor. For more
|
||||
information about each of these files, see the NOTES and README files in
|
||||
the calltool distribution.
|
||||
|
||||
You can find calltool at
|
||||
https://gitweb.torproject.org/user/nickm/calltool.git
|
||||
EOF
|
||||
|
|
@ -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())
|
|
@ -7,15 +7,11 @@
|
|||
DIRA="$1"
|
||||
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"
|
||||
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/;'
|
||||
for A in $DIRA/*; do
|
||||
B=$DIRB/`basename $A`
|
||||
perl -pe 's/^\s*\!*\d+:/ 1:/; s/^([^:]+:)[\d\s]+:/$1/; s/^ *-:(Runs|Programs):.*//;' "$A" > "$A.tmp"
|
||||
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
|
||||
|
||||
|
|
|
@ -29,7 +29,7 @@ for fn in src/or/*.c src/common/*.c; do
|
|||
gcov -o $on $fn
|
||||
if [ -e $GC ]
|
||||
then
|
||||
if [ -d "$dst" ]
|
||||
if [ -n $dst ]
|
||||
then
|
||||
mv $GC $dst/$GC
|
||||
fi
|
||||
|
|
|
@ -5,76 +5,37 @@
|
|||
# This script is used for running a bunch of clang scan-build checkers
|
||||
# on Tor.
|
||||
|
||||
# These don't seem to cause false positives in our code, so let's turn
|
||||
# them on.
|
||||
CHECKERS="\
|
||||
-enable-checker alpha.core.CallAndMessageUnInitRefArg \
|
||||
-disable-checker deadcode.DeadStores \
|
||||
-enable-checker alpha.core.CastSize \
|
||||
-enable-checker alpha.core.CastToStruct \
|
||||
-enable-checker alpha.core.Conversion \
|
||||
-enable-checker alpha.core.FixedAddr \
|
||||
-enable-checker alpha.core.IdenticalExpr \
|
||||
-enable-checker alpha.core.PointerArithm \
|
||||
-enable-checker alpha.core.SizeofPtr \
|
||||
-enable-checker alpha.core.TestAfterDivZero \
|
||||
-enable-checker alpha.security.ArrayBoundV2 \
|
||||
-enable-checker alpha.security.MallocOverflow \
|
||||
-enable-checker alpha.security.ReturnPtrRange \
|
||||
-enable-checker alpha.unix.BlockInCriticalSection \
|
||||
-enable-checker alpha.unix.Chroot \
|
||||
-enable-checker alpha.unix.PthreadLock \
|
||||
-enable-checker alpha.unix.PthreadLock \
|
||||
-enable-checker alpha.unix.SimpleStream \
|
||||
-enable-checker alpha.unix.Stream \
|
||||
-enable-checker alpha.unix.SimpleStream
|
||||
-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 security.FloatLoopCounter \
|
||||
-enable-checker security.insecureAPI.strcpy \
|
||||
"
|
||||
|
||||
# These have high false-positive rates.
|
||||
EXTRA_CHECKERS="\
|
||||
-enable-checker alpha.security.ArrayBoundV2 \
|
||||
-enable-checker alpha.unix.cstring.OutOfBounds \
|
||||
-enable-checker alpha.core.CastSize \
|
||||
-enable-checker alpha.core.FixedAddr \
|
||||
-enable-checker security.insecureAPI.strcpy \
|
||||
-enable-checker alpha.unix.PthreadLock \
|
||||
-enable-checker alpha.core.PointerArithm \
|
||||
-enable-checker alpha.core.TestAfterDivZero \
|
||||
"
|
||||
|
||||
# These don't seem to generate anything useful
|
||||
NOISY_CHECKERS="\
|
||||
-enable-checker alpha.clone.CloneChecker \
|
||||
-enable-checker alpha.deadcode.UnreachableCode \
|
||||
"
|
||||
|
||||
if test "x$SCAN_BUILD_OUTPUT" != "x"; then
|
||||
OUTPUTARG="-o $SCAN_BUILD_OUTPUT"
|
||||
else
|
||||
OUTPUTARG=""
|
||||
fi
|
||||
|
||||
scan-build \
|
||||
$CHECKERS \
|
||||
./configure
|
||||
|
||||
scan-build \
|
||||
make clean
|
||||
|
||||
# Make this not get scanned for dead assignments, since it has lots of
|
||||
# dead assignments we don't care about.
|
||||
scan-build \
|
||||
$CHECKERS \
|
||||
-disable-checker deadcode.DeadStores \
|
||||
make -j5 -k ./src/ext/ed25519/ref10/libed25519_ref10.a
|
||||
make -j2 -k
|
||||
|
||||
scan-build \
|
||||
$CHECKERS $OUTPUTARG \
|
||||
make -j5 -k
|
||||
|
||||
CHECKERS="\
|
||||
"
|
||||
|
||||
# This one gives a false positive on every strcmp.
|
||||
# -enable-checker alpha.core.PointerSub
|
||||
|
||||
# Needs work
|
||||
# -enable-checker alpha.unix.MallocWithAnnotations
|
||||
# alpha.unix.MallocWithAnnotations ??
|
||||
|
|
|
@ -33,7 +33,7 @@
|
|||
#include <process.h>
|
||||
#include <windows.h>
|
||||
#include <iphlpapi.h>
|
||||
#endif /* defined(_WIN32) */
|
||||
#endif
|
||||
|
||||
#include "compat.h"
|
||||
#include "util.h"
|
||||
|
@ -198,7 +198,7 @@ tor_sockaddr_to_str(const struct sockaddr *sa)
|
|||
tor_asprintf(&result, "unix:%s", s_un->sun_path);
|
||||
return result;
|
||||
}
|
||||
#endif /* defined(HAVE_SYS_UN_H) */
|
||||
#endif
|
||||
if (sa->sa_family == AF_UNSPEC)
|
||||
return tor_strdup("unspec");
|
||||
|
||||
|
@ -305,7 +305,7 @@ tor_addr_lookup,(const char *name, uint16_t family, tor_addr_t *addr))
|
|||
return result;
|
||||
}
|
||||
return (err == EAI_AGAIN) ? 1 : -1;
|
||||
#else /* !(defined(HAVE_GETADDRINFO)) */
|
||||
#else
|
||||
struct hostent *ent;
|
||||
int err;
|
||||
#ifdef HAVE_GETHOSTBYNAME_R_6_ARG
|
||||
|
@ -330,7 +330,7 @@ tor_addr_lookup,(const char *name, uint16_t family, tor_addr_t *addr))
|
|||
#else
|
||||
err = h_errno;
|
||||
#endif
|
||||
#endif /* defined(HAVE_GETHOSTBYNAME_R_6_ARG) || ... */
|
||||
#endif /* endif HAVE_GETHOSTBYNAME_R_6_ARG. */
|
||||
if (ent) {
|
||||
if (ent->h_addrtype == AF_INET) {
|
||||
tor_addr_from_in(addr, (struct in_addr*) ent->h_addr);
|
||||
|
@ -346,7 +346,7 @@ tor_addr_lookup,(const char *name, uint16_t family, tor_addr_t *addr))
|
|||
#else
|
||||
return (err == TRY_AGAIN) ? 1 : -1;
|
||||
#endif
|
||||
#endif /* defined(HAVE_GETADDRINFO) */
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -907,8 +907,8 @@ tor_addr_is_loopback(const tor_addr_t *addr)
|
|||
return (tor_addr_to_ipv4h(addr) & 0xff000000) == 0x7f000000;
|
||||
case AF_UNSPEC:
|
||||
return 0;
|
||||
/* LCOV_EXCL_START */
|
||||
default:
|
||||
/* LCOV_EXCL_START */
|
||||
tor_fragile_assert();
|
||||
return 0;
|
||||
/* LCOV_EXCL_STOP */
|
||||
|
@ -1031,10 +1031,8 @@ tor_addr_copy_tight(tor_addr_t *dest, const tor_addr_t *src)
|
|||
memcpy(dest->addr.in6_addr.s6_addr, src->addr.in6_addr.s6_addr, 16);
|
||||
case AF_UNSPEC:
|
||||
break;
|
||||
// LCOV_EXCL_START
|
||||
default:
|
||||
tor_fragile_assert();
|
||||
// LCOV_EXCL_STOP
|
||||
tor_fragile_assert(); // LCOV_EXCL_LINE
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1125,7 +1123,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
|
||||
|
@ -1140,8 +1138,8 @@ tor_addr_compare_masked(const tor_addr_t *addr1, const tor_addr_t *addr2,
|
|||
return 0;
|
||||
else
|
||||
return 1;
|
||||
/* LCOV_EXCL_START */
|
||||
default:
|
||||
/* LCOV_EXCL_START */
|
||||
tor_fragile_assert();
|
||||
return 0;
|
||||
/* LCOV_EXCL_STOP */
|
||||
|
@ -1199,8 +1197,8 @@ tor_addr_hash(const tor_addr_t *addr)
|
|||
return siphash24g(unspec_hash_input, sizeof(unspec_hash_input));
|
||||
case AF_INET6:
|
||||
return siphash24g(&addr->addr.in6_addr.s6_addr, 16);
|
||||
/* LCOV_EXCL_START */
|
||||
default:
|
||||
/* LCOV_EXCL_START */
|
||||
tor_fragile_assert();
|
||||
return 0;
|
||||
/* LCOV_EXCL_STOP */
|
||||
|
@ -1436,7 +1434,7 @@ get_interface_addresses_ifaddrs(int severity, sa_family_t family)
|
|||
|
||||
return result;
|
||||
}
|
||||
#endif /* defined(HAVE_IFADDRS_TO_SMARTLIST) */
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_IP_ADAPTER_TO_SMARTLIST
|
||||
|
||||
|
@ -1527,7 +1525,7 @@ get_interface_addresses_win32(int severity, sa_family_t family)
|
|||
return result;
|
||||
}
|
||||
|
||||
#endif /* defined(HAVE_IP_ADAPTER_TO_SMARTLIST) */
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_IFCONF_TO_SMARTLIST
|
||||
|
||||
|
@ -1540,18 +1538,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,10 +1624,10 @@ 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) */
|
||||
#endif
|
||||
|
||||
/** Try to ask our network interfaces what addresses they are bound to.
|
||||
* Return a new smartlist of tor_addr_t on success, and NULL on failure.
|
||||
|
@ -1697,7 +1683,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 +1726,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 +1782,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 +1804,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,
|
||||
|
|
|
@ -44,7 +44,7 @@
|
|||
#endif
|
||||
|
||||
// TODO win32 specific includes
|
||||
#endif /* defined(ADDRESS_PRIVATE) */
|
||||
#endif // ADDRESS_PRIVATE
|
||||
|
||||
/** The number of bits from an address to consider while doing a masked
|
||||
* comparison. */
|
||||
|
@ -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
|
||||
|
@ -357,23 +360,23 @@ STATIC smartlist_t *ifaddrs_to_smartlist(const struct ifaddrs *ifa,
|
|||
sa_family_t family);
|
||||
STATIC smartlist_t *get_interface_addresses_ifaddrs(int severity,
|
||||
sa_family_t family);
|
||||
#endif /* defined(HAVE_IFADDRS_TO_SMARTLIST) */
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_IP_ADAPTER_TO_SMARTLIST
|
||||
STATIC smartlist_t *ip_adapter_addresses_to_smartlist(
|
||||
const IP_ADAPTER_ADDRESSES *addresses);
|
||||
STATIC smartlist_t *get_interface_addresses_win32(int severity,
|
||||
sa_family_t family);
|
||||
#endif /* defined(HAVE_IP_ADAPTER_TO_SMARTLIST) */
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_IFCONF_TO_SMARTLIST
|
||||
STATIC smartlist_t *ifreq_to_smartlist(char *ifr,
|
||||
size_t buflen);
|
||||
STATIC smartlist_t *get_interface_addresses_ioctl(int severity,
|
||||
sa_family_t family);
|
||||
#endif /* defined(HAVE_IFCONF_TO_SMARTLIST) */
|
||||
#endif
|
||||
|
||||
#endif /* defined(ADDRESS_PRIVATE) */
|
||||
#endif // ADDRESS_PRIVATE
|
||||
|
||||
#endif /* !defined(TOR_ADDRESS_H) */
|
||||
#endif
|
||||
|
||||
|
|
|
@ -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"
|
||||
|
@ -67,11 +66,11 @@ ENABLE_GCC_WARNING(redundant-decls)
|
|||
#elif OPENSSL_VERSION_NUMBER >= OPENSSL_V_NOPATCH(1,0,1) && \
|
||||
(defined(__i386) || defined(__i386__) || defined(_M_IX86) || \
|
||||
defined(__x86_64) || defined(__x86_64__) || \
|
||||
defined(_M_AMD64) || defined(_M_X64) || defined(__INTEL__))
|
||||
defined(_M_AMD64) || defined(_M_X64) || defined(__INTEL__)) \
|
||||
|
||||
#define USE_EVP_AES_CTR
|
||||
|
||||
#endif /* OPENSSL_VERSION_NUMBER >= OPENSSL_V_NOPATCH(1,1,0) || ... */
|
||||
#endif
|
||||
|
||||
/* We have 2 strategies for getting the AES block cipher: Via OpenSSL's
|
||||
* AES_encrypt function, or via OpenSSL's EVP_EncryptUpdate function.
|
||||
|
@ -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
|
||||
|
@ -147,7 +142,7 @@ evaluate_ctr_for_aes(void)
|
|||
{
|
||||
return 0;
|
||||
}
|
||||
#else /* !(defined(USE_EVP_AES_CTR)) */
|
||||
#else
|
||||
|
||||
/*======================================================================*/
|
||||
/* Interface to AES code, and counter implementation */
|
||||
|
@ -168,7 +163,7 @@ struct aes_cnt_cipher {
|
|||
uint32_t counter2;
|
||||
uint32_t counter1;
|
||||
uint32_t counter0;
|
||||
#endif /* !defined(WORDS_BIGENDIAN) */
|
||||
#endif
|
||||
|
||||
union {
|
||||
/** The counter, in big-endian order, as bytes. */
|
||||
|
@ -217,7 +212,7 @@ evaluate_evp_for_aes(int force_val)
|
|||
log_info(LD_CRYPTO, "No AES engine found; using AES_* functions.");
|
||||
should_use_EVP = 0;
|
||||
}
|
||||
#endif /* defined(DISABLE_ENGINES) */
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -317,7 +312,7 @@ aes_set_key(aes_cnt_cipher_t *cipher, const uint8_t *key, int key_bits)
|
|||
cipher->counter1 = 0;
|
||||
cipher->counter2 = 0;
|
||||
cipher->counter3 = 0;
|
||||
#endif /* defined(USING_COUNTER_VARS) */
|
||||
#endif
|
||||
|
||||
memset(cipher->ctr_buf.buf, 0, sizeof(cipher->ctr_buf.buf));
|
||||
|
||||
|
@ -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;
|
||||
|
@ -346,7 +341,7 @@ aes_cipher_free_(aes_cnt_cipher_t *cipher)
|
|||
STMT_END
|
||||
#else
|
||||
#define UPDATE_CTR_BUF(c, n)
|
||||
#endif /* defined(USING_COUNTER_VARS) */
|
||||
#endif
|
||||
|
||||
/* Helper function to use EVP with openssl's counter-mode wrapper. */
|
||||
static void
|
||||
|
@ -401,10 +396,10 @@ aes_set_iv(aes_cnt_cipher_t *cipher, const uint8_t *iv)
|
|||
cipher->counter2 = ntohl(get_uint32(iv+4));
|
||||
cipher->counter1 = ntohl(get_uint32(iv+8));
|
||||
cipher->counter0 = ntohl(get_uint32(iv+12));
|
||||
#endif /* defined(USING_COUNTER_VARS) */
|
||||
#endif
|
||||
cipher->pos = 0;
|
||||
memcpy(cipher->ctr_buf.buf, iv, 16);
|
||||
}
|
||||
|
||||
#endif /* defined(USE_EVP_AES_CTR) */
|
||||
#endif
|
||||
|
||||
|
|
|
@ -17,13 +17,11 @@ 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);
|
||||
int evaluate_ctr_for_aes(void);
|
||||
|
||||
#endif /* !defined(TOR_AES_H) */
|
||||
#endif
|
||||
|
||||
|
|
|
@ -37,7 +37,7 @@
|
|||
#include <sys/ucontext.h>
|
||||
#elif defined(HAVE_UCONTEXT_H)
|
||||
#include <ucontext.h>
|
||||
#endif /* defined(HAVE_CYGWIN_SIGNAL_H) || ... */
|
||||
#endif
|
||||
|
||||
#define EXPOSE_CLEAN_BACKTRACE
|
||||
#include "backtrace.h"
|
||||
|
@ -81,16 +81,16 @@ clean_backtrace(void **stack, size_t depth, const ucontext_t *ctx)
|
|||
const size_t n = 2;
|
||||
#else
|
||||
const size_t n = 1;
|
||||
#endif /* defined(__linux__) || ... */
|
||||
#endif
|
||||
if (depth <= n)
|
||||
return;
|
||||
|
||||
stack[n] = (void*) ctx->PC_FROM_UCONTEXT;
|
||||
#else /* !(defined(PC_FROM_UCONTEXT)) */
|
||||
#else
|
||||
(void) depth;
|
||||
(void) ctx;
|
||||
(void) stack;
|
||||
#endif /* defined(PC_FROM_UCONTEXT) */
|
||||
#endif
|
||||
}
|
||||
|
||||
/** Log a message <b>msg</b> at <b>severity</b> in <b>domain</b>, and follow
|
||||
|
@ -202,7 +202,7 @@ remove_bt_handler(void)
|
|||
{
|
||||
tor_mutex_uninit(&cb_buf_mutex);
|
||||
}
|
||||
#endif /* defined(USE_BACKTRACE) */
|
||||
#endif
|
||||
|
||||
#ifdef NO_BACKTRACE_IMPL
|
||||
void
|
||||
|
@ -221,7 +221,7 @@ static void
|
|||
remove_bt_handler(void)
|
||||
{
|
||||
}
|
||||
#endif /* defined(NO_BACKTRACE_IMPL) */
|
||||
#endif
|
||||
|
||||
/** Set up code to handle generating error messages on crashes. */
|
||||
int
|
||||
|
|
|
@ -15,7 +15,7 @@ void clean_up_backtrace_handler(void);
|
|||
defined(HAVE_BACKTRACE_SYMBOLS_FD) && defined(HAVE_SIGACTION)
|
||||
void clean_backtrace(void **stack, size_t depth, const ucontext_t *ctx);
|
||||
#endif
|
||||
#endif /* defined(EXPOSE_CLEAN_BACKTRACE) */
|
||||
#endif
|
||||
|
||||
#endif /* !defined(TOR_BACKTRACE_H) */
|
||||
#endif
|
||||
|
||||
|
|
1146
src/common/buffers.c
1146
src/common/buffers.c
File diff suppressed because it is too large
Load Diff
|
@ -1,131 +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 buffers.h
|
||||
* \brief Header file for buffers.c.
|
||||
**/
|
||||
|
||||
#ifndef TOR_BUFFERS_H
|
||||
#define TOR_BUFFERS_H
|
||||
|
||||
#include "compat.h"
|
||||
#include "torint.h"
|
||||
#include "testsupport.h"
|
||||
|
||||
typedef struct buf_t buf_t;
|
||||
|
||||
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_clear(buf_t *buf);
|
||||
buf_t *buf_copy(const buf_t *buf);
|
||||
|
||||
MOCK_DECL(size_t, buf_datalen, (const buf_t *buf));
|
||||
size_t buf_allocation(const buf_t *buf);
|
||||
size_t buf_slack(const buf_t *buf);
|
||||
|
||||
uint32_t buf_get_oldest_chunk_timestamp(const buf_t *buf, uint32_t now);
|
||||
size_t buf_get_total_allocation(void);
|
||||
|
||||
int buf_read_from_socket(buf_t *buf, tor_socket_t s, size_t at_most,
|
||||
int *reached_eof,
|
||||
int *socket_error);
|
||||
|
||||
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);
|
||||
int buf_get_line(buf_t *buf, char *data_out, size_t *data_len);
|
||||
|
||||
#define PEEK_BUF_STARTSWITH_MAX 16
|
||||
int buf_peek_startswith(const buf_t *buf, const char *cmd);
|
||||
|
||||
int buf_set_to_copy(buf_t **output,
|
||||
const buf_t *input);
|
||||
|
||||
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
|
||||
buf_t *buf_new_with_data(const char *cp, size_t sz);
|
||||
#endif
|
||||
size_t buf_preferred_chunk_size(size_t target);
|
||||
|
||||
#define DEBUG_CHUNK_ALLOC
|
||||
/** A single chunk on a buffer. */
|
||||
typedef struct chunk_t {
|
||||
struct chunk_t *next; /**< The next chunk on the buffer. */
|
||||
size_t datalen; /**< The number of bytes stored in this chunk */
|
||||
size_t memlen; /**< The number of usable bytes of storage in <b>mem</b>. */
|
||||
#ifdef DEBUG_CHUNK_ALLOC
|
||||
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. */
|
||||
char mem[FLEXIBLE_ARRAY_MEMBER]; /**< The actual memory used for storage in
|
||||
* this chunk. */
|
||||
} chunk_t;
|
||||
|
||||
/** Magic value for buf_t.magic, to catch pointer errors. */
|
||||
#define BUFFER_MAGIC 0xB0FFF312u
|
||||
/** A resizeable buffer, optimized for reading and writing. */
|
||||
struct buf_t {
|
||||
uint32_t magic; /**< Magic cookie for debugging: Must be set to
|
||||
* BUFFER_MAGIC. */
|
||||
size_t datalen; /**< How many bytes is this buffer holding right now? */
|
||||
size_t default_chunk_size; /**< Don't allocate any chunks smaller than
|
||||
* this for this buffer. */
|
||||
chunk_t *head; /**< First chunk in the list, or NULL for none. */
|
||||
chunk_t *tail; /**< Last chunk in the list, or NULL for none. */
|
||||
};
|
||||
|
||||
chunk_t *buf_add_chunk_with_capacity(buf_t *buf, size_t capacity, int capped);
|
||||
/** If a read onto the end of a chunk would be smaller than this number, then
|
||||
* just start a new chunk. */
|
||||
#define MIN_READ_LEN 8
|
||||
|
||||
/** Return the number of bytes that can be written onto <b>chunk</b> without
|
||||
* running out of space. */
|
||||
static inline size_t
|
||||
CHUNK_REMAINING_CAPACITY(const chunk_t *chunk)
|
||||
{
|
||||
return (chunk->mem + chunk->memlen) - (chunk->data + chunk->datalen);
|
||||
}
|
||||
|
||||
/** Return the next character in <b>chunk</b> onto which data can be appended.
|
||||
* If the chunk is full, this might be off the end of chunk->mem. */
|
||||
static inline char *
|
||||
CHUNK_WRITE_PTR(chunk_t *chunk)
|
||||
{
|
||||
return chunk->data + chunk->datalen;
|
||||
}
|
||||
|
||||
#endif /* defined(BUFFERS_PRIVATE) */
|
||||
|
||||
#endif /* !defined(TOR_BUFFERS_H) */
|
||||
|
|
@ -1,179 +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 */
|
||||
|
||||
#define BUFFERS_PRIVATE
|
||||
#include "orconfig.h"
|
||||
#include <stddef.h>
|
||||
#include "buffers.h"
|
||||
#include "buffers_tls.h"
|
||||
#include "compat.h"
|
||||
#include "compress.h"
|
||||
#include "util.h"
|
||||
#include "torint.h"
|
||||
#include "torlog.h"
|
||||
#include "tortls.h"
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
/** As read_to_chunk(), but return (negative) error code on error, blocking,
|
||||
* or TLS, and the number of bytes read otherwise. */
|
||||
static inline int
|
||||
read_to_chunk_tls(buf_t *buf, chunk_t *chunk, tor_tls_t *tls,
|
||||
size_t at_most)
|
||||
{
|
||||
int read_result;
|
||||
|
||||
tor_assert(CHUNK_REMAINING_CAPACITY(chunk) >= at_most);
|
||||
read_result = tor_tls_read(tls, CHUNK_WRITE_PTR(chunk), at_most);
|
||||
if (read_result < 0)
|
||||
return read_result;
|
||||
buf->datalen += read_result;
|
||||
chunk->datalen += read_result;
|
||||
return read_result;
|
||||
}
|
||||
|
||||
/** As read_to_buf, but reads from a TLS connection, and returns a TLS
|
||||
* status value rather than the number of bytes read.
|
||||
*
|
||||
* Using TLS on OR connections complicates matters in two ways.
|
||||
*
|
||||
* First, a TLS stream has its own read buffer independent of the
|
||||
* connection's read buffer. (TLS needs to read an entire frame from
|
||||
* the network before it can decrypt any data. Thus, trying to read 1
|
||||
* byte from TLS can require that several KB be read from the network
|
||||
* and decrypted. The extra data is stored in TLS's decrypt buffer.)
|
||||
* Because the data hasn't been read by Tor (it's still inside the TLS),
|
||||
* this means that sometimes a connection "has stuff to read" even when
|
||||
* poll() didn't return POLLIN. The tor_tls_get_pending_bytes function is
|
||||
* used in connection.c to detect TLS objects with non-empty internal
|
||||
* buffers and read from them again.
|
||||
*
|
||||
* Second, the TLS stream's events do not correspond directly to network
|
||||
* events: sometimes, before a TLS stream can read, the network must be
|
||||
* ready to write -- or vice versa.
|
||||
*/
|
||||
int
|
||||
buf_read_from_tls(buf_t *buf, tor_tls_t *tls, size_t at_most)
|
||||
{
|
||||
int r = 0;
|
||||
size_t total_read = 0;
|
||||
|
||||
check_no_tls_errors();
|
||||
|
||||
if (BUG(buf->datalen >= INT_MAX))
|
||||
return -1;
|
||||
if (BUG(buf->datalen >= INT_MAX - at_most))
|
||||
return -1;
|
||||
|
||||
while (at_most > total_read) {
|
||||
size_t readlen = at_most - total_read;
|
||||
chunk_t *chunk;
|
||||
if (!buf->tail || CHUNK_REMAINING_CAPACITY(buf->tail) < MIN_READ_LEN) {
|
||||
chunk = buf_add_chunk_with_capacity(buf, at_most, 1);
|
||||
if (readlen > chunk->memlen)
|
||||
readlen = chunk->memlen;
|
||||
} else {
|
||||
size_t cap = CHUNK_REMAINING_CAPACITY(buf->tail);
|
||||
chunk = buf->tail;
|
||||
if (cap < readlen)
|
||||
readlen = cap;
|
||||
}
|
||||
|
||||
r = read_to_chunk_tls(buf, chunk, tls, readlen);
|
||||
if (r < 0)
|
||||
return r; /* Error */
|
||||
tor_assert(total_read+r < INT_MAX);
|
||||
total_read += r;
|
||||
if ((size_t)r < readlen) /* eof, block, or no more to read. */
|
||||
break;
|
||||
}
|
||||
return (int)total_read;
|
||||
}
|
||||
|
||||
/** Helper for buf_flush_to_tls(): try to write <b>sz</b> bytes from chunk
|
||||
* <b>chunk</b> of buffer <b>buf</b> onto socket <b>s</b>. (Tries to write
|
||||
* more if there is a forced pending write size.) On success, deduct the
|
||||
* bytes written from *<b>buf_flushlen</b>. Return the number of bytes
|
||||
* written on success, and a TOR_TLS error code on failure or blocking.
|
||||
*/
|
||||
static inline int
|
||||
flush_chunk_tls(tor_tls_t *tls, buf_t *buf, chunk_t *chunk,
|
||||
size_t sz, size_t *buf_flushlen)
|
||||
{
|
||||
int r;
|
||||
size_t forced;
|
||||
char *data;
|
||||
|
||||
forced = tor_tls_get_forced_write_size(tls);
|
||||
if (forced > sz)
|
||||
sz = forced;
|
||||
if (chunk) {
|
||||
data = chunk->data;
|
||||
tor_assert(sz <= chunk->datalen);
|
||||
} else {
|
||||
data = NULL;
|
||||
tor_assert(sz == 0);
|
||||
}
|
||||
r = tor_tls_write(tls, data, sz);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (*buf_flushlen > (size_t)r)
|
||||
*buf_flushlen -= r;
|
||||
else
|
||||
*buf_flushlen = 0;
|
||||
buf_drain(buf, r);
|
||||
log_debug(LD_NET,"flushed %d bytes, %d ready to flush, %d remain.",
|
||||
r,(int)*buf_flushlen,(int)buf->datalen);
|
||||
return r;
|
||||
}
|
||||
|
||||
/** As buf_flush_to_socket(), but writes data to a TLS connection. Can write
|
||||
* more than <b>flushlen</b> bytes.
|
||||
*/
|
||||
int
|
||||
buf_flush_to_tls(buf_t *buf, tor_tls_t *tls, size_t flushlen,
|
||||
size_t *buf_flushlen)
|
||||
{
|
||||
int r;
|
||||
size_t flushed = 0;
|
||||
ssize_t sz;
|
||||
tor_assert(buf_flushlen);
|
||||
if (BUG(*buf_flushlen > buf->datalen)) {
|
||||
*buf_flushlen = buf->datalen;
|
||||
}
|
||||
if (BUG(flushlen > *buf_flushlen)) {
|
||||
flushlen = *buf_flushlen;
|
||||
}
|
||||
sz = (ssize_t) flushlen;
|
||||
|
||||
/* we want to let tls write even if flushlen is zero, because it might
|
||||
* have a partial record pending */
|
||||
check_no_tls_errors();
|
||||
|
||||
do {
|
||||
size_t flushlen0;
|
||||
if (buf->head) {
|
||||
if ((ssize_t)buf->head->datalen >= sz)
|
||||
flushlen0 = sz;
|
||||
else
|
||||
flushlen0 = buf->head->datalen;
|
||||
} else {
|
||||
flushlen0 = 0;
|
||||
}
|
||||
|
||||
r = flush_chunk_tls(tls, buf, buf->head, flushlen0, buf_flushlen);
|
||||
if (r < 0)
|
||||
return r;
|
||||
flushed += r;
|
||||
sz -= r;
|
||||
if (r == 0) /* Can't flush any more now. */
|
||||
break;
|
||||
} while (sz > 0);
|
||||
tor_assert(flushed < INT_MAX);
|
||||
return (int)flushed;
|
||||
}
|
||||
|
|
@ -1,19 +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 */
|
||||
|
||||
#ifndef TOR_BUFFERS_TLS_H
|
||||
#define TOR_BUFFERS_TLS_H
|
||||
|
||||
struct buf_t;
|
||||
struct tor_tls_t;
|
||||
|
||||
int buf_read_from_tls(struct buf_t *buf,
|
||||
struct tor_tls_t *tls, size_t at_most);
|
||||
int buf_flush_to_tls(struct buf_t *buf, struct tor_tls_t *tls,
|
||||
size_t sz, size_t *buf_flushlen);
|
||||
|
||||
#endif /* !defined(TOR_BUFFERS_TLS_H) */
|
||||
|
|
@ -88,20 +88,21 @@ SecureZeroMemory(PVOID ptr, SIZE_T cnt)
|
|||
while (cnt--)
|
||||
*vcptr++ = 0;
|
||||
}
|
||||
#endif /* defined(HAVE_DECL_SECUREZEROMEMORY) && !HAVE_DECL_SECUREZEROMEMORY */
|
||||
#endif
|
||||
#elif defined(HAVE_READPASSPHRASE_H)
|
||||
#include <readpassphrase.h>
|
||||
#else
|
||||
#include "tor_readpassphrase.h"
|
||||
#endif /* defined(_WIN32) || ... */
|
||||
#endif
|
||||
|
||||
/* Includes for the process attaching prevention */
|
||||
#if defined(HAVE_SYS_PRCTL_H) && defined(__linux__)
|
||||
/* 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__) || ... */
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_NETDB_H
|
||||
#include <netdb.h>
|
||||
|
@ -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
|
||||
|
@ -160,7 +161,7 @@ tor_open_cloexec(const char *path, int flags, unsigned mode)
|
|||
* are running on one without. */
|
||||
if (errno != EINVAL)
|
||||
return -1;
|
||||
#endif /* defined(O_CLOEXEC) */
|
||||
#endif
|
||||
|
||||
log_debug(LD_FS, "Opening %s with flags %x", p, flags);
|
||||
fd = open(p, flags, mode);
|
||||
|
@ -172,7 +173,7 @@ tor_open_cloexec(const char *path, int flags, unsigned mode)
|
|||
return -1;
|
||||
}
|
||||
}
|
||||
#endif /* defined(FD_CLOEXEC) */
|
||||
#endif
|
||||
return fd;
|
||||
}
|
||||
|
||||
|
@ -190,7 +191,7 @@ tor_fopen_cloexec(const char *path, const char *mode)
|
|||
return NULL;
|
||||
}
|
||||
}
|
||||
#endif /* defined(FD_CLOEXEC) */
|
||||
#endif
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -203,17 +204,24 @@ 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 +250,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 +417,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
|
||||
|
||||
/** Replacement for snprintf. Differs from platform snprintf in two
|
||||
* ways: First, always NUL-terminates its output. Second, always
|
||||
|
@ -543,7 +590,7 @@ tor_vasprintf(char **strp, const char *fmt, va_list args)
|
|||
}
|
||||
*strp = strp_tmp;
|
||||
return len;
|
||||
#endif /* defined(HAVE_VASPRINTF) || ... */
|
||||
#endif
|
||||
}
|
||||
|
||||
/** Given <b>hlen</b> bytes at <b>haystack</b> and <b>nlen</b> bytes at
|
||||
|
@ -589,7 +636,7 @@ tor_memmem(const void *_haystack, size_t hlen,
|
|||
}
|
||||
}
|
||||
return NULL;
|
||||
#endif /* defined(HAVE_MEMMEM) && (!defined(__GNUC__) || __GNUC__ >= 2) */
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -727,7 +774,7 @@ tor_fix_source_file(const char *fname)
|
|||
}
|
||||
return r;
|
||||
}
|
||||
#endif /* defined(_WIN32) */
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Read a 16-bit value beginning at <b>cp</b>. Equivalent to
|
||||
|
@ -821,7 +868,7 @@ replace_file(const char *from, const char *to)
|
|||
return -1;
|
||||
}
|
||||
return tor_rename(from,to);
|
||||
#endif /* !defined(_WIN32) */
|
||||
#endif
|
||||
}
|
||||
|
||||
/** Change <b>fname</b>'s modification time to now. */
|
||||
|
@ -907,7 +954,7 @@ tor_lockfile_lock(const char *filename, int blocking, int *locked_out)
|
|||
return NULL;
|
||||
}
|
||||
}
|
||||
#endif /* defined(_WIN32) || ... */
|
||||
#endif
|
||||
|
||||
result = tor_malloc(sizeof(tor_lockfile_t));
|
||||
result->filename = tor_strdup(filename);
|
||||
|
@ -935,7 +982,7 @@ tor_lockfile_unlock(tor_lockfile_t *lockfile)
|
|||
}
|
||||
#else
|
||||
/* Closing the lockfile is sufficient. */
|
||||
#endif /* defined(_WIN32) || ... */
|
||||
#endif
|
||||
|
||||
close(lockfile->fd);
|
||||
lockfile->fd = -1;
|
||||
|
@ -983,9 +1030,9 @@ tor_fd_seekend(int fd)
|
|||
* no need to worry. */
|
||||
if (rc < 0 && errno == ESPIPE)
|
||||
rc = 0;
|
||||
#endif /* defined(ESPIPE) */
|
||||
#endif
|
||||
return (rc < 0) ? -1 : 0;
|
||||
#endif /* defined(_WIN32) */
|
||||
#endif
|
||||
}
|
||||
|
||||
/** Move <b>fd</b> to position <b>pos</b> in the file. Return -1 on error, 0
|
||||
|
@ -1024,7 +1071,7 @@ tor_ftruncate(int fd)
|
|||
static bitarray_t *open_sockets = NULL;
|
||||
/** The size of <b>open_sockets</b>, in bits. */
|
||||
static int max_socket = -1;
|
||||
#endif /* defined(DEBUG_SOCKET_COUNTING) */
|
||||
#endif
|
||||
|
||||
/** Count of number of sockets currently open. (Undercounts sockets opened by
|
||||
* eventdns and libevent.) */
|
||||
|
@ -1094,7 +1141,7 @@ tor_close_socket,(tor_socket_t s))
|
|||
tor_assert(open_sockets && s <= max_socket);
|
||||
bitarray_clear(open_sockets, s);
|
||||
}
|
||||
#endif /* defined(DEBUG_SOCKET_COUNTING) */
|
||||
#endif
|
||||
if (r == 0) {
|
||||
--n_sockets_open;
|
||||
} else {
|
||||
|
@ -1104,7 +1151,7 @@ tor_close_socket,(tor_socket_t s))
|
|||
#else
|
||||
if (r != EBADF)
|
||||
--n_sockets_open; // LCOV_EXCL_LINE -- EIO and EINTR too hard to force.
|
||||
#endif /* defined(_WIN32) */
|
||||
#endif
|
||||
r = -1;
|
||||
}
|
||||
|
||||
|
@ -1137,9 +1184,9 @@ mark_socket_open(tor_socket_t s)
|
|||
}
|
||||
bitarray_set(open_sockets, s);
|
||||
}
|
||||
#else /* !(defined(DEBUG_SOCKET_COUNTING)) */
|
||||
#define mark_socket_open(s) ((void) (s))
|
||||
#endif /* defined(DEBUG_SOCKET_COUNTING) */
|
||||
#else
|
||||
#define mark_socket_open(s) STMT_NIL
|
||||
#endif
|
||||
/** @} */
|
||||
|
||||
/** As socket(), but counts the number of open sockets. */
|
||||
|
@ -1197,7 +1244,7 @@ tor_open_socket_with_extensions(int domain, int type, int protocol,
|
|||
* support, we are running on one without. */
|
||||
if (errno != EINVAL)
|
||||
return s;
|
||||
#endif /* defined(SOCK_CLOEXEC) && defined(SOCK_NONBLOCK) */
|
||||
#endif /* SOCK_CLOEXEC && SOCK_NONBLOCK */
|
||||
|
||||
s = socket(domain, type, protocol);
|
||||
if (! SOCKET_OK(s))
|
||||
|
@ -1211,9 +1258,9 @@ tor_open_socket_with_extensions(int domain, int type, int protocol,
|
|||
return TOR_INVALID_SOCKET;
|
||||
}
|
||||
}
|
||||
#else /* !(defined(FD_CLOEXEC)) */
|
||||
#else
|
||||
(void)cloexec;
|
||||
#endif /* defined(FD_CLOEXEC) */
|
||||
#endif
|
||||
|
||||
if (nonblock) {
|
||||
if (set_socket_nonblocking(s) == -1) {
|
||||
|
@ -1225,22 +1272,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. */
|
||||
|
@ -1280,8 +1316,7 @@ tor_accept_socket_with_extensions(tor_socket_t sockfd, struct sockaddr *addr,
|
|||
return TOR_INVALID_SOCKET;
|
||||
}
|
||||
|
||||
#if defined(HAVE_ACCEPT4) && defined(SOCK_CLOEXEC) \
|
||||
&& defined(SOCK_NONBLOCK)
|
||||
#if defined(HAVE_ACCEPT4) && defined(SOCK_CLOEXEC) && defined(SOCK_NONBLOCK)
|
||||
int ext_flags = (cloexec ? SOCK_CLOEXEC : 0) |
|
||||
(nonblock ? SOCK_NONBLOCK : 0);
|
||||
s = accept4(sockfd, addr, len, ext_flags);
|
||||
|
@ -1293,7 +1328,7 @@ tor_accept_socket_with_extensions(tor_socket_t sockfd, struct sockaddr *addr,
|
|||
* we are missing SOCK_CLOEXEC/SOCK_NONBLOCK support. */
|
||||
if (errno != EINVAL && errno != ENOSYS)
|
||||
return s;
|
||||
#endif /* defined(HAVE_ACCEPT4) && defined(SOCK_CLOEXEC) ... */
|
||||
#endif
|
||||
|
||||
s = accept(sockfd, addr, len);
|
||||
if (!SOCKET_OK(s))
|
||||
|
@ -1307,9 +1342,9 @@ tor_accept_socket_with_extensions(tor_socket_t sockfd, struct sockaddr *addr,
|
|||
return TOR_INVALID_SOCKET;
|
||||
}
|
||||
}
|
||||
#else /* !(defined(FD_CLOEXEC)) */
|
||||
#else
|
||||
(void)cloexec;
|
||||
#endif /* defined(FD_CLOEXEC) */
|
||||
#endif
|
||||
|
||||
if (nonblock) {
|
||||
if (set_socket_nonblocking(s) == -1) {
|
||||
|
@ -1321,7 +1356,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 +1382,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.
|
||||
*/
|
||||
|
@ -1384,7 +1404,7 @@ set_socket_nonblocking(tor_socket_t sock)
|
|||
log_warn(LD_NET, "Couldn't set file status flags: %s", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
#endif /* defined(_WIN32) */
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1422,7 +1442,7 @@ tor_socketpair(int family, int type, int protocol, tor_socket_t fd[2])
|
|||
* are running on one without. */
|
||||
if (errno != EINVAL)
|
||||
return -errno;
|
||||
#endif /* defined(SOCK_CLOEXEC) */
|
||||
#endif
|
||||
|
||||
r = socketpair(family, type, protocol, fd);
|
||||
if (r < 0)
|
||||
|
@ -1445,7 +1465,7 @@ tor_socketpair(int family, int type, int protocol, tor_socket_t fd[2])
|
|||
return -errno;
|
||||
}
|
||||
}
|
||||
#endif /* defined(FD_CLOEXEC) */
|
||||
#endif
|
||||
goto sockets_ok; /* So that sockets_ok will not be unused. */
|
||||
|
||||
sockets_ok:
|
||||
|
@ -1461,9 +1481,9 @@ tor_socketpair(int family, int type, int protocol, tor_socket_t fd[2])
|
|||
socket_accounting_unlock();
|
||||
|
||||
return 0;
|
||||
#else /* !(defined(HAVE_SOCKETPAIR) && !defined(_WIN32)) */
|
||||
#else
|
||||
return tor_ersatz_socketpair(family, type, protocol, fd);
|
||||
#endif /* defined(HAVE_SOCKETPAIR) && !defined(_WIN32) */
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef NEED_ERSATZ_SOCKETPAIR
|
||||
|
@ -1620,7 +1640,7 @@ tor_ersatz_socketpair(int family, int type, int protocol, tor_socket_t fd[2])
|
|||
|
||||
#undef SIZEOF_SOCKADDR
|
||||
|
||||
#endif /* defined(NEED_ERSATZ_SOCKETPAIR) */
|
||||
#endif
|
||||
|
||||
/* Return the maximum number of allowed sockets. */
|
||||
int
|
||||
|
@ -1674,7 +1694,7 @@ set_max_file_descriptors(rlim_t limit, int *max_out)
|
|||
#else
|
||||
const char *platform = "unknown platforms with no getrlimit()";
|
||||
const unsigned long MAX_CONNECTIONS = 15000;
|
||||
#endif /* defined(CYGWIN) || defined(__CYGWIN__) || ... */
|
||||
#endif
|
||||
log_fn(LOG_INFO, LD_NET,
|
||||
"This platform is missing getrlimit(). Proceeding.");
|
||||
if (limit > MAX_CONNECTIONS) {
|
||||
|
@ -1685,7 +1705,7 @@ set_max_file_descriptors(rlim_t limit, int *max_out)
|
|||
return -1;
|
||||
}
|
||||
limit = MAX_CONNECTIONS;
|
||||
#else /* !(!defined(HAVE_GETRLIMIT)) */
|
||||
#else /* HAVE_GETRLIMIT */
|
||||
struct rlimit rlim;
|
||||
|
||||
if (getrlimit(RLIMIT_NOFILE, &rlim) != 0) {
|
||||
|
@ -1735,7 +1755,7 @@ set_max_file_descriptors(rlim_t limit, int *max_out)
|
|||
couldnt_set = 0;
|
||||
}
|
||||
}
|
||||
#endif /* defined(OPEN_MAX) */
|
||||
#endif /* OPEN_MAX */
|
||||
if (couldnt_set) {
|
||||
log_warn(LD_CONFIG,"Couldn't set maximum number of file descriptors: %s",
|
||||
strerror(setrlimit_errno));
|
||||
|
@ -1743,7 +1763,7 @@ set_max_file_descriptors(rlim_t limit, int *max_out)
|
|||
}
|
||||
/* leave some overhead for logs, etc, */
|
||||
limit = rlim.rlim_cur;
|
||||
#endif /* !defined(HAVE_GETRLIMIT) */
|
||||
#endif /* HAVE_GETRLIMIT */
|
||||
|
||||
if (limit > INT_MAX)
|
||||
limit = INT_MAX;
|
||||
|
@ -1781,7 +1801,7 @@ log_credential_status(void)
|
|||
"UID is %u (real), %u (effective), %u (saved)",
|
||||
(unsigned)ruid, (unsigned)euid, (unsigned)suid);
|
||||
}
|
||||
#else /* !(defined(HAVE_GETRESUID)) */
|
||||
#else
|
||||
/* getresuid is not present on MacOS X, so we can't get the saved (E)UID */
|
||||
ruid = getuid();
|
||||
euid = geteuid();
|
||||
|
@ -1790,7 +1810,7 @@ log_credential_status(void)
|
|||
log_fn(CREDENTIAL_LOG_LEVEL, LD_GENERAL,
|
||||
"UID is %u (real), %u (effective), unknown (saved)",
|
||||
(unsigned)ruid, (unsigned)euid);
|
||||
#endif /* defined(HAVE_GETRESUID) */
|
||||
#endif
|
||||
|
||||
/* log GIDs */
|
||||
#ifdef HAVE_GETRESGID
|
||||
|
@ -1802,7 +1822,7 @@ log_credential_status(void)
|
|||
"GID is %u (real), %u (effective), %u (saved)",
|
||||
(unsigned)rgid, (unsigned)egid, (unsigned)sgid);
|
||||
}
|
||||
#else /* !(defined(HAVE_GETRESGID)) */
|
||||
#else
|
||||
/* getresgid is not present on MacOS X, so we can't get the saved (E)GID */
|
||||
rgid = getgid();
|
||||
egid = getegid();
|
||||
|
@ -1810,7 +1830,7 @@ log_credential_status(void)
|
|||
log_fn(CREDENTIAL_LOG_LEVEL, LD_GENERAL,
|
||||
"GID is %u (real), %u (effective), unknown (saved)",
|
||||
(unsigned)rgid, (unsigned)egid);
|
||||
#endif /* defined(HAVE_GETRESGID) */
|
||||
#endif
|
||||
|
||||
/* log supplementary groups */
|
||||
sup_gids_size = 64;
|
||||
|
@ -1850,7 +1870,7 @@ log_credential_status(void)
|
|||
|
||||
return 0;
|
||||
}
|
||||
#endif /* !defined(_WIN32) */
|
||||
#endif
|
||||
|
||||
#ifndef _WIN32
|
||||
/** Cached struct from the last getpwname() call we did successfully. */
|
||||
|
@ -1875,12 +1895,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;
|
||||
|
@ -1953,7 +1970,7 @@ tor_getpwuid(uid_t uid)
|
|||
|
||||
return NULL;
|
||||
}
|
||||
#endif /* !defined(_WIN32) */
|
||||
#endif
|
||||
|
||||
/** Return true iff we were compiled with capability support, and capabilities
|
||||
* seem to work. **/
|
||||
|
@ -1966,9 +1983,9 @@ have_capability_support(void)
|
|||
return 0;
|
||||
cap_free(caps);
|
||||
return 1;
|
||||
#else /* !(defined(HAVE_LINUX_CAPABILITIES)) */
|
||||
#else
|
||||
return 0;
|
||||
#endif /* defined(HAVE_LINUX_CAPABILITIES) */
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef HAVE_LINUX_CAPABILITIES
|
||||
|
@ -2027,7 +2044,7 @@ drop_capabilities(int pre_setuid)
|
|||
|
||||
return 0;
|
||||
}
|
||||
#endif /* defined(HAVE_LINUX_CAPABILITIES) */
|
||||
#endif
|
||||
|
||||
/** Call setuid and setgid to run as <b>user</b> and switch to their
|
||||
* primary group. Return 0 on success. On failure, log and return -1.
|
||||
|
@ -2077,13 +2094,13 @@ switch_id(const char *user, const unsigned flags)
|
|||
if (drop_capabilities(1))
|
||||
return -1;
|
||||
}
|
||||
#else /* !(defined(HAVE_LINUX_CAPABILITIES)) */
|
||||
#else
|
||||
(void) keep_bindlow;
|
||||
if (warn_if_no_caps) {
|
||||
log_warn(LD_CONFIG, "KeepBindCapabilities set, but no capability support "
|
||||
"on this system.");
|
||||
}
|
||||
#endif /* defined(HAVE_LINUX_CAPABILITIES) */
|
||||
#endif
|
||||
|
||||
/* Properly switch egid,gid,euid,uid here or bail out */
|
||||
if (setgroups(1, &pw->pw_gid)) {
|
||||
|
@ -2143,7 +2160,7 @@ switch_id(const char *user, const unsigned flags)
|
|||
if (drop_capabilities(0))
|
||||
return -1;
|
||||
}
|
||||
#endif /* defined(HAVE_LINUX_CAPABILITIES) */
|
||||
#endif
|
||||
|
||||
#if !defined(CYGWIN) && !defined(__CYGWIN__)
|
||||
/* If we tried to drop privilege to a group/user other than root, attempt to
|
||||
|
@ -2167,7 +2184,7 @@ switch_id(const char *user, const unsigned flags)
|
|||
return -1;
|
||||
}
|
||||
}
|
||||
#endif /* !defined(CYGWIN) && !defined(__CYGWIN__) */
|
||||
#endif
|
||||
|
||||
/* Check what really happened */
|
||||
if (log_credential_status()) {
|
||||
|
@ -2176,8 +2193,8 @@ switch_id(const char *user, const unsigned flags)
|
|||
|
||||
have_already_switched_id = 1; /* mark success so we never try again */
|
||||
|
||||
#if defined(__linux__) && defined(HAVE_SYS_PRCTL_H) && \
|
||||
defined(HAVE_PRCTL) && defined(PR_SET_DUMPABLE)
|
||||
#if defined(__linux__) && defined(HAVE_SYS_PRCTL_H) && defined(HAVE_PRCTL)
|
||||
#ifdef PR_SET_DUMPABLE
|
||||
if (pw->pw_uid) {
|
||||
/* Re-enable core dumps if we're not running as root. */
|
||||
log_info(LD_CONFIG, "Re-enabling coredumps");
|
||||
|
@ -2185,16 +2202,17 @@ switch_id(const char *user, const unsigned flags)
|
|||
log_warn(LD_CONFIG, "Unable to re-enable coredumps: %s",strerror(errno));
|
||||
}
|
||||
}
|
||||
#endif /* defined(__linux__) && defined(HAVE_SYS_PRCTL_H) && ... */
|
||||
#endif
|
||||
#endif
|
||||
return 0;
|
||||
|
||||
#else /* !(!defined(_WIN32)) */
|
||||
#else
|
||||
(void)user;
|
||||
(void)flags;
|
||||
|
||||
log_warn(LD_CONFIG, "Switching users is unsupported on your OS.");
|
||||
return -1;
|
||||
#endif /* !defined(_WIN32) */
|
||||
#endif
|
||||
}
|
||||
|
||||
/* We only use the linux prctl for now. There is no Win32 support; this may
|
||||
|
@ -2217,32 +2235,35 @@ switch_id(const char *user, const unsigned flags)
|
|||
int
|
||||
tor_disable_debugger_attach(void)
|
||||
{
|
||||
int r = -1;
|
||||
int r, attempted;
|
||||
r = -1;
|
||||
attempted = 0;
|
||||
log_debug(LD_CONFIG,
|
||||
"Attemping to disable debugger attachment to Tor for "
|
||||
"unprivileged users.");
|
||||
#if defined(__linux__) && defined(HAVE_SYS_PRCTL_H) \
|
||||
&& defined(HAVE_PRCTL) && defined(PR_SET_DUMPABLE)
|
||||
#define TRIED_TO_DISABLE
|
||||
#if defined(__linux__) && defined(HAVE_SYS_PRCTL_H) && defined(HAVE_PRCTL)
|
||||
#ifdef PR_SET_DUMPABLE
|
||||
attempted = 1;
|
||||
r = prctl(PR_SET_DUMPABLE, 0);
|
||||
#elif defined(__APPLE__) && defined(PT_DENY_ATTACH)
|
||||
#define TRIED_TO_ATTACH
|
||||
r = ptrace(PT_DENY_ATTACH, 0, 0, 0);
|
||||
#endif /* defined(__linux__) && defined(HAVE_SYS_PRCTL_H) ... || ... */
|
||||
#endif
|
||||
#endif
|
||||
#if defined(__APPLE__) && defined(PT_DENY_ATTACH)
|
||||
if (r < 0) {
|
||||
attempted = 1;
|
||||
r = ptrace(PT_DENY_ATTACH, 0, 0, 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
// XXX: TODO - Mac OS X has dtrace and this may be disabled.
|
||||
// XXX: TODO - Windows probably has something similar
|
||||
#ifdef TRIED_TO_DISABLE
|
||||
if (r == 0) {
|
||||
if (r == 0 && attempted) {
|
||||
log_debug(LD_CONFIG,"Debugger attachment disabled for "
|
||||
"unprivileged users.");
|
||||
return 1;
|
||||
} else {
|
||||
} else if (attempted) {
|
||||
log_warn(LD_CONFIG, "Unable to disable debugger attaching: %s",
|
||||
strerror(errno));
|
||||
}
|
||||
#endif /* defined(TRIED_TO_DISABLE) */
|
||||
#undef TRIED_TO_DISABLE
|
||||
return r;
|
||||
}
|
||||
|
||||
|
@ -2261,7 +2282,7 @@ get_user_homedir(const char *username)
|
|||
}
|
||||
return tor_strdup(pw->pw_dir);
|
||||
}
|
||||
#endif /* defined(HAVE_PWD_H) */
|
||||
#endif
|
||||
|
||||
/** Modify <b>fname</b> to contain the name of its parent directory. Doesn't
|
||||
* actually examine the filesystem; does a purely syntactic modification.
|
||||
|
@ -2289,7 +2310,7 @@ get_parent_directory(char *fname)
|
|||
if (fname[0] && fname[1] == ':') {
|
||||
fname += 2;
|
||||
}
|
||||
#endif /* defined(_WIN32) */
|
||||
#endif
|
||||
/* Now we want to remove all path-separators at the end of the string,
|
||||
* and to remove the end of the string starting with the path separator
|
||||
* before the last non-path-separator. In perl, this would be
|
||||
|
@ -2328,36 +2349,17 @@ get_parent_directory(char *fname)
|
|||
static char *
|
||||
alloc_getcwd(void)
|
||||
{
|
||||
#ifdef HAVE_GET_CURRENT_DIR_NAME
|
||||
/* Glibc makes this nice and simple for us. */
|
||||
char *cwd = get_current_dir_name();
|
||||
char *result = NULL;
|
||||
if (cwd) {
|
||||
/* We make a copy here, in case tor_malloc() is not malloc(). */
|
||||
result = tor_strdup(cwd);
|
||||
raw_free(cwd); // alias for free to avoid tripping check-spaces.
|
||||
}
|
||||
return result;
|
||||
#else /* !(defined(HAVE_GET_CURRENT_DIR_NAME)) */
|
||||
size_t size = 1024;
|
||||
char *buf = NULL;
|
||||
char *ptr = NULL;
|
||||
#ifdef PATH_MAX
|
||||
#define MAX_CWD PATH_MAX
|
||||
#else
|
||||
#define MAX_CWD 4096
|
||||
#endif
|
||||
|
||||
while (ptr == NULL) {
|
||||
buf = tor_realloc(buf, size);
|
||||
ptr = getcwd(buf, size);
|
||||
|
||||
if (ptr == NULL && errno != ERANGE) {
|
||||
tor_free(buf);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
size *= 2;
|
||||
}
|
||||
return buf;
|
||||
#endif /* defined(HAVE_GET_CURRENT_DIR_NAME) */
|
||||
char path_buf[MAX_CWD];
|
||||
char *path = getcwd(path_buf, sizeof(path_buf));
|
||||
return path ? tor_strdup(path) : NULL;
|
||||
}
|
||||
#endif /* !defined(_WIN32) */
|
||||
#endif
|
||||
|
||||
/** Expand possibly relative path <b>fname</b> to an absolute path.
|
||||
* Return a newly allocated string, possibly equal to <b>fname</b>. */
|
||||
|
@ -2373,7 +2375,7 @@ make_path_absolute(char *fname)
|
|||
if (absfname_malloced) raw_free(absfname_malloced);
|
||||
|
||||
return absfname;
|
||||
#else /* !(defined(_WIN32)) */
|
||||
#else
|
||||
char *absfname = NULL, *path = NULL;
|
||||
|
||||
tor_assert(fname);
|
||||
|
@ -2396,7 +2398,7 @@ make_path_absolute(char *fname)
|
|||
}
|
||||
}
|
||||
return absfname;
|
||||
#endif /* defined(_WIN32) */
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifndef HAVE__NSGETENVIRON
|
||||
|
@ -2405,8 +2407,8 @@ make_path_absolute(char *fname)
|
|||
#ifndef RUNNING_DOXYGEN
|
||||
extern char **environ;
|
||||
#endif
|
||||
#endif /* !defined(HAVE_EXTERN_ENVIRON_DECLARED) */
|
||||
#endif /* !defined(HAVE__NSGETENVIRON) */
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/** Return the current environment. This is a portable replacement for
|
||||
* 'environ'. */
|
||||
|
@ -2418,14 +2420,14 @@ get_environment(void)
|
|||
* when we do a mostly-static build on OSX 10.7, the resulting binary won't
|
||||
* work on OSX 10.6. */
|
||||
return *_NSGetEnviron();
|
||||
#else /* !(defined(HAVE__NSGETENVIRON)) */
|
||||
#else
|
||||
return environ;
|
||||
#endif /* defined(HAVE__NSGETENVIRON) */
|
||||
#endif
|
||||
}
|
||||
|
||||
/** 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,
|
||||
|
@ -2561,7 +2563,6 @@ tor_inet_pton(int af, const char *src, void *dst)
|
|||
int gapPos = -1, i, setWords=0;
|
||||
const char *dot = strchr(src, '.');
|
||||
const char *eow; /* end of words. */
|
||||
memset(words, 0xf8, sizeof(words));
|
||||
if (dot == src)
|
||||
return 0;
|
||||
else if (!dot)
|
||||
|
@ -2599,7 +2600,7 @@ tor_inet_pton(int af, const char *src, void *dst)
|
|||
long r = strtol(src, &next, 16);
|
||||
if (next == NULL || next == src) {
|
||||
/* The 'next == src' error case can happen on versions of openbsd
|
||||
* which treat "0xfoo" as an error, rather than as "0" followed by
|
||||
* where treats "0xfoo" as an error, rather than as "0" followed by
|
||||
* "xfoo". */
|
||||
return 0;
|
||||
}
|
||||
|
@ -2698,7 +2699,7 @@ get_uname,(void))
|
|||
/* (Linux says 0 is success, Solaris says 1 is success) */
|
||||
strlcpy(uname_result, u.sysname, sizeof(uname_result));
|
||||
} else
|
||||
#endif /* defined(HAVE_UNAME) */
|
||||
#endif
|
||||
{
|
||||
#ifdef _WIN32
|
||||
OSVERSIONINFOEX info;
|
||||
|
@ -2760,12 +2761,12 @@ get_uname,(void))
|
|||
info.wProductType == VER_NT_DOMAIN_CONTROLLER) {
|
||||
strlcat(uname_result, " [server]", sizeof(uname_result));
|
||||
}
|
||||
#endif /* defined(VER_NT_SERVER) */
|
||||
#else /* !(defined(_WIN32)) */
|
||||
#endif
|
||||
#else
|
||||
/* LCOV_EXCL_START -- can't provoke uname failure */
|
||||
strlcpy(uname_result, "Unknown platform", sizeof(uname_result));
|
||||
/* LCOV_EXCL_STOP */
|
||||
#endif /* defined(_WIN32) */
|
||||
#endif
|
||||
}
|
||||
uname_result_is_set = 1;
|
||||
}
|
||||
|
@ -2821,7 +2822,7 @@ compute_num_cpus_impl(void)
|
|||
return -1;
|
||||
#else
|
||||
return -1;
|
||||
#endif /* defined(_WIN32) || ... */
|
||||
#endif
|
||||
}
|
||||
|
||||
#define MAX_DETECTABLE_CPUS 16
|
||||
|
@ -2860,7 +2861,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 *
|
||||
|
@ -2984,7 +2985,7 @@ tor_localtime_r(const time_t *timep, struct tm *result)
|
|||
memcpy(result, r, sizeof(struct tm));
|
||||
return correct_tm(1, timep, result, r);
|
||||
}
|
||||
#endif /* defined(HAVE_LOCALTIME_R) || ... */
|
||||
#endif
|
||||
/** @} */
|
||||
|
||||
/** @{ */
|
||||
|
@ -3027,13 +3028,9 @@ tor_gmtime_r(const time_t *timep, struct tm *result)
|
|||
memcpy(result, r, sizeof(struct tm));
|
||||
return correct_tm(0, timep, result, r);
|
||||
}
|
||||
#endif /* defined(HAVE_GMTIME_R) || ... */
|
||||
|
||||
#if defined(HAVE_MLOCKALL) && HAVE_DECL_MLOCKALL && defined(RLIMIT_MEMLOCK)
|
||||
#define HAVE_UNIX_MLOCKALL
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_UNIX_MLOCKALL
|
||||
#if defined(HAVE_MLOCKALL) && HAVE_DECL_MLOCKALL && defined(RLIMIT_MEMLOCK)
|
||||
/** Attempt to raise the current and max rlimit to infinity for our process.
|
||||
* This only needs to be done once and can probably only be done when we have
|
||||
* not already dropped privileges.
|
||||
|
@ -3064,7 +3061,7 @@ tor_set_max_memlock(void)
|
|||
|
||||
return 0;
|
||||
}
|
||||
#endif /* defined(HAVE_UNIX_MLOCKALL) */
|
||||
#endif
|
||||
|
||||
/** Attempt to lock all current and all future memory pages.
|
||||
* This should only be called once and while we're privileged.
|
||||
|
@ -3089,7 +3086,7 @@ tor_mlockall(void)
|
|||
* http://msdn.microsoft.com/en-us/library/aa366895(VS.85).aspx
|
||||
*/
|
||||
|
||||
#ifdef HAVE_UNIX_MLOCKALL
|
||||
#if defined(HAVE_MLOCKALL) && HAVE_DECL_MLOCKALL && defined(RLIMIT_MEMLOCK)
|
||||
if (tor_set_max_memlock() == 0) {
|
||||
log_debug(LD_GENERAL, "RLIMIT_MEMLOCK is now set to RLIM_INFINITY.");
|
||||
}
|
||||
|
@ -3110,10 +3107,10 @@ tor_mlockall(void)
|
|||
"pages: %s", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
#else /* !(defined(HAVE_UNIX_MLOCKALL)) */
|
||||
#else
|
||||
log_warn(LD_GENERAL, "Unable to lock memory pages. mlockall() unsupported?");
|
||||
return -1;
|
||||
#endif /* defined(HAVE_UNIX_MLOCKALL) */
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -3141,7 +3138,7 @@ tor_socket_errno(tor_socket_t sock)
|
|||
}
|
||||
return err;
|
||||
}
|
||||
#endif /* defined(_WIN32) */
|
||||
#endif
|
||||
|
||||
#if defined(_WIN32)
|
||||
#define E(code, s) { code, (s " [" #code " ]") }
|
||||
|
@ -3217,7 +3214,7 @@ tor_socket_strerror(int e)
|
|||
}
|
||||
return strerror(e);
|
||||
}
|
||||
#endif /* defined(_WIN32) */
|
||||
#endif
|
||||
|
||||
/** Called before we make any calls to network-related functions.
|
||||
* (Some operating systems require their network libraries to be
|
||||
|
@ -3243,7 +3240,7 @@ network_init(void)
|
|||
/* WSAData.iMaxSockets might show the max sockets we're allowed to use.
|
||||
* We might use it to complain if we're trying to be a server but have
|
||||
* too few sockets available. */
|
||||
#endif /* defined(_WIN32) */
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -3279,9 +3276,9 @@ format_win32_error(DWORD err)
|
|||
result = tor_malloc(len);
|
||||
wcstombs(result,str,len);
|
||||
result[len-1] = '\0';
|
||||
#else /* !(defined(UNICODE)) */
|
||||
#else
|
||||
result = tor_strdup(str);
|
||||
#endif /* defined(UNICODE) */
|
||||
#endif
|
||||
} else {
|
||||
result = tor_strdup("<unformattable error>");
|
||||
}
|
||||
|
@ -3290,7 +3287,7 @@ format_win32_error(DWORD err)
|
|||
}
|
||||
return result;
|
||||
}
|
||||
#endif /* defined(_WIN32) */
|
||||
#endif
|
||||
|
||||
#if defined(HW_PHYSMEM64)
|
||||
/* This appears to be an OpenBSD thing */
|
||||
|
@ -3298,7 +3295,7 @@ format_win32_error(DWORD err)
|
|||
#elif defined(HW_MEMSIZE)
|
||||
/* OSX defines this one */
|
||||
#define INT64_HW_MEM HW_MEMSIZE
|
||||
#endif /* defined(HW_PHYSMEM64) || ... */
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Helper: try to detect the total system memory, and return it. On failure,
|
||||
|
@ -3331,8 +3328,8 @@ get_total_system_memory_impl(void)
|
|||
tor_free(s);
|
||||
return result * 1024;
|
||||
|
||||
/* LCOV_EXCL_START Can't reach this unless proc is broken. */
|
||||
err:
|
||||
/* LCOV_EXCL_START Can't reach this unless proc is broken. */
|
||||
tor_free(s);
|
||||
close(fd);
|
||||
return 0;
|
||||
|
@ -3372,15 +3369,15 @@ get_total_system_memory_impl(void)
|
|||
#else
|
||||
/* I have no clue. */
|
||||
return 0;
|
||||
#endif /* defined(__linux__) || ... */
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* 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();
|
||||
|
@ -3405,7 +3402,7 @@ get_total_system_memory, (size_t *mem_out))
|
|||
* size_t. */
|
||||
m = SIZE_MAX;
|
||||
}
|
||||
#endif /* SIZE_MAX != UINT64_MAX */
|
||||
#endif
|
||||
|
||||
*mem_out = mem_cached = (size_t) m;
|
||||
|
||||
|
@ -3486,7 +3483,7 @@ tor_getpass(const char *prompt, char *output, size_t buflen)
|
|||
return r;
|
||||
#else
|
||||
#error "No implementation for tor_getpass found!"
|
||||
#endif /* defined(HAVE_READPASSPHRASE) || ... */
|
||||
#endif
|
||||
}
|
||||
|
||||
/** Return the amount of free disk space we have permission to use, in
|
||||
|
@ -3526,6 +3523,6 @@ tor_get_avail_disk_space(const char *path)
|
|||
(void)path;
|
||||
errno = ENOSYS;
|
||||
return -1;
|
||||
#endif /* defined(HAVE_STATVFS) || ... */
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
@ -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"
|
||||
|
@ -53,8 +50,8 @@
|
|||
* clang rejects because it is off the end of a less-than-3. Clang hates this,
|
||||
* even though those references never actually happen. */
|
||||
# undef strcmp
|
||||
#endif /* __has_feature(address_sanitizer) */
|
||||
#endif /* defined(__has_feature) */
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
|
@ -79,13 +76,13 @@
|
|||
__attribute__ ((format(printf, formatIdx, firstArg)))
|
||||
#else
|
||||
#define CHECK_PRINTF(formatIdx, firstArg)
|
||||
#endif /* defined(__GNUC__) */
|
||||
#endif
|
||||
#ifdef __GNUC__
|
||||
#define CHECK_SCANF(formatIdx, firstArg) \
|
||||
__attribute__ ((format(scanf, formatIdx, firstArg)))
|
||||
#else
|
||||
#define CHECK_SCANF(formatIdx, firstArg)
|
||||
#endif /* defined(__GNUC__) */
|
||||
#endif
|
||||
|
||||
/* What GCC do we have? */
|
||||
#ifdef __GNUC__
|
||||
|
@ -112,18 +109,18 @@
|
|||
PRAGMA_DIAGNOSTIC_(ignored PRAGMA_JOIN_STRINGIFY_(-W,warningopt))
|
||||
# define ENABLE_GCC_WARNING(warningopt) \
|
||||
PRAGMA_DIAGNOSTIC_(pop)
|
||||
#else /* !(defined(__clang__) || GCC_VERSION >= 406) */
|
||||
# else
|
||||
/* older version of gcc: no push/pop support. */
|
||||
# define DISABLE_GCC_WARNING(warningopt) \
|
||||
PRAGMA_DIAGNOSTIC_(ignored PRAGMA_JOIN_STRINGIFY_(-W,warningopt))
|
||||
# define ENABLE_GCC_WARNING(warningopt) \
|
||||
PRAGMA_DIAGNOSTIC_(warning PRAGMA_JOIN_STRINGIFY_(-W,warningopt))
|
||||
#endif /* defined(__clang__) || GCC_VERSION >= 406 */
|
||||
#else /* !(defined(__GNUC__)) */
|
||||
# endif
|
||||
#else /* ifdef __GNUC__ */
|
||||
/* not gcc at all */
|
||||
# define DISABLE_GCC_WARNING(warning)
|
||||
# define ENABLE_GCC_WARNING(warning)
|
||||
#endif /* defined(__GNUC__) */
|
||||
#endif
|
||||
|
||||
/* inline is __inline on windows. */
|
||||
#ifdef _WIN32
|
||||
|
@ -145,9 +142,9 @@
|
|||
#define __func__ __FUNC__
|
||||
#else
|
||||
#define __func__ "???"
|
||||
#endif /* defined(HAVE_MACRO__FUNCTION__) || ... */
|
||||
#endif /* !defined(HAVE_MACRO__func__) */
|
||||
#endif /* defined(_MSC_VER) */
|
||||
#endif
|
||||
#endif /* ifndef MAVE_MACRO__func__ */
|
||||
#endif /* if not windows */
|
||||
|
||||
#define U64_TO_DBL(x) ((double) (x))
|
||||
#define DBL_TO_U64(x) ((uint64_t) (x))
|
||||
|
@ -160,7 +157,7 @@
|
|||
* problems), but if enumerated types are unsigned, we must use unsigned,
|
||||
* so that the loss of precision doesn't make large values negative. */
|
||||
#define ENUM_BF(t) t
|
||||
#endif /* defined(ENUM_VALS_ARE_SIGNED) */
|
||||
#endif
|
||||
|
||||
/* GCC has several useful attributes. */
|
||||
#if defined(__GNUC__) && __GNUC__ >= 3
|
||||
|
@ -197,7 +194,7 @@
|
|||
* taken. This can generate slightly better code with some CPUs.
|
||||
*/
|
||||
#define PREDICT_UNLIKELY(exp) __builtin_expect(!!(exp), 0)
|
||||
#else /* !(defined(__GNUC__) && __GNUC__ >= 3) */
|
||||
#else
|
||||
#define ATTR_NORETURN
|
||||
#define ATTR_CONST
|
||||
#define ATTR_MALLOC
|
||||
|
@ -207,7 +204,7 @@
|
|||
#define ATTR_WUR
|
||||
#define PREDICT_LIKELY(exp) (exp)
|
||||
#define PREDICT_UNLIKELY(exp) (exp)
|
||||
#endif /* defined(__GNUC__) && __GNUC__ >= 3 */
|
||||
#endif
|
||||
|
||||
/** Expands to a syntactically valid empty statement. */
|
||||
#define STMT_NIL (void)0
|
||||
|
@ -227,7 +224,7 @@
|
|||
#else
|
||||
#define STMT_BEGIN do {
|
||||
#define STMT_END } while (0)
|
||||
#endif /* defined(__GNUC__) || ... */
|
||||
#endif
|
||||
|
||||
/* Some tools (like coccinelle) don't like to see operators as macro
|
||||
* arguments. */
|
||||
|
@ -254,7 +251,7 @@
|
|||
*/
|
||||
#undef strlcat
|
||||
#undef strlcpy
|
||||
#endif /* defined __APPLE__ */
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_STRLCAT
|
||||
size_t strlcat(char *dst, const char *src, size_t siz) ATTR_NONNULL((1,2));
|
||||
|
@ -275,28 +272,24 @@ size_t strlcpy(char *dst, const char *src, size_t siz) ATTR_NONNULL((1,2));
|
|||
#define I64_PRINTF_ARG(a) (a)
|
||||
#define I64_SCANF_ARG(a) (a)
|
||||
#define I64_LITERAL(n) (n ## i64)
|
||||
#else /* !(defined(_MSC_VER)) */
|
||||
#else
|
||||
#define U64_PRINTF_ARG(a) ((long long unsigned int)(a))
|
||||
#define U64_SCANF_ARG(a) ((long long unsigned int*)(a))
|
||||
#define U64_LITERAL(n) (n ## llu)
|
||||
#define I64_PRINTF_ARG(a) ((long long signed int)(a))
|
||||
#define I64_SCANF_ARG(a) ((long long signed int*)(a))
|
||||
#define I64_LITERAL(n) (n ## ll)
|
||||
#endif /* defined(_MSC_VER) */
|
||||
|
||||
#if defined(__MINGW32__) || defined(__MINGW64__)
|
||||
#define MINGW_ANY
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER) || defined(MINGW_ANY)
|
||||
#if defined(_MSC_VER) || defined(__MINGW32__) || defined(__MINGW64__)
|
||||
/** The formatting string used to put a uint64_t value in a printf() or
|
||||
* scanf() function. See also U64_PRINTF_ARG and U64_SCANF_ARG. */
|
||||
#define U64_FORMAT "%I64u"
|
||||
#define I64_FORMAT "%I64d"
|
||||
#else /* !(defined(_MSC_VER) || defined(MINGW_ANY)) */
|
||||
#else
|
||||
#define U64_FORMAT "%llu"
|
||||
#define I64_FORMAT "%lld"
|
||||
#endif /* defined(_MSC_VER) || defined(MINGW_ANY) */
|
||||
#endif
|
||||
|
||||
#if (SIZEOF_INTPTR_T == SIZEOF_INT)
|
||||
#define INTPTR_T_FORMAT "%d"
|
||||
|
@ -309,7 +302,7 @@ size_t strlcpy(char *dst, const char *src, size_t siz) ATTR_NONNULL((1,2));
|
|||
#define INTPTR_PRINTF_ARG(x) I64_PRINTF_ARG(x)
|
||||
#else
|
||||
#error Unknown: SIZEOF_INTPTR_T
|
||||
#endif /* (SIZEOF_INTPTR_T == SIZEOF_INT) || ... */
|
||||
#endif
|
||||
|
||||
/** Represents an mmaped file. Allocated via tor_mmap_file; freed with
|
||||
* tor_munmap_file. */
|
||||
|
@ -318,12 +311,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
|
||||
|
||||
} tor_mmap_t;
|
||||
|
||||
|
@ -385,7 +378,7 @@ const char *tor_fix_source_file(const char *fname);
|
|||
#else
|
||||
#define SHORT_FILE__ (__FILE__)
|
||||
#define tor_fix_source_file(s) (s)
|
||||
#endif /* defined(_WIN32) */
|
||||
#endif
|
||||
|
||||
/* ===== Time compatibility */
|
||||
|
||||
|
@ -404,7 +397,7 @@ struct tm *tor_gmtime_r(const time_t *timep, struct tm *result);
|
|||
(tvout)->tv_sec++; \
|
||||
} \
|
||||
} while (0)
|
||||
#endif /* !defined(timeradd) */
|
||||
#endif
|
||||
|
||||
#ifndef timersub
|
||||
/** Replacement for timersub on platforms that do not have it: sets tvout to
|
||||
|
@ -418,7 +411,7 @@ struct tm *tor_gmtime_r(const time_t *timep, struct tm *result);
|
|||
(tvout)->tv_sec--; \
|
||||
} \
|
||||
} while (0)
|
||||
#endif /* !defined(timersub) */
|
||||
#endif
|
||||
|
||||
#ifndef timercmp
|
||||
/** Replacement for timercmp on platforms that do not have it: returns true
|
||||
|
@ -432,7 +425,7 @@ struct tm *tor_gmtime_r(const time_t *timep, struct tm *result);
|
|||
(((tv1)->tv_sec == (tv2)->tv_sec) ? \
|
||||
((tv1)->tv_usec op (tv2)->tv_usec) : \
|
||||
((tv1)->tv_sec op (tv2)->tv_sec))
|
||||
#endif /* !defined(timercmp) */
|
||||
#endif
|
||||
|
||||
/* ===== File compatibility */
|
||||
int tor_open_cloexec(const char *path, int flags, unsigned mode);
|
||||
|
@ -474,7 +467,7 @@ typedef int socklen_t;
|
|||
#define TOR_SOCKET_T_FORMAT INTPTR_T_FORMAT
|
||||
#define SOCKET_OK(s) ((SOCKET)(s) != INVALID_SOCKET)
|
||||
#define TOR_INVALID_SOCKET INVALID_SOCKET
|
||||
#else /* !(defined(_WIN32)) */
|
||||
#else
|
||||
/** Type used for a network socket. */
|
||||
#define tor_socket_t int
|
||||
#define TOR_SOCKET_T_FORMAT "%d"
|
||||
|
@ -482,11 +475,10 @@ typedef int socklen_t;
|
|||
#define SOCKET_OK(s) ((s) >= 0)
|
||||
/** Error/uninitialized value for a tor_socket_t. */
|
||||
#define TOR_INVALID_SOCKET (-1)
|
||||
#endif /* defined(_WIN32) */
|
||||
#endif
|
||||
|
||||
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 +502,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)
|
||||
|
@ -532,19 +522,19 @@ struct in6_addr
|
|||
#define s6_addr16 in6_u.u6_addr16
|
||||
#define s6_addr32 in6_u.u6_addr32
|
||||
};
|
||||
#endif /* !defined(HAVE_STRUCT_IN6_ADDR) */
|
||||
#endif
|
||||
|
||||
/** @{ */
|
||||
/** Many BSD variants seem not to define these. */
|
||||
#if defined(__APPLE__) || defined(__darwin__) || \
|
||||
defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)
|
||||
#if defined(__APPLE__) || defined(__darwin__) || defined(__FreeBSD__) \
|
||||
|| defined(__NetBSD__) || defined(__OpenBSD__)
|
||||
#ifndef s6_addr16
|
||||
#define s6_addr16 __u6_addr.__u6_addr16
|
||||
#endif
|
||||
#ifndef s6_addr32
|
||||
#define s6_addr32 __u6_addr.__u6_addr32
|
||||
#endif
|
||||
#endif /* defined(__APPLE__) || defined(__darwin__) || ... */
|
||||
#endif
|
||||
/** @} */
|
||||
|
||||
#ifndef HAVE_SA_FAMILY_T
|
||||
|
@ -576,7 +566,7 @@ struct sockaddr_in6 {
|
|||
struct in6_addr sin6_addr;
|
||||
// uint32_t sin6_scope_id;
|
||||
};
|
||||
#endif /* !defined(HAVE_STRUCT_SOCKADDR_IN6) */
|
||||
#endif
|
||||
|
||||
MOCK_DECL(int,tor_gethostname,(char *name, size_t namelen));
|
||||
int tor_inet_aton(const char *cp, struct in_addr *addr) ATTR_NONNULL((1,2));
|
||||
|
@ -617,14 +607,14 @@ int network_init(void);
|
|||
#define ERRNO_IS_EINTR(e) ((e) == WSAEINTR || 0)
|
||||
int tor_socket_errno(tor_socket_t sock);
|
||||
const char *tor_socket_strerror(int e);
|
||||
#else /* !(defined(_WIN32)) */
|
||||
#else
|
||||
#define SOCK_ERRNO(e) e
|
||||
#if EAGAIN == EWOULDBLOCK
|
||||
/* || 0 is for -Wparentheses-equality (-Wall?) appeasement under clang */
|
||||
#define ERRNO_IS_EAGAIN(e) ((e) == EAGAIN || 0)
|
||||
#else
|
||||
#define ERRNO_IS_EAGAIN(e) ((e) == EAGAIN || (e) == EWOULDBLOCK)
|
||||
#endif /* EAGAIN == EWOULDBLOCK */
|
||||
#endif
|
||||
#define ERRNO_IS_EINTR(e) ((e) == EINTR || 0)
|
||||
#define ERRNO_IS_EINPROGRESS(e) ((e) == EINPROGRESS || 0)
|
||||
#define ERRNO_IS_CONN_EINPROGRESS(e) ((e) == EINPROGRESS || 0)
|
||||
|
@ -635,7 +625,7 @@ const char *tor_socket_strerror(int e);
|
|||
#define ERRNO_IS_EADDRINUSE(e) (((e) == EADDRINUSE) || 0)
|
||||
#define tor_socket_errno(sock) (errno)
|
||||
#define tor_socket_strerror(e) strerror(e)
|
||||
#endif /* defined(_WIN32) */
|
||||
#endif
|
||||
|
||||
/** Specified SOCKS5 status codes. */
|
||||
typedef enum {
|
||||
|
@ -701,7 +691,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);
|
||||
|
||||
|
@ -738,7 +728,7 @@ char *format_win32_error(DWORD err);
|
|||
#define VER_SUITE_SINGLEUSERTS 0x00000100
|
||||
#endif
|
||||
|
||||
#endif /* defined(_WIN32) */
|
||||
#endif
|
||||
|
||||
#ifdef COMPAT_PRIVATE
|
||||
#if !defined(HAVE_SOCKETPAIR) || defined(_WIN32) || defined(TOR_UNIT_TESTS)
|
||||
|
@ -746,12 +736,12 @@ char *format_win32_error(DWORD err);
|
|||
STATIC int tor_ersatz_socketpair(int family, int type, int protocol,
|
||||
tor_socket_t fd[2]);
|
||||
#endif
|
||||
#endif /* defined(COMPAT_PRIVATE) */
|
||||
#endif
|
||||
|
||||
ssize_t tor_getpass(const char *prompt, char *output, size_t buflen);
|
||||
|
||||
/* This needs some of the declarations above so we include it here. */
|
||||
#include "compat_threads.h"
|
||||
|
||||
#endif /* !defined(TOR_COMPAT_H) */
|
||||
#endif
|
||||
|
||||
|
|
|
@ -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). */
|
||||
|
@ -125,8 +88,8 @@ rescan_mainloop_cb(evutil_socket_t fd, short events, void *arg)
|
|||
(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 1040)
|
||||
#else
|
||||
#define MACOSX_KQUEUE_IS_BROKEN 0
|
||||
#endif /* defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) */
|
||||
#endif /* defined(__APPLE__) */
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/** Initialize the Libevent library and set up the event base. */
|
||||
void
|
||||
|
@ -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,50 @@ 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
|
||||
/** 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
|
||||
|
@ -532,5 +289,6 @@ tor_libevent_postfork(void)
|
|||
int r = event_reinit(tor_libevent_get_base());
|
||||
tor_assert(r == 0);
|
||||
}
|
||||
#endif /* defined(TOR_UNIT_TESTS) */
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
@ -92,7 +70,7 @@ void tor_libevent_exit_loop_after_callback(struct event_base *base);
|
|||
|
||||
STATIC void
|
||||
libevent_logging_callback(int severity, const char *msg);
|
||||
#endif /* defined(COMPAT_LIBEVENT_PRIVATE) */
|
||||
#endif
|
||||
|
||||
#endif /* !defined(TOR_COMPAT_LIBEVENT_H) */
|
||||
#endif
|
||||
|
||||
|
|
|
@ -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) && \
|
||||
|
@ -26,13 +25,10 @@
|
|||
/* We define this macro if we're trying to build with the majorly refactored
|
||||
* API in OpenSSL 1.1 */
|
||||
#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()
|
||||
|
@ -41,11 +37,11 @@
|
|||
((st) == SSL3_ST_SW_SRVR_HELLO_B))
|
||||
#define OSSL_HANDSHAKE_STATE int
|
||||
#define CONST_IF_OPENSSL_1_1_API
|
||||
#else /* !(!defined(OPENSSL_1_1_API)) */
|
||||
#else
|
||||
#define STATE_IS_SW_SERVER_HELLO(st) \
|
||||
((st) == TLS_ST_SW_SRVR_HELLO)
|
||||
#define CONST_IF_OPENSSL_1_1_API const
|
||||
#endif /* !defined(OPENSSL_1_1_API) */
|
||||
#endif
|
||||
|
||||
#endif /* !defined(TOR_COMPAT_OPENSSL_H) */
|
||||
#endif
|
||||
|
||||
|
|
|
@ -201,21 +201,20 @@ tor_cond_init(tor_cond_t *cond)
|
|||
}
|
||||
|
||||
#if defined(HAVE_CLOCK_GETTIME)
|
||||
#if defined(HAVE_PTHREAD_CONDATTR_SETCLOCK) && \
|
||||
defined(CLOCK_MONOTONIC)
|
||||
#if defined(CLOCK_MONOTONIC) && defined(HAVE_PTHREAD_CONDATTR_SETCLOCK)
|
||||
/* Use monotonic time so when we timedwait() on it, any clock adjustment
|
||||
* won't affect the timeout value. */
|
||||
if (pthread_condattr_setclock(&condattr, CLOCK_MONOTONIC)) {
|
||||
return -1;
|
||||
}
|
||||
#define USE_COND_CLOCK CLOCK_MONOTONIC
|
||||
#else /* !(defined(HAVE_PTHREAD_CONDATTR_SETCLOCK) && ...) */
|
||||
#else /* !defined HAVE_PTHREAD_CONDATTR_SETCLOCK */
|
||||
/* On OSX Sierra, there is no pthread_condattr_setclock, so we are stuck
|
||||
* with the realtime clock.
|
||||
*/
|
||||
#define USE_COND_CLOCK CLOCK_REALTIME
|
||||
#endif /* defined(HAVE_PTHREAD_CONDATTR_SETCLOCK) && ... */
|
||||
#endif /* defined(HAVE_CLOCK_GETTIME) */
|
||||
#endif /* which clock to use */
|
||||
#endif /* HAVE_CLOCK_GETTIME */
|
||||
if (pthread_cond_init(&cond->cond, &condattr)) {
|
||||
return -1;
|
||||
}
|
||||
|
@ -267,11 +266,11 @@ tor_cond_wait(tor_cond_t *cond, tor_mutex_t *mutex, const struct timeval *tv)
|
|||
tvnow.tv_sec = ts.tv_sec;
|
||||
tvnow.tv_usec = (int)(ts.tv_nsec / 1000);
|
||||
timeradd(tv, &tvnow, &tvsum);
|
||||
#else /* !(defined(HAVE_CLOCK_GETTIME) && defined(USE_COND_CLOCK)) */
|
||||
#else
|
||||
if (gettimeofday(&tvnow, NULL) < 0)
|
||||
return -1;
|
||||
timeradd(tv, &tvnow, &tvsum);
|
||||
#endif /* defined(HAVE_CLOCK_GETTIME) && defined(USE_COND_CLOCK) */
|
||||
#endif /* HAVE_CLOCK_GETTIME, CLOCK_MONOTONIC */
|
||||
|
||||
ts.tv_sec = tvsum.tv_sec;
|
||||
ts.tv_nsec = tvsum.tv_usec * 1000;
|
||||
|
|
|
@ -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
|
||||
|
|
@ -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;
|
||||
|
@ -126,7 +126,7 @@ read_ni(int fd, void *buf, size_t n)
|
|||
}
|
||||
return r;
|
||||
}
|
||||
#endif /* defined(HAVE_EVENTFD) || defined(HAVE_PIPE) */
|
||||
#endif
|
||||
|
||||
/** As send(), but retry on EINTR, and return the negative error code on
|
||||
* error. */
|
||||
|
@ -186,7 +186,7 @@ eventfd_drain(int fd)
|
|||
return r;
|
||||
return 0;
|
||||
}
|
||||
#endif /* defined(HAVE_EVENTFD) */
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_PIPE
|
||||
/** Send a byte over a pipe. Return 0 on success or EAGAIN; -1 on error */
|
||||
|
@ -214,7 +214,7 @@ pipe_drain(int fd)
|
|||
/* A value of r = 0 means EOF on the fd so successfully drained. */
|
||||
return 0;
|
||||
}
|
||||
#endif /* defined(HAVE_PIPE) */
|
||||
#endif
|
||||
|
||||
/** Send a byte on socket <b>fd</b>t. Return 0 on success or EAGAIN,
|
||||
* -1 on error. */
|
||||
|
@ -276,7 +276,7 @@ alert_sockets_create(alert_sockets_t *socks_out, uint32_t flags)
|
|||
socks_out->drain_fn = eventfd_drain;
|
||||
return 0;
|
||||
}
|
||||
#endif /* defined(HAVE_EVENTFD) */
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_PIPE2
|
||||
/* Now we're going to try pipes. First type the pipe2() syscall, if we
|
||||
|
@ -289,7 +289,7 @@ alert_sockets_create(alert_sockets_t *socks_out, uint32_t flags)
|
|||
socks_out->drain_fn = pipe_drain;
|
||||
return 0;
|
||||
}
|
||||
#endif /* defined(HAVE_PIPE2) */
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_PIPE
|
||||
/* Now try the regular pipe() syscall. Pipes have a bit lower overhead than
|
||||
|
@ -313,7 +313,7 @@ alert_sockets_create(alert_sockets_t *socks_out, uint32_t flags)
|
|||
socks_out->drain_fn = pipe_drain;
|
||||
return 0;
|
||||
}
|
||||
#endif /* defined(HAVE_PIPE) */
|
||||
#endif
|
||||
|
||||
/* If nothing else worked, fall back on socketpair(). */
|
||||
if (!(flags & ASOCKS_NOSOCKETPAIR) &&
|
||||
|
@ -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,17 +14,13 @@
|
|||
#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)
|
||||
#define USE_PTHREADS
|
||||
#else
|
||||
#error "No threading system was found"
|
||||
#endif /* defined(_WIN32) || ... */
|
||||
#endif
|
||||
|
||||
int spawn_func(void (*func)(void *), void *data);
|
||||
void spawn_exit(void) ATTR_NORETURN;
|
||||
|
@ -45,7 +41,7 @@ typedef struct tor_mutex_t {
|
|||
#else
|
||||
/** No-threads only: Dummy variable so that tor_mutex_t takes up space. */
|
||||
int _unused;
|
||||
#endif /* defined(USE_WIN32_THREADS) || ... */
|
||||
#endif
|
||||
} tor_mutex_t;
|
||||
|
||||
tor_mutex_t *tor_mutex_new(void);
|
||||
|
@ -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);
|
||||
|
@ -78,12 +73,11 @@ typedef struct tor_cond_t {
|
|||
int generation;
|
||||
#else
|
||||
#error no known condition implementation.
|
||||
#endif /* defined(USE_PTHREADS) || ... */
|
||||
#endif
|
||||
} 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
|
||||
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);
|
||||
|
||||
#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) */
|
||||
|
||||
#endif /* !defined(TOR_COMPAT_THREADS_H) */
|
||||
#endif
|
||||
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
/* as fallback implementation for tor_sleep_msec */
|
||||
#include <sys/select.h>
|
||||
#endif
|
||||
#endif /* defined(TOR_UNIT_TESTS) */
|
||||
#endif
|
||||
|
||||
#ifdef __APPLE__
|
||||
#include <mach/mach_time.h>
|
||||
|
@ -64,15 +64,15 @@ tor_sleep_msec(int msec)
|
|||
select(0, NULL, NULL, NULL, &tv);
|
||||
#else
|
||||
sleep(CEIL_DIV(msec, 1000));
|
||||
#endif /* defined(_WIN32) || ... */
|
||||
#endif
|
||||
}
|
||||
#endif /* defined(TOR_UNIT_TESTS) */
|
||||
#endif
|
||||
|
||||
/** 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)
|
||||
|
@ -112,7 +112,7 @@ tor_gettimeofday, (struct timeval *timeval))
|
|||
timeval->tv_usec = tb.millitm * 1000;
|
||||
#else
|
||||
#error "No way to get time."
|
||||
#endif /* defined(_WIN32) || ... */
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -187,8 +187,8 @@ monotime_coarse_set_mock_time_nsec(int64_t nsec)
|
|||
tor_assert_nonfatal(monotime_mocking_enabled == 1);
|
||||
mock_time_nsec_coarse = nsec;
|
||||
}
|
||||
#endif /* defined(MONOTIME_COARSE_FN_IS_DIFFERENT) */
|
||||
#endif /* defined(TOR_UNIT_TESTS) */
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* "ratchet" functions for monotonic time. */
|
||||
|
||||
|
@ -235,7 +235,7 @@ ratchet_coarse_performance_counter(const int64_t count_raw)
|
|||
last_tick_count = count;
|
||||
return count;
|
||||
}
|
||||
#endif /* defined(_WIN32) || defined(TOR_UNIT_TESTS) */
|
||||
#endif
|
||||
|
||||
#if defined(MONOTIME_USING_GETTIMEOFDAY) || defined(TOR_UNIT_TESTS)
|
||||
static struct timeval last_timeofday = { 0, 0 };
|
||||
|
@ -251,7 +251,7 @@ ratchet_timeval(const struct timeval *timeval_raw, struct timeval *out)
|
|||
{
|
||||
/* must hold lock */
|
||||
timeradd(timeval_raw, &timeofday_offset, out);
|
||||
if (PREDICT_UNLIKELY(timercmp(out, &last_timeofday, OP_LT))) {
|
||||
if (PREDICT_UNLIKELY(timercmp(out, &last_timeofday, <))) {
|
||||
/* time ran backwards. Instead, declare that no time occurred. */
|
||||
timersub(&last_timeofday, timeval_raw, &timeofday_offset);
|
||||
memcpy(out, &last_timeofday, sizeof(struct timeval));
|
||||
|
@ -259,7 +259,7 @@ ratchet_timeval(const struct timeval *timeval_raw, struct timeval *out)
|
|||
memcpy(&last_timeofday, out, sizeof(struct timeval));
|
||||
}
|
||||
}
|
||||
#endif /* defined(MONOTIME_USING_GETTIMEOFDAY) || defined(TOR_UNIT_TESTS) */
|
||||
#endif
|
||||
|
||||
#ifdef TOR_UNIT_TESTS
|
||||
/** For testing: reset all the ratchets */
|
||||
|
@ -271,7 +271,7 @@ monotime_reset_ratchets_for_testing(void)
|
|||
memset(&last_timeofday, 0, sizeof(struct timeval));
|
||||
memset(&timeofday_offset, 0, sizeof(struct timeval));
|
||||
}
|
||||
#endif /* defined(TOR_UNIT_TESTS) */
|
||||
#endif
|
||||
|
||||
#ifdef __APPLE__
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -319,25 +301,10 @@ monotime_get(monotime_t *out)
|
|||
/ mach_time_info.numer;
|
||||
return;
|
||||
}
|
||||
#endif /* defined(TOR_UNIT_TESTS) */
|
||||
#endif
|
||||
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)
|
||||
|
||||
|
@ -401,7 +332,7 @@ monotime_add_msec(monotime_t *out, const monotime_t *val, uint32_t msec)
|
|||
* an old Linux kernel. In that case, we will fall back to CLOCK_MONOTONIC.
|
||||
*/
|
||||
static int clock_monotonic_coarse = CLOCK_MONOTONIC_COARSE;
|
||||
#endif /* defined(CLOCK_MONOTONIC_COARSE) */
|
||||
#endif
|
||||
|
||||
static void
|
||||
monotime_init_internal(void)
|
||||
|
@ -413,7 +344,7 @@ monotime_init_internal(void)
|
|||
"falling back to CLOCK_MONOTONIC.", strerror(errno));
|
||||
clock_monotonic_coarse = CLOCK_MONOTONIC;
|
||||
}
|
||||
#endif /* defined(CLOCK_MONOTONIC_COARSE) */
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -425,7 +356,7 @@ monotime_get(monotime_t *out)
|
|||
out->ts_.tv_nsec = (int) (mock_time_nsec % ONE_BILLION);
|
||||
return;
|
||||
}
|
||||
#endif /* defined(TOR_UNIT_TESTS) */
|
||||
#endif
|
||||
int r = clock_gettime(CLOCK_MONOTONIC, &out->ts_);
|
||||
tor_assert(r == 0);
|
||||
}
|
||||
|
@ -440,7 +371,7 @@ monotime_coarse_get(monotime_coarse_t *out)
|
|||
out->ts_.tv_nsec = (int) (mock_time_nsec_coarse % ONE_BILLION);
|
||||
return;
|
||||
}
|
||||
#endif /* defined(TOR_UNIT_TESTS) */
|
||||
#endif
|
||||
int r = clock_gettime(clock_monotonic_coarse, &out->ts_);
|
||||
if (PREDICT_UNLIKELY(r < 0) &&
|
||||
errno == EINVAL &&
|
||||
|
@ -455,7 +386,7 @@ monotime_coarse_get(monotime_coarse_t *out)
|
|||
|
||||
tor_assert(r == 0);
|
||||
}
|
||||
#endif /* defined(CLOCK_MONOTONIC_COARSE) */
|
||||
#endif
|
||||
|
||||
int64_t
|
||||
monotime_diff_nsec(const monotime_t *start,
|
||||
|
@ -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)
|
||||
|
||||
|
@ -571,7 +462,7 @@ monotime_get(monotime_t *out)
|
|||
/ nsec_per_tick_numer;
|
||||
return;
|
||||
}
|
||||
#endif /* defined(TOR_UNIT_TESTS) */
|
||||
#endif
|
||||
|
||||
/* Alas, QueryPerformanceCounter is not always monotonic: see bug list at
|
||||
|
||||
|
@ -595,7 +486,7 @@ monotime_coarse_get(monotime_coarse_t *out)
|
|||
out->tick_count_ = mock_time_nsec_coarse / ONE_MILLION;
|
||||
return;
|
||||
}
|
||||
#endif /* defined(TOR_UNIT_TESTS) */
|
||||
#endif
|
||||
|
||||
if (GetTickCount64_fn) {
|
||||
out->tick_count_ = (int64_t)GetTickCount64_fn();
|
||||
|
@ -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,49 +567,10 @@ 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."
|
||||
#endif /* defined(__APPLE__) || ... */
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Initialize the monotonic timer subsystem. Must be called before any
|
||||
|
@ -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
|
||||
|
||||
|
|
|
@ -28,13 +28,13 @@
|
|||
#include <time.h>
|
||||
#endif
|
||||
|
||||
#if !defined(HAVE_STRUCT_TIMEVAL_TV_SEC)
|
||||
#if !defined(HAVE_GETTIMEOFDAY) && !defined(HAVE_STRUCT_TIMEVAL_TV_SEC)
|
||||
/** Implementation of timeval for platforms that don't have it. */
|
||||
struct timeval {
|
||||
time_t tv_sec;
|
||||
unsigned int tv_usec;
|
||||
};
|
||||
#endif /* !defined(HAVE_STRUCT_TIMEVAL_TV_SEC) */
|
||||
#endif
|
||||
|
||||
/** Represents a monotonic timer in a platform-dependent way. */
|
||||
typedef struct monotime_t {
|
||||
|
@ -51,11 +51,10 @@ typedef struct monotime_t {
|
|||
#define MONOTIME_USING_GETTIMEOFDAY
|
||||
/* Otherwise, we will be stuck using gettimeofday. */
|
||||
struct timeval tv_;
|
||||
#endif /* defined(__APPLE__) || ... */
|
||||
#endif
|
||||
} monotime_t;
|
||||
|
||||
#if defined(CLOCK_MONOTONIC_COARSE) && \
|
||||
defined(HAVE_CLOCK_GETTIME)
|
||||
#if defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_MONOTONIC_COARSE)
|
||||
#define MONOTIME_COARSE_FN_IS_DIFFERENT
|
||||
#define monotime_coarse_t monotime_t
|
||||
#elif defined(_WIN32)
|
||||
|
@ -65,12 +64,9 @@ 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) && ... || ... */
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Initialize the timing subsystem. This function is idempotent.
|
||||
|
@ -105,21 +101,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.
|
||||
|
@ -128,30 +109,12 @@ void monotime_coarse_get(monotime_coarse_t *out);
|
|||
uint64_t monotime_coarse_absolute_nsec(void);
|
||||
uint64_t monotime_coarse_absolute_usec(void);
|
||||
uint64_t monotime_coarse_absolute_msec(void);
|
||||
#else /* !(defined(MONOTIME_COARSE_FN_IS_DIFFERENT)) */
|
||||
#else
|
||||
#define monotime_coarse_get monotime_get
|
||||
#define monotime_coarse_absolute_nsec monotime_absolute_nsec
|
||||
#define monotime_coarse_absolute_usec monotime_absolute_usec
|
||||
#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);
|
||||
#endif
|
||||
|
||||
#if defined(MONOTIME_COARSE_TYPE_IS_DIFFERENT)
|
||||
int64_t monotime_coarse_diff_nsec(const monotime_coarse_t *start,
|
||||
|
@ -160,47 +123,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)) */
|
||||
#else
|
||||
#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);
|
||||
|
@ -213,7 +142,7 @@ void monotime_coarse_set_mock_time_nsec(int64_t);
|
|||
#else
|
||||
#define monotime_coarse_set_mock_time_nsec monotime_set_mock_time_nsec
|
||||
#endif
|
||||
#endif /* defined(TOR_UNIT_TESTS) */
|
||||
#endif
|
||||
|
||||
#ifdef COMPAT_TIME_PRIVATE
|
||||
#if defined(_WIN32) || defined(TOR_UNIT_TESTS)
|
||||
|
@ -227,7 +156,7 @@ STATIC void ratchet_timeval(const struct timeval *timeval_raw,
|
|||
#ifdef TOR_UNIT_TESTS
|
||||
void monotime_reset_ratchets_for_testing(void);
|
||||
#endif
|
||||
#endif /* defined(COMPAT_TIME_PRIVATE) */
|
||||
#endif
|
||||
|
||||
#endif /* !defined(TOR_COMPAT_TIME_H) */
|
||||
#endif
|
||||
|
||||
|
|
|
@ -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
|
||||
|
@ -247,5 +246,5 @@ tor_threads_init(void)
|
|||
set_main_thread();
|
||||
}
|
||||
|
||||
#endif /* defined(_WIN32) */
|
||||
#endif
|
||||
|
||||
|
|
|
@ -51,8 +51,8 @@ static atomic_counter_t total_compress_allocation;
|
|||
|
||||
/** Return true if uncompressing an input of size <b>in_size</b> to an input of
|
||||
* size at least <b>size_out</b> looks like a compression bomb. */
|
||||
MOCK_IMPL(int,
|
||||
tor_compress_is_compression_bomb,(size_t size_in, size_t size_out))
|
||||
int
|
||||
tor_compress_is_compression_bomb(size_t size_in, size_t size_out)
|
||||
{
|
||||
if (size_in == 0 || size_out < CHECK_FOR_COMPRESSION_BOMB_AFTER)
|
||||
return 0;
|
||||
|
@ -164,7 +164,7 @@ tor_compress_impl(int compress,
|
|||
goto err;
|
||||
}
|
||||
if (out_alloc >= SIZE_T_CEILING / 2) {
|
||||
log_warn(LD_GENERAL, "While %scompressing data: ran out of space.",
|
||||
log_warn(LD_GENERAL, "While %scompresing data: ran out of space.",
|
||||
compress?"":"un");
|
||||
goto err;
|
||||
}
|
||||
|
@ -185,12 +185,11 @@ tor_compress_impl(int compress,
|
|||
}
|
||||
case TOR_COMPRESS_ERROR:
|
||||
log_fn(protocol_warn_level, LD_GENERAL,
|
||||
"Error while %scompressing data: bad input?",
|
||||
"Error while %scompresing data: bad input?",
|
||||
compress?"":"un");
|
||||
goto err; // bad data.
|
||||
|
||||
// LCOV_EXCL_START
|
||||
default:
|
||||
// LCOV_EXCL_START
|
||||
tor_assert_nonfatal_unreached();
|
||||
goto err;
|
||||
// LCOV_EXCL_STOP
|
||||
|
@ -562,9 +561,9 @@ tor_compress_process(tor_compress_state_t *state,
|
|||
finish);
|
||||
break;
|
||||
case LZMA_METHOD:
|
||||
rv = tor_lzma_compress_process(state->u.lzma_state,
|
||||
out, out_len, in, in_len,
|
||||
finish);
|
||||
rv =tor_lzma_compress_process(state->u.lzma_state,
|
||||
out, out_len, in, in_len,
|
||||
finish);
|
||||
break;
|
||||
case ZSTD_METHOD:
|
||||
rv = tor_zstd_compress_process(state->u.zstd_state,
|
||||
|
@ -582,12 +581,6 @@ tor_compress_process(tor_compress_state_t *state,
|
|||
if (BUG((rv == TOR_COMPRESS_OK) &&
|
||||
*in_len == in_len_orig &&
|
||||
*out_len == out_len_orig)) {
|
||||
log_warn(LD_GENERAL,
|
||||
"More info on the bug: method == %s, finish == %d, "
|
||||
" *in_len == in_len_orig == %lu, "
|
||||
"*out_len == out_len_orig == %lu",
|
||||
compression_method_get_human_name(state->method), finish,
|
||||
(unsigned long)in_len_orig, (unsigned long)out_len_orig);
|
||||
return TOR_COMPRESS_ERROR;
|
||||
}
|
||||
|
||||
|
@ -598,7 +591,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 +656,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();
|
||||
}
|
||||
|
||||
|
|
|
@ -45,8 +45,7 @@ int tor_uncompress(char **out, size_t *out_len,
|
|||
|
||||
compress_method_t detect_compression_method(const char *in, size_t in_len);
|
||||
|
||||
MOCK_DECL(int,tor_compress_is_compression_bomb,(size_t size_in,
|
||||
size_t size_out));
|
||||
int tor_compress_is_compression_bomb(size_t size_in, size_t size_out);
|
||||
|
||||
int tor_compress_supports_method(compress_method_t method);
|
||||
unsigned tor_compress_get_supported_method_bitmask(void);
|
||||
|
@ -80,14 +79,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) */
|
||||
#endif // TOR_COMPRESS_H.
|
||||
|
||||
|
|
|
@ -75,7 +75,7 @@ lzma_error_str(lzma_ret error)
|
|||
return "Unknown LZMA error";
|
||||
}
|
||||
}
|
||||
#endif /* defined(HAVE_LZMA) */
|
||||
#endif // HAVE_LZMA.
|
||||
|
||||
/** Return 1 if LZMA compression is supported; otherwise 0. */
|
||||
int
|
||||
|
@ -158,12 +158,10 @@ tor_lzma_state_size_precalc(int compress, compression_level_t level)
|
|||
|
||||
return (size_t)memory_usage;
|
||||
|
||||
// LCOV_EXCL_START
|
||||
err:
|
||||
return 0;
|
||||
// LCOV_EXCL_STOP
|
||||
return 0; // LCOV_EXCL_LINE
|
||||
}
|
||||
#endif /* defined(HAVE_LZMA) */
|
||||
#endif // HAVE_LZMA.
|
||||
|
||||
/** Construct and return a tor_lzma_compress_state_t object using
|
||||
* <b>method</b>. If <b>compress</b>, it's for compression; otherwise it's for
|
||||
|
@ -214,18 +212,16 @@ tor_lzma_compress_new(int compress,
|
|||
atomic_counter_add(&total_lzma_allocation, result->allocation);
|
||||
return result;
|
||||
|
||||
/* LCOV_EXCL_START */
|
||||
err:
|
||||
tor_free(result);
|
||||
tor_free(result); // LCOV_EXCL_LINE
|
||||
return NULL;
|
||||
/* LCOV_EXCL_STOP */
|
||||
#else /* !(defined(HAVE_LZMA)) */
|
||||
#else // HAVE_LZMA.
|
||||
(void)compress;
|
||||
(void)method;
|
||||
(void)level;
|
||||
|
||||
return NULL;
|
||||
#endif /* defined(HAVE_LZMA) */
|
||||
#endif // HAVE_LZMA.
|
||||
}
|
||||
|
||||
/** Compress/decompress some bytes using <b>state</b>. Read up to
|
||||
|
@ -310,7 +306,7 @@ tor_lzma_compress_process(tor_lzma_compress_state_t *state,
|
|||
lzma_error_str(retval));
|
||||
return TOR_COMPRESS_ERROR;
|
||||
}
|
||||
#else /* !(defined(HAVE_LZMA)) */
|
||||
#else // HAVE_LZMA.
|
||||
(void)state;
|
||||
(void)out;
|
||||
(void)out_len;
|
||||
|
@ -318,12 +314,12 @@ tor_lzma_compress_process(tor_lzma_compress_state_t *state,
|
|||
(void)in_len;
|
||||
(void)finish;
|
||||
return TOR_COMPRESS_ERROR;
|
||||
#endif /* defined(HAVE_LZMA) */
|
||||
#endif // HAVE_LZMA.
|
||||
}
|
||||
|
||||
/** 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);
|
||||
|
||||
|
@ -42,5 +39,5 @@ size_t tor_lzma_get_total_allocation(void);
|
|||
|
||||
void tor_lzma_init(void);
|
||||
|
||||
#endif /* !defined(TOR_COMPRESS_LZMA_H) */
|
||||
#endif // TOR_COMPRESS_LZMA_H.
|
||||
|
||||
|
|
|
@ -16,5 +16,5 @@ tor_cnone_compress_process(char **out, size_t *out_len,
|
|||
const char **in, size_t *in_len,
|
||||
int finish);
|
||||
|
||||
#endif /* !defined(TOR_COMPRESS_NONE_H) */
|
||||
#endif // TOR_COMPRESS_NONE_H.
|
||||
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue