Compare commits
177 Commits
master
...
release-0.
Author | SHA1 | Date |
---|---|---|
Nick Mathewson | d07e069c97 | |
Nick Mathewson | b2b59b06c8 | |
Nick Mathewson | 2ffdf43e70 | |
Nick Mathewson | f3ea412110 | |
Nick Mathewson | 7c411bba8a | |
Nick Mathewson | 72c2292efc | |
Nick Mathewson | 698e4a4780 | |
Nick Mathewson | bcf033047d | |
Nick Mathewson | 1fe6e318f1 | |
Nick Mathewson | 1ff7c60759 | |
Nick Mathewson | ad3b01e056 | |
Nick Mathewson | e11830b2b4 | |
Nick Mathewson | ebf4f3f823 | |
Nick Mathewson | 87de19eff4 | |
Nick Mathewson | df1bae8f0f | |
Nick Mathewson | 27b04b8bad | |
Nick Mathewson | e5e3f13640 | |
Nick Mathewson | b734f871b7 | |
Nick Mathewson | 2b716e8599 | |
Nick Mathewson | f1cbb09e35 | |
Nick Mathewson | b1c543cf4d | |
Nick Mathewson | 98b28e789e | |
Nick Mathewson | 5926f14ecf | |
Nick Mathewson | 7b93939c77 | |
Nick Mathewson | fa3cad363e | |
Nick Mathewson | f5bd987c75 | |
Nick Mathewson | 100ff4a928 | |
Nick Mathewson | f02007a3e4 | |
Nick Mathewson | abff196c6a | |
Nick Mathewson | c346c892a4 | |
Nick Mathewson | 4d73ed10c4 | |
Nick Mathewson | 700c654d70 | |
Nick Mathewson | 4d308789e2 | |
Nick Mathewson | 0ad7317107 | |
Nick Mathewson | 2244838ec0 | |
Nick Mathewson | 658cd486ba | |
Nick Mathewson | 0f1b510b60 | |
Nick Mathewson | fe022f3ab0 | |
Nick Mathewson | 00322a9ba9 | |
Nick Mathewson | 385a44bac5 | |
Nick Mathewson | bea47fde59 | |
Nick Mathewson | 78b8274679 | |
Nick Mathewson | ee3d83dbf7 | |
Nick Mathewson | 44019d73ff | |
Nick Mathewson | 87b2047f9e | |
Nick Mathewson | 5df265ae55 | |
Nick Mathewson | 2db94810bf | |
Nick Mathewson | b594455ddd | |
Nick Mathewson | 5cb83c9425 | |
Nick Mathewson | d9bc1cdd1c | |
Nick Mathewson | 881307dc77 | |
Nick Mathewson | eebf93dfdc | |
Nick Mathewson | 61f3fe0418 | |
Nick Mathewson | fdcb065bf7 | |
Nick Mathewson | 070e82a02d | |
Nick Mathewson | 9c8b07c5eb | |
Nick Mathewson | c3debdfe6c | |
Nick Mathewson | 3a7e2ce1b6 | |
Nick Mathewson | 4c21daa9e2 | |
Nick Mathewson | 923efa3db8 | |
Nick Mathewson | 75e0843893 | |
Nick Mathewson | abe5b07c13 | |
Nick Mathewson | c33db290a9 | |
Nick Mathewson | 514212ed66 | |
Nick Mathewson | df16f89a8a | |
Nick Mathewson | a0d0e8842c | |
Nick Mathewson | 33d693fc74 | |
Nick Mathewson | 59cd249335 | |
Nick Mathewson | 93d376d8b3 | |
Nick Mathewson | 7902c2fa05 | |
Nick Mathewson | 136fb78f40 | |
Nick Mathewson | bc4a44e426 | |
Nick Mathewson | 388ed4c815 | |
Nick Mathewson | ef1d939751 | |
Nick Mathewson | df58a97f40 | |
Nick Mathewson | a2523196a4 | |
Nick Mathewson | ea5368026d | |
Nick Mathewson | c90ea4ee18 | |
Nick Mathewson | ce2f38f054 | |
Nick Mathewson | 72f06fc59c | |
Nick Mathewson | 7ebec27e72 | |
Nick Mathewson | 58e39a5596 | |
Nick Mathewson | 10ac393293 | |
Nick Mathewson | 036e60aa6e | |
Nick Mathewson | 1fb2e467d5 | |
Nick Mathewson | 03539b76cf | |
Nick Mathewson | 2e3c5296ff | |
Nick Mathewson | 22b3bf094e | |
Nick Mathewson | 3e5d9ae31a | |
Nick Mathewson | c552ce0e17 | |
Nick Mathewson | 7444f2daf9 | |
Nick Mathewson | 50cc49dd7f | |
Nick Mathewson | 4da0fe0234 | |
Nick Mathewson | 315667c448 | |
Nick Mathewson | 723f0487e9 | |
Nick Mathewson | 48ff8bb49b | |
Nick Mathewson | e23084bc6a | |
Nick Mathewson | 1bf534c8b3 | |
Nick Mathewson | b4ae31e2b7 | |
Nick Mathewson | db96d1b6b0 | |
Nick Mathewson | 802d30d9b7 | |
Nick Mathewson | 2664156a34 | |
Nick Mathewson | 03b91ac8c9 | |
Nick Mathewson | 63d0426af5 | |
Nick Mathewson | 916791f0be | |
Nick Mathewson | 17c61d98e4 | |
Nick Mathewson | 9390ec043b | |
Nick Mathewson | 2d26802524 | |
Nick Mathewson | 624bccc35e | |
Nick Mathewson | fae8bcba9e | |
Nick Mathewson | 0e8e775a40 | |
Nick Mathewson | 1ef83505db | |
Nick Mathewson | 10c33a6af2 | |
Nick Mathewson | 2ab1de9f3b | |
Roger Dingledine | 384457912f | |
Nick Mathewson | 94b5128395 | |
Nick Mathewson | 647fa4bdf4 | |
Nick Mathewson | bd62f78ebd | |
Nick Mathewson | 4663bec513 | |
Nick Mathewson | cfd9c1bdc0 | |
Nick Mathewson | 2da783ac84 | |
Nick Mathewson | 1dc4e86e41 | |
Nick Mathewson | 695425db0c | |
Nick Mathewson | 1fbd1e526c | |
Nick Mathewson | e4f29dc61a | |
Roger Dingledine | f8f34a8220 | |
Nick Mathewson | 6758549fe8 | |
Nick Mathewson | 7372315d56 | |
Nick Mathewson | a6cf5f6014 | |
Nick Mathewson | 75e22561a1 | |
Nick Mathewson | 47d2e4f06e | |
Nick Mathewson | 6f9af94757 | |
Nick Mathewson | d7c55e6700 | |
Nick Mathewson | a172303484 | |
Nick Mathewson | 43a0ae395d | |
Nick Mathewson | cab3aafcb3 | |
Nick Mathewson | 37c966db04 | |
Nick Mathewson | ddccc0f9b4 | |
Nick Mathewson | 03e5216700 | |
Nick Mathewson | e9a315c2df | |
Nick Mathewson | 4048c08332 | |
Nick Mathewson | 11f8342586 | |
Nick Mathewson | 5eb2786600 | |
Nick Mathewson | b44bb249a4 | |
Nick Mathewson | fe3cb4a337 | |
Nick Mathewson | b2e500f95b | |
Nick Mathewson | 91c60d77d6 | |
Nick Mathewson | 7257d41aa7 | |
Nick Mathewson | 3e463312df | |
Nick Mathewson | f50363e37a | |
Nick Mathewson | 0c0f8ad061 | |
Nick Mathewson | e1718c2dc0 | |
Nick Mathewson | 698984c180 | |
Nick Mathewson | 0e101e6545 | |
Nick Mathewson | 0c58627c1c | |
Nick Mathewson | 51ae5d8440 | |
Nick Mathewson | 7ec17188fe | |
Nick Mathewson | 7ffef14d33 | |
Nick Mathewson | 2e3645d026 | |
Nick Mathewson | 4ed142ae9b | |
Nick Mathewson | 92944a65be | |
Nick Mathewson | ea95c6d1ba | |
Nick Mathewson | 9e574fce98 | |
Nick Mathewson | d1054b09b9 | |
Nick Mathewson | f0dab06fca | |
Nick Mathewson | 18a4a4d7fd | |
Nick Mathewson | 26997ef9ae | |
Nick Mathewson | 23d365f3ae | |
Nick Mathewson | d66c184e3f | |
Nick Mathewson | 9ea09d15ab | |
Nick Mathewson | 9094936040 | |
Nick Mathewson | cf9844fcfa | |
Nick Mathewson | d6b6257121 | |
Nick Mathewson | 35ea6fb580 | |
Nick Mathewson | 96e471693f | |
Nick Mathewson | 46e096f2eb | |
Nick Mathewson | a9217bf6a5 |
|
@ -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
|
*.swp
|
||||||
*.swo
|
|
||||||
# C stuff
|
# C stuff
|
||||||
*.o
|
*.o
|
||||||
*.obj
|
*.obj
|
||||||
|
@ -19,8 +18,6 @@
|
||||||
.dirstamp
|
.dirstamp
|
||||||
*.trs
|
*.trs
|
||||||
*.log
|
*.log
|
||||||
# Calltool stuff
|
|
||||||
.*.graph
|
|
||||||
# Stuff made by our makefiles
|
# Stuff made by our makefiles
|
||||||
*.bak
|
*.bak
|
||||||
# Python droppings
|
# Python droppings
|
||||||
|
@ -71,7 +68,6 @@ uptime-*.json
|
||||||
/Tor*Bundle.dmg
|
/Tor*Bundle.dmg
|
||||||
/tor-*-win32.exe
|
/tor-*-win32.exe
|
||||||
/coverage_html/
|
/coverage_html/
|
||||||
/callgraph/
|
|
||||||
|
|
||||||
# /contrib/
|
# /contrib/
|
||||||
/contrib/dist/tor.sh
|
/contrib/dist/tor.sh
|
||||||
|
@ -127,9 +123,6 @@ uptime-*.json
|
||||||
/src/Makefile
|
/src/Makefile
|
||||||
/src/Makefile.in
|
/src/Makefile.in
|
||||||
|
|
||||||
# /src/trace
|
|
||||||
/src/trace/libor-trace.a
|
|
||||||
|
|
||||||
# /src/common/
|
# /src/common/
|
||||||
/src/common/Makefile
|
/src/common/Makefile
|
||||||
/src/common/Makefile.in
|
/src/common/Makefile.in
|
||||||
|
@ -175,12 +168,6 @@ uptime-*.json
|
||||||
/src/or/libtor-testing.a
|
/src/or/libtor-testing.a
|
||||||
/src/or/libtor.lib
|
/src/or/libtor.lib
|
||||||
|
|
||||||
# /src/rust
|
|
||||||
/src/rust/.cargo/config
|
|
||||||
/src/rust/.cargo/registry
|
|
||||||
/src/rust/target
|
|
||||||
/src/rust/registry
|
|
||||||
|
|
||||||
# /src/test
|
# /src/test
|
||||||
/src/test/Makefile
|
/src/test/Makefile
|
||||||
/src/test/Makefile.in
|
/src/test/Makefile.in
|
||||||
|
@ -192,7 +179,6 @@ uptime-*.json
|
||||||
/src/test/test-child
|
/src/test/test-child
|
||||||
/src/test/test-memwipe
|
/src/test/test-memwipe
|
||||||
/src/test/test-ntor-cl
|
/src/test/test-ntor-cl
|
||||||
/src/test/test-hs-ntor-cl
|
|
||||||
/src/test/test-switch-id
|
/src/test/test-switch-id
|
||||||
/src/test/test-timers
|
/src/test/test-timers
|
||||||
/src/test/test_workqueue
|
/src/test/test_workqueue
|
||||||
|
@ -201,7 +187,6 @@ uptime-*.json
|
||||||
/src/test/test-bt-cl.exe
|
/src/test/test-bt-cl.exe
|
||||||
/src/test/test-child.exe
|
/src/test/test-child.exe
|
||||||
/src/test/test-ntor-cl.exe
|
/src/test/test-ntor-cl.exe
|
||||||
/src/test/test-hs-ntor-cl.exe
|
|
||||||
/src/test/test-memwipe.exe
|
/src/test/test-memwipe.exe
|
||||||
/src/test/test-switch-id.exe
|
/src/test/test-switch-id.exe
|
||||||
/src/test/test-timers.exe
|
/src/test/test-timers.exe
|
||||||
|
@ -212,7 +197,6 @@ uptime-*.json
|
||||||
/src/test/fuzz/lf-fuzz-*
|
/src/test/fuzz/lf-fuzz-*
|
||||||
|
|
||||||
# /src/tools/
|
# /src/tools/
|
||||||
/src/tools/libtorrunner.a
|
|
||||||
/src/tools/tor-checkkey
|
/src/tools/tor-checkkey
|
||||||
/src/tools/tor-resolve
|
/src/tools/tor-resolve
|
||||||
/src/tools/tor-cov-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
|
|
|
@ -1,3 +0,0 @@
|
||||||
[submodule "src/ext/rust"]
|
|
||||||
path = src/ext/rust
|
|
||||||
url = https://git.torproject.org/tor-rust-dependencies
|
|
79
.travis.yml
79
.travis.yml
|
@ -60,76 +60,30 @@ env:
|
||||||
global:
|
global:
|
||||||
## The Travis CI environment allows us two cores, so let's use both.
|
## The Travis CI environment allows us two cores, so let's use both.
|
||||||
- MAKEFLAGS="-j 2"
|
- MAKEFLAGS="-j 2"
|
||||||
matrix:
|
|
||||||
## Leave at least one entry here or Travis seems to generate a
|
|
||||||
## matrix entry with empty matrix environment variables. Leaving
|
|
||||||
## 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:
|
matrix:
|
||||||
## Uncomment to allow the build to report success (with non-required
|
## If one build in the matrix fails (e.g. if building withour Rust and Clang
|
||||||
## sub-builds continuing to run) if all required sub-builds have
|
## fails, but building with Rust and GCC is still going), then cancel the
|
||||||
## succeeded. This is somewhat buggy currently: it can cause
|
## entire job early and call the whole thing a failure.
|
||||||
## duplicate notifications and prematurely report success if a
|
fast_finish: true
|
||||||
## single sub-build has succeeded. See
|
|
||||||
## https://github.com/travis-ci/travis-ci/issues/1696
|
|
||||||
# fast_finish: true
|
|
||||||
|
|
||||||
## Uncomment the appropriate lines below to allow the build to
|
|
||||||
## report success even if some less-critical sub-builds fail and it
|
|
||||||
## seems likely to take a while for someone to fix it. Currently
|
|
||||||
## Travis CI doesn't distinguish "all builds succeeded" from "some
|
|
||||||
## non-required sub-builds failed" except on the individual build's
|
|
||||||
## page, which makes it somewhat annoying to detect from the
|
|
||||||
## branches and build history pages. See
|
|
||||||
## https://github.com/travis-ci/travis-ci/issues/8716
|
|
||||||
allow_failures:
|
|
||||||
# - env: RUST_OPTIONS="--enable-rust" TOR_RUST_DEPENDENCIES=true
|
|
||||||
# - env: RUST_OPTIONS="--enable-rust --enable-cargo-online-mode
|
|
||||||
# - compiler: clang
|
|
||||||
|
|
||||||
## Create explicit matrix entries to work around a Travis CI
|
## Create explicit matrix entries to work around a Travis CI
|
||||||
## environment issue. Missing keys inherit from the first list
|
## environment issue. Missing keys inherit from the first list
|
||||||
## entry under that key outside the "include" clause.
|
## entry under that key outside the "include" clause.
|
||||||
include:
|
include:
|
||||||
- compiler: gcc
|
- 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"
|
|
||||||
## The "sudo: required" forces non-containerized builds, working
|
## The "sudo: required" forces non-containerized builds, working
|
||||||
## around a Travis CI environment issue: clang LeakAnalyzer fails
|
## around a Travis CI environment issue: clang LeakAnalyzer fails
|
||||||
## because it requires ptrace and the containerized environment no
|
## because it requires ptrace and the containerized environment no
|
||||||
## longer allows ptrace.
|
## longer allows ptrace.
|
||||||
- compiler: clang
|
- compiler: clang
|
||||||
sudo: required
|
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:
|
before_install:
|
||||||
## If we're on OSX, homebrew usually needs to updated first
|
## If we're on OSX, homebrew usually needs to updated first
|
||||||
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew update ; fi
|
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew update ; fi
|
||||||
## Download rustup
|
## Download rustup
|
||||||
- if [[ "$RUST_OPTIONS" != "" ]]; then curl -Ssf -o rustup.sh https://sh.rustup.rs; fi
|
- curl -Ssf -o rustup.sh https://sh.rustup.rs
|
||||||
- if [[ "$COVERAGE_OPTIONS" != "" ]]; then pip install --user cpp-coveralls; fi
|
|
||||||
|
|
||||||
install:
|
install:
|
||||||
## If we're on OSX use brew to install required dependencies (for Linux, see the "apt:" section above)
|
## If we're on OSX use brew to install required dependencies (for Linux, see the "apt:" section above)
|
||||||
|
@ -140,30 +94,13 @@ install:
|
||||||
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then { brew outdated xz || brew upgrade xz; }; fi
|
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then { brew outdated xz || brew upgrade xz; }; fi
|
||||||
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then { brew outdated libscrypt || brew upgrade libscrypt; }; fi
|
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then { brew outdated libscrypt || brew upgrade libscrypt; }; fi
|
||||||
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then { brew outdated zstd || brew upgrade zstd; }; fi
|
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then { brew outdated zstd || brew upgrade zstd; }; fi
|
||||||
## Install the stable channels of rustc and cargo and setup our toolchain environment
|
|
||||||
- if [[ "$RUST_OPTIONS" != "" ]]; then sh rustup.sh -y --default-toolchain stable; fi
|
|
||||||
- if [[ "$RUST_OPTIONS" != "" ]]; then source $HOME/.cargo/env; fi
|
|
||||||
## Get some info about rustc and cargo
|
|
||||||
- if [[ "$RUST_OPTIONS" != "" ]]; then which rustc; fi
|
|
||||||
- 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:
|
script:
|
||||||
- ./autogen.sh
|
- ./autogen.sh
|
||||||
- ./configure $RUST_OPTIONS $COVERAGE_OPTIONS $MODULES_OPTIONS --disable-asciidoc --enable-fatal-warnings --disable-silent-rules --enable-fragile-hardening
|
- ./configure $RUST_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.
|
## We run `make check` because that's what https://jenkins.torproject.org does.
|
||||||
- if [[ "$DISTCHECK" == "" ]]; then make check; fi
|
- make check
|
||||||
- if [[ "$DISTCHECK" != "" ]]; then make distcheck DISTCHECK_CONFIGURE_FLAGS="$RUST_OPTIONS $COVERAGE_OPTIONS --disable-asciidoc --enable-fatal-warnings --disable-silent-rules --enable-fragile-hardening"; fi
|
|
||||||
|
|
||||||
after_failure:
|
after_failure:
|
||||||
## `make check` will leave a log file with more details of test failures.
|
## `make check` will leave a log file with more details of test failures.
|
||||||
- if [[ "$DISTCHECK" == "" ]]; then cat test-suite.log; fi
|
- cat test-suite.log
|
||||||
## `make distcheck` puts it somewhere different.
|
|
||||||
- if [[ "$DISTCHECK" != "" ]]; then make show-distdir-testlog; fi
|
|
||||||
|
|
||||||
after_success:
|
|
||||||
## If this build was one that produced coverage, upload it.
|
|
||||||
- if [[ "$COVERAGE_OPTIONS" != "" ]]; then coveralls -b . --exclude src/test --exclude src/trunnel --gcov-options '\-p'; 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
|
|
2
LICENSE
2
LICENSE
|
@ -13,7 +13,7 @@ Tor is distributed under this license:
|
||||||
|
|
||||||
Copyright (c) 2001-2004, Roger Dingledine
|
Copyright (c) 2001-2004, Roger Dingledine
|
||||||
Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson
|
Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson
|
||||||
Copyright (c) 2007-2017, The Tor Project, Inc.
|
Copyright (c) 2007-2016, The Tor Project, Inc.
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
Redistribution and use in source and binary forms, with or without
|
||||||
modification, are permitted provided that the following conditions are
|
modification, are permitted provided that the following conditions are
|
||||||
|
|
75
Makefile.am
75
Makefile.am
|
@ -1,6 +1,6 @@
|
||||||
# Copyright (c) 2001-2004, Roger Dingledine
|
# Copyright (c) 2001-2004, Roger Dingledine
|
||||||
# Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson
|
# Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson
|
||||||
# Copyright (c) 2007-2017, The Tor Project, Inc.
|
# Copyright (c) 2007-2015, The Tor Project, Inc.
|
||||||
# See LICENSE for licensing information
|
# See LICENSE for licensing information
|
||||||
|
|
||||||
ACLOCAL_AMFLAGS = -I m4
|
ACLOCAL_AMFLAGS = -I m4
|
||||||
|
@ -16,7 +16,7 @@ noinst_PROGRAMS=
|
||||||
DISTCLEANFILES=
|
DISTCLEANFILES=
|
||||||
bin_SCRIPTS=
|
bin_SCRIPTS=
|
||||||
AM_CPPFLAGS=
|
AM_CPPFLAGS=
|
||||||
AM_CFLAGS=@TOR_SYSTEMD_CFLAGS@ @CFLAGS_BUGTRAP@ @TOR_LZMA_CFLAGS@ @TOR_ZSTD_CFLAGS@
|
AM_CFLAGS=@TOR_SYSTEMD_CFLAGS@ @CFLAGS_BUGTRAP@
|
||||||
SHELL=@SHELL@
|
SHELL=@SHELL@
|
||||||
|
|
||||||
if COVERAGE_ENABLED
|
if COVERAGE_ENABLED
|
||||||
|
@ -25,20 +25,12 @@ else
|
||||||
TESTING_TOR_BINARY=$(top_builddir)/src/or/tor$(EXEEXT)
|
TESTING_TOR_BINARY=$(top_builddir)/src/or/tor$(EXEEXT)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
if USE_RUST
|
|
||||||
rust_ldadd=$(top_builddir)/src/rust/target/release/@TOR_RUST_STATIC_NAME@ \
|
|
||||||
@TOR_RUST_EXTRA_LIBS@
|
|
||||||
else
|
|
||||||
rust_ldadd=
|
|
||||||
endif
|
|
||||||
|
|
||||||
include src/include.am
|
include src/include.am
|
||||||
include doc/include.am
|
include doc/include.am
|
||||||
include contrib/include.am
|
include contrib/include.am
|
||||||
|
|
||||||
EXTRA_DIST+= \
|
EXTRA_DIST+= \
|
||||||
ChangeLog \
|
ChangeLog \
|
||||||
CONTRIBUTING \
|
|
||||||
INSTALL \
|
INSTALL \
|
||||||
LICENSE \
|
LICENSE \
|
||||||
Makefile.nmake \
|
Makefile.nmake \
|
||||||
|
@ -52,14 +44,14 @@ AM_ETAGSFLAGS=--regex='{c}/MOCK_IMPL([^,]+,\W*\([a-zA-Z0-9_]+\)\W*,/\1/s'
|
||||||
if COVERAGE_ENABLED
|
if COVERAGE_ENABLED
|
||||||
TEST_CFLAGS=-fno-inline -fprofile-arcs -ftest-coverage
|
TEST_CFLAGS=-fno-inline -fprofile-arcs -ftest-coverage
|
||||||
if DISABLE_ASSERTS_IN_UNIT_TESTS
|
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
|
else
|
||||||
TEST_CPPFLAGS=-DTOR_UNIT_TESTS -DTOR_COVERAGE @TOR_MODULES_ALL_ENABLED@
|
TEST_CPPFLAGS=-DTOR_UNIT_TESTS -DTOR_COVERAGE
|
||||||
endif
|
endif
|
||||||
TEST_NETWORK_FLAGS=--coverage --hs-multi-client 1
|
TEST_NETWORK_FLAGS=--coverage --hs-multi-client 1
|
||||||
else
|
else
|
||||||
TEST_CFLAGS=
|
TEST_CFLAGS=
|
||||||
TEST_CPPFLAGS=-DTOR_UNIT_TESTS @TOR_MODULES_ALL_ENABLED@
|
TEST_CPPFLAGS=-DTOR_UNIT_TESTS
|
||||||
TEST_NETWORK_FLAGS=--hs-multi-client 1
|
TEST_NETWORK_FLAGS=--hs-multi-client 1
|
||||||
endif
|
endif
|
||||||
TEST_NETWORK_WARNING_FLAGS=--quiet --only-warnings
|
TEST_NETWORK_WARNING_FLAGS=--quiet --only-warnings
|
||||||
|
@ -98,7 +90,7 @@ doxygen:
|
||||||
test: all
|
test: all
|
||||||
$(top_builddir)/src/test/test
|
$(top_builddir)/src/test/test
|
||||||
|
|
||||||
check-local: check-spaces check-changes
|
check-local: check-spaces
|
||||||
|
|
||||||
need-chutney-path:
|
need-chutney-path:
|
||||||
@if test ! -d "$$CHUTNEY_PATH"; then \
|
@if test ! -d "$$CHUTNEY_PATH"; then \
|
||||||
|
@ -119,19 +111,17 @@ test-network: need-chutney-path $(TESTING_TOR_BINARY) src/tools/tor-gencert
|
||||||
|
|
||||||
# Run all available tests using automake's test-driver
|
# 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 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)
|
# 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
|
# only run mixed tests if we have a tor-stable binary
|
||||||
# Try the syntax for BSD ping6, Linux ping6, and Linux ping -6,
|
# Try both the BSD and the Linux ping6 syntax, because they're incompatible
|
||||||
# because they're incompatible
|
|
||||||
test-network-all: need-chutney-path test-driver $(TESTING_TOR_BINARY) src/tools/tor-gencert
|
test-network-all: need-chutney-path test-driver $(TESTING_TOR_BINARY) src/tools/tor-gencert
|
||||||
mkdir -p $(TEST_NETWORK_ALL_LOG_DIR)
|
mkdir -p $(TEST_NETWORK_ALL_LOG_DIR)
|
||||||
@flavors="$(TEST_CHUTNEY_FLAVORS)"; \
|
@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 \
|
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 or ping ::1 succeeded, running IPv6 flavors: $(TEST_CHUTNEY_FLAVORS_IPV6)."; \
|
echo "ping6 ::1 succeeded, running IPv6 flavors: $(TEST_CHUTNEY_FLAVORS_IPV6)."; \
|
||||||
flavors="$$flavors $(TEST_CHUTNEY_FLAVORS_IPV6)"; \
|
flavors="$$flavors $(TEST_CHUTNEY_FLAVORS_IPV6)"; \
|
||||||
else \
|
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)"; \
|
skip_flavors="$$skip_flavors $(TEST_CHUTNEY_FLAVORS_IPV6)"; \
|
||||||
fi; \
|
fi; \
|
||||||
if command -v tor-stable >/dev/null 2>&1; then \
|
if command -v tor-stable >/dev/null 2>&1; then \
|
||||||
|
@ -218,42 +208,16 @@ check-logs:
|
||||||
$(top_srcdir)/scripts/maint/checkLogs.pl \
|
$(top_srcdir)/scripts/maint/checkLogs.pl \
|
||||||
$(top_srcdir)/src/*/*.[ch] | sort -n
|
$(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
|
.PHONY: check-changes
|
||||||
check-changes:
|
check-changes:
|
||||||
if USEPYTHON
|
|
||||||
@if test -d "$(top_srcdir)/changes"; then \
|
@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
|
fi
|
||||||
endif
|
|
||||||
|
|
||||||
.PHONY: update-versions
|
.PHONY: update-versions
|
||||||
update-versions:
|
update-versions:
|
||||||
$(PERL) $(top_builddir)/scripts/maint/updateVersions.pl
|
$(PERL) $(top_builddir)/scripts/maint/updateVersions.pl
|
||||||
|
|
||||||
.PHONY: callgraph
|
|
||||||
callgraph:
|
|
||||||
$(top_builddir)/scripts/maint/run_calltool.sh
|
|
||||||
|
|
||||||
version:
|
version:
|
||||||
@echo "Tor @VERSION@"
|
@echo "Tor @VERSION@"
|
||||||
@if test -d "$(top_srcdir)/.git" && test -x "`which git 2>&1;true`"; then \
|
@if test -d "$(top_srcdir)/.git" && test -x "`which git 2>&1;true`"; then \
|
||||||
|
@ -266,20 +230,3 @@ mostlyclean-local:
|
||||||
rm -rf $(HTML_COVER_DIR)
|
rm -rf $(HTML_COVER_DIR)
|
||||||
rm -rf $(top_builddir)/doc/doxygen
|
rm -rf $(top_builddir)/doc/doxygen
|
||||||
rm -rf $(TEST_NETWORK_ALL_LOG_DIR)
|
rm -rf $(TEST_NETWORK_ALL_LOG_DIR)
|
||||||
|
|
||||||
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.
|
|
||||||
show-distdir-testlog:
|
|
||||||
@if test -d "$(distdir)/_build/sub"; then \
|
|
||||||
cat $(distdir)/_build/sub/$(TEST_SUITE_LOG); \
|
|
||||||
else \
|
|
||||||
cat $(distdir)/_build/$(TEST_SUITE_LOG); fi
|
|
||||||
|
|
3
README
3
README
|
@ -27,6 +27,3 @@ Frequently Asked Questions:
|
||||||
|
|
||||||
To get started working on Tor development:
|
To get started working on Tor development:
|
||||||
See the doc/HACKING directory.
|
See the doc/HACKING directory.
|
||||||
|
|
||||||
Release timeline:
|
|
||||||
https://trac.torproject.org/projects/tor/wiki/org/teams/NetworkTeam/CoreTorReleases
|
|
||||||
|
|
3945
ReleaseNotes
3945
ReleaseNotes
File diff suppressed because it is too large
Load Diff
|
@ -2,7 +2,7 @@ dnl Helper macros for Tor configure.ac
|
||||||
dnl Copyright (c) 2001-2004, Roger Dingledine
|
dnl Copyright (c) 2001-2004, Roger Dingledine
|
||||||
dnl Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson
|
dnl Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson
|
||||||
dnl Copyright (c) 2007-2008, Roger Dingledine, Nick Mathewson
|
dnl Copyright (c) 2007-2008, Roger Dingledine, Nick Mathewson
|
||||||
dnl Copyright (c) 2007-2017, The Tor Project, Inc.
|
dnl Copyright (c) 2007-2015, The Tor Project, Inc.
|
||||||
dnl See LICENSE for licensing information
|
dnl See LICENSE for licensing information
|
||||||
|
|
||||||
AC_DEFUN([TOR_EXTEND_CODEPATH],
|
AC_DEFUN([TOR_EXTEND_CODEPATH],
|
||||||
|
|
|
@ -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,5 @@
|
||||||
|
o Minor bugfixes (entry guards):
|
||||||
|
- Tor now updates its guard state when it reads a consensus regardless of
|
||||||
|
whether it's missing descriptors. That makes tor use its primary guards
|
||||||
|
to fetch descriptors in some edge cases where it would have used fallback
|
||||||
|
directories in the past. Fixes bug 23862; bugfix on 0.3.0.1-alpha.
|
|
@ -0,0 +1,9 @@
|
||||||
|
o Minor bugfixes (bootstrapping):
|
||||||
|
- Fetch descriptors aggressively whenever we lack enough
|
||||||
|
to build circuits, regardless of how many descriptors we are missing.
|
||||||
|
Previously, we would delay launching the fetch when we had fewer than
|
||||||
|
15 missing descriptors, even if some of those descriptors were
|
||||||
|
blocking circuits from building. Fixes bug 23985; bugfix on
|
||||||
|
0.1.1.11-alpha. The effects of this bug became worse in 0.3.0.3-alpha,
|
||||||
|
when we began treating missing descriptors from our primary guards
|
||||||
|
as a reason to delay circuits.
|
|
@ -0,0 +1,7 @@
|
||||||
|
o Minor bugfixes (network layer):
|
||||||
|
- When closing a connection via close_connection_immediately(), we
|
||||||
|
mark it as "not blocked on bandwidth", to prevent later calls
|
||||||
|
from trying to unblock it, and give it permission to read. This
|
||||||
|
fixes a backtrace warning that can happen on relays under various
|
||||||
|
circumstances. Fixes bug 24167; bugfix on 0.1.0.1-rc.
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
o Minor bugfixes (compilation):
|
||||||
|
- Fix a signed/unsigned comparison warning introduced by our
|
||||||
|
fix to TROVE-2017-009. Fixes bug 24480; bugfix on 0.2.5.16.
|
|
@ -0,0 +1,5 @@
|
||||||
|
o Minor bugfixes (portability, msvc):
|
||||||
|
- Fix a bug in the bit-counting parts of our timing-wheel code on
|
||||||
|
MSVC. (Note that MSVC is still not a supported build platform,
|
||||||
|
due to cyptographic timing channel risks.) Fixes bug 24633;
|
||||||
|
bugfix on 0.2.9.1-alpha.
|
|
@ -0,0 +1,7 @@
|
||||||
|
o Minor bugfixes (memory usage):
|
||||||
|
|
||||||
|
- When queuing DESTROY cells on a channel, only queue the
|
||||||
|
circuit-id and reason fields: not the entire 514-byte
|
||||||
|
cell. This fix should help mitigate any bugs or attacks that
|
||||||
|
fill up these queues, and free more RAM for other uses. Fixes
|
||||||
|
bug 24666; bugfix on 0.2.5.1-alpha.
|
|
@ -0,0 +1,6 @@
|
||||||
|
o Minor bugfixes (address selection):
|
||||||
|
- When the fascist_firewall_choose_address_ functions don't find a
|
||||||
|
reachable address, set the returned address to the null address and port.
|
||||||
|
This is a precautionary measure, because some callers do not check the
|
||||||
|
return value.
|
||||||
|
Fixes bug 24736; bugfix on 0.2.8.2-alpha.
|
|
@ -0,0 +1,8 @@
|
||||||
|
o Major bugfixes (onion services):
|
||||||
|
- Fix an "off by 2" error in counting rendezvous failures on the onion
|
||||||
|
service side. While we thought we would stop the rendezvous attempt
|
||||||
|
after one failed circuit, we were actually making three circuit attempts
|
||||||
|
before giving up. Now switch to a default of 2, and allow the consensus
|
||||||
|
parameter "hs_service_max_rdv_failures" to override. Fixes bug 24895;
|
||||||
|
bugfix on 0.0.6.
|
||||||
|
|
|
@ -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.
|
|
|
@ -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,7 +0,0 @@
|
||||||
o Minor bugfixes (compatibility, openssl):
|
|
||||||
- Work around a change in OpenSSL 1.1.1 where
|
|
||||||
return values that would previously indicate "no password" now
|
|
||||||
indicate an empty password. Without this workaround, Tor instances
|
|
||||||
running with OpenSSL 1.1.1 would accept descriptors that other Tor
|
|
||||||
instances would reject. Fixes bug 26116; bugfix on 0.2.5.16.
|
|
||||||
|
|
|
@ -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 (hardening):
|
|
||||||
- Prevent a possible out-of-bounds smartlist read in
|
|
||||||
protover_compute_vote(). Fixes bug 26196; bugfix on
|
|
||||||
0.2.9.4-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.
|
|
|
@ -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 (geoip):
|
||||||
|
- Update geoip and geoip6 to the December 6 2017 Maxmind GeoLite2
|
||||||
|
Country database.
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
o Minor features (geoip):
|
||||||
|
- Update geoip and geoip6 to the January 5 2018 Maxmind GeoLite2
|
||||||
|
Country database.
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
o Minor feature (relay statistics):
|
||||||
|
- Change relay bandwidth reporting stats interval from 4 hours to 24 hours
|
||||||
|
in order to reduce the efficiency of guard discovery attacks. Fixes
|
||||||
|
ticket 23856.
|
|
@ -0,0 +1,6 @@
|
||||||
|
o Minor features (fallback directory mirrors):
|
||||||
|
- Make the default DirAuthorityFallbackRate 0.1, so that clients on the
|
||||||
|
public tor network prefer to bootstrap off fallback directory mirrors.
|
||||||
|
This is a follow-up to 24679, which removed weights from the default
|
||||||
|
fallbacks.
|
||||||
|
Implements ticket 24681.
|
|
@ -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,5 @@
|
||||||
|
o Minor features (new fallback directories):
|
||||||
|
- The fallback directory list has been re-generated based on the
|
||||||
|
current status of the network. Tor uses fallback directories to
|
||||||
|
bootstrap it doesn't yet have up-to-date directory
|
||||||
|
information. Closes ticket 24801.
|
369
configure.ac
369
configure.ac
|
@ -1,10 +1,10 @@
|
||||||
dnl Copyright (c) 2001-2004, Roger Dingledine
|
dnl Copyright (c) 2001-2004, Roger Dingledine
|
||||||
dnl Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson
|
dnl Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson
|
||||||
dnl Copyright (c) 2007-2017, The Tor Project, Inc.
|
dnl Copyright (c) 2007-2015, The Tor Project, Inc.
|
||||||
dnl See LICENSE for licensing information
|
dnl See LICENSE for licensing information
|
||||||
|
|
||||||
AC_PREREQ([2.63])
|
AC_PREREQ([2.63])
|
||||||
AC_INIT([tor],[0.3.4.1-alpha-dev])
|
AC_INIT([tor],[0.3.0.13-dev])
|
||||||
AC_CONFIG_SRCDIR([src/or/main.c])
|
AC_CONFIG_SRCDIR([src/or/main.c])
|
||||||
AC_CONFIG_MACRO_DIR([m4])
|
AC_CONFIG_MACRO_DIR([m4])
|
||||||
|
|
||||||
|
@ -53,16 +53,6 @@ AC_ARG_ENABLE(libfuzzer,
|
||||||
AS_HELP_STRING(--enable-libfuzzer, [build extra fuzzers based on 'libfuzzer']))
|
AS_HELP_STRING(--enable-libfuzzer, [build extra fuzzers based on 'libfuzzer']))
|
||||||
AC_ARG_ENABLE(oss-fuzz,
|
AC_ARG_ENABLE(oss-fuzz,
|
||||||
AS_HELP_STRING(--enable-oss-fuzz, [build extra fuzzers based on 'oss-fuzz' environment]))
|
AS_HELP_STRING(--enable-oss-fuzz, [build extra fuzzers based on 'oss-fuzz' environment]))
|
||||||
AC_ARG_ENABLE(memory-sentinels,
|
|
||||||
AS_HELP_STRING(--disable-memory-sentinels, [disable code that tries to prevent some kinds of memory access bugs. For fuzzing only.]))
|
|
||||||
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
|
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])
|
AC_MSG_ERROR([Can't disable assertions outside of coverage build])
|
||||||
|
@ -73,7 +63,6 @@ AM_CONDITIONAL(COVERAGE_ENABLED, test "x$enable_coverage" = "xyes")
|
||||||
AM_CONDITIONAL(DISABLE_ASSERTS_IN_UNIT_TESTS, test "x$enable_asserts_in_tests" = "xno")
|
AM_CONDITIONAL(DISABLE_ASSERTS_IN_UNIT_TESTS, test "x$enable_asserts_in_tests" = "xno")
|
||||||
AM_CONDITIONAL(LIBFUZZER_ENABLED, test "x$enable_libfuzzer" = "xyes")
|
AM_CONDITIONAL(LIBFUZZER_ENABLED, test "x$enable_libfuzzer" = "xyes")
|
||||||
AM_CONDITIONAL(OSS_FUZZ_ENABLED, test "x$enable_oss_fuzz" = "xyes")
|
AM_CONDITIONAL(OSS_FUZZ_ENABLED, test "x$enable_oss_fuzz" = "xyes")
|
||||||
AM_CONDITIONAL(USE_RUST, test "x$enable_rust" = "xyes")
|
|
||||||
|
|
||||||
if test "$enable_static_tor" = "yes"; then
|
if test "$enable_static_tor" = "yes"; then
|
||||||
enable_static_libevent="yes";
|
enable_static_libevent="yes";
|
||||||
|
@ -87,11 +76,6 @@ if test "$enable_system_torrc" = "no"; then
|
||||||
[Defined if we're not going to look for a torrc in SYSCONF])
|
[Defined if we're not going to look for a torrc in SYSCONF])
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if test "$enable_memory_sentinels" = "no"; then
|
|
||||||
AC_DEFINE(DISABLE_MEMORY_SENTINELS, 1,
|
|
||||||
[Defined if we're turning off memory safety code to look for bugs])
|
|
||||||
fi
|
|
||||||
|
|
||||||
AM_CONDITIONAL(USE_OPENBSD_MALLOC, test "x$enable_openbsd_malloc" = "xyes")
|
AM_CONDITIONAL(USE_OPENBSD_MALLOC, test "x$enable_openbsd_malloc" = "xyes")
|
||||||
|
|
||||||
AC_ARG_ENABLE(asciidoc,
|
AC_ARG_ENABLE(asciidoc,
|
||||||
|
@ -111,15 +95,7 @@ AC_ARG_ENABLE(systemd,
|
||||||
* ) AC_MSG_ERROR(bad value for --enable-systemd) ;;
|
* ) AC_MSG_ERROR(bad value for --enable-systemd) ;;
|
||||||
esac], [systemd=auto])
|
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
|
# systemd support
|
||||||
if test "x$enable_systemd" = "xno"; then
|
if test "x$enable_systemd" = "xno"; then
|
||||||
|
@ -206,55 +182,6 @@ AC_ARG_ENABLE(seccomp,
|
||||||
AC_ARG_ENABLE(libscrypt,
|
AC_ARG_ENABLE(libscrypt,
|
||||||
AS_HELP_STRING(--disable-libscrypt, [do not attempt to use libscrypt]))
|
AS_HELP_STRING(--disable-libscrypt, [do not attempt to use libscrypt]))
|
||||||
|
|
||||||
dnl Enable event tracing which are transformed to debug log statement.
|
|
||||||
AC_ARG_ENABLE(event-tracing-debug,
|
|
||||||
AS_HELP_STRING(--enable-event-tracing-debug, [build with event tracing to debug log]))
|
|
||||||
AM_CONDITIONAL([USE_EVENT_TRACING_DEBUG], [test "x$enable_event_tracing_debug" = "xyes"])
|
|
||||||
|
|
||||||
if test x$enable_event_tracing_debug = xyes; then
|
|
||||||
AC_DEFINE([USE_EVENT_TRACING_DEBUG], [1], [Tracing framework to log debug])
|
|
||||||
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 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 (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.)
|
dnl so kludge up a replacement for the case where it isn't there yet.)
|
||||||
|
@ -305,13 +232,6 @@ if test "x$PYTHON" = "x"; then
|
||||||
fi
|
fi
|
||||||
AM_CONDITIONAL(USEPYTHON, [test "x$PYTHON" != "x"])
|
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 \
|
|
||||||
"
|
|
||||||
AC_SUBST(rust_crates)
|
|
||||||
|
|
||||||
ifdef([AC_C_FLEXIBLE_ARRAY_MEMBER], [
|
ifdef([AC_C_FLEXIBLE_ARRAY_MEMBER], [
|
||||||
AC_C_FLEXIBLE_ARRAY_MEMBER
|
AC_C_FLEXIBLE_ARRAY_MEMBER
|
||||||
], [
|
], [
|
||||||
|
@ -429,7 +349,6 @@ AH_BOTTOM([
|
||||||
|
|
||||||
|
|
||||||
AM_CONDITIONAL(BUILD_NT_SERVICES, test "x$bwin32" = "xtrue")
|
AM_CONDITIONAL(BUILD_NT_SERVICES, test "x$bwin32" = "xtrue")
|
||||||
AM_CONDITIONAL(BUILD_LIBTORRUNNER, test "x$bwin32" != "xtrue")
|
|
||||||
|
|
||||||
dnl Enable C99 when compiling with MIPSpro
|
dnl Enable C99 when compiling with MIPSpro
|
||||||
AC_MSG_CHECKING([for MIPSpro compiler])
|
AC_MSG_CHECKING([for MIPSpro compiler])
|
||||||
|
@ -448,91 +367,6 @@ fi
|
||||||
|
|
||||||
AC_C_BIGENDIAN
|
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(socket, [socket network])
|
||||||
AC_SEARCH_LIBS(gethostbyname, [nsl])
|
AC_SEARCH_LIBS(gethostbyname, [nsl])
|
||||||
AC_SEARCH_LIBS(dlopen, [dl])
|
AC_SEARCH_LIBS(dlopen, [dl])
|
||||||
|
@ -563,14 +397,12 @@ AC_CHECK_FUNCS(
|
||||||
timingsafe_memcmp \
|
timingsafe_memcmp \
|
||||||
flock \
|
flock \
|
||||||
ftime \
|
ftime \
|
||||||
get_current_dir_name \
|
|
||||||
getaddrinfo \
|
getaddrinfo \
|
||||||
getifaddrs \
|
getifaddrs \
|
||||||
getpass \
|
getpass \
|
||||||
getrlimit \
|
getrlimit \
|
||||||
gettimeofday \
|
gettimeofday \
|
||||||
gmtime_r \
|
gmtime_r \
|
||||||
gnu_get_libc_version \
|
|
||||||
htonll \
|
htonll \
|
||||||
inet_aton \
|
inet_aton \
|
||||||
ioctl \
|
ioctl \
|
||||||
|
@ -578,10 +410,8 @@ AC_CHECK_FUNCS(
|
||||||
llround \
|
llround \
|
||||||
localtime_r \
|
localtime_r \
|
||||||
lround \
|
lround \
|
||||||
mach_approximate_time \
|
|
||||||
memmem \
|
memmem \
|
||||||
memset_s \
|
memset_s \
|
||||||
mmap \
|
|
||||||
pipe \
|
pipe \
|
||||||
pipe2 \
|
pipe2 \
|
||||||
prctl \
|
prctl \
|
||||||
|
@ -608,7 +438,7 @@ AC_CHECK_FUNCS(
|
||||||
# Apple messed up when they added two functions functions in Sierra: they
|
# Apple messed up when they added two functions functions in Sierra: they
|
||||||
# forgot to decorate them with appropriate AVAILABLE_MAC_OS_VERSION
|
# 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
|
# 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_MSG_CHECKING([for a pre-Sierra OSX build target])
|
||||||
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
|
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
|
@ -650,21 +480,6 @@ fi
|
||||||
AM_CONDITIONAL(BUILD_READPASSPHRASE_C,
|
AM_CONDITIONAL(BUILD_READPASSPHRASE_C,
|
||||||
test "x$ac_cv_func_readpassphrase" = "xno" && test "$bwin32" = "false")
|
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 ------------------------------------------------------
|
||||||
dnl Where do you live, libevent? And how do we call you?
|
dnl Where do you live, libevent? And how do we call you?
|
||||||
|
|
||||||
|
@ -674,16 +489,13 @@ if test "$bwin32" = "true"; then
|
||||||
# Some of the cargo-cults recommend -lwsock32 as well, but I don't
|
# Some of the cargo-cults recommend -lwsock32 as well, but I don't
|
||||||
# think it's actually necessary.
|
# think it's actually necessary.
|
||||||
TOR_LIB_GDI=-lgdi32
|
TOR_LIB_GDI=-lgdi32
|
||||||
TOR_LIB_USERENV=-luserenv
|
|
||||||
else
|
else
|
||||||
TOR_LIB_WS32=
|
TOR_LIB_WS32=
|
||||||
TOR_LIB_GDI=
|
TOR_LIB_GDI=
|
||||||
TOR_LIB_USERENV=
|
|
||||||
fi
|
fi
|
||||||
AC_SUBST(TOR_LIB_WS32)
|
AC_SUBST(TOR_LIB_WS32)
|
||||||
AC_SUBST(TOR_LIB_GDI)
|
AC_SUBST(TOR_LIB_GDI)
|
||||||
AC_SUBST(TOR_LIB_IPHLPAPI)
|
AC_SUBST(TOR_LIB_IPHLPAPI)
|
||||||
AC_SUBST(TOR_LIB_USERENV)
|
|
||||||
|
|
||||||
tor_libevent_pkg_redhat="libevent"
|
tor_libevent_pkg_redhat="libevent"
|
||||||
tor_libevent_pkg_debian="libevent-dev"
|
tor_libevent_pkg_debian="libevent-dev"
|
||||||
|
@ -710,13 +522,12 @@ TOR_SEARCH_LIBRARY(libevent, $trylibeventdir, [-levent $STATIC_LIBEVENT_FLAGS $T
|
||||||
#include <winsock2.h>
|
#include <winsock2.h>
|
||||||
#endif
|
#endif
|
||||||
struct event_base;
|
struct event_base;
|
||||||
struct event_base *event_base_new(void);
|
struct event_base *event_base_new(void);],
|
||||||
void event_base_free(struct event_base *);],
|
|
||||||
[
|
[
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
{WSADATA d; WSAStartup(0x101,&d); }
|
{WSADATA d; WSAStartup(0x101,&d); }
|
||||||
#endif
|
#endif
|
||||||
event_base_free(event_base_new());
|
event_base_new();
|
||||||
], [--with-libevent-dir], [/opt/libevent])
|
], [--with-libevent-dir], [/opt/libevent])
|
||||||
|
|
||||||
dnl Determine the incantation needed to link libevent.
|
dnl Determine the incantation needed to link libevent.
|
||||||
|
@ -814,21 +625,11 @@ AC_ARG_WITH(ssl-dir,
|
||||||
fi
|
fi
|
||||||
])
|
])
|
||||||
|
|
||||||
AC_MSG_NOTICE([Now, we'll look for OpenSSL >= 1.0.1])
|
TOR_SEARCH_LIBRARY(openssl, $tryssldir, [-lssl -lcrypto $TOR_LIB_GDI],
|
||||||
TOR_SEARCH_LIBRARY(openssl, $tryssldir, [-lssl -lcrypto $TOR_LIB_GDI $TOR_LIB_WS32],
|
[#include <openssl/rand.h>],
|
||||||
[#include <openssl/ssl.h>
|
[void RAND_add(const void *buf, int num, double entropy);],
|
||||||
char *getenv(const char *);],
|
[RAND_add((void*)0,0,0);], [],
|
||||||
[struct ssl_cipher_st;
|
[/usr/local/openssl /usr/lib/openssl /usr/local/ssl /usr/lib/ssl /usr/local /usr/athena /opt/openssl])
|
||||||
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])
|
|
||||||
|
|
||||||
dnl XXXX check for OPENSSL_VERSION_NUMBER == SSLeay()
|
dnl XXXX check for OPENSSL_VERSION_NUMBER == SSLeay()
|
||||||
|
|
||||||
|
@ -894,38 +695,6 @@ AC_CHECK_MEMBERS([SSL.state], , ,
|
||||||
[#include <openssl/ssl.h>
|
[#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"
|
LIBS="$save_LIBS"
|
||||||
LDFLAGS="$save_LDFLAGS"
|
LDFLAGS="$save_LDFLAGS"
|
||||||
CPPFLAGS="$save_CPPFLAGS"
|
CPPFLAGS="$save_CPPFLAGS"
|
||||||
|
@ -956,80 +725,6 @@ else
|
||||||
fi
|
fi
|
||||||
AC_SUBST(TOR_ZLIB_LIBS)
|
AC_SUBST(TOR_ZLIB_LIBS)
|
||||||
|
|
||||||
dnl ------------------------------------------------------
|
|
||||||
dnl Where we do we find lzma?
|
|
||||||
|
|
||||||
AC_ARG_ENABLE(lzma,
|
|
||||||
AS_HELP_STRING(--enable-lzma, [enable support for the LZMA compression scheme.]),
|
|
||||||
[case "${enableval}" in
|
|
||||||
"yes") lzma=true ;;
|
|
||||||
"no") lzma=false ;;
|
|
||||||
* ) AC_MSG_ERROR(bad value for --enable-lzma) ;;
|
|
||||||
esac], [lzma=auto])
|
|
||||||
|
|
||||||
if test "x$enable_lzma" = "xno"; then
|
|
||||||
have_lzma=no;
|
|
||||||
else
|
|
||||||
PKG_CHECK_MODULES([LZMA],
|
|
||||||
[liblzma],
|
|
||||||
have_lzma=yes,
|
|
||||||
have_lzma=no)
|
|
||||||
|
|
||||||
if test "x$have_lzma" = "xno" ; then
|
|
||||||
AC_MSG_WARN([Unable to find liblzma.])
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
if test "x$have_lzma" = "xyes"; then
|
|
||||||
AC_DEFINE(HAVE_LZMA,1,[Have LZMA])
|
|
||||||
TOR_LZMA_CFLAGS="${LZMA_CFLAGS}"
|
|
||||||
TOR_LZMA_LIBS="${LZMA_LIBS}"
|
|
||||||
fi
|
|
||||||
AC_SUBST(TOR_LZMA_CFLAGS)
|
|
||||||
AC_SUBST(TOR_LZMA_LIBS)
|
|
||||||
|
|
||||||
dnl ------------------------------------------------------
|
|
||||||
dnl Where we do we find zstd?
|
|
||||||
|
|
||||||
AC_ARG_ENABLE(zstd,
|
|
||||||
AS_HELP_STRING(--enable-zstd, [enable support for the Zstandard compression scheme.]),
|
|
||||||
[case "${enableval}" in
|
|
||||||
"yes") zstd=true ;;
|
|
||||||
"no") zstd=false ;;
|
|
||||||
* ) AC_MSG_ERROR(bad value for --enable-zstd) ;;
|
|
||||||
esac], [zstd=auto])
|
|
||||||
|
|
||||||
if test "x$enable_zstd" = "xno"; then
|
|
||||||
have_zstd=no;
|
|
||||||
else
|
|
||||||
PKG_CHECK_MODULES([ZSTD],
|
|
||||||
[libzstd >= 1.1],
|
|
||||||
have_zstd=yes,
|
|
||||||
have_zstd=no)
|
|
||||||
|
|
||||||
if test "x$have_zstd" = "xno" ; then
|
|
||||||
AC_MSG_WARN([Unable to find libzstd.])
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
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)
|
|
||||||
|
|
||||||
dnl ----------------------------------------------------------------------
|
dnl ----------------------------------------------------------------------
|
||||||
dnl Check if libcap is available for capabilities.
|
dnl Check if libcap is available for capabilities.
|
||||||
|
|
||||||
|
@ -1050,7 +745,7 @@ dnl since sometimes the linker will like an option but not be willing to
|
||||||
dnl use it with a build of a library.
|
dnl use it with a build of a library.
|
||||||
|
|
||||||
all_ldflags_for_check="$TOR_LDFLAGS_zlib $TOR_LDFLAGS_openssl $TOR_LDFLAGS_libevent"
|
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_FTRAPV=
|
||||||
CFLAGS_FWRAPV=
|
CFLAGS_FWRAPV=
|
||||||
|
@ -1100,12 +795,12 @@ if test "$fragile_hardening" = "yes"; then
|
||||||
|
|
||||||
TOR_TRY_COMPILE_WITH_CFLAGS([-fsanitize=address], also_link, CFLAGS_ASAN="-fsanitize=address", true)
|
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
|
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
|
fi
|
||||||
|
|
||||||
TOR_TRY_COMPILE_WITH_CFLAGS([-fsanitize=undefined], also_link, CFLAGS_UBSAN="-fsanitize=undefined", true)
|
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
|
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
|
fi
|
||||||
|
|
||||||
TOR_CHECK_CFLAGS([-fno-omit-frame-pointer])
|
TOR_CHECK_CFLAGS([-fno-omit-frame-pointer])
|
||||||
|
@ -1330,7 +1025,6 @@ AC_CHECK_HEADERS([assert.h \
|
||||||
arpa/inet.h \
|
arpa/inet.h \
|
||||||
crt_externs.h \
|
crt_externs.h \
|
||||||
execinfo.h \
|
execinfo.h \
|
||||||
gnu/libc-version.h \
|
|
||||||
grp.h \
|
grp.h \
|
||||||
ifaddrs.h \
|
ifaddrs.h \
|
||||||
inttypes.h \
|
inttypes.h \
|
||||||
|
@ -1346,7 +1040,6 @@ AC_CHECK_HEADERS([assert.h \
|
||||||
pwd.h \
|
pwd.h \
|
||||||
readpassphrase.h \
|
readpassphrase.h \
|
||||||
stdint.h \
|
stdint.h \
|
||||||
stdatomic.h \
|
|
||||||
sys/eventfd.h \
|
sys/eventfd.h \
|
||||||
sys/file.h \
|
sys/file.h \
|
||||||
sys/ioctl.h \
|
sys/ioctl.h \
|
||||||
|
@ -1711,24 +1404,6 @@ if test "$tor_cv_sign_extend" != "no"; then
|
||||||
[Define to 1 iff right-shifting a negative value performs sign-extension])
|
[Define to 1 iff right-shifting a negative value performs sign-extension])
|
||||||
fi
|
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.
|
# Whether we should use the dmalloc memory allocation debugging library.
|
||||||
AC_MSG_CHECKING(whether to use dmalloc (debug memory allocation library))
|
AC_MSG_CHECKING(whether to use dmalloc (debug memory allocation library))
|
||||||
AC_ARG_WITH(dmalloc,
|
AC_ARG_WITH(dmalloc,
|
||||||
|
@ -1778,6 +1453,14 @@ AC_CHECK_DECLS([mlockall], , , [
|
||||||
#include <sys/mman.h>
|
#include <sys/mman.h>
|
||||||
#endif])
|
#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
|
# Allow user to specify an alternate syslog facility
|
||||||
AC_ARG_WITH(syslog-facility,
|
AC_ARG_WITH(syslog-facility,
|
||||||
AS_HELP_STRING(--with-syslog-facility=LOG, [syslog facility to use (default=LOG_DAEMON)]),
|
AS_HELP_STRING(--with-syslog-facility=LOG, [syslog facility to use (default=LOG_DAEMON)]),
|
||||||
|
@ -1915,12 +1598,6 @@ AC_SUBST(BUILDDIR)
|
||||||
AH_TEMPLATE([BUILDDIR],[tor's build directory])
|
AH_TEMPLATE([BUILDDIR],[tor's build directory])
|
||||||
AC_DEFINE_UNQUOTED(BUILDDIR,"$BUILDDIR")
|
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
|
if test "x$CONFDIR" = "x"; then
|
||||||
CONFDIR=`eval echo $sysconfdir/tor`
|
CONFDIR=`eval echo $sysconfdir/tor`
|
||||||
fi
|
fi
|
||||||
|
@ -2102,6 +1779,7 @@ if test "x$enable_gcc_warnings_advisory" != "xno"; then
|
||||||
-Winvalid-source-encoding
|
-Winvalid-source-encoding
|
||||||
-Winvalid-token-paste
|
-Winvalid-token-paste
|
||||||
-Wknr-promoted-parameter
|
-Wknr-promoted-parameter
|
||||||
|
-Wlanguage-extension-token
|
||||||
-Wlarge-by-value-copy
|
-Wlarge-by-value-copy
|
||||||
-Wliteral-conversion
|
-Wliteral-conversion
|
||||||
-Wliteral-range
|
-Wliteral-range
|
||||||
|
@ -2127,7 +1805,7 @@ if test "x$enable_gcc_warnings_advisory" != "xno"; then
|
||||||
-Wnon-literal-null-conversion
|
-Wnon-literal-null-conversion
|
||||||
-Wnon-pod-varargs
|
-Wnon-pod-varargs
|
||||||
-Wnonportable-cfstrings
|
-Wnonportable-cfstrings
|
||||||
-Wnormalized=nfkc
|
-Wnormalized=id
|
||||||
-Wnull-arithmetic
|
-Wnull-arithmetic
|
||||||
-Wnull-character
|
-Wnull-character
|
||||||
-Wnull-conversion
|
-Wnull-conversion
|
||||||
|
@ -2267,7 +1945,6 @@ AC_CONFIG_FILES([
|
||||||
contrib/dist/tor.service
|
contrib/dist/tor.service
|
||||||
src/config/torrc.sample
|
src/config/torrc.sample
|
||||||
src/config/torrc.minimal
|
src/config/torrc.minimal
|
||||||
src/rust/.cargo/config
|
|
||||||
scripts/maint/checkOptionDocs.pl
|
scripts/maint/checkOptionDocs.pl
|
||||||
scripts/maint/updateVersions.pl
|
scripts/maint/updateVersions.pl
|
||||||
])
|
])
|
||||||
|
|
|
@ -87,7 +87,7 @@ RATE_UP=5000
|
||||||
# machine does any other network activity. That is not very fun.
|
# machine does any other network activity. That is not very fun.
|
||||||
RATE_UP_TOR=1500
|
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.
|
# kbits/sec.
|
||||||
RATE_UP_TOR_CEIL=5000
|
RATE_UP_TOR_CEIL=5000
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
!include "LogicLib.nsh"
|
!include "LogicLib.nsh"
|
||||||
!include "FileFunc.nsh"
|
!include "FileFunc.nsh"
|
||||||
!insertmacro GetParameters
|
!insertmacro GetParameters
|
||||||
!define VERSION "0.3.4.1-alpha-dev"
|
!define VERSION "0.3.0.13-dev"
|
||||||
!define INSTALLER "tor-${VERSION}-win32.exe"
|
!define INSTALLER "tor-${VERSION}-win32.exe"
|
||||||
!define WEBSITE "https://www.torproject.org/"
|
!define WEBSITE "https://www.torproject.org/"
|
||||||
!define LICENSE "LICENSE"
|
!define LICENSE "LICENSE"
|
||||||
|
|
|
@ -4,10 +4,9 @@ Coding conventions for Tor
|
||||||
tl;dr:
|
tl;dr:
|
||||||
|
|
||||||
- Run configure with `--enable-fatal-warnings`
|
- Run configure with `--enable-fatal-warnings`
|
||||||
|
- Run `make check-spaces` to catch whitespace errors
|
||||||
- Document your functions
|
- Document your functions
|
||||||
- Write unit tests
|
- Write unit tests
|
||||||
- Run `make check` before submitting a patch
|
|
||||||
- Run `make distcheck` if you have made changes to build system components
|
|
||||||
- Add a file in `changes` for your branch.
|
- Add a file in `changes` for your branch.
|
||||||
|
|
||||||
Patch checklist
|
Patch checklist
|
||||||
|
@ -23,42 +22,13 @@ preference)
|
||||||
Did you remember...
|
Did you remember...
|
||||||
|
|
||||||
- To build your code while configured with `--enable-fatal-warnings`?
|
- To build your code while configured with `--enable-fatal-warnings`?
|
||||||
|
- To run `make check-spaces` on your code?
|
||||||
- To run `make check-docs` to see whether all new options are on
|
- To run `make check-docs` to see whether all new options are on
|
||||||
the manpage?
|
the manpage?
|
||||||
- To write unit tests, as possible?
|
- To write unit tests, as possible?
|
||||||
- To run `make test-full` to test against all unit and integration tests (or
|
|
||||||
`make test-full-online` if you have a working connection to the internet)?
|
|
||||||
- To test that the distribution will actually work via `make distcheck`?
|
|
||||||
- To base your code on the appropriate branch?
|
- To base your code on the appropriate branch?
|
||||||
- To include a file in the `changes` directory as appropriate?
|
- 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
|
How we use Git branches
|
||||||
=======================
|
=======================
|
||||||
|
|
||||||
|
@ -79,17 +49,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,
|
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
|
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.)
|
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, 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.
|
|
||||||
|
|
||||||
|
|
||||||
How we log changes
|
How we log changes
|
||||||
|
@ -113,34 +74,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
|
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
|
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,
|
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
|
you can use `make check-changes`.
|
||||||
`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".
|
|
||||||
|
|
||||||
When we go to make a release, we will concatenate all the entries
|
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
|
in changes to make a draft changelog, and clear the directory. We'll
|
||||||
then edit the draft changelog into a nice readable format.
|
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?
|
What needs a changes file?
|
||||||
|
|
||||||
* A not-exhaustive list: Anything that might change user-visible
|
* A not-exhaustive list: Anything that might change user-visible
|
||||||
|
@ -209,79 +153,6 @@ old C functions. Use `strlcat`, `strlcpy`, or `tor_snprintf/tor_asprintf` inste
|
||||||
We don't call `memcmp()` directly. Use `fast_memeq()`, `fast_memneq()`,
|
We don't call `memcmp()` directly. Use `fast_memeq()`, `fast_memneq()`,
|
||||||
`tor_memeq()`, or `tor_memneq()` for most purposes.
|
`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
|
Functions not to write
|
||||||
----------------------
|
----------------------
|
||||||
|
|
||||||
|
@ -343,64 +214,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
|
with a string like "internal error"). Option (A) is to be preferred to
|
||||||
option (B).
|
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
|
Doxygen comment conventions
|
||||||
|
@ -434,4 +247,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
|
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,
|
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.
|
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
|
If you are looking for a more bare-bones, less user-friendly information
|
||||||
dump of important information, you might like reading the "torguts"
|
dump of important information, you might like reading doc/HACKING
|
||||||
documents linked to below. You should probably read it before you write
|
instead. You should probably read it before you write your first patch.
|
||||||
your first patch.
|
|
||||||
|
|
||||||
|
|
||||||
Required background
|
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
|
These aren't strictly necessary for hacking on Tor, but they can help track
|
||||||
down bugs.
|
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
|
Jenkins
|
||||||
-------
|
-------
|
||||||
|
|
||||||
|
@ -127,18 +111,14 @@ Running gcov for unit test coverage
|
||||||
|
|
||||||
(On OSX, you'll need to start with `--enable-coverage CC=clang`.)
|
(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
|
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
|
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.
|
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
|
If that doesn't work:
|
||||||
gcov](https://gcc.gnu.org/onlinedocs/gcc/Invoking-Gcov.html) chapter
|
|
||||||
of the GCC manual.
|
* 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,
|
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.
|
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
|
./scripts/test/cov-diff coverage-output1 coverage-output2 | less
|
||||||
|
|
||||||
In this diff, any lines that were visited at least once will have coverage "1",
|
In this diff, any lines that were visited at least once will have coverage
|
||||||
and line numbers are deleted. This lets you inspect what you (probably) really
|
"1". This lets you inspect what you (probably) really want to know: which
|
||||||
want to know: which untested lines were changed? Are there any new untested
|
untested lines were changed? Are there any new untested lines?
|
||||||
lines?
|
|
||||||
|
|
||||||
If you run ./scripts/test/cov-exclude, it marks excluded unreached
|
|
||||||
lines with 'x', and excluded reached lines with '!!!'.
|
|
||||||
|
|
||||||
Running integration tests
|
Running integration tests
|
||||||
-------------------------
|
-------------------------
|
||||||
|
@ -250,10 +226,17 @@ performance! See the gperftools manual for more info, but basically:
|
||||||
Generating and analyzing a callgraph
|
Generating and analyzing a callgraph
|
||||||
------------------------------------
|
------------------------------------
|
||||||
|
|
||||||
0. Build Tor on linux or mac, ideally with -O0 or -fno-inline.
|
1. Run `./scripts/maint/generate_callgraph.sh`. This will generate a
|
||||||
|
bunch of files in a new ./callgraph directory.
|
||||||
|
|
||||||
1. Clone 'https://gitweb.torproject.org/user/nickm/calltool.git/' .
|
2. Run `./scripts/maint/analyze_callgraph.py callgraph/src/*/*`. This
|
||||||
Follow the README in that repository.
|
will do a lot of graph operations and then dump out a new
|
||||||
|
`callgraph.pkl` file, containing data in Python's 'pickle' format.
|
||||||
|
|
||||||
|
3. Run `./scripts/maint/display_callgraph.py`. It will display:
|
||||||
|
- the number of functions reachable from each function.
|
||||||
|
- all strongly-connnected components in the Tor callgraph
|
||||||
|
- the largest bottlenecks in the largest SCC in the Tor callgraph.
|
||||||
|
|
||||||
Note that currently the callgraph generator can't detect calls that pass
|
Note that currently the callgraph generator can't detect calls that pass
|
||||||
through function pointers.
|
through function pointers.
|
||||||
|
|
|
@ -19,8 +19,6 @@ Top-level smell-checks
|
||||||
|
|
||||||
- Does `make check-spaces` pass?
|
- Does `make check-spaces` pass?
|
||||||
|
|
||||||
- Does `make check-changes` pass?
|
|
||||||
|
|
||||||
- Does it have a reasonable amount of tests? Do they pass? Do they leak
|
- Does it have a reasonable amount of tests? Do they pass? Do they leak
|
||||||
memory?
|
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 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!
|
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
|
=== 0. Preliminaries
|
||||||
|
|
||||||
1. Get at least three of weasel/arma/Sebastian/Sina to put the new
|
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
|
version number in their approved versions list.
|
||||||
days to do this if you can.
|
|
||||||
|
|
||||||
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
|
=== I. Make sure it works
|
||||||
|
|
||||||
|
@ -25,7 +18,6 @@ new Tor release:
|
||||||
resolve those.
|
resolve those.
|
||||||
|
|
||||||
As applicable, merge the `maint-X` branch into the `release-X` branch.
|
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.
|
2. Are all of the jenkins builders happy? See jenkins.torproject.org.
|
||||||
|
|
||||||
|
@ -34,37 +26,39 @@ new Tor release:
|
||||||
|
|
||||||
What about Coverity Scan?
|
What about Coverity Scan?
|
||||||
|
|
||||||
What about clang scan-build?
|
Is make check-spaces happy?
|
||||||
|
|
||||||
Does 'make distcheck' complain?
|
Does 'make distcheck' complain?
|
||||||
|
|
||||||
How about 'make test-stem' and 'make test-network' and
|
How about 'make test-stem' and 'make test-network'?
|
||||||
`make test-network-full`?
|
|
||||||
|
|
||||||
- Are all those tests still happy with --enable-expensive-hardening ?
|
- Are all those tests still happy with --enable-expensive-hardening ?
|
||||||
|
|
||||||
Any memory leaks?
|
Any memory leaks?
|
||||||
|
|
||||||
|
|
||||||
=== II. Write a changelog
|
=== II. Write a changelog.
|
||||||
|
|
||||||
|
|
||||||
1a. (Alpha release variant)
|
1. Gather the `changes/*` files into a changelog entry, rewriting many
|
||||||
|
|
||||||
Gather the `changes/*` files into a changelog entry, rewriting many
|
|
||||||
of them and reordering to focus on what users and funders would find
|
of them and reordering to focus on what users and funders would find
|
||||||
interesting and understandable.
|
interesting and understandable.
|
||||||
|
|
||||||
To do this, first run `./scripts/maint/lintChanges.py changes/*` and
|
1. Make sure that everything that wants a bug number has one.
|
||||||
fix as many warnings as you can. Then run `./scripts/maint/sortChanges.py
|
Make sure that everything which is a bugfix says what version
|
||||||
changes/* > changelog.in` to combine headings and sort the entries.
|
it was a bugfix on.
|
||||||
After that, it's time to hand-edit and fix the issues that lintChanges
|
|
||||||
can't find:
|
|
||||||
|
|
||||||
1. Within each section, sort by "version it's a bugfix on", else by
|
2. Concatenate them.
|
||||||
numerical ticket order.
|
|
||||||
|
|
||||||
2. Clean them up:
|
3. Sort them by section. Within each section, sort by "version it's
|
||||||
|
a bugfix on", else by numerical ticket order.
|
||||||
|
|
||||||
|
4. Clean them up:
|
||||||
|
|
||||||
|
Standard idioms:
|
||||||
|
`Fixes bug 9999; bugfix on 0.3.3.3-alpha.`
|
||||||
|
|
||||||
|
One space after a period.
|
||||||
|
|
||||||
Make stuff very terse
|
Make stuff very terse
|
||||||
|
|
||||||
|
@ -92,32 +86,19 @@ new Tor release:
|
||||||
maint-0.2.1), be sure to make the stanzas identical (so people can
|
maint-0.2.1), be sure to make the stanzas identical (so people can
|
||||||
distinguish if these are the same change).
|
distinguish if these are the same change).
|
||||||
|
|
||||||
3. Clean everything one last time.
|
5. Merge them in.
|
||||||
|
|
||||||
4. Run `./scripts/maint/format_changelog.py --inplace` to make it prettier
|
6. Clean everything one last time.
|
||||||
|
|
||||||
1b. (old-stable release variant)
|
7. Run `./scripts/maint/format_changelog.py` to make it prettier.
|
||||||
|
|
||||||
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
|
2. Compose a short release blurb to highlight the user-facing
|
||||||
changes. Insert said release blurb into the ChangeLog stanza. If it's
|
changes. Insert said release blurb into the ChangeLog stanza. If it's
|
||||||
a stable release, add it to the ReleaseNotes file too. If we're adding
|
a stable release, add it to the ReleaseNotes file too. If we're adding
|
||||||
to a release-* branch, manually commit the changelogs to the later
|
to a release-0.2.x branch, manually commit the changelogs to the later
|
||||||
git branches too.
|
git branches too.
|
||||||
|
|
||||||
3. If there are changes that require or suggest operator intervention
|
3. If you're doing the first stable release in a series, you need to
|
||||||
before or during the update, mail operators (either dirauth or relays
|
|
||||||
list) with a headline that indicates that an action is required or
|
|
||||||
appreciated.
|
|
||||||
|
|
||||||
4. If you're doing the first stable release in a series, you need to
|
|
||||||
create a ReleaseNotes for the series as a whole. To get started
|
create a ReleaseNotes for the series as a whole. To get started
|
||||||
there, copy all of the Changelog entries from the series into a new
|
there, copy all of the Changelog entries from the series into a new
|
||||||
file, and run `./scripts/maint/sortChanges.py` on it. That will
|
file, and run `./scripts/maint/sortChanges.py` on it. That will
|
||||||
|
@ -130,61 +111,51 @@ new Tor release:
|
||||||
|
|
||||||
=== III. Making the source release.
|
=== III. Making the source release.
|
||||||
|
|
||||||
1. In `maint-0.?.x`, bump the version number in `configure.ac` and run
|
1. In `maint-0.2.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`.
|
places, and commit. Then merge `maint-0.2.x` into `release-0.2.x`.
|
||||||
|
|
||||||
(NOTE: To bump the version number, edit `configure.ac`, and then run
|
(NOTE: To bump the version number, edit `configure.ac`, and then run
|
||||||
either `make`, or `perl scripts/maint/updateVersions.pl`, depending on
|
either `make`, or `perl scripts/maint/updateVersions.pl`, depending on
|
||||||
your version.)
|
your version.)
|
||||||
|
|
||||||
When you merge the maint branch forward to the next maint branch, or into
|
2. Make distcheck, put the tarball up somewhere, and tell `#tor` about
|
||||||
master, merge it with "-s ours" to avoid a needless version bump.
|
it. Wait a while to see if anybody has problems building it. Try to
|
||||||
|
get Sebastian or somebody to try building it on Windows.
|
||||||
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.
|
|
||||||
(Though jenkins is usually pretty good about catching these things.)
|
|
||||||
|
|
||||||
=== IV. Commit, upload, announce
|
=== IV. Commit, upload, announce
|
||||||
|
|
||||||
1. Sign the tarball, then sign and push the git tag:
|
1. Sign the tarball, then sign and push the git tag:
|
||||||
|
|
||||||
gpg -ba <the_tarball>
|
gpg -ba <the_tarball>
|
||||||
git tag -u <keyid> tor-0.3.x.y-status
|
git tag -u <keyid> tor-0.2.x.y-status
|
||||||
git push origin tag tor-0.3.x.y-status
|
git push origin tag tor-0.2.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.
|
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
|
`/srv/dist-master.torproject.org/htdocs/` on dist-master. When you want
|
||||||
it to go live, you run "static-update-component dist.torproject.org"
|
it to go live, you run "static-update-component dist.torproject.org"
|
||||||
on dist-master.
|
on dist-master.
|
||||||
|
|
||||||
In the webwml.git repository, `include/versions.wmi` and `Makefile`
|
Edit `include/versions.wmi` and `Makefile` to note the new version.
|
||||||
to note the new version.
|
|
||||||
|
|
||||||
(NOTE: Due to #17805, there can only be one stable version listed at
|
(NOTE: Due to #17805, there can only be one stable version listed at
|
||||||
once. Nonetheless, do not call your version "alpha" if it is stable,
|
once. Nonetheless, do not call your version "alpha" if it is stable,
|
||||||
or people will get confused.)
|
or people will get confused.)
|
||||||
|
|
||||||
3. Email the packagers (cc'ing tor-team) that a new tarball is up.
|
3. Email the packagers (cc'ing tor-assistants) that a new tarball is up.
|
||||||
The current list of packagers is:
|
The current list of packagers is:
|
||||||
|
|
||||||
- {weasel,gk,mikeperry} at torproject dot org
|
- {weasel,gk,mikeperry} at torproject dot org
|
||||||
- {blueness} at gentoo dot org
|
- {blueness} at gentoo dot org
|
||||||
- {paul} at invizbox dot io
|
- {paul} at invizbox dot io
|
||||||
- {vincent} at invizbox dot com
|
|
||||||
- {lfleischer} at archlinux dot org
|
- {lfleischer} at archlinux dot org
|
||||||
- {Nathan} at freitas dot net
|
- {Nathan} at freitas dot net
|
||||||
- {mike} at tig dot as
|
- {mike} at tig dot as
|
||||||
- {tails-rm} at boum dot org
|
- {tails-rm} at boum dot org (for pre-release announcments)
|
||||||
- {simon} at sdeziel.info
|
|
||||||
- {yuri} at freebsd.org
|
|
||||||
- {mh+tor} at scrit.ch
|
- {tails-dev} at boum dot org (for at-release announcements)
|
||||||
|
|
||||||
Also, email tor-packagers@lists.torproject.org.
|
|
||||||
|
|
||||||
4. Add the version number to Trac. To do this, go to Trac, log in,
|
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
|
select "Admin" near the top of the screen, then select "Versions" from
|
||||||
|
@ -193,28 +164,24 @@ new Tor release:
|
||||||
0.2.2.23-alpha" (or whatever the version is), and we select the date as
|
0.2.2.23-alpha" (or whatever the version is), and we select the date as
|
||||||
the date in the ChangeLog.
|
the date in the ChangeLog.
|
||||||
|
|
||||||
5. Double-check: did the version get recommended in the consensus yet? Is
|
5. Mail the release blurb and ChangeLog to tor-talk (development release) or
|
||||||
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
|
|
||||||
tor-announce (stable).
|
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
|
blog-formatted version of the changelog with the -B option to
|
||||||
format-changelog.
|
format-changelog.
|
||||||
|
|
||||||
When you post, include an estimate of when the next TorBrowser
|
When you post, include an estimate of when the next TorBrowser releases
|
||||||
releases will come out that include this Tor release. This will
|
will come out that include this Tor release.
|
||||||
usually track https://wiki.mozilla.org/RapidRelease/Calendar , but it
|
|
||||||
can vary.
|
|
||||||
|
|
||||||
|
|
||||||
=== V. Aftermath and cleanup
|
=== V. Aftermath and cleanup
|
||||||
|
|
||||||
1. If it's a stable release, bump the version number in the
|
1. If it's a stable release, bump the version number in the `maint-x.y.z`
|
||||||
`maint-x.y.z` branch to "newversion-dev", and do a `merge -s ours`
|
branch to "newversion-dev", and do a `merge -s ours` merge to avoid
|
||||||
merge to avoid taking that change into master.
|
taking that change into master. Do a similar `merge -s theirs`
|
||||||
|
merge to get the change (and only that change) into release. (Some
|
||||||
|
of the build scripts require that maint merge cleanly into release.)
|
||||||
|
|
||||||
2. Forward-port the ChangeLog (and ReleaseNotes if appropriate).
|
2. Forward-port the ChangeLog (and ReleaseNotes if appropriate).
|
||||||
|
|
||||||
|
|
|
@ -1,91 +0,0 @@
|
||||||
# Tracing #
|
|
||||||
|
|
||||||
This document describes how the event tracing subsystem works in tor so
|
|
||||||
developers can add events to the code base but also hook them to an event
|
|
||||||
tracing framework.
|
|
||||||
|
|
||||||
## Basics ###
|
|
||||||
|
|
||||||
Event tracing is separated 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.
|
|
||||||
|
|
||||||
### Events ###
|
|
||||||
|
|
||||||
A trace event is basically a function from which we can pass any data that
|
|
||||||
we want to collect. In addition, we specify a context for the event such as
|
|
||||||
a subsystem and an event name.
|
|
||||||
|
|
||||||
A trace event in tor has the following standard format:
|
|
||||||
|
|
||||||
tor_trace(subsystem, event\_name, args...)
|
|
||||||
|
|
||||||
The `subsystem` parameter is the name of the subsytem the trace event is in.
|
|
||||||
For example that could be "scheduler" or "vote" or "hs". The idea is to add
|
|
||||||
some context to the event so when we collect them we know where it's coming
|
|
||||||
from. The `event_name` is the name of the event which helps a lot with
|
|
||||||
adding some semantic to the event. Finally, `args` is any number of
|
|
||||||
arguments we want to collect.
|
|
||||||
|
|
||||||
Here is an example of a possible tracepoint in main():
|
|
||||||
|
|
||||||
tor_trace(main, init_phase, argc)
|
|
||||||
|
|
||||||
The above is a tracepoint in the `main` subsystem with `init_phase` as the
|
|
||||||
event name and the `int argc` is passed to the event as well.
|
|
||||||
|
|
||||||
How `argc` is collected or used has nothing to do with the instrumentation
|
|
||||||
(adding trace events to the code). It is the work of the tracer so this is why
|
|
||||||
the trace events and collection framework (tracer) are decoupled. You _can_
|
|
||||||
have trace events without a tracer.
|
|
||||||
|
|
||||||
### Tracer ###
|
|
||||||
|
|
||||||
In `src/trace/events.h`, we map the `tor_trace()` function to the right
|
|
||||||
tracer. A tracer support is only enabled at compile time. For instance, the
|
|
||||||
file `src/trace/debug.h` contains the mapping of the generic tracing function
|
|
||||||
`tor_trace()` to the `log_debug()` function. More specialized function can be
|
|
||||||
mapped depending on the tracepoint.
|
|
||||||
|
|
||||||
## Build System ##
|
|
||||||
|
|
||||||
This section describes how it is integrated into the build system of tor.
|
|
||||||
|
|
||||||
By default, every tracing events are disabled in tor that is `tor_trace()`
|
|
||||||
is a NOP.
|
|
||||||
|
|
||||||
To enable a tracer, there is a configure option on the form of:
|
|
||||||
|
|
||||||
--enable-tracing-<tracer>
|
|
||||||
|
|
||||||
We have an option that will send every trace events to a `log_debug()` (as
|
|
||||||
mentionned above) which will print you the subsystem and name of the event but
|
|
||||||
not the arguments for technical reasons. This is useful if you want to quickly
|
|
||||||
see if your trace event is being hit or well written. To do so, use this
|
|
||||||
configure option:
|
|
||||||
|
|
||||||
--enable-tracing-debug
|
|
||||||
|
|
||||||
## Instrument Tor ##
|
|
||||||
|
|
||||||
This is pretty easy. Let's say you want to add a trace event in
|
|
||||||
`src/or/rendcache.c`, you only have to add this include statement:
|
|
||||||
|
|
||||||
#include "trace/events.h"
|
|
||||||
|
|
||||||
Once done, you can add as many as you want `tor_trace()` that you need.
|
|
||||||
Please use the right subsystem (here it would be `hs`) and a unique name that
|
|
||||||
tells what the event is for. For example:
|
|
||||||
|
|
||||||
tor_trace(hs, store_desc_as_client, desc, desc_id);
|
|
||||||
|
|
||||||
If you look in `src/trace/events.h`, you'll see that if tracing is enabled it
|
|
||||||
will be mapped to a function called:
|
|
||||||
|
|
||||||
tor_trace_hs_store_desc_as_client(desc, desc_id)
|
|
||||||
|
|
||||||
And the point of all this is for that function to be defined in a new file
|
|
||||||
that you might want to add named `src/trace/hs.{c|h}` which would defined how
|
|
||||||
to collect the data for the `tor_trace_hs_store_desc_as_client()` function
|
|
||||||
like for instance sending it to a `log_debug()` or do more complex operations
|
|
||||||
or use a userspace tracer like LTTng (https://lttng.org).
|
|
|
@ -91,9 +91,6 @@ coverage percentage.
|
||||||
For a summary of the test coverage for each _function_, run
|
For a summary of the test coverage for each _function_, run
|
||||||
`./scripts/test/cov-display -f ${TMPDIR}/*`.
|
`./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
|
### Comparing test coverage
|
||||||
|
|
||||||
Sometimes it's useful to compare test coverage for a branch you're writing to
|
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.
|
lcov don't understand these lines.
|
||||||
|
|
||||||
You can post-process .gcov files to make these lines 'unreached' by
|
You can post-process .gcov files to make these lines 'unreached' by
|
||||||
running ./scripts/test/cov-exclude on them. It marks excluded
|
running ./scripts/test/cov-exclude on them.
|
||||||
unreached lines with 'x', and excluded reached lines with '!!!'.
|
|
||||||
|
|
||||||
Note: you should never do this unless the line is meant to 100%
|
Note: you should never do this unless the line is meant to 100%
|
||||||
unreachable by actual code.
|
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/TUNING \
|
||||||
doc/HACKING/README.1st.md \
|
doc/HACKING/README.1st.md \
|
||||||
doc/HACKING/CodingStandards.md \
|
doc/HACKING/CodingStandards.md \
|
||||||
doc/HACKING/CodingStandardsRust.md \
|
|
||||||
doc/HACKING/Fuzzing.md \
|
|
||||||
doc/HACKING/GettingStarted.md \
|
doc/HACKING/GettingStarted.md \
|
||||||
doc/HACKING/GettingStartedRust.md \
|
|
||||||
doc/HACKING/HelpfulTools.md \
|
doc/HACKING/HelpfulTools.md \
|
||||||
doc/HACKING/HowToReview.md \
|
doc/HACKING/HowToReview.md \
|
||||||
doc/HACKING/Module.md \
|
|
||||||
doc/HACKING/ReleasingTor.md \
|
doc/HACKING/ReleasingTor.md \
|
||||||
doc/HACKING/Tracing.md \
|
|
||||||
doc/HACKING/WritingTests.md
|
doc/HACKING/WritingTests.md
|
||||||
|
|
||||||
docdir = @docdir@
|
docdir = @docdir@
|
||||||
|
|
1272
doc/tor.1.txt
1272
doc/tor.1.txt
File diff suppressed because it is too large
Load Diff
|
@ -17,23 +17,25 @@ SYNOPSIS
|
||||||
|
|
||||||
DESCRIPTION
|
DESCRIPTION
|
||||||
-----------
|
-----------
|
||||||
**torify** is a simple wrapper that calls torsocks with a tor-specific
|
**torify** is a simple wrapper that attempts to find the best underlying Tor
|
||||||
configuration file.
|
wrapper available on a system. It calls torsocks with a tor specific
|
||||||
|
configuration file. +
|
||||||
|
|
||||||
It is provided for backward compatibility; instead you should use torsocks.
|
torsocks is an improved wrapper that explicitly rejects UDP, safely resolves DNS
|
||||||
|
lookups and properly socksifies your TCP connections. +
|
||||||
|
|
||||||
|
Please note that since both method use LD_PRELOAD, torify cannot be applied to
|
||||||
|
suid binaries.
|
||||||
|
|
||||||
WARNING
|
WARNING
|
||||||
-------
|
-------
|
||||||
When used with torsocks, torify should not leak DNS requests or UDP data.
|
When used with torsocks, torify should not leak DNS requests or UDP data. +
|
||||||
|
|
||||||
torify can leak ICMP data.
|
Both will leak ICMP data.
|
||||||
|
|
||||||
torify will not ensure that different requests are processed on
|
|
||||||
different circuits.
|
|
||||||
|
|
||||||
SEE ALSO
|
SEE ALSO
|
||||||
--------
|
--------
|
||||||
**tor**(1), **torsocks**(1)
|
**tor**(1), **tor-resolve**(1), **torsocks**(1)
|
||||||
|
|
||||||
AUTHORS
|
AUTHORS
|
||||||
-------
|
-------
|
||||||
|
|
|
@ -18,10 +18,9 @@ does, not what it should do.
|
||||||
; specified in RFC5234.
|
; specified in RFC5234.
|
||||||
|
|
||||||
; A file is interpreted as every Entry in the file, in order.
|
; A file is interpreted as every Entry in the file, in order.
|
||||||
TorrcFile = *Line [ UnterminatedLine ]
|
TorrcFile = *Line
|
||||||
|
|
||||||
Line = BlankLine LF / Entry LF
|
Line = BlankLine / Entry
|
||||||
UnterminatedLine = BlankLine / Entry
|
|
||||||
|
|
||||||
BlankLine = *WSP OptComment LF
|
BlankLine = *WSP OptComment LF
|
||||||
BlankLine =/ *WSP LF
|
BlankLine =/ *WSP LF
|
||||||
|
@ -70,12 +69,6 @@ does, not what it should do.
|
||||||
; Anything besides NUL and LF
|
; Anything besides NUL and LF
|
||||||
NonLF = %x01-%x09 / %x0b - %xff
|
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'
|
OCTDIG = '0' - '7'
|
||||||
|
|
||||||
KC = Any character except an isspace() character or '#' or NUL
|
KC = Any character except an isspace() character or '#' or NUL
|
||||||
|
@ -182,7 +175,7 @@ and\
|
||||||
friends
|
friends
|
||||||
|
|
||||||
# Backslashes in the middle of a line are included as-is. The key of
|
# Backslashes in the middle of a line are included as-is. The key of
|
||||||
# this one is "Too" and the value is "Many\\Backsl\ashes \here" (with
|
# this one is "Too" and the value is "Many\\Backsl\ashes here" (with
|
||||||
# backslashes in that last string as-is)
|
# backslashes in that last string as-is)
|
||||||
Too \
|
Too \
|
||||||
Many\\\
|
Many\\\
|
||||||
|
@ -192,7 +185,7 @@ here
|
||||||
# And here's the really yucky part. If a comment appears in a multi-line
|
# And here's the really yucky part. If a comment appears in a multi-line
|
||||||
# entry, the entry is still able to continue on the next line, as in the
|
# entry, the entry is still able to continue on the next line, as in the
|
||||||
# following, where the key is "This" and the value is
|
# following, where the key is "This" and the value is
|
||||||
# "entry and some are silly"
|
# "entry and some are silly"
|
||||||
This entry \
|
This entry \
|
||||||
# has comments \
|
# has comments \
|
||||||
and some \
|
and some \
|
||||||
|
|
|
@ -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()
|
|
|
@ -1,160 +0,0 @@
|
||||||
#!/usr/bin/python
|
|
||||||
|
|
||||||
FUZZERS = """
|
|
||||||
consensus
|
|
||||||
descriptor
|
|
||||||
diff
|
|
||||||
diff-apply
|
|
||||||
extrainfo
|
|
||||||
hsdescv2
|
|
||||||
hsdescv3
|
|
||||||
http
|
|
||||||
http-connect
|
|
||||||
iptsv2
|
|
||||||
microdesc
|
|
||||||
vrs
|
|
||||||
"""
|
|
||||||
|
|
||||||
|
|
||||||
PREAMBLE = r"""
|
|
||||||
FUZZING_CPPFLAGS = \
|
|
||||||
$(src_test_AM_CPPFLAGS) $(TEST_CPPFLAGS)
|
|
||||||
FUZZING_CFLAGS = \
|
|
||||||
$(AM_CFLAGS) $(TEST_CFLAGS)
|
|
||||||
FUZZING_LDFLAG = \
|
|
||||||
@TOR_LDFLAGS_zlib@ @TOR_LDFLAGS_openssl@ @TOR_LDFLAGS_libevent@
|
|
||||||
FUZZING_LIBS = \
|
|
||||||
src/or/libtor-testing.a \
|
|
||||||
src/common/libor-crypto-testing.a \
|
|
||||||
$(LIBKECCAK_TINY) \
|
|
||||||
$(LIBDONNA) \
|
|
||||||
src/common/libor-testing.a \
|
|
||||||
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_SYSTEMD_LIBS@ \
|
|
||||||
@TOR_LZMA_LIBS@ \
|
|
||||||
@TOR_ZSTD_LIBS@
|
|
||||||
|
|
||||||
oss-fuzz-prereqs: \
|
|
||||||
src/or/libtor-testing.a \
|
|
||||||
src/common/libor-crypto-testing.a \
|
|
||||||
$(LIBKECCAK_TINY) \
|
|
||||||
$(LIBDONNA) \
|
|
||||||
src/common/libor-testing.a \
|
|
||||||
src/common/libor-ctime-testing.a \
|
|
||||||
src/common/libor-event-testing.a \
|
|
||||||
src/trunnel/libor-trunnel-testing.a
|
|
||||||
|
|
||||||
noinst_HEADERS += \
|
|
||||||
src/test/fuzz/fuzzing.h
|
|
||||||
|
|
||||||
LIBFUZZER = -lFuzzer
|
|
||||||
LIBFUZZER_CPPFLAGS = $(FUZZING_CPPFLAGS) -DLLVM_FUZZ
|
|
||||||
LIBFUZZER_CFLAGS = $(FUZZING_CFLAGS)
|
|
||||||
LIBFUZZER_LDFLAG = $(FUZZING_LDFLAG)
|
|
||||||
LIBFUZZER_LIBS = $(FUZZING_LIBS) $(LIBFUZZER) -lstdc++
|
|
||||||
|
|
||||||
LIBOSS_FUZZ_CPPFLAGS = $(FUZZING_CPPFLAGS) -DLLVM_FUZZ
|
|
||||||
LIBOSS_FUZZ_CFLAGS = $(FUZZING_CFLAGS)
|
|
||||||
"""
|
|
||||||
|
|
||||||
POSTAMBLE = r"""
|
|
||||||
noinst_PROGRAMS += $(FUZZERS) $(LIBFUZZER_FUZZERS)
|
|
||||||
noinst_LIBRARIES += $(OSS_FUZZ_FUZZERS)
|
|
||||||
oss-fuzz-fuzzers: oss-fuzz-prereqs $(OSS_FUZZ_FUZZERS)
|
|
||||||
fuzzers: $(FUZZERS) $(LIBFUZZER_FUZZERS)
|
|
||||||
|
|
||||||
test-fuzz-corpora: $(FUZZERS)
|
|
||||||
$(top_srcdir)/src/test/fuzz_static_testcases.sh
|
|
||||||
"""
|
|
||||||
|
|
||||||
########### No user serviceable parts will follow.
|
|
||||||
|
|
||||||
PREAMBLE = PREAMBLE.strip()
|
|
||||||
POSTAMBLE = POSTAMBLE.strip() # If I use it, it's a word!
|
|
||||||
FUZZERS = FUZZERS.split()
|
|
||||||
FUZZERS.sort()
|
|
||||||
|
|
||||||
WARNING = """
|
|
||||||
# This file was generated by fuzzing_include_am.py; do not hand-edit unless
|
|
||||||
# you enjoy having your changes erased.
|
|
||||||
""".strip()
|
|
||||||
|
|
||||||
print(WARNING)
|
|
||||||
|
|
||||||
print(PREAMBLE)
|
|
||||||
|
|
||||||
print("\n# ===== AFL fuzzers")
|
|
||||||
|
|
||||||
def get_id_name(s):
|
|
||||||
return s.replace("-", "_")
|
|
||||||
|
|
||||||
for fuzzer in FUZZERS:
|
|
||||||
idname = get_id_name(fuzzer)
|
|
||||||
print("""\
|
|
||||||
src_test_fuzz_fuzz_{name}_SOURCES = \\
|
|
||||||
src/test/fuzz/fuzzing_common.c \\
|
|
||||||
src/test/fuzz/fuzz_{name}.c
|
|
||||||
src_test_fuzz_fuzz_{name}_CPPFLAGS = $(FUZZING_CPPFLAGS)
|
|
||||||
src_test_fuzz_fuzz_{name}_CFLAGS = $(FUZZING_CFLAGS)
|
|
||||||
src_test_fuzz_fuzz_{name}_LDFLAGS = $(FUZZING_LDFLAG)
|
|
||||||
src_test_fuzz_fuzz_{name}_LDADD = $(FUZZING_LIBS)
|
|
||||||
""".format(name=idname))
|
|
||||||
|
|
||||||
print("FUZZERS = \\")
|
|
||||||
print(" \\\n".join("\tsrc/test/fuzz/fuzz-{name}".format(name=fuzzer)
|
|
||||||
for fuzzer in FUZZERS))
|
|
||||||
|
|
||||||
print("\n# ===== libfuzzer")
|
|
||||||
print("\nif LIBFUZZER_ENABLED")
|
|
||||||
|
|
||||||
for fuzzer in FUZZERS:
|
|
||||||
idname = get_id_name(fuzzer)
|
|
||||||
print("""\
|
|
||||||
src_test_fuzz_lf_fuzz_{name}_SOURCES = \\
|
|
||||||
$(src_test_fuzz_fuzz_{name}_SOURCES)
|
|
||||||
src_test_fuzz_lf_fuzz_{name}_CPPFLAGS = $(LIBFUZZER_CPPFLAGS)
|
|
||||||
src_test_fuzz_lf_fuzz_{name}_CFLAGS = $(LIBFUZZER_CFLAGS)
|
|
||||||
src_test_fuzz_lf_fuzz_{name}_LDFLAGS = $(LIBFUZZER_LDFLAG)
|
|
||||||
src_test_fuzz_lf_fuzz_{name}_LDADD = $(LIBFUZZER_LIBS)
|
|
||||||
""".format(name=idname))
|
|
||||||
|
|
||||||
print("LIBFUZZER_FUZZERS = \\")
|
|
||||||
print(" \\\n".join("\tsrc/test/fuzz/lf-fuzz-{name}".format(name=fuzzer)
|
|
||||||
for fuzzer in FUZZERS))
|
|
||||||
|
|
||||||
print("""
|
|
||||||
else
|
|
||||||
LIBFUZZER_FUZZERS =
|
|
||||||
endif""")
|
|
||||||
|
|
||||||
print("\n# ===== oss-fuzz\n")
|
|
||||||
print("if OSS_FUZZ_ENABLED")
|
|
||||||
|
|
||||||
for fuzzer in FUZZERS:
|
|
||||||
idname = get_id_name(fuzzer)
|
|
||||||
print("""\
|
|
||||||
src_test_fuzz_liboss_fuzz_{name}_a_SOURCES = \\
|
|
||||||
$(src_test_fuzz_fuzz_{name}_SOURCES)
|
|
||||||
src_test_fuzz_liboss_fuzz_{name}_a_CPPFLAGS = $(LIBOSS_FUZZ_CPPFLAGS)
|
|
||||||
src_test_fuzz_liboss_fuzz_{name}_a_CFLAGS = $(LIBOSS_FUZZ_CFLAGS)
|
|
||||||
""".format(name=idname))
|
|
||||||
|
|
||||||
print("OSS_FUZZ_FUZZERS = \\")
|
|
||||||
print(" \\\n".join("\tsrc/test/fuzz/liboss-fuzz-{name}.a".format(name=fuzzer)
|
|
||||||
for fuzzer in FUZZERS))
|
|
||||||
|
|
||||||
print("""
|
|
||||||
else
|
|
||||||
OSS_FUZZ_FUZZERS =
|
|
||||||
endif""")
|
|
||||||
|
|
||||||
print("")
|
|
||||||
|
|
||||||
print(POSTAMBLE)
|
|
|
@ -1,5 +1,5 @@
|
||||||
#!/usr/bin/python
|
#!/usr/bin/python
|
||||||
# Copyright 2014-2017, The Tor Project, Inc
|
# Copyright 2014-2015, The Tor Project, Inc
|
||||||
# See LICENSE for licensing information
|
# See LICENSE for licensing information
|
||||||
|
|
||||||
# This script parses openssl headers to find ciphersuite names, determines
|
# This script parses openssl headers to find ciphersuite names, determines
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
#!/usr/bin/python
|
#!/usr/bin/python
|
||||||
# coding=utf-8
|
# coding=utf-8
|
||||||
# Copyright 2011-2017, The Tor Project, Inc
|
# Copyright 2011-2015, The Tor Project, Inc
|
||||||
# original version by Arturo Filastò
|
# original version by Arturo Filastò
|
||||||
# See LICENSE for licensing information
|
# See LICENSE for licensing information
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#!/usr/bin/python
|
#!/usr/bin/python
|
||||||
# Copyright 2014-2017, The Tor Project, Inc.
|
# Copyright 2014-2015, The Tor Project, Inc.
|
||||||
# See LICENSE for license information
|
# See LICENSE for license information
|
||||||
|
|
||||||
# This is a kludgey python script that uses ctypes and openssl to sign
|
# This is a kludgey python script that uses ctypes and openssl to sign
|
||||||
|
|
|
@ -0,0 +1,259 @@
|
||||||
|
#!/usr/bin/python
|
||||||
|
|
||||||
|
import re
|
||||||
|
import sys
|
||||||
|
import copy
|
||||||
|
import cPickle
|
||||||
|
import os
|
||||||
|
|
||||||
|
class Parser:
|
||||||
|
def __init__(self):
|
||||||
|
self.calls = {}
|
||||||
|
self.definedIn = {}
|
||||||
|
|
||||||
|
def enter_func(self, name):
|
||||||
|
if self.infunc and not self.extern and self.calledfns:
|
||||||
|
if self.infunc in self.definedIn:
|
||||||
|
#print "{}: {} or {}?".format(
|
||||||
|
# self.infunc, self.definedIn[self.infunc], self.module)
|
||||||
|
self.definedIn[self.infunc] = 'nil'
|
||||||
|
else:
|
||||||
|
self.definedIn[self.infunc] = self.module
|
||||||
|
self.calls.setdefault(self.infunc, set()).update( self.calledfns )
|
||||||
|
|
||||||
|
self.calledfns = set()
|
||||||
|
self.infunc = name
|
||||||
|
self.extern = False
|
||||||
|
|
||||||
|
def parse_callgraph_file(self, inp, module):
|
||||||
|
self.infunc = None
|
||||||
|
self.extern = False
|
||||||
|
self.calledfns = set()
|
||||||
|
self.module = module
|
||||||
|
|
||||||
|
for line in inp:
|
||||||
|
m = re.match(r"Call graph node for function: '([^']+)'", line)
|
||||||
|
if m:
|
||||||
|
self.enter_func(m.group(1))
|
||||||
|
continue
|
||||||
|
m = re.match(r" CS<[^>]+> calls external node", line)
|
||||||
|
if m:
|
||||||
|
self.extern = True
|
||||||
|
m = re.match(r" CS<[^>]+> calls function '([^']+)'", line)
|
||||||
|
if m:
|
||||||
|
self.calledfns.add(m.group(1))
|
||||||
|
self.enter_func(None)
|
||||||
|
|
||||||
|
def extract_callgraph(self):
|
||||||
|
c = self.calls
|
||||||
|
self.calls = {}
|
||||||
|
return c
|
||||||
|
|
||||||
|
|
||||||
|
def transitive_closure(g):
|
||||||
|
passno = 0
|
||||||
|
changed = True
|
||||||
|
g = copy.deepcopy(g)
|
||||||
|
import random
|
||||||
|
while changed:
|
||||||
|
passno += 1
|
||||||
|
changed = False
|
||||||
|
keys = g.keys()
|
||||||
|
idx = 0
|
||||||
|
for k in keys:
|
||||||
|
idx += 1
|
||||||
|
print "Pass %d/?: %d/%d\r" %(passno, idx, len(keys)),
|
||||||
|
sys.stdout.flush()
|
||||||
|
newset = g[k].copy()
|
||||||
|
for fn in g[k]:
|
||||||
|
newset.update(g.get(fn, set()))
|
||||||
|
if len(newset) != len(g[k]):
|
||||||
|
g[k].update( newset )
|
||||||
|
changed = True
|
||||||
|
|
||||||
|
print
|
||||||
|
|
||||||
|
return g
|
||||||
|
|
||||||
|
def strongly_connected_components(g):
|
||||||
|
# From https://en.wikipedia.org/wiki/Tarjan%27s_strongly_connected_components_algorithm, done stupidly.
|
||||||
|
index_of = {}
|
||||||
|
index = [ 0 ]
|
||||||
|
lowlink = {}
|
||||||
|
S = []
|
||||||
|
onStack = set()
|
||||||
|
|
||||||
|
all_sccs = []
|
||||||
|
|
||||||
|
def strongconnect(fn):
|
||||||
|
index_of[fn] = index[0]
|
||||||
|
lowlink[fn] = index[0]
|
||||||
|
index[0] += 1
|
||||||
|
S.append(fn)
|
||||||
|
onStack.add(fn)
|
||||||
|
|
||||||
|
for w in g.get(fn, []):
|
||||||
|
if w not in index_of:
|
||||||
|
strongconnect(w)
|
||||||
|
lowlink[fn] = min(lowlink[fn], lowlink[w])
|
||||||
|
elif w in onStack:
|
||||||
|
lowlink[fn] = min(lowlink[fn], index_of[w])
|
||||||
|
|
||||||
|
if lowlink[fn] == index_of[fn]:
|
||||||
|
this_scc = []
|
||||||
|
all_sccs.append(this_scc)
|
||||||
|
while True:
|
||||||
|
w = S.pop()
|
||||||
|
onStack.remove(w)
|
||||||
|
this_scc.append(w)
|
||||||
|
if w == fn:
|
||||||
|
break
|
||||||
|
|
||||||
|
for v in g.keys():
|
||||||
|
if v not in index_of:
|
||||||
|
strongconnect(v)
|
||||||
|
|
||||||
|
return all_sccs
|
||||||
|
|
||||||
|
def biggest_component(sccs):
|
||||||
|
return max(len(c) for c in sccs)
|
||||||
|
|
||||||
|
def connection_bottlenecks(callgraph):
|
||||||
|
|
||||||
|
callers = {}
|
||||||
|
for fn in callgraph:
|
||||||
|
for fn2 in callgraph[fn]:
|
||||||
|
callers.setdefault(fn2, set()).add(fn)
|
||||||
|
|
||||||
|
components = strongly_connected_components(callgraph)
|
||||||
|
components.sort(key=len)
|
||||||
|
big_component_fns = components[-1]
|
||||||
|
size = len(big_component_fns)
|
||||||
|
|
||||||
|
function_bottlenecks = fn_results = []
|
||||||
|
|
||||||
|
total = len(big_component_fns)
|
||||||
|
idx = 0
|
||||||
|
for fn in big_component_fns:
|
||||||
|
idx += 1
|
||||||
|
print "Pass 1/3: %d/%d\r"%(idx, total),
|
||||||
|
sys.stdout.flush()
|
||||||
|
cg2 = copy.deepcopy(callgraph)
|
||||||
|
del cg2[fn]
|
||||||
|
|
||||||
|
fn_results.append( (size - biggest_component(strongly_connected_components(cg2)), fn) )
|
||||||
|
|
||||||
|
print
|
||||||
|
bcf_set = set(big_component_fns)
|
||||||
|
|
||||||
|
call_bottlenecks = fn_results = []
|
||||||
|
result_set = set()
|
||||||
|
total = len(big_component_fns)
|
||||||
|
idx = 0
|
||||||
|
for fn in big_component_fns:
|
||||||
|
fn_callers = callers[fn].intersection(bcf_set)
|
||||||
|
idx += 1
|
||||||
|
if len(fn_callers) != 1:
|
||||||
|
continue
|
||||||
|
|
||||||
|
print "Pass 2/3: %d/%d\r"%(idx, total),
|
||||||
|
sys.stdout.flush()
|
||||||
|
|
||||||
|
caller = fn_callers.pop()
|
||||||
|
assert len(fn_callers) == 0
|
||||||
|
cg2 = copy.deepcopy(callgraph)
|
||||||
|
cg2[caller].remove(fn)
|
||||||
|
|
||||||
|
fn_results.append( (size - biggest_component(strongly_connected_components(cg2)), fn, "called by", caller) )
|
||||||
|
result_set.add( (caller, fn) )
|
||||||
|
|
||||||
|
print
|
||||||
|
|
||||||
|
total = len(big_component_fns)
|
||||||
|
idx = 0
|
||||||
|
for fn in big_component_fns:
|
||||||
|
fn_calls = callgraph[fn].intersection(bcf_set)
|
||||||
|
idx += 1
|
||||||
|
if len(fn_calls) != 1:
|
||||||
|
continue
|
||||||
|
|
||||||
|
print "Pass 3/3: %d/%d\r"%(idx, total),
|
||||||
|
sys.stdout.flush()
|
||||||
|
|
||||||
|
callee = fn_calls.pop()
|
||||||
|
if (fn, callee) in result_set:
|
||||||
|
continue
|
||||||
|
|
||||||
|
assert len(fn_calls) == 0
|
||||||
|
cg2 = copy.deepcopy(callgraph)
|
||||||
|
cg2[fn].remove(callee)
|
||||||
|
|
||||||
|
fn_results.append( (size - biggest_component(strongly_connected_components(cg2)), callee, "called by", fn) )
|
||||||
|
|
||||||
|
print
|
||||||
|
|
||||||
|
|
||||||
|
return (function_bottlenecks, call_bottlenecks)
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
p = Parser()
|
||||||
|
for fname in sys.argv[1:]:
|
||||||
|
modname = re.sub(r'.*/', '', fname).replace('.callgraph', '.c')
|
||||||
|
with open(fname, 'r') as f:
|
||||||
|
p.parse_callgraph_file(f, modname)
|
||||||
|
|
||||||
|
sys.stdout.flush()
|
||||||
|
|
||||||
|
print "Building callgraph"
|
||||||
|
callgraph = p.extract_callgraph()
|
||||||
|
inModule = p.definedIn
|
||||||
|
|
||||||
|
print "Deriving module callgraph"
|
||||||
|
modCallgraph = {}
|
||||||
|
for fn in callgraph:
|
||||||
|
fnMod = inModule[fn]
|
||||||
|
for called in callgraph[fn]:
|
||||||
|
try:
|
||||||
|
calledMod = inModule[called]
|
||||||
|
except KeyError:
|
||||||
|
continue
|
||||||
|
modCallgraph.setdefault(fnMod, set()).add(calledMod)
|
||||||
|
del modCallgraph['nil']
|
||||||
|
|
||||||
|
print "Finding strongly connected components"
|
||||||
|
sccs = strongly_connected_components(callgraph)
|
||||||
|
|
||||||
|
print "Finding the transitive closure of the callgraph.."
|
||||||
|
closure = transitive_closure(callgraph)
|
||||||
|
|
||||||
|
print "Finding bottlenecks..."
|
||||||
|
bottlenecks = connection_bottlenecks(callgraph)
|
||||||
|
|
||||||
|
print "Finding module SCCs"
|
||||||
|
modSCCS = strongly_connected_components(modCallgraph)
|
||||||
|
|
||||||
|
print "Finding module TC"
|
||||||
|
modTC = transitive_closure(modCallgraph)
|
||||||
|
|
||||||
|
print "Finding module bottlenecks"
|
||||||
|
modB = connection_bottlenecks(modCallgraph)
|
||||||
|
|
||||||
|
data = {
|
||||||
|
'callgraph' : callgraph,
|
||||||
|
'sccs' : sccs,
|
||||||
|
'closure' : closure,
|
||||||
|
'bottlenecks' : bottlenecks,
|
||||||
|
'modules' : p.definedIn,
|
||||||
|
'modItems' : {
|
||||||
|
'callgraph' : modCallgraph,
|
||||||
|
'sccs' : modSCCS,
|
||||||
|
'closure' : modTC,
|
||||||
|
'bottlenecks' : modB,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
with open('callgraph.pkl', 'w') as f:
|
||||||
|
cPickle.dump(data, f)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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'])\{/) {
|
if (/([^\s'])\{/) {
|
||||||
msg " $1\{:$fn:$.\n";
|
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.
|
## Warn about multiple internal spaces.
|
||||||
#if (/[^\s,:]\s{2,}[^\s\\=]/) {
|
#if (/[^\s,:]\s{2,}[^\s\\=]/) {
|
||||||
# msg " X X:$fn:$.\n";
|
# 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 "switch" and $1 ne "return" and $1 ne "int" and
|
||||||
$1 ne "elsif" and $1 ne "WINAPI" and $2 ne "WINAPI" 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 "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") {
|
$1 ne "workqueue_reply_t") {
|
||||||
msg " fn ():$fn:$.\n";
|
msg " fn ():$fn:$.\n";
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,41 @@
|
||||||
|
#!/usr/bin/python
|
||||||
|
|
||||||
|
import cPickle
|
||||||
|
|
||||||
|
data = cPickle.load(open("callgraph.pkl"))
|
||||||
|
|
||||||
|
# data = data['modItems']
|
||||||
|
|
||||||
|
callgraph = data['callgraph']
|
||||||
|
closure = data['closure']
|
||||||
|
sccs = data['sccs']
|
||||||
|
fn_bottle, call_bottle = data['bottlenecks']
|
||||||
|
|
||||||
|
for n_reachable, fn in sorted(list((len(r), fn) for fn, r in closure.iteritems())):
|
||||||
|
print "%s can reach %s other functions." %(fn, n_reachable)
|
||||||
|
|
||||||
|
|
||||||
|
c = [ (len(component), component) for component in sccs ]
|
||||||
|
c.sort()
|
||||||
|
|
||||||
|
print "\n================================"
|
||||||
|
|
||||||
|
for n, component in c:
|
||||||
|
if n < 2:
|
||||||
|
continue
|
||||||
|
print "Strongly connected component of size %d:"%n
|
||||||
|
print component
|
||||||
|
|
||||||
|
|
||||||
|
print "\n================================"
|
||||||
|
|
||||||
|
print "====== Number of functions pulled into blob, by function in blob."
|
||||||
|
fn_bottle.sort()
|
||||||
|
for n, fn in fn_bottle[-30:]:
|
||||||
|
print "%3d: %s"%(n, fn)
|
||||||
|
|
||||||
|
print "====== Number of functions pulled into blob, by call in blob."
|
||||||
|
call_bottle.sort()
|
||||||
|
for n, fn1, _, fn2 in call_bottle[-30:]:
|
||||||
|
print "%3d: %s -> %s "%(n, fn2, fn1)
|
||||||
|
|
|
@ -3,8 +3,6 @@
|
||||||
# Format:
|
# Format:
|
||||||
# [ IPv4[:DirPort] ] [ orport=<ORPort> ] [ id=<ID> ] ...
|
# [ IPv4[:DirPort] ] [ orport=<ORPort> ] [ id=<ID> ] ...
|
||||||
# [ ipv6=<IPv6>[:<IPv6 ORPort>] ]
|
# [ ipv6=<IPv6>[:<IPv6 ORPort>] ]
|
||||||
# or use:
|
|
||||||
# scripts/maint/generateFallbackDirLine.py fingerprint ...
|
|
||||||
#
|
#
|
||||||
# If a sufficiently specific group of attributes matches, the directory mirror
|
# If a sufficiently specific group of attributes matches, the directory mirror
|
||||||
# will be excluded: (each group is listed on its own line)
|
# 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: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
|
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
|
# Email sent directly to teor, verified using relay contact info
|
||||||
216.17.99.183:80 orport=443 id=D52CD431CEF28E01B11F545A84347EE45524BCA7
|
216.17.99.183:80 orport=443 id=D52CD431CEF28E01B11F545A84347EE45524BCA7
|
||||||
216.17.99.183:8080 orport=9001 id=EE21F83AB6F76E3B3FFCBA5C2496F789CB84E7C6
|
216.17.99.183:8080 orport=9001 id=EE21F83AB6F76E3B3FFCBA5C2496F789CB84E7C6
|
||||||
|
@ -68,6 +74,9 @@
|
||||||
# Email sent directly to teor, verified using relay contact info
|
# Email sent directly to teor, verified using relay contact info
|
||||||
185.21.216.140:9030 orport=9001 id=921DA852C95141F8964B359F774B35502E489869
|
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
|
# 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
|
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
|
# Email sent directly to teor, verified using relay contact info
|
||||||
88.190.208.4:30555 orport=30556 id=030A6EB24725C05D8E0FCE21923CBA5223E75E0E
|
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
|
# 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
|
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
|
# Email sent directly to teor, verified using relay contact info
|
||||||
195.154.15.227:9030 orport=9001 id=6C3E3AB2F5F03CD71B637D433BAD924A1ECC5796
|
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
|
# Fallback was on 0.2.8.6 list, but opted-out before 0.2.9
|
||||||
144.76.73.140:9030 orport=9001 id=6A640018EABF3DA9BAD9321AA37C2C87BBE1F907
|
144.76.73.140:9030 orport=9001 id=6A640018EABF3DA9BAD9321AA37C2C87BBE1F907
|
||||||
|
|
||||||
|
@ -210,23 +252,3 @@
|
||||||
|
|
||||||
# Email sent directly to teor, verified using relay contact info
|
# Email sent directly to teor, verified using relay contact info
|
||||||
163.172.35.245:80 orport=443 id=B771AA877687F88E6F1CA5354756DF6C8A7B6B24
|
163.172.35.245:80 orport=443 id=B771AA877687F88E6F1CA5354756DF6C8A7B6B24
|
||||||
|
|
||||||
# Email sent directly to teor, verified using relay contact info
|
|
||||||
104.243.35.196:9030 orport=9001 id=FA3415659444AE006E7E9E5375E82F29700CFDFD
|
|
||||||
|
|
||||||
# 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
|
|
||||||
|
|
||||||
# Emails sent directly to teor, verified using relay contact info
|
|
||||||
195.154.75.84:9030 orport=9001 id=F80FDE27EFCB3F6A7B4E2CC517133DBFFA78BA2D
|
|
||||||
195.154.127.246:9030 orport=9001 id=4FEE77AFFD157BBCF2D896AE417FBF647860466C
|
|
||||||
|
|
||||||
# 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
|
|
||||||
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:
|
# Format:
|
||||||
# IPv4:DirPort orport=<ORPort> id=<ID> [ ipv6=<IPv6>:<IPv6 ORPort> ]
|
# 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.
|
# All attributes must match for the directory mirror to be included.
|
||||||
# If the fallback has an ipv6 key, the whitelist line must also have
|
# 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> ]
|
# <IPv4>:<DirPort> orport=<ORPort> id=<ID> [ ipv6=<IPv6>:<IPv6 ORPort> ]
|
||||||
|
|
||||||
# https://lists.torproject.org/pipermail/tor-relays/2015-December/008362.html
|
# 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
|
||||||
78.47.18.110:443 orport=80 id=F8D27B163B9247B232A2EEE68DD8B698695C28DE ipv6=[2a01:4f8:120:4023::110]:80 # fluxe3
|
131.188.40.188:443 orport=80 id=EBE718E1A49EE229071702964F8DB1F318075FF8
|
||||||
131.188.40.188:1443 orport=80 id=EBE718E1A49EE229071702964F8DB1F318075FF8 ipv6=[2001:638:a000:4140::ffff:188]:80 # fluxe4
|
|
||||||
|
|
||||||
# https://lists.torproject.org/pipermail/tor-relays/2015-December/008366.html
|
# 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
|
5.39.88.19:9030 orport=9001 id=7CB8C31432A796731EA7B6BF4025548DFEB25E0C ipv6=[2001:41d0:8:9a13::1]:9050
|
||||||
|
@ -40,6 +37,8 @@
|
||||||
# https://lists.torproject.org/pipermail/tor-relays/2015-December/008370.html
|
# https://lists.torproject.org/pipermail/tor-relays/2015-December/008370.html
|
||||||
# https://lists.torproject.org/pipermail/tor-relays/2016-January/008517.html
|
# https://lists.torproject.org/pipermail/tor-relays/2016-January/008517.html
|
||||||
# https://lists.torproject.org/pipermail/tor-relays/2016-January/008555.html
|
# https://lists.torproject.org/pipermail/tor-relays/2016-January/008555.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
|
||||||
212.47.237.95:9030 orport=9001 id=3F5D8A879C58961BB45A3D26AC41B543B40236D6
|
212.47.237.95:9030 orport=9001 id=3F5D8A879C58961BB45A3D26AC41B543B40236D6
|
||||||
212.47.237.95:9130 orport=9101 id=6FB38EB22E57EF7ED5EF00238F6A48E553735D88
|
212.47.237.95:9130 orport=9101 id=6FB38EB22E57EF7ED5EF00238F6A48E553735D88
|
||||||
|
|
||||||
|
@ -50,26 +49,24 @@
|
||||||
# https://lists.torproject.org/pipermail/tor-relays/2015-December/008373.html
|
# https://lists.torproject.org/pipermail/tor-relays/2015-December/008373.html
|
||||||
167.114.35.28:9030 orport=9001 id=E65D300F11E1DB12C534B0146BDAB6972F1A8A48
|
167.114.35.28:9030 orport=9001 id=E65D300F11E1DB12C534B0146BDAB6972F1A8A48
|
||||||
|
|
||||||
|
# https://lists.torproject.org/pipermail/tor-relays/2015-December/008374.html
|
||||||
|
104.243.35.196:9030 orport=9001 id=FA3415659444AE006E7E9E5375E82F29700CFDFD
|
||||||
|
|
||||||
# https://lists.torproject.org/pipermail/tor-relays/2015-December/008378.html
|
# https://lists.torproject.org/pipermail/tor-relays/2015-December/008378.html
|
||||||
144.76.14.145:110 orport=143 id=14419131033443AE6E21DA82B0D307F7CAE42BDB ipv6=[2a01:4f8:190:9490::dead]:443
|
144.76.14.145:110 orport=143 id=14419131033443AE6E21DA82B0D307F7CAE42BDB ipv6=[2a01:4f8:190:9490::dead]:443
|
||||||
|
|
||||||
# https://lists.torproject.org/pipermail/tor-relays/2015-December/008379.html
|
# https://lists.torproject.org/pipermail/tor-relays/2015-December/008379.html
|
||||||
# Email sent directly to teor, verified using relay contact info
|
# Email sent directly to teor, verified using relay contact info
|
||||||
91.121.84.137:4951 orport=4051 id=6DE61A6F72C1E5418A66BFED80DFB63E4C77668F
|
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
|
|
||||||
|
|
||||||
# https://lists.torproject.org/pipermail/tor-relays/2015-December/008381.html
|
# https://lists.torproject.org/pipermail/tor-relays/2015-December/008381.html
|
||||||
# Sent additional emails to teor with updated relays
|
# Sent additional email to teor with more relays
|
||||||
81.7.11.96:9030 orport=9001 id=8FA37B93397015B2BC5A525C908485260BE9F422 # Doedel22
|
178.254.44.135:9030 orport=9001 id=8FA37B93397015B2BC5A525C908485260BE9F422
|
||||||
# 9F5068310818ED7C70B0BC4087AB55CB12CB4377 not found in current consensus
|
178.254.20.134:80 orport=443 id=9F5068310818ED7C70B0BC4087AB55CB12CB4377
|
||||||
178.254.19.101:80 orport=443 id=F9246DEF2B653807236DA134F2AEAB103D58ABFE # Freebird31
|
178.254.20.134:9030 orport=9001 id=2CE96A8A1DA032664C90F574AFFBECE18A6E8DFC
|
||||||
178.254.19.101:9030 orport=9001 id=0C475BA4D3AA3C289B716F95954CAD616E50C4E5 # Freebird32
|
178.254.44.135:80 orport=443 id=AE6A8C18E7499B586CD36246AC4BCAFFBBF93AB2
|
||||||
81.7.14.253:9001 orport=443 id=1AE039EE0B11DB79E4B4B29CBA9F752864A0259E # Ichotolot60
|
178.254.13.126:80 orport=443 id=F9246DEF2B653807236DA134F2AEAB103D58ABFE
|
||||||
81.7.11.186:1080 orport=443 id=B86137AE9681701901C6720E55C16805B46BD8E3 # BeastieJoy60
|
178.254.13.126:9030 orport=9001 id=0C475BA4D3AA3C289B716F95954CAD616E50C4E5
|
||||||
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
|
|
||||||
|
|
||||||
# https://lists.torproject.org/pipermail/tor-relays/2015-December/008382.html
|
# https://lists.torproject.org/pipermail/tor-relays/2015-December/008382.html
|
||||||
51.255.33.237:9091 orport=9001 id=A360C21FA87FFA2046D92C17086A6B47E5C68109
|
51.255.33.237:9091 orport=9001 id=A360C21FA87FFA2046D92C17086A6B47E5C68109
|
||||||
|
@ -98,15 +95,21 @@
|
||||||
# https://lists.torproject.org/pipermail/tor-relays/2016-January/008542.html
|
# https://lists.torproject.org/pipermail/tor-relays/2016-January/008542.html
|
||||||
178.62.199.226:80 orport=443 id=CBEFF7BA4A4062045133C053F2D70524D8BBE5BE ipv6=[2a03:b0c0:2:d0::b7:5001]:443
|
178.62.199.226:80 orport=443 id=CBEFF7BA4A4062045133C053F2D70524D8BBE5BE ipv6=[2a03:b0c0:2:d0::b7:5001]:443
|
||||||
|
|
||||||
|
# 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
|
||||||
|
|
||||||
# Email sent directly to teor, verified using relay contact info
|
# Email sent directly to teor, verified using relay contact info
|
||||||
94.23.204.175:9030 orport=9001 id=5665A3904C89E22E971305EE8C1997BCA4123C69
|
94.23.204.175:9030 orport=9001 id=5665A3904C89E22E971305EE8C1997BCA4123C69
|
||||||
|
|
||||||
# Email sent directly to teor, verified using relay contact info
|
# 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.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.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
|
171.25.193.20:80 orport=443 id=DD8BD7307017407FCC36F8D04A688F74A0774C02 ipv6=[2001:67c:289c::20]:443
|
||||||
# same machine as DD8BD7307017407FCC36F8D04A688F74A0774C02
|
# OK, but same machine as 79861CF8522FC637EF046F7688F5289E49D94576
|
||||||
171.25.193.25:80 orport=443 id=185663B7C12777F052B2C2D23D7A239D8DA88A0F ipv6=[2001:67c:289c::25]:443
|
#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
|
# 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
|
212.47.229.2:9030 orport=9001 id=20462CBA5DA4C2D963567D17D0B7249718114A68 ipv6=[2001:bc8:4400:2100::f03]:9001
|
||||||
|
@ -114,12 +117,8 @@
|
||||||
46.28.109.231:9030 orport=9001 id=F70B7C5CD72D74C7F9F2DC84FA9D20D51BA13610 ipv6=[2a02:2b88:2:1::4205:1]:9001
|
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
|
# Email sent directly to teor, verified using relay contact info
|
||||||
85.235.250.88:80 orport=443 id=72B2B12A3F60408BDBC98C6DF53988D3A0B3F0EE # TykRelay01
|
85.235.250.88:80 orport=443 id=72B2B12A3F60408BDBC98C6DF53988D3A0B3F0EE
|
||||||
185.96.88.29:80 orport=443 id=86C281AD135058238D7A337D546C902BE8505DDE # TykRelay051
|
185.96.180.29:80 orport=443 id=F93D8F37E35C390BCAD9F9069E13085B745EC216
|
||||||
# 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
|
|
||||||
|
|
||||||
# Email sent directly to teor, verified using relay contact info
|
# Email sent directly to teor, verified using relay contact info
|
||||||
185.11.180.67:80 orport=9001 id=794D8EA8343A4E820320265D05D4FA83AB6D1778
|
185.11.180.67:80 orport=9001 id=794D8EA8343A4E820320265D05D4FA83AB6D1778
|
||||||
|
@ -159,10 +158,9 @@
|
||||||
109.163.234.8:80 orport=443 id=0818DAE0E2DDF795AEDEAC60B15E71901084F281
|
109.163.234.8:80 orport=443 id=0818DAE0E2DDF795AEDEAC60B15E71901084F281
|
||||||
109.163.234.9:80 orport=443 id=ABF7FBF389C9A747938B639B20E80620B460B2A9
|
109.163.234.9:80 orport=443 id=ABF7FBF389C9A747938B639B20E80620B460B2A9
|
||||||
62.102.148.67:80 orport=443 id=4A0C3E177AF684581EF780981AEAF51A98A6B5CF
|
62.102.148.67:80 orport=443 id=4A0C3E177AF684581EF780981AEAF51A98A6B5CF
|
||||||
# Assume details update is permanent
|
77.247.181.162:80 orport=443 id=7BB160A8F54BD74F3DA5F2CE701E8772B841859D
|
||||||
77.247.181.166:80 orport=443 id=77131D7E2EC1CA9B8D737502256DA9103599CE51 # CriticalMass
|
77.247.181.164:80 orport=443 id=10E13E340651D0EF66B4DEBF610B3C0981168107
|
||||||
77.247.181.164:80 orport=443 id=204DFD2A2C6A0DC1FA0EACB495218E0B661704FD # HaveHeart
|
77.247.181.166:80 orport=443 id=06E123865C590189B3181114F23F0F13A7BC0E69
|
||||||
77.247.181.162:80 orport=443 id=7BFB908A3AA5B491DA4CA72CCBEE0E1F2A939B55 # sofia
|
|
||||||
|
|
||||||
# https://twitter.com/biotimylated/status/718994247500718080
|
# https://twitter.com/biotimylated/status/718994247500718080
|
||||||
212.47.252.149:9030 orport=9001 id=2CAC39BAA996791CEFAADC9D4754D65AF5EB77C0
|
212.47.252.149:9030 orport=9001 id=2CAC39BAA996791CEFAADC9D4754D65AF5EB77C0
|
||||||
|
@ -214,19 +212,20 @@
|
||||||
# Email sent directly to teor, verified using relay contact info
|
# Email sent directly to teor, verified using relay contact info
|
||||||
89.187.142.208:80 orport=443 id=64186650FFE4469EBBE52B644AE543864D32F43C
|
89.187.142.208:80 orport=443 id=64186650FFE4469EBBE52B644AE543864D32F43C
|
||||||
|
|
||||||
# Email sent directly to teor
|
# Email sent directly to teor, verified using relay contact info
|
||||||
# Assume details update is permanent
|
212.51.134.123:9030 orport=9001 id=50586E25BE067FD1F739998550EDDCB1A14CA5B2 ipv6=[2a02:168:6e00:0:3a60:77ff:fe9c:8bd1]:9001
|
||||||
212.51.134.123:9030 orport=9001 id=50586E25BE067FD1F739998550EDDCB1A14CA5B2 # Jans
|
|
||||||
|
|
||||||
# Email sent directly to teor, verified using relay contact info
|
# Email sent directly to teor, verified using relay contact info
|
||||||
46.101.143.173:80 orport=443 id=F960DF50F0FD4075AC9B505C1D4FFC8384C490FB
|
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
|
# Email sent directly to teor, verified using relay contact info
|
||||||
193.171.202.146:9030 orport=9001 id=01A9258A46E97FF8B2CAC7910577862C14F2C524
|
193.171.202.146:9030 orport=9001 id=01A9258A46E97FF8B2CAC7910577862C14F2C524
|
||||||
|
|
||||||
# Email sent directly to teor, verified using relay contact info
|
# Email sent directly to teor, verified using relay contact info
|
||||||
# Assume details update is permanent
|
197.231.221.211:9030 orport=9001 id=BC630CBBB518BE7E9F4E09712AB0269E9DC7D626
|
||||||
197.231.221.211:9030 orport=443 id=BC630CBBB518BE7E9F4E09712AB0269E9DC7D626 # IPredator
|
|
||||||
|
|
||||||
# Email sent directly to teor, verified using relay contact info
|
# Email sent directly to teor, verified using relay contact info
|
||||||
185.61.138.18:8080 orport=4443 id=2541759BEC04D37811C2209A88E863320271EC9C
|
185.61.138.18:8080 orport=4443 id=2541759BEC04D37811C2209A88E863320271EC9C
|
||||||
|
@ -237,7 +236,7 @@
|
||||||
193.11.114.46:9032 orport=9003 id=B83DC1558F0D34353BB992EF93AFEAFDB226A73E
|
193.11.114.46:9032 orport=9003 id=B83DC1558F0D34353BB992EF93AFEAFDB226A73E
|
||||||
|
|
||||||
# Email sent directly to teor, verified using relay contact info
|
# 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
|
# Email sent directly to teor, verified using relay contact info
|
||||||
37.221.162.226:9030 orport=9001 id=D64366987CB39F61AD21DBCF8142FA0577B92811
|
37.221.162.226:9030 orport=9001 id=D64366987CB39F61AD21DBCF8142FA0577B92811
|
||||||
|
@ -255,7 +254,7 @@
|
||||||
134.119.3.164:9030 orport=9001 id=D1B8AAA98C65F3DF7D8BB3AF881CAEB84A33D8EE
|
134.119.3.164:9030 orport=9001 id=D1B8AAA98C65F3DF7D8BB3AF881CAEB84A33D8EE
|
||||||
|
|
||||||
# Email sent directly to teor, verified using relay contact info
|
# 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
|
# 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
|
178.62.22.36:80 orport=443 id=A0766C0D3A667A3232C7D569DE94A28F9922FCB1 ipv6=[2a03:b0c0:1:d0::174:1]:9050
|
||||||
|
@ -306,15 +305,14 @@
|
||||||
46.148.18.74:8080 orport=443 id=6CACF0B5F03C779672F3C5C295F37C8D234CA3F7
|
46.148.18.74:8080 orport=443 id=6CACF0B5F03C779672F3C5C295F37C8D234CA3F7
|
||||||
|
|
||||||
# Email sent directly to teor, verified using relay contact info
|
# 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
|
37.187.102.108:9090 orport=5550 id=F4263275CF54A6836EE7BD527B1328836A6F06E1
|
||||||
212.47.241.21:80 orport=443 id=892F941915F6A0C6E0958E52E0A9685C190CF45C # EvilMoe
|
212.47.241.21:80 orport=443 id=892F941915F6A0C6E0958E52E0A9685C190CF45C
|
||||||
|
|
||||||
# Email sent directly to teor, verified using relay contact info
|
# Email sent directly to teor, verified using relay contact info
|
||||||
212.129.38.254:9030 orport=9001 id=FDF845FC159C0020E2BDDA120C30C5C5038F74B4
|
212.129.38.254:9030 orport=9001 id=FDF845FC159C0020E2BDDA120C30C5C5038F74B4
|
||||||
|
|
||||||
# Email sent directly to teor
|
# Email sent directly to teor, verified using relay contact info
|
||||||
37.157.195.87:8030 orport=443 id=12FD624EE73CEF37137C90D38B2406A66F68FAA2 # thanatosCZ
|
37.157.195.87:8030 orport=443 id=12FD624EE73CEF37137C90D38B2406A66F68FAA2
|
||||||
5.189.169.190:8030 orport=8080 id=8D79F73DCD91FC4F5017422FAC70074D6DB8DD81 # thanatosDE
|
|
||||||
|
|
||||||
# Email sent directly to teor, verified using relay contact info
|
# 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
|
37.187.7.74:80 orport=443 id=AEA43CB1E47BE5F8051711B2BF01683DB1568E05 ipv6=[2001:41d0:a:74a::1]:443
|
||||||
|
@ -331,6 +329,9 @@
|
||||||
# Email sent directly to teor, verified using relay contact info
|
# Email sent directly to teor, verified using relay contact info
|
||||||
37.187.102.186:9030 orport=9001 id=489D94333DF66D57FFE34D9D59CC2D97E2CB0053 ipv6=[2001:41d0:a:26ba::1]:9001
|
37.187.102.186:9030 orport=9001 id=489D94333DF66D57FFE34D9D59CC2D97E2CB0053 ipv6=[2001:41d0:a:26ba::1]:9001
|
||||||
|
|
||||||
|
# Email sent directly to teor, verified using relay contact info
|
||||||
|
5.35.251.247:9030 orport=9001 id=9B1F5187DFBA89DC24B37EA7BF896C12B43A27AE
|
||||||
|
|
||||||
# Email sent directly to teor, verified using relay contact info
|
# Email sent directly to teor, verified using relay contact info
|
||||||
198.96.155.3:8080 orport=5001 id=BCEDF6C193AA687AE471B8A22EBF6BC57C2D285E
|
198.96.155.3:8080 orport=5001 id=BCEDF6C193AA687AE471B8A22EBF6BC57C2D285E
|
||||||
|
|
||||||
|
@ -377,6 +378,14 @@
|
||||||
# Email sent directly to teor, verified using relay contact info
|
# Email sent directly to teor, verified using relay contact info
|
||||||
91.219.237.229:80 orport=443 id=1ECD73B936CB6E6B3CD647CC204F108D9DF2C9F7
|
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
|
# Email sent directly to teor, verified using relay contact info
|
||||||
46.101.151.222:80 orport=443 id=1DBAED235E3957DE1ABD25B4206BE71406FB61F8
|
46.101.151.222:80 orport=443 id=1DBAED235E3957DE1ABD25B4206BE71406FB61F8
|
||||||
178.62.60.37:80 orport=443 id=175921396C7C426309AB03775A9930B6F611F794
|
178.62.60.37:80 orport=443 id=175921396C7C426309AB03775A9930B6F611F794
|
||||||
|
@ -405,8 +414,8 @@
|
||||||
# Email sent directly to teor, verified using relay contact info
|
# Email sent directly to teor, verified using relay contact info
|
||||||
5.199.142.236:9030 orport=9001 id=F4C0EDAA0BF0F7EC138746F8FEF1CE26C7860265
|
5.199.142.236:9030 orport=9001 id=F4C0EDAA0BF0F7EC138746F8FEF1CE26C7860265
|
||||||
|
|
||||||
# Email sent directly to teor
|
# Email sent directly to teor, verified using relay contact info
|
||||||
188.166.133.133:9030 orport=9001 id=774555642FDC1E1D4FDF2E0C31B7CA9501C5C9C7 ipv6=[2a03:b0c0:2:d0::26c0:1]:9001 # dropsy
|
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
|
# Email sent directly to teor, verified using relay contact info
|
||||||
46.8.249.10:80 orport=443 id=31670150090A7C3513CB7914B9610E786391A95D
|
46.8.249.10:80 orport=443 id=31670150090A7C3513CB7914B9610E786391A95D
|
||||||
|
@ -418,10 +427,12 @@
|
||||||
46.4.24.161:9030 orport=9001 id=DB4C76A3AD7E234DA0F00D6F1405D8AFDF4D8DED
|
46.4.24.161:9030 orport=9001 id=DB4C76A3AD7E234DA0F00D6F1405D8AFDF4D8DED
|
||||||
46.4.24.161:9031 orport=9002 id=7460F3D12EBE861E4EE073F6233047AACFE46AB4
|
46.4.24.161:9031 orport=9002 id=7460F3D12EBE861E4EE073F6233047AACFE46AB4
|
||||||
46.38.51.132:9030 orport=9001 id=810DEFA7E90B6C6C383C063028EC397A71D7214A
|
46.38.51.132:9030 orport=9001 id=810DEFA7E90B6C6C383C063028EC397A71D7214A
|
||||||
163.172.194.53:9030 orport=9001 id=8C00FA7369A7A308F6A137600F0FA07990D9D451 ipv6=[2001:bc8:225f:142:6c69:7461:7669:73]:9001
|
163.172.194.53:9030 orport=9001 id=8C00FA7369A7A308F6A137600F0FA07990D9D451
|
||||||
|
|
||||||
# Email sent directly to teor, verified using relay contact info
|
# Email sent directly to teor, verified using relay contact info
|
||||||
176.10.107.180:9030 orport=9001 id=3D7E274A87D9A89AF064C13D1EE4CA1F184F2600
|
176.10.107.180:9030 orport=9001 id=3D7E274A87D9A89AF064C13D1EE4CA1F184F2600
|
||||||
|
195.154.75.84:9030 orport=9001 id=F80FDE27EFCB3F6A7B4E2CC517133DBFFA78BA2D
|
||||||
|
195.154.127.246:9030 orport=9001 id=4FEE77AFFD157BBCF2D896AE417FBF647860466C
|
||||||
|
|
||||||
# Email sent directly to teor, verified using relay contact info
|
# Email sent directly to teor, verified using relay contact info
|
||||||
46.28.207.19:80 orport=443 id=5B92FA5C8A49D46D235735504C72DBB3472BA321
|
46.28.207.19:80 orport=443 id=5B92FA5C8A49D46D235735504C72DBB3472BA321
|
||||||
|
@ -460,7 +471,7 @@
|
||||||
185.35.202.221:9030 orport=9001 id=C13B91384CDD52A871E3ECECE4EF74A7AC7DCB08 ipv6=[2a02:ed06::221]:9001
|
185.35.202.221:9030 orport=9001 id=C13B91384CDD52A871E3ECECE4EF74A7AC7DCB08 ipv6=[2a02:ed06::221]:9001
|
||||||
|
|
||||||
# Email sent directly to teor, verified using relay contact info
|
# Email sent directly to teor, verified using relay contact info
|
||||||
5.9.151.241:9030 orport=4223 id=9BF04559224F0F1C3C953D641F1744AF0192543A ipv6=[2a01:4f8:190:34f0::2]:4223
|
5.9.151.241:9030 orport=4223 id=9BF04559224F0F1C3C953D641F1744AF0192543A
|
||||||
|
|
||||||
# Email sent directly to teor, verified using relay contact info
|
# Email sent directly to teor, verified using relay contact info
|
||||||
89.40.71.149:8081 orport=8080 id=EC639EDAA5121B47DBDF3D6B01A22E48A8CB6CC7
|
89.40.71.149:8081 orport=8080 id=EC639EDAA5121B47DBDF3D6B01A22E48A8CB6CC7
|
||||||
|
@ -477,6 +488,9 @@
|
||||||
# Email sent directly to teor, verified using relay contact info
|
# Email sent directly to teor, verified using relay contact info
|
||||||
95.130.11.147:9030 orport=443 id=6B697F3FF04C26123466A5C0E5D1F8D91925967A
|
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
|
# 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
|
128.199.55.207:9030 orport=9001 id=BCEF908195805E03E92CCFE669C48738E556B9C5 ipv6=[2a03:b0c0:2:d0::158:3001]:9001
|
||||||
|
|
||||||
|
@ -495,8 +509,8 @@
|
||||||
# Email sent directly to teor, verified using relay contact info
|
# Email sent directly to teor, verified using relay contact info
|
||||||
185.97.32.18:9030 orport=9001 id=04250C3835019B26AA6764E85D836088BE441088
|
185.97.32.18:9030 orport=9001 id=04250C3835019B26AA6764E85D836088BE441088
|
||||||
|
|
||||||
# Email sent directly to teor
|
# Email sent directly to teor, verified using relay contact info
|
||||||
149.56.45.200:9030 orport=9001 id=FE296180018833AF03A8EACD5894A614623D3F76 ipv6=[2607:5300:201:3000::17d3]:9002 # PiotrTorpotkinOne
|
149.56.45.200:9030 orport=9001 id=FE296180018833AF03A8EACD5894A614623D3F76
|
||||||
|
|
||||||
# Email sent directly to teor, verified using relay contact info
|
# 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
|
81.2.209.10:443 orport=80 id=B6904ADD4C0D10CDA7179E051962350A69A63243 ipv6=[2001:15e8:201:1::d10a]:80
|
||||||
|
@ -534,8 +548,8 @@
|
||||||
# Email sent directly to teor, verified using relay contact info
|
# 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
|
212.238.208.48:9030 orport=9001 id=F406219CDD339026D160E53FCA0EF6857C70F109 ipv6=[2001:984:a8fb:1:ba27:ebff:feac:c109]:9001
|
||||||
|
|
||||||
# Email sent directly to teor
|
# Email sent directly to teor, verified using relay contact info
|
||||||
176.158.236.102:9030 orport=9001 id=DC163DDEF4B6F0C6BC226F9F6656A5A30C5C5686 # Underworld
|
176.158.132.12:9030 orport=9001 id=DC163DDEF4B6F0C6BC226F9F6656A5A30C5C5686
|
||||||
|
|
||||||
# Email sent directly to teor, verified using relay contact info
|
# Email sent directly to teor, verified using relay contact info
|
||||||
91.229.20.27:9030 orport=9001 id=9A0D54D3A6D2E0767596BF1515E6162A75B3293F
|
91.229.20.27:9030 orport=9001 id=9A0D54D3A6D2E0767596BF1515E6162A75B3293F
|
||||||
|
@ -543,8 +557,8 @@
|
||||||
# Email sent directly to teor, verified using relay contact info
|
# 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
|
80.127.137.19:80 orport=443 id=6EF897645B79B6CB35E853B32506375014DE3621 ipv6=[2001:981:47c1:1::6]:443
|
||||||
|
|
||||||
# Email sent directly to teor
|
# Email sent directly to teor, verified using relay contact info
|
||||||
163.172.138.22:80 orport=443 id=16102E458460349EE45C0901DAA6C30094A9BBEA ipv6=[2001:bc8:4400:2100::1:3]:443 # mkultra
|
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
|
# Email sent directly to teor, verified using relay contact info
|
||||||
97.74.237.196:9030 orport=9001 id=2F0F32AB1E5B943CA7D062C03F18960C86E70D94
|
97.74.237.196:9030 orport=9001 id=2F0F32AB1E5B943CA7D062C03F18960C86E70D94
|
||||||
|
@ -560,7 +574,6 @@
|
||||||
|
|
||||||
# Email sent directly to teor, verified using relay contact info
|
# Email sent directly to teor, verified using relay contact info
|
||||||
185.100.86.100:80 orport=443 id=0E8C0C8315B66DB5F703804B3889A1DD66C67CE0
|
185.100.86.100:80 orport=443 id=0E8C0C8315B66DB5F703804B3889A1DD66C67CE0
|
||||||
185.100.84.82:80 orport=443 id=7D05A38E39FC5D29AFE6BE487B9B4DC9E635D09E
|
|
||||||
|
|
||||||
# Email sent directly to teor, verified using relay contact info
|
# Email sent directly to teor, verified using relay contact info
|
||||||
164.132.77.175:9030 orport=9001 id=3B33F6FCA645AD4E91428A3AF7DC736AD9FB727B
|
164.132.77.175:9030 orport=9001 id=3B33F6FCA645AD4E91428A3AF7DC736AD9FB727B
|
||||||
|
@ -578,8 +591,7 @@
|
||||||
167.114.113.48:9030 orport=403 id=2EC0C66EA700C44670444280AABAB1EC78B722A0
|
167.114.113.48:9030 orport=403 id=2EC0C66EA700C44670444280AABAB1EC78B722A0
|
||||||
|
|
||||||
# Email sent directly to teor, verified using relay contact info
|
# Email sent directly to teor, verified using relay contact info
|
||||||
# Assume details update is permanent
|
79.120.16.42:9030 orport=9001 id=BD552C165E2ED2887D3F1CCE9CFF155DDA2D86E6
|
||||||
213.141.138.174:9030 orport=9001 id=BD552C165E2ED2887D3F1CCE9CFF155DDA2D86E6 # Schakalium
|
|
||||||
|
|
||||||
# Email sent directly to teor, verified using relay contact info
|
# 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
|
95.128.43.164:80 orport=443 id=616081EC829593AF4232550DE6FFAA1D75B37A90 ipv6=[2a02:ec0:209:10::4]:443
|
||||||
|
@ -608,13 +620,10 @@
|
||||||
# Email sent directly to teor, verified using relay contact info
|
# Email sent directly to teor, verified using relay contact info
|
||||||
31.31.78.49:80 orport=443 id=46791D156C9B6C255C2665D4D8393EC7DBAA7798
|
31.31.78.49:80 orport=443 id=46791D156C9B6C255C2665D4D8393EC7DBAA7798
|
||||||
|
|
||||||
# Email sent directly to teor
|
# Email sent directly to teor, verified using relay contact info
|
||||||
192.160.102.169:80 orport=9001 id=C0192FF43E777250084175F4E59AC1BA2290CE38 ipv6=[2620:132:300c:c01d::9]:9002 # manipogo
|
96.47.231.214:9030 orport=8080 id=F843CB5729575D76FF1FFBB2179BDCF52C0C6387
|
||||||
192.160.102.166:80 orport=9001 id=547DA56F6B88B6C596B3E3086803CDA4F0EF8F21 ipv6=[2620:132:300c:c01d::6]:9002 # chaucer
|
192.99.246.48:9030 orport=9001 id=CD6B149BED1BB254EF6DFF9D75DDB11E7F8A38A4 ipv6=[2607:5300:100:200::de3]:9002
|
||||||
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=[2605:e200:d00c:c01d::1111]:9002
|
||||||
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
|
# Email sent directly to teor, verified using relay contact info
|
||||||
136.243.214.137:80 orport=443 id=B291D30517D23299AD7CEE3E60DFE60D0E3A4664
|
136.243.214.137:80 orport=443 id=B291D30517D23299AD7CEE3E60DFE60D0E3A4664
|
||||||
|
@ -625,14 +634,17 @@
|
||||||
|
|
||||||
# Email sent directly to teor, verified using relay contact info
|
# Email sent directly to teor, verified using relay contact info
|
||||||
192.87.28.28:9030 orport=9001 id=ED2338CAC2711B3E331392E1ED2831219B794024
|
192.87.28.28:9030 orport=9001 id=ED2338CAC2711B3E331392E1ED2831219B794024
|
||||||
# same machine as ED2338CAC2711B3E331392E1ED2831219B794024
|
# OK, but same machine as ED2338CAC2711B3E331392E1ED2831219B794024
|
||||||
192.87.28.82:9030 orport=9001 id=844AE9CAD04325E955E2BE1521563B79FE7094B7
|
#192.87.28.82:9030 orport=9001 id=844AE9CAD04325E955E2BE1521563B79FE7094B7
|
||||||
|
|
||||||
# https://twitter.com/kosjoli/status/719507270904758272
|
# https://twitter.com/kosjoli/status/719507270904758272
|
||||||
85.10.202.87:9030 orport=9001 id=971AFB23C168DCD8EDA17473C1C452B359DE3A5A
|
85.10.202.87:9030 orport=9001 id=971AFB23C168DCD8EDA17473C1C452B359DE3A5A
|
||||||
176.9.5.116:9030 orport=9001 id=A1EB8D8F1EE28DB98BBB1EAA3B4BEDD303BAB911
|
176.9.5.116:9030 orport=9001 id=A1EB8D8F1EE28DB98BBB1EAA3B4BEDD303BAB911
|
||||||
46.4.111.124:9030 orport=9001 id=D9065F9E57899B3D272AA212317AF61A9B14D204
|
46.4.111.124:9030 orport=9001 id=D9065F9E57899B3D272AA212317AF61A9B14D204
|
||||||
|
|
||||||
|
# Email sent directly to teor, verified using relay contact info
|
||||||
|
138.201.130.32:9030 orport=9001 id=52AEA31188331F421B2EDB494DB65CD181E5B257
|
||||||
|
|
||||||
# Email sent directly to teor, verified using relay contact info
|
# Email sent directly to teor, verified using relay contact info
|
||||||
185.100.85.61:80 orport=443 id=025B66CEBC070FCB0519D206CF0CF4965C20C96E
|
185.100.85.61:80 orport=443 id=025B66CEBC070FCB0519D206CF0CF4965C20C96E
|
||||||
|
|
||||||
|
@ -682,8 +694,7 @@
|
||||||
213.239.217.18:1338 orport=1337 id=C37BC191AC389179674578C3E6944E925FE186C2 ipv6=[2a01:4f8:a0:746a:101:1:1:1]:1337
|
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
|
# Email sent directly to teor, verified using relay contact info
|
||||||
# Assume details update is permanent
|
188.40.128.246:9030 orport=9001 id=AD19490C7DBB26D3A68EFC824F67E69B0A96E601
|
||||||
188.40.128.246:9030 orport=9001 id=AD19490C7DBB26D3A68EFC824F67E69B0A96E601 ipv6=[2a01:4f8:221:1ac1:dead:beef:7005:9001]:9001 # sputnik
|
|
||||||
|
|
||||||
# Email sent directly to teor, verified using relay contact info
|
# 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
|
88.198.253.13:9030 orport=9001 id=DF924196D69AAE3C00C115A9CCDF7BB62A175310 ipv6=[2a01:4f8:11a:b1f::2]:9001
|
||||||
|
@ -701,44 +712,19 @@
|
||||||
# Email sent directly to teor, verified using relay contact info
|
# Email sent directly to teor, verified using relay contact info
|
||||||
107.170.101.39:9030 orport=443 id=30973217E70AF00EBE51797FF6D9AA720A902EAA
|
107.170.101.39:9030 orport=443 id=30973217E70AF00EBE51797FF6D9AA720A902EAA
|
||||||
|
|
||||||
# Email sent directly to teor
|
# Email sent directly to teor, verified using relay contact info
|
||||||
193.70.112.165:80 orport=443 id=F10BDE279AE71515DDCCCC61DC19AC8765F8A3CC # ParkBenchInd001
|
192.99.212.139:80 orport=443 id=F10BDE279AE71515DDCCCC61DC19AC8765F8A3CC
|
||||||
|
|
||||||
# Email sent directly to teor
|
# Email sent directly to teor, verified using relay contact info
|
||||||
185.220.101.6:10006 orport=20006 id=C08DE49658E5B3CFC6F2A952B453C4B608C9A16A # niftyvolcanorabbit
|
163.172.35.249:80 orport=443 id=C08DE49658E5B3CFC6F2A952B453C4B608C9A16A
|
||||||
185.220.101.13:10013 orport=20013 id=71AB4726D830FAE776D74AEF790CF04D8E0151B4 # niftycottontail
|
163.172.35.247:80 orport=443 id=71AB4726D830FAE776D74AEF790CF04D8E0151B4
|
||||||
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
|
# Email sent directly to teor, verified using relay contact info
|
||||||
64.113.32.29:9030 orport=9001 id=30C19B81981F450C402306E2E7CFB6C3F79CB6B2
|
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
|
# Emails sent directly to teor, verified using relay contact info
|
||||||
51.254.101.242:9002 orport=9001 id=4CC9CC9195EC38645B699A33307058624F660CCF
|
51.254.101.242:9002 orport=9001 id=4CC9CC9195EC38645B699A33307058624F660CCF
|
||||||
|
|
||||||
|
@ -795,17 +781,17 @@
|
||||||
178.33.183.251:80 orport=443 id=DD823AFB415380A802DCAEB9461AE637604107FB ipv6=[2001:41d0:2:a683::251]:443
|
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
|
# Email sent directly to teor, verified using relay contact info
|
||||||
31.185.104.19:80 orport=443 id=9EAD5B2D3DBD96DBC80DCE423B0C345E920A758D
|
#31.185.104.19:80 orport=443 id=9EAD5B2D3DBD96DBC80DCE423B0C345E920A758D
|
||||||
# same machine as 9EAD5B2D3DBD96DBC80DCE423B0C345E920A758D
|
# OK, but on same machine as 9EAD5B2D3DBD96DBC80DCE423B0C345E920A758D
|
||||||
31.185.104.20:80 orport=443 id=ADB2C26629643DBB9F8FE0096E7D16F9414B4F8D
|
31.185.104.20:80 orport=443 id=ADB2C26629643DBB9F8FE0096E7D16F9414B4F8D
|
||||||
31.185.104.21:80 orport=443 id=C2AAB088555850FC434E68943F551072042B85F1
|
#31.185.104.21:80 orport=443 id=C2AAB088555850FC434E68943F551072042B85F1
|
||||||
31.185.104.22:80 orport=443 id=5BA3A52760A0EABF7E7C3ED3048A77328FF0F148
|
#31.185.104.22:80 orport=443 id=5BA3A52760A0EABF7E7C3ED3048A77328FF0F148
|
||||||
|
|
||||||
# Email sent directly to teor, verified using relay contact info
|
# Email sent directly to teor, verified using relay contact info
|
||||||
185.34.60.114:80 orport=443 id=7F7A695DF6F2B8640A70B6ADD01105BC2EBC5135
|
185.34.60.114:80 orport=443 id=7F7A695DF6F2B8640A70B6ADD01105BC2EBC5135
|
||||||
|
|
||||||
# https://lists.torproject.org/pipermail/tor-relays/2017-December/013939.html
|
# 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 # rejozenger
|
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
|
# 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
|
185.129.62.62:9030 orport=9001 id=ACDD9E85A05B127BA010466C13C8C47212E8A38F ipv6=[2a06:d380:0:3700::62]:9001
|
||||||
|
@ -842,155 +828,3 @@
|
||||||
|
|
||||||
# Email sent directly to teor, verified using relay contact info
|
# Email sent directly to teor, verified using relay contact info
|
||||||
95.85.8.226:80 orport=443 id=1211AC1BBB8A1AF7CBA86BCE8689AA3146B86423
|
95.85.8.226:80 orport=443 id=1211AC1BBB8A1AF7CBA86BCE8689AA3146B86423
|
||||||
|
|
||||||
# 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
|
|
||||||
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
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
#!/usr/bin/python
|
#!/usr/bin/python
|
||||||
# Copyright (c) 2014-2017, The Tor Project, Inc.
|
# Copyright (c) 2014-2015, The Tor Project, Inc.
|
||||||
# See LICENSE for licensing information
|
# See LICENSE for licensing information
|
||||||
#
|
#
|
||||||
# This script reformats a section of the changelog to wrap everything to
|
# This script reformats a section of the changelog to wrap everything to
|
||||||
|
@ -205,8 +205,6 @@ def head_score(s):
|
||||||
score = -300
|
score = -300
|
||||||
elif lw.startswith("deprecated version"):
|
elif lw.startswith("deprecated version"):
|
||||||
score = -200
|
score = -200
|
||||||
elif lw.startswith("directory auth"):
|
|
||||||
score = -150
|
|
||||||
elif (('new' in lw and 'requirement' in lw) or
|
elif (('new' in lw and 'requirement' in lw) or
|
||||||
('new' in lw and 'dependenc' in lw) or
|
('new' in lw and 'dependenc' in lw) or
|
||||||
('build' in lw and 'requirement' in lw) or
|
('build' in lw and 'requirement' in lw) or
|
||||||
|
|
|
@ -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))
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
C_FILES=`echo src/common/*.c src/or/*.c src/tools/*.c`
|
||||||
|
CFLAGS="-Isrc/ext/trunnel -Isrc/trunnel -I. -Isrc/ext -Isrc/common -DLOCALSTATEDIR=\"\" -DSHARE_DATADIR=\"\" -Dinline="
|
||||||
|
|
||||||
|
mkdir -p callgraph/src/common
|
||||||
|
mkdir -p callgraph/src/or
|
||||||
|
mkdir -p callgraph/src/tools
|
||||||
|
|
||||||
|
for fn in $C_FILES; do
|
||||||
|
echo $fn
|
||||||
|
clang $CFLAGS -S -emit-llvm -fno-inline -o - $fn | \
|
||||||
|
opt -analyze -print-callgraph >/dev/null 2> "callgraph/${fn}allgraph"
|
||||||
|
done
|
|
@ -20,20 +20,8 @@ KNOWN_GROUPS = set([
|
||||||
"Testing",
|
"Testing",
|
||||||
"Documentation",
|
"Documentation",
|
||||||
"Code simplification and refactoring",
|
"Code simplification and refactoring",
|
||||||
"Removed features",
|
"Removed features"])
|
||||||
"Deprecated features",
|
|
||||||
"Directory authority changes"])
|
|
||||||
|
|
||||||
NEEDS_SUBCATEGORIES = set([
|
|
||||||
"Minor bugfix",
|
|
||||||
"Minor bugfixes",
|
|
||||||
"Major bugfix",
|
|
||||||
"Major bugfixes",
|
|
||||||
"Minor feature",
|
|
||||||
"Minor features",
|
|
||||||
"Major feature",
|
|
||||||
"Major features",
|
|
||||||
])
|
|
||||||
|
|
||||||
def lintfile(fname):
|
def lintfile(fname):
|
||||||
have_warned = []
|
have_warned = []
|
||||||
|
@ -58,11 +46,13 @@ def lintfile(fname):
|
||||||
|
|
||||||
m = re.match(r'^[ ]{2}o ([^\(:]*)([^:]*):', contents)
|
m = re.match(r'^[ ]{2}o ([^\(:]*)([^:]*):', contents)
|
||||||
if not m:
|
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:
|
elif m.group(1).strip() not in KNOWN_GROUPS:
|
||||||
warn("Unrecognized header: %r" % m.group(1))
|
warn("Weird header: %r" % m.group(1))
|
||||||
elif (m.group(1) in NEEDS_SUBCATEGORIES and '(' not in m.group(2)):
|
elif (("bugfix" in m.group(1) or "feature" in m.group(1)) and
|
||||||
warn("Missing subcategory on %r" % m.group(1))
|
("Removed" not in m.group(1)) and
|
||||||
|
'(' not in m.group(2)):
|
||||||
|
warn("Missing subcategory on %s" % m.group(1))
|
||||||
|
|
||||||
if m:
|
if m:
|
||||||
isBug = ("bug" in m.group(1).lower() or "fix" in m.group(1).lower())
|
isBug = ("bug" in m.group(1).lower() or "fix" in m.group(1).lower())
|
||||||
|
@ -72,46 +62,25 @@ def lintfile(fname):
|
||||||
contents = " ".join(contents.split())
|
contents = " ".join(contents.split())
|
||||||
|
|
||||||
if re.search(r'\#\d{2,}', contents):
|
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):
|
if isBug and not re.search(r'(\d+)', contents):
|
||||||
warn("Ticket marked as bugfix, but does not mention a number.")
|
warn("bugfix does not mention a number")
|
||||||
elif isBug and not re.search(r'Fixes ([a-z ]*)bugs? (\d+)', contents):
|
elif isBug and not re.search(r'Fixes ([a-z ]*)bug (\d+)', contents):
|
||||||
warn("Ticket marked as bugfix, but does not say 'Fixes bug XXX'")
|
warn("bugfix does not say 'Fixes bug XXX'")
|
||||||
|
|
||||||
if re.search(r'[bB]ug (\d+)', contents):
|
if re.search(r'[bB]ug (\d+)', contents):
|
||||||
if not re.search(r'[Bb]ugfix on ', contents):
|
if not re.search(r'[Bb]ugfix on ', contents):
|
||||||
warn("Bugfix does not say 'bugfix on X.Y.Z'")
|
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 ',
|
elif not re.search('[fF]ixes ([a-z ]*)bug (\d+); bugfix on ',
|
||||||
contents):
|
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):
|
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__':
|
if __name__ == '__main__':
|
||||||
problems = 0
|
for fname in sys.argv[1:]:
|
||||||
for fname in files(sys.argv[1:]):
|
|
||||||
if fname.endswith("~"):
|
if fname.endswith("~"):
|
||||||
continue
|
continue
|
||||||
if lintfile(fname):
|
lintfile(fname)
|
||||||
problems += 1
|
|
||||||
|
|
||||||
if problems:
|
|
||||||
sys.exit(1)
|
|
||||||
else:
|
|
||||||
sys.exit(0)
|
|
||||||
|
|
|
@ -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)
|
|
|
@ -1,6 +1,6 @@
|
||||||
#!/usr/bin/python
|
#!/usr/bin/python
|
||||||
#
|
#
|
||||||
# Copyright (c) 2008-2017, The Tor Project, Inc.
|
# Copyright (c) 2008-2015, The Tor Project, Inc.
|
||||||
# See LICENSE for licensing information.
|
# See LICENSE for licensing information.
|
||||||
#
|
#
|
||||||
# Hi!
|
# Hi!
|
||||||
|
@ -101,7 +101,7 @@ def read():
|
||||||
|
|
||||||
def findline(lines, lineno, ident):
|
def findline(lines, lineno, ident):
|
||||||
"""Given a list of all the lines in the file (adjusted so 1-indexing works),
|
"""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."""
|
the line where ident was really declared."""
|
||||||
lno = lineno
|
lno = lineno
|
||||||
for lineno in xrange(lineno, 0, -1):
|
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,5 +1,5 @@
|
||||||
#!/usr/bin/python
|
#!/usr/bin/python
|
||||||
# Copyright (c) 2014-2017, The Tor Project, Inc.
|
# Copyright (c) 2014-2015, The Tor Project, Inc.
|
||||||
# See LICENSE for licensing information
|
# See LICENSE for licensing information
|
||||||
|
|
||||||
"""This script sorts a bunch of changes files listed on its command
|
"""This script sorts a bunch of changes files listed on its command
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/perl -i -w -p
|
#!/usr/bin/perl -i -w -p
|
||||||
|
|
||||||
$NEWYEAR=2017;
|
$NEWYEAR=2016;
|
||||||
|
|
||||||
s/Copyright(.*) (201[^7]), The Tor Project/Copyright$1 $2-${NEWYEAR}, The Tor Project/;
|
s/Copyright(.*) (201[^6]), The Tor Project/Copyright$1 $2-${NEWYEAR}, The Tor Project/;
|
||||||
|
|
||||||
s/Copyright(.*)-(20..), The Tor Project/Copyright$1-${NEWYEAR}, The Tor Project/;
|
s/Copyright(.*)-(20..), The Tor Project/Copyright$1-${NEWYEAR}, The Tor Project/;
|
||||||
|
|
|
@ -1,25 +1,22 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/python
|
||||||
|
|
||||||
# Usage:
|
# Usage:
|
||||||
#
|
# scripts/maint/updateFallbackDirs.py > src/or/fallback_dirs.inc
|
||||||
# Regenerate the list:
|
# scripts/maint/updateFallbackDirs.py check_existing > src/or/fallback_dirs.inc
|
||||||
# scripts/maint/updateFallbackDirs.py > src/or/fallback_dirs.inc 2> fallback_dirs.log
|
|
||||||
#
|
|
||||||
# Check the existing list:
|
|
||||||
# scripts/maint/updateFallbackDirs.py check_existing > fallback_dirs.inc.ok 2> fallback_dirs.log
|
|
||||||
# mv fallback_dirs.inc.ok src/or/fallback_dirs.inc
|
|
||||||
#
|
#
|
||||||
# This script should be run from a stable, reliable network connection,
|
# This script should be run from a stable, reliable network connection,
|
||||||
# with no other network activity (and not over tor).
|
# with no other network activity (and not over tor).
|
||||||
# If this is not possible, please disable:
|
# If this is not possible, please disable:
|
||||||
# PERFORM_IPV4_DIRPORT_CHECKS and PERFORM_IPV6_DIRPORT_CHECKS
|
# 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)
|
# 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
|
# 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
|
# Script by weasel, April 2015
|
||||||
# Portions by gsathya & karsten, 2013
|
# Portions by gsathya & karsten, 2013
|
||||||
|
@ -45,7 +42,7 @@ import copy
|
||||||
import re
|
import re
|
||||||
|
|
||||||
from stem.descriptor import DocumentHandler
|
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
|
import logging
|
||||||
logging.root.name = ''
|
logging.root.name = ''
|
||||||
|
@ -66,17 +63,6 @@ except ImportError:
|
||||||
|
|
||||||
## Top-Level Configuration
|
## 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 all candidate fallbacks, or only output selected fallbacks?
|
||||||
OUTPUT_CANDIDATES = False
|
OUTPUT_CANDIDATES = False
|
||||||
|
|
||||||
|
@ -107,12 +93,11 @@ DOWNLOAD_MICRODESC_CONSENSUS = True
|
||||||
# reject consensuses that are older than REASONABLY_LIVE_TIME.
|
# reject consensuses that are older than REASONABLY_LIVE_TIME.
|
||||||
# For the consensus expiry check to be accurate, the machine running this
|
# For the consensus expiry check to be accurate, the machine running this
|
||||||
# script needs an accurate clock.
|
# script needs an accurate clock.
|
||||||
#
|
# We use 24 hours to compensate for #20909, where relays on 0.2.9.5-alpha and
|
||||||
# Relays on 0.3.0 and later return a 404 when they are about to serve an
|
# 0.3.0.0-alpha-dev and later deliver stale consensuses, but typically recover
|
||||||
# expired consensus. This makes them fail the download check.
|
# after ~12 hours.
|
||||||
# We use a tolerance of 0, so that 0.2.x series relays also fail the download
|
# We should make this lower when #20909 is fixed, see #20942.
|
||||||
# check if they serve an expired consensus.
|
CONSENSUS_EXPIRY_TOLERANCE = 24*60*60
|
||||||
CONSENSUS_EXPIRY_TOLERANCE = 0
|
|
||||||
|
|
||||||
# Output fallback name, flags, bandwidth, and ContactInfo in a C comment?
|
# Output fallback name, flags, bandwidth, and ContactInfo in a C comment?
|
||||||
OUTPUT_COMMENTS = True if OUTPUT_CANDIDATES else False
|
OUTPUT_COMMENTS = True if OUTPUT_CANDIDATES else False
|
||||||
|
@ -169,25 +154,22 @@ MAX_LIST_FILE_SIZE = 1024 * 1024
|
||||||
## Eligibility Settings
|
## Eligibility Settings
|
||||||
|
|
||||||
# Require fallbacks to have the same address and port for a set amount of time
|
# 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.
|
|
||||||
#
|
#
|
||||||
# If a relay changes address or port, that's it, it's not useful any more,
|
# There was a bug in Tor 0.2.8.1-alpha and earlier where a relay temporarily
|
||||||
# because clients can't find it
|
# submits a 0 DirPort when restarted.
|
||||||
ADDRESS_AND_PORT_STABLE_DAYS = 90
|
# 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 = 7
|
||||||
# We ignore relays that have been down for more than this period
|
# We ignore relays that have been down for more than this period
|
||||||
MAX_DOWNTIME_DAYS = 0 if MUST_BE_RUNNING_NOW else 7
|
MAX_DOWNTIME_DAYS = 0 if MUST_BE_RUNNING_NOW else 7
|
||||||
# FallbackDirs must have a time-weighted-fraction that is greater than or
|
# What time-weighted-fraction of these flags must FallbackDirs
|
||||||
# equal to:
|
# Equal or Exceed?
|
||||||
# Mirrors that are down half the time are still useful half the time
|
CUTOFF_RUNNING = .90
|
||||||
CUTOFF_RUNNING = .50
|
CUTOFF_V2DIR = .90
|
||||||
CUTOFF_V2DIR = .50
|
CUTOFF_GUARD = .90
|
||||||
# Guard flags are removed for some time after a relay restarts, so we ignore
|
# What time-weighted-fraction of these flags must FallbackDirs
|
||||||
# the guard flag.
|
# Equal or Fall Under?
|
||||||
CUTOFF_GUARD = .00
|
|
||||||
# FallbackDirs must have a time-weighted-fraction that is less than or equal
|
|
||||||
# to:
|
|
||||||
# .00 means no bad exits
|
# .00 means no bad exits
|
||||||
PERMITTED_BADEXIT = .00
|
PERMITTED_BADEXIT = .00
|
||||||
|
|
||||||
|
@ -207,26 +189,20 @@ FALLBACK_PROPORTION_OF_GUARDS = None if OUTPUT_CANDIDATES else _FB_POG
|
||||||
# Limit the number of fallbacks (eliminating lowest by advertised bandwidth)
|
# Limit the number of fallbacks (eliminating lowest by advertised bandwidth)
|
||||||
MAX_FALLBACK_COUNT = None if OUTPUT_CANDIDATES else 200
|
MAX_FALLBACK_COUNT = None if OUTPUT_CANDIDATES else 200
|
||||||
# Emit a C #error if the number of fallbacks is less than expected
|
# Emit a C #error if the number of fallbacks is less than expected
|
||||||
MIN_FALLBACK_COUNT = 0 if OUTPUT_CANDIDATES else MAX_FALLBACK_COUNT*0.5
|
MIN_FALLBACK_COUNT = 0 if OUTPUT_CANDIDATES else MAX_FALLBACK_COUNT*0.75
|
||||||
|
|
||||||
# The maximum number of fallbacks on the same address, contact, or family
|
# The maximum number of fallbacks on the same address, contact, or family
|
||||||
#
|
# With 200 fallbacks, this means each operator can see 1% of client bootstraps
|
||||||
# With 150 fallbacks, this means each operator sees 5% of client bootstraps.
|
# (The directory authorities used to see ~12% of client bootstraps each.)
|
||||||
# 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.
|
|
||||||
MAX_FALLBACKS_PER_IP = 1
|
MAX_FALLBACKS_PER_IP = 1
|
||||||
MAX_FALLBACKS_PER_IPV4 = MAX_FALLBACKS_PER_IP
|
MAX_FALLBACKS_PER_IPV4 = MAX_FALLBACKS_PER_IP
|
||||||
MAX_FALLBACKS_PER_IPV6 = MAX_FALLBACKS_PER_IP
|
MAX_FALLBACKS_PER_IPV6 = MAX_FALLBACKS_PER_IP
|
||||||
MAX_FALLBACKS_PER_CONTACT = 7
|
MAX_FALLBACKS_PER_CONTACT = 3
|
||||||
MAX_FALLBACKS_PER_FAMILY = 7
|
MAX_FALLBACKS_PER_FAMILY = 3
|
||||||
|
|
||||||
## Fallback Bandwidth Requirements
|
## 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
|
# to make sure we aren't further overloading exits
|
||||||
# (Set to 1.0, because we asked that only lightly loaded exits opt-in,
|
# (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.)
|
# and the extra load really isn't that much for large relays.)
|
||||||
|
@ -234,11 +210,11 @@ EXIT_BANDWIDTH_FRACTION = 1.0
|
||||||
|
|
||||||
# If a single fallback's bandwidth is too low, it's pointless adding it
|
# 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
|
# 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,
|
# We convert this to a consensus weight before applying the filter,
|
||||||
# because all the bandwidth amounts are specified by the relay
|
# 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
|
# Clients will time out after 30 seconds trying to download a consensus
|
||||||
# So allow fallback directories half that to deliver a consensus
|
# So allow fallback directories half that to deliver a consensus
|
||||||
|
@ -250,6 +226,21 @@ CONSENSUS_DOWNLOAD_SPEED_MAX = 15.0
|
||||||
# This avoids delisting a relay due to transient network conditions
|
# This avoids delisting a relay due to transient network conditions
|
||||||
CONSENSUS_DOWNLOAD_RETRY = True
|
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
|
## Parsing Functions
|
||||||
|
|
||||||
def parse_ts(t):
|
def parse_ts(t):
|
||||||
|
@ -289,10 +280,6 @@ def cleanse_c_multiline_comment(raw_string):
|
||||||
bad_char_list = '*/'
|
bad_char_list = '*/'
|
||||||
# Prevent a malicious string from using C nulls
|
# Prevent a malicious string from using C nulls
|
||||||
bad_char_list += '\0'
|
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
|
# Be safer by removing bad characters entirely
|
||||||
cleansed_string = remove_bad_chars(cleansed_string, bad_char_list)
|
cleansed_string = remove_bad_chars(cleansed_string, bad_char_list)
|
||||||
# Some compilers may further process the content of comments
|
# Some compilers may further process the content of comments
|
||||||
|
@ -313,10 +300,6 @@ def cleanse_c_string(raw_string):
|
||||||
bad_char_list += '\\'
|
bad_char_list += '\\'
|
||||||
# Prevent a malicious string from using C nulls
|
# Prevent a malicious string from using C nulls
|
||||||
bad_char_list += '\0'
|
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
|
# Be safer by removing bad characters entirely
|
||||||
cleansed_string = remove_bad_chars(cleansed_string, bad_char_list)
|
cleansed_string = remove_bad_chars(cleansed_string, bad_char_list)
|
||||||
# Some compilers may further process the content of strings
|
# Some compilers may further process the content of strings
|
||||||
|
@ -555,7 +538,7 @@ class Candidate(object):
|
||||||
details['flags'] = []
|
details['flags'] = []
|
||||||
if (not 'advertised_bandwidth' in details
|
if (not 'advertised_bandwidth' in details
|
||||||
or details['advertised_bandwidth'] is None):
|
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
|
# consensus weight
|
||||||
details['advertised_bandwidth'] = 0
|
details['advertised_bandwidth'] = 0
|
||||||
if (not 'effective_family' in details
|
if (not 'effective_family' in details
|
||||||
|
@ -578,7 +561,6 @@ class Candidate(object):
|
||||||
if not self.has_ipv6():
|
if not self.has_ipv6():
|
||||||
logging.debug("Failed to get an ipv6 address for %s."%(self._fpr,))
|
logging.debug("Failed to get an ipv6 address for %s."%(self._fpr,))
|
||||||
self._compute_version()
|
self._compute_version()
|
||||||
self._extra_info_cache = None
|
|
||||||
|
|
||||||
def _stable_sort_or_addresses(self):
|
def _stable_sort_or_addresses(self):
|
||||||
# replace self._data['or_addresses'] with a stable ordering,
|
# replace self._data['or_addresses'] with a stable ordering,
|
||||||
|
@ -1344,14 +1326,8 @@ class Candidate(object):
|
||||||
# comment-out the returned string
|
# comment-out the returned string
|
||||||
def fallbackdir_info(self, dl_speed_ok):
|
def fallbackdir_info(self, dl_speed_ok):
|
||||||
# "address:dirport orport=port id=fingerprint"
|
# "address:dirport orport=port id=fingerprint"
|
||||||
# (insert additional madatory fields here)
|
|
||||||
# "[ipv6=addr:orport]"
|
# "[ipv6=addr:orport]"
|
||||||
# (insert additional optional fields here)
|
# "weight=FALLBACK_OUTPUT_WEIGHT",
|
||||||
# /* nickname=name */
|
|
||||||
# /* extrainfo={0,1} */
|
|
||||||
# (insert additional comment fields here)
|
|
||||||
# /* ===== */
|
|
||||||
# ,
|
|
||||||
#
|
#
|
||||||
# Do we want a C string, or a commented-out string?
|
# Do we want a C string, or a commented-out string?
|
||||||
c_string = dl_speed_ok
|
c_string = dl_speed_ok
|
||||||
|
@ -1372,34 +1348,10 @@ class Candidate(object):
|
||||||
self.orport,
|
self.orport,
|
||||||
cleanse_c_string(self._fpr))
|
cleanse_c_string(self._fpr))
|
||||||
s += '\n'
|
s += '\n'
|
||||||
# (insert additional madatory fields here)
|
|
||||||
if self.has_ipv6():
|
if self.has_ipv6():
|
||||||
s += '" ipv6=%s:%d"'%(cleanse_c_string(self.ipv6addr), self.ipv6orport)
|
s += '" ipv6=%s:%d"'%(cleanse_c_string(self.ipv6addr), self.ipv6orport)
|
||||||
s += '\n'
|
s += '\n'
|
||||||
# (insert additional optional fields here)
|
s += '" weight=%d",'%(FALLBACK_OUTPUT_WEIGHT)
|
||||||
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 += ','
|
|
||||||
if comment_string:
|
if comment_string:
|
||||||
s += '\n'
|
s += '\n'
|
||||||
s += '*/'
|
s += '*/'
|
||||||
|
@ -1589,7 +1541,7 @@ class CandidateList(dict):
|
||||||
excluded_count, initial_count)
|
excluded_count, initial_count)
|
||||||
|
|
||||||
# calculate each fallback's measured bandwidth based on the median
|
# 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):
|
def calculate_measured_bandwidth(self):
|
||||||
self.sort_fallbacks_by_cw_to_bw_factor()
|
self.sort_fallbacks_by_cw_to_bw_factor()
|
||||||
median_fallback = self.fallback_median(True)
|
median_fallback = self.fallback_median(True)
|
||||||
|
@ -1784,53 +1736,6 @@ class CandidateList(dict):
|
||||||
self.fallbacks = family_limit_fallbacks
|
self.fallbacks = family_limit_fallbacks
|
||||||
return original_count - len(self.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
|
# try a download check on each fallback candidate in order
|
||||||
# stop after max_count successful downloads
|
# stop after max_count successful downloads
|
||||||
# but don't remove any candidates from the array
|
# but don't remove any candidates from the array
|
||||||
|
@ -1990,7 +1895,7 @@ class CandidateList(dict):
|
||||||
# this doesn't actually tell us anything useful
|
# this doesn't actually tell us anything useful
|
||||||
#self.describe_fallback_ipv4_netblock_mask(8)
|
#self.describe_fallback_ipv4_netblock_mask(8)
|
||||||
self.describe_fallback_ipv4_netblock_mask(16)
|
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),
|
# log a message about the proportion of fallbacks in each IPv6 /12 (RIR),
|
||||||
# /23 (smaller RIR blocks), /32 (LIR), /48 (Customer), and /64 (Host)
|
# /23 (smaller RIR blocks), /32 (LIR), /48 (Customer), and /64 (Host)
|
||||||
|
@ -2000,7 +1905,7 @@ class CandidateList(dict):
|
||||||
#self.describe_fallback_ipv6_netblock_mask(12)
|
#self.describe_fallback_ipv6_netblock_mask(12)
|
||||||
#self.describe_fallback_ipv6_netblock_mask(23)
|
#self.describe_fallback_ipv6_netblock_mask(23)
|
||||||
self.describe_fallback_ipv6_netblock_mask(32)
|
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)
|
self.describe_fallback_ipv6_netblock_mask(64)
|
||||||
|
|
||||||
# log a message about the proportion of fallbacks in each IPv4 and IPv6
|
# log a message about the proportion of fallbacks in each IPv4 and IPv6
|
||||||
|
@ -2078,18 +1983,6 @@ class CandidateList(dict):
|
||||||
CandidateList.describe_percentage(dir_count,
|
CandidateList.describe_percentage(dir_count,
|
||||||
fallback_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
|
# return a list of fallbacks which have the Exit flag
|
||||||
def fallbacks_with_exit(self):
|
def fallbacks_with_exit(self):
|
||||||
return filter(lambda x: x.is_exit(), self.fallbacks)
|
return filter(lambda x: x.is_exit(), self.fallbacks)
|
||||||
|
@ -2117,6 +2010,10 @@ class CandidateList(dict):
|
||||||
def summarise_fallbacks(self, eligible_count, operator_count, failed_count,
|
def summarise_fallbacks(self, eligible_count, operator_count, failed_count,
|
||||||
guard_count, target_count):
|
guard_count, target_count):
|
||||||
s = ''
|
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:
|
# Report:
|
||||||
# whether we checked consensus download times
|
# whether we checked consensus download times
|
||||||
# the number of fallback directories (and limits/exclusions, if relevant)
|
# the number of fallback directories (and limits/exclusions, if relevant)
|
||||||
|
@ -2217,16 +2114,6 @@ def list_fallbacks(whitelist, blacklist):
|
||||||
""" Fetches required onionoo documents and evaluates the
|
""" Fetches required onionoo documents and evaluates the
|
||||||
fallback directory criteria for each of the relays """
|
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. ' +
|
logging.warning('Downloading and parsing Onionoo data. ' +
|
||||||
'This may take some time.')
|
'This may take some time.')
|
||||||
# find relays that could be fallbacks
|
# find relays that could be fallbacks
|
||||||
|
@ -2292,9 +2179,6 @@ def list_fallbacks(whitelist, blacklist):
|
||||||
'This may take some time.')
|
'This may take some time.')
|
||||||
failed_count = candidates.perform_download_consensus_checks(max_count)
|
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
|
# analyse and log interesting diversity metrics
|
||||||
# like netblock, ports, exit, IPv4-only
|
# like netblock, ports, exit, IPv4-only
|
||||||
# (we can't easily analyse AS, and it's hard to accurately analyse country)
|
# (we can't easily analyse AS, and it's hard to accurately analyse country)
|
||||||
|
@ -2303,7 +2187,6 @@ def list_fallbacks(whitelist, blacklist):
|
||||||
if HAVE_IPADDRESS:
|
if HAVE_IPADDRESS:
|
||||||
candidates.describe_fallback_netblocks()
|
candidates.describe_fallback_netblocks()
|
||||||
candidates.describe_fallback_ports()
|
candidates.describe_fallback_ports()
|
||||||
candidates.describe_fallback_extra_info_caches()
|
|
||||||
candidates.describe_fallback_exit_flag()
|
candidates.describe_fallback_exit_flag()
|
||||||
|
|
||||||
# output C comments summarising the fallback selection process
|
# output C comments summarising the fallback selection process
|
||||||
|
@ -2318,9 +2201,6 @@ def list_fallbacks(whitelist, blacklist):
|
||||||
for s in fetch_source_list():
|
for s in fetch_source_list():
|
||||||
print describe_fetch_source(s)
|
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:
|
# sort the list differently depending on why we've created it:
|
||||||
# if we're outputting the final fallback list, sort by fingerprint
|
# if we're outputting the final fallback list, sort by fingerprint
|
||||||
# this makes diffs much more stable
|
# 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"
|
DIRA="$1"
|
||||||
DIRB="$2"
|
DIRB="$2"
|
||||||
|
|
||||||
for B in $DIRB/*; do
|
for A in $DIRA/*; do
|
||||||
A=$DIRA/`basename $B`
|
B=$DIRB/`basename $A`
|
||||||
if [ -f $A ]; then
|
perl -pe 's/^\s*\!*\d+:/ 1:/; s/^([^:]+:)[\d\s]+:/$1/; s/^ *-:(Runs|Programs):.*//;' "$A" > "$A.tmp"
|
||||||
perl -pe 's/^\s*\!*\d+(\*?):/ 1$1:/; s/^([^:]+:)[\d\s]+:/$1/; s/^ *-:(Runs|Programs):.*//;' "$A" > "$A.tmp"
|
perl -pe 's/^\s*\!*\d+:/ 1:/; s/^([^:]+:)[\d\s]+:/$1/; s/^ *-:(Runs|Programs):.*//;' "$B" > "$B.tmp"
|
||||||
else
|
diff -u "$A.tmp" "$B.tmp"
|
||||||
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/;'
|
|
||||||
rm "$A.tmp" "$B.tmp"
|
rm "$A.tmp" "$B.tmp"
|
||||||
done
|
done
|
||||||
|
|
||||||
|
|
|
@ -26,9 +26,3 @@ if ($excluding or $exclude_this) {
|
||||||
s{^\s*\#\#+:}{ x:};
|
s{^\s*\#\#+:}{ x:};
|
||||||
s{^ (\s*)(\d+):}{$1!!!$2:};
|
s{^ (\s*)(\d+):}{$1!!!$2:};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (eof and $excluding) {
|
|
||||||
warn "Runaway LCOV_EXCL_START in $ARGV";
|
|
||||||
$excluding = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
|
@ -29,7 +29,7 @@ for fn in src/or/*.c src/common/*.c; do
|
||||||
gcov -o $on $fn
|
gcov -o $on $fn
|
||||||
if [ -e $GC ]
|
if [ -e $GC ]
|
||||||
then
|
then
|
||||||
if [ -d "$dst" ]
|
if [ -n $dst ]
|
||||||
then
|
then
|
||||||
mv $GC $dst/$GC
|
mv $GC $dst/$GC
|
||||||
fi
|
fi
|
||||||
|
|
|
@ -5,76 +5,37 @@
|
||||||
# This script is used for running a bunch of clang scan-build checkers
|
# This script is used for running a bunch of clang scan-build checkers
|
||||||
# on Tor.
|
# on Tor.
|
||||||
|
|
||||||
# These don't seem to cause false positives in our code, so let's turn
|
|
||||||
# them on.
|
|
||||||
CHECKERS="\
|
CHECKERS="\
|
||||||
-enable-checker alpha.core.CallAndMessageUnInitRefArg \
|
-disable-checker deadcode.DeadStores \
|
||||||
|
-enable-checker alpha.core.CastSize \
|
||||||
-enable-checker alpha.core.CastToStruct \
|
-enable-checker alpha.core.CastToStruct \
|
||||||
-enable-checker alpha.core.Conversion \
|
|
||||||
-enable-checker alpha.core.FixedAddr \
|
|
||||||
-enable-checker alpha.core.IdenticalExpr \
|
-enable-checker alpha.core.IdenticalExpr \
|
||||||
-enable-checker alpha.core.PointerArithm \
|
|
||||||
-enable-checker alpha.core.SizeofPtr \
|
-enable-checker alpha.core.SizeofPtr \
|
||||||
-enable-checker alpha.core.TestAfterDivZero \
|
-enable-checker alpha.security.ArrayBoundV2 \
|
||||||
-enable-checker alpha.security.MallocOverflow \
|
-enable-checker alpha.security.MallocOverflow \
|
||||||
-enable-checker alpha.security.ReturnPtrRange \
|
-enable-checker alpha.security.ReturnPtrRange \
|
||||||
-enable-checker alpha.unix.BlockInCriticalSection \
|
-enable-checker alpha.unix.SimpleStream
|
||||||
-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.cstring.BufferOverlap \
|
-enable-checker alpha.unix.cstring.BufferOverlap \
|
||||||
-enable-checker alpha.unix.cstring.NotNullTerminated \
|
-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.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 \
|
scan-build \
|
||||||
$CHECKERS \
|
$CHECKERS \
|
||||||
./configure
|
./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 \
|
scan-build \
|
||||||
$CHECKERS \
|
$CHECKERS \
|
||||||
-disable-checker deadcode.DeadStores \
|
make -j2 -k
|
||||||
make -j5 -k ./src/ext/ed25519/ref10/libed25519_ref10.a
|
|
||||||
|
|
||||||
scan-build \
|
|
||||||
$CHECKERS $OUTPUTARG \
|
|
||||||
make -j5 -k
|
|
||||||
|
|
||||||
CHECKERS="\
|
|
||||||
"
|
|
||||||
|
|
||||||
# This one gives a false positive on every strcmp.
|
# This one gives a false positive on every strcmp.
|
||||||
# -enable-checker alpha.core.PointerSub
|
# -enable-checker alpha.core.PointerSub
|
||||||
|
|
||||||
# Needs work
|
# Needs work
|
||||||
# -enable-checker alpha.unix.MallocWithAnnotations
|
# alpha.unix.MallocWithAnnotations ??
|
||||||
|
|
|
@ -7,8 +7,8 @@ LIBOR_OBJECTS = address.obj backtrace.obj compat.obj container.obj di_ops.obj \
|
||||||
log.obj memarea.obj mempool.obj procmon.obj sandbox.obj util.obj \
|
log.obj memarea.obj mempool.obj procmon.obj sandbox.obj util.obj \
|
||||||
util_codedigest.obj
|
util_codedigest.obj
|
||||||
|
|
||||||
LIBOR_CRYPTO_OBJECTS = aes.obj crypto.obj crypto_format.obj compress.obj compress_zlib.obj \
|
LIBOR_CRYPTO_OBJECTS = aes.obj crypto.obj crypto_format.obj torgzip.obj tortls.obj \
|
||||||
tortls.obj crypto_curve25519.obj curve25519-donna.obj
|
crypto_curve25519.obj curve25519-donna.obj
|
||||||
|
|
||||||
LIBOR_EVENT_OBJECTS = compat_libevent.obj
|
LIBOR_EVENT_OBJECTS = compat_libevent.obj
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* Copyright (c) 2003-2004, Roger Dingledine
|
/* Copyright (c) 2003-2004, Roger Dingledine
|
||||||
* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
|
* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
|
||||||
* Copyright (c) 2007-2017, The Tor Project, Inc. */
|
* Copyright (c) 2007-2016, The Tor Project, Inc. */
|
||||||
/* See LICENSE for licensing information */
|
/* See LICENSE for licensing information */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -33,7 +33,7 @@
|
||||||
#include <process.h>
|
#include <process.h>
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include <iphlpapi.h>
|
#include <iphlpapi.h>
|
||||||
#endif /* defined(_WIN32) */
|
#endif
|
||||||
|
|
||||||
#include "compat.h"
|
#include "compat.h"
|
||||||
#include "util.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);
|
tor_asprintf(&result, "unix:%s", s_un->sun_path);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
#endif /* defined(HAVE_SYS_UN_H) */
|
#endif
|
||||||
if (sa->sa_family == AF_UNSPEC)
|
if (sa->sa_family == AF_UNSPEC)
|
||||||
return tor_strdup("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 result;
|
||||||
}
|
}
|
||||||
return (err == EAI_AGAIN) ? 1 : -1;
|
return (err == EAI_AGAIN) ? 1 : -1;
|
||||||
#else /* !(defined(HAVE_GETADDRINFO)) */
|
#else
|
||||||
struct hostent *ent;
|
struct hostent *ent;
|
||||||
int err;
|
int err;
|
||||||
#ifdef HAVE_GETHOSTBYNAME_R_6_ARG
|
#ifdef HAVE_GETHOSTBYNAME_R_6_ARG
|
||||||
|
@ -330,7 +330,7 @@ tor_addr_lookup,(const char *name, uint16_t family, tor_addr_t *addr))
|
||||||
#else
|
#else
|
||||||
err = h_errno;
|
err = h_errno;
|
||||||
#endif
|
#endif
|
||||||
#endif /* defined(HAVE_GETHOSTBYNAME_R_6_ARG) || ... */
|
#endif /* endif HAVE_GETHOSTBYNAME_R_6_ARG. */
|
||||||
if (ent) {
|
if (ent) {
|
||||||
if (ent->h_addrtype == AF_INET) {
|
if (ent->h_addrtype == AF_INET) {
|
||||||
tor_addr_from_in(addr, (struct in_addr*) ent->h_addr);
|
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
|
#else
|
||||||
return (err == TRY_AGAIN) ? 1 : -1;
|
return (err == TRY_AGAIN) ? 1 : -1;
|
||||||
#endif
|
#endif
|
||||||
#endif /* defined(HAVE_GETADDRINFO) */
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -564,8 +564,8 @@ tor_addr_parse_PTR_name(tor_addr_t *result, const char *address,
|
||||||
|
|
||||||
/** Convert <b>addr</b> to an in-addr.arpa name or a .ip6.arpa name,
|
/** Convert <b>addr</b> to an in-addr.arpa name or a .ip6.arpa name,
|
||||||
* and store the result in the <b>outlen</b>-byte buffer at
|
* and store the result in the <b>outlen</b>-byte buffer at
|
||||||
* <b>out</b>. Returns a non-negative integer on success.
|
* <b>out</b>. Return the number of chars written to <b>out</b>, not
|
||||||
* Returns -1 on failure. */
|
* including the trailing \0, on success. Returns -1 on failure. */
|
||||||
int
|
int
|
||||||
tor_addr_to_PTR_name(char *out, size_t outlen,
|
tor_addr_to_PTR_name(char *out, size_t outlen,
|
||||||
const tor_addr_t *addr)
|
const tor_addr_t *addr)
|
||||||
|
@ -907,8 +907,8 @@ tor_addr_is_loopback(const tor_addr_t *addr)
|
||||||
return (tor_addr_to_ipv4h(addr) & 0xff000000) == 0x7f000000;
|
return (tor_addr_to_ipv4h(addr) & 0xff000000) == 0x7f000000;
|
||||||
case AF_UNSPEC:
|
case AF_UNSPEC:
|
||||||
return 0;
|
return 0;
|
||||||
/* LCOV_EXCL_START */
|
|
||||||
default:
|
default:
|
||||||
|
/* LCOV_EXCL_START */
|
||||||
tor_fragile_assert();
|
tor_fragile_assert();
|
||||||
return 0;
|
return 0;
|
||||||
/* LCOV_EXCL_STOP */
|
/* 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);
|
memcpy(dest->addr.in6_addr.s6_addr, src->addr.in6_addr.s6_addr, 16);
|
||||||
case AF_UNSPEC:
|
case AF_UNSPEC:
|
||||||
break;
|
break;
|
||||||
// LCOV_EXCL_START
|
|
||||||
default:
|
default:
|
||||||
tor_fragile_assert();
|
tor_fragile_assert(); // LCOV_EXCL_LINE
|
||||||
// LCOV_EXCL_STOP
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1125,7 +1123,7 @@ tor_addr_compare_masked(const tor_addr_t *addr1, const tor_addr_t *addr2,
|
||||||
case AF_UNIX:
|
case AF_UNIX:
|
||||||
/* HACKHACKHACKHACKHACK:
|
/* HACKHACKHACKHACKHACK:
|
||||||
* tor_addr_t doesn't contain a copy of sun_path, so it's not
|
* 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
|
* Since the only time we currently actually should be comparing
|
||||||
* 2 AF_UNIX addresses is when dealing with ISO_CLIENTADDR (which
|
* 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;
|
return 0;
|
||||||
else
|
else
|
||||||
return 1;
|
return 1;
|
||||||
/* LCOV_EXCL_START */
|
|
||||||
default:
|
default:
|
||||||
|
/* LCOV_EXCL_START */
|
||||||
tor_fragile_assert();
|
tor_fragile_assert();
|
||||||
return 0;
|
return 0;
|
||||||
/* LCOV_EXCL_STOP */
|
/* LCOV_EXCL_STOP */
|
||||||
|
@ -1185,9 +1183,6 @@ tor_addr_compare_masked(const tor_addr_t *addr1, const tor_addr_t *addr2,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Input for siphash, to produce some output for an unspec value. */
|
|
||||||
static const uint32_t unspec_hash_input[] = { 0x4e4df09f, 0x92985342 };
|
|
||||||
|
|
||||||
/** Return a hash code based on the address addr. DOCDOC extra */
|
/** Return a hash code based on the address addr. DOCDOC extra */
|
||||||
uint64_t
|
uint64_t
|
||||||
tor_addr_hash(const tor_addr_t *addr)
|
tor_addr_hash(const tor_addr_t *addr)
|
||||||
|
@ -1196,36 +1191,14 @@ tor_addr_hash(const tor_addr_t *addr)
|
||||||
case AF_INET:
|
case AF_INET:
|
||||||
return siphash24g(&addr->addr.in_addr.s_addr, 4);
|
return siphash24g(&addr->addr.in_addr.s_addr, 4);
|
||||||
case AF_UNSPEC:
|
case AF_UNSPEC:
|
||||||
return siphash24g(unspec_hash_input, sizeof(unspec_hash_input));
|
return 0x4e4d5342;
|
||||||
case AF_INET6:
|
case AF_INET6:
|
||||||
return siphash24g(&addr->addr.in6_addr.s6_addr, 16);
|
return siphash24g(&addr->addr.in6_addr.s6_addr, 16);
|
||||||
/* LCOV_EXCL_START */
|
|
||||||
default:
|
|
||||||
tor_fragile_assert();
|
|
||||||
return 0;
|
|
||||||
/* LCOV_EXCL_STOP */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** As tor_addr_hash, but use a particular siphash key. */
|
|
||||||
uint64_t
|
|
||||||
tor_addr_keyed_hash(const struct sipkey *key, const tor_addr_t *addr)
|
|
||||||
{
|
|
||||||
/* This is duplicate code with tor_addr_hash, since this function needs to
|
|
||||||
* be backportable all the way to 0.2.9. */
|
|
||||||
|
|
||||||
switch (tor_addr_family(addr)) {
|
|
||||||
case AF_INET:
|
|
||||||
return siphash24(&addr->addr.in_addr.s_addr, 4, key);
|
|
||||||
case AF_UNSPEC:
|
|
||||||
return siphash24(unspec_hash_input, sizeof(unspec_hash_input), key);
|
|
||||||
case AF_INET6:
|
|
||||||
return siphash24(&addr->addr.in6_addr.s6_addr, 16, key);
|
|
||||||
default:
|
default:
|
||||||
/* LCOV_EXCL_START */
|
/* LCOV_EXCL_START */
|
||||||
tor_fragile_assert();
|
tor_fragile_assert();
|
||||||
return 0;
|
return 0;
|
||||||
/* LCOV_EXCL_STOP */
|
/* LCOV_EXCL_END */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1436,7 +1409,7 @@ get_interface_addresses_ifaddrs(int severity, sa_family_t family)
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
#endif /* defined(HAVE_IFADDRS_TO_SMARTLIST) */
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_IP_ADAPTER_TO_SMARTLIST
|
#ifdef HAVE_IP_ADAPTER_TO_SMARTLIST
|
||||||
|
|
||||||
|
@ -1527,7 +1500,7 @@ get_interface_addresses_win32(int severity, sa_family_t family)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* defined(HAVE_IP_ADAPTER_TO_SMARTLIST) */
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_IFCONF_TO_SMARTLIST
|
#ifdef HAVE_IFCONF_TO_SMARTLIST
|
||||||
|
|
||||||
|
@ -1540,18 +1513,6 @@ get_interface_addresses_win32(int severity, sa_family_t family)
|
||||||
#define _SIZEOF_ADDR_IFREQ sizeof
|
#define _SIZEOF_ADDR_IFREQ sizeof
|
||||||
#endif
|
#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>,
|
/** Convert <b>*buf</b>, an ifreq structure array of size <b>buflen</b>,
|
||||||
* into smartlist of <b>tor_addr_t</b> structures.
|
* into smartlist of <b>tor_addr_t</b> structures.
|
||||||
*/
|
*/
|
||||||
|
@ -1638,10 +1599,10 @@ get_interface_addresses_ioctl(int severity, sa_family_t family)
|
||||||
done:
|
done:
|
||||||
if (fd >= 0)
|
if (fd >= 0)
|
||||||
close(fd);
|
close(fd);
|
||||||
ifconf_free_ifc_buf(&ifc);
|
tor_free(ifc.ifc_buf);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
#endif /* defined(HAVE_IFCONF_TO_SMARTLIST) */
|
#endif
|
||||||
|
|
||||||
/** Try to ask our network interfaces what addresses they are bound to.
|
/** 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.
|
* Return a new smartlist of tor_addr_t on success, and NULL on failure.
|
||||||
|
@ -1697,7 +1658,7 @@ get_interface_address6_via_udp_socket_hack,(int severity,
|
||||||
sa_family_t family,
|
sa_family_t family,
|
||||||
tor_addr_t *addr))
|
tor_addr_t *addr))
|
||||||
{
|
{
|
||||||
struct sockaddr_storage target_addr;
|
struct sockaddr_storage my_addr, target_addr;
|
||||||
int sock=-1, r=-1;
|
int sock=-1, r=-1;
|
||||||
socklen_t addr_len;
|
socklen_t addr_len;
|
||||||
|
|
||||||
|
@ -1740,19 +1701,21 @@ get_interface_address6_via_udp_socket_hack,(int severity,
|
||||||
goto err;
|
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);
|
int e = tor_socket_errno(sock);
|
||||||
log_fn(severity, LD_NET, "getsockname() to determine interface failed: %s",
|
log_fn(severity, LD_NET, "getsockname() to determine interface failed: %s",
|
||||||
tor_socket_strerror(e));
|
tor_socket_strerror(e));
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tor_addr_is_loopback(addr) || tor_addr_is_multicast(addr)) {
|
if (tor_addr_from_sockaddr(addr, (struct sockaddr*)&my_addr, NULL) == 0) {
|
||||||
log_fn(severity, LD_NET, "Address that we determined via UDP socket"
|
if (tor_addr_is_loopback(addr) || tor_addr_is_multicast(addr)) {
|
||||||
" magic is unsuitable for public comms.");
|
log_fn(severity, LD_NET, "Address that we determined via UDP socket"
|
||||||
} else {
|
" magic is unsuitable for public comms.");
|
||||||
r=0;
|
} else {
|
||||||
}
|
r=0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
err:
|
err:
|
||||||
if (sock >= 0)
|
if (sock >= 0)
|
||||||
|
@ -1794,14 +1757,14 @@ get_interface_address6,(int severity, sa_family_t family, tor_addr_t *addr))
|
||||||
break;
|
break;
|
||||||
} SMARTLIST_FOREACH_END(a);
|
} SMARTLIST_FOREACH_END(a);
|
||||||
|
|
||||||
interface_address6_list_free(addrs);
|
free_interface_address6_list(addrs);
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Free a smartlist of IP addresses returned by get_interface_address6_list.
|
/** Free a smartlist of IP addresses returned by get_interface_address6_list.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
interface_address6_list_free_(smartlist_t *addrs)
|
free_interface_address6_list(smartlist_t *addrs)
|
||||||
{
|
{
|
||||||
if (addrs != NULL) {
|
if (addrs != NULL) {
|
||||||
SMARTLIST_FOREACH(addrs, tor_addr_t *, a, tor_free(a));
|
SMARTLIST_FOREACH(addrs, tor_addr_t *, a, tor_free(a));
|
||||||
|
@ -1816,12 +1779,11 @@ interface_address6_list_free_(smartlist_t *addrs)
|
||||||
* An empty smartlist means that there are no addresses of the selected type
|
* An empty smartlist means that there are no addresses of the selected type
|
||||||
* matching these criteria.
|
* matching these criteria.
|
||||||
* Returns NULL on failure.
|
* 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 *,
|
MOCK_IMPL(smartlist_t *,get_interface_address6_list,(int severity,
|
||||||
get_interface_address6_list,(int severity,
|
sa_family_t family,
|
||||||
sa_family_t family,
|
int include_internal))
|
||||||
int include_internal))
|
|
||||||
{
|
{
|
||||||
smartlist_t *addrs;
|
smartlist_t *addrs;
|
||||||
tor_addr_t addr;
|
tor_addr_t addr;
|
||||||
|
@ -2089,8 +2051,7 @@ parse_port_range(const char *port, uint16_t *port_min_out,
|
||||||
|
|
||||||
/** Given an IPv4 in_addr struct *<b>in</b> (in network order, as usual),
|
/** Given an IPv4 in_addr struct *<b>in</b> (in network order, as usual),
|
||||||
* write it as a string into the <b>buf_len</b>-byte buffer in
|
* write it as a string into the <b>buf_len</b>-byte buffer in
|
||||||
* <b>buf</b>. Returns a non-negative integer on success.
|
* <b>buf</b>.
|
||||||
* Returns -1 on failure.
|
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
tor_inet_ntoa(const struct in_addr *in, char *buf, size_t buf_len)
|
tor_inet_ntoa(const struct in_addr *in, char *buf, size_t buf_len)
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* Copyright (c) 2003-2004, Roger Dingledine
|
/* Copyright (c) 2003-2004, Roger Dingledine
|
||||||
* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
|
* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
|
||||||
* Copyright (c) 2007-2017, The Tor Project, Inc. */
|
* Copyright (c) 2007-2016, The Tor Project, Inc. */
|
||||||
/* See LICENSE for licensing information */
|
/* See LICENSE for licensing information */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -44,7 +44,7 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// TODO win32 specific includes
|
// TODO win32 specific includes
|
||||||
#endif /* defined(ADDRESS_PRIVATE) */
|
#endif // ADDRESS_PRIVATE
|
||||||
|
|
||||||
/** The number of bits from an address to consider while doing a masked
|
/** The number of bits from an address to consider while doing a masked
|
||||||
* comparison. */
|
* comparison. */
|
||||||
|
@ -206,9 +206,7 @@ const char * fmt_addr32(uint32_t addr);
|
||||||
|
|
||||||
MOCK_DECL(int,get_interface_address6,(int severity, sa_family_t family,
|
MOCK_DECL(int,get_interface_address6,(int severity, sa_family_t family,
|
||||||
tor_addr_t *addr));
|
tor_addr_t *addr));
|
||||||
void interface_address6_list_free_(smartlist_t * addrs);// XXXX
|
void free_interface_address6_list(smartlist_t * addrs);
|
||||||
#define interface_address6_list_free(addrs) \
|
|
||||||
FREE_AND_NULL(smartlist_t, interface_address6_list_free_, (addrs))
|
|
||||||
MOCK_DECL(smartlist_t *,get_interface_address6_list,(int severity,
|
MOCK_DECL(smartlist_t *,get_interface_address6_list,(int severity,
|
||||||
sa_family_t family,
|
sa_family_t family,
|
||||||
int include_internal));
|
int include_internal));
|
||||||
|
@ -231,8 +229,6 @@ int tor_addr_compare_masked(const tor_addr_t *addr1, const tor_addr_t *addr2,
|
||||||
#define tor_addr_eq(a,b) (0==tor_addr_compare((a),(b),CMP_EXACT))
|
#define tor_addr_eq(a,b) (0==tor_addr_compare((a),(b),CMP_EXACT))
|
||||||
|
|
||||||
uint64_t tor_addr_hash(const tor_addr_t *addr);
|
uint64_t tor_addr_hash(const tor_addr_t *addr);
|
||||||
struct sipkey;
|
|
||||||
uint64_t tor_addr_keyed_hash(const struct sipkey *key, const tor_addr_t *addr);
|
|
||||||
int tor_addr_is_v4(const tor_addr_t *addr);
|
int tor_addr_is_v4(const tor_addr_t *addr);
|
||||||
int tor_addr_is_internal_(const tor_addr_t *ip, int for_listening,
|
int tor_addr_is_internal_(const tor_addr_t *ip, int for_listening,
|
||||||
const char *filename, int lineno);
|
const char *filename, int lineno);
|
||||||
|
@ -325,8 +321,13 @@ int addr_mask_get_bits(uint32_t mask);
|
||||||
int tor_inet_ntoa(const struct in_addr *in, char *buf, size_t buf_len);
|
int tor_inet_ntoa(const struct in_addr *in, char *buf, size_t buf_len);
|
||||||
char *tor_dup_ip(uint32_t addr) ATTR_MALLOC;
|
char *tor_dup_ip(uint32_t addr) ATTR_MALLOC;
|
||||||
MOCK_DECL(int,get_interface_address,(int severity, uint32_t *addr));
|
MOCK_DECL(int,get_interface_address,(int severity, uint32_t *addr));
|
||||||
#define interface_address_list_free(lst)\
|
/** Free a smartlist of IP addresses returned by get_interface_address_list.
|
||||||
interface_address6_list_free(lst)
|
*/
|
||||||
|
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.
|
/** Return a smartlist of the IPv4 addresses of all interfaces on the server.
|
||||||
* Excludes loopback and multicast addresses. Only includes internal addresses
|
* Excludes loopback and multicast addresses. Only includes internal addresses
|
||||||
* if include_internal is true. (Note that a relay behind NAT may use an
|
* if include_internal is true. (Note that a relay behind NAT may use an
|
||||||
|
@ -357,23 +358,23 @@ STATIC smartlist_t *ifaddrs_to_smartlist(const struct ifaddrs *ifa,
|
||||||
sa_family_t family);
|
sa_family_t family);
|
||||||
STATIC smartlist_t *get_interface_addresses_ifaddrs(int severity,
|
STATIC smartlist_t *get_interface_addresses_ifaddrs(int severity,
|
||||||
sa_family_t family);
|
sa_family_t family);
|
||||||
#endif /* defined(HAVE_IFADDRS_TO_SMARTLIST) */
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_IP_ADAPTER_TO_SMARTLIST
|
#ifdef HAVE_IP_ADAPTER_TO_SMARTLIST
|
||||||
STATIC smartlist_t *ip_adapter_addresses_to_smartlist(
|
STATIC smartlist_t *ip_adapter_addresses_to_smartlist(
|
||||||
const IP_ADAPTER_ADDRESSES *addresses);
|
const IP_ADAPTER_ADDRESSES *addresses);
|
||||||
STATIC smartlist_t *get_interface_addresses_win32(int severity,
|
STATIC smartlist_t *get_interface_addresses_win32(int severity,
|
||||||
sa_family_t family);
|
sa_family_t family);
|
||||||
#endif /* defined(HAVE_IP_ADAPTER_TO_SMARTLIST) */
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_IFCONF_TO_SMARTLIST
|
#ifdef HAVE_IFCONF_TO_SMARTLIST
|
||||||
STATIC smartlist_t *ifreq_to_smartlist(char *ifr,
|
STATIC smartlist_t *ifreq_to_smartlist(char *ifr,
|
||||||
size_t buflen);
|
size_t buflen);
|
||||||
STATIC smartlist_t *get_interface_addresses_ioctl(int severity,
|
STATIC smartlist_t *get_interface_addresses_ioctl(int severity,
|
||||||
sa_family_t family);
|
sa_family_t family);
|
||||||
#endif /* defined(HAVE_IFCONF_TO_SMARTLIST) */
|
#endif
|
||||||
|
|
||||||
#endif /* defined(ADDRESS_PRIVATE) */
|
#endif // ADDRESS_PRIVATE
|
||||||
|
|
||||||
#endif /* !defined(TOR_ADDRESS_H) */
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -1,129 +0,0 @@
|
||||||
/* Copyright (c) 2018, The Tor Project, Inc. */
|
|
||||||
/* See LICENSE for licensing information */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \file address_set.c
|
|
||||||
* \brief Implementation for a set of addresses.
|
|
||||||
*
|
|
||||||
* This module was first written on a semi-emergency basis to improve the
|
|
||||||
* robustness of the anti-DoS module. As such, it's written in a pretty
|
|
||||||
* conservative way, and should be susceptible to improvement later on.
|
|
||||||
**/
|
|
||||||
|
|
||||||
#include "orconfig.h"
|
|
||||||
#include "address_set.h"
|
|
||||||
#include "address.h"
|
|
||||||
#include "compat.h"
|
|
||||||
#include "container.h"
|
|
||||||
#include "crypto_rand.h"
|
|
||||||
#include "util.h"
|
|
||||||
#include "siphash.h"
|
|
||||||
|
|
||||||
/** How many 64-bit siphash values to extract per address */
|
|
||||||
#define N_HASHES 2
|
|
||||||
/** How many bloom-filter bits we set per address. This is twice the N_HASHES
|
|
||||||
* value, since we split the siphash output into two 32-bit values. */
|
|
||||||
#define N_BITS_PER_ITEM (N_HASHES * 2)
|
|
||||||
|
|
||||||
/* XXXX This code is largely duplicated with digestset_t. We should merge
|
|
||||||
* them together into a common bloom-filter implementation. I'm keeping
|
|
||||||
* them separate for now, though, since this module needs to be backported
|
|
||||||
* all the way to 0.2.9.
|
|
||||||
*
|
|
||||||
* The main difference between digestset_t and this code is that we use
|
|
||||||
* 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. */
|
|
||||||
struct sipkey key[N_HASHES];
|
|
||||||
int mask; /**< One less than the number of bits in <b>ba</b>; always one less
|
|
||||||
* than a power of two. */
|
|
||||||
bitarray_t *ba; /**< A bit array to implement the Bloom filter. */
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Allocate and return an address_set, suitable for holding up to
|
|
||||||
* <b>max_address_guess</b> distinct values.
|
|
||||||
*/
|
|
||||||
address_set_t *
|
|
||||||
address_set_new(int max_addresses_guess)
|
|
||||||
{
|
|
||||||
/* See digestset_new() for rationale on this equation. */
|
|
||||||
int n_bits = 1u << (tor_log2(max_addresses_guess)+5);
|
|
||||||
|
|
||||||
address_set_t *set = tor_malloc_zero(sizeof(address_set_t));
|
|
||||||
set->mask = n_bits - 1;
|
|
||||||
set->ba = bitarray_init_zero(n_bits);
|
|
||||||
crypto_rand((char*) set->key, sizeof(set->key));
|
|
||||||
|
|
||||||
return set;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Release all storage associated with <b>set</b>.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
address_set_free(address_set_t *set)
|
|
||||||
{
|
|
||||||
if (! set)
|
|
||||||
return;
|
|
||||||
|
|
||||||
bitarray_free(set->ba);
|
|
||||||
tor_free(set);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Yield the bit index corresponding to 'val' for set. */
|
|
||||||
#define BIT(set, val) ((val) & (set)->mask)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add <b>addr</b> to <b>set</b>.
|
|
||||||
*
|
|
||||||
* All future queries for <b>addr</b> in set will return true. Removing
|
|
||||||
* items is not possible.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
address_set_add(address_set_t *set, const struct tor_addr_t *addr)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
for (i = 0; i < N_HASHES; ++i) {
|
|
||||||
uint64_t h = tor_addr_keyed_hash(&set->key[i], addr);
|
|
||||||
uint32_t high_bits = (uint32_t)(h >> 32);
|
|
||||||
uint32_t low_bits = (uint32_t)(h);
|
|
||||||
bitarray_set(set->ba, BIT(set, high_bits));
|
|
||||||
bitarray_set(set->ba, BIT(set, low_bits));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** As address_set_add(), but take an ipv4 address in host order. */
|
|
||||||
void
|
|
||||||
address_set_add_ipv4h(address_set_t *set, uint32_t addr)
|
|
||||||
{
|
|
||||||
tor_addr_t a;
|
|
||||||
tor_addr_from_ipv4h(&a, addr);
|
|
||||||
address_set_add(set, &a);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return true if <b>addr</b> is a member of <b>set</b>. (And probably,
|
|
||||||
* return false if <b>addr</b> is not a member of set.)
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
address_set_probably_contains(address_set_t *set,
|
|
||||||
const struct tor_addr_t *addr)
|
|
||||||
{
|
|
||||||
int i, matches = 0;
|
|
||||||
for (i = 0; i < N_HASHES; ++i) {
|
|
||||||
uint64_t h = tor_addr_keyed_hash(&set->key[i], addr);
|
|
||||||
uint32_t high_bits = (uint32_t)(h >> 32);
|
|
||||||
uint32_t low_bits = (uint32_t)(h);
|
|
||||||
// Note that !! is necessary here, since bitarray_is_set does not
|
|
||||||
// necessarily return 1 on true.
|
|
||||||
matches += !! bitarray_is_set(set->ba, BIT(set, high_bits));
|
|
||||||
matches += !! bitarray_is_set(set->ba, BIT(set, low_bits));
|
|
||||||
}
|
|
||||||
return matches == N_BITS_PER_ITEM;
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,35 +0,0 @@
|
||||||
/* Copyright (c) 2018, The Tor Project, Inc. */
|
|
||||||
/* See LICENSE for licensing information */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \file address_set.h
|
|
||||||
* \brief Types to handle sets of addresses.
|
|
||||||
*
|
|
||||||
* This module was first written on a semi-emergency basis to improve the
|
|
||||||
* robustness of the anti-DoS module. As such, it's written in a pretty
|
|
||||||
* conservative way, and should be susceptible to improvement later on.
|
|
||||||
**/
|
|
||||||
|
|
||||||
#ifndef TOR_ADDRESS_SET_H
|
|
||||||
#define TOR_ADDRESS_SET_H
|
|
||||||
|
|
||||||
#include "orconfig.h"
|
|
||||||
#include "torint.h"
|
|
||||||
|
|
||||||
/**
|
|
||||||
* An address_set_t represents a set of tor_addr_t values. The implementation
|
|
||||||
* is probabilistic: false negatives cannot occur but false positives are
|
|
||||||
* possible.
|
|
||||||
*/
|
|
||||||
typedef struct address_set_t address_set_t;
|
|
||||||
struct tor_addr_t;
|
|
||||||
|
|
||||||
address_set_t *address_set_new(int max_addresses_guess);
|
|
||||||
void address_set_free(address_set_t *set);
|
|
||||||
void address_set_add(address_set_t *set, const struct tor_addr_t *addr);
|
|
||||||
void address_set_add_ipv4h(address_set_t *set, uint32_t addr);
|
|
||||||
int address_set_probably_contains(address_set_t *set,
|
|
||||||
const struct tor_addr_t *addr);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/* Copyright (c) 2001, Matej Pfajfar.
|
/* Copyright (c) 2001, Matej Pfajfar.
|
||||||
* Copyright (c) 2001-2004, Roger Dingledine.
|
* Copyright (c) 2001-2004, Roger Dingledine.
|
||||||
* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
|
* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
|
||||||
* Copyright (c) 2007-2017, The Tor Project, Inc. */
|
* Copyright (c) 2007-2016, The Tor Project, Inc. */
|
||||||
/* See LICENSE for licensing information */
|
/* See LICENSE for licensing information */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -16,9 +16,8 @@
|
||||||
#include <ws2tcpip.h>
|
#include <ws2tcpip.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "compat_openssl.h"
|
|
||||||
#include <openssl/opensslv.h>
|
#include <openssl/opensslv.h>
|
||||||
#include "crypto_openssl_mgt.h"
|
#include "crypto.h"
|
||||||
|
|
||||||
#if OPENSSL_VERSION_NUMBER < OPENSSL_V_SERIES(1,0,0)
|
#if OPENSSL_VERSION_NUMBER < OPENSSL_V_SERIES(1,0,0)
|
||||||
#error "We require OpenSSL >= 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) && \
|
#elif OPENSSL_VERSION_NUMBER >= OPENSSL_V_NOPATCH(1,0,1) && \
|
||||||
(defined(__i386) || defined(__i386__) || defined(_M_IX86) || \
|
(defined(__i386) || defined(__i386__) || defined(_M_IX86) || \
|
||||||
defined(__x86_64) || defined(__x86_64__) || \
|
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
|
#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
|
/* We have 2 strategies for getting the AES block cipher: Via OpenSSL's
|
||||||
* AES_encrypt function, or via OpenSSL's EVP_EncryptUpdate function.
|
* 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;
|
return (aes_cnt_cipher_t *) cipher;
|
||||||
}
|
}
|
||||||
void
|
void
|
||||||
aes_cipher_free_(aes_cnt_cipher_t *cipher_)
|
aes_cipher_free(aes_cnt_cipher_t *cipher_)
|
||||||
{
|
{
|
||||||
if (!cipher_)
|
if (!cipher_)
|
||||||
return;
|
return;
|
||||||
EVP_CIPHER_CTX *cipher = (EVP_CIPHER_CTX *) cipher_;
|
EVP_CIPHER_CTX *cipher = (EVP_CIPHER_CTX *) cipher_;
|
||||||
#ifdef OPENSSL_1_1_API
|
|
||||||
EVP_CIPHER_CTX_reset(cipher);
|
|
||||||
#else
|
|
||||||
EVP_CIPHER_CTX_cleanup(cipher);
|
EVP_CIPHER_CTX_cleanup(cipher);
|
||||||
#endif
|
|
||||||
EVP_CIPHER_CTX_free(cipher);
|
EVP_CIPHER_CTX_free(cipher);
|
||||||
}
|
}
|
||||||
void
|
void
|
||||||
|
@ -147,7 +142,7 @@ evaluate_ctr_for_aes(void)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#else /* !(defined(USE_EVP_AES_CTR)) */
|
#else
|
||||||
|
|
||||||
/*======================================================================*/
|
/*======================================================================*/
|
||||||
/* Interface to AES code, and counter implementation */
|
/* Interface to AES code, and counter implementation */
|
||||||
|
@ -168,7 +163,7 @@ struct aes_cnt_cipher {
|
||||||
uint32_t counter2;
|
uint32_t counter2;
|
||||||
uint32_t counter1;
|
uint32_t counter1;
|
||||||
uint32_t counter0;
|
uint32_t counter0;
|
||||||
#endif /* !defined(WORDS_BIGENDIAN) */
|
#endif
|
||||||
|
|
||||||
union {
|
union {
|
||||||
/** The counter, in big-endian order, as bytes. */
|
/** 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.");
|
log_info(LD_CRYPTO, "No AES engine found; using AES_* functions.");
|
||||||
should_use_EVP = 0;
|
should_use_EVP = 0;
|
||||||
}
|
}
|
||||||
#endif /* defined(DISABLE_ENGINES) */
|
#endif
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -259,7 +254,7 @@ evaluate_ctr_for_aes(void)
|
||||||
/* LCOV_EXCL_START */
|
/* LCOV_EXCL_START */
|
||||||
log_err(LD_CRYPTO, "This OpenSSL has a buggy version of counter mode; "
|
log_err(LD_CRYPTO, "This OpenSSL has a buggy version of counter mode; "
|
||||||
"quitting tor.");
|
"quitting tor.");
|
||||||
exit(1); // exit ok: openssl is broken.
|
exit(1);
|
||||||
/* LCOV_EXCL_STOP */
|
/* LCOV_EXCL_STOP */
|
||||||
}
|
}
|
||||||
return 0;
|
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->counter1 = 0;
|
||||||
cipher->counter2 = 0;
|
cipher->counter2 = 0;
|
||||||
cipher->counter3 = 0;
|
cipher->counter3 = 0;
|
||||||
#endif /* defined(USING_COUNTER_VARS) */
|
#endif
|
||||||
|
|
||||||
memset(cipher->ctr_buf.buf, 0, sizeof(cipher->ctr_buf.buf));
|
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>
|
/** Release storage held by <b>cipher</b>
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
aes_cipher_free_(aes_cnt_cipher_t *cipher)
|
aes_cipher_free(aes_cnt_cipher_t *cipher)
|
||||||
{
|
{
|
||||||
if (!cipher)
|
if (!cipher)
|
||||||
return;
|
return;
|
||||||
|
@ -346,7 +341,7 @@ aes_cipher_free_(aes_cnt_cipher_t *cipher)
|
||||||
STMT_END
|
STMT_END
|
||||||
#else
|
#else
|
||||||
#define UPDATE_CTR_BUF(c, n)
|
#define UPDATE_CTR_BUF(c, n)
|
||||||
#endif /* defined(USING_COUNTER_VARS) */
|
#endif
|
||||||
|
|
||||||
/* Helper function to use EVP with openssl's counter-mode wrapper. */
|
/* Helper function to use EVP with openssl's counter-mode wrapper. */
|
||||||
static void
|
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->counter2 = ntohl(get_uint32(iv+4));
|
||||||
cipher->counter1 = ntohl(get_uint32(iv+8));
|
cipher->counter1 = ntohl(get_uint32(iv+8));
|
||||||
cipher->counter0 = ntohl(get_uint32(iv+12));
|
cipher->counter0 = ntohl(get_uint32(iv+12));
|
||||||
#endif /* defined(USING_COUNTER_VARS) */
|
#endif
|
||||||
cipher->pos = 0;
|
cipher->pos = 0;
|
||||||
memcpy(cipher->ctr_buf.buf, iv, 16);
|
memcpy(cipher->ctr_buf.buf, iv, 16);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* defined(USE_EVP_AES_CTR) */
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* Copyright (c) 2003, Roger Dingledine
|
/* Copyright (c) 2003, Roger Dingledine
|
||||||
* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
|
* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
|
||||||
* Copyright (c) 2007-2017, The Tor Project, Inc. */
|
* Copyright (c) 2007-2016, The Tor Project, Inc. */
|
||||||
/* See LICENSE for licensing information */
|
/* See LICENSE for licensing information */
|
||||||
|
|
||||||
/* Implements a minimal interface to counter-mode AES. */
|
/* Implements a minimal interface to counter-mode AES. */
|
||||||
|
@ -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,
|
aes_cnt_cipher_t* aes_new_cipher(const uint8_t *key, const uint8_t *iv,
|
||||||
int key_bits);
|
int key_bits);
|
||||||
void aes_cipher_free_(aes_cnt_cipher_t *cipher);
|
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_crypt_inplace(aes_cnt_cipher_t *cipher, char *data, size_t len);
|
void aes_crypt_inplace(aes_cnt_cipher_t *cipher, char *data, size_t len);
|
||||||
|
|
||||||
int evaluate_evp_for_aes(int force_value);
|
int evaluate_evp_for_aes(int force_value);
|
||||||
int evaluate_ctr_for_aes(void);
|
int evaluate_ctr_for_aes(void);
|
||||||
|
|
||||||
#endif /* !defined(TOR_AES_H) */
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* Copyright (c) 2013-2017, The Tor Project, Inc. */
|
/* Copyright (c) 2013-2016, The Tor Project, Inc. */
|
||||||
/* See LICENSE for licensing information */
|
/* See LICENSE for licensing information */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -37,7 +37,7 @@
|
||||||
#include <sys/ucontext.h>
|
#include <sys/ucontext.h>
|
||||||
#elif defined(HAVE_UCONTEXT_H)
|
#elif defined(HAVE_UCONTEXT_H)
|
||||||
#include <ucontext.h>
|
#include <ucontext.h>
|
||||||
#endif /* defined(HAVE_CYGWIN_SIGNAL_H) || ... */
|
#endif
|
||||||
|
|
||||||
#define EXPOSE_CLEAN_BACKTRACE
|
#define EXPOSE_CLEAN_BACKTRACE
|
||||||
#include "backtrace.h"
|
#include "backtrace.h"
|
||||||
|
@ -81,16 +81,16 @@ clean_backtrace(void **stack, size_t depth, const ucontext_t *ctx)
|
||||||
const size_t n = 2;
|
const size_t n = 2;
|
||||||
#else
|
#else
|
||||||
const size_t n = 1;
|
const size_t n = 1;
|
||||||
#endif /* defined(__linux__) || ... */
|
#endif
|
||||||
if (depth <= n)
|
if (depth <= n)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
stack[n] = (void*) ctx->PC_FROM_UCONTEXT;
|
stack[n] = (void*) ctx->PC_FROM_UCONTEXT;
|
||||||
#else /* !(defined(PC_FROM_UCONTEXT)) */
|
#else
|
||||||
(void) depth;
|
(void) depth;
|
||||||
(void) ctx;
|
(void) ctx;
|
||||||
(void) stack;
|
(void) stack;
|
||||||
#endif /* defined(PC_FROM_UCONTEXT) */
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Log a message <b>msg</b> at <b>severity</b> in <b>domain</b>, and follow
|
/** 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);
|
tor_mutex_uninit(&cb_buf_mutex);
|
||||||
}
|
}
|
||||||
#endif /* defined(USE_BACKTRACE) */
|
#endif
|
||||||
|
|
||||||
#ifdef NO_BACKTRACE_IMPL
|
#ifdef NO_BACKTRACE_IMPL
|
||||||
void
|
void
|
||||||
|
@ -221,7 +221,7 @@ static void
|
||||||
remove_bt_handler(void)
|
remove_bt_handler(void)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
#endif /* defined(NO_BACKTRACE_IMPL) */
|
#endif
|
||||||
|
|
||||||
/** Set up code to handle generating error messages on crashes. */
|
/** Set up code to handle generating error messages on crashes. */
|
||||||
int
|
int
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* Copyright (c) 2013-2017, The Tor Project, Inc. */
|
/* Copyright (c) 2013-2016, The Tor Project, Inc. */
|
||||||
/* See LICENSE for licensing information */
|
/* See LICENSE for licensing information */
|
||||||
|
|
||||||
#ifndef TOR_BACKTRACE_H
|
#ifndef TOR_BACKTRACE_H
|
||||||
|
@ -15,7 +15,7 @@ void clean_up_backtrace_handler(void);
|
||||||
defined(HAVE_BACKTRACE_SYMBOLS_FD) && defined(HAVE_SIGACTION)
|
defined(HAVE_BACKTRACE_SYMBOLS_FD) && defined(HAVE_SIGACTION)
|
||||||
void clean_backtrace(void **stack, size_t depth, const ucontext_t *ctx);
|
void clean_backtrace(void **stack, size_t depth, const ucontext_t *ctx);
|
||||||
#endif
|
#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) */
|
|
||||||
|
|
|
@ -2,27 +2,8 @@
|
||||||
* advertise. Before including it, you should define the CIPHER and XCIPHER
|
* advertise. Before including it, you should define the CIPHER and XCIPHER
|
||||||
* macros.
|
* macros.
|
||||||
*
|
*
|
||||||
* This file was automatically generated by get_mozilla_ciphers.py;
|
* This file was automatically generated by get_mozilla_ciphers.py.
|
||||||
* TLSv1.3 ciphers were added manually.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Here are the TLS1.3 ciphers. Note that we don't have XCIPHER instances
|
|
||||||
* here, since we don't want to ever fake them.
|
|
||||||
*/
|
|
||||||
#ifdef TLS1_3_TXT_AES_128_GCM_SHA256
|
|
||||||
CIPHER(0x1301, TLS1_3_TXT_AES_128_GCM_SHA256)
|
|
||||||
#endif
|
|
||||||
#ifdef TLS1_3_TXT_AES_256_GCM_SHA384
|
|
||||||
CIPHER(0x1302, TLS1_3_TXT_AES_256_GCM_SHA384)
|
|
||||||
#endif
|
|
||||||
#ifdef TLS1_3_TXT_CHACHA20_POLY1305_SHA256
|
|
||||||
CIPHER(0x1303, TLS1_3_TXT_CHACHA20_POLY1305_SHA256)
|
|
||||||
#endif
|
|
||||||
#ifdef TLS1_3_TXT_AES_128_CCM_SHA256
|
|
||||||
CIPHER(0x1304, TLS1_3_TXT_AES_128_CCM_SHA256)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Here's the machine-generated list. */
|
|
||||||
#ifdef TLS1_TXT_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
|
#ifdef TLS1_TXT_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
|
||||||
CIPHER(0xc02b, TLS1_TXT_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256)
|
CIPHER(0xc02b, TLS1_TXT_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256)
|
||||||
#else
|
#else
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* Copyright (c) 2003-2004, Roger Dingledine
|
/* Copyright (c) 2003-2004, Roger Dingledine
|
||||||
* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
|
* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
|
||||||
* Copyright (c) 2007-2017, The Tor Project, Inc. */
|
* Copyright (c) 2007-2016, The Tor Project, Inc. */
|
||||||
/* See LICENSE for licensing information */
|
/* See LICENSE for licensing information */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -88,20 +88,21 @@ SecureZeroMemory(PVOID ptr, SIZE_T cnt)
|
||||||
while (cnt--)
|
while (cnt--)
|
||||||
*vcptr++ = 0;
|
*vcptr++ = 0;
|
||||||
}
|
}
|
||||||
#endif /* defined(HAVE_DECL_SECUREZEROMEMORY) && !HAVE_DECL_SECUREZEROMEMORY */
|
#endif
|
||||||
#elif defined(HAVE_READPASSPHRASE_H)
|
#elif defined(HAVE_READPASSPHRASE_H)
|
||||||
#include <readpassphrase.h>
|
#include <readpassphrase.h>
|
||||||
#else
|
#else
|
||||||
#include "tor_readpassphrase.h"
|
#include "tor_readpassphrase.h"
|
||||||
#endif /* defined(_WIN32) || ... */
|
#endif
|
||||||
|
|
||||||
/* Includes for the process attaching prevention */
|
/* Includes for the process attaching prevention */
|
||||||
#if defined(HAVE_SYS_PRCTL_H) && defined(__linux__)
|
#if defined(HAVE_SYS_PRCTL_H) && defined(__linux__)
|
||||||
/* Only use the linux prctl; the IRIX prctl is totally different */
|
/* Only use the linux prctl; the IRIX prctl is totally different */
|
||||||
#include <sys/prctl.h>
|
#include <sys/prctl.h>
|
||||||
#elif defined(__APPLE__)
|
#elif defined(__APPLE__)
|
||||||
|
#include <sys/types.h>
|
||||||
#include <sys/ptrace.h>
|
#include <sys/ptrace.h>
|
||||||
#endif /* defined(HAVE_SYS_PRCTL_H) && defined(__linux__) || ... */
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_NETDB_H
|
#ifdef HAVE_NETDB_H
|
||||||
#include <netdb.h>
|
#include <netdb.h>
|
||||||
|
@ -115,7 +116,7 @@ SecureZeroMemory(PVOID ptr, SIZE_T cnt)
|
||||||
#ifdef HAVE_SIGNAL_H
|
#ifdef HAVE_SIGNAL_H
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAVE_MMAP
|
#ifdef HAVE_SYS_MMAN_H
|
||||||
#include <sys/mman.h>
|
#include <sys/mman.h>
|
||||||
#endif
|
#endif
|
||||||
#ifdef HAVE_SYS_SYSLIMITS_H
|
#ifdef HAVE_SYS_SYSLIMITS_H
|
||||||
|
@ -160,7 +161,7 @@ tor_open_cloexec(const char *path, int flags, unsigned mode)
|
||||||
* are running on one without. */
|
* are running on one without. */
|
||||||
if (errno != EINVAL)
|
if (errno != EINVAL)
|
||||||
return -1;
|
return -1;
|
||||||
#endif /* defined(O_CLOEXEC) */
|
#endif
|
||||||
|
|
||||||
log_debug(LD_FS, "Opening %s with flags %x", p, flags);
|
log_debug(LD_FS, "Opening %s with flags %x", p, flags);
|
||||||
fd = open(p, flags, mode);
|
fd = open(p, flags, mode);
|
||||||
|
@ -172,7 +173,7 @@ tor_open_cloexec(const char *path, int flags, unsigned mode)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif /* defined(FD_CLOEXEC) */
|
#endif
|
||||||
return fd;
|
return fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -190,7 +191,7 @@ tor_fopen_cloexec(const char *path, const char *mode)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif /* defined(FD_CLOEXEC) */
|
#endif
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -203,17 +204,24 @@ tor_rename(const char *path_old, const char *path_new)
|
||||||
sandbox_intern_string(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
|
/** Try to create a memory mapping for <b>filename</b> and return it. On
|
||||||
* failure, return NULL. Sets errno properly, using ERANGE to mean
|
* failure, return NULL. Sets errno properly, using ERANGE to mean
|
||||||
* "empty file". Must only be called on trusted Tor-owned files, as changing
|
* "empty file". */
|
||||||
* the underlying file's size causes unspecified behavior. */
|
|
||||||
tor_mmap_t *
|
tor_mmap_t *
|
||||||
tor_mmap_file(const char *filename)
|
tor_mmap_file(const char *filename)
|
||||||
{
|
{
|
||||||
int fd; /* router file */
|
int fd; /* router file */
|
||||||
char *string;
|
char *string;
|
||||||
int result;
|
int page_size, result;
|
||||||
tor_mmap_t *res;
|
tor_mmap_t *res;
|
||||||
size_t size, filesize;
|
size_t size, filesize;
|
||||||
struct stat st;
|
struct stat st;
|
||||||
|
@ -242,6 +250,13 @@ tor_mmap_file(const char *filename)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
size = filesize = (size_t)(st.st_size);
|
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) {
|
if (st.st_size > SSIZE_T_CEILING || (off_t)size < st.st_size) {
|
||||||
log_warn(LD_FS, "File \"%s\" is too large. Ignoring.",filename);
|
log_warn(LD_FS, "File \"%s\" is too large. Ignoring.",filename);
|
||||||
|
@ -402,8 +417,40 @@ tor_munmap_file(tor_mmap_t *handle)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
#error "cannot implement tor_mmap_file"
|
tor_mmap_t *
|
||||||
#endif /* defined(HAVE_MMAP) || ... || ... */
|
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
|
/** Replacement for snprintf. Differs from platform snprintf in two
|
||||||
* ways: First, always NUL-terminates its output. Second, always
|
* 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;
|
*strp = strp_tmp;
|
||||||
return len;
|
return len;
|
||||||
#endif /* defined(HAVE_VASPRINTF) || ... */
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Given <b>hlen</b> bytes at <b>haystack</b> and <b>nlen</b> bytes at
|
/** 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;
|
return NULL;
|
||||||
#endif /* defined(HAVE_MEMMEM) && (!defined(__GNUC__) || __GNUC__ >= 2) */
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -727,7 +774,7 @@ tor_fix_source_file(const char *fname)
|
||||||
}
|
}
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
#endif /* defined(_WIN32) */
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Read a 16-bit value beginning at <b>cp</b>. Equivalent to
|
* 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 -1;
|
||||||
}
|
}
|
||||||
return tor_rename(from,to);
|
return tor_rename(from,to);
|
||||||
#endif /* !defined(_WIN32) */
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Change <b>fname</b>'s modification time to now. */
|
/** 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;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif /* defined(_WIN32) || ... */
|
#endif
|
||||||
|
|
||||||
result = tor_malloc(sizeof(tor_lockfile_t));
|
result = tor_malloc(sizeof(tor_lockfile_t));
|
||||||
result->filename = tor_strdup(filename);
|
result->filename = tor_strdup(filename);
|
||||||
|
@ -935,7 +982,7 @@ tor_lockfile_unlock(tor_lockfile_t *lockfile)
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
/* Closing the lockfile is sufficient. */
|
/* Closing the lockfile is sufficient. */
|
||||||
#endif /* defined(_WIN32) || ... */
|
#endif
|
||||||
|
|
||||||
close(lockfile->fd);
|
close(lockfile->fd);
|
||||||
lockfile->fd = -1;
|
lockfile->fd = -1;
|
||||||
|
@ -983,9 +1030,9 @@ tor_fd_seekend(int fd)
|
||||||
* no need to worry. */
|
* no need to worry. */
|
||||||
if (rc < 0 && errno == ESPIPE)
|
if (rc < 0 && errno == ESPIPE)
|
||||||
rc = 0;
|
rc = 0;
|
||||||
#endif /* defined(ESPIPE) */
|
#endif
|
||||||
return (rc < 0) ? -1 : 0;
|
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
|
/** 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;
|
static bitarray_t *open_sockets = NULL;
|
||||||
/** The size of <b>open_sockets</b>, in bits. */
|
/** The size of <b>open_sockets</b>, in bits. */
|
||||||
static int max_socket = -1;
|
static int max_socket = -1;
|
||||||
#endif /* defined(DEBUG_SOCKET_COUNTING) */
|
#endif
|
||||||
|
|
||||||
/** Count of number of sockets currently open. (Undercounts sockets opened by
|
/** Count of number of sockets currently open. (Undercounts sockets opened by
|
||||||
* eventdns and libevent.) */
|
* eventdns and libevent.) */
|
||||||
|
@ -1094,7 +1141,7 @@ tor_close_socket,(tor_socket_t s))
|
||||||
tor_assert(open_sockets && s <= max_socket);
|
tor_assert(open_sockets && s <= max_socket);
|
||||||
bitarray_clear(open_sockets, s);
|
bitarray_clear(open_sockets, s);
|
||||||
}
|
}
|
||||||
#endif /* defined(DEBUG_SOCKET_COUNTING) */
|
#endif
|
||||||
if (r == 0) {
|
if (r == 0) {
|
||||||
--n_sockets_open;
|
--n_sockets_open;
|
||||||
} else {
|
} else {
|
||||||
|
@ -1104,7 +1151,7 @@ tor_close_socket,(tor_socket_t s))
|
||||||
#else
|
#else
|
||||||
if (r != EBADF)
|
if (r != EBADF)
|
||||||
--n_sockets_open; // LCOV_EXCL_LINE -- EIO and EINTR too hard to force.
|
--n_sockets_open; // LCOV_EXCL_LINE -- EIO and EINTR too hard to force.
|
||||||
#endif /* defined(_WIN32) */
|
#endif
|
||||||
r = -1;
|
r = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1137,9 +1184,9 @@ mark_socket_open(tor_socket_t s)
|
||||||
}
|
}
|
||||||
bitarray_set(open_sockets, s);
|
bitarray_set(open_sockets, s);
|
||||||
}
|
}
|
||||||
#else /* !(defined(DEBUG_SOCKET_COUNTING)) */
|
#else
|
||||||
#define mark_socket_open(s) ((void) (s))
|
#define mark_socket_open(s) STMT_NIL
|
||||||
#endif /* defined(DEBUG_SOCKET_COUNTING) */
|
#endif
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
||||||
/** As socket(), but counts the number of open sockets. */
|
/** 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. */
|
* support, we are running on one without. */
|
||||||
if (errno != EINVAL)
|
if (errno != EINVAL)
|
||||||
return s;
|
return s;
|
||||||
#endif /* defined(SOCK_CLOEXEC) && defined(SOCK_NONBLOCK) */
|
#endif /* SOCK_CLOEXEC && SOCK_NONBLOCK */
|
||||||
|
|
||||||
s = socket(domain, type, protocol);
|
s = socket(domain, type, protocol);
|
||||||
if (! SOCKET_OK(s))
|
if (! SOCKET_OK(s))
|
||||||
|
@ -1211,9 +1258,9 @@ tor_open_socket_with_extensions(int domain, int type, int protocol,
|
||||||
return TOR_INVALID_SOCKET;
|
return TOR_INVALID_SOCKET;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#else /* !(defined(FD_CLOEXEC)) */
|
#else
|
||||||
(void)cloexec;
|
(void)cloexec;
|
||||||
#endif /* defined(FD_CLOEXEC) */
|
#endif
|
||||||
|
|
||||||
if (nonblock) {
|
if (nonblock) {
|
||||||
if (set_socket_nonblocking(s) == -1) {
|
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. */
|
goto socket_ok; /* So that socket_ok will not be unused. */
|
||||||
|
|
||||||
socket_ok:
|
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();
|
socket_accounting_lock();
|
||||||
++n_sockets_open;
|
++n_sockets_open;
|
||||||
mark_socket_open(s);
|
mark_socket_open(s);
|
||||||
socket_accounting_unlock();
|
socket_accounting_unlock();
|
||||||
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** As accept(), but counts the number of open sockets. */
|
/** 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;
|
return TOR_INVALID_SOCKET;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(HAVE_ACCEPT4) && defined(SOCK_CLOEXEC) \
|
#if defined(HAVE_ACCEPT4) && defined(SOCK_CLOEXEC) && defined(SOCK_NONBLOCK)
|
||||||
&& defined(SOCK_NONBLOCK)
|
|
||||||
int ext_flags = (cloexec ? SOCK_CLOEXEC : 0) |
|
int ext_flags = (cloexec ? SOCK_CLOEXEC : 0) |
|
||||||
(nonblock ? SOCK_NONBLOCK : 0);
|
(nonblock ? SOCK_NONBLOCK : 0);
|
||||||
s = accept4(sockfd, addr, len, ext_flags);
|
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. */
|
* we are missing SOCK_CLOEXEC/SOCK_NONBLOCK support. */
|
||||||
if (errno != EINVAL && errno != ENOSYS)
|
if (errno != EINVAL && errno != ENOSYS)
|
||||||
return s;
|
return s;
|
||||||
#endif /* defined(HAVE_ACCEPT4) && defined(SOCK_CLOEXEC) ... */
|
#endif
|
||||||
|
|
||||||
s = accept(sockfd, addr, len);
|
s = accept(sockfd, addr, len);
|
||||||
if (!SOCKET_OK(s))
|
if (!SOCKET_OK(s))
|
||||||
|
@ -1307,9 +1342,9 @@ tor_accept_socket_with_extensions(tor_socket_t sockfd, struct sockaddr *addr,
|
||||||
return TOR_INVALID_SOCKET;
|
return TOR_INVALID_SOCKET;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#else /* !(defined(FD_CLOEXEC)) */
|
#else
|
||||||
(void)cloexec;
|
(void)cloexec;
|
||||||
#endif /* defined(FD_CLOEXEC) */
|
#endif
|
||||||
|
|
||||||
if (nonblock) {
|
if (nonblock) {
|
||||||
if (set_socket_nonblocking(s) == -1) {
|
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. */
|
goto socket_ok; /* So that socket_ok will not be unused. */
|
||||||
|
|
||||||
socket_ok:
|
socket_ok:
|
||||||
tor_take_socket_ownership(s);
|
socket_accounting_lock();
|
||||||
|
++n_sockets_open;
|
||||||
|
mark_socket_open(s);
|
||||||
|
socket_accounting_unlock();
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1344,24 +1382,6 @@ tor_getsockname,(tor_socket_t sock, struct sockaddr *address,
|
||||||
return getsockname(sock, address, address_len);
|
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
|
/** Turn <b>socket</b> into a nonblocking socket. Return 0 on success, -1
|
||||||
* on failure.
|
* 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));
|
log_warn(LD_NET, "Couldn't set file status flags: %s", strerror(errno));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
#endif /* defined(_WIN32) */
|
#endif
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1422,7 +1442,7 @@ tor_socketpair(int family, int type, int protocol, tor_socket_t fd[2])
|
||||||
* are running on one without. */
|
* are running on one without. */
|
||||||
if (errno != EINVAL)
|
if (errno != EINVAL)
|
||||||
return -errno;
|
return -errno;
|
||||||
#endif /* defined(SOCK_CLOEXEC) */
|
#endif
|
||||||
|
|
||||||
r = socketpair(family, type, protocol, fd);
|
r = socketpair(family, type, protocol, fd);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
|
@ -1445,7 +1465,7 @@ tor_socketpair(int family, int type, int protocol, tor_socket_t fd[2])
|
||||||
return -errno;
|
return -errno;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif /* defined(FD_CLOEXEC) */
|
#endif
|
||||||
goto sockets_ok; /* So that sockets_ok will not be unused. */
|
goto sockets_ok; /* So that sockets_ok will not be unused. */
|
||||||
|
|
||||||
sockets_ok:
|
sockets_ok:
|
||||||
|
@ -1461,9 +1481,9 @@ tor_socketpair(int family, int type, int protocol, tor_socket_t fd[2])
|
||||||
socket_accounting_unlock();
|
socket_accounting_unlock();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
#else /* !(defined(HAVE_SOCKETPAIR) && !defined(_WIN32)) */
|
#else
|
||||||
return tor_ersatz_socketpair(family, type, protocol, fd);
|
return tor_ersatz_socketpair(family, type, protocol, fd);
|
||||||
#endif /* defined(HAVE_SOCKETPAIR) && !defined(_WIN32) */
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef NEED_ERSATZ_SOCKETPAIR
|
#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
|
#undef SIZEOF_SOCKADDR
|
||||||
|
|
||||||
#endif /* defined(NEED_ERSATZ_SOCKETPAIR) */
|
#endif
|
||||||
|
|
||||||
/* Return the maximum number of allowed sockets. */
|
/* Return the maximum number of allowed sockets. */
|
||||||
int
|
int
|
||||||
|
@ -1645,7 +1665,7 @@ get_max_sockets(void)
|
||||||
* fail by returning -1 and <b>max_out</b> is untouched.
|
* fail by returning -1 and <b>max_out</b> is untouched.
|
||||||
*
|
*
|
||||||
* If we are unable to set the limit value because of setrlimit() failing,
|
* If we are unable to set the limit value because of setrlimit() failing,
|
||||||
* return 0 and <b>max_out</b> is set to the current maximum value returned
|
* return -1 and <b>max_out</b> is set to the current maximum value returned
|
||||||
* by getrlimit().
|
* by getrlimit().
|
||||||
*
|
*
|
||||||
* Otherwise, return 0 and store the maximum we found inside <b>max_out</b>
|
* Otherwise, return 0 and store the maximum we found inside <b>max_out</b>
|
||||||
|
@ -1674,7 +1694,7 @@ set_max_file_descriptors(rlim_t limit, int *max_out)
|
||||||
#else
|
#else
|
||||||
const char *platform = "unknown platforms with no getrlimit()";
|
const char *platform = "unknown platforms with no getrlimit()";
|
||||||
const unsigned long MAX_CONNECTIONS = 15000;
|
const unsigned long MAX_CONNECTIONS = 15000;
|
||||||
#endif /* defined(CYGWIN) || defined(__CYGWIN__) || ... */
|
#endif
|
||||||
log_fn(LOG_INFO, LD_NET,
|
log_fn(LOG_INFO, LD_NET,
|
||||||
"This platform is missing getrlimit(). Proceeding.");
|
"This platform is missing getrlimit(). Proceeding.");
|
||||||
if (limit > MAX_CONNECTIONS) {
|
if (limit > MAX_CONNECTIONS) {
|
||||||
|
@ -1685,7 +1705,7 @@ set_max_file_descriptors(rlim_t limit, int *max_out)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
limit = MAX_CONNECTIONS;
|
limit = MAX_CONNECTIONS;
|
||||||
#else /* !(!defined(HAVE_GETRLIMIT)) */
|
#else /* HAVE_GETRLIMIT */
|
||||||
struct rlimit rlim;
|
struct rlimit rlim;
|
||||||
|
|
||||||
if (getrlimit(RLIMIT_NOFILE, &rlim) != 0) {
|
if (getrlimit(RLIMIT_NOFILE, &rlim) != 0) {
|
||||||
|
@ -1710,14 +1730,13 @@ set_max_file_descriptors(rlim_t limit, int *max_out)
|
||||||
rlim.rlim_cur = rlim.rlim_max;
|
rlim.rlim_cur = rlim.rlim_max;
|
||||||
|
|
||||||
if (setrlimit(RLIMIT_NOFILE, &rlim) != 0) {
|
if (setrlimit(RLIMIT_NOFILE, &rlim) != 0) {
|
||||||
int couldnt_set = 1;
|
int bad = 1;
|
||||||
const int setrlimit_errno = errno;
|
|
||||||
#ifdef OPEN_MAX
|
#ifdef OPEN_MAX
|
||||||
uint64_t try_limit = OPEN_MAX - ULIMIT_BUFFER;
|
uint64_t try_limit = OPEN_MAX - ULIMIT_BUFFER;
|
||||||
if (errno == EINVAL && try_limit < (uint64_t) rlim.rlim_cur) {
|
if (errno == EINVAL && try_limit < (uint64_t) rlim.rlim_cur) {
|
||||||
/* On some platforms, OPEN_MAX is the real limit, and getrlimit() is
|
/* On some platforms, OPEN_MAX is the real limit, and getrlimit() is
|
||||||
* full of nasty lies. I'm looking at you, OSX 10.5.... */
|
* full of nasty lies. I'm looking at you, OSX 10.5.... */
|
||||||
rlim.rlim_cur = MIN((rlim_t) try_limit, rlim.rlim_cur);
|
rlim.rlim_cur = try_limit;
|
||||||
if (setrlimit(RLIMIT_NOFILE, &rlim) == 0) {
|
if (setrlimit(RLIMIT_NOFILE, &rlim) == 0) {
|
||||||
if (rlim.rlim_cur < (rlim_t)limit) {
|
if (rlim.rlim_cur < (rlim_t)limit) {
|
||||||
log_warn(LD_CONFIG, "We are limited to %lu file descriptors by "
|
log_warn(LD_CONFIG, "We are limited to %lu file descriptors by "
|
||||||
|
@ -1732,18 +1751,19 @@ set_max_file_descriptors(rlim_t limit, int *max_out)
|
||||||
(unsigned long)try_limit, (unsigned long)OPEN_MAX,
|
(unsigned long)try_limit, (unsigned long)OPEN_MAX,
|
||||||
(unsigned long)rlim.rlim_max);
|
(unsigned long)rlim.rlim_max);
|
||||||
}
|
}
|
||||||
couldnt_set = 0;
|
bad = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif /* defined(OPEN_MAX) */
|
#endif /* OPEN_MAX */
|
||||||
if (couldnt_set) {
|
if (bad) {
|
||||||
log_warn(LD_CONFIG,"Couldn't set maximum number of file descriptors: %s",
|
log_warn(LD_CONFIG,"Couldn't set maximum number of file descriptors: %s",
|
||||||
strerror(setrlimit_errno));
|
strerror(errno));
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* leave some overhead for logs, etc, */
|
/* leave some overhead for logs, etc, */
|
||||||
limit = rlim.rlim_cur;
|
limit = rlim.rlim_cur;
|
||||||
#endif /* !defined(HAVE_GETRLIMIT) */
|
#endif /* HAVE_GETRLIMIT */
|
||||||
|
|
||||||
if (limit > INT_MAX)
|
if (limit > INT_MAX)
|
||||||
limit = INT_MAX;
|
limit = INT_MAX;
|
||||||
|
@ -1781,7 +1801,7 @@ log_credential_status(void)
|
||||||
"UID is %u (real), %u (effective), %u (saved)",
|
"UID is %u (real), %u (effective), %u (saved)",
|
||||||
(unsigned)ruid, (unsigned)euid, (unsigned)suid);
|
(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 */
|
/* getresuid is not present on MacOS X, so we can't get the saved (E)UID */
|
||||||
ruid = getuid();
|
ruid = getuid();
|
||||||
euid = geteuid();
|
euid = geteuid();
|
||||||
|
@ -1790,7 +1810,7 @@ log_credential_status(void)
|
||||||
log_fn(CREDENTIAL_LOG_LEVEL, LD_GENERAL,
|
log_fn(CREDENTIAL_LOG_LEVEL, LD_GENERAL,
|
||||||
"UID is %u (real), %u (effective), unknown (saved)",
|
"UID is %u (real), %u (effective), unknown (saved)",
|
||||||
(unsigned)ruid, (unsigned)euid);
|
(unsigned)ruid, (unsigned)euid);
|
||||||
#endif /* defined(HAVE_GETRESUID) */
|
#endif
|
||||||
|
|
||||||
/* log GIDs */
|
/* log GIDs */
|
||||||
#ifdef HAVE_GETRESGID
|
#ifdef HAVE_GETRESGID
|
||||||
|
@ -1802,7 +1822,7 @@ log_credential_status(void)
|
||||||
"GID is %u (real), %u (effective), %u (saved)",
|
"GID is %u (real), %u (effective), %u (saved)",
|
||||||
(unsigned)rgid, (unsigned)egid, (unsigned)sgid);
|
(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 */
|
/* getresgid is not present on MacOS X, so we can't get the saved (E)GID */
|
||||||
rgid = getgid();
|
rgid = getgid();
|
||||||
egid = getegid();
|
egid = getegid();
|
||||||
|
@ -1810,7 +1830,7 @@ log_credential_status(void)
|
||||||
log_fn(CREDENTIAL_LOG_LEVEL, LD_GENERAL,
|
log_fn(CREDENTIAL_LOG_LEVEL, LD_GENERAL,
|
||||||
"GID is %u (real), %u (effective), unknown (saved)",
|
"GID is %u (real), %u (effective), unknown (saved)",
|
||||||
(unsigned)rgid, (unsigned)egid);
|
(unsigned)rgid, (unsigned)egid);
|
||||||
#endif /* defined(HAVE_GETRESGID) */
|
#endif
|
||||||
|
|
||||||
/* log supplementary groups */
|
/* log supplementary groups */
|
||||||
sup_gids_size = 64;
|
sup_gids_size = 64;
|
||||||
|
@ -1850,7 +1870,7 @@ log_credential_status(void)
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif /* !defined(_WIN32) */
|
#endif
|
||||||
|
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
/** Cached struct from the last getpwname() call we did successfully. */
|
/** Cached struct from the last getpwname() call we did successfully. */
|
||||||
|
@ -1875,12 +1895,9 @@ tor_passwd_dup(const struct passwd *pw)
|
||||||
return new_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. */
|
/** Helper: free one of our cached 'struct passwd' values. */
|
||||||
static void
|
static void
|
||||||
tor_passwd_free_(struct passwd *pw)
|
tor_passwd_free(struct passwd *pw)
|
||||||
{
|
{
|
||||||
if (!pw)
|
if (!pw)
|
||||||
return;
|
return;
|
||||||
|
@ -1953,7 +1970,7 @@ tor_getpwuid(uid_t uid)
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
#endif /* !defined(_WIN32) */
|
#endif
|
||||||
|
|
||||||
/** Return true iff we were compiled with capability support, and capabilities
|
/** Return true iff we were compiled with capability support, and capabilities
|
||||||
* seem to work. **/
|
* seem to work. **/
|
||||||
|
@ -1966,9 +1983,9 @@ have_capability_support(void)
|
||||||
return 0;
|
return 0;
|
||||||
cap_free(caps);
|
cap_free(caps);
|
||||||
return 1;
|
return 1;
|
||||||
#else /* !(defined(HAVE_LINUX_CAPABILITIES)) */
|
#else
|
||||||
return 0;
|
return 0;
|
||||||
#endif /* defined(HAVE_LINUX_CAPABILITIES) */
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_LINUX_CAPABILITIES
|
#ifdef HAVE_LINUX_CAPABILITIES
|
||||||
|
@ -2027,7 +2044,7 @@ drop_capabilities(int pre_setuid)
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif /* defined(HAVE_LINUX_CAPABILITIES) */
|
#endif
|
||||||
|
|
||||||
/** Call setuid and setgid to run as <b>user</b> and switch to their
|
/** 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.
|
* 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))
|
if (drop_capabilities(1))
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
#else /* !(defined(HAVE_LINUX_CAPABILITIES)) */
|
#else
|
||||||
(void) keep_bindlow;
|
(void) keep_bindlow;
|
||||||
if (warn_if_no_caps) {
|
if (warn_if_no_caps) {
|
||||||
log_warn(LD_CONFIG, "KeepBindCapabilities set, but no capability support "
|
log_warn(LD_CONFIG, "KeepBindCapabilities set, but no capability support "
|
||||||
"on this system.");
|
"on this system.");
|
||||||
}
|
}
|
||||||
#endif /* defined(HAVE_LINUX_CAPABILITIES) */
|
#endif
|
||||||
|
|
||||||
/* Properly switch egid,gid,euid,uid here or bail out */
|
/* Properly switch egid,gid,euid,uid here or bail out */
|
||||||
if (setgroups(1, &pw->pw_gid)) {
|
if (setgroups(1, &pw->pw_gid)) {
|
||||||
|
@ -2143,7 +2160,7 @@ switch_id(const char *user, const unsigned flags)
|
||||||
if (drop_capabilities(0))
|
if (drop_capabilities(0))
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
#endif /* defined(HAVE_LINUX_CAPABILITIES) */
|
#endif
|
||||||
|
|
||||||
#if !defined(CYGWIN) && !defined(__CYGWIN__)
|
#if !defined(CYGWIN) && !defined(__CYGWIN__)
|
||||||
/* If we tried to drop privilege to a group/user other than root, attempt to
|
/* 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;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif /* !defined(CYGWIN) && !defined(__CYGWIN__) */
|
#endif
|
||||||
|
|
||||||
/* Check what really happened */
|
/* Check what really happened */
|
||||||
if (log_credential_status()) {
|
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 */
|
have_already_switched_id = 1; /* mark success so we never try again */
|
||||||
|
|
||||||
#if defined(__linux__) && defined(HAVE_SYS_PRCTL_H) && \
|
#if defined(__linux__) && defined(HAVE_SYS_PRCTL_H) && defined(HAVE_PRCTL)
|
||||||
defined(HAVE_PRCTL) && defined(PR_SET_DUMPABLE)
|
#ifdef PR_SET_DUMPABLE
|
||||||
if (pw->pw_uid) {
|
if (pw->pw_uid) {
|
||||||
/* Re-enable core dumps if we're not running as root. */
|
/* Re-enable core dumps if we're not running as root. */
|
||||||
log_info(LD_CONFIG, "Re-enabling coredumps");
|
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));
|
log_warn(LD_CONFIG, "Unable to re-enable coredumps: %s",strerror(errno));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif /* defined(__linux__) && defined(HAVE_SYS_PRCTL_H) && ... */
|
#endif
|
||||||
|
#endif
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
#else /* !(!defined(_WIN32)) */
|
#else
|
||||||
(void)user;
|
(void)user;
|
||||||
(void)flags;
|
(void)flags;
|
||||||
|
|
||||||
log_warn(LD_CONFIG, "Switching users is unsupported on your OS.");
|
log_warn(LD_CONFIG, "Switching users is unsupported on your OS.");
|
||||||
return -1;
|
return -1;
|
||||||
#endif /* !defined(_WIN32) */
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/* We only use the linux prctl for now. There is no Win32 support; this may
|
/* 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
|
int
|
||||||
tor_disable_debugger_attach(void)
|
tor_disable_debugger_attach(void)
|
||||||
{
|
{
|
||||||
int r = -1;
|
int r, attempted;
|
||||||
|
r = -1;
|
||||||
|
attempted = 0;
|
||||||
log_debug(LD_CONFIG,
|
log_debug(LD_CONFIG,
|
||||||
"Attemping to disable debugger attachment to Tor for "
|
"Attemping to disable debugger attachment to Tor for "
|
||||||
"unprivileged users.");
|
"unprivileged users.");
|
||||||
#if defined(__linux__) && defined(HAVE_SYS_PRCTL_H) \
|
#if defined(__linux__) && defined(HAVE_SYS_PRCTL_H) && defined(HAVE_PRCTL)
|
||||||
&& defined(HAVE_PRCTL) && defined(PR_SET_DUMPABLE)
|
#ifdef PR_SET_DUMPABLE
|
||||||
#define TRIED_TO_DISABLE
|
attempted = 1;
|
||||||
r = prctl(PR_SET_DUMPABLE, 0);
|
r = prctl(PR_SET_DUMPABLE, 0);
|
||||||
#elif defined(__APPLE__) && defined(PT_DENY_ATTACH)
|
#endif
|
||||||
#define TRIED_TO_ATTACH
|
#endif
|
||||||
r = ptrace(PT_DENY_ATTACH, 0, 0, 0);
|
#if defined(__APPLE__) && defined(PT_DENY_ATTACH)
|
||||||
#endif /* defined(__linux__) && defined(HAVE_SYS_PRCTL_H) ... || ... */
|
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 - Mac OS X has dtrace and this may be disabled.
|
||||||
// XXX: TODO - Windows probably has something similar
|
// XXX: TODO - Windows probably has something similar
|
||||||
#ifdef TRIED_TO_DISABLE
|
if (r == 0 && attempted) {
|
||||||
if (r == 0) {
|
|
||||||
log_debug(LD_CONFIG,"Debugger attachment disabled for "
|
log_debug(LD_CONFIG,"Debugger attachment disabled for "
|
||||||
"unprivileged users.");
|
"unprivileged users.");
|
||||||
return 1;
|
return 1;
|
||||||
} else {
|
} else if (attempted) {
|
||||||
log_warn(LD_CONFIG, "Unable to disable debugger attaching: %s",
|
log_warn(LD_CONFIG, "Unable to disable debugger attaching: %s",
|
||||||
strerror(errno));
|
strerror(errno));
|
||||||
}
|
}
|
||||||
#endif /* defined(TRIED_TO_DISABLE) */
|
|
||||||
#undef TRIED_TO_DISABLE
|
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2261,7 +2282,7 @@ get_user_homedir(const char *username)
|
||||||
}
|
}
|
||||||
return tor_strdup(pw->pw_dir);
|
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
|
/** Modify <b>fname</b> to contain the name of its parent directory. Doesn't
|
||||||
* actually examine the filesystem; does a purely syntactic modification.
|
* actually examine the filesystem; does a purely syntactic modification.
|
||||||
|
@ -2289,7 +2310,7 @@ get_parent_directory(char *fname)
|
||||||
if (fname[0] && fname[1] == ':') {
|
if (fname[0] && fname[1] == ':') {
|
||||||
fname += 2;
|
fname += 2;
|
||||||
}
|
}
|
||||||
#endif /* defined(_WIN32) */
|
#endif
|
||||||
/* Now we want to remove all path-separators at the end of the string,
|
/* 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
|
* and to remove the end of the string starting with the path separator
|
||||||
* before the last non-path-separator. In perl, this would be
|
* before the last non-path-separator. In perl, this would be
|
||||||
|
@ -2328,36 +2349,17 @@ get_parent_directory(char *fname)
|
||||||
static char *
|
static char *
|
||||||
alloc_getcwd(void)
|
alloc_getcwd(void)
|
||||||
{
|
{
|
||||||
#ifdef HAVE_GET_CURRENT_DIR_NAME
|
#ifdef PATH_MAX
|
||||||
/* Glibc makes this nice and simple for us. */
|
#define MAX_CWD PATH_MAX
|
||||||
char *cwd = get_current_dir_name();
|
#else
|
||||||
char *result = NULL;
|
#define MAX_CWD 4096
|
||||||
if (cwd) {
|
#endif
|
||||||
/* 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;
|
|
||||||
|
|
||||||
while (ptr == NULL) {
|
char path_buf[MAX_CWD];
|
||||||
buf = tor_realloc(buf, size);
|
char *path = getcwd(path_buf, sizeof(path_buf));
|
||||||
ptr = getcwd(buf, size);
|
return path ? tor_strdup(path) : NULL;
|
||||||
|
|
||||||
if (ptr == NULL && errno != ERANGE) {
|
|
||||||
tor_free(buf);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
size *= 2;
|
|
||||||
}
|
|
||||||
return buf;
|
|
||||||
#endif /* defined(HAVE_GET_CURRENT_DIR_NAME) */
|
|
||||||
}
|
}
|
||||||
#endif /* !defined(_WIN32) */
|
#endif
|
||||||
|
|
||||||
/** Expand possibly relative path <b>fname</b> to an absolute path.
|
/** Expand possibly relative path <b>fname</b> to an absolute path.
|
||||||
* Return a newly allocated string, possibly equal to <b>fname</b>. */
|
* 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);
|
if (absfname_malloced) raw_free(absfname_malloced);
|
||||||
|
|
||||||
return absfname;
|
return absfname;
|
||||||
#else /* !(defined(_WIN32)) */
|
#else
|
||||||
char *absfname = NULL, *path = NULL;
|
char *absfname = NULL, *path = NULL;
|
||||||
|
|
||||||
tor_assert(fname);
|
tor_assert(fname);
|
||||||
|
@ -2396,7 +2398,7 @@ make_path_absolute(char *fname)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return absfname;
|
return absfname;
|
||||||
#endif /* defined(_WIN32) */
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef HAVE__NSGETENVIRON
|
#ifndef HAVE__NSGETENVIRON
|
||||||
|
@ -2405,8 +2407,8 @@ make_path_absolute(char *fname)
|
||||||
#ifndef RUNNING_DOXYGEN
|
#ifndef RUNNING_DOXYGEN
|
||||||
extern char **environ;
|
extern char **environ;
|
||||||
#endif
|
#endif
|
||||||
#endif /* !defined(HAVE_EXTERN_ENVIRON_DECLARED) */
|
#endif
|
||||||
#endif /* !defined(HAVE__NSGETENVIRON) */
|
#endif
|
||||||
|
|
||||||
/** Return the current environment. This is a portable replacement for
|
/** Return the current environment. This is a portable replacement for
|
||||||
* 'environ'. */
|
* 'environ'. */
|
||||||
|
@ -2418,14 +2420,14 @@ get_environment(void)
|
||||||
* when we do a mostly-static build on OSX 10.7, the resulting binary won't
|
* when we do a mostly-static build on OSX 10.7, the resulting binary won't
|
||||||
* work on OSX 10.6. */
|
* work on OSX 10.6. */
|
||||||
return *_NSGetEnviron();
|
return *_NSGetEnviron();
|
||||||
#else /* !(defined(HAVE__NSGETENVIRON)) */
|
#else
|
||||||
return environ;
|
return environ;
|
||||||
#endif /* defined(HAVE__NSGETENVIRON) */
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Get name of current host and write it to <b>name</b> array, whose
|
/** 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
|
* 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().)
|
* this function is merely a mockable wrapper for POSIX gethostname().)
|
||||||
*/
|
*/
|
||||||
MOCK_IMPL(int,
|
MOCK_IMPL(int,
|
||||||
|
@ -2561,7 +2563,6 @@ tor_inet_pton(int af, const char *src, void *dst)
|
||||||
int gapPos = -1, i, setWords=0;
|
int gapPos = -1, i, setWords=0;
|
||||||
const char *dot = strchr(src, '.');
|
const char *dot = strchr(src, '.');
|
||||||
const char *eow; /* end of words. */
|
const char *eow; /* end of words. */
|
||||||
memset(words, 0xf8, sizeof(words));
|
|
||||||
if (dot == src)
|
if (dot == src)
|
||||||
return 0;
|
return 0;
|
||||||
else if (!dot)
|
else if (!dot)
|
||||||
|
@ -2599,7 +2600,7 @@ tor_inet_pton(int af, const char *src, void *dst)
|
||||||
long r = strtol(src, &next, 16);
|
long r = strtol(src, &next, 16);
|
||||||
if (next == NULL || next == src) {
|
if (next == NULL || next == src) {
|
||||||
/* The 'next == src' error case can happen on versions of openbsd
|
/* 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". */
|
* "xfoo". */
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -2686,8 +2687,7 @@ static int uname_result_is_set = 0;
|
||||||
|
|
||||||
/** Return a pointer to a description of our platform.
|
/** Return a pointer to a description of our platform.
|
||||||
*/
|
*/
|
||||||
MOCK_IMPL(const char *,
|
MOCK_IMPL(const char *, get_uname, (void))
|
||||||
get_uname,(void))
|
|
||||||
{
|
{
|
||||||
#ifdef HAVE_UNAME
|
#ifdef HAVE_UNAME
|
||||||
struct utsname u;
|
struct utsname u;
|
||||||
|
@ -2698,7 +2698,7 @@ get_uname,(void))
|
||||||
/* (Linux says 0 is success, Solaris says 1 is success) */
|
/* (Linux says 0 is success, Solaris says 1 is success) */
|
||||||
strlcpy(uname_result, u.sysname, sizeof(uname_result));
|
strlcpy(uname_result, u.sysname, sizeof(uname_result));
|
||||||
} else
|
} else
|
||||||
#endif /* defined(HAVE_UNAME) */
|
#endif
|
||||||
{
|
{
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
OSVERSIONINFOEX info;
|
OSVERSIONINFOEX info;
|
||||||
|
@ -2760,12 +2760,12 @@ get_uname,(void))
|
||||||
info.wProductType == VER_NT_DOMAIN_CONTROLLER) {
|
info.wProductType == VER_NT_DOMAIN_CONTROLLER) {
|
||||||
strlcat(uname_result, " [server]", sizeof(uname_result));
|
strlcat(uname_result, " [server]", sizeof(uname_result));
|
||||||
}
|
}
|
||||||
#endif /* defined(VER_NT_SERVER) */
|
#endif
|
||||||
#else /* !(defined(_WIN32)) */
|
#else
|
||||||
/* LCOV_EXCL_START -- can't provoke uname failure */
|
/* LCOV_EXCL_START -- can't provoke uname failure */
|
||||||
strlcpy(uname_result, "Unknown platform", sizeof(uname_result));
|
strlcpy(uname_result, "Unknown platform", sizeof(uname_result));
|
||||||
/* LCOV_EXCL_STOP */
|
/* LCOV_EXCL_STOP */
|
||||||
#endif /* defined(_WIN32) */
|
#endif
|
||||||
}
|
}
|
||||||
uname_result_is_set = 1;
|
uname_result_is_set = 1;
|
||||||
}
|
}
|
||||||
|
@ -2821,7 +2821,7 @@ compute_num_cpus_impl(void)
|
||||||
return -1;
|
return -1;
|
||||||
#else
|
#else
|
||||||
return -1;
|
return -1;
|
||||||
#endif /* defined(_WIN32) || ... */
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#define MAX_DETECTABLE_CPUS 16
|
#define MAX_DETECTABLE_CPUS 16
|
||||||
|
@ -2860,7 +2860,7 @@ compute_num_cpus(void)
|
||||||
/** Helper: Deal with confused or out-of-bounds values from localtime_r and
|
/** 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
|
* 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
|
* 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
|
* as its input. If we need to store new results, store them in
|
||||||
* <b>resultbuf</b>. */
|
* <b>resultbuf</b>. */
|
||||||
static struct tm *
|
static struct tm *
|
||||||
|
@ -2984,7 +2984,7 @@ tor_localtime_r(const time_t *timep, struct tm *result)
|
||||||
memcpy(result, r, sizeof(struct tm));
|
memcpy(result, r, sizeof(struct tm));
|
||||||
return correct_tm(1, timep, result, r);
|
return correct_tm(1, timep, result, r);
|
||||||
}
|
}
|
||||||
#endif /* defined(HAVE_LOCALTIME_R) || ... */
|
#endif
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
||||||
/** @{ */
|
/** @{ */
|
||||||
|
@ -3027,13 +3027,9 @@ tor_gmtime_r(const time_t *timep, struct tm *result)
|
||||||
memcpy(result, r, sizeof(struct tm));
|
memcpy(result, r, sizeof(struct tm));
|
||||||
return correct_tm(0, timep, result, r);
|
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
|
#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.
|
/** 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
|
* This only needs to be done once and can probably only be done when we have
|
||||||
* not already dropped privileges.
|
* not already dropped privileges.
|
||||||
|
@ -3064,7 +3060,7 @@ tor_set_max_memlock(void)
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif /* defined(HAVE_UNIX_MLOCKALL) */
|
#endif
|
||||||
|
|
||||||
/** Attempt to lock all current and all future memory pages.
|
/** Attempt to lock all current and all future memory pages.
|
||||||
* This should only be called once and while we're privileged.
|
* This should only be called once and while we're privileged.
|
||||||
|
@ -3089,7 +3085,7 @@ tor_mlockall(void)
|
||||||
* http://msdn.microsoft.com/en-us/library/aa366895(VS.85).aspx
|
* 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) {
|
if (tor_set_max_memlock() == 0) {
|
||||||
log_debug(LD_GENERAL, "RLIMIT_MEMLOCK is now set to RLIM_INFINITY.");
|
log_debug(LD_GENERAL, "RLIMIT_MEMLOCK is now set to RLIM_INFINITY.");
|
||||||
}
|
}
|
||||||
|
@ -3110,10 +3106,10 @@ tor_mlockall(void)
|
||||||
"pages: %s", strerror(errno));
|
"pages: %s", strerror(errno));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
#else /* !(defined(HAVE_UNIX_MLOCKALL)) */
|
#else
|
||||||
log_warn(LD_GENERAL, "Unable to lock memory pages. mlockall() unsupported?");
|
log_warn(LD_GENERAL, "Unable to lock memory pages. mlockall() unsupported?");
|
||||||
return -1;
|
return -1;
|
||||||
#endif /* defined(HAVE_UNIX_MLOCKALL) */
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -3141,7 +3137,7 @@ tor_socket_errno(tor_socket_t sock)
|
||||||
}
|
}
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
#endif /* defined(_WIN32) */
|
#endif
|
||||||
|
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
#define E(code, s) { code, (s " [" #code " ]") }
|
#define E(code, s) { code, (s " [" #code " ]") }
|
||||||
|
@ -3217,7 +3213,7 @@ tor_socket_strerror(int e)
|
||||||
}
|
}
|
||||||
return strerror(e);
|
return strerror(e);
|
||||||
}
|
}
|
||||||
#endif /* defined(_WIN32) */
|
#endif
|
||||||
|
|
||||||
/** Called before we make any calls to network-related functions.
|
/** Called before we make any calls to network-related functions.
|
||||||
* (Some operating systems require their network libraries to be
|
* (Some operating systems require their network libraries to be
|
||||||
|
@ -3243,7 +3239,7 @@ network_init(void)
|
||||||
/* WSAData.iMaxSockets might show the max sockets we're allowed to use.
|
/* 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
|
* We might use it to complain if we're trying to be a server but have
|
||||||
* too few sockets available. */
|
* too few sockets available. */
|
||||||
#endif /* defined(_WIN32) */
|
#endif
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3264,7 +3260,7 @@ format_win32_error(DWORD err)
|
||||||
FORMAT_MESSAGE_FROM_SYSTEM |
|
FORMAT_MESSAGE_FROM_SYSTEM |
|
||||||
FORMAT_MESSAGE_IGNORE_INSERTS,
|
FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||||
NULL, err,
|
NULL, err,
|
||||||
MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT),
|
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
||||||
(LPVOID)&str,
|
(LPVOID)&str,
|
||||||
0, NULL);
|
0, NULL);
|
||||||
|
|
||||||
|
@ -3279,9 +3275,9 @@ format_win32_error(DWORD err)
|
||||||
result = tor_malloc(len);
|
result = tor_malloc(len);
|
||||||
wcstombs(result,str,len);
|
wcstombs(result,str,len);
|
||||||
result[len-1] = '\0';
|
result[len-1] = '\0';
|
||||||
#else /* !(defined(UNICODE)) */
|
#else
|
||||||
result = tor_strdup(str);
|
result = tor_strdup(str);
|
||||||
#endif /* defined(UNICODE) */
|
#endif
|
||||||
} else {
|
} else {
|
||||||
result = tor_strdup("<unformattable error>");
|
result = tor_strdup("<unformattable error>");
|
||||||
}
|
}
|
||||||
|
@ -3290,7 +3286,7 @@ format_win32_error(DWORD err)
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
#endif /* defined(_WIN32) */
|
#endif
|
||||||
|
|
||||||
#if defined(HW_PHYSMEM64)
|
#if defined(HW_PHYSMEM64)
|
||||||
/* This appears to be an OpenBSD thing */
|
/* This appears to be an OpenBSD thing */
|
||||||
|
@ -3298,7 +3294,7 @@ format_win32_error(DWORD err)
|
||||||
#elif defined(HW_MEMSIZE)
|
#elif defined(HW_MEMSIZE)
|
||||||
/* OSX defines this one */
|
/* OSX defines this one */
|
||||||
#define INT64_HW_MEM HW_MEMSIZE
|
#define INT64_HW_MEM HW_MEMSIZE
|
||||||
#endif /* defined(HW_PHYSMEM64) || ... */
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper: try to detect the total system memory, and return it. On failure,
|
* Helper: try to detect the total system memory, and return it. On failure,
|
||||||
|
@ -3331,8 +3327,8 @@ get_total_system_memory_impl(void)
|
||||||
tor_free(s);
|
tor_free(s);
|
||||||
return result * 1024;
|
return result * 1024;
|
||||||
|
|
||||||
/* LCOV_EXCL_START Can't reach this unless proc is broken. */
|
|
||||||
err:
|
err:
|
||||||
|
/* LCOV_EXCL_START Can't reach this unless proc is broken. */
|
||||||
tor_free(s);
|
tor_free(s);
|
||||||
close(fd);
|
close(fd);
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -3372,15 +3368,15 @@ get_total_system_memory_impl(void)
|
||||||
#else
|
#else
|
||||||
/* I have no clue. */
|
/* I have no clue. */
|
||||||
return 0;
|
return 0;
|
||||||
#endif /* defined(__linux__) || ... */
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Try to find out how much physical memory the system has. On success,
|
* 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.
|
* return 0 and set *<b>mem_out</b> to that value. On failure, return -1.
|
||||||
*/
|
*/
|
||||||
MOCK_IMPL(int,
|
int
|
||||||
get_total_system_memory, (size_t *mem_out))
|
get_total_system_memory(size_t *mem_out)
|
||||||
{
|
{
|
||||||
static size_t mem_cached=0;
|
static size_t mem_cached=0;
|
||||||
uint64_t m = get_total_system_memory_impl();
|
uint64_t m = get_total_system_memory_impl();
|
||||||
|
@ -3405,7 +3401,7 @@ get_total_system_memory, (size_t *mem_out))
|
||||||
* size_t. */
|
* size_t. */
|
||||||
m = SIZE_MAX;
|
m = SIZE_MAX;
|
||||||
}
|
}
|
||||||
#endif /* SIZE_MAX != UINT64_MAX */
|
#endif
|
||||||
|
|
||||||
*mem_out = mem_cached = (size_t) m;
|
*mem_out = mem_cached = (size_t) m;
|
||||||
|
|
||||||
|
@ -3486,7 +3482,7 @@ tor_getpass(const char *prompt, char *output, size_t buflen)
|
||||||
return r;
|
return r;
|
||||||
#else
|
#else
|
||||||
#error "No implementation for tor_getpass found!"
|
#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
|
/** Return the amount of free disk space we have permission to use, in
|
||||||
|
@ -3526,6 +3522,6 @@ tor_get_avail_disk_space(const char *path)
|
||||||
(void)path;
|
(void)path;
|
||||||
errno = ENOSYS;
|
errno = ENOSYS;
|
||||||
return -1;
|
return -1;
|
||||||
#endif /* defined(HAVE_STATVFS) || ... */
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* Copyright (c) 2003-2004, Roger Dingledine
|
/* Copyright (c) 2003-2004, Roger Dingledine
|
||||||
* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
|
* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
|
||||||
* Copyright (c) 2007-2017, The Tor Project, Inc. */
|
* Copyright (c) 2007-2016, The Tor Project, Inc. */
|
||||||
/* See LICENSE for licensing information */
|
/* See LICENSE for licensing information */
|
||||||
|
|
||||||
#ifndef TOR_COMPAT_H
|
#ifndef TOR_COMPAT_H
|
||||||
|
@ -10,9 +10,6 @@
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#include <winsock2.h>
|
#include <winsock2.h>
|
||||||
#include <ws2tcpip.h>
|
#include <ws2tcpip.h>
|
||||||
#ifndef SIO_IDEAL_SEND_BACKLOG_QUERY
|
|
||||||
#define SIO_IDEAL_SEND_BACKLOG_QUERY 0x4004747b
|
|
||||||
#endif
|
|
||||||
#endif
|
#endif
|
||||||
#include "torint.h"
|
#include "torint.h"
|
||||||
#include "testsupport.h"
|
#include "testsupport.h"
|
||||||
|
@ -53,8 +50,8 @@
|
||||||
* clang rejects because it is off the end of a less-than-3. Clang hates this,
|
* clang rejects because it is off the end of a less-than-3. Clang hates this,
|
||||||
* even though those references never actually happen. */
|
* even though those references never actually happen. */
|
||||||
# undef strcmp
|
# undef strcmp
|
||||||
#endif /* __has_feature(address_sanitizer) */
|
# endif
|
||||||
#endif /* defined(__has_feature) */
|
#endif
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
@ -79,13 +76,13 @@
|
||||||
__attribute__ ((format(printf, formatIdx, firstArg)))
|
__attribute__ ((format(printf, formatIdx, firstArg)))
|
||||||
#else
|
#else
|
||||||
#define CHECK_PRINTF(formatIdx, firstArg)
|
#define CHECK_PRINTF(formatIdx, firstArg)
|
||||||
#endif /* defined(__GNUC__) */
|
#endif
|
||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
#define CHECK_SCANF(formatIdx, firstArg) \
|
#define CHECK_SCANF(formatIdx, firstArg) \
|
||||||
__attribute__ ((format(scanf, formatIdx, firstArg)))
|
__attribute__ ((format(scanf, formatIdx, firstArg)))
|
||||||
#else
|
#else
|
||||||
#define CHECK_SCANF(formatIdx, firstArg)
|
#define CHECK_SCANF(formatIdx, firstArg)
|
||||||
#endif /* defined(__GNUC__) */
|
#endif
|
||||||
|
|
||||||
/* What GCC do we have? */
|
/* What GCC do we have? */
|
||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
|
@ -112,18 +109,18 @@
|
||||||
PRAGMA_DIAGNOSTIC_(ignored PRAGMA_JOIN_STRINGIFY_(-W,warningopt))
|
PRAGMA_DIAGNOSTIC_(ignored PRAGMA_JOIN_STRINGIFY_(-W,warningopt))
|
||||||
# define ENABLE_GCC_WARNING(warningopt) \
|
# define ENABLE_GCC_WARNING(warningopt) \
|
||||||
PRAGMA_DIAGNOSTIC_(pop)
|
PRAGMA_DIAGNOSTIC_(pop)
|
||||||
#else /* !(defined(__clang__) || GCC_VERSION >= 406) */
|
# else
|
||||||
/* older version of gcc: no push/pop support. */
|
/* older version of gcc: no push/pop support. */
|
||||||
# define DISABLE_GCC_WARNING(warningopt) \
|
# define DISABLE_GCC_WARNING(warningopt) \
|
||||||
PRAGMA_DIAGNOSTIC_(ignored PRAGMA_JOIN_STRINGIFY_(-W,warningopt))
|
PRAGMA_DIAGNOSTIC_(ignored PRAGMA_JOIN_STRINGIFY_(-W,warningopt))
|
||||||
# define ENABLE_GCC_WARNING(warningopt) \
|
# define ENABLE_GCC_WARNING(warningopt) \
|
||||||
PRAGMA_DIAGNOSTIC_(warning PRAGMA_JOIN_STRINGIFY_(-W,warningopt))
|
PRAGMA_DIAGNOSTIC_(warning PRAGMA_JOIN_STRINGIFY_(-W,warningopt))
|
||||||
#endif /* defined(__clang__) || GCC_VERSION >= 406 */
|
# endif
|
||||||
#else /* !(defined(__GNUC__)) */
|
#else /* ifdef __GNUC__ */
|
||||||
/* not gcc at all */
|
/* not gcc at all */
|
||||||
# define DISABLE_GCC_WARNING(warning)
|
# define DISABLE_GCC_WARNING(warning)
|
||||||
# define ENABLE_GCC_WARNING(warning)
|
# define ENABLE_GCC_WARNING(warning)
|
||||||
#endif /* defined(__GNUC__) */
|
#endif
|
||||||
|
|
||||||
/* inline is __inline on windows. */
|
/* inline is __inline on windows. */
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
|
@ -145,9 +142,9 @@
|
||||||
#define __func__ __FUNC__
|
#define __func__ __FUNC__
|
||||||
#else
|
#else
|
||||||
#define __func__ "???"
|
#define __func__ "???"
|
||||||
#endif /* defined(HAVE_MACRO__FUNCTION__) || ... */
|
#endif
|
||||||
#endif /* !defined(HAVE_MACRO__func__) */
|
#endif /* ifndef MAVE_MACRO__func__ */
|
||||||
#endif /* defined(_MSC_VER) */
|
#endif /* if not windows */
|
||||||
|
|
||||||
#define U64_TO_DBL(x) ((double) (x))
|
#define U64_TO_DBL(x) ((double) (x))
|
||||||
#define DBL_TO_U64(x) ((uint64_t) (x))
|
#define DBL_TO_U64(x) ((uint64_t) (x))
|
||||||
|
@ -160,7 +157,7 @@
|
||||||
* problems), but if enumerated types are unsigned, we must use unsigned,
|
* problems), but if enumerated types are unsigned, we must use unsigned,
|
||||||
* so that the loss of precision doesn't make large values negative. */
|
* so that the loss of precision doesn't make large values negative. */
|
||||||
#define ENUM_BF(t) t
|
#define ENUM_BF(t) t
|
||||||
#endif /* defined(ENUM_VALS_ARE_SIGNED) */
|
#endif
|
||||||
|
|
||||||
/* GCC has several useful attributes. */
|
/* GCC has several useful attributes. */
|
||||||
#if defined(__GNUC__) && __GNUC__ >= 3
|
#if defined(__GNUC__) && __GNUC__ >= 3
|
||||||
|
@ -197,7 +194,7 @@
|
||||||
* taken. This can generate slightly better code with some CPUs.
|
* taken. This can generate slightly better code with some CPUs.
|
||||||
*/
|
*/
|
||||||
#define PREDICT_UNLIKELY(exp) __builtin_expect(!!(exp), 0)
|
#define PREDICT_UNLIKELY(exp) __builtin_expect(!!(exp), 0)
|
||||||
#else /* !(defined(__GNUC__) && __GNUC__ >= 3) */
|
#else
|
||||||
#define ATTR_NORETURN
|
#define ATTR_NORETURN
|
||||||
#define ATTR_CONST
|
#define ATTR_CONST
|
||||||
#define ATTR_MALLOC
|
#define ATTR_MALLOC
|
||||||
|
@ -207,7 +204,7 @@
|
||||||
#define ATTR_WUR
|
#define ATTR_WUR
|
||||||
#define PREDICT_LIKELY(exp) (exp)
|
#define PREDICT_LIKELY(exp) (exp)
|
||||||
#define PREDICT_UNLIKELY(exp) (exp)
|
#define PREDICT_UNLIKELY(exp) (exp)
|
||||||
#endif /* defined(__GNUC__) && __GNUC__ >= 3 */
|
#endif
|
||||||
|
|
||||||
/** Expands to a syntactically valid empty statement. */
|
/** Expands to a syntactically valid empty statement. */
|
||||||
#define STMT_NIL (void)0
|
#define STMT_NIL (void)0
|
||||||
|
@ -227,7 +224,7 @@
|
||||||
#else
|
#else
|
||||||
#define STMT_BEGIN do {
|
#define STMT_BEGIN do {
|
||||||
#define STMT_END } while (0)
|
#define STMT_END } while (0)
|
||||||
#endif /* defined(__GNUC__) || ... */
|
#endif
|
||||||
|
|
||||||
/* Some tools (like coccinelle) don't like to see operators as macro
|
/* Some tools (like coccinelle) don't like to see operators as macro
|
||||||
* arguments. */
|
* arguments. */
|
||||||
|
@ -254,7 +251,7 @@
|
||||||
*/
|
*/
|
||||||
#undef strlcat
|
#undef strlcat
|
||||||
#undef strlcpy
|
#undef strlcpy
|
||||||
#endif /* defined __APPLE__ */
|
#endif
|
||||||
|
|
||||||
#ifndef HAVE_STRLCAT
|
#ifndef HAVE_STRLCAT
|
||||||
size_t strlcat(char *dst, const char *src, size_t siz) ATTR_NONNULL((1,2));
|
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_PRINTF_ARG(a) (a)
|
||||||
#define I64_SCANF_ARG(a) (a)
|
#define I64_SCANF_ARG(a) (a)
|
||||||
#define I64_LITERAL(n) (n ## i64)
|
#define I64_LITERAL(n) (n ## i64)
|
||||||
#else /* !(defined(_MSC_VER)) */
|
#else
|
||||||
#define U64_PRINTF_ARG(a) ((long long unsigned int)(a))
|
#define U64_PRINTF_ARG(a) ((long long unsigned int)(a))
|
||||||
#define U64_SCANF_ARG(a) ((long long unsigned int*)(a))
|
#define U64_SCANF_ARG(a) ((long long unsigned int*)(a))
|
||||||
#define U64_LITERAL(n) (n ## llu)
|
#define U64_LITERAL(n) (n ## llu)
|
||||||
#define I64_PRINTF_ARG(a) ((long long signed int)(a))
|
#define I64_PRINTF_ARG(a) ((long long signed int)(a))
|
||||||
#define I64_SCANF_ARG(a) ((long long signed int*)(a))
|
#define I64_SCANF_ARG(a) ((long long signed int*)(a))
|
||||||
#define I64_LITERAL(n) (n ## ll)
|
#define I64_LITERAL(n) (n ## ll)
|
||||||
#endif /* defined(_MSC_VER) */
|
|
||||||
|
|
||||||
#if defined(__MINGW32__) || defined(__MINGW64__)
|
|
||||||
#define MINGW_ANY
|
|
||||||
#endif
|
#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
|
/** 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. */
|
* scanf() function. See also U64_PRINTF_ARG and U64_SCANF_ARG. */
|
||||||
#define U64_FORMAT "%I64u"
|
#define U64_FORMAT "%I64u"
|
||||||
#define I64_FORMAT "%I64d"
|
#define I64_FORMAT "%I64d"
|
||||||
#else /* !(defined(_MSC_VER) || defined(MINGW_ANY)) */
|
#else
|
||||||
#define U64_FORMAT "%llu"
|
#define U64_FORMAT "%llu"
|
||||||
#define I64_FORMAT "%lld"
|
#define I64_FORMAT "%lld"
|
||||||
#endif /* defined(_MSC_VER) || defined(MINGW_ANY) */
|
#endif
|
||||||
|
|
||||||
#if (SIZEOF_INTPTR_T == SIZEOF_INT)
|
#if (SIZEOF_INTPTR_T == SIZEOF_INT)
|
||||||
#define INTPTR_T_FORMAT "%d"
|
#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)
|
#define INTPTR_PRINTF_ARG(x) I64_PRINTF_ARG(x)
|
||||||
#else
|
#else
|
||||||
#error Unknown: SIZEOF_INTPTR_T
|
#error Unknown: SIZEOF_INTPTR_T
|
||||||
#endif /* (SIZEOF_INTPTR_T == SIZEOF_INT) || ... */
|
#endif
|
||||||
|
|
||||||
/** Represents an mmaped file. Allocated via tor_mmap_file; freed with
|
/** Represents an mmaped file. Allocated via tor_mmap_file; freed with
|
||||||
* tor_munmap_file. */
|
* tor_munmap_file. */
|
||||||
|
@ -318,12 +311,12 @@ typedef struct tor_mmap_t {
|
||||||
size_t size; /**< Size of the file. */
|
size_t size; /**< Size of the file. */
|
||||||
|
|
||||||
/* None of the fields below should be accessed from outside compat.c */
|
/* 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_t mapping_size; /**< Size of the actual mapping. (This is this file
|
||||||
* size, rounded up to the nearest page.) */
|
* size, rounded up to the nearest page.) */
|
||||||
#elif defined _WIN32
|
#elif defined _WIN32
|
||||||
HANDLE mmap_handle;
|
HANDLE mmap_handle;
|
||||||
#endif /* defined(HAVE_MMAP) || ... */
|
#endif
|
||||||
|
|
||||||
} tor_mmap_t;
|
} tor_mmap_t;
|
||||||
|
|
||||||
|
@ -385,7 +378,7 @@ const char *tor_fix_source_file(const char *fname);
|
||||||
#else
|
#else
|
||||||
#define SHORT_FILE__ (__FILE__)
|
#define SHORT_FILE__ (__FILE__)
|
||||||
#define tor_fix_source_file(s) (s)
|
#define tor_fix_source_file(s) (s)
|
||||||
#endif /* defined(_WIN32) */
|
#endif
|
||||||
|
|
||||||
/* ===== Time compatibility */
|
/* ===== Time compatibility */
|
||||||
|
|
||||||
|
@ -404,7 +397,7 @@ struct tm *tor_gmtime_r(const time_t *timep, struct tm *result);
|
||||||
(tvout)->tv_sec++; \
|
(tvout)->tv_sec++; \
|
||||||
} \
|
} \
|
||||||
} while (0)
|
} while (0)
|
||||||
#endif /* !defined(timeradd) */
|
#endif
|
||||||
|
|
||||||
#ifndef timersub
|
#ifndef timersub
|
||||||
/** Replacement for timersub on platforms that do not have it: sets tvout to
|
/** Replacement for timersub on platforms that do not have it: sets tvout to
|
||||||
|
@ -418,13 +411,13 @@ struct tm *tor_gmtime_r(const time_t *timep, struct tm *result);
|
||||||
(tvout)->tv_sec--; \
|
(tvout)->tv_sec--; \
|
||||||
} \
|
} \
|
||||||
} while (0)
|
} while (0)
|
||||||
#endif /* !defined(timersub) */
|
#endif
|
||||||
|
|
||||||
#ifndef timercmp
|
#ifndef timercmp
|
||||||
/** Replacement for timercmp on platforms that do not have it: returns true
|
/** Replacement for timersub on platforms that do not have it: returns true
|
||||||
* iff the relational operator "op" makes the expression tv1 op tv2 true.
|
* iff the relational operator "op" makes the expression tv1 op tv2 true.
|
||||||
*
|
*
|
||||||
* Note that while this definition should work for all boolean operators, some
|
* Note that while this definition should work for all boolean opeators, some
|
||||||
* platforms' native timercmp definitions do not support >=, <=, or ==. So
|
* platforms' native timercmp definitions do not support >=, <=, or ==. So
|
||||||
* don't use those.
|
* don't use those.
|
||||||
*/
|
*/
|
||||||
|
@ -432,7 +425,7 @@ struct tm *tor_gmtime_r(const time_t *timep, struct tm *result);
|
||||||
(((tv1)->tv_sec == (tv2)->tv_sec) ? \
|
(((tv1)->tv_sec == (tv2)->tv_sec) ? \
|
||||||
((tv1)->tv_usec op (tv2)->tv_usec) : \
|
((tv1)->tv_usec op (tv2)->tv_usec) : \
|
||||||
((tv1)->tv_sec op (tv2)->tv_sec))
|
((tv1)->tv_sec op (tv2)->tv_sec))
|
||||||
#endif /* !defined(timercmp) */
|
#endif
|
||||||
|
|
||||||
/* ===== File compatibility */
|
/* ===== File compatibility */
|
||||||
int tor_open_cloexec(const char *path, int flags, unsigned mode);
|
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 TOR_SOCKET_T_FORMAT INTPTR_T_FORMAT
|
||||||
#define SOCKET_OK(s) ((SOCKET)(s) != INVALID_SOCKET)
|
#define SOCKET_OK(s) ((SOCKET)(s) != INVALID_SOCKET)
|
||||||
#define TOR_INVALID_SOCKET INVALID_SOCKET
|
#define TOR_INVALID_SOCKET INVALID_SOCKET
|
||||||
#else /* !(defined(_WIN32)) */
|
#else
|
||||||
/** Type used for a network socket. */
|
/** Type used for a network socket. */
|
||||||
#define tor_socket_t int
|
#define tor_socket_t int
|
||||||
#define TOR_SOCKET_T_FORMAT "%d"
|
#define TOR_SOCKET_T_FORMAT "%d"
|
||||||
|
@ -482,11 +475,10 @@ typedef int socklen_t;
|
||||||
#define SOCKET_OK(s) ((s) >= 0)
|
#define SOCKET_OK(s) ((s) >= 0)
|
||||||
/** Error/uninitialized value for a tor_socket_t. */
|
/** Error/uninitialized value for a tor_socket_t. */
|
||||||
#define TOR_INVALID_SOCKET (-1)
|
#define TOR_INVALID_SOCKET (-1)
|
||||||
#endif /* defined(_WIN32) */
|
#endif
|
||||||
|
|
||||||
int tor_close_socket_simple(tor_socket_t s);
|
int tor_close_socket_simple(tor_socket_t s);
|
||||||
MOCK_DECL(int, tor_close_socket, (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(
|
tor_socket_t tor_open_socket_with_extensions(
|
||||||
int domain, int type, int protocol,
|
int domain, int type, int protocol,
|
||||||
int cloexec, int nonblock);
|
int cloexec, int nonblock);
|
||||||
|
@ -510,8 +502,6 @@ int get_n_open_sockets(void);
|
||||||
MOCK_DECL(int,
|
MOCK_DECL(int,
|
||||||
tor_getsockname,(tor_socket_t socket, struct sockaddr *address,
|
tor_getsockname,(tor_socket_t socket, struct sockaddr *address,
|
||||||
socklen_t *address_len));
|
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_send(s, buf, len, flags) send(s, buf, len, flags)
|
||||||
#define tor_socket_recv(s, buf, len, flags) recv(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_addr16 in6_u.u6_addr16
|
||||||
#define s6_addr32 in6_u.u6_addr32
|
#define s6_addr32 in6_u.u6_addr32
|
||||||
};
|
};
|
||||||
#endif /* !defined(HAVE_STRUCT_IN6_ADDR) */
|
#endif
|
||||||
|
|
||||||
/** @{ */
|
/** @{ */
|
||||||
/** Many BSD variants seem not to define these. */
|
/** Many BSD variants seem not to define these. */
|
||||||
#if defined(__APPLE__) || defined(__darwin__) || \
|
#if defined(__APPLE__) || defined(__darwin__) || defined(__FreeBSD__) \
|
||||||
defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)
|
|| defined(__NetBSD__) || defined(__OpenBSD__)
|
||||||
#ifndef s6_addr16
|
#ifndef s6_addr16
|
||||||
#define s6_addr16 __u6_addr.__u6_addr16
|
#define s6_addr16 __u6_addr.__u6_addr16
|
||||||
#endif
|
#endif
|
||||||
#ifndef s6_addr32
|
#ifndef s6_addr32
|
||||||
#define s6_addr32 __u6_addr.__u6_addr32
|
#define s6_addr32 __u6_addr.__u6_addr32
|
||||||
#endif
|
#endif
|
||||||
#endif /* defined(__APPLE__) || defined(__darwin__) || ... */
|
#endif
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
||||||
#ifndef HAVE_SA_FAMILY_T
|
#ifndef HAVE_SA_FAMILY_T
|
||||||
|
@ -576,7 +566,7 @@ struct sockaddr_in6 {
|
||||||
struct in6_addr sin6_addr;
|
struct in6_addr sin6_addr;
|
||||||
// uint32_t sin6_scope_id;
|
// uint32_t sin6_scope_id;
|
||||||
};
|
};
|
||||||
#endif /* !defined(HAVE_STRUCT_SOCKADDR_IN6) */
|
#endif
|
||||||
|
|
||||||
MOCK_DECL(int,tor_gethostname,(char *name, size_t namelen));
|
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));
|
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)
|
#define ERRNO_IS_EINTR(e) ((e) == WSAEINTR || 0)
|
||||||
int tor_socket_errno(tor_socket_t sock);
|
int tor_socket_errno(tor_socket_t sock);
|
||||||
const char *tor_socket_strerror(int e);
|
const char *tor_socket_strerror(int e);
|
||||||
#else /* !(defined(_WIN32)) */
|
#else
|
||||||
#define SOCK_ERRNO(e) e
|
#define SOCK_ERRNO(e) e
|
||||||
#if EAGAIN == EWOULDBLOCK
|
#if EAGAIN == EWOULDBLOCK
|
||||||
/* || 0 is for -Wparentheses-equality (-Wall?) appeasement under clang */
|
/* || 0 is for -Wparentheses-equality (-Wall?) appeasement under clang */
|
||||||
#define ERRNO_IS_EAGAIN(e) ((e) == EAGAIN || 0)
|
#define ERRNO_IS_EAGAIN(e) ((e) == EAGAIN || 0)
|
||||||
#else
|
#else
|
||||||
#define ERRNO_IS_EAGAIN(e) ((e) == EAGAIN || (e) == EWOULDBLOCK)
|
#define ERRNO_IS_EAGAIN(e) ((e) == EAGAIN || (e) == EWOULDBLOCK)
|
||||||
#endif /* EAGAIN == EWOULDBLOCK */
|
#endif
|
||||||
#define ERRNO_IS_EINTR(e) ((e) == EINTR || 0)
|
#define ERRNO_IS_EINTR(e) ((e) == EINTR || 0)
|
||||||
#define ERRNO_IS_EINPROGRESS(e) ((e) == EINPROGRESS || 0)
|
#define ERRNO_IS_EINPROGRESS(e) ((e) == EINPROGRESS || 0)
|
||||||
#define ERRNO_IS_CONN_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 ERRNO_IS_EADDRINUSE(e) (((e) == EADDRINUSE) || 0)
|
||||||
#define tor_socket_errno(sock) (errno)
|
#define tor_socket_errno(sock) (errno)
|
||||||
#define tor_socket_strerror(e) strerror(e)
|
#define tor_socket_strerror(e) strerror(e)
|
||||||
#endif /* defined(_WIN32) */
|
#endif
|
||||||
|
|
||||||
/** Specified SOCKS5 status codes. */
|
/** Specified SOCKS5 status codes. */
|
||||||
typedef enum {
|
typedef enum {
|
||||||
|
@ -701,7 +691,7 @@ char *make_path_absolute(char *fname);
|
||||||
|
|
||||||
char **get_environment(void);
|
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);
|
int compute_num_cpus(void);
|
||||||
|
|
||||||
|
@ -738,7 +728,7 @@ char *format_win32_error(DWORD err);
|
||||||
#define VER_SUITE_SINGLEUSERTS 0x00000100
|
#define VER_SUITE_SINGLEUSERTS 0x00000100
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* defined(_WIN32) */
|
#endif
|
||||||
|
|
||||||
#ifdef COMPAT_PRIVATE
|
#ifdef COMPAT_PRIVATE
|
||||||
#if !defined(HAVE_SOCKETPAIR) || defined(_WIN32) || defined(TOR_UNIT_TESTS)
|
#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,
|
STATIC int tor_ersatz_socketpair(int family, int type, int protocol,
|
||||||
tor_socket_t fd[2]);
|
tor_socket_t fd[2]);
|
||||||
#endif
|
#endif
|
||||||
#endif /* defined(COMPAT_PRIVATE) */
|
#endif
|
||||||
|
|
||||||
ssize_t tor_getpass(const char *prompt, char *output, size_t buflen);
|
ssize_t tor_getpass(const char *prompt, char *output, size_t buflen);
|
||||||
|
|
||||||
/* This needs some of the declarations above so we include it here. */
|
/* This needs some of the declarations above so we include it here. */
|
||||||
#include "compat_threads.h"
|
#include "compat_threads.h"
|
||||||
|
|
||||||
#endif /* !defined(TOR_COMPAT_H) */
|
#endif
|
||||||
|
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue