Compare commits
214 Commits
master
...
release-0.
Author | SHA1 | Date |
---|---|---|
Nick Mathewson | 4843d5349d | |
Nick Mathewson | 3f8fe441cf | |
Nick Mathewson | 12e465344e | |
Nick Mathewson | 90e7364e7e | |
Nick Mathewson | d47da40058 | |
Nick Mathewson | 5fd8f3b71d | |
Nick Mathewson | 9ca9e6a1f7 | |
Nick Mathewson | 8ddd84707e | |
Nick Mathewson | 3bf89fb85f | |
Nick Mathewson | edf721f8f0 | |
Nick Mathewson | beaaeecd20 | |
Nick Mathewson | 3f2cf1c0f5 | |
Nick Mathewson | 28dc7a519c | |
Nick Mathewson | 02ac1822ab | |
Nick Mathewson | ae0ee02026 | |
Nick Mathewson | 8eb9aaf4f6 | |
Nick Mathewson | 347b38d6d9 | |
Nick Mathewson | 04007557fb | |
Nick Mathewson | cbea95ae67 | |
Nick Mathewson | e9ec63d1ac | |
Nick Mathewson | 72db4f836a | |
Nick Mathewson | 35179a8c05 | |
Nick Mathewson | 1eb7041ef1 | |
Nick Mathewson | e3966d47c7 | |
Nick Mathewson | 21cea2c9de | |
Nick Mathewson | 19602bffbe | |
Nick Mathewson | babd102f0b | |
Nick Mathewson | b6b239ce0c | |
Nick Mathewson | ce9df228a5 | |
Nick Mathewson | ff679ee066 | |
Nick Mathewson | 60d3a3c754 | |
Nick Mathewson | 7e2e8ac245 | |
Nick Mathewson | 7e4623a235 | |
Nick Mathewson | f0f22ad92c | |
Nick Mathewson | b9b7013062 | |
Nick Mathewson | 0f4b1020af | |
Nick Mathewson | 97c988c431 | |
Nick Mathewson | c93f69af58 | |
Nick Mathewson | cf55f0516c | |
Nick Mathewson | ed13a7f625 | |
Nick Mathewson | abd6205384 | |
Nick Mathewson | 6f238a44d8 | |
Nick Mathewson | 6d0309e48b | |
Nick Mathewson | d83d1c7a89 | |
Nick Mathewson | 76b73013e2 | |
Nick Mathewson | 0e0baad5e8 | |
Nick Mathewson | c30d2daae0 | |
Nick Mathewson | 256cd9d877 | |
Nick Mathewson | 83648ef077 | |
Nick Mathewson | f9fe48989b | |
Nick Mathewson | 0e5140320b | |
Nick Mathewson | e9a102ff5e | |
Nick Mathewson | ed304a052f | |
Nick Mathewson | a8a060cdb3 | |
Nick Mathewson | 45b1c6bc8b | |
Nick Mathewson | 40faebd45b | |
Nick Mathewson | 1723138fcd | |
Nick Mathewson | bda3c54447 | |
Nick Mathewson | ee1bbe21ab | |
Nick Mathewson | b63cbec65e | |
Nick Mathewson | 74ce41d4d4 | |
Nick Mathewson | 2edad42fd8 | |
Nick Mathewson | fbb74fb37c | |
Nick Mathewson | 24f7698320 | |
Nick Mathewson | d3048a8f5b | |
Nick Mathewson | 9703b41480 | |
Nick Mathewson | 727d3f1b5e | |
Nick Mathewson | 94ad23deb2 | |
Nick Mathewson | d8d52f2b73 | |
Nick Mathewson | 14746dfba2 | |
Nick Mathewson | 7c548437cc | |
Nick Mathewson | bedd32e5d1 | |
Nick Mathewson | 3c0150aa46 | |
Nick Mathewson | 70fcbd5f83 | |
Nick Mathewson | d96f7f38e8 | |
Nick Mathewson | 5355b99dc0 | |
Nick Mathewson | 5c98411663 | |
Nick Mathewson | fe5d607d6b | |
Nick Mathewson | ba1db0c797 | |
Nick Mathewson | fb1c191e54 | |
Nick Mathewson | 6155f76691 | |
Nick Mathewson | 987f628b73 | |
Nick Mathewson | ad5027f7dc | |
Nick Mathewson | 4a49e134bc | |
Nick Mathewson | ee70e2ed6d | |
Nick Mathewson | af51ac47e0 | |
Nick Mathewson | d5e3b6e6b7 | |
Nick Mathewson | ce8d60674d | |
Nick Mathewson | ebedb5e06f | |
Nick Mathewson | 602f9565a9 | |
Nick Mathewson | 5f78775a8a | |
Nick Mathewson | 11abdccc75 | |
Nick Mathewson | 2fee12a96a | |
Nick Mathewson | 919286be05 | |
Nick Mathewson | adb7b92ca3 | |
Nick Mathewson | af5454e01c | |
Nick Mathewson | ecc84d8780 | |
Nick Mathewson | db4651469d | |
Nick Mathewson | 29b459a637 | |
Nick Mathewson | 2074984c34 | |
Nick Mathewson | e2ddc8b547 | |
Nick Mathewson | 5bf84b1f00 | |
Nick Mathewson | 7ef22d0bf0 | |
Nick Mathewson | 61d0f65cf0 | |
Nick Mathewson | 1115200d97 | |
Nick Mathewson | ac21fb8c68 | |
Nick Mathewson | 6babd3d9ba | |
Nick Mathewson | 9d35ddf110 | |
Nick Mathewson | 17e67dce81 | |
Nick Mathewson | ee2e3e852a | |
Nick Mathewson | d7eef61147 | |
Nick Mathewson | b05226f05c | |
Nick Mathewson | fd8d526f0d | |
Nick Mathewson | 2894ac304c | |
Nick Mathewson | dc01695810 | |
Nick Mathewson | 5e37c7d780 | |
Nick Mathewson | 44c2973224 | |
Nick Mathewson | 3c6034eaac | |
Nick Mathewson | 8230b0768b | |
Nick Mathewson | c61e919ec2 | |
Nick Mathewson | a040b05890 | |
Nick Mathewson | 3747807333 | |
Nick Mathewson | 931b2dbae5 | |
Nick Mathewson | 77a848b9d4 | |
Nick Mathewson | 8b4ff0168a | |
Nick Mathewson | 4d4e2fc224 | |
Nick Mathewson | 6108499c99 | |
Nick Mathewson | 636b5d19ae | |
Nick Mathewson | f0fa7a3420 | |
Nick Mathewson | c4ecb8f867 | |
Nick Mathewson | efc306c59a | |
Nick Mathewson | cf0124b238 | |
Nick Mathewson | b9c29105f1 | |
Nick Mathewson | bebf7eb54e | |
Nick Mathewson | c515fbc732 | |
Nick Mathewson | 3a5cf9aa2f | |
Nick Mathewson | faa28d40ec | |
Nick Mathewson | 1da84c63eb | |
Nick Mathewson | 526211949e | |
Nick Mathewson | 7ed8037495 | |
Nick Mathewson | ff2c31093a | |
Nick Mathewson | 51d14b3d47 | |
Nick Mathewson | 1dd0be75c2 | |
Nick Mathewson | 882dd4de0b | |
Nick Mathewson | 9944fd92ce | |
Nick Mathewson | 4d5e8378be | |
Nick Mathewson | 47e7a167d2 | |
Nick Mathewson | cbcff6759d | |
Nick Mathewson | f248a4a38e | |
Nick Mathewson | 8e451c5c7c | |
Nick Mathewson | e084fa419a | |
Nick Mathewson | 3938692f32 | |
Nick Mathewson | 4872c28afa | |
Nick Mathewson | 9409d98ee9 | |
Nick Mathewson | ef592d1331 | |
Nick Mathewson | 83389502ee | |
Nick Mathewson | c1b411109e | |
Nick Mathewson | 6ddc4d5e27 | |
Nick Mathewson | 026882fa3d | |
Nick Mathewson | 61ceb26229 | |
Nick Mathewson | 883d1957f6 | |
Nick Mathewson | 09f5077d48 | |
Nick Mathewson | 72aa33c017 | |
Nick Mathewson | 949c62c771 | |
Nick Mathewson | 31417631cb | |
Nick Mathewson | 66801bc90c | |
Nick Mathewson | 2faee019e2 | |
Nick Mathewson | 2e166d8684 | |
Nick Mathewson | 75eaca4e81 | |
Nick Mathewson | 3205700bc4 | |
Nick Mathewson | 8c2ccf9370 | |
Nick Mathewson | a2a5bd83f0 | |
Nick Mathewson | 180e21fbc0 | |
Nick Mathewson | a2d7033195 | |
Nick Mathewson | 4557f3f908 | |
Nick Mathewson | 3ada086d38 | |
Nick Mathewson | 745ffd6d3a | |
Nick Mathewson | f1431f4393 | |
Nick Mathewson | 4db33ecc04 | |
Nick Mathewson | 5eefa43137 | |
Nick Mathewson | 05ca8ab5b6 | |
Nick Mathewson | 11b2d36db3 | |
Nick Mathewson | 4d52b740f9 | |
Nick Mathewson | d5c1b7f185 | |
Nick Mathewson | 9665bad777 | |
Nick Mathewson | 47982cdc09 | |
Nick Mathewson | 0be10dde5a | |
Nick Mathewson | ab1c182127 | |
Nick Mathewson | 251316c5d8 | |
Nick Mathewson | f6a36996db | |
Nick Mathewson | 02030009c5 | |
Nick Mathewson | adae5d3b69 | |
Nick Mathewson | c8e6b2e4bf | |
Nick Mathewson | d9663a2513 | |
Nick Mathewson | fe2a9cb389 | |
Nick Mathewson | 402f4bcef1 | |
Nick Mathewson | ba45eec743 | |
Nick Mathewson | 26c9afc386 | |
Nick Mathewson | fab91a290d | |
Nick Mathewson | 26fd00418c | |
Nick Mathewson | 7377c0bc06 | |
Nick Mathewson | 01de8edd27 | |
Nick Mathewson | 2b393776cf | |
Nick Mathewson | 07862d8435 | |
Nick Mathewson | d9c230e712 | |
Nick Mathewson | 173dc174bf | |
Nick Mathewson | 20a46bdce6 | |
Nick Mathewson | b2ae5fc96b | |
Nick Mathewson | 62c87f857b | |
Nick Mathewson | ce64ab2f09 | |
Nick Mathewson | 27688994a9 | |
Nick Mathewson | 1bf3ef1c28 | |
Nick Mathewson | 403969a3a7 | |
Nick Mathewson | ac89262b1c |
|
@ -1,62 +0,0 @@
|
||||||
version: 1.0.{build}
|
|
||||||
|
|
||||||
clone_depth: 50
|
|
||||||
|
|
||||||
environment:
|
|
||||||
compiler: mingw
|
|
||||||
|
|
||||||
matrix:
|
|
||||||
- target: i686-w64-mingw32
|
|
||||||
compiler_path: mingw32
|
|
||||||
openssl_path: /c/OpenSSL-Win32
|
|
||||||
- target: x86_64-w64-mingw32
|
|
||||||
compiler_path: mingw64
|
|
||||||
openssl_path: /c/OpenSSL-Win64
|
|
||||||
|
|
||||||
install:
|
|
||||||
- ps: >-
|
|
||||||
Function Execute-Command ($commandPath)
|
|
||||||
{
|
|
||||||
& $commandPath $args 2>&1
|
|
||||||
if ( $LastExitCode -ne 0 ) {
|
|
||||||
$host.SetShouldExit( $LastExitCode )
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Function Execute-Bash ()
|
|
||||||
{
|
|
||||||
Execute-Command 'c:\msys64\usr\bin\bash' '-e' '-c' $args
|
|
||||||
}
|
|
||||||
Execute-Command "C:\msys64\usr\bin\pacman" -Sy --noconfirm openssl-devel openssl libevent-devel libevent mingw-w64-i686-libevent mingw-w64-x86_64-libevent mingw-w64-i686-openssl mingw-w64-x86_64-openssl mingw-w64-i686-zstd mingw-w64-x86_64-zstd
|
|
||||||
|
|
||||||
build_script:
|
|
||||||
- ps: >-
|
|
||||||
if ($env:compiler -eq "mingw") {
|
|
||||||
$oldpath = ${env:Path} -split ';'
|
|
||||||
$buildpath = @("C:\msys64\${env:compiler_path}\bin", "C:\msys64\usr\bin") + $oldpath
|
|
||||||
$env:Path = @($buildpath) -join ';'
|
|
||||||
$env:build = @("${env:APPVEYOR_BUILD_FOLDER}", $env:target) -join '\'
|
|
||||||
Set-Location "${env:APPVEYOR_BUILD_FOLDER}"
|
|
||||||
Execute-Bash 'autoreconf -i'
|
|
||||||
mkdir "${env:build}"
|
|
||||||
Set-Location "${env:build}"
|
|
||||||
Execute-Bash "../configure --prefix=/${env:compiler_path} --build=${env:target} --host=${env:target} --disable-asciidoc --enable-fatal-warnings --with-openssl-dir=${env:openssl_path}"
|
|
||||||
Execute-Bash "V=1 make -j2"
|
|
||||||
Execute-Bash "V=1 make -j2 install"
|
|
||||||
}
|
|
||||||
|
|
||||||
test_script:
|
|
||||||
- ps: >-
|
|
||||||
if ($env:compiler -eq "mingw") {
|
|
||||||
$oldpath = ${env:Path} -split ';'
|
|
||||||
$buildpath = @("C:\msys64\${env:compiler_path}\bin") + $oldpath
|
|
||||||
$env:Path = $buildpath -join ';'
|
|
||||||
Set-Location "${env:build}"
|
|
||||||
Execute-Bash "VERBOSE=1 make -j2 check"
|
|
||||||
}
|
|
||||||
|
|
||||||
on_success:
|
|
||||||
- cmd: C:\Python27\python.exe %APPVEYOR_BUILD_FOLDER%\scripts\test\appveyor-irc-notify.py irc.oftc.net:6697 tor-ci success
|
|
||||||
|
|
||||||
on_failure:
|
|
||||||
- cmd: C:\Python27\python.exe %APPVEYOR_BUILD_FOLDER%\scripts\test\appveyor-irc-notify.py irc.oftc.net:6697 tor-ci failure
|
|
||||||
|
|
|
@ -3,7 +3,6 @@
|
||||||
.#*
|
.#*
|
||||||
*~
|
*~
|
||||||
*.swp
|
*.swp
|
||||||
*.swo
|
|
||||||
# C stuff
|
# C stuff
|
||||||
*.o
|
*.o
|
||||||
*.obj
|
*.obj
|
||||||
|
@ -71,7 +70,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
|
||||||
|
@ -212,7 +210,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
|
|
19
.travis.yml
19
.travis.yml
|
@ -66,7 +66,6 @@ env:
|
||||||
## more than one entry causes unwanted matrix entries with
|
## more than one entry causes unwanted matrix entries with
|
||||||
## unspecified compilers.
|
## unspecified compilers.
|
||||||
- RUST_OPTIONS="--enable-rust --enable-cargo-online-mode"
|
- RUST_OPTIONS="--enable-rust --enable-cargo-online-mode"
|
||||||
# - RUST_OPTIONS="--enable-rust" TOR_RUST_DEPENDENCIES=true
|
|
||||||
# - RUST_OPTIONS=""
|
# - RUST_OPTIONS=""
|
||||||
|
|
||||||
matrix:
|
matrix:
|
||||||
|
@ -96,33 +95,21 @@ matrix:
|
||||||
## 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
|
- compiler: gcc
|
||||||
env: RUST_OPTIONS=""
|
env: RUST_OPTIONS=""
|
||||||
- compiler: gcc
|
- compiler: gcc
|
||||||
env: COVERAGE_OPTIONS="--enable-coverage"
|
env: COVERAGE_OPTIONS="--enable-coverage"
|
||||||
- compiler: gcc
|
- compiler: gcc
|
||||||
env: DISTCHECK="yes" RUST_OPTIONS=""
|
env: DISTCHECK="yes"
|
||||||
- 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
|
- compiler: clang
|
||||||
sudo: required
|
sudo: required
|
||||||
env: RUST_OPTIONS=""
|
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
|
||||||
|
@ -148,12 +135,10 @@ install:
|
||||||
- if [[ "$RUST_OPTIONS" != "" ]]; then which cargo; fi
|
- if [[ "$RUST_OPTIONS" != "" ]]; then which cargo; fi
|
||||||
- if [[ "$RUST_OPTIONS" != "" ]]; then rustc --version; fi
|
- if [[ "$RUST_OPTIONS" != "" ]]; then rustc --version; fi
|
||||||
- if [[ "$RUST_OPTIONS" != "" ]]; then cargo --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 $COVERAGE_OPTIONS --disable-asciidoc --enable-fatal-warnings --disable-silent-rules --enable-fragile-hardening
|
||||||
## We run `make check` because that's what https://jenkins.torproject.org does.
|
## We run `make check` because that's what https://jenkins.torproject.org does.
|
||||||
- if [[ "$DISTCHECK" == "" ]]; then make check; fi
|
- if [[ "$DISTCHECK" == "" ]]; then make check; fi
|
||||||
- if [[ "$DISTCHECK" != "" ]]; then make distcheck DISTCHECK_CONFIGURE_FLAGS="$RUST_OPTIONS $COVERAGE_OPTIONS --disable-asciidoc --enable-fatal-warnings --disable-silent-rules --enable-fragile-hardening"; fi
|
- if [[ "$DISTCHECK" != "" ]]; then make distcheck DISTCHECK_CONFIGURE_FLAGS="$RUST_OPTIONS $COVERAGE_OPTIONS --disable-asciidoc --enable-fatal-warnings --disable-silent-rules --enable-fragile-hardening"; fi
|
||||||
|
|
39
CONTRIBUTING
39
CONTRIBUTING
|
@ -1,39 +0,0 @@
|
||||||
Contributing to Tor
|
|
||||||
-------------------
|
|
||||||
|
|
||||||
### Getting started
|
|
||||||
|
|
||||||
Welcome!
|
|
||||||
|
|
||||||
We have a bunch of documentation about how to develop Tor in the
|
|
||||||
doc/HACKING/ directory. We recommend that you start with
|
|
||||||
doc/HACKING/README.1st.md , and then go from there. It will tell
|
|
||||||
you how to find your way around the source code, how to get
|
|
||||||
involved with the Tor community, how to write patches, and much
|
|
||||||
more!
|
|
||||||
|
|
||||||
You don't have to be a C developer to help with Tor: have a look
|
|
||||||
at https://www.torproject.org/getinvolved/volunteer !
|
|
||||||
|
|
||||||
The Tor Project is committed to fostering a inclusive community
|
|
||||||
where people feel safe to engage, share their points of view, and
|
|
||||||
participate. For the latest version of our Code of Conduct, please
|
|
||||||
see
|
|
||||||
|
|
||||||
https://gitweb.torproject.org/community/policies.git/plain/code_of_conduct.txt
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### License issues
|
|
||||||
|
|
||||||
Tor is distributed under the license terms in the LICENSE -- in
|
|
||||||
brief, the "3-clause BSD license". If you send us code to
|
|
||||||
distribute with Tor, it needs to be code that we can distribute
|
|
||||||
under those terms. Please don't send us patches unless you agree
|
|
||||||
to allow this.
|
|
||||||
|
|
||||||
Some compatible licenses include:
|
|
||||||
|
|
||||||
- 3-clause BSD
|
|
||||||
- 2-clause BSD
|
|
||||||
- CC0 Public Domain Dedication
|
|
54
Makefile.am
54
Makefile.am
|
@ -26,8 +26,7 @@ TESTING_TOR_BINARY=$(top_builddir)/src/or/tor$(EXEEXT)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
if USE_RUST
|
if USE_RUST
|
||||||
rust_ldadd=$(top_builddir)/src/rust/target/release/@TOR_RUST_STATIC_NAME@ \
|
rust_ldadd=$(top_builddir)/src/rust/target/release/libtor_util.a
|
||||||
@TOR_RUST_EXTRA_LIBS@
|
|
||||||
else
|
else
|
||||||
rust_ldadd=
|
rust_ldadd=
|
||||||
endif
|
endif
|
||||||
|
@ -38,7 +37,6 @@ include contrib/include.am
|
||||||
|
|
||||||
EXTRA_DIST+= \
|
EXTRA_DIST+= \
|
||||||
ChangeLog \
|
ChangeLog \
|
||||||
CONTRIBUTING \
|
|
||||||
INSTALL \
|
INSTALL \
|
||||||
LICENSE \
|
LICENSE \
|
||||||
Makefile.nmake \
|
Makefile.nmake \
|
||||||
|
@ -52,14 +50,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 +96,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 +117,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 +214,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 \
|
||||||
|
@ -271,10 +241,6 @@ clean-local:
|
||||||
rm -rf $(top_builddir)/src/rust/target
|
rm -rf $(top_builddir)/src/rust/target
|
||||||
rm -rf $(top_builddir)/src/rust/.cargo/registry
|
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
|
# This relies on some internal details of how automake implements
|
||||||
# distcheck. We check two directories because automake-1.15 changed
|
# distcheck. We check two directories because automake-1.15 changed
|
||||||
# from $(distdir)/_build to $(distdir)/_build/sub.
|
# from $(distdir)/_build to $(distdir)/_build/sub.
|
||||||
|
|
3
README
3
README
|
@ -27,6 +27,3 @@ Frequently Asked Questions:
|
||||||
|
|
||||||
To get started working on Tor development:
|
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
|
|
||||||
|
|
2592
ReleaseNotes
2592
ReleaseNotes
File diff suppressed because it is too large
Load Diff
|
@ -1,6 +0,0 @@
|
||||||
o Major bugfixes (security, directory authority, denial-of-service):
|
|
||||||
- Fix a bug that could have allowed an attacker to force a
|
|
||||||
directory authority to use up all its RAM by passing it a
|
|
||||||
maliciously crafted protocol versions string. Fixes bug 25517;
|
|
||||||
bugfix on 0.2.9.4-alpha. This issue is also tracked as
|
|
||||||
TROVE-2018-005.
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
o Minor bugfixes (relay, crash):
|
||||||
|
- Avoid a crash when running with DirPort set but ORPort tuned off.
|
||||||
|
Fixes a case of bug 23693; bugfix on 0.3.1.1-alpha.
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
o Code simplification and refactoring:
|
||||||
|
- Move the list of default directory authorities to their own file for
|
||||||
|
inclusion using the C preprocessor. Closes ticket 24854. Patch by "beastr0".
|
|
@ -0,0 +1,3 @@
|
||||||
|
o Minor bugfixes (Linux seccomp2 sandbox):
|
||||||
|
- Allow the nanosleep() system call, which glibc uses to implement
|
||||||
|
sleep() and usleep(). Fixes bug 24969; bugfix on 0.2.5.1-alpha.
|
|
@ -0,0 +1,3 @@
|
||||||
|
o Minor bugfixes (C correctness):
|
||||||
|
- Fix a very unlikely null pointer dereference. Fixes bug 25629;
|
||||||
|
bugfix on 0.2.9.15. Found by Coverity; this is CID 1430932.
|
|
@ -1,3 +0,0 @@
|
||||||
o Minor bugfixes (onion services):
|
|
||||||
- Fix a bug that blocked the creation of ephemeral v3 onion services. Fixes
|
|
||||||
bug 25939; bugfix on 0.3.4.1-alpha.
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
o Major bugfixes (directory authorities, security):
|
||||||
|
- When directory authorities read a zero-byte bandwidth file, they log
|
||||||
|
a warning with the contents of an uninitialised buffer. Log a warning
|
||||||
|
about the empty file instead.
|
||||||
|
Fixes bug 26007; bugfix on 0.2.2.1-alpha.
|
|
@ -0,0 +1,5 @@
|
||||||
|
o Minor bugfixes (hidden service v3):
|
||||||
|
- When parsing the descriptor signature, look for the token plus an extra
|
||||||
|
white-space at the end. This is more correct but also will allow us to
|
||||||
|
support new fields that might start with "signature". Fixes bug 26069;
|
||||||
|
bugfix on 0.3.0.1-alpha.
|
|
@ -0,0 +1,5 @@
|
||||||
|
o Minor bugfixes (correctness, client):
|
||||||
|
- Upon receiving a malformed connected cell, stop processing the cell
|
||||||
|
immediately. Previously we would mark the connection for close, but
|
||||||
|
continue processing the cell as if the connection were open. Fixes bug
|
||||||
|
26072; bugfix on 0.2.4.7-alpha.
|
|
@ -1,5 +0,0 @@
|
||||||
o Minor bugfixes (test coverage tools):
|
|
||||||
- Update our "cov-diff" script to handle output from the latest
|
|
||||||
version of gcov, and to remove extraneous timestamp information
|
|
||||||
from its output. Fixes bugs 26101 and 26102; bugfix on
|
|
||||||
0.2.5.1-alpha.
|
|
|
@ -1,6 +0,0 @@
|
||||||
o Minor bugfixes (controller):
|
|
||||||
- Improve accuracy of the BUILDTIMEOUT_SET control port event's
|
|
||||||
TIMEOUT_RATE and CLOSE_RATE fields. (We were previously miscounting
|
|
||||||
the total number of circuits for these field values.) Fixes bug
|
|
||||||
26121; bugfix on 0.3.3.1-alpha.
|
|
||||||
|
|
|
@ -1,3 +0,0 @@
|
||||||
o Minor bugfixes (compilation):
|
|
||||||
- Fix compilation when building with OpenSSL 1.1.0 with the
|
|
||||||
"no-deprecated" flag enabled. Fixes bug 26156; bugfix on 0.3.4.1-alpha.
|
|
|
@ -1,4 +0,0 @@
|
||||||
o Minor bugfixes (control port):
|
|
||||||
- Do not count 0-length RELAY_COMMAND_DATA cells as valid data in CIRC_BW
|
|
||||||
events. Previously, such cells were counted entirely in the OVERHEAD
|
|
||||||
field. Now they are not. Fixes bug 26259; bugfix on 0.3.4.1-alpha.
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
o Minor features (continuous integration):
|
||||||
|
- Our Travis CI configuration now integrates with the Coveralls coverage
|
||||||
|
analysis tool. Closes ticket 25818.
|
|
@ -1,4 +0,0 @@
|
||||||
o Documentation:
|
|
||||||
- In code comment, point the reader to the exact section
|
|
||||||
in Tor specification that specifies circuit close error
|
|
||||||
code values. Resolves ticket 25237.
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
o Minor features (sandbox):
|
||||||
|
- Explicitly permit the poll() system call when the Linux seccomp2-based
|
||||||
|
sandbox is enabled: apparently, some versions of libc use poll() when
|
||||||
|
calling getpwnam(). Closes ticket 25313.
|
|
@ -0,0 +1,4 @@
|
||||||
|
o Minor features (geoip):
|
||||||
|
- Update geoip and geoip6 to the March 8 2018 Maxmind GeoLite2
|
||||||
|
Country database. Closes ticket 25469.
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
o Minor features (geoip):
|
||||||
|
- Update geoip and geoip6 to the April 3 2018 Maxmind GeoLite2
|
||||||
|
Country database. Closes ticket 25718.
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
o Minor features (geoip):
|
||||||
|
- Update geoip and geoip6 to the May 1 2018 Maxmind GeoLite2
|
||||||
|
Country database. Closes ticket 26104.
|
||||||
|
|
|
@ -1,4 +0,0 @@
|
||||||
o Minor features (continuous integration):
|
|
||||||
- Add the necessary configuration files for continuous integration
|
|
||||||
testing on Windows, via the Appveyor platform. Closes ticket 25549.
|
|
||||||
Patches from Marcin Cieślak and Isis Lovecruft.
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
o Minor feature (continuous integration):
|
||||||
|
- Update the Travis CI configuration to use the stable Rust
|
||||||
|
channel, now that we have decided to require that. Closes
|
||||||
|
ticket 25714.
|
|
@ -0,0 +1,3 @@
|
||||||
|
o Minor bugfixes (client):
|
||||||
|
- Don't consider Tor running as a client if the ControlPort is open. Fixes
|
||||||
|
bug 26062; bugfix on 0.2.9.4-alpha.
|
|
@ -0,0 +1,4 @@
|
||||||
|
o Minor features (continuous integration):
|
||||||
|
- Our .travis.yml configuration now includes support for testing
|
||||||
|
the results of "make distcheck". (It's not uncommon for "make check" to
|
||||||
|
pass but "make distcheck" to fail.) Closes ticket 25814.
|
334
configure.ac
334
configure.ac
|
@ -4,7 +4,7 @@ dnl Copyright (c) 2007-2017, The Tor Project, Inc.
|
||||||
dnl See LICENSE for licensing information
|
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.1.10-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])
|
||||||
|
|
||||||
|
@ -59,10 +59,6 @@ AC_ARG_ENABLE(rust,
|
||||||
AS_HELP_STRING(--enable-rust, [enable rust integration]))
|
AS_HELP_STRING(--enable-rust, [enable rust integration]))
|
||||||
AC_ARG_ENABLE(cargo-online-mode,
|
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.]))
|
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])
|
||||||
|
@ -111,15 +107,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
|
||||||
|
@ -216,45 +204,6 @@ if test x$enable_event_tracing_debug = xyes; then
|
||||||
AC_DEFINE([TOR_EVENT_TRACING_ENABLED], [1], [Compile the event tracing instrumentation])
|
AC_DEFINE([TOR_EVENT_TRACING_ENABLED], [1], [Compile the event tracing instrumentation])
|
||||||
fi
|
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.)
|
||||||
|
@ -306,12 +255,67 @@ 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
|
dnl List all external rust crates we depend on here. Include the version
|
||||||
rust_crates=" \
|
rust_crates="libc-0.2.22"
|
||||||
digest-0.7.2 \
|
|
||||||
libc-0.2.39 \
|
|
||||||
"
|
|
||||||
AC_SUBST(rust_crates)
|
AC_SUBST(rust_crates)
|
||||||
|
|
||||||
|
if test "x$enable_rust" = "xyes"; then
|
||||||
|
AC_ARG_VAR([RUSTC], [path to the rustc binary])
|
||||||
|
AC_CHECK_PROG([RUSTC], [rustc], [rustc],[no])
|
||||||
|
if test "x$RUSTC" = "xno"; then
|
||||||
|
AC_MSG_ERROR([rustc unavailable but rust integration requested.])
|
||||||
|
fi
|
||||||
|
|
||||||
|
AC_ARG_VAR([CARGO], [path to the cargo binary])
|
||||||
|
AC_CHECK_PROG([CARGO], [cargo], [cargo],[no])
|
||||||
|
if test "x$CARGO" = "xno"; then
|
||||||
|
AC_MSG_ERROR([cargo unavailable but rust integration requested.])
|
||||||
|
fi
|
||||||
|
|
||||||
|
AC_DEFINE([HAVE_RUST], 1, [have Rust])
|
||||||
|
if test "x$enable_cargo_online_mode" = "xyes"; then
|
||||||
|
CARGO_ONLINE=
|
||||||
|
RUST_DL=#
|
||||||
|
else
|
||||||
|
CARGO_ONLINE=--frozen
|
||||||
|
RUST_DL=
|
||||||
|
|
||||||
|
dnl When we're not allowed to touch the network, we need crate dependencies
|
||||||
|
dnl locally available.
|
||||||
|
AC_MSG_CHECKING([rust crate dependencies])
|
||||||
|
AC_ARG_VAR([RUST_DEPENDENCIES], [path to directory with local crate mirror])
|
||||||
|
if test "x$RUST_DEPENDENCIES" = "x"; then
|
||||||
|
RUST_DEPENDENCIES="$srcdir/src/ext/rust/"
|
||||||
|
NEED_MOD=1
|
||||||
|
fi
|
||||||
|
if test ! -d "$RUST_DEPENDENCIES"; then
|
||||||
|
AC_MSG_ERROR([Rust dependency directory $RUST_DEPENDENCIES does not exist. Specify a dependency directory using the RUST_DEPENDENCIES variable or allow cargo to fetch crates using --enable-cargo-online-mode.])
|
||||||
|
fi
|
||||||
|
for dep in $rust_crates; do
|
||||||
|
if test ! -d "$RUST_DEPENDENCIES"/"$dep"; then
|
||||||
|
AC_MSG_ERROR([Failure to find rust dependency $RUST_DEPENDENCIES/$dep. Specify a dependency directory using the RUST_DEPENDENCIES variable or allow cargo to fetch crates using --enable-cargo-online-mode.])
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
if test "x$NEED_MOD" = "x1"; then
|
||||||
|
dnl When looking for dependencies from cargo, pick right directory
|
||||||
|
RUST_DEPENDENCIES="../../src/ext/rust"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
AC_SUBST(CARGO_ONLINE)
|
||||||
|
AC_SUBST(RUST_DL)
|
||||||
|
|
||||||
|
dnl Let's check the rustc version, too
|
||||||
|
AC_MSG_CHECKING([rust version])
|
||||||
|
RUSTC_VERSION_MAJOR=`$RUSTC --version | cut -d ' ' -f 2 | cut -d '.' -f 1`
|
||||||
|
RUSTC_VERSION_MINOR=`$RUSTC --version | cut -d ' ' -f 2 | cut -d '.' -f 2`
|
||||||
|
if test "x$RUSTC_VERSION_MAJOR" = "x" -o "x$RUSTC_VERSION_MINOR" = "x"; then
|
||||||
|
AC_MSG_ERROR([rustc version couldn't be identified])
|
||||||
|
fi
|
||||||
|
if test "$RUSTC_VERSION_MAJOR" -lt 2 -a "$RUSTC_VERSION_MINOR" -lt 14; then
|
||||||
|
AC_MSG_ERROR([rustc must be at least version 1.14])
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
ifdef([AC_C_FLEXIBLE_ARRAY_MEMBER], [
|
ifdef([AC_C_FLEXIBLE_ARRAY_MEMBER], [
|
||||||
AC_C_FLEXIBLE_ARRAY_MEMBER
|
AC_C_FLEXIBLE_ARRAY_MEMBER
|
||||||
], [
|
], [
|
||||||
|
@ -429,7 +433,6 @@ AH_BOTTOM([
|
||||||
|
|
||||||
|
|
||||||
AM_CONDITIONAL(BUILD_NT_SERVICES, test "x$bwin32" = "xtrue")
|
AM_CONDITIONAL(BUILD_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 +451,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,7 +481,6 @@ AC_CHECK_FUNCS(
|
||||||
timingsafe_memcmp \
|
timingsafe_memcmp \
|
||||||
flock \
|
flock \
|
||||||
ftime \
|
ftime \
|
||||||
get_current_dir_name \
|
|
||||||
getaddrinfo \
|
getaddrinfo \
|
||||||
getifaddrs \
|
getifaddrs \
|
||||||
getpass \
|
getpass \
|
||||||
|
@ -578,10 +495,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 +523,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 +565,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 +574,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 +607,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 +710,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 +780,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"
|
||||||
|
@ -1016,16 +870,6 @@ if test "x$have_zstd" = "xyes"; then
|
||||||
AC_DEFINE(HAVE_ZSTD,1,[Have Zstd])
|
AC_DEFINE(HAVE_ZSTD,1,[Have Zstd])
|
||||||
TOR_ZSTD_CFLAGS="${ZSTD_CFLAGS}"
|
TOR_ZSTD_CFLAGS="${ZSTD_CFLAGS}"
|
||||||
TOR_ZSTD_LIBS="${ZSTD_LIBS}"
|
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
|
fi
|
||||||
AC_SUBST(TOR_ZSTD_CFLAGS)
|
AC_SUBST(TOR_ZSTD_CFLAGS)
|
||||||
AC_SUBST(TOR_ZSTD_LIBS)
|
AC_SUBST(TOR_ZSTD_LIBS)
|
||||||
|
@ -1050,7 +894,7 @@ dnl since sometimes the linker will like an option but not be willing to
|
||||||
dnl use it with a build of a library.
|
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 +944,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])
|
||||||
|
@ -1346,7 +1190,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 +1554,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 +1603,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 +1748,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 +1929,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 +1955,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
|
||||||
|
|
|
@ -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.1.10-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"
|
||||||
|
|
|
@ -6,8 +6,8 @@ tl;dr:
|
||||||
- Run configure with `--enable-fatal-warnings`
|
- Run configure with `--enable-fatal-warnings`
|
||||||
- Document your functions
|
- Document your functions
|
||||||
- Write unit tests
|
- Write unit tests
|
||||||
- Run `make check` before submitting a patch
|
- Run `make test-full` to test against all unit and integration tests.
|
||||||
- Run `make distcheck` if you have made changes to build system components
|
- Run `make distcheck` to ensure the distribution works
|
||||||
- Add a file in `changes` for your branch.
|
- Add a file in `changes` for your branch.
|
||||||
|
|
||||||
Patch checklist
|
Patch checklist
|
||||||
|
@ -32,33 +32,6 @@ Did you remember...
|
||||||
- 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 +52,8 @@ before it gets merged into maint, but that's rare.
|
||||||
|
|
||||||
If you're working on a bugfix for a bug that occurs in a particular version,
|
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 +77,17 @@ you can use `git describe --contains <sha1 of commit>`.
|
||||||
If at all possible, try to create this file in the same commit where you are
|
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 +156,6 @@ old C functions. Use `strlcat`, `strlcpy`, or `tor_snprintf/tor_asprintf` inste
|
||||||
We don't call `memcmp()` directly. Use `fast_memeq()`, `fast_memneq()`,
|
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 +217,6 @@ end-users that they aren't expected to understand the message (perhaps
|
||||||
with a string like "internal error"). Option (A) is to be preferred to
|
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 +250,3 @@ the functions that call your function rely on it doing something, then your
|
||||||
function should mention that it does that something in the documentation. If
|
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
|
||||||
-------------------------
|
-------------------------
|
||||||
|
|
|
@ -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,24 +26,19 @@ new Tor release:
|
||||||
|
|
||||||
What about Coverity Scan?
|
What about Coverity Scan?
|
||||||
|
|
||||||
What about clang scan-build?
|
|
||||||
|
|
||||||
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.
|
||||||
|
|
||||||
|
@ -96,15 +83,6 @@ new Tor release:
|
||||||
|
|
||||||
4. Run `./scripts/maint/format_changelog.py --inplace` to make it prettier
|
4. Run `./scripts/maint/format_changelog.py --inplace` to make it prettier
|
||||||
|
|
||||||
1b. (old-stable release variant)
|
|
||||||
|
|
||||||
For stable releases that backport things from later, we try to compose
|
|
||||||
their releases, we try to make sure that we keep the changelog entries
|
|
||||||
identical to their original versions, with a 'backport from 0.x.y.z'
|
|
||||||
note added to each section. So in this case, once you have the items
|
|
||||||
from the changes files copied together, don't use them to build a new
|
|
||||||
changelog: instead, look up the corrected versions that were merged
|
|
||||||
into ChangeLog in the master branch, and use those.
|
|
||||||
|
|
||||||
2. Compose a short release blurb to highlight the user-facing
|
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
|
||||||
|
@ -131,16 +109,13 @@ 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.?.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.?.x` into `release-0.?.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
|
|
||||||
master, merge it with "-s ours" to avoid a needless version bump.
|
|
||||||
|
|
||||||
2. Make distcheck, put the tarball up in somewhere (how about your
|
2. Make distcheck, put the tarball up in somewhere (how about your
|
||||||
homedir on your homedir on people.torproject.org?) , and tell `#tor`
|
homedir on your homedir on people.torproject.org?) , and tell `#tor`
|
||||||
about it. Wait a while to see if anybody has problems building it.
|
about it. Wait a while to see if anybody has problems building it.
|
||||||
|
@ -154,9 +129,6 @@ new Tor release:
|
||||||
git tag -u <keyid> tor-0.3.x.y-status
|
git tag -u <keyid> tor-0.3.x.y-status
|
||||||
git push origin tag tor-0.3.x.y-status
|
git push origin tag tor-0.3.x.y-status
|
||||||
|
|
||||||
(You must do this before you update the website: it relies on finding
|
|
||||||
the version by tag.)
|
|
||||||
|
|
||||||
2. scp the tarball and its sig to the dist website, i.e.
|
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"
|
||||||
|
@ -175,16 +147,10 @@ new Tor release:
|
||||||
- {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
|
||||||
- {simon} at sdeziel.info
|
|
||||||
- {yuri} at freebsd.org
|
|
||||||
- {mh+tor} at scrit.ch
|
|
||||||
|
|
||||||
Also, email tor-packagers@lists.torproject.org.
|
|
||||||
|
|
||||||
4. Add the version number to Trac. To do this, go to Trac, log in,
|
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,14 +159,10 @@ 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.
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@ tracing framework.
|
||||||
|
|
||||||
## Basics ###
|
## Basics ###
|
||||||
|
|
||||||
Event tracing is separated in two concepts, trace events and a tracer. The
|
Event tracing is seperated in two concepts, trace events and a tracer. The
|
||||||
tracing subsystem can be found in `src/trace`. The `events.h` header file is
|
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.
|
the main file that maps the different tracers to trace events.
|
||||||
|
|
||||||
|
|
|
@ -91,9 +91,6 @@ coverage percentage.
|
||||||
For a summary of the test coverage for each _function_, run
|
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@
|
||||||
|
|
1066
doc/tor.1.txt
1066
doc/tor.1.txt
File diff suppressed because it is too large
Load Diff
|
@ -18,10 +18,9 @@ does, not what it should do.
|
||||||
; specified in RFC5234.
|
; 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
|
||||||
|
|
|
@ -1,6 +0,0 @@
|
||||||
@@
|
|
||||||
expression n, d;
|
|
||||||
@@
|
|
||||||
|
|
||||||
- (((n) + (d) - 1) / (d))
|
|
||||||
+ CEIL_DIV(n, d)
|
|
|
@ -1,11 +0,0 @@
|
||||||
#!/usr/bin/perl -w -p -i
|
|
||||||
|
|
||||||
next if m#^ */\*# or m#^ *\* #;
|
|
||||||
|
|
||||||
s/<([,)])/OP_LT$1/;
|
|
||||||
s/(?<=[\s,])>([,)])/OP_GT$1/;
|
|
||||||
#s/>([,)])/OP_GT$1/;
|
|
||||||
s/==([,)])/OP_EQ$1/;
|
|
||||||
s/>=([,)])/OP_GE$1/;
|
|
||||||
s/<=([,)])/OP_LE$1/;
|
|
||||||
s/!=([,)])/OP_NE$1/;
|
|
|
@ -1,49 +0,0 @@
|
||||||
@@
|
|
||||||
int e;
|
|
||||||
constant c;
|
|
||||||
@@
|
|
||||||
|
|
||||||
(
|
|
||||||
- tt_assert(e == c)
|
|
||||||
+ tt_int_op(e, OP_EQ, c)
|
|
||||||
|
|
|
||||||
- tt_assert(e != c)
|
|
||||||
+ tt_int_op(e, OP_NE, c)
|
|
||||||
|
|
|
||||||
- tt_assert(e < c)
|
|
||||||
+ tt_int_op(e, OP_LT, c)
|
|
||||||
|
|
|
||||||
- tt_assert(e <= c)
|
|
||||||
+ tt_int_op(e, OP_LE, c)
|
|
||||||
|
|
|
||||||
- tt_assert(e > c)
|
|
||||||
+ tt_int_op(e, OP_GT, c)
|
|
||||||
|
|
|
||||||
- tt_assert(e >= c)
|
|
||||||
+ tt_int_op(e, OP_GE, c)
|
|
||||||
)
|
|
||||||
|
|
||||||
@@
|
|
||||||
unsigned int e;
|
|
||||||
constant c;
|
|
||||||
@@
|
|
||||||
|
|
||||||
(
|
|
||||||
- tt_assert(e == c)
|
|
||||||
+ tt_uint_op(e, OP_EQ, c)
|
|
||||||
|
|
|
||||||
- tt_assert(e != c)
|
|
||||||
+ tt_uint_op(e, OP_NE, c)
|
|
||||||
|
|
|
||||||
- tt_assert(e < c)
|
|
||||||
+ tt_uint_op(e, OP_LT, c)
|
|
||||||
|
|
|
||||||
- tt_assert(e <= c)
|
|
||||||
+ tt_uint_op(e, OP_LE, c)
|
|
||||||
|
|
|
||||||
- tt_assert(e > c)
|
|
||||||
+ tt_uint_op(e, OP_GT, c)
|
|
||||||
|
|
|
||||||
- tt_assert(e >= c)
|
|
||||||
+ tt_uint_op(e, OP_GE, c)
|
|
||||||
)
|
|
|
@ -1,11 +0,0 @@
|
||||||
@@
|
|
||||||
expression * e;
|
|
||||||
@@
|
|
||||||
|
|
||||||
(
|
|
||||||
- tt_assert(e != NULL)
|
|
||||||
+ tt_ptr_op(e, OP_NE, NULL)
|
|
||||||
|
|
|
||||||
- tt_assert(e == NULL)
|
|
||||||
+ tt_ptr_op(e, OP_EQ, NULL)
|
|
||||||
)
|
|
|
@ -1,5 +0,0 @@
|
||||||
@@
|
|
||||||
@@
|
|
||||||
|
|
||||||
- tt_assert(0)
|
|
||||||
+ tt_abort()
|
|
|
@ -7,9 +7,7 @@ FUZZERS = """
|
||||||
diff-apply
|
diff-apply
|
||||||
extrainfo
|
extrainfo
|
||||||
hsdescv2
|
hsdescv2
|
||||||
hsdescv3
|
|
||||||
http
|
http
|
||||||
http-connect
|
|
||||||
iptsv2
|
iptsv2
|
||||||
microdesc
|
microdesc
|
||||||
vrs
|
vrs
|
||||||
|
@ -32,14 +30,13 @@ FUZZING_LIBS = \
|
||||||
src/common/libor-ctime-testing.a \
|
src/common/libor-ctime-testing.a \
|
||||||
src/common/libor-event-testing.a \
|
src/common/libor-event-testing.a \
|
||||||
src/trunnel/libor-trunnel-testing.a \
|
src/trunnel/libor-trunnel-testing.a \
|
||||||
$(rust_ldadd) \
|
|
||||||
@TOR_ZLIB_LIBS@ @TOR_LIB_MATH@ \
|
@TOR_ZLIB_LIBS@ @TOR_LIB_MATH@ \
|
||||||
@TOR_LIBEVENT_LIBS@ \
|
@TOR_LIBEVENT_LIBS@ \
|
||||||
@TOR_OPENSSL_LIBS@ @TOR_LIB_WS32@ @TOR_LIB_GDI@ @TOR_LIB_USERENV@ \
|
@TOR_OPENSSL_LIBS@ @TOR_LIB_WS32@ @TOR_LIB_GDI@ @CURVE25519_LIBS@ \
|
||||||
@CURVE25519_LIBS@ \
|
|
||||||
@TOR_SYSTEMD_LIBS@ \
|
@TOR_SYSTEMD_LIBS@ \
|
||||||
@TOR_LZMA_LIBS@ \
|
@TOR_LZMA_LIBS@ \
|
||||||
@TOR_ZSTD_LIBS@
|
@TOR_ZSTD_LIBS@ \
|
||||||
|
$(rust_ldadd)
|
||||||
|
|
||||||
oss-fuzz-prereqs: \
|
oss-fuzz-prereqs: \
|
||||||
src/or/libtor-testing.a \
|
src/or/libtor-testing.a \
|
||||||
|
|
|
@ -1,74 +0,0 @@
|
||||||
#!/usr/bin/python
|
|
||||||
# Copyright (c) 2017, The Tor Project, Inc.
|
|
||||||
# See LICENSE for licensing information
|
|
||||||
|
|
||||||
import re
|
|
||||||
|
|
||||||
LINE_OBVIOUSNESS_LIMIT = 4
|
|
||||||
|
|
||||||
class Problem(Exception):
|
|
||||||
pass
|
|
||||||
|
|
||||||
def uncomment(s):
|
|
||||||
s = re.sub(r'//.*','',s)
|
|
||||||
s = re.sub(r'/\*.*','',s)
|
|
||||||
return s.strip()
|
|
||||||
|
|
||||||
def translate(f_in, f_out):
|
|
||||||
whole_file = []
|
|
||||||
stack = []
|
|
||||||
cur_level = whole_file
|
|
||||||
lineno = 0
|
|
||||||
for line in f_in:
|
|
||||||
lineno += 1
|
|
||||||
m = re.match(r'\s*#\s*(if|ifdef|ifndef|else|endif|elif)\b\s*(.*)',
|
|
||||||
line)
|
|
||||||
if not m:
|
|
||||||
f_out.write(line)
|
|
||||||
continue
|
|
||||||
command,rest = m.groups()
|
|
||||||
if command in ("if", "ifdef", "ifndef"):
|
|
||||||
# The #if directive pushes us one level lower on the stack.
|
|
||||||
if command == 'ifdef':
|
|
||||||
rest = "defined(%s)"%uncomment(rest)
|
|
||||||
elif command == 'ifndef':
|
|
||||||
rest = "!defined(%s)"%uncomment(rest)
|
|
||||||
elif rest.endswith("\\"):
|
|
||||||
rest = rest[:-1]+"..."
|
|
||||||
|
|
||||||
rest = uncomment(rest)
|
|
||||||
|
|
||||||
new_level = [ (command, rest, lineno) ]
|
|
||||||
stack.append(cur_level)
|
|
||||||
cur_level = new_level
|
|
||||||
f_out.write(line)
|
|
||||||
elif command in ("else", "elif"):
|
|
||||||
if len(cur_level) == 0 or cur_level[-1][0] == 'else':
|
|
||||||
raise Problem("Unexpected #%s on %d"% (command,lineno))
|
|
||||||
if (len(cur_level) == 1 and command == 'else' and
|
|
||||||
lineno > cur_level[0][2] + LINE_OBVIOUSNESS_LIMIT):
|
|
||||||
f_out.write("#else /* !(%s) */\n"%cur_level[0][1])
|
|
||||||
else:
|
|
||||||
f_out.write(line)
|
|
||||||
cur_level.append((command, rest, lineno))
|
|
||||||
else:
|
|
||||||
assert command == 'endif'
|
|
||||||
if len(stack) == 0:
|
|
||||||
raise Problem("Unmatched #%s on %s"% (command,lineno))
|
|
||||||
if lineno <= cur_level[0][2] + LINE_OBVIOUSNESS_LIMIT:
|
|
||||||
f_out.write(line)
|
|
||||||
elif len(cur_level) == 1 or (
|
|
||||||
len(cur_level) == 2 and cur_level[1][0] == 'else'):
|
|
||||||
f_out.write("#endif /* %s */\n"%cur_level[0][1])
|
|
||||||
else:
|
|
||||||
f_out.write("#endif /* %s || ... */\n"%cur_level[0][1])
|
|
||||||
cur_level = stack.pop()
|
|
||||||
if len(stack) or cur_level != whole_file:
|
|
||||||
raise Problem("Missing #endif")
|
|
||||||
|
|
||||||
import sys,os
|
|
||||||
for fn in sys.argv[1:]:
|
|
||||||
with open(fn+"_OUT", 'w') as output_file:
|
|
||||||
translate(open(fn, 'r'), output_file)
|
|
||||||
os.rename(fn+"_OUT", fn)
|
|
||||||
|
|
|
@ -123,10 +123,6 @@ for my $fn (@ARGV) {
|
||||||
if (/([^\s'])\{/) {
|
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";
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
@ -214,6 +256,9 @@
|
||||||
# Email sent directly to teor, verified using relay contact info
|
# Email sent directly to teor, verified using relay contact info
|
||||||
104.243.35.196:9030 orport=9001 id=FA3415659444AE006E7E9E5375E82F29700CFDFD
|
104.243.35.196:9030 orport=9001 id=FA3415659444AE006E7E9E5375E82F29700CFDFD
|
||||||
|
|
||||||
|
# Relay changed IPv4 address, operator uncontactable
|
||||||
|
138.201.130.32:9030 orport=9001 id=52AEA31188331F421B2EDB494DB65CD181E5B257
|
||||||
|
|
||||||
# Emails sent directly to teor, verified using relay contact info
|
# 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
|
217.12.199.208:80 orport=443 id=DF3AED4322B1824BF5539AE54B2D1B38E080FF05 ipv6=[2a02:27a8:0:2::7e]:443
|
||||||
|
|
||||||
|
@ -224,9 +269,6 @@
|
||||||
# Email sent directly to teor, verified using relay contact info
|
# Email sent directly to teor, verified using relay contact info
|
||||||
5.35.251.247:9030 orport=9001 id=9B1F5187DFBA89DC24B37EA7BF896C12B43A27AE
|
5.35.251.247:9030 orport=9001 id=9B1F5187DFBA89DC24B37EA7BF896C12B43A27AE
|
||||||
|
|
||||||
#https://lists.torproject.org/pipermail/tor-relays/2017-May/012281.html
|
#https://lists.torproject.org/pipermail/tor-relays/2017-May/012281.html
|
||||||
62.210.124.124:9030 orport=9001 id=86E78DD3720C78DA8673182EF96C54B162CD660C ipv6=[2001:bc8:3f23:100::1]:9001
|
62.210.124.124: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
|
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
|
||||||
|
@ -55,21 +52,17 @@
|
||||||
|
|
||||||
# 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
|
91.121.84.137:4952 orport=4052 id=9FBEB75E8BC142565F12CBBE078D63310236A334 ipv6=[2001:41d0:1:8989::1]:4052
|
||||||
|
|
||||||
# https://lists.torproject.org/pipermail/tor-relays/2015-December/008381.html
|
# 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
|
||||||
|
@ -104,9 +97,12 @@
|
||||||
# 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 +110,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 +151,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 +205,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 +229,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 +247,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 +298,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
|
||||||
|
@ -377,6 +368,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 +404,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
|
||||||
|
@ -477,6 +476,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 +497,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 +536,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 +545,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
|
||||||
|
@ -578,8 +580,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 +609,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,8 +623,8 @@
|
||||||
|
|
||||||
# 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
|
||||||
|
@ -682,8 +680,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 +698,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 +767,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
|
||||||
|
@ -846,151 +818,12 @@
|
||||||
# Email sent directly to teor, verified using relay contact info
|
# Email sent directly to teor, verified using relay contact info
|
||||||
85.214.151.72:9030 orport=9001 id=722D365140C8C52DBB3C9FF6986E3CEFFE2BA812
|
85.214.151.72:9030 orport=9001 id=722D365140C8C52DBB3C9FF6986E3CEFFE2BA812
|
||||||
|
|
||||||
# email sent directly to teor
|
# Email sent directly to teor, verified using relay contact info
|
||||||
72.52.75.27:9030 orport=9001 id=8567AD0A6369ED08527A8A8533A5162AC00F7678 # piecoopdotnet
|
72.52.75.27:9030 orport=9001 id=1220F0F20E80D348244C5F3B6D126DAA0A446DFD
|
||||||
|
|
||||||
# Email sent directly to teor, verified using relay contact info
|
# Email sent directly to teor, verified using relay contact info
|
||||||
5.9.146.203:80 orport=443 id=1F45542A24A61BF9408F1C05E0DCE4E29F2CBA11
|
5.9.146.203:80 orport=443 id=1F45542A24A61BF9408F1C05E0DCE4E29F2CBA11
|
||||||
5.9.159.14:9030 orport=9001 id=0F100F60C7A63BED90216052324D29B08CFCF797
|
5.9.159.14:9030 orport=9001 id=0F100F60C7A63BED90216052324D29B08CFCF797
|
||||||
|
|
||||||
# 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
|
5.9.147.226:9030 orport=9001 id=B0553175AADB0501E5A61FC61CEA3970BE130FF2
|
||||||
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,38 +0,0 @@
|
||||||
#!/usr/bin/env python
|
|
||||||
|
|
||||||
# Generate a fallback directory whitelist/blacklist line for every fingerprint
|
|
||||||
# passed as an argument.
|
|
||||||
#
|
|
||||||
# Usage:
|
|
||||||
# generateFallbackDirLine.py fingerprint ...
|
|
||||||
|
|
||||||
import sys
|
|
||||||
import urllib2
|
|
||||||
|
|
||||||
import stem.descriptor.remote
|
|
||||||
import stem.util.tor_tools
|
|
||||||
|
|
||||||
if len(sys.argv) <= 1:
|
|
||||||
print('Usage: %s fingerprint ...' % sys.argv[0])
|
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
for fingerprint in sys.argv[1:]:
|
|
||||||
if not stem.util.tor_tools.is_valid_fingerprint(fingerprint):
|
|
||||||
print("'%s' isn't a valid relay fingerprint" % fingerprint)
|
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
try:
|
|
||||||
desc = stem.descriptor.remote.get_server_descriptors(fingerprint).run()[0]
|
|
||||||
except urllib2.HTTPError as exc:
|
|
||||||
if exc.code == 404:
|
|
||||||
print('# %s not found in recent descriptors' % fingerprint)
|
|
||||||
continue
|
|
||||||
else:
|
|
||||||
raise
|
|
||||||
|
|
||||||
if not desc.dir_port:
|
|
||||||
print("# %s needs a DirPort" % fingerprint)
|
|
||||||
else:
|
|
||||||
ipv6_addresses = [(address, port) for address, port, is_ipv6 in desc.or_addresses if is_ipv6]
|
|
||||||
ipv6_field = ' ipv6=[%s]:%s' % ipv6_addresses[0] if ipv6_addresses else ''
|
|
||||||
print('%s:%s orport=%s id=%s%s # %s' % (desc.address, desc.dir_port, desc.or_port, fingerprint, ipv6_field, desc.nickname))
|
|
|
@ -17,23 +17,12 @@ KNOWN_GROUPS = set([
|
||||||
"Major feature",
|
"Major feature",
|
||||||
"Major features",
|
"Major features",
|
||||||
"New system requirements",
|
"New system requirements",
|
||||||
|
"New dependencies",
|
||||||
"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 +47,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 +63,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)
|
|
|
@ -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,12 +1,12 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/python
|
||||||
|
|
||||||
# Usage:
|
# Usage:
|
||||||
#
|
#
|
||||||
# Regenerate the list:
|
# Regenerate the list:
|
||||||
# scripts/maint/updateFallbackDirs.py > src/or/fallback_dirs.inc 2> fallback_dirs.log
|
# scripts/maint/updateFallbackDirs.py > src/or/fallback_dirs.inc
|
||||||
#
|
#
|
||||||
# Check the existing list:
|
# Check the existing list:
|
||||||
# scripts/maint/updateFallbackDirs.py check_existing > fallback_dirs.inc.ok 2> fallback_dirs.log
|
# scripts/maint/updateFallbackDirs.py check_existing > fallback_dirs.inc.ok
|
||||||
# mv fallback_dirs.inc.ok src/or/fallback_dirs.inc
|
# 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,
|
||||||
|
@ -14,12 +14,14 @@
|
||||||
# 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 +47,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 +68,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 +98,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
|
||||||
|
@ -170,24 +160,25 @@ MAX_LIST_FILE_SIZE = 1024 * 1024
|
||||||
|
|
||||||
# Require fallbacks to have the same address and port for a set amount of time
|
# 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
|
# 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
|
# meant that we had to rebuild the list more often.
|
||||||
# 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 = 30
|
||||||
# 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
|
# Tolerate lower guard flag averages, as guard flags are removed for some time
|
||||||
# Guard flags are removed for some time after a relay restarts, so we ignore
|
# after a relay restarts
|
||||||
# the guard flag.
|
CUTOFF_GUARD = .80
|
||||||
CUTOFF_GUARD = .00
|
# What time-weighted-fraction of these flags must FallbackDirs
|
||||||
# FallbackDirs must have a time-weighted-fraction that is less than or equal
|
# Equal or Fall Under?
|
||||||
# to:
|
|
||||||
# .00 means no bad exits
|
# .00 means no bad exits
|
||||||
PERMITTED_BADEXIT = .00
|
PERMITTED_BADEXIT = .00
|
||||||
|
|
||||||
|
@ -210,23 +201,17 @@ MAX_FALLBACK_COUNT = None if OUTPUT_CANDIDATES else 200
|
||||||
MIN_FALLBACK_COUNT = 0 if OUTPUT_CANDIDATES else MAX_FALLBACK_COUNT*0.5
|
MIN_FALLBACK_COUNT = 0 if OUTPUT_CANDIDATES else MAX_FALLBACK_COUNT*0.5
|
||||||
|
|
||||||
# The maximum number of fallbacks on the same address, contact, or family
|
# 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 +219,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 +235,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 +289,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 +309,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 +547,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 +570,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 +1335,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 +1357,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 +1550,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 +1745,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 +1904,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 +1914,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 +1992,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 +2019,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 +2123,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 +2188,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 +2196,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 +2210,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
|
||||||
|
|
||||||
|
|
|
@ -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 ??
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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 */
|
||||||
|
@ -1199,8 +1197,8 @@ tor_addr_hash(const tor_addr_t *addr)
|
||||||
return siphash24g(unspec_hash_input, sizeof(unspec_hash_input));
|
return siphash24g(unspec_hash_input, sizeof(unspec_hash_input));
|
||||||
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:
|
default:
|
||||||
|
/* LCOV_EXCL_START */
|
||||||
tor_fragile_assert();
|
tor_fragile_assert();
|
||||||
return 0;
|
return 0;
|
||||||
/* LCOV_EXCL_STOP */
|
/* LCOV_EXCL_STOP */
|
||||||
|
@ -1436,7 +1434,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 +1525,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 +1538,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 +1624,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 +1683,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 +1726,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 +1782,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,7 +1804,7 @@ 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,
|
||||||
|
|
|
@ -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));
|
||||||
|
@ -325,8 +323,13 @@ int addr_mask_get_bits(uint32_t mask);
|
||||||
int tor_inet_ntoa(const struct in_addr *in, char *buf, size_t buf_len);
|
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 +360,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
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
#include "address.h"
|
#include "address.h"
|
||||||
#include "compat.h"
|
#include "compat.h"
|
||||||
#include "container.h"
|
#include "container.h"
|
||||||
#include "crypto_rand.h"
|
#include "crypto.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "siphash.h"
|
#include "siphash.h"
|
||||||
|
|
||||||
|
@ -34,7 +34,7 @@
|
||||||
* independent siphashes rather than messing around with bit-shifts. The
|
* independent siphashes rather than messing around with bit-shifts. The
|
||||||
* approach here is probably more sound, and we should prefer it if&when we
|
* approach here is probably more sound, and we should prefer it if&when we
|
||||||
* unify the implementations.
|
* unify the implementations.
|
||||||
*/
|
**/
|
||||||
|
|
||||||
struct address_set_t {
|
struct address_set_t {
|
||||||
/** siphash keys to make N_HASHES independent hashes for each address. */
|
/** siphash keys to make N_HASHES independent hashes for each address. */
|
||||||
|
@ -63,7 +63,7 @@ address_set_new(int max_addresses_guess)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Release all storage associated with <b>set</b>.
|
* Release all storage associated with <b>set</b>
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
address_set_free(address_set_t *set)
|
address_set_free(address_set_t *set)
|
||||||
|
@ -107,7 +107,7 @@ address_set_add_ipv4h(address_set_t *set, uint32_t addr)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return true if <b>addr</b> is a member of <b>set</b>. (And probably,
|
* Return true if <b>addr</b> if a member of <b>set</b>. (And probably,
|
||||||
* return false if <b>addr</b> is not a member of set.)
|
* return false if <b>addr</b> is not a member of set.)
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
/* See LICENSE for licensing information */
|
/* See LICENSE for licensing information */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \file address_set.h
|
* \file addressset.h
|
||||||
* \brief Types to handle sets of addresses.
|
* \brief Types to handle sets of addresses.
|
||||||
*
|
*
|
||||||
* This module was first written on a semi-emergency basis to improve the
|
* This module was first written on a semi-emergency basis to improve the
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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) */
|
|
||||||
|
|
|
@ -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
|
||||||
|
@ -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) {
|
||||||
|
@ -1735,7 +1755,7 @@ set_max_file_descriptors(rlim_t limit, int *max_out)
|
||||||
couldnt_set = 0;
|
couldnt_set = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif /* defined(OPEN_MAX) */
|
#endif /* OPEN_MAX */
|
||||||
if (couldnt_set) {
|
if (couldnt_set) {
|
||||||
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(setrlimit_errno));
|
||||||
|
@ -1743,7 +1763,7 @@ set_max_file_descriptors(rlim_t limit, int *max_out)
|
||||||
}
|
}
|
||||||
/* 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;
|
||||||
}
|
}
|
||||||
|
@ -2698,7 +2699,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 +2761,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 +2822,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 +2861,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 +2985,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 +3028,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 +3061,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 +3086,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 +3107,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 +3138,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 +3214,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 +3240,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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3279,9 +3276,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 +3287,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 +3295,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 +3328,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 +3369,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 +3402,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 +3483,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 +3523,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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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,7 +411,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(timersub) */
|
#endif
|
||||||
|
|
||||||
#ifndef timercmp
|
#ifndef timercmp
|
||||||
/** Replacement for timercmp on platforms that do not have it: returns true
|
/** Replacement for timercmp on platforms that do not have it: returns true
|
||||||
|
@ -432,7 +425,7 @@ struct tm *tor_gmtime_r(const time_t *timep, struct tm *result);
|
||||||
(((tv1)->tv_sec == (tv2)->tv_sec) ? \
|
(((tv1)->tv_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
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
#define COMPAT_LIBEVENT_PRIVATE
|
#define COMPAT_LIBEVENT_PRIVATE
|
||||||
#include "compat_libevent.h"
|
#include "compat_libevent.h"
|
||||||
|
|
||||||
#include "crypto_rand.h"
|
#include "crypto.h"
|
||||||
|
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "torlog.h"
|
#include "torlog.h"
|
||||||
|
@ -69,7 +69,7 @@ suppress_libevent_log_msg(const char *msg)
|
||||||
|
|
||||||
/* Wrapper for event_free() that tolerates tor_event_free(NULL) */
|
/* Wrapper for event_free() that tolerates tor_event_free(NULL) */
|
||||||
void
|
void
|
||||||
tor_event_free_(struct event *ev)
|
tor_event_free(struct event *ev)
|
||||||
{
|
{
|
||||||
if (ev == NULL)
|
if (ev == NULL)
|
||||||
return;
|
return;
|
||||||
|
@ -79,43 +79,6 @@ tor_event_free_(struct event *ev)
|
||||||
/** Global event base for use by the main thread. */
|
/** Global event base for use by the main thread. */
|
||||||
static struct event_base *the_event_base = NULL;
|
static struct event_base *the_event_base = NULL;
|
||||||
|
|
||||||
/**
|
|
||||||
* @defgroup postloop post-loop event helpers
|
|
||||||
*
|
|
||||||
* If we're not careful, Libevent can susceptible to infinite event chains:
|
|
||||||
* one event can activate another, whose callback activates another, whose
|
|
||||||
* callback activates another, ad infinitum. While this is happening,
|
|
||||||
* Libevent won't be checking timeouts, socket-based events, signals, and so
|
|
||||||
* on.
|
|
||||||
*
|
|
||||||
* We solve this problem by marking some events as "post-loop". A post-loop
|
|
||||||
* event behaves like any ordinary event, but any events that _it_ activates
|
|
||||||
* cannot run until Libevent has checked for other events at least once.
|
|
||||||
*
|
|
||||||
* @{ */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* An event that stops Libevent from running any more events on the current
|
|
||||||
* iteration of its loop, until it has re-checked for socket events, signal
|
|
||||||
* events, timeouts, etc.
|
|
||||||
*/
|
|
||||||
static struct event *rescan_mainloop_ev = NULL;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Callback to implement rescan_mainloop_ev: it simply exits the mainloop,
|
|
||||||
* and relies on Tor to re-enter the mainloop since no error has occurred.
|
|
||||||
*/
|
|
||||||
static void
|
|
||||||
rescan_mainloop_cb(evutil_socket_t fd, short events, void *arg)
|
|
||||||
{
|
|
||||||
(void)fd;
|
|
||||||
(void)events;
|
|
||||||
struct event_base *the_base = arg;
|
|
||||||
event_base_loopbreak(the_base);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @} */
|
|
||||||
|
|
||||||
/* This is what passes for version detection on OSX. We set
|
/* This is what passes for version detection on OSX. We set
|
||||||
* MACOSX_KQUEUE_IS_BROKEN to true iff we're on a version of OSX before
|
* MACOSX_KQUEUE_IS_BROKEN to true iff we're on a version of OSX before
|
||||||
* 10.4.0 (aka 1040). */
|
* 10.4.0 (aka 1040). */
|
||||||
|
@ -125,8 +88,8 @@ rescan_mainloop_cb(evutil_socket_t fd, short events, void *arg)
|
||||||
(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 1040)
|
(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 1040)
|
||||||
#else
|
#else
|
||||||
#define MACOSX_KQUEUE_IS_BROKEN 0
|
#define MACOSX_KQUEUE_IS_BROKEN 0
|
||||||
#endif /* defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) */
|
#endif
|
||||||
#endif /* defined(__APPLE__) */
|
#endif
|
||||||
|
|
||||||
/** Initialize the Libevent library and set up the event base. */
|
/** Initialize the Libevent library and set up the event base. */
|
||||||
void
|
void
|
||||||
|
@ -163,16 +126,7 @@ tor_libevent_initialize(tor_libevent_cfg *torcfg)
|
||||||
if (!the_event_base) {
|
if (!the_event_base) {
|
||||||
/* LCOV_EXCL_START */
|
/* LCOV_EXCL_START */
|
||||||
log_err(LD_GENERAL, "Unable to initialize Libevent: cannot continue.");
|
log_err(LD_GENERAL, "Unable to initialize Libevent: cannot continue.");
|
||||||
exit(1); // exit ok: libevent is broken.
|
exit(1);
|
||||||
/* LCOV_EXCL_STOP */
|
|
||||||
}
|
|
||||||
|
|
||||||
rescan_mainloop_ev = event_new(the_event_base, -1, 0,
|
|
||||||
rescan_mainloop_cb, the_event_base);
|
|
||||||
if (!rescan_mainloop_ev) {
|
|
||||||
/* LCOV_EXCL_START */
|
|
||||||
log_err(LD_GENERAL, "Unable to create rescan event: cannot continue.");
|
|
||||||
exit(1); // exit ok: libevent is broken.
|
|
||||||
/* LCOV_EXCL_STOP */
|
/* LCOV_EXCL_STOP */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -253,42 +207,13 @@ periodic_timer_new(struct event_base *base,
|
||||||
}
|
}
|
||||||
timer->cb = cb;
|
timer->cb = cb;
|
||||||
timer->data = data;
|
timer->data = data;
|
||||||
periodic_timer_launch(timer, tv);
|
event_add(timer->ev, (struct timeval *)tv); /*drop const for old libevent*/
|
||||||
return timer;
|
return timer;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Launch the timer <b>timer</b> to run at <b>tv</b> from now, and every
|
|
||||||
* <b>tv</b> thereafter.
|
|
||||||
*
|
|
||||||
* If the timer is already enabled, this function does nothing.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
periodic_timer_launch(periodic_timer_t *timer, const struct timeval *tv)
|
|
||||||
{
|
|
||||||
tor_assert(timer);
|
|
||||||
if (event_pending(timer->ev, EV_TIMEOUT, NULL))
|
|
||||||
return;
|
|
||||||
event_add(timer->ev, tv);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Disable the provided <b>timer</b>, but do not free it.
|
|
||||||
*
|
|
||||||
* You can reenable the same timer later with periodic_timer_launch.
|
|
||||||
*
|
|
||||||
* If the timer is already disabled, this function does nothing.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
periodic_timer_disable(periodic_timer_t *timer)
|
|
||||||
{
|
|
||||||
tor_assert(timer);
|
|
||||||
(void) event_del(timer->ev);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Stop and free a periodic timer */
|
/** Stop and free a periodic timer */
|
||||||
void
|
void
|
||||||
periodic_timer_free_(periodic_timer_t *timer)
|
periodic_timer_free(periodic_timer_t *timer)
|
||||||
{
|
{
|
||||||
if (!timer)
|
if (!timer)
|
||||||
return;
|
return;
|
||||||
|
@ -296,173 +221,6 @@ periodic_timer_free_(periodic_timer_t *timer)
|
||||||
tor_free(timer);
|
tor_free(timer);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Type used to represent events that run directly from the main loop,
|
|
||||||
* either because they are activated from elsewhere in the code, or
|
|
||||||
* because they have a simple timeout.
|
|
||||||
*
|
|
||||||
* We use this type to avoid exposing Libevent's API throughout the rest
|
|
||||||
* of the codebase.
|
|
||||||
*
|
|
||||||
* This type can't be used for all events: it doesn't handle events that
|
|
||||||
* are triggered by signals or by sockets.
|
|
||||||
*/
|
|
||||||
struct mainloop_event_t {
|
|
||||||
struct event *ev;
|
|
||||||
void (*cb)(mainloop_event_t *, void *);
|
|
||||||
void *userdata;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Internal: Implements mainloop event using a libevent event.
|
|
||||||
*/
|
|
||||||
static void
|
|
||||||
mainloop_event_cb(evutil_socket_t fd, short what, void *arg)
|
|
||||||
{
|
|
||||||
(void)fd;
|
|
||||||
(void)what;
|
|
||||||
mainloop_event_t *mev = arg;
|
|
||||||
mev->cb(mev, mev->userdata);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* As mainloop_event_cb, but implements a post-loop event.
|
|
||||||
*/
|
|
||||||
static void
|
|
||||||
mainloop_event_postloop_cb(evutil_socket_t fd, short what, void *arg)
|
|
||||||
{
|
|
||||||
(void)fd;
|
|
||||||
(void)what;
|
|
||||||
|
|
||||||
/* Note that if rescan_mainloop_ev is already activated,
|
|
||||||
* event_active() will do nothing: only the first post-loop event that
|
|
||||||
* happens each time through the event loop will cause it to be
|
|
||||||
* activated.
|
|
||||||
*
|
|
||||||
* Because event_active() puts events on a FIFO queue, every event
|
|
||||||
* that is made active _after_ rescan_mainloop_ev will get its
|
|
||||||
* callback run after rescan_mainloop_cb is called -- that is, on the
|
|
||||||
* next iteration of the loop.
|
|
||||||
*/
|
|
||||||
event_active(rescan_mainloop_ev, EV_READ, 1);
|
|
||||||
|
|
||||||
mainloop_event_t *mev = arg;
|
|
||||||
mev->cb(mev, mev->userdata);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Helper for mainloop_event_new() and mainloop_event_postloop_new().
|
|
||||||
*/
|
|
||||||
static mainloop_event_t *
|
|
||||||
mainloop_event_new_impl(int postloop,
|
|
||||||
void (*cb)(mainloop_event_t *, void *),
|
|
||||||
void *userdata)
|
|
||||||
{
|
|
||||||
tor_assert(cb);
|
|
||||||
|
|
||||||
struct event_base *base = tor_libevent_get_base();
|
|
||||||
mainloop_event_t *mev = tor_malloc_zero(sizeof(mainloop_event_t));
|
|
||||||
mev->ev = tor_event_new(base, -1, 0,
|
|
||||||
postloop ? mainloop_event_postloop_cb : mainloop_event_cb,
|
|
||||||
mev);
|
|
||||||
tor_assert(mev->ev);
|
|
||||||
mev->cb = cb;
|
|
||||||
mev->userdata = userdata;
|
|
||||||
return mev;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create and return a new mainloop_event_t to run the function <b>cb</b>.
|
|
||||||
*
|
|
||||||
* When run, the callback function will be passed the mainloop_event_t
|
|
||||||
* and <b>userdata</b> as its arguments. The <b>userdata</b> pointer
|
|
||||||
* must remain valid for as long as the mainloop_event_t event exists:
|
|
||||||
* it is your responsibility to free it.
|
|
||||||
*
|
|
||||||
* The event is not scheduled by default: Use mainloop_event_activate()
|
|
||||||
* or mainloop_event_schedule() to make it run.
|
|
||||||
*/
|
|
||||||
mainloop_event_t *
|
|
||||||
mainloop_event_new(void (*cb)(mainloop_event_t *, void *),
|
|
||||||
void *userdata)
|
|
||||||
{
|
|
||||||
return mainloop_event_new_impl(0, cb, userdata);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* As mainloop_event_new(), but create a post-loop event.
|
|
||||||
*
|
|
||||||
* A post-loop event behaves like any ordinary event, but any events
|
|
||||||
* that _it_ activates cannot run until Libevent has checked for other
|
|
||||||
* events at least once.
|
|
||||||
*/
|
|
||||||
mainloop_event_t *
|
|
||||||
mainloop_event_postloop_new(void (*cb)(mainloop_event_t *, void *),
|
|
||||||
void *userdata)
|
|
||||||
{
|
|
||||||
return mainloop_event_new_impl(1, cb, userdata);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Schedule <b>event</b> to run in the main loop, immediately. If it is
|
|
||||||
* not scheduled, it will run anyway. If it is already scheduled to run
|
|
||||||
* later, it will run now instead. This function will have no effect if
|
|
||||||
* the event is already scheduled to run.
|
|
||||||
*
|
|
||||||
* This function may only be called from the main thread.
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
mainloop_event_activate(mainloop_event_t *event)
|
|
||||||
{
|
|
||||||
tor_assert(event);
|
|
||||||
event_active(event->ev, EV_READ, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Schedule <b>event</b> to run in the main loop, after a delay of <b>tv</b>.
|
|
||||||
*
|
|
||||||
* If the event is scheduled for a different time, cancel it and run
|
|
||||||
* after this delay instead. If the event is currently pending to run
|
|
||||||
* <em>now</b>, has no effect.
|
|
||||||
*
|
|
||||||
* Do not call this function with <b>tv</b> == NULL -- use
|
|
||||||
* mainloop_event_activate() instead.
|
|
||||||
*
|
|
||||||
* This function may only be called from the main thread.
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
mainloop_event_schedule(mainloop_event_t *event, const struct timeval *tv)
|
|
||||||
{
|
|
||||||
tor_assert(event);
|
|
||||||
if (BUG(tv == NULL)) {
|
|
||||||
// LCOV_EXCL_START
|
|
||||||
mainloop_event_activate(event);
|
|
||||||
return 0;
|
|
||||||
// LCOV_EXCL_STOP
|
|
||||||
}
|
|
||||||
return event_add(event->ev, tv);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Cancel <b>event</b> if it is currently active or pending. (Do nothing if
|
|
||||||
* the event is not currently active or pending.) */
|
|
||||||
void
|
|
||||||
mainloop_event_cancel(mainloop_event_t *event)
|
|
||||||
{
|
|
||||||
if (!event)
|
|
||||||
return;
|
|
||||||
(void) event_del(event->ev);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Cancel <b>event</b> and release all storage associated with it. */
|
|
||||||
void
|
|
||||||
mainloop_event_free_(mainloop_event_t *event)
|
|
||||||
{
|
|
||||||
if (!event)
|
|
||||||
return;
|
|
||||||
tor_event_free(event->ev);
|
|
||||||
memset(event, 0xb8, sizeof(*event));
|
|
||||||
tor_free(event);
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
int
|
||||||
tor_init_libevent_rng(void)
|
tor_init_libevent_rng(void)
|
||||||
{
|
{
|
||||||
|
@ -479,51 +237,50 @@ tor_init_libevent_rng(void)
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
#if defined(LIBEVENT_VERSION_NUMBER) && LIBEVENT_VERSION_NUMBER >= V(2,1,1) \
|
||||||
* Un-initialize libevent in preparation for an exit
|
&& !defined(TOR_UNIT_TESTS)
|
||||||
*/
|
|
||||||
void
|
void
|
||||||
tor_libevent_free_all(void)
|
tor_gettimeofday_cached(struct timeval *tv)
|
||||||
{
|
{
|
||||||
tor_event_free(rescan_mainloop_ev);
|
event_base_gettimeofday_cached(the_event_base, tv);
|
||||||
if (the_event_base)
|
|
||||||
event_base_free(the_event_base);
|
|
||||||
the_event_base = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Run the event loop for the provided event_base, handling events until
|
|
||||||
* something stops it. If <b>once</b> is set, then just poll-and-run
|
|
||||||
* once, then exit. Return 0 on success, -1 if an error occurred, or 1
|
|
||||||
* if we exited because no events were pending or active.
|
|
||||||
*
|
|
||||||
* This isn't reentrant or multithreaded.
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
tor_libevent_run_event_loop(struct event_base *base, int once)
|
|
||||||
{
|
|
||||||
const int flags = once ? EVLOOP_ONCE : 0;
|
|
||||||
return event_base_loop(base, flags);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Tell the event loop to exit after <b>delay</b>. If <b>delay</b> is NULL,
|
|
||||||
* instead exit after we're done running the currently active events. */
|
|
||||||
void
|
void
|
||||||
tor_libevent_exit_loop_after_delay(struct event_base *base,
|
tor_gettimeofday_cache_clear(void)
|
||||||
const struct timeval *delay)
|
|
||||||
{
|
{
|
||||||
event_base_loopexit(base, delay);
|
event_base_update_cache_time(the_event_base);
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
/** Cache the current hi-res time; the cache gets reset when libevent
|
||||||
|
* calls us. */
|
||||||
|
static struct timeval cached_time_hires = {0, 0};
|
||||||
|
|
||||||
/** Tell the event loop to exit after running whichever callback is currently
|
/** Return a fairly recent view of the current time. */
|
||||||
* active. */
|
|
||||||
void
|
void
|
||||||
tor_libevent_exit_loop_after_callback(struct event_base *base)
|
tor_gettimeofday_cached(struct timeval *tv)
|
||||||
{
|
{
|
||||||
event_base_loopbreak(base);
|
if (cached_time_hires.tv_sec == 0) {
|
||||||
|
tor_gettimeofday(&cached_time_hires);
|
||||||
|
}
|
||||||
|
*tv = cached_time_hires;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Reset the cached view of the current time, so that the next time we try
|
||||||
|
* to learn it, we will get an up-to-date value. */
|
||||||
|
void
|
||||||
|
tor_gettimeofday_cache_clear(void)
|
||||||
|
{
|
||||||
|
cached_time_hires.tv_sec = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef TOR_UNIT_TESTS
|
||||||
|
/** For testing: force-update the cached time to a given value. */
|
||||||
|
void
|
||||||
|
tor_gettimeofday_cache_set(const struct timeval *tv)
|
||||||
|
{
|
||||||
|
tor_assert(tv);
|
||||||
|
memcpy(&cached_time_hires, tv, sizeof(*tv));
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(TOR_UNIT_TESTS)
|
|
||||||
/** For testing: called post-fork to make libevent reinitialize
|
/** For testing: called post-fork to make libevent reinitialize
|
||||||
* kernel structures. */
|
* kernel structures. */
|
||||||
void
|
void
|
||||||
|
@ -532,5 +289,6 @@ tor_libevent_postfork(void)
|
||||||
int r = event_reinit(tor_libevent_get_base());
|
int r = event_reinit(tor_libevent_get_base());
|
||||||
tor_assert(r == 0);
|
tor_assert(r == 0);
|
||||||
}
|
}
|
||||||
#endif /* defined(TOR_UNIT_TESTS) */
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,8 @@
|
||||||
#include "orconfig.h"
|
#include "orconfig.h"
|
||||||
#include "testsupport.h"
|
#include "testsupport.h"
|
||||||
|
|
||||||
|
#include <event2/event.h>
|
||||||
|
|
||||||
void configure_libevent_logging(void);
|
void configure_libevent_logging(void);
|
||||||
void suppress_libevent_log_msg(const char *msg);
|
void suppress_libevent_log_msg(const char *msg);
|
||||||
|
|
||||||
|
@ -17,12 +19,7 @@ void suppress_libevent_log_msg(const char *msg);
|
||||||
evdns_add_server_port_with_base(tor_libevent_get_base(), \
|
evdns_add_server_port_with_base(tor_libevent_get_base(), \
|
||||||
(sock),(tcp),(cb),(data));
|
(sock),(tcp),(cb),(data));
|
||||||
|
|
||||||
struct event;
|
void tor_event_free(struct event *ev);
|
||||||
struct event_base;
|
|
||||||
|
|
||||||
void tor_event_free_(struct event *ev);
|
|
||||||
#define tor_event_free(ev) \
|
|
||||||
FREE_AND_NULL(struct event, tor_event_free_, (ev))
|
|
||||||
|
|
||||||
typedef struct periodic_timer_t periodic_timer_t;
|
typedef struct periodic_timer_t periodic_timer_t;
|
||||||
|
|
||||||
|
@ -30,25 +27,9 @@ periodic_timer_t *periodic_timer_new(struct event_base *base,
|
||||||
const struct timeval *tv,
|
const struct timeval *tv,
|
||||||
void (*cb)(periodic_timer_t *timer, void *data),
|
void (*cb)(periodic_timer_t *timer, void *data),
|
||||||
void *data);
|
void *data);
|
||||||
void periodic_timer_free_(periodic_timer_t *);
|
void periodic_timer_free(periodic_timer_t *);
|
||||||
void periodic_timer_launch(periodic_timer_t *, const struct timeval *tv);
|
|
||||||
void periodic_timer_disable(periodic_timer_t *);
|
|
||||||
#define periodic_timer_free(t) \
|
|
||||||
FREE_AND_NULL(periodic_timer_t, periodic_timer_free_, (t))
|
|
||||||
|
|
||||||
typedef struct mainloop_event_t mainloop_event_t;
|
#define tor_event_base_loopexit event_base_loopexit
|
||||||
mainloop_event_t *mainloop_event_new(void (*cb)(mainloop_event_t *, void *),
|
|
||||||
void *userdata);
|
|
||||||
mainloop_event_t * mainloop_event_postloop_new(
|
|
||||||
void (*cb)(mainloop_event_t *, void *),
|
|
||||||
void *userdata);
|
|
||||||
void mainloop_event_activate(mainloop_event_t *event);
|
|
||||||
int mainloop_event_schedule(mainloop_event_t *event,
|
|
||||||
const struct timeval *delay);
|
|
||||||
void mainloop_event_cancel(mainloop_event_t *event);
|
|
||||||
void mainloop_event_free_(mainloop_event_t *event);
|
|
||||||
#define mainloop_event_free(event) \
|
|
||||||
FREE_AND_NULL(mainloop_event_t, mainloop_event_free_, (event))
|
|
||||||
|
|
||||||
/** Defines a configuration for using libevent with Tor: passed as an argument
|
/** Defines a configuration for using libevent with Tor: passed as an argument
|
||||||
* to tor_libevent_initialize() to describe how we want to set up. */
|
* to tor_libevent_initialize() to describe how we want to set up. */
|
||||||
|
@ -66,19 +47,16 @@ const char *tor_libevent_get_method(void);
|
||||||
void tor_check_libevent_header_compatibility(void);
|
void tor_check_libevent_header_compatibility(void);
|
||||||
const char *tor_libevent_get_version_str(void);
|
const char *tor_libevent_get_version_str(void);
|
||||||
const char *tor_libevent_get_header_version_str(void);
|
const char *tor_libevent_get_header_version_str(void);
|
||||||
void tor_libevent_free_all(void);
|
|
||||||
|
|
||||||
int tor_init_libevent_rng(void);
|
int tor_init_libevent_rng(void);
|
||||||
|
|
||||||
|
void tor_gettimeofday_cached(struct timeval *tv);
|
||||||
|
void tor_gettimeofday_cache_clear(void);
|
||||||
#ifdef TOR_UNIT_TESTS
|
#ifdef TOR_UNIT_TESTS
|
||||||
|
void tor_gettimeofday_cache_set(const struct timeval *tv);
|
||||||
void tor_libevent_postfork(void);
|
void tor_libevent_postfork(void);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int tor_libevent_run_event_loop(struct event_base *base, int once);
|
|
||||||
void tor_libevent_exit_loop_after_delay(struct event_base *base,
|
|
||||||
const struct timeval *delay);
|
|
||||||
void tor_libevent_exit_loop_after_callback(struct event_base *base);
|
|
||||||
|
|
||||||
#ifdef COMPAT_LIBEVENT_PRIVATE
|
#ifdef COMPAT_LIBEVENT_PRIVATE
|
||||||
|
|
||||||
/** Macro: returns the number of a Libevent version as a 4-byte number,
|
/** Macro: returns the number of a Libevent version as a 4-byte number,
|
||||||
|
@ -92,7 +70,7 @@ void tor_libevent_exit_loop_after_callback(struct event_base *base);
|
||||||
|
|
||||||
STATIC void
|
STATIC void
|
||||||
libevent_logging_callback(int severity, const char *msg);
|
libevent_logging_callback(int severity, const char *msg);
|
||||||
#endif /* defined(COMPAT_LIBEVENT_PRIVATE) */
|
#endif
|
||||||
|
|
||||||
#endif /* !defined(TOR_COMPAT_LIBEVENT_H) */
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -8,12 +8,11 @@
|
||||||
#define TOR_COMPAT_OPENSSL_H
|
#define TOR_COMPAT_OPENSSL_H
|
||||||
|
|
||||||
#include <openssl/opensslv.h>
|
#include <openssl/opensslv.h>
|
||||||
#include "crypto_openssl_mgt.h"
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \file compat_openssl.h
|
* \file compat_openssl.h
|
||||||
*
|
*
|
||||||
* \brief compatibility definitions for working with different openssl forks
|
* \brief compatability definitions for working with different openssl forks
|
||||||
**/
|
**/
|
||||||
|
|
||||||
#if !defined(LIBRESSL_VERSION_NUMBER) && \
|
#if !defined(LIBRESSL_VERSION_NUMBER) && \
|
||||||
|
@ -26,13 +25,10 @@
|
||||||
/* We define this macro if we're trying to build with the majorly refactored
|
/* We define this macro if we're trying to build with the majorly refactored
|
||||||
* API in OpenSSL 1.1 */
|
* API in OpenSSL 1.1 */
|
||||||
#define OPENSSL_1_1_API
|
#define OPENSSL_1_1_API
|
||||||
#endif /* OPENSSL_VERSION_NUMBER >= OPENSSL_V_SERIES(1,1,0) && ... */
|
|
||||||
|
|
||||||
#ifndef OPENSSL_VERSION
|
|
||||||
#define OPENSSL_VERSION SSLEAY_VERSION
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef OPENSSL_1_1_API
|
#ifndef OPENSSL_1_1_API
|
||||||
|
#define OPENSSL_VERSION SSLEAY_VERSION
|
||||||
#define OpenSSL_version(v) SSLeay_version(v)
|
#define OpenSSL_version(v) SSLeay_version(v)
|
||||||
#define OpenSSL_version_num() SSLeay()
|
#define OpenSSL_version_num() SSLeay()
|
||||||
#define RAND_OpenSSL() RAND_SSLeay()
|
#define RAND_OpenSSL() RAND_SSLeay()
|
||||||
|
@ -41,11 +37,11 @@
|
||||||
((st) == SSL3_ST_SW_SRVR_HELLO_B))
|
((st) == SSL3_ST_SW_SRVR_HELLO_B))
|
||||||
#define OSSL_HANDSHAKE_STATE int
|
#define OSSL_HANDSHAKE_STATE int
|
||||||
#define CONST_IF_OPENSSL_1_1_API
|
#define CONST_IF_OPENSSL_1_1_API
|
||||||
#else /* !(!defined(OPENSSL_1_1_API)) */
|
#else
|
||||||
#define STATE_IS_SW_SERVER_HELLO(st) \
|
#define STATE_IS_SW_SERVER_HELLO(st) \
|
||||||
((st) == TLS_ST_SW_SRVR_HELLO)
|
((st) == TLS_ST_SW_SRVR_HELLO)
|
||||||
#define CONST_IF_OPENSSL_1_1_API const
|
#define CONST_IF_OPENSSL_1_1_API const
|
||||||
#endif /* !defined(OPENSSL_1_1_API) */
|
#endif
|
||||||
|
|
||||||
#endif /* !defined(TOR_COMPAT_OPENSSL_H) */
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -201,21 +201,20 @@ tor_cond_init(tor_cond_t *cond)
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(HAVE_CLOCK_GETTIME)
|
#if defined(HAVE_CLOCK_GETTIME)
|
||||||
#if defined(HAVE_PTHREAD_CONDATTR_SETCLOCK) && \
|
#if defined(CLOCK_MONOTONIC) && defined(HAVE_PTHREAD_CONDATTR_SETCLOCK)
|
||||||
defined(CLOCK_MONOTONIC)
|
|
||||||
/* Use monotonic time so when we timedwait() on it, any clock adjustment
|
/* Use monotonic time so when we timedwait() on it, any clock adjustment
|
||||||
* won't affect the timeout value. */
|
* won't affect the timeout value. */
|
||||||
if (pthread_condattr_setclock(&condattr, CLOCK_MONOTONIC)) {
|
if (pthread_condattr_setclock(&condattr, CLOCK_MONOTONIC)) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
#define USE_COND_CLOCK CLOCK_MONOTONIC
|
#define USE_COND_CLOCK CLOCK_MONOTONIC
|
||||||
#else /* !(defined(HAVE_PTHREAD_CONDATTR_SETCLOCK) && ...) */
|
#else /* !defined HAVE_PTHREAD_CONDATTR_SETCLOCK */
|
||||||
/* On OSX Sierra, there is no pthread_condattr_setclock, so we are stuck
|
/* On OSX Sierra, there is no pthread_condattr_setclock, so we are stuck
|
||||||
* with the realtime clock.
|
* with the realtime clock.
|
||||||
*/
|
*/
|
||||||
#define USE_COND_CLOCK CLOCK_REALTIME
|
#define USE_COND_CLOCK CLOCK_REALTIME
|
||||||
#endif /* defined(HAVE_PTHREAD_CONDATTR_SETCLOCK) && ... */
|
#endif /* which clock to use */
|
||||||
#endif /* defined(HAVE_CLOCK_GETTIME) */
|
#endif /* HAVE_CLOCK_GETTIME */
|
||||||
if (pthread_cond_init(&cond->cond, &condattr)) {
|
if (pthread_cond_init(&cond->cond, &condattr)) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -267,11 +266,11 @@ tor_cond_wait(tor_cond_t *cond, tor_mutex_t *mutex, const struct timeval *tv)
|
||||||
tvnow.tv_sec = ts.tv_sec;
|
tvnow.tv_sec = ts.tv_sec;
|
||||||
tvnow.tv_usec = (int)(ts.tv_nsec / 1000);
|
tvnow.tv_usec = (int)(ts.tv_nsec / 1000);
|
||||||
timeradd(tv, &tvnow, &tvsum);
|
timeradd(tv, &tvnow, &tvsum);
|
||||||
#else /* !(defined(HAVE_CLOCK_GETTIME) && defined(USE_COND_CLOCK)) */
|
#else
|
||||||
if (gettimeofday(&tvnow, NULL) < 0)
|
if (gettimeofday(&tvnow, NULL) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
timeradd(tv, &tvnow, &tvsum);
|
timeradd(tv, &tvnow, &tvsum);
|
||||||
#endif /* defined(HAVE_CLOCK_GETTIME) && defined(USE_COND_CLOCK) */
|
#endif /* HAVE_CLOCK_GETTIME, CLOCK_MONOTONIC */
|
||||||
|
|
||||||
ts.tv_sec = tvsum.tv_sec;
|
ts.tv_sec = tvsum.tv_sec;
|
||||||
ts.tv_nsec = tvsum.tv_usec * 1000;
|
ts.tv_nsec = tvsum.tv_usec * 1000;
|
||||||
|
|
|
@ -0,0 +1,39 @@
|
||||||
|
/* Copyright (c) 2017, The Tor Project, Inc. */
|
||||||
|
/* See LICENSE for licensing information */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \file rust_compat.c
|
||||||
|
* \brief Rust FFI compatibility functions and helpers. This file is only built
|
||||||
|
* if Rust is not used.
|
||||||
|
**/
|
||||||
|
|
||||||
|
#include "compat_rust.h"
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Free storage pointed to by <b>str</b>, and itself.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
rust_str_free(rust_str_t str)
|
||||||
|
{
|
||||||
|
char *s = (char *)str;
|
||||||
|
tor_free(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return zero-terminated contained string.
|
||||||
|
*/
|
||||||
|
const char *
|
||||||
|
rust_str_get(const rust_str_t str)
|
||||||
|
{
|
||||||
|
return (const char *)str;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If we were using Rust, we'd say so on startup. */
|
||||||
|
rust_str_t
|
||||||
|
rust_welcome_string(void)
|
||||||
|
{
|
||||||
|
char *s = tor_malloc_zero(1);
|
||||||
|
return (rust_str_t)s;
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,28 @@
|
||||||
|
/* Copyright (c) 2017, The Tor Project, Inc. */
|
||||||
|
/* See LICENSE for licensing information */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \file rust_compat.h
|
||||||
|
* \brief Headers for rust_compat.c
|
||||||
|
**/
|
||||||
|
|
||||||
|
#ifndef TOR_RUST_COMPAT_H
|
||||||
|
#define TOR_RUST_COMPAT_H
|
||||||
|
|
||||||
|
#include "torint.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Strings allocated in Rust must be freed from Rust code again. Let's make
|
||||||
|
* it less likely to accidentally mess up and call tor_free() on it, because
|
||||||
|
* currently it'll just work but might break at any time.
|
||||||
|
*/
|
||||||
|
typedef uintptr_t rust_str_t;
|
||||||
|
|
||||||
|
void rust_str_free(rust_str_t);
|
||||||
|
|
||||||
|
const char *rust_str_get(const rust_str_t);
|
||||||
|
|
||||||
|
rust_str_t rust_welcome_string(void);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
|
@ -48,7 +48,7 @@ tor_mutex_new_nonrecursive(void)
|
||||||
}
|
}
|
||||||
/** Release all storage and system resources held by <b>m</b>. */
|
/** Release all storage and system resources held by <b>m</b>. */
|
||||||
void
|
void
|
||||||
tor_mutex_free_(tor_mutex_t *m)
|
tor_mutex_free(tor_mutex_t *m)
|
||||||
{
|
{
|
||||||
if (!m)
|
if (!m)
|
||||||
return;
|
return;
|
||||||
|
@ -68,7 +68,7 @@ tor_cond_new(void)
|
||||||
|
|
||||||
/** Free all storage held in <b>c</b>. */
|
/** Free all storage held in <b>c</b>. */
|
||||||
void
|
void
|
||||||
tor_cond_free_(tor_cond_t *c)
|
tor_cond_free(tor_cond_t *c)
|
||||||
{
|
{
|
||||||
if (!c)
|
if (!c)
|
||||||
return;
|
return;
|
||||||
|
@ -126,7 +126,7 @@ read_ni(int fd, void *buf, size_t n)
|
||||||
}
|
}
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
#endif /* defined(HAVE_EVENTFD) || defined(HAVE_PIPE) */
|
#endif
|
||||||
|
|
||||||
/** As send(), but retry on EINTR, and return the negative error code on
|
/** As send(), but retry on EINTR, and return the negative error code on
|
||||||
* error. */
|
* error. */
|
||||||
|
@ -186,7 +186,7 @@ eventfd_drain(int fd)
|
||||||
return r;
|
return r;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif /* defined(HAVE_EVENTFD) */
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_PIPE
|
#ifdef HAVE_PIPE
|
||||||
/** Send a byte over a pipe. Return 0 on success or EAGAIN; -1 on error */
|
/** Send a byte over a pipe. Return 0 on success or EAGAIN; -1 on error */
|
||||||
|
@ -214,7 +214,7 @@ pipe_drain(int fd)
|
||||||
/* A value of r = 0 means EOF on the fd so successfully drained. */
|
/* A value of r = 0 means EOF on the fd so successfully drained. */
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif /* defined(HAVE_PIPE) */
|
#endif
|
||||||
|
|
||||||
/** Send a byte on socket <b>fd</b>t. Return 0 on success or EAGAIN,
|
/** Send a byte on socket <b>fd</b>t. Return 0 on success or EAGAIN,
|
||||||
* -1 on error. */
|
* -1 on error. */
|
||||||
|
@ -276,7 +276,7 @@ alert_sockets_create(alert_sockets_t *socks_out, uint32_t flags)
|
||||||
socks_out->drain_fn = eventfd_drain;
|
socks_out->drain_fn = eventfd_drain;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif /* defined(HAVE_EVENTFD) */
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_PIPE2
|
#ifdef HAVE_PIPE2
|
||||||
/* Now we're going to try pipes. First type the pipe2() syscall, if we
|
/* Now we're going to try pipes. First type the pipe2() syscall, if we
|
||||||
|
@ -289,7 +289,7 @@ alert_sockets_create(alert_sockets_t *socks_out, uint32_t flags)
|
||||||
socks_out->drain_fn = pipe_drain;
|
socks_out->drain_fn = pipe_drain;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif /* defined(HAVE_PIPE2) */
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_PIPE
|
#ifdef HAVE_PIPE
|
||||||
/* Now try the regular pipe() syscall. Pipes have a bit lower overhead than
|
/* Now try the regular pipe() syscall. Pipes have a bit lower overhead than
|
||||||
|
@ -313,7 +313,7 @@ alert_sockets_create(alert_sockets_t *socks_out, uint32_t flags)
|
||||||
socks_out->drain_fn = pipe_drain;
|
socks_out->drain_fn = pipe_drain;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif /* defined(HAVE_PIPE) */
|
#endif
|
||||||
|
|
||||||
/* If nothing else worked, fall back on socketpair(). */
|
/* If nothing else worked, fall back on socketpair(). */
|
||||||
if (!(flags & ASOCKS_NOSOCKETPAIR) &&
|
if (!(flags & ASOCKS_NOSOCKETPAIR) &&
|
||||||
|
@ -352,7 +352,12 @@ alert_sockets_close(alert_sockets_t *socks)
|
||||||
socks->read_fd = socks->write_fd = -1;
|
socks->read_fd = socks->write_fd = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef HAVE_STDATOMIC_H
|
/*
|
||||||
|
* XXXX We might be smart to move to compiler intrinsics or real atomic
|
||||||
|
* XXXX operations at some point. But not yet.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
/** Initialize a new atomic counter with the value 0 */
|
/** Initialize a new atomic counter with the value 0 */
|
||||||
void
|
void
|
||||||
atomic_counter_init(atomic_counter_t *counter)
|
atomic_counter_init(atomic_counter_t *counter)
|
||||||
|
@ -392,16 +397,4 @@ atomic_counter_get(atomic_counter_t *counter)
|
||||||
tor_mutex_release(&counter->mutex);
|
tor_mutex_release(&counter->mutex);
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
/** Replace the value of an atomic counter; return the old one. */
|
|
||||||
size_t
|
|
||||||
atomic_counter_exchange(atomic_counter_t *counter, size_t newval)
|
|
||||||
{
|
|
||||||
size_t oldval;
|
|
||||||
tor_mutex_acquire(&counter->mutex);
|
|
||||||
oldval = counter->val;
|
|
||||||
counter->val = newval;
|
|
||||||
tor_mutex_release(&counter->mutex);
|
|
||||||
return oldval;
|
|
||||||
}
|
|
||||||
#endif /* !defined(HAVE_STDATOMIC_H) */
|
|
||||||
|
|
||||||
|
|
|
@ -14,17 +14,13 @@
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_STDATOMIC_H
|
|
||||||
#include <stdatomic.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
#define USE_WIN32_THREADS
|
#define USE_WIN32_THREADS
|
||||||
#elif defined(HAVE_PTHREAD_H) && defined(HAVE_PTHREAD_CREATE)
|
#elif defined(HAVE_PTHREAD_H) && defined(HAVE_PTHREAD_CREATE)
|
||||||
#define USE_PTHREADS
|
#define USE_PTHREADS
|
||||||
#else
|
#else
|
||||||
#error "No threading system was found"
|
#error "No threading system was found"
|
||||||
#endif /* defined(_WIN32) || ... */
|
#endif
|
||||||
|
|
||||||
int spawn_func(void (*func)(void *), void *data);
|
int spawn_func(void (*func)(void *), void *data);
|
||||||
void spawn_exit(void) ATTR_NORETURN;
|
void spawn_exit(void) ATTR_NORETURN;
|
||||||
|
@ -45,7 +41,7 @@ typedef struct tor_mutex_t {
|
||||||
#else
|
#else
|
||||||
/** No-threads only: Dummy variable so that tor_mutex_t takes up space. */
|
/** No-threads only: Dummy variable so that tor_mutex_t takes up space. */
|
||||||
int _unused;
|
int _unused;
|
||||||
#endif /* defined(USE_WIN32_THREADS) || ... */
|
#endif
|
||||||
} tor_mutex_t;
|
} tor_mutex_t;
|
||||||
|
|
||||||
tor_mutex_t *tor_mutex_new(void);
|
tor_mutex_t *tor_mutex_new(void);
|
||||||
|
@ -54,8 +50,7 @@ void tor_mutex_init(tor_mutex_t *m);
|
||||||
void tor_mutex_init_nonrecursive(tor_mutex_t *m);
|
void tor_mutex_init_nonrecursive(tor_mutex_t *m);
|
||||||
void tor_mutex_acquire(tor_mutex_t *m);
|
void tor_mutex_acquire(tor_mutex_t *m);
|
||||||
void tor_mutex_release(tor_mutex_t *m);
|
void tor_mutex_release(tor_mutex_t *m);
|
||||||
void tor_mutex_free_(tor_mutex_t *m);
|
void tor_mutex_free(tor_mutex_t *m);
|
||||||
#define tor_mutex_free(m) FREE_AND_NULL(tor_mutex_t, tor_mutex_free_, (m))
|
|
||||||
void tor_mutex_uninit(tor_mutex_t *m);
|
void tor_mutex_uninit(tor_mutex_t *m);
|
||||||
unsigned long tor_get_thread_id(void);
|
unsigned long tor_get_thread_id(void);
|
||||||
void tor_threads_init(void);
|
void tor_threads_init(void);
|
||||||
|
@ -78,12 +73,11 @@ typedef struct tor_cond_t {
|
||||||
int generation;
|
int generation;
|
||||||
#else
|
#else
|
||||||
#error no known condition implementation.
|
#error no known condition implementation.
|
||||||
#endif /* defined(USE_PTHREADS) || ... */
|
#endif
|
||||||
} tor_cond_t;
|
} tor_cond_t;
|
||||||
|
|
||||||
tor_cond_t *tor_cond_new(void);
|
tor_cond_t *tor_cond_new(void);
|
||||||
void tor_cond_free_(tor_cond_t *cond);
|
void tor_cond_free(tor_cond_t *cond);
|
||||||
#define tor_cond_free(c) FREE_AND_NULL(tor_cond_t, tor_cond_free_, (c))
|
|
||||||
int tor_cond_init(tor_cond_t *cond);
|
int tor_cond_init(tor_cond_t *cond);
|
||||||
void tor_cond_uninit(tor_cond_t *cond);
|
void tor_cond_uninit(tor_cond_t *cond);
|
||||||
int tor_cond_wait(tor_cond_t *cond, tor_mutex_t *mutex,
|
int tor_cond_wait(tor_cond_t *cond, tor_mutex_t *mutex,
|
||||||
|
@ -156,68 +150,16 @@ void tor_threadlocal_set(tor_threadlocal_t *threadlocal, void *value);
|
||||||
/**
|
/**
|
||||||
* Atomic counter type; holds a size_t value.
|
* Atomic counter type; holds a size_t value.
|
||||||
*/
|
*/
|
||||||
#ifdef HAVE_STDATOMIC_H
|
|
||||||
typedef struct atomic_counter_t {
|
|
||||||
atomic_size_t val;
|
|
||||||
} atomic_counter_t;
|
|
||||||
#define ATOMIC_LINKAGE static
|
|
||||||
#else /* !(defined(HAVE_STDATOMIC_H)) */
|
|
||||||
typedef struct atomic_counter_t {
|
typedef struct atomic_counter_t {
|
||||||
tor_mutex_t mutex;
|
tor_mutex_t mutex;
|
||||||
size_t val;
|
size_t val;
|
||||||
} atomic_counter_t;
|
} atomic_counter_t;
|
||||||
#define ATOMIC_LINKAGE
|
|
||||||
#endif /* defined(HAVE_STDATOMIC_H) */
|
|
||||||
|
|
||||||
ATOMIC_LINKAGE void atomic_counter_init(atomic_counter_t *counter);
|
void atomic_counter_init(atomic_counter_t *counter);
|
||||||
ATOMIC_LINKAGE void atomic_counter_destroy(atomic_counter_t *counter);
|
void atomic_counter_destroy(atomic_counter_t *counter);
|
||||||
ATOMIC_LINKAGE void atomic_counter_add(atomic_counter_t *counter, size_t add);
|
void atomic_counter_add(atomic_counter_t *counter, size_t add);
|
||||||
ATOMIC_LINKAGE void atomic_counter_sub(atomic_counter_t *counter, size_t sub);
|
void atomic_counter_sub(atomic_counter_t *counter, size_t sub);
|
||||||
ATOMIC_LINKAGE size_t atomic_counter_get(atomic_counter_t *counter);
|
size_t atomic_counter_get(atomic_counter_t *counter);
|
||||||
ATOMIC_LINKAGE size_t atomic_counter_exchange(atomic_counter_t *counter,
|
|
||||||
size_t newval);
|
|
||||||
#undef ATOMIC_LINKAGE
|
|
||||||
|
|
||||||
#ifdef HAVE_STDATOMIC_H
|
#endif
|
||||||
/** Initialize a new atomic counter with the value 0 */
|
|
||||||
static inline void
|
|
||||||
atomic_counter_init(atomic_counter_t *counter)
|
|
||||||
{
|
|
||||||
atomic_init(&counter->val, 0);
|
|
||||||
}
|
|
||||||
/** Clean up all resources held by an atomic counter. */
|
|
||||||
static inline void
|
|
||||||
atomic_counter_destroy(atomic_counter_t *counter)
|
|
||||||
{
|
|
||||||
(void)counter;
|
|
||||||
}
|
|
||||||
/** Add a value to an atomic counter. */
|
|
||||||
static inline void
|
|
||||||
atomic_counter_add(atomic_counter_t *counter, size_t add)
|
|
||||||
{
|
|
||||||
(void) atomic_fetch_add(&counter->val, add);
|
|
||||||
}
|
|
||||||
/** Subtract a value from an atomic counter. */
|
|
||||||
static inline void
|
|
||||||
atomic_counter_sub(atomic_counter_t *counter, size_t sub)
|
|
||||||
{
|
|
||||||
(void) atomic_fetch_sub(&counter->val, sub);
|
|
||||||
}
|
|
||||||
/** Return the current value of an atomic counter */
|
|
||||||
static inline size_t
|
|
||||||
atomic_counter_get(atomic_counter_t *counter)
|
|
||||||
{
|
|
||||||
return atomic_load(&counter->val);
|
|
||||||
}
|
|
||||||
/** Replace the value of an atomic counter; return the old one. */
|
|
||||||
static inline size_t
|
|
||||||
atomic_counter_exchange(atomic_counter_t *counter, size_t newval)
|
|
||||||
{
|
|
||||||
return atomic_exchange(&counter->val, newval);
|
|
||||||
}
|
|
||||||
|
|
||||||
#else /* !(defined(HAVE_STDATOMIC_H)) */
|
|
||||||
#endif /* defined(HAVE_STDATOMIC_H) */
|
|
||||||
|
|
||||||
#endif /* !defined(TOR_COMPAT_THREADS_H) */
|
|
||||||
|
|
||||||
|
|
|
@ -28,7 +28,7 @@
|
||||||
/* as fallback implementation for tor_sleep_msec */
|
/* as fallback implementation for tor_sleep_msec */
|
||||||
#include <sys/select.h>
|
#include <sys/select.h>
|
||||||
#endif
|
#endif
|
||||||
#endif /* defined(TOR_UNIT_TESTS) */
|
#endif
|
||||||
|
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
#include <mach/mach_time.h>
|
#include <mach/mach_time.h>
|
||||||
|
@ -64,15 +64,15 @@ tor_sleep_msec(int msec)
|
||||||
select(0, NULL, NULL, NULL, &tv);
|
select(0, NULL, NULL, NULL, &tv);
|
||||||
#else
|
#else
|
||||||
sleep(CEIL_DIV(msec, 1000));
|
sleep(CEIL_DIV(msec, 1000));
|
||||||
#endif /* defined(_WIN32) || ... */
|
#endif
|
||||||
}
|
}
|
||||||
#endif /* defined(TOR_UNIT_TESTS) */
|
#endif
|
||||||
|
|
||||||
/** Set *timeval to the current time of day. On error, log and terminate.
|
/** Set *timeval to the current time of day. On error, log and terminate.
|
||||||
* (Same as gettimeofday(timeval,NULL), but never returns -1.)
|
* (Same as gettimeofday(timeval,NULL), but never returns -1.)
|
||||||
*/
|
*/
|
||||||
MOCK_IMPL(void,
|
void
|
||||||
tor_gettimeofday, (struct timeval *timeval))
|
tor_gettimeofday(struct timeval *timeval)
|
||||||
{
|
{
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
/* Epoch bias copied from perl: number of units between windows epoch and
|
/* Epoch bias copied from perl: number of units between windows epoch and
|
||||||
|
@ -90,7 +90,7 @@ tor_gettimeofday, (struct timeval *timeval))
|
||||||
if (ft.ft_64 < EPOCH_BIAS) {
|
if (ft.ft_64 < EPOCH_BIAS) {
|
||||||
/* LCOV_EXCL_START */
|
/* LCOV_EXCL_START */
|
||||||
log_err(LD_GENERAL,"System time is before 1970; failing.");
|
log_err(LD_GENERAL,"System time is before 1970; failing.");
|
||||||
exit(1); // exit ok: system clock is broken.
|
exit(1);
|
||||||
/* LCOV_EXCL_STOP */
|
/* LCOV_EXCL_STOP */
|
||||||
}
|
}
|
||||||
ft.ft_64 -= EPOCH_BIAS;
|
ft.ft_64 -= EPOCH_BIAS;
|
||||||
|
@ -102,7 +102,7 @@ tor_gettimeofday, (struct timeval *timeval))
|
||||||
log_err(LD_GENERAL,"gettimeofday failed.");
|
log_err(LD_GENERAL,"gettimeofday failed.");
|
||||||
/* If gettimeofday dies, we have either given a bad timezone (we didn't),
|
/* If gettimeofday dies, we have either given a bad timezone (we didn't),
|
||||||
or segfaulted.*/
|
or segfaulted.*/
|
||||||
exit(1); // exit ok: gettimeofday failed.
|
exit(1);
|
||||||
/* LCOV_EXCL_STOP */
|
/* LCOV_EXCL_STOP */
|
||||||
}
|
}
|
||||||
#elif defined(HAVE_FTIME)
|
#elif defined(HAVE_FTIME)
|
||||||
|
@ -112,7 +112,7 @@ tor_gettimeofday, (struct timeval *timeval))
|
||||||
timeval->tv_usec = tb.millitm * 1000;
|
timeval->tv_usec = tb.millitm * 1000;
|
||||||
#else
|
#else
|
||||||
#error "No way to get time."
|
#error "No way to get time."
|
||||||
#endif /* defined(_WIN32) || ... */
|
#endif
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -187,8 +187,8 @@ monotime_coarse_set_mock_time_nsec(int64_t nsec)
|
||||||
tor_assert_nonfatal(monotime_mocking_enabled == 1);
|
tor_assert_nonfatal(monotime_mocking_enabled == 1);
|
||||||
mock_time_nsec_coarse = nsec;
|
mock_time_nsec_coarse = nsec;
|
||||||
}
|
}
|
||||||
#endif /* defined(MONOTIME_COARSE_FN_IS_DIFFERENT) */
|
#endif
|
||||||
#endif /* defined(TOR_UNIT_TESTS) */
|
#endif
|
||||||
|
|
||||||
/* "ratchet" functions for monotonic time. */
|
/* "ratchet" functions for monotonic time. */
|
||||||
|
|
||||||
|
@ -235,7 +235,7 @@ ratchet_coarse_performance_counter(const int64_t count_raw)
|
||||||
last_tick_count = count;
|
last_tick_count = count;
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
#endif /* defined(_WIN32) || defined(TOR_UNIT_TESTS) */
|
#endif
|
||||||
|
|
||||||
#if defined(MONOTIME_USING_GETTIMEOFDAY) || defined(TOR_UNIT_TESTS)
|
#if defined(MONOTIME_USING_GETTIMEOFDAY) || defined(TOR_UNIT_TESTS)
|
||||||
static struct timeval last_timeofday = { 0, 0 };
|
static struct timeval last_timeofday = { 0, 0 };
|
||||||
|
@ -251,7 +251,7 @@ ratchet_timeval(const struct timeval *timeval_raw, struct timeval *out)
|
||||||
{
|
{
|
||||||
/* must hold lock */
|
/* must hold lock */
|
||||||
timeradd(timeval_raw, &timeofday_offset, out);
|
timeradd(timeval_raw, &timeofday_offset, out);
|
||||||
if (PREDICT_UNLIKELY(timercmp(out, &last_timeofday, OP_LT))) {
|
if (PREDICT_UNLIKELY(timercmp(out, &last_timeofday, <))) {
|
||||||
/* time ran backwards. Instead, declare that no time occurred. */
|
/* time ran backwards. Instead, declare that no time occurred. */
|
||||||
timersub(&last_timeofday, timeval_raw, &timeofday_offset);
|
timersub(&last_timeofday, timeval_raw, &timeofday_offset);
|
||||||
memcpy(out, &last_timeofday, sizeof(struct timeval));
|
memcpy(out, &last_timeofday, sizeof(struct timeval));
|
||||||
|
@ -259,7 +259,7 @@ ratchet_timeval(const struct timeval *timeval_raw, struct timeval *out)
|
||||||
memcpy(&last_timeofday, out, sizeof(struct timeval));
|
memcpy(&last_timeofday, out, sizeof(struct timeval));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif /* defined(MONOTIME_USING_GETTIMEOFDAY) || defined(TOR_UNIT_TESTS) */
|
#endif
|
||||||
|
|
||||||
#ifdef TOR_UNIT_TESTS
|
#ifdef TOR_UNIT_TESTS
|
||||||
/** For testing: reset all the ratchets */
|
/** For testing: reset all the ratchets */
|
||||||
|
@ -271,7 +271,7 @@ monotime_reset_ratchets_for_testing(void)
|
||||||
memset(&last_timeofday, 0, sizeof(struct timeval));
|
memset(&last_timeofday, 0, sizeof(struct timeval));
|
||||||
memset(&timeofday_offset, 0, sizeof(struct timeval));
|
memset(&timeofday_offset, 0, sizeof(struct timeval));
|
||||||
}
|
}
|
||||||
#endif /* defined(TOR_UNIT_TESTS) */
|
#endif
|
||||||
|
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
|
|
||||||
|
@ -279,8 +279,6 @@ monotime_reset_ratchets_for_testing(void)
|
||||||
* nanoseconds.
|
* nanoseconds.
|
||||||
*/
|
*/
|
||||||
static struct mach_timebase_info mach_time_info;
|
static struct mach_timebase_info mach_time_info;
|
||||||
static struct mach_timebase_info mach_time_info_msec_cvt;
|
|
||||||
static int monotime_shift = 0;
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
monotime_init_internal(void)
|
monotime_init_internal(void)
|
||||||
|
@ -289,22 +287,6 @@ monotime_init_internal(void)
|
||||||
int r = mach_timebase_info(&mach_time_info);
|
int r = mach_timebase_info(&mach_time_info);
|
||||||
tor_assert(r == 0);
|
tor_assert(r == 0);
|
||||||
tor_assert(mach_time_info.denom != 0);
|
tor_assert(mach_time_info.denom != 0);
|
||||||
|
|
||||||
{
|
|
||||||
// approximate only.
|
|
||||||
uint64_t ns_per_tick = mach_time_info.numer / mach_time_info.denom;
|
|
||||||
uint64_t ms_per_tick = ns_per_tick * ONE_MILLION;
|
|
||||||
// requires that tor_log2(0) == 0.
|
|
||||||
monotime_shift = tor_log2(ms_per_tick);
|
|
||||||
}
|
|
||||||
{
|
|
||||||
// For converting ticks to milliseconds in a 32-bit-friendly way, we
|
|
||||||
// will first right-shift by 20, and then multiply by 20/19, since
|
|
||||||
// (1<<20) * 19/20 is about 1e6. We precompute a new numerate and
|
|
||||||
// denominator here to avoid multiple multiplies.
|
|
||||||
mach_time_info_msec_cvt.numer = mach_time_info.numer * 20;
|
|
||||||
mach_time_info_msec_cvt.denom = mach_time_info.denom * 19;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -319,25 +301,10 @@ monotime_get(monotime_t *out)
|
||||||
/ mach_time_info.numer;
|
/ mach_time_info.numer;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif /* defined(TOR_UNIT_TESTS) */
|
#endif
|
||||||
out->abstime_ = mach_absolute_time();
|
out->abstime_ = mach_absolute_time();
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(HAVE_MACH_APPROXIMATE_TIME)
|
|
||||||
void
|
|
||||||
monotime_coarse_get(monotime_coarse_t *out)
|
|
||||||
{
|
|
||||||
#ifdef TOR_UNIT_TESTS
|
|
||||||
if (monotime_mocking_enabled) {
|
|
||||||
out->abstime_ = (mock_time_nsec_coarse * mach_time_info.denom)
|
|
||||||
/ mach_time_info.numer;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
#endif /* defined(TOR_UNIT_TESTS) */
|
|
||||||
out->abstime_ = mach_approximate_time();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the number of nanoseconds between <b>start</b> and <b>end</b>.
|
* Return the number of nanoseconds between <b>start</b> and <b>end</b>.
|
||||||
*/
|
*/
|
||||||
|
@ -354,42 +321,6 @@ monotime_diff_nsec(const monotime_t *start,
|
||||||
return diff_nsec;
|
return diff_nsec;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t
|
|
||||||
monotime_coarse_diff_msec32_(const monotime_coarse_t *start,
|
|
||||||
const monotime_coarse_t *end)
|
|
||||||
{
|
|
||||||
if (BUG(mach_time_info.denom == 0)) {
|
|
||||||
monotime_init();
|
|
||||||
}
|
|
||||||
const int64_t diff_ticks = end->abstime_ - start->abstime_;
|
|
||||||
|
|
||||||
/* We already require in di_ops.c that right-shift performs a sign-extend. */
|
|
||||||
const int32_t diff_microticks = (int32_t)(diff_ticks >> 20);
|
|
||||||
|
|
||||||
return (diff_microticks * mach_time_info_msec_cvt.numer) /
|
|
||||||
mach_time_info_msec_cvt.denom;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t
|
|
||||||
monotime_coarse_to_stamp(const monotime_coarse_t *t)
|
|
||||||
{
|
|
||||||
return (uint32_t)(t->abstime_ >> monotime_shift);
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
monotime_is_zero(const monotime_t *val)
|
|
||||||
{
|
|
||||||
return val->abstime_ == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
monotime_add_msec(monotime_t *out, const monotime_t *val, uint32_t msec)
|
|
||||||
{
|
|
||||||
const uint64_t nsec = msec * ONE_MILLION;
|
|
||||||
const uint64_t ticks = (nsec * mach_time_info.denom) / mach_time_info.numer;
|
|
||||||
out->abstime_ = val->abstime_ + ticks;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* end of "__APPLE__" */
|
/* end of "__APPLE__" */
|
||||||
#elif defined(HAVE_CLOCK_GETTIME)
|
#elif defined(HAVE_CLOCK_GETTIME)
|
||||||
|
|
||||||
|
@ -401,7 +332,7 @@ monotime_add_msec(monotime_t *out, const monotime_t *val, uint32_t msec)
|
||||||
* an old Linux kernel. In that case, we will fall back to CLOCK_MONOTONIC.
|
* an old Linux kernel. In that case, we will fall back to CLOCK_MONOTONIC.
|
||||||
*/
|
*/
|
||||||
static int clock_monotonic_coarse = CLOCK_MONOTONIC_COARSE;
|
static int clock_monotonic_coarse = CLOCK_MONOTONIC_COARSE;
|
||||||
#endif /* defined(CLOCK_MONOTONIC_COARSE) */
|
#endif
|
||||||
|
|
||||||
static void
|
static void
|
||||||
monotime_init_internal(void)
|
monotime_init_internal(void)
|
||||||
|
@ -413,7 +344,7 @@ monotime_init_internal(void)
|
||||||
"falling back to CLOCK_MONOTONIC.", strerror(errno));
|
"falling back to CLOCK_MONOTONIC.", strerror(errno));
|
||||||
clock_monotonic_coarse = CLOCK_MONOTONIC;
|
clock_monotonic_coarse = CLOCK_MONOTONIC;
|
||||||
}
|
}
|
||||||
#endif /* defined(CLOCK_MONOTONIC_COARSE) */
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -425,7 +356,7 @@ monotime_get(monotime_t *out)
|
||||||
out->ts_.tv_nsec = (int) (mock_time_nsec % ONE_BILLION);
|
out->ts_.tv_nsec = (int) (mock_time_nsec % ONE_BILLION);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif /* defined(TOR_UNIT_TESTS) */
|
#endif
|
||||||
int r = clock_gettime(CLOCK_MONOTONIC, &out->ts_);
|
int r = clock_gettime(CLOCK_MONOTONIC, &out->ts_);
|
||||||
tor_assert(r == 0);
|
tor_assert(r == 0);
|
||||||
}
|
}
|
||||||
|
@ -440,7 +371,7 @@ monotime_coarse_get(monotime_coarse_t *out)
|
||||||
out->ts_.tv_nsec = (int) (mock_time_nsec_coarse % ONE_BILLION);
|
out->ts_.tv_nsec = (int) (mock_time_nsec_coarse % ONE_BILLION);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif /* defined(TOR_UNIT_TESTS) */
|
#endif
|
||||||
int r = clock_gettime(clock_monotonic_coarse, &out->ts_);
|
int r = clock_gettime(clock_monotonic_coarse, &out->ts_);
|
||||||
if (PREDICT_UNLIKELY(r < 0) &&
|
if (PREDICT_UNLIKELY(r < 0) &&
|
||||||
errno == EINVAL &&
|
errno == EINVAL &&
|
||||||
|
@ -455,7 +386,7 @@ monotime_coarse_get(monotime_coarse_t *out)
|
||||||
|
|
||||||
tor_assert(r == 0);
|
tor_assert(r == 0);
|
||||||
}
|
}
|
||||||
#endif /* defined(CLOCK_MONOTONIC_COARSE) */
|
#endif
|
||||||
|
|
||||||
int64_t
|
int64_t
|
||||||
monotime_diff_nsec(const monotime_t *start,
|
monotime_diff_nsec(const monotime_t *start,
|
||||||
|
@ -468,46 +399,6 @@ monotime_diff_nsec(const monotime_t *start,
|
||||||
return diff_nsec;
|
return diff_nsec;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t
|
|
||||||
monotime_coarse_diff_msec32_(const monotime_coarse_t *start,
|
|
||||||
const monotime_coarse_t *end)
|
|
||||||
{
|
|
||||||
const int32_t diff_sec = (int32_t)(end->ts_.tv_sec - start->ts_.tv_sec);
|
|
||||||
const int32_t diff_nsec = (int32_t)(end->ts_.tv_nsec - start->ts_.tv_nsec);
|
|
||||||
return diff_sec * 1000 + diff_nsec / ONE_MILLION;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* This value is ONE_BILLION >> 20. */
|
|
||||||
static const uint32_t STAMP_TICKS_PER_SECOND = 953;
|
|
||||||
|
|
||||||
uint32_t
|
|
||||||
monotime_coarse_to_stamp(const monotime_coarse_t *t)
|
|
||||||
{
|
|
||||||
uint32_t nsec = (uint32_t)t->ts_.tv_nsec;
|
|
||||||
uint32_t sec = (uint32_t)t->ts_.tv_sec;
|
|
||||||
|
|
||||||
return (sec * STAMP_TICKS_PER_SECOND) + (nsec >> 20);
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
monotime_is_zero(const monotime_t *val)
|
|
||||||
{
|
|
||||||
return val->ts_.tv_sec == 0 && val->ts_.tv_nsec == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
monotime_add_msec(monotime_t *out, const monotime_t *val, uint32_t msec)
|
|
||||||
{
|
|
||||||
const uint32_t sec = msec / 1000;
|
|
||||||
const uint32_t msec_remainder = msec % 1000;
|
|
||||||
out->ts_.tv_sec = val->ts_.tv_sec + sec;
|
|
||||||
out->ts_.tv_nsec = val->ts_.tv_nsec + (msec_remainder * ONE_MILLION);
|
|
||||||
if (out->ts_.tv_nsec > ONE_BILLION) {
|
|
||||||
out->ts_.tv_nsec -= ONE_BILLION;
|
|
||||||
out->ts_.tv_sec += 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* end of "HAVE_CLOCK_GETTIME" */
|
/* end of "HAVE_CLOCK_GETTIME" */
|
||||||
#elif defined (_WIN32)
|
#elif defined (_WIN32)
|
||||||
|
|
||||||
|
@ -571,7 +462,7 @@ monotime_get(monotime_t *out)
|
||||||
/ nsec_per_tick_numer;
|
/ nsec_per_tick_numer;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif /* defined(TOR_UNIT_TESTS) */
|
#endif
|
||||||
|
|
||||||
/* Alas, QueryPerformanceCounter is not always monotonic: see bug list at
|
/* Alas, QueryPerformanceCounter is not always monotonic: see bug list at
|
||||||
|
|
||||||
|
@ -595,7 +486,7 @@ monotime_coarse_get(monotime_coarse_t *out)
|
||||||
out->tick_count_ = mock_time_nsec_coarse / ONE_MILLION;
|
out->tick_count_ = mock_time_nsec_coarse / ONE_MILLION;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif /* defined(TOR_UNIT_TESTS) */
|
#endif
|
||||||
|
|
||||||
if (GetTickCount64_fn) {
|
if (GetTickCount64_fn) {
|
||||||
out->tick_count_ = (int64_t)GetTickCount64_fn();
|
out->tick_count_ = (int64_t)GetTickCount64_fn();
|
||||||
|
@ -626,13 +517,6 @@ monotime_coarse_diff_msec(const monotime_coarse_t *start,
|
||||||
return diff_ticks;
|
return diff_ticks;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t
|
|
||||||
monotime_coarse_diff_msec32_(const monotime_coarse_t *start,
|
|
||||||
const monotime_coarse_t *end)
|
|
||||||
{
|
|
||||||
return (int32_t)monotime_coarse_diff_msec(start, end);
|
|
||||||
}
|
|
||||||
|
|
||||||
int64_t
|
int64_t
|
||||||
monotime_coarse_diff_usec(const monotime_coarse_t *start,
|
monotime_coarse_diff_usec(const monotime_coarse_t *start,
|
||||||
const monotime_coarse_t *end)
|
const monotime_coarse_t *end)
|
||||||
|
@ -647,41 +531,6 @@ monotime_coarse_diff_nsec(const monotime_coarse_t *start,
|
||||||
return monotime_coarse_diff_msec(start, end) * ONE_MILLION;
|
return monotime_coarse_diff_msec(start, end) * ONE_MILLION;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const uint32_t STAMP_TICKS_PER_SECOND = 1000;
|
|
||||||
|
|
||||||
uint32_t
|
|
||||||
monotime_coarse_to_stamp(const monotime_coarse_t *t)
|
|
||||||
{
|
|
||||||
return (uint32_t) t->tick_count_;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
monotime_is_zero(const monotime_t *val)
|
|
||||||
{
|
|
||||||
return val->pcount_ == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
monotime_coarse_is_zero(const monotime_coarse_t *val)
|
|
||||||
{
|
|
||||||
return val->tick_count_ == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
monotime_add_msec(monotime_t *out, const monotime_t *val, uint32_t msec)
|
|
||||||
{
|
|
||||||
const uint64_t nsec = msec * ONE_MILLION;
|
|
||||||
const uint64_t ticks = (nsec * nsec_per_tick_denom) / nsec_per_tick_numer;
|
|
||||||
out->pcount_ = val->pcount_ + ticks;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
monotime_coarse_add_msec(monotime_coarse_t *out, const monotime_coarse_t *val,
|
|
||||||
uint32_t msec)
|
|
||||||
{
|
|
||||||
out->tick_count_ = val->tick_count_ + msec;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* end of "_WIN32" */
|
/* end of "_WIN32" */
|
||||||
#elif defined(MONOTIME_USING_GETTIMEOFDAY)
|
#elif defined(MONOTIME_USING_GETTIMEOFDAY)
|
||||||
|
|
||||||
|
@ -718,49 +567,10 @@ monotime_diff_nsec(const monotime_t *start,
|
||||||
return (diff.tv_sec * ONE_BILLION + diff.tv_usec * 1000);
|
return (diff.tv_sec * ONE_BILLION + diff.tv_usec * 1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t
|
|
||||||
monotime_coarse_diff_msec32_(const monotime_coarse_t *start,
|
|
||||||
const monotime_coarse_t *end)
|
|
||||||
{
|
|
||||||
struct timeval diff;
|
|
||||||
timersub(&end->tv_, &start->tv_, &diff);
|
|
||||||
return diff.tv_sec * 1000 + diff.tv_usec / 1000;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* This value is ONE_MILLION >> 10. */
|
|
||||||
static const uint32_t STAMP_TICKS_PER_SECOND = 976;
|
|
||||||
|
|
||||||
uint32_t
|
|
||||||
monotime_coarse_to_stamp(const monotime_coarse_t *t)
|
|
||||||
{
|
|
||||||
const uint32_t usec = (uint32_t)t->tv_.tv_usec;
|
|
||||||
const uint32_t sec = (uint32_t)t->tv_.tv_sec;
|
|
||||||
return (sec * STAMP_TICKS_PER_SECOND) | (nsec >> 10);
|
|
||||||
}
|
|
||||||
|
|
||||||
int
|
|
||||||
monotime_is_zero(const monotime_t *val)
|
|
||||||
{
|
|
||||||
return val->tv_.tv_sec == 0 && val->tv_.tv_usec == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
monotime_add_msec(monotime_t *out, const monotime_t *val, uint32_t msec)
|
|
||||||
{
|
|
||||||
const uint32_t sec = msec / 1000;
|
|
||||||
const uint32_t msec_remainder = msec % 1000;
|
|
||||||
out->tv_.tv_sec = val->tv_.tv_sec + sec;
|
|
||||||
out->tv_.tv_usec = val->tv_.tv_nsec + (msec_remainder * 1000);
|
|
||||||
if (out->tv_.tv_usec > ONE_MILLION) {
|
|
||||||
out->tv_.tv_usec -= ONE_MILLION;
|
|
||||||
out->tv_.tv_sec += 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* end of "MONOTIME_USING_GETTIMEOFDAY" */
|
/* end of "MONOTIME_USING_GETTIMEOFDAY" */
|
||||||
#else
|
#else
|
||||||
#error "No way to implement monotonic timers."
|
#error "No way to implement monotonic timers."
|
||||||
#endif /* defined(__APPLE__) || ... */
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize the monotonic timer subsystem. Must be called before any
|
* Initialize the monotonic timer subsystem. Must be called before any
|
||||||
|
@ -779,19 +589,6 @@ monotime_init(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
monotime_zero(monotime_t *out)
|
|
||||||
{
|
|
||||||
memset(out, 0, sizeof(*out));
|
|
||||||
}
|
|
||||||
#ifdef MONOTIME_COARSE_TYPE_IS_DIFFERENT
|
|
||||||
void
|
|
||||||
monotime_coarse_zero(monotime_coarse_t *out)
|
|
||||||
{
|
|
||||||
memset(out, 0, sizeof(*out));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
int64_t
|
int64_t
|
||||||
monotime_diff_usec(const monotime_t *start,
|
monotime_diff_usec(const monotime_t *start,
|
||||||
const monotime_t *end)
|
const monotime_t *end)
|
||||||
|
@ -856,48 +653,5 @@ monotime_coarse_absolute_msec(void)
|
||||||
{
|
{
|
||||||
return monotime_coarse_absolute_nsec() / ONE_MILLION;
|
return monotime_coarse_absolute_nsec() / ONE_MILLION;
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
#define initialized_at_coarse initialized_at
|
|
||||||
#endif /* defined(MONOTIME_COARSE_FN_IS_DIFFERENT) */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return the current time "stamp" as described by monotime_coarse_to_stamp.
|
|
||||||
*/
|
|
||||||
uint32_t
|
|
||||||
monotime_coarse_get_stamp(void)
|
|
||||||
{
|
|
||||||
monotime_coarse_t now;
|
|
||||||
monotime_coarse_get(&now);
|
|
||||||
return monotime_coarse_to_stamp(&now);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef __APPLE__
|
|
||||||
uint64_t
|
|
||||||
monotime_coarse_stamp_units_to_approx_msec(uint64_t units)
|
|
||||||
{
|
|
||||||
/* Recover as much precision as we can. */
|
|
||||||
uint64_t abstime_diff = (units << monotime_shift);
|
|
||||||
return (abstime_diff * mach_time_info.numer) /
|
|
||||||
(mach_time_info.denom * ONE_MILLION);
|
|
||||||
}
|
|
||||||
uint64_t
|
|
||||||
monotime_msec_to_approx_coarse_stamp_units(uint64_t msec)
|
|
||||||
{
|
|
||||||
uint64_t abstime_val =
|
|
||||||
(((uint64_t)msec) * ONE_MILLION * mach_time_info.denom) /
|
|
||||||
mach_time_info.numer;
|
|
||||||
return abstime_val >> monotime_shift;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
uint64_t
|
|
||||||
monotime_coarse_stamp_units_to_approx_msec(uint64_t units)
|
|
||||||
{
|
|
||||||
return (units * 1000) / STAMP_TICKS_PER_SECOND;
|
|
||||||
}
|
|
||||||
uint64_t
|
|
||||||
monotime_msec_to_approx_coarse_stamp_units(uint64_t msec)
|
|
||||||
{
|
|
||||||
return (msec * STAMP_TICKS_PER_SECOND) / 1000;
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -28,13 +28,13 @@
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !defined(HAVE_STRUCT_TIMEVAL_TV_SEC)
|
#if !defined(HAVE_GETTIMEOFDAY) && !defined(HAVE_STRUCT_TIMEVAL_TV_SEC)
|
||||||
/** Implementation of timeval for platforms that don't have it. */
|
/** Implementation of timeval for platforms that don't have it. */
|
||||||
struct timeval {
|
struct timeval {
|
||||||
time_t tv_sec;
|
time_t tv_sec;
|
||||||
unsigned int tv_usec;
|
unsigned int tv_usec;
|
||||||
};
|
};
|
||||||
#endif /* !defined(HAVE_STRUCT_TIMEVAL_TV_SEC) */
|
#endif
|
||||||
|
|
||||||
/** Represents a monotonic timer in a platform-dependent way. */
|
/** Represents a monotonic timer in a platform-dependent way. */
|
||||||
typedef struct monotime_t {
|
typedef struct monotime_t {
|
||||||
|
@ -51,11 +51,10 @@ typedef struct monotime_t {
|
||||||
#define MONOTIME_USING_GETTIMEOFDAY
|
#define MONOTIME_USING_GETTIMEOFDAY
|
||||||
/* Otherwise, we will be stuck using gettimeofday. */
|
/* Otherwise, we will be stuck using gettimeofday. */
|
||||||
struct timeval tv_;
|
struct timeval tv_;
|
||||||
#endif /* defined(__APPLE__) || ... */
|
#endif
|
||||||
} monotime_t;
|
} monotime_t;
|
||||||
|
|
||||||
#if defined(CLOCK_MONOTONIC_COARSE) && \
|
#if defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_MONOTONIC_COARSE)
|
||||||
defined(HAVE_CLOCK_GETTIME)
|
|
||||||
#define MONOTIME_COARSE_FN_IS_DIFFERENT
|
#define MONOTIME_COARSE_FN_IS_DIFFERENT
|
||||||
#define monotime_coarse_t monotime_t
|
#define monotime_coarse_t monotime_t
|
||||||
#elif defined(_WIN32)
|
#elif defined(_WIN32)
|
||||||
|
@ -65,12 +64,9 @@ typedef struct monotime_t {
|
||||||
typedef struct monotime_coarse_t {
|
typedef struct monotime_coarse_t {
|
||||||
uint64_t tick_count_;
|
uint64_t tick_count_;
|
||||||
} monotime_coarse_t;
|
} monotime_coarse_t;
|
||||||
#elif defined(__APPLE__) && defined(HAVE_MACH_APPROXIMATE_TIME)
|
|
||||||
#define MONOTIME_COARSE_FN_IS_DIFFERENT
|
|
||||||
#define monotime_coarse_t monotime_t
|
|
||||||
#else
|
#else
|
||||||
#define monotime_coarse_t monotime_t
|
#define monotime_coarse_t monotime_t
|
||||||
#endif /* defined(CLOCK_MONOTONIC_COARSE) && ... || ... */
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize the timing subsystem. This function is idempotent.
|
* Initialize the timing subsystem. This function is idempotent.
|
||||||
|
@ -105,21 +101,6 @@ uint64_t monotime_absolute_usec(void);
|
||||||
*/
|
*/
|
||||||
uint64_t monotime_absolute_msec(void);
|
uint64_t monotime_absolute_msec(void);
|
||||||
|
|
||||||
/**
|
|
||||||
* Set <b>out</b> to zero.
|
|
||||||
*/
|
|
||||||
void monotime_zero(monotime_t *out);
|
|
||||||
/**
|
|
||||||
* Return true iff <b>out</b> is zero
|
|
||||||
*/
|
|
||||||
int monotime_is_zero(const monotime_t *out);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set <b>out</b> to N milliseconds after <b>val</b>.
|
|
||||||
*/
|
|
||||||
/* XXXX We should add a more generic function here if we ever need to */
|
|
||||||
void monotime_add_msec(monotime_t *out, const monotime_t *val, uint32_t msec);
|
|
||||||
|
|
||||||
#if defined(MONOTIME_COARSE_FN_IS_DIFFERENT)
|
#if defined(MONOTIME_COARSE_FN_IS_DIFFERENT)
|
||||||
/**
|
/**
|
||||||
* Set <b>out</b> to the current coarse time.
|
* Set <b>out</b> to the current coarse time.
|
||||||
|
@ -128,30 +109,12 @@ void monotime_coarse_get(monotime_coarse_t *out);
|
||||||
uint64_t monotime_coarse_absolute_nsec(void);
|
uint64_t monotime_coarse_absolute_nsec(void);
|
||||||
uint64_t monotime_coarse_absolute_usec(void);
|
uint64_t monotime_coarse_absolute_usec(void);
|
||||||
uint64_t monotime_coarse_absolute_msec(void);
|
uint64_t monotime_coarse_absolute_msec(void);
|
||||||
#else /* !(defined(MONOTIME_COARSE_FN_IS_DIFFERENT)) */
|
#else
|
||||||
#define monotime_coarse_get monotime_get
|
#define monotime_coarse_get monotime_get
|
||||||
#define monotime_coarse_absolute_nsec monotime_absolute_nsec
|
#define monotime_coarse_absolute_nsec monotime_absolute_nsec
|
||||||
#define monotime_coarse_absolute_usec monotime_absolute_usec
|
#define monotime_coarse_absolute_usec monotime_absolute_usec
|
||||||
#define monotime_coarse_absolute_msec monotime_absolute_msec
|
#define monotime_coarse_absolute_msec monotime_absolute_msec
|
||||||
#endif /* defined(MONOTIME_COARSE_FN_IS_DIFFERENT) */
|
#endif
|
||||||
|
|
||||||
/**
|
|
||||||
* Return a "timestamp" approximation for a coarse monotonic timer.
|
|
||||||
* This timestamp is meant to be fast to calculate and easy to
|
|
||||||
* compare, and have a unit of something roughly around 1 msec.
|
|
||||||
*
|
|
||||||
* It will wrap over from time to time.
|
|
||||||
*
|
|
||||||
* It has no defined zero point.
|
|
||||||
*/
|
|
||||||
uint32_t monotime_coarse_to_stamp(const monotime_coarse_t *t);
|
|
||||||
/**
|
|
||||||
* Convert a difference, expressed in the units of monotime_coarse_to_stamp,
|
|
||||||
* into an approximate number of milliseconds.
|
|
||||||
*/
|
|
||||||
uint64_t monotime_coarse_stamp_units_to_approx_msec(uint64_t units);
|
|
||||||
uint64_t monotime_msec_to_approx_coarse_stamp_units(uint64_t msec);
|
|
||||||
uint32_t monotime_coarse_get_stamp(void);
|
|
||||||
|
|
||||||
#if defined(MONOTIME_COARSE_TYPE_IS_DIFFERENT)
|
#if defined(MONOTIME_COARSE_TYPE_IS_DIFFERENT)
|
||||||
int64_t monotime_coarse_diff_nsec(const monotime_coarse_t *start,
|
int64_t monotime_coarse_diff_nsec(const monotime_coarse_t *start,
|
||||||
|
@ -160,47 +123,13 @@ int64_t monotime_coarse_diff_usec(const monotime_coarse_t *start,
|
||||||
const monotime_coarse_t *end);
|
const monotime_coarse_t *end);
|
||||||
int64_t monotime_coarse_diff_msec(const monotime_coarse_t *start,
|
int64_t monotime_coarse_diff_msec(const monotime_coarse_t *start,
|
||||||
const monotime_coarse_t *end);
|
const monotime_coarse_t *end);
|
||||||
void monotime_coarse_zero(monotime_coarse_t *out);
|
#else
|
||||||
int monotime_coarse_is_zero(const monotime_coarse_t *val);
|
|
||||||
void monotime_coarse_add_msec(monotime_coarse_t *out,
|
|
||||||
const monotime_coarse_t *val, uint32_t msec);
|
|
||||||
#else /* !(defined(MONOTIME_COARSE_TYPE_IS_DIFFERENT)) */
|
|
||||||
#define monotime_coarse_diff_nsec monotime_diff_nsec
|
#define monotime_coarse_diff_nsec monotime_diff_nsec
|
||||||
#define monotime_coarse_diff_usec monotime_diff_usec
|
#define monotime_coarse_diff_usec monotime_diff_usec
|
||||||
#define monotime_coarse_diff_msec monotime_diff_msec
|
#define monotime_coarse_diff_msec monotime_diff_msec
|
||||||
#define monotime_coarse_zero monotime_zero
|
|
||||||
#define monotime_coarse_is_zero monotime_is_zero
|
|
||||||
#define monotime_coarse_add_msec monotime_add_msec
|
|
||||||
#endif /* defined(MONOTIME_COARSE_TYPE_IS_DIFFERENT) */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* As monotime_coarse_diff_msec, but avoid 64-bit division.
|
|
||||||
*
|
|
||||||
* Requires that the difference fit into an int32_t; not for use with
|
|
||||||
* large time differences.
|
|
||||||
*/
|
|
||||||
int32_t monotime_coarse_diff_msec32_(const monotime_coarse_t *start,
|
|
||||||
const monotime_coarse_t *end);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* As monotime_coarse_diff_msec, but avoid 64-bit division if it is expensive.
|
|
||||||
*
|
|
||||||
* Requires that the difference fit into an int32_t; not for use with
|
|
||||||
* large time differences.
|
|
||||||
*/
|
|
||||||
static inline int32_t
|
|
||||||
monotime_coarse_diff_msec32(const monotime_coarse_t *start,
|
|
||||||
const monotime_coarse_t *end)
|
|
||||||
{
|
|
||||||
#if SIZEOF_VOID_P == 8
|
|
||||||
// on a 64-bit platform, let's assume 64/64 division is cheap.
|
|
||||||
return (int32_t) monotime_coarse_diff_msec(start, end);
|
|
||||||
#else
|
|
||||||
return monotime_coarse_diff_msec32_(start, end);
|
|
||||||
#endif
|
#endif
|
||||||
}
|
|
||||||
|
|
||||||
MOCK_DECL(void, tor_gettimeofday, (struct timeval *timeval));
|
void tor_gettimeofday(struct timeval *timeval);
|
||||||
|
|
||||||
#ifdef TOR_UNIT_TESTS
|
#ifdef TOR_UNIT_TESTS
|
||||||
void tor_sleep_msec(int msec);
|
void tor_sleep_msec(int msec);
|
||||||
|
@ -213,7 +142,7 @@ void monotime_coarse_set_mock_time_nsec(int64_t);
|
||||||
#else
|
#else
|
||||||
#define monotime_coarse_set_mock_time_nsec monotime_set_mock_time_nsec
|
#define monotime_coarse_set_mock_time_nsec monotime_set_mock_time_nsec
|
||||||
#endif
|
#endif
|
||||||
#endif /* defined(TOR_UNIT_TESTS) */
|
#endif
|
||||||
|
|
||||||
#ifdef COMPAT_TIME_PRIVATE
|
#ifdef COMPAT_TIME_PRIVATE
|
||||||
#if defined(_WIN32) || defined(TOR_UNIT_TESTS)
|
#if defined(_WIN32) || defined(TOR_UNIT_TESTS)
|
||||||
|
@ -227,7 +156,7 @@ STATIC void ratchet_timeval(const struct timeval *timeval_raw,
|
||||||
#ifdef TOR_UNIT_TESTS
|
#ifdef TOR_UNIT_TESTS
|
||||||
void monotime_reset_ratchets_for_testing(void);
|
void monotime_reset_ratchets_for_testing(void);
|
||||||
#endif
|
#endif
|
||||||
#endif /* defined(COMPAT_TIME_PRIVATE) */
|
#endif
|
||||||
|
|
||||||
#endif /* !defined(TOR_COMPAT_TIME_H) */
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "container.h"
|
#include "container.h"
|
||||||
#include "torlog.h"
|
#include "torlog.h"
|
||||||
|
#include <process.h>
|
||||||
|
|
||||||
/* This value is more or less total cargo-cult */
|
/* This value is more or less total cargo-cult */
|
||||||
#define SPIN_COUNT 2000
|
#define SPIN_COUNT 2000
|
||||||
|
@ -47,12 +48,10 @@ void
|
||||||
spawn_exit(void)
|
spawn_exit(void)
|
||||||
{
|
{
|
||||||
_endthread();
|
_endthread();
|
||||||
// LCOV_EXCL_START
|
|
||||||
//we should never get here. my compiler thinks that _endthread returns, this
|
//we should never get here. my compiler thinks that _endthread returns, this
|
||||||
//is an attempt to fool it.
|
//is an attempt to fool it.
|
||||||
tor_assert(0);
|
tor_assert(0);
|
||||||
_exit(0); // exit ok: unreachable.
|
_exit(0);
|
||||||
// LCOV_EXCL_STOP
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -247,5 +246,5 @@ tor_threads_init(void)
|
||||||
set_main_thread();
|
set_main_thread();
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* defined(_WIN32) */
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -51,8 +51,8 @@ static atomic_counter_t total_compress_allocation;
|
||||||
|
|
||||||
/** Return true if uncompressing an input of size <b>in_size</b> to an input of
|
/** Return true if uncompressing an input of size <b>in_size</b> to an input of
|
||||||
* size at least <b>size_out</b> looks like a compression bomb. */
|
* size at least <b>size_out</b> looks like a compression bomb. */
|
||||||
MOCK_IMPL(int,
|
int
|
||||||
tor_compress_is_compression_bomb,(size_t size_in, size_t size_out))
|
tor_compress_is_compression_bomb(size_t size_in, size_t size_out)
|
||||||
{
|
{
|
||||||
if (size_in == 0 || size_out < CHECK_FOR_COMPRESSION_BOMB_AFTER)
|
if (size_in == 0 || size_out < CHECK_FOR_COMPRESSION_BOMB_AFTER)
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -164,7 +164,7 @@ tor_compress_impl(int compress,
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
if (out_alloc >= SIZE_T_CEILING / 2) {
|
if (out_alloc >= SIZE_T_CEILING / 2) {
|
||||||
log_warn(LD_GENERAL, "While %scompressing data: ran out of space.",
|
log_warn(LD_GENERAL, "While %scompresing data: ran out of space.",
|
||||||
compress?"":"un");
|
compress?"":"un");
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
@ -185,12 +185,11 @@ tor_compress_impl(int compress,
|
||||||
}
|
}
|
||||||
case TOR_COMPRESS_ERROR:
|
case TOR_COMPRESS_ERROR:
|
||||||
log_fn(protocol_warn_level, LD_GENERAL,
|
log_fn(protocol_warn_level, LD_GENERAL,
|
||||||
"Error while %scompressing data: bad input?",
|
"Error while %scompresing data: bad input?",
|
||||||
compress?"":"un");
|
compress?"":"un");
|
||||||
goto err; // bad data.
|
goto err; // bad data.
|
||||||
|
|
||||||
// LCOV_EXCL_START
|
|
||||||
default:
|
default:
|
||||||
|
// LCOV_EXCL_START
|
||||||
tor_assert_nonfatal_unreached();
|
tor_assert_nonfatal_unreached();
|
||||||
goto err;
|
goto err;
|
||||||
// LCOV_EXCL_STOP
|
// LCOV_EXCL_STOP
|
||||||
|
@ -562,9 +561,9 @@ tor_compress_process(tor_compress_state_t *state,
|
||||||
finish);
|
finish);
|
||||||
break;
|
break;
|
||||||
case LZMA_METHOD:
|
case LZMA_METHOD:
|
||||||
rv = tor_lzma_compress_process(state->u.lzma_state,
|
rv =tor_lzma_compress_process(state->u.lzma_state,
|
||||||
out, out_len, in, in_len,
|
out, out_len, in, in_len,
|
||||||
finish);
|
finish);
|
||||||
break;
|
break;
|
||||||
case ZSTD_METHOD:
|
case ZSTD_METHOD:
|
||||||
rv = tor_zstd_compress_process(state->u.zstd_state,
|
rv = tor_zstd_compress_process(state->u.zstd_state,
|
||||||
|
@ -582,12 +581,6 @@ tor_compress_process(tor_compress_state_t *state,
|
||||||
if (BUG((rv == TOR_COMPRESS_OK) &&
|
if (BUG((rv == TOR_COMPRESS_OK) &&
|
||||||
*in_len == in_len_orig &&
|
*in_len == in_len_orig &&
|
||||||
*out_len == out_len_orig)) {
|
*out_len == out_len_orig)) {
|
||||||
log_warn(LD_GENERAL,
|
|
||||||
"More info on the bug: method == %s, finish == %d, "
|
|
||||||
" *in_len == in_len_orig == %lu, "
|
|
||||||
"*out_len == out_len_orig == %lu",
|
|
||||||
compression_method_get_human_name(state->method), finish,
|
|
||||||
(unsigned long)in_len_orig, (unsigned long)out_len_orig);
|
|
||||||
return TOR_COMPRESS_ERROR;
|
return TOR_COMPRESS_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -598,7 +591,7 @@ tor_compress_process(tor_compress_state_t *state,
|
||||||
|
|
||||||
/** Deallocate <b>state</b>. */
|
/** Deallocate <b>state</b>. */
|
||||||
void
|
void
|
||||||
tor_compress_free_(tor_compress_state_t *state)
|
tor_compress_free(tor_compress_state_t *state)
|
||||||
{
|
{
|
||||||
if (state == NULL)
|
if (state == NULL)
|
||||||
return;
|
return;
|
||||||
|
@ -663,13 +656,3 @@ tor_compress_init(void)
|
||||||
tor_zstd_init();
|
tor_zstd_init();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Warn if we had any problems while setting up our compression libraries.
|
|
||||||
*
|
|
||||||
* (This isn't part of tor_compress_init, since the logs aren't set up yet.)
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
tor_compress_log_init_warnings(void)
|
|
||||||
{
|
|
||||||
tor_zstd_warn_if_version_mismatched();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
|
@ -45,8 +45,7 @@ int tor_uncompress(char **out, size_t *out_len,
|
||||||
|
|
||||||
compress_method_t detect_compression_method(const char *in, size_t in_len);
|
compress_method_t detect_compression_method(const char *in, size_t in_len);
|
||||||
|
|
||||||
MOCK_DECL(int,tor_compress_is_compression_bomb,(size_t size_in,
|
int tor_compress_is_compression_bomb(size_t size_in, size_t size_out);
|
||||||
size_t size_out));
|
|
||||||
|
|
||||||
int tor_compress_supports_method(compress_method_t method);
|
int tor_compress_supports_method(compress_method_t method);
|
||||||
unsigned tor_compress_get_supported_method_bitmask(void);
|
unsigned tor_compress_get_supported_method_bitmask(void);
|
||||||
|
@ -80,14 +79,11 @@ tor_compress_output_t tor_compress_process(tor_compress_state_t *state,
|
||||||
char **out, size_t *out_len,
|
char **out, size_t *out_len,
|
||||||
const char **in, size_t *in_len,
|
const char **in, size_t *in_len,
|
||||||
int finish);
|
int finish);
|
||||||
void tor_compress_free_(tor_compress_state_t *state);
|
void tor_compress_free(tor_compress_state_t *state);
|
||||||
#define tor_compress_free(st) \
|
|
||||||
FREE_AND_NULL(tor_compress_state_t, tor_compress_free_, (st))
|
|
||||||
|
|
||||||
size_t tor_compress_state_size(const tor_compress_state_t *state);
|
size_t tor_compress_state_size(const tor_compress_state_t *state);
|
||||||
|
|
||||||
void tor_compress_init(void);
|
void tor_compress_init(void);
|
||||||
void tor_compress_log_init_warnings(void);
|
|
||||||
|
|
||||||
#endif /* !defined(TOR_COMPRESS_H) */
|
#endif // TOR_COMPRESS_H.
|
||||||
|
|
||||||
|
|
|
@ -75,7 +75,7 @@ lzma_error_str(lzma_ret error)
|
||||||
return "Unknown LZMA error";
|
return "Unknown LZMA error";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif /* defined(HAVE_LZMA) */
|
#endif // HAVE_LZMA.
|
||||||
|
|
||||||
/** Return 1 if LZMA compression is supported; otherwise 0. */
|
/** Return 1 if LZMA compression is supported; otherwise 0. */
|
||||||
int
|
int
|
||||||
|
@ -158,12 +158,10 @@ tor_lzma_state_size_precalc(int compress, compression_level_t level)
|
||||||
|
|
||||||
return (size_t)memory_usage;
|
return (size_t)memory_usage;
|
||||||
|
|
||||||
// LCOV_EXCL_START
|
|
||||||
err:
|
err:
|
||||||
return 0;
|
return 0; // LCOV_EXCL_LINE
|
||||||
// LCOV_EXCL_STOP
|
|
||||||
}
|
}
|
||||||
#endif /* defined(HAVE_LZMA) */
|
#endif // HAVE_LZMA.
|
||||||
|
|
||||||
/** Construct and return a tor_lzma_compress_state_t object using
|
/** Construct and return a tor_lzma_compress_state_t object using
|
||||||
* <b>method</b>. If <b>compress</b>, it's for compression; otherwise it's for
|
* <b>method</b>. If <b>compress</b>, it's for compression; otherwise it's for
|
||||||
|
@ -214,18 +212,16 @@ tor_lzma_compress_new(int compress,
|
||||||
atomic_counter_add(&total_lzma_allocation, result->allocation);
|
atomic_counter_add(&total_lzma_allocation, result->allocation);
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
/* LCOV_EXCL_START */
|
|
||||||
err:
|
err:
|
||||||
tor_free(result);
|
tor_free(result); // LCOV_EXCL_LINE
|
||||||
return NULL;
|
return NULL;
|
||||||
/* LCOV_EXCL_STOP */
|
#else // HAVE_LZMA.
|
||||||
#else /* !(defined(HAVE_LZMA)) */
|
|
||||||
(void)compress;
|
(void)compress;
|
||||||
(void)method;
|
(void)method;
|
||||||
(void)level;
|
(void)level;
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
#endif /* defined(HAVE_LZMA) */
|
#endif // HAVE_LZMA.
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Compress/decompress some bytes using <b>state</b>. Read up to
|
/** Compress/decompress some bytes using <b>state</b>. Read up to
|
||||||
|
@ -310,7 +306,7 @@ tor_lzma_compress_process(tor_lzma_compress_state_t *state,
|
||||||
lzma_error_str(retval));
|
lzma_error_str(retval));
|
||||||
return TOR_COMPRESS_ERROR;
|
return TOR_COMPRESS_ERROR;
|
||||||
}
|
}
|
||||||
#else /* !(defined(HAVE_LZMA)) */
|
#else // HAVE_LZMA.
|
||||||
(void)state;
|
(void)state;
|
||||||
(void)out;
|
(void)out;
|
||||||
(void)out_len;
|
(void)out_len;
|
||||||
|
@ -318,12 +314,12 @@ tor_lzma_compress_process(tor_lzma_compress_state_t *state,
|
||||||
(void)in_len;
|
(void)in_len;
|
||||||
(void)finish;
|
(void)finish;
|
||||||
return TOR_COMPRESS_ERROR;
|
return TOR_COMPRESS_ERROR;
|
||||||
#endif /* defined(HAVE_LZMA) */
|
#endif // HAVE_LZMA.
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Deallocate <b>state</b>. */
|
/** Deallocate <b>state</b>. */
|
||||||
void
|
void
|
||||||
tor_lzma_compress_free_(tor_lzma_compress_state_t *state)
|
tor_lzma_compress_free(tor_lzma_compress_state_t *state)
|
||||||
{
|
{
|
||||||
if (state == NULL)
|
if (state == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -31,10 +31,7 @@ tor_lzma_compress_process(tor_lzma_compress_state_t *state,
|
||||||
const char **in, size_t *in_len,
|
const char **in, size_t *in_len,
|
||||||
int finish);
|
int finish);
|
||||||
|
|
||||||
void tor_lzma_compress_free_(tor_lzma_compress_state_t *state);
|
void tor_lzma_compress_free(tor_lzma_compress_state_t *state);
|
||||||
#define tor_lzma_compress_free(st) \
|
|
||||||
FREE_AND_NULL(tor_lzma_compress_state_t, \
|
|
||||||
tor_lzma_compress_free_, (st))
|
|
||||||
|
|
||||||
size_t tor_lzma_compress_state_size(const tor_lzma_compress_state_t *state);
|
size_t tor_lzma_compress_state_size(const tor_lzma_compress_state_t *state);
|
||||||
|
|
||||||
|
@ -42,5 +39,5 @@ size_t tor_lzma_get_total_allocation(void);
|
||||||
|
|
||||||
void tor_lzma_init(void);
|
void tor_lzma_init(void);
|
||||||
|
|
||||||
#endif /* !defined(TOR_COMPRESS_LZMA_H) */
|
#endif // TOR_COMPRESS_LZMA_H.
|
||||||
|
|
||||||
|
|
|
@ -16,5 +16,5 @@ tor_cnone_compress_process(char **out, size_t *out_len,
|
||||||
const char **in, size_t *in_len,
|
const char **in, size_t *in_len,
|
||||||
int finish);
|
int finish);
|
||||||
|
|
||||||
#endif /* !defined(TOR_COMPRESS_NONE_H) */
|
#endif // TOR_COMPRESS_NONE_H.
|
||||||
|
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue