Compare commits
143 Commits
master
...
release-0.
Author | SHA1 | Date |
---|---|---|
Nick Mathewson | 279fa65d34 | |
Nick Mathewson | 1d281eb933 | |
Nick Mathewson | 0d63a60643 | |
Nick Mathewson | b2c220a623 | |
Nick Mathewson | 7d1d868ea0 | |
Nick Mathewson | e212c752f2 | |
Nick Mathewson | eb0c7ab433 | |
Nick Mathewson | ba0c0ef771 | |
Nick Mathewson | beeeeb0afa | |
Nick Mathewson | ca19b2115a | |
Nick Mathewson | 20ca62ffb5 | |
Nick Mathewson | 9cb1c2b4ad | |
Nick Mathewson | 7d83cfb3ab | |
Nick Mathewson | b97fb313a9 | |
Nick Mathewson | 4902cfcf19 | |
Nick Mathewson | 6d0f332a2e | |
Nick Mathewson | 6177674a5b | |
Nick Mathewson | e26f387026 | |
Nick Mathewson | 765fd0845f | |
Nick Mathewson | 5a0e73c75b | |
Nick Mathewson | 078604630d | |
Nick Mathewson | 8669a1ea50 | |
Nick Mathewson | 55c918e7d2 | |
Nick Mathewson | 5e1bad3259 | |
Nick Mathewson | 533ae56fcf | |
Nick Mathewson | 558eafe56e | |
Nick Mathewson | e2979ebe25 | |
Nick Mathewson | e17659b701 | |
Nick Mathewson | 4e10ada1e8 | |
Nick Mathewson | 2e2ec4cb5e | |
Nick Mathewson | 0c44446c40 | |
Nick Mathewson | d1340423fa | |
Nick Mathewson | e4d7f97c40 | |
Nick Mathewson | 9c96dbe7b0 | |
Nick Mathewson | e6d77520ef | |
Nick Mathewson | c1195d42bc | |
Nick Mathewson | 24bc8caf35 | |
Nick Mathewson | e14006a545 | |
Nick Mathewson | d9dd67e216 | |
Nick Mathewson | 0a78d2947c | |
Nick Mathewson | 020c003a63 | |
Nick Mathewson | b104ea724d | |
Nick Mathewson | 33b69e6884 | |
Nick Mathewson | 148d76c092 | |
Nick Mathewson | 51ca3dc811 | |
Nick Mathewson | 45245fe29e | |
Nick Mathewson | 5c5298e4ff | |
Nick Mathewson | 30844dd51a | |
Nick Mathewson | 8e0bf7fac1 | |
Nick Mathewson | b909aed534 | |
Nick Mathewson | 7b1762481b | |
Nick Mathewson | a8a1e7e8da | |
Nick Mathewson | c0ff59f870 | |
Nick Mathewson | c0257f14cd | |
Nick Mathewson | 2f6a66a174 | |
Nick Mathewson | 72d9e057c3 | |
Nick Mathewson | 9203b3e4ed | |
Nick Mathewson | 2393e67b2e | |
Nick Mathewson | e89163845a | |
Nick Mathewson | 2e02b59772 | |
Nick Mathewson | 056978c31c | |
Nick Mathewson | 5322713b48 | |
Nick Mathewson | 1ffe29ff8d | |
Nick Mathewson | d27160b407 | |
Nick Mathewson | 53947389a7 | |
Nick Mathewson | 8c2cad52c4 | |
Nick Mathewson | 77abd68855 | |
Nick Mathewson | c0c92c3e2a | |
Nick Mathewson | 01d5921435 | |
Nick Mathewson | c79976bc9b | |
Nick Mathewson | 99d0579ff5 | |
Nick Mathewson | c1237ed516 | |
Nick Mathewson | 5a4caad88d | |
Nick Mathewson | 53a605ee00 | |
Nick Mathewson | cfb61f909a | |
Nick Mathewson | 4dcfc3ded6 | |
Nick Mathewson | 8ba0ea4419 | |
Nick Mathewson | e573a51916 | |
Nick Mathewson | 6bf06c5656 | |
Nick Mathewson | 78d9af302e | |
Nick Mathewson | a286fbd711 | |
Nick Mathewson | 2f962b9309 | |
Nick Mathewson | b0fff2a9c5 | |
Nick Mathewson | 4b54ad017d | |
Nick Mathewson | 1d02f64932 | |
Roger Dingledine | 42b42605f8 | |
Nick Mathewson | 7fd7a2c7c3 | |
Nick Mathewson | 495d201c36 | |
Nick Mathewson | 44b933cf01 | |
Nick Mathewson | 0829e05630 | |
Nick Mathewson | 023ce9e0f8 | |
Nick Mathewson | 334f4f60e8 | |
Nick Mathewson | e6ae154ab4 | |
Nick Mathewson | f69c7a152f | |
Nick Mathewson | 056ff52c53 | |
Nick Mathewson | b82be6cf66 | |
Nick Mathewson | 095080360f | |
Nick Mathewson | 9ffb2d8818 | |
Nick Mathewson | 42336f32f0 | |
Nick Mathewson | 6a58a380f9 | |
Nick Mathewson | e6c16e6267 | |
Nick Mathewson | 6880aaf0a9 | |
Nick Mathewson | dfcdb34b8e | |
Nick Mathewson | f17167ac0a | |
Nick Mathewson | 96f46922c7 | |
Nick Mathewson | c82aaaa48a | |
Nick Mathewson | f77d8901fc | |
Roger Dingledine | a64f3ab3ee | |
Roger Dingledine | 36b979bb8d | |
Roger Dingledine | 347a9f98b8 | |
Roger Dingledine | 9fe7395984 | |
Roger Dingledine | 70762a0e9c | |
Roger Dingledine | 22a82164b1 | |
Roger Dingledine | 0b004ba5c0 | |
Nick Mathewson | 396ac67f62 | |
Roger Dingledine | 40233cadbb | |
Nick Mathewson | 76f72e3b41 | |
Nick Mathewson | 5958261f23 | |
Nick Mathewson | 102c7d7b2c | |
Nick Mathewson | 2fbaa2f9d6 | |
Nick Mathewson | 8e7ee0e2c0 | |
Nick Mathewson | 351f245e2a | |
Nick Mathewson | 04755ff764 | |
Roger Dingledine | 83e069fd52 | |
Nick Mathewson | 32c5806e1c | |
Nick Mathewson | 37516391be | |
Nick Mathewson | 43bf511c31 | |
Nick Mathewson | 06e8f4b370 | |
Nick Mathewson | 475c95f28a | |
Nick Mathewson | b969ee9dad | |
Roger Dingledine | ef89fd142c | |
Nick Mathewson | f8ca81c04f | |
Nick Mathewson | ad8281cb8b | |
Nick Mathewson | 9fc5dd8ae7 | |
Nick Mathewson | 9f950d80c3 | |
Roger Dingledine | 390728d856 | |
Roger Dingledine | 0b586b44dd | |
Roger Dingledine | 6c84b124aa | |
Roger Dingledine | bf372578c1 | |
Roger Dingledine | f4992beb56 | |
Roger Dingledine | 2be259fabf | |
Roger Dingledine | c0411e1c89 | |
Nick Mathewson | d14fcdc5e8 |
|
@ -1,62 +0,0 @@
|
|||
version: 1.0.{build}
|
||||
|
||||
clone_depth: 50
|
||||
|
||||
environment:
|
||||
compiler: mingw
|
||||
|
||||
matrix:
|
||||
- target: i686-w64-mingw32
|
||||
compiler_path: mingw32
|
||||
openssl_path: /c/OpenSSL-Win32
|
||||
- target: x86_64-w64-mingw32
|
||||
compiler_path: mingw64
|
||||
openssl_path: /c/OpenSSL-Win64
|
||||
|
||||
install:
|
||||
- ps: >-
|
||||
Function Execute-Command ($commandPath)
|
||||
{
|
||||
& $commandPath $args 2>&1
|
||||
if ( $LastExitCode -ne 0 ) {
|
||||
$host.SetShouldExit( $LastExitCode )
|
||||
}
|
||||
}
|
||||
Function Execute-Bash ()
|
||||
{
|
||||
Execute-Command 'c:\msys64\usr\bin\bash' '-e' '-c' $args
|
||||
}
|
||||
Execute-Command "C:\msys64\usr\bin\pacman" -Sy --noconfirm openssl-devel openssl libevent-devel libevent mingw-w64-i686-libevent mingw-w64-x86_64-libevent mingw-w64-i686-openssl mingw-w64-x86_64-openssl mingw-w64-i686-zstd mingw-w64-x86_64-zstd
|
||||
|
||||
build_script:
|
||||
- ps: >-
|
||||
if ($env:compiler -eq "mingw") {
|
||||
$oldpath = ${env:Path} -split ';'
|
||||
$buildpath = @("C:\msys64\${env:compiler_path}\bin", "C:\msys64\usr\bin") + $oldpath
|
||||
$env:Path = @($buildpath) -join ';'
|
||||
$env:build = @("${env:APPVEYOR_BUILD_FOLDER}", $env:target) -join '\'
|
||||
Set-Location "${env:APPVEYOR_BUILD_FOLDER}"
|
||||
Execute-Bash 'autoreconf -i'
|
||||
mkdir "${env:build}"
|
||||
Set-Location "${env:build}"
|
||||
Execute-Bash "../configure --prefix=/${env:compiler_path} --build=${env:target} --host=${env:target} --disable-asciidoc --enable-fatal-warnings --with-openssl-dir=${env:openssl_path}"
|
||||
Execute-Bash "V=1 make -j2"
|
||||
Execute-Bash "V=1 make -j2 install"
|
||||
}
|
||||
|
||||
test_script:
|
||||
- ps: >-
|
||||
if ($env:compiler -eq "mingw") {
|
||||
$oldpath = ${env:Path} -split ';'
|
||||
$buildpath = @("C:\msys64\${env:compiler_path}\bin") + $oldpath
|
||||
$env:Path = $buildpath -join ';'
|
||||
Set-Location "${env:build}"
|
||||
Execute-Bash "VERBOSE=1 make -j2 check"
|
||||
}
|
||||
|
||||
on_success:
|
||||
- cmd: C:\Python27\python.exe %APPVEYOR_BUILD_FOLDER%\scripts\test\appveyor-irc-notify.py irc.oftc.net:6697 tor-ci success
|
||||
|
||||
on_failure:
|
||||
- cmd: C:\Python27\python.exe %APPVEYOR_BUILD_FOLDER%\scripts\test\appveyor-irc-notify.py irc.oftc.net:6697 tor-ci failure
|
||||
|
|
@ -3,7 +3,6 @@
|
|||
.#*
|
||||
*~
|
||||
*.swp
|
||||
*.swo
|
||||
# C stuff
|
||||
*.o
|
||||
*.obj
|
||||
|
@ -19,8 +18,6 @@
|
|||
.dirstamp
|
||||
*.trs
|
||||
*.log
|
||||
# Calltool stuff
|
||||
.*.graph
|
||||
# Stuff made by our makefiles
|
||||
*.bak
|
||||
# Python droppings
|
||||
|
@ -28,20 +25,11 @@
|
|||
*.pyo
|
||||
# Cscope
|
||||
cscope.*
|
||||
# OSX junk
|
||||
*.dSYM
|
||||
.DS_Store
|
||||
# updateFallbackDirs.py temp files
|
||||
details-*.json
|
||||
uptime-*.json
|
||||
*.full_url
|
||||
*.last_modified
|
||||
|
||||
# /
|
||||
/Makefile
|
||||
/Makefile.in
|
||||
/aclocal.m4
|
||||
/ar-lib
|
||||
/autom4te.cache
|
||||
/build-stamp
|
||||
/compile
|
||||
|
@ -60,7 +48,6 @@ uptime-*.json
|
|||
/stamp-h
|
||||
/stamp-h.in
|
||||
/stamp-h1
|
||||
/TAGS
|
||||
/test-driver
|
||||
/tor.sh
|
||||
/tor.spec
|
||||
|
@ -70,8 +57,6 @@ uptime-*.json
|
|||
/mkinstalldirs
|
||||
/Tor*Bundle.dmg
|
||||
/tor-*-win32.exe
|
||||
/coverage_html/
|
||||
/callgraph/
|
||||
|
||||
# /contrib/
|
||||
/contrib/dist/tor.sh
|
||||
|
@ -99,6 +84,11 @@ uptime-*.json
|
|||
/doc/tor.html
|
||||
/doc/tor.html.in
|
||||
/doc/tor.1.xml
|
||||
/doc/tor-fw-helper.1
|
||||
/doc/tor-fw-helper.1.in
|
||||
/doc/tor-fw-helper.html
|
||||
/doc/tor-fw-helper.html.in
|
||||
/doc/tor-fw-helper.1.xml
|
||||
/doc/tor-gencert.1
|
||||
/doc/tor-gencert.1.in
|
||||
/doc/tor-gencert.html
|
||||
|
@ -119,26 +109,17 @@ uptime-*.json
|
|||
/doc/spec/Makefile
|
||||
/doc/spec/Makefile.in
|
||||
|
||||
# /scripts
|
||||
/scripts/maint/checkOptionDocs.pl
|
||||
/scripts/maint/updateVersions.pl
|
||||
|
||||
# /src/
|
||||
/src/Makefile
|
||||
/src/Makefile.in
|
||||
|
||||
# /src/trace
|
||||
/src/trace/libor-trace.a
|
||||
|
||||
# /src/common/
|
||||
/src/common/Makefile
|
||||
/src/common/Makefile.in
|
||||
/src/common/common_sha1.i
|
||||
/src/common/libor.a
|
||||
/src/common/libor-testing.a
|
||||
/src/common/libor.lib
|
||||
/src/common/libor-ctime.a
|
||||
/src/common/libor-ctime-testing.a
|
||||
/src/common/libor-ctime.lib
|
||||
/src/common/libor-crypto.a
|
||||
/src/common/libor-crypto-testing.a
|
||||
/src/common/libor-crypto.lib
|
||||
|
@ -154,19 +135,11 @@ uptime-*.json
|
|||
/src/config/sample-server-torrc
|
||||
/src/config/torrc
|
||||
/src/config/torrc.sample
|
||||
/src/config/torrc.minimal
|
||||
|
||||
# /src/ext/
|
||||
/src/ext/ed25519/ref10/libed25519_ref10.a
|
||||
/src/ext/ed25519/ref10/libed25519_ref10.lib
|
||||
/src/ext/ed25519/donna/libed25519_donna.a
|
||||
/src/ext/ed25519/donna/libed25519_donna.lib
|
||||
/src/ext/keccak-tiny/libkeccak-tiny.a
|
||||
/src/ext/keccak-tiny/libkeccak-tiny.lib
|
||||
|
||||
# /src/or/
|
||||
/src/or/Makefile
|
||||
/src/or/Makefile.in
|
||||
/src/or/or_sha1.i
|
||||
/src/or/tor
|
||||
/src/or/tor.exe
|
||||
/src/or/tor-cov
|
||||
|
@ -175,60 +148,35 @@ uptime-*.json
|
|||
/src/or/libtor-testing.a
|
||||
/src/or/libtor.lib
|
||||
|
||||
# /src/rust
|
||||
/src/rust/.cargo/config
|
||||
/src/rust/.cargo/registry
|
||||
/src/rust/target
|
||||
/src/rust/registry
|
||||
|
||||
# /src/test
|
||||
/src/test/Makefile
|
||||
/src/test/Makefile.in
|
||||
/src/test/bench
|
||||
/src/test/bench.exe
|
||||
/src/test/test
|
||||
/src/test/test-slow
|
||||
/src/test/test-bt-cl
|
||||
/src/test/test-child
|
||||
/src/test/test-memwipe
|
||||
/src/test/test-ntor-cl
|
||||
/src/test/test-hs-ntor-cl
|
||||
/src/test/test-switch-id
|
||||
/src/test/test-timers
|
||||
/src/test/test_workqueue
|
||||
/src/test/test.exe
|
||||
/src/test/test-slow.exe
|
||||
/src/test/test-bt-cl.exe
|
||||
/src/test/test-child.exe
|
||||
/src/test/test-ntor-cl.exe
|
||||
/src/test/test-hs-ntor-cl.exe
|
||||
/src/test/test-memwipe.exe
|
||||
/src/test/test-switch-id.exe
|
||||
/src/test/test-timers.exe
|
||||
/src/test/test_workqueue.exe
|
||||
|
||||
# /src/test/fuzz
|
||||
/src/test/fuzz/fuzz-*
|
||||
/src/test/fuzz/lf-fuzz-*
|
||||
|
||||
# /src/tools/
|
||||
/src/tools/libtorrunner.a
|
||||
/src/tools/tor-checkkey
|
||||
/src/tools/tor-resolve
|
||||
/src/tools/tor-cov-resolve
|
||||
/src/tools/tor-gencert
|
||||
/src/tools/tor-cov-gencert
|
||||
/src/tools/tor-checkkey.exe
|
||||
/src/tools/tor-resolve.exe
|
||||
/src/tools/tor-cov-resolve.exe
|
||||
/src/tools/tor-gencert.exe
|
||||
/src/tools/tor-cov-gencert.exe
|
||||
/src/tools/Makefile
|
||||
/src/tools/Makefile.in
|
||||
|
||||
# /src/trunnel/
|
||||
/src/trunnel/libor-trunnel-testing.a
|
||||
/src/trunnel/libor-trunnel.a
|
||||
# /src/tools/tor-fw-helper/
|
||||
/src/tools/tor-fw-helper/tor-fw-helper
|
||||
/src/tools/tor-fw-helper/tor-fw-helper.exe
|
||||
/src/tools/tor-fw-helper/Makefile
|
||||
/src/tools/tor-fw-helper/Makefile.in
|
||||
|
||||
# /src/win32/
|
||||
/src/win32/Makefile
|
||||
|
|
|
@ -1,45 +0,0 @@
|
|||
before_script:
|
||||
- apt-get update -qq
|
||||
- apt-get upgrade -qy
|
||||
|
||||
build:
|
||||
script:
|
||||
- apt-get install -qy --fix-missing automake build-essential
|
||||
libevent-dev libssl-dev zlib1g-dev
|
||||
libseccomp-dev liblzma-dev libscrypt-dev
|
||||
- ./autogen.sh
|
||||
- ./configure --disable-asciidoc --enable-fatal-warnings
|
||||
--disable-silent-rules
|
||||
- make check || (e=$?; cat test-suite.log; exit $e)
|
||||
- make install
|
||||
|
||||
update:
|
||||
only:
|
||||
- schedules
|
||||
script:
|
||||
- "apt-get install -y --fix-missing git openssh-client"
|
||||
|
||||
# Run ssh-agent (inside the build environment)
|
||||
- eval $(ssh-agent -s)
|
||||
|
||||
# Add the SSH key stored in SSH_PRIVATE_KEY variable to the agent store
|
||||
- ssh-add <(echo "$DEPLOY_KEY")
|
||||
|
||||
# For Docker builds disable host key checking. Be aware that by adding that
|
||||
# you are susceptible to man-in-the-middle attacks.
|
||||
# WARNING: Use this only with the Docker executor, if you use it with shell
|
||||
# you will overwrite your user's SSH config.
|
||||
- mkdir -p ~/.ssh
|
||||
- '[[ -f /.dockerenv ]] && echo -e "Host *\n\tStrictHostKeyChecking no\n\n" > ~/.ssh/config'
|
||||
# In order to properly check the server's host key, assuming you created the
|
||||
# SSH_SERVER_HOSTKEYS variable previously, uncomment the following two lines
|
||||
# instead.
|
||||
- mkdir -p ~/.ssh
|
||||
- '[[ -f /.dockerenv ]] && echo "$SSH_SERVER_HOSTKEYS" > ~/.ssh/known_hosts'
|
||||
- echo "merging from torgit"
|
||||
- git config --global user.email "labadmin@oniongit.eu"
|
||||
- git config --global user.name "gitadmin"
|
||||
- "mkdir tor"
|
||||
- "cd tor"
|
||||
- git clone --bare https://git.torproject.org/tor.git
|
||||
- git push --mirror git@oniongit.eu:network/tor.git
|
|
@ -1,3 +0,0 @@
|
|||
[submodule "src/ext/rust"]
|
||||
path = src/ext/rust
|
||||
url = https://git.torproject.org/tor-rust-dependencies
|
55
.travis.yml
55
.travis.yml
|
@ -60,14 +60,6 @@ env:
|
|||
global:
|
||||
## The Travis CI environment allows us two cores, so let's use both.
|
||||
- MAKEFLAGS="-j 2"
|
||||
matrix:
|
||||
## Leave at least one entry here or Travis seems to generate a
|
||||
## matrix entry with empty matrix environment variables. Leaving
|
||||
## more than one entry causes unwanted matrix entries with
|
||||
## unspecified compilers.
|
||||
- RUST_OPTIONS="--enable-rust --enable-cargo-online-mode"
|
||||
# - RUST_OPTIONS="--enable-rust" TOR_RUST_DEPENDENCIES=true
|
||||
# - RUST_OPTIONS=""
|
||||
|
||||
matrix:
|
||||
## Uncomment to allow the build to report success (with non-required
|
||||
|
@ -96,40 +88,18 @@ matrix:
|
|||
## entry under that key outside the "include" clause.
|
||||
include:
|
||||
- compiler: gcc
|
||||
- compiler: gcc
|
||||
env: RUST_OPTIONS="--enable-rust" TOR_RUST_DEPENDENCIES=true
|
||||
- compiler: gcc
|
||||
env: RUST_OPTIONS=""
|
||||
- compiler: gcc
|
||||
env: COVERAGE_OPTIONS="--enable-coverage"
|
||||
- compiler: gcc
|
||||
env: DISTCHECK="yes" RUST_OPTIONS=""
|
||||
- compiler: gcc
|
||||
env: DISTCHECK="yes" RUST_OPTIONS="--enable-rust --enable-cargo-online-mode"
|
||||
- compiler: gcc
|
||||
env: MODULES_OPTIONS="--disable-module-dirauth"
|
||||
## The "sudo: required" forces non-containerized builds, working
|
||||
## around a Travis CI environment issue: clang LeakAnalyzer fails
|
||||
## because it requires ptrace and the containerized environment no
|
||||
## longer allows ptrace.
|
||||
- compiler: clang
|
||||
sudo: required
|
||||
- compiler: clang
|
||||
sudo: required
|
||||
env: RUST_OPTIONS="--enable-rust" TOR_RUST_DEPENDENCIES=true
|
||||
- compiler: clang
|
||||
sudo: required
|
||||
env: RUST_OPTIONS=""
|
||||
- compiler: clang
|
||||
sudo: required
|
||||
env: MODULES_OPTIONS="--disable-module-dirauth"
|
||||
|
||||
before_install:
|
||||
## If we're on OSX, homebrew usually needs to updated first
|
||||
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew update ; fi
|
||||
## Download rustup
|
||||
- if [[ "$RUST_OPTIONS" != "" ]]; then curl -Ssf -o rustup.sh https://sh.rustup.rs; fi
|
||||
- if [[ "$COVERAGE_OPTIONS" != "" ]]; then pip install --user cpp-coveralls; fi
|
||||
- curl -Ssf -o rustup.sh https://sh.rustup.rs
|
||||
|
||||
install:
|
||||
## If we're on OSX use brew to install required dependencies (for Linux, see the "apt:" section above)
|
||||
|
@ -140,30 +110,13 @@ install:
|
|||
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then { brew outdated xz || brew upgrade xz; }; fi
|
||||
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then { brew outdated libscrypt || brew upgrade libscrypt; }; fi
|
||||
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then { brew outdated zstd || brew upgrade zstd; }; fi
|
||||
## Install the stable channels of rustc and cargo and setup our toolchain environment
|
||||
- if [[ "$RUST_OPTIONS" != "" ]]; then sh rustup.sh -y --default-toolchain stable; fi
|
||||
- if [[ "$RUST_OPTIONS" != "" ]]; then source $HOME/.cargo/env; fi
|
||||
## Get some info about rustc and cargo
|
||||
- if [[ "$RUST_OPTIONS" != "" ]]; then which rustc; fi
|
||||
- if [[ "$RUST_OPTIONS" != "" ]]; then which cargo; fi
|
||||
- if [[ "$RUST_OPTIONS" != "" ]]; then rustc --version; fi
|
||||
- if [[ "$RUST_OPTIONS" != "" ]]; then cargo --version; fi
|
||||
## If we're testing rust builds in offline-mode, then set up our vendored dependencies
|
||||
- if [[ "$TOR_RUST_DEPENDENCIES" == "true" ]]; then export TOR_RUST_DEPENDENCIES=$PWD/src/ext/rust/crates; fi
|
||||
|
||||
script:
|
||||
- ./autogen.sh
|
||||
- ./configure $RUST_OPTIONS $COVERAGE_OPTIONS $MODULES_OPTIONS --disable-asciidoc --enable-fatal-warnings --disable-silent-rules --enable-fragile-hardening
|
||||
- ./configure $RUST_OPTIONS --disable-asciidoc --enable-gcc-warnings --disable-silent-rules --enable-fragile-hardening
|
||||
## We run `make check` because that's what https://jenkins.torproject.org does.
|
||||
- if [[ "$DISTCHECK" == "" ]]; then make check; fi
|
||||
- if [[ "$DISTCHECK" != "" ]]; then make distcheck DISTCHECK_CONFIGURE_FLAGS="$RUST_OPTIONS $COVERAGE_OPTIONS --disable-asciidoc --enable-fatal-warnings --disable-silent-rules --enable-fragile-hardening"; fi
|
||||
- make check
|
||||
|
||||
after_failure:
|
||||
## `make check` will leave a log file with more details of test failures.
|
||||
- if [[ "$DISTCHECK" == "" ]]; then cat test-suite.log; fi
|
||||
## `make distcheck` puts it somewhere different.
|
||||
- if [[ "$DISTCHECK" != "" ]]; then make show-distdir-testlog; fi
|
||||
|
||||
after_success:
|
||||
## If this build was one that produced coverage, upload it.
|
||||
- if [[ "$COVERAGE_OPTIONS" != "" ]]; then coveralls -b . --exclude src/test --exclude src/trunnel --gcov-options '\-p'; fi
|
||||
- cat test-suite.log
|
||||
|
|
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
|
32
Doxyfile.in
32
Doxyfile.in
|
@ -38,7 +38,7 @@ PROJECT_NUMBER = @VERSION@
|
|||
# If a relative path is entered, it will be relative to the location
|
||||
# where doxygen was started. If left blank the current directory will be used.
|
||||
|
||||
OUTPUT_DIRECTORY = @top_builddir@/doc/doxygen
|
||||
OUTPUT_DIRECTORY = ./doc/doxygen
|
||||
|
||||
# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create
|
||||
# 4096 sub-directories (in 2 levels) under the output directory of each output
|
||||
|
@ -446,6 +446,12 @@ MAX_INITIALIZER_LINES = 30
|
|||
|
||||
SHOW_USED_FILES = YES
|
||||
|
||||
# If the sources in your project are distributed over multiple directories
|
||||
# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy
|
||||
# in the documentation. The default is NO.
|
||||
|
||||
SHOW_DIRECTORIES = NO
|
||||
|
||||
# Set the SHOW_FILES tag to NO to disable the generation of the Files page.
|
||||
# This will remove the Files entry from the Quick Index and from the
|
||||
# Folder Tree View (if specified). The default is YES.
|
||||
|
@ -528,8 +534,8 @@ WARN_LOGFILE =
|
|||
# directories like "/usr/src/myproject". Separate the files or directories
|
||||
# with spaces.
|
||||
|
||||
INPUT = @top_srcdir@/src/common \
|
||||
@top_srcdir@/src/or
|
||||
INPUT = src/common \
|
||||
src/or
|
||||
|
||||
# This tag can be used to specify the character encoding of the source files
|
||||
# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is
|
||||
|
@ -754,6 +760,12 @@ HTML_FOOTER =
|
|||
|
||||
HTML_STYLESHEET =
|
||||
|
||||
# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes,
|
||||
# files or namespaces will be aligned in HTML using tables. If set to
|
||||
# NO a bullet list will be used.
|
||||
|
||||
HTML_ALIGN_MEMBERS = YES
|
||||
|
||||
# If the GENERATE_HTMLHELP tag is set to YES, additional index files
|
||||
# will be generated that can be used as input for tools like the
|
||||
# Microsoft HTML help workshop to generate a compiled HTML help file (.chm)
|
||||
|
@ -1035,6 +1047,18 @@ GENERATE_XML = NO
|
|||
|
||||
XML_OUTPUT = xml
|
||||
|
||||
# The XML_SCHEMA tag can be used to specify an XML schema,
|
||||
# which can be used by a validating XML parser to check the
|
||||
# syntax of the XML files.
|
||||
|
||||
XML_SCHEMA =
|
||||
|
||||
# The XML_DTD tag can be used to specify an XML DTD,
|
||||
# which can be used by a validating XML parser to check the
|
||||
# syntax of the XML files.
|
||||
|
||||
XML_DTD =
|
||||
|
||||
# If the XML_PROGRAMLISTING tag is set to YES Doxygen will
|
||||
# dump the program listings (including syntax highlighting
|
||||
# and cross-referencing information) to the XML output. Note that
|
||||
|
@ -1240,7 +1264,7 @@ HAVE_DOT = NO
|
|||
# DOTFONTPATH environment variable or by setting DOT_FONTPATH to the directory
|
||||
# containing the font.
|
||||
|
||||
DOT_FONTNAME =
|
||||
DOT_FONTNAME = FreeSans
|
||||
|
||||
# By default doxygen will tell dot to use the output directory to look for the
|
||||
# FreeSans.ttf font (which doxygen will put there itself). If you specify a
|
||||
|
|
188
LICENSE
188
LICENSE
|
@ -13,7 +13,7 @@ Tor is distributed under this license:
|
|||
|
||||
Copyright (c) 2001-2004, Roger Dingledine
|
||||
Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson
|
||||
Copyright (c) 2007-2017, The Tor Project, Inc.
|
||||
Copyright (c) 2007-2013, The Tor Project, Inc.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
|
@ -122,38 +122,6 @@ src/ext/csiphash.c is licensed under the following license:
|
|||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
===============================================================================
|
||||
Trunnel is distributed under this license:
|
||||
|
||||
Copyright 2014 The Tor Project, Inc.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following disclaimer
|
||||
in the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
|
||||
* Neither the names of the copyright owners nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
===============================================================================
|
||||
src/config/geoip is licensed under the following license:
|
||||
|
@ -191,7 +159,7 @@ ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|||
DATABASE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
===============================================================================
|
||||
m4/pc_from_ucontext.m4 is available under the following license. Note that
|
||||
it is *not* built into the Tor software.
|
||||
it is *not* built into the Tor license.
|
||||
|
||||
Copyright (c) 2005, Google Inc.
|
||||
All rights reserved.
|
||||
|
@ -222,158 +190,6 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
===============================================================================
|
||||
m4/pkg.m4 is available under the following license. Note that
|
||||
it is *not* built into the Tor software.
|
||||
|
||||
pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*-
|
||||
serial 1 (pkg-config-0.24)
|
||||
|
||||
Copyright © 2004 Scott James Remnant <scott@netsplit.com>.
|
||||
|
||||
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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
As a special exception to the GNU General Public License, if you
|
||||
distribute this file as part of a program that contains a
|
||||
configuration script generated by Autoconf, you may include it under
|
||||
the same distribution terms that you use for the rest of that program.
|
||||
===============================================================================
|
||||
src/ext/readpassphrase.[ch] are distributed under this license:
|
||||
|
||||
Copyright (c) 2000-2002, 2007 Todd C. Miller <Todd.Miller@courtesan.com>
|
||||
|
||||
Permission to use, copy, modify, and distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
Sponsored in part by the Defense Advanced Research Projects
|
||||
Agency (DARPA) and Air Force Research Laboratory, Air Force
|
||||
Materiel Command, USAF, under agreement number F39502-99-1-0512.
|
||||
|
||||
===============================================================================
|
||||
src/ext/mulodi4.c is distributed under this license:
|
||||
|
||||
=========================================================================
|
||||
compiler_rt License
|
||||
=========================================================================
|
||||
|
||||
The compiler_rt library is dual licensed under both the
|
||||
University of Illinois "BSD-Like" license and the MIT license.
|
||||
As a user of this code you may choose to use it under either
|
||||
license. As a contributor, you agree to allow your code to be
|
||||
used under both.
|
||||
|
||||
Full text of the relevant licenses is included below.
|
||||
|
||||
=========================================================================
|
||||
|
||||
University of Illinois/NCSA
|
||||
Open Source License
|
||||
|
||||
Copyright (c) 2009-2016 by the contributors listed in CREDITS.TXT
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Developed by:
|
||||
|
||||
LLVM Team
|
||||
|
||||
University of Illinois at Urbana-Champaign
|
||||
|
||||
http://llvm.org
|
||||
|
||||
Permission is hereby granted, free of charge, to any person
|
||||
obtaining a copy of this software and associated documentation
|
||||
files (the "Software"), to deal with the Software without
|
||||
restriction, including without limitation the rights to use,
|
||||
copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the
|
||||
Software is furnished to do so, subject to the following
|
||||
conditions:
|
||||
|
||||
* Redistributions of source code must retain the above
|
||||
copyright notice, this list of conditions and the following
|
||||
disclaimers.
|
||||
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following
|
||||
disclaimers in the documentation and/or other materials
|
||||
provided with the distribution.
|
||||
|
||||
* Neither the names of the LLVM Team, University of Illinois
|
||||
at Urbana-Champaign, nor the names of its contributors may
|
||||
be used to endorse or promote products derived from this
|
||||
Software without specific prior written permission.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE CONTRIBUTORS OR COPYRIGHT
|
||||
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
OTHER DEALINGS WITH THE SOFTWARE.
|
||||
|
||||
=========================================================================
|
||||
|
||||
Copyright (c) 2009-2015 by the contributors listed in CREDITS.TXT
|
||||
|
||||
Permission is hereby granted, free of charge, to any person
|
||||
obtaining a copy of this software and associated documentation
|
||||
files (the "Software"), to deal in the Software without
|
||||
restriction, including without limitation the rights to use,
|
||||
copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the
|
||||
Software is furnished to do so, subject to the following
|
||||
conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
||||
=========================================================================
|
||||
Copyrights and Licenses for Third Party Software Distributed with LLVM:
|
||||
=========================================================================
|
||||
|
||||
The LLVM software contains code written by third parties. Such
|
||||
software will have its own individual LICENSE.TXT file in the
|
||||
directory in which it appears. This file will describe the
|
||||
copyrights, license, and restrictions which apply to that code.
|
||||
|
||||
The disclaimer of warranty in the University of Illinois Open
|
||||
Source License applies to all code in the LLVM Distribution, and
|
||||
nothing in any of the other licenses gives permission to use the
|
||||
names of the LLVM Team or the University of Illinois to endorse
|
||||
or promote products derived from this Software.
|
||||
|
||||
===============================================================================
|
||||
If you got Tor as a static binary with OpenSSL included, then you should know:
|
||||
"This product includes software developed by the OpenSSL Project
|
||||
|
|
233
Makefile.am
233
Makefile.am
|
@ -1,76 +1,42 @@
|
|||
# Copyright (c) 2001-2004, Roger Dingledine
|
||||
# Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson
|
||||
# Copyright (c) 2007-2017, The Tor Project, Inc.
|
||||
# Copyright (c) 2007-2011, The Tor Project, Inc.
|
||||
# See LICENSE for licensing information
|
||||
|
||||
# "foreign" means we don't follow GNU package layout standards
|
||||
# 1.9 means we require automake vesion 1.9
|
||||
AUTOMAKE_OPTIONS = foreign 1.9 subdir-objects
|
||||
|
||||
ACLOCAL_AMFLAGS = -I m4
|
||||
|
||||
noinst_LIBRARIES=
|
||||
EXTRA_DIST=
|
||||
noinst_HEADERS=
|
||||
bin_PROGRAMS=
|
||||
EXTRA_PROGRAMS=
|
||||
CLEANFILES=
|
||||
TESTS=
|
||||
noinst_PROGRAMS=
|
||||
DISTCLEANFILES=
|
||||
bin_SCRIPTS=
|
||||
AM_CPPFLAGS=
|
||||
AM_CFLAGS=@TOR_SYSTEMD_CFLAGS@ @CFLAGS_BUGTRAP@ @TOR_LZMA_CFLAGS@ @TOR_ZSTD_CFLAGS@
|
||||
SHELL=@SHELL@
|
||||
|
||||
if COVERAGE_ENABLED
|
||||
TESTING_TOR_BINARY=$(top_builddir)/src/or/tor-cov$(EXEEXT)
|
||||
else
|
||||
TESTING_TOR_BINARY=$(top_builddir)/src/or/tor$(EXEEXT)
|
||||
endif
|
||||
|
||||
if USE_RUST
|
||||
rust_ldadd=$(top_builddir)/src/rust/target/release/@TOR_RUST_STATIC_NAME@ \
|
||||
@TOR_RUST_EXTRA_LIBS@
|
||||
else
|
||||
rust_ldadd=
|
||||
endif
|
||||
|
||||
include src/include.am
|
||||
include doc/include.am
|
||||
include contrib/include.am
|
||||
|
||||
|
||||
EXTRA_DIST+= \
|
||||
ChangeLog \
|
||||
CONTRIBUTING \
|
||||
INSTALL \
|
||||
LICENSE \
|
||||
Makefile.nmake \
|
||||
README \
|
||||
ReleaseNotes \
|
||||
scripts/maint/checkSpace.pl
|
||||
|
||||
## This tells etags how to find mockable function definitions.
|
||||
AM_ETAGSFLAGS=--regex='{c}/MOCK_IMPL([^,]+,\W*\([a-zA-Z0-9_]+\)\W*,/\1/s'
|
||||
ReleaseNotes
|
||||
|
||||
if COVERAGE_ENABLED
|
||||
TEST_CFLAGS=-fno-inline -fprofile-arcs -ftest-coverage
|
||||
if DISABLE_ASSERTS_IN_UNIT_TESTS
|
||||
TEST_CPPFLAGS=-DTOR_UNIT_TESTS -DTOR_COVERAGE -DDISABLE_ASSERTS_IN_UNIT_TESTS @TOR_MODULES_ALL_ENABLED@
|
||||
else
|
||||
TEST_CPPFLAGS=-DTOR_UNIT_TESTS -DTOR_COVERAGE @TOR_MODULES_ALL_ENABLED@
|
||||
endif
|
||||
TEST_NETWORK_FLAGS=--coverage --hs-multi-client 1
|
||||
else
|
||||
TEST_CFLAGS=
|
||||
TEST_CPPFLAGS=-DTOR_UNIT_TESTS @TOR_MODULES_ALL_ENABLED@
|
||||
TEST_NETWORK_FLAGS=--hs-multi-client 1
|
||||
endif
|
||||
TEST_NETWORK_WARNING_FLAGS=--quiet --only-warnings
|
||||
|
||||
if LIBFUZZER_ENABLED
|
||||
TEST_CFLAGS += -fsanitize-coverage=trace-pc-guard,trace-cmp,trace-div
|
||||
# not "edge"
|
||||
endif
|
||||
|
||||
TEST_NETWORK_ALL_LOG_DIR=$(top_builddir)/test_network_log
|
||||
TEST_NETWORK_ALL_DRIVER_FLAGS=--color-tests yes
|
||||
|
||||
#install-data-local:
|
||||
# $(INSTALL) -m 755 -d $(LOCALSTATEDIR)/lib/tor
|
||||
|
@ -92,167 +58,38 @@ dist-rpm: dist-gzip
|
|||
echo "RPM build finished"; \
|
||||
#end of dist-rpm
|
||||
|
||||
dist: check
|
||||
|
||||
doxygen:
|
||||
doxygen && cd doc/doxygen/latex && make
|
||||
|
||||
test: all
|
||||
$(top_builddir)/src/test/test
|
||||
|
||||
check-local: check-spaces check-changes
|
||||
|
||||
need-chutney-path:
|
||||
@if test ! -d "$$CHUTNEY_PATH"; then \
|
||||
echo '$$CHUTNEY_PATH was not set.'; \
|
||||
if test -d $(top_srcdir)/../chutney -a -x $(top_srcdir)/../chutney/chutney; then \
|
||||
echo "Assuming test-network.sh will find" $(top_srcdir)/../chutney; \
|
||||
else \
|
||||
echo; \
|
||||
echo "To run these tests, git clone https://git.torproject.org/chutney.git ; export CHUTNEY_PATH=\`pwd\`/chutney"; \
|
||||
exit 1; \
|
||||
fi \
|
||||
fi
|
||||
./src/test/test
|
||||
|
||||
# Note that test-network requires a copy of Chutney in $CHUTNEY_PATH.
|
||||
# Chutney can be cloned from https://git.torproject.org/chutney.git .
|
||||
test-network: need-chutney-path $(TESTING_TOR_BINARY) src/tools/tor-gencert
|
||||
$(top_srcdir)/src/test/test-network.sh $(TEST_NETWORK_FLAGS)
|
||||
|
||||
# Run all available tests using automake's test-driver
|
||||
# only run IPv6 tests if we can ping6 ::1 (localhost)
|
||||
# only run IPv6 tests if we can ping ::1 (localhost)
|
||||
# some IPv6 tests will fail without an IPv6 DNS server (see #16971 and #17011)
|
||||
# only run mixed tests if we have a tor-stable binary
|
||||
# Try the syntax for BSD ping6, Linux ping6, and Linux ping -6,
|
||||
# because they're incompatible
|
||||
test-network-all: need-chutney-path test-driver $(TESTING_TOR_BINARY) src/tools/tor-gencert
|
||||
mkdir -p $(TEST_NETWORK_ALL_LOG_DIR)
|
||||
@flavors="$(TEST_CHUTNEY_FLAVORS)"; \
|
||||
if ping6 -q -c 1 -o ::1 >/dev/null 2>&1 || ping6 -q -c 1 -W 1 ::1 >/dev/null 2>&1 || ping -6 -c 1 -W 1 ::1 >/dev/null 2>&1; then \
|
||||
echo "ping6 ::1 or ping ::1 succeeded, running IPv6 flavors: $(TEST_CHUTNEY_FLAVORS_IPV6)."; \
|
||||
flavors="$$flavors $(TEST_CHUTNEY_FLAVORS_IPV6)"; \
|
||||
else \
|
||||
echo "ping6 ::1 and ping ::1 failed, skipping IPv6 flavors: $(TEST_CHUTNEY_FLAVORS_IPV6)."; \
|
||||
skip_flavors="$$skip_flavors $(TEST_CHUTNEY_FLAVORS_IPV6)"; \
|
||||
fi; \
|
||||
if command -v tor-stable >/dev/null 2>&1; then \
|
||||
echo "tor-stable found, running mixed flavors: $(TEST_CHUTNEY_FLAVORS_MIXED)."; \
|
||||
flavors="$$flavors $(TEST_CHUTNEY_FLAVORS_MIXED)"; \
|
||||
else \
|
||||
echo "tor-stable not found, skipping mixed flavors: $(TEST_CHUTNEY_FLAVORS_MIXED)."; \
|
||||
skip_flavors="$$skip_flavors $(TEST_CHUTNEY_FLAVORS_MIXED)"; \
|
||||
fi; \
|
||||
for f in $$skip_flavors; do \
|
||||
echo "SKIP: $$f"; \
|
||||
done; \
|
||||
for f in $$flavors; do \
|
||||
$(SHELL) $(top_srcdir)/test-driver --test-name $$f --log-file $(TEST_NETWORK_ALL_LOG_DIR)/$$f.log --trs-file $(TEST_NETWORK_ALL_LOG_DIR)/$$f.trs $(TEST_NETWORK_ALL_DRIVER_FLAGS) $(top_srcdir)/src/test/test-network.sh --flavor $$f $(TEST_NETWORK_FLAGS); \
|
||||
$(top_srcdir)/src/test/test-network.sh $(TEST_NETWORK_WARNING_FLAGS); \
|
||||
done; \
|
||||
echo "Log and result files are available in $(TEST_NETWORK_ALL_LOG_DIR)."; \
|
||||
! grep -q FAIL test_network_log/*.trs
|
||||
|
||||
need-stem-path:
|
||||
@if test ! -d "$$STEM_SOURCE_DIR"; then \
|
||||
echo '$$STEM_SOURCE_DIR was not set.'; echo; \
|
||||
echo "To run these tests, git clone https://git.torproject.org/stem.git/ ; export STEM_SOURCE_DIR=\`pwd\`/stem"; \
|
||||
exit 1; \
|
||||
fi
|
||||
|
||||
test-stem: need-stem-path $(TESTING_TOR_BINARY)
|
||||
@$(PYTHON) "$$STEM_SOURCE_DIR"/run_tests.py --tor "$(TESTING_TOR_BINARY)" --all --log notice --target RUN_ALL;
|
||||
|
||||
test-stem-full: need-stem-path $(TESTING_TOR_BINARY)
|
||||
@$(PYTHON) "$$STEM_SOURCE_DIR"/run_tests.py --tor "$(TESTING_TOR_BINARY)" --all --log notice --target RUN_ALL,ONLINE -v;
|
||||
|
||||
test-full: need-stem-path need-chutney-path check test-network test-stem
|
||||
|
||||
test-full-online: need-stem-path need-chutney-path check test-network test-stem-full
|
||||
test-network: all
|
||||
./src/test/test-network.sh
|
||||
|
||||
reset-gcov:
|
||||
rm -f $(top_builddir)/src/*/*.gcda $(top_builddir)/src/*/*/*.gcda
|
||||
|
||||
HTML_COVER_DIR=$(top_builddir)/coverage_html
|
||||
coverage-html: all
|
||||
if COVERAGE_ENABLED
|
||||
test -e "`which lcov`" || (echo "lcov must be installed. See <http://ltp.sourceforge.net/coverage/lcov.php>." && false)
|
||||
test -d "$(HTML_COVER_DIR)" || $(MKDIR_P) "$(HTML_COVER_DIR)"
|
||||
lcov --rc lcov_branch_coverage=1 --directory $(top_builddir)/src --zerocounters
|
||||
$(MAKE) reset-gcov
|
||||
$(MAKE) check
|
||||
lcov --capture --rc lcov_branch_coverage=1 --no-external --directory $(top_builddir) --base-directory $(top_srcdir) --output-file "$(HTML_COVER_DIR)/lcov.tmp"
|
||||
lcov --remove "$(HTML_COVER_DIR)/lcov.tmp" --rc lcov_branch_coverage=1 'test/*' 'ext/tinytest*' '/usr/*' --output-file "$(HTML_COVER_DIR)/lcov.info"
|
||||
genhtml --branch-coverage -o "$(HTML_COVER_DIR)" "$(HTML_COVER_DIR)/lcov.info"
|
||||
else
|
||||
@printf "Not configured with --enable-coverage, run ./configure --enable-coverage\n"
|
||||
endif
|
||||
|
||||
coverage-html-full: all
|
||||
test -e "`which lcov`" || (echo "lcov must be installed. See <http://ltp.sourceforge.net/coverage/lcov.php>." && false)
|
||||
test -d "$(HTML_COVER_DIR)" || mkdir -p "$(HTML_COVER_DIR)"
|
||||
lcov --rc lcov_branch_coverage=1 --directory ./src --zerocounters
|
||||
$(MAKE) reset-gcov
|
||||
$(MAKE) check
|
||||
$(MAKE) test-stem-full
|
||||
CHUTNEY_TOR=tor-cov CHUTNEY_TOR_GENCERT=tor-cov-gencert $(top_srcdir)/src/test/test-network.sh
|
||||
CHUTNEY_TOR=tor-cov CHUTNEY_TOR_GENCERT=tor-cov-gencert $(top_srcdir)/src/test/test-network.sh --flavor hs
|
||||
lcov --capture --rc lcov_branch_coverage=1 --no-external --directory . --output-file "$(HTML_COVER_DIR)/lcov.tmp"
|
||||
lcov --remove "$(HTML_COVER_DIR)/lcov.tmp" --rc lcov_branch_coverage=1 'test/*' 'ext/tinytest*' '/usr/*' --output-file "$(HTML_COVER_DIR)/lcov.info"
|
||||
genhtml --branch-coverage -o "$(HTML_COVER_DIR)" "$(HTML_COVER_DIR)/lcov.info"
|
||||
rm -f src/*/*.gcda
|
||||
|
||||
# Avoid strlcpy.c, strlcat.c, aes.c, OpenBSD_malloc_Linux.c, sha256.c,
|
||||
# tinytest*.[ch]
|
||||
# eventdns.[hc], tinytest*.[ch]
|
||||
check-spaces:
|
||||
if USE_PERL
|
||||
$(PERL) $(top_srcdir)/scripts/maint/checkSpace.pl -C \
|
||||
$(top_srcdir)/src/common/*.[ch] \
|
||||
$(top_srcdir)/src/or/*.[ch] \
|
||||
$(top_srcdir)/src/test/*.[ch] \
|
||||
$(top_srcdir)/src/test/*/*.[ch] \
|
||||
$(top_srcdir)/src/tools/*.[ch]
|
||||
endif
|
||||
./scripts/maint/checkSpace.pl -C \
|
||||
src/common/*.[ch] \
|
||||
src/or/*.[ch] \
|
||||
src/test/*.[ch] \
|
||||
src/tools/*.[ch] \
|
||||
src/tools/tor-fw-helper/*.[ch]
|
||||
|
||||
check-docs: all
|
||||
$(PERL) $(top_builddir)/scripts/maint/checkOptionDocs.pl
|
||||
check-docs:
|
||||
./scripts/maint/checkOptionDocs.pl
|
||||
|
||||
check-logs:
|
||||
$(top_srcdir)/scripts/maint/checkLogs.pl \
|
||||
$(top_srcdir)/src/*/*.[ch] | sort -n
|
||||
|
||||
.PHONY: check-typos
|
||||
check-typos:
|
||||
@if test -x "`which misspell 2>&1;true`"; then \
|
||||
echo "Checking for Typos ..."; \
|
||||
(misspell \
|
||||
$(top_srcdir)/src/[^e]*/*.[ch] \
|
||||
$(top_srcdir)/doc \
|
||||
$(top_srcdir)/contrib \
|
||||
$(top_srcdir)/scripts \
|
||||
$(top_srcdir)/README \
|
||||
$(top_srcdir)/ChangeLog \
|
||||
$(top_srcdir)/INSTALL \
|
||||
$(top_srcdir)/ReleaseNotes \
|
||||
$(top_srcdir)/LICENSE); \
|
||||
else \
|
||||
echo "Tor can use misspell to check for typos."; \
|
||||
echo "It seems that you don't have misspell installed."; \
|
||||
echo "You can install the latest version of misspell here: https://github.com/client9/misspell#install"; \
|
||||
fi
|
||||
|
||||
.PHONY: check-changes
|
||||
check-changes:
|
||||
if USEPYTHON
|
||||
@if test -d "$(top_srcdir)/changes"; then \
|
||||
$(PYTHON) $(top_srcdir)/scripts/maint/lintChanges.py $(top_srcdir)/changes; \
|
||||
fi
|
||||
endif
|
||||
|
||||
.PHONY: update-versions
|
||||
update-versions:
|
||||
$(PERL) $(top_builddir)/scripts/maint/updateVersions.pl
|
||||
|
||||
.PHONY: callgraph
|
||||
callgraph:
|
||||
$(top_builddir)/scripts/maint/run_calltool.sh
|
||||
./scripts/maint/checkLogs.pl \
|
||||
src/*/*.[ch] | sort -n
|
||||
|
||||
version:
|
||||
@echo "Tor @VERSION@"
|
||||
|
@ -262,24 +99,4 @@ version:
|
|||
fi
|
||||
|
||||
mostlyclean-local:
|
||||
rm -f $(top_builddir)/src/*/*.gc{da,no} $(top_builddir)/src/*/*/*.gc{da,no}
|
||||
rm -rf $(HTML_COVER_DIR)
|
||||
rm -rf $(top_builddir)/doc/doxygen
|
||||
rm -rf $(TEST_NETWORK_ALL_LOG_DIR)
|
||||
|
||||
clean-local:
|
||||
rm -rf $(top_builddir)/src/rust/target
|
||||
rm -rf $(top_builddir)/src/rust/.cargo/registry
|
||||
|
||||
if USE_RUST
|
||||
distclean-local: distclean-rust
|
||||
endif
|
||||
|
||||
# This relies on some internal details of how automake implements
|
||||
# distcheck. We check two directories because automake-1.15 changed
|
||||
# from $(distdir)/_build to $(distdir)/_build/sub.
|
||||
show-distdir-testlog:
|
||||
@if test -d "$(distdir)/_build/sub"; then \
|
||||
cat $(distdir)/_build/sub/$(TEST_SUITE_LOG); \
|
||||
else \
|
||||
cat $(distdir)/_build/$(TEST_SUITE_LOG); fi
|
||||
rm -f src/*/*.gc{da,no}
|
||||
|
|
8
README
8
README
|
@ -6,9 +6,6 @@ configure it properly.
|
|||
To build Tor from source:
|
||||
./configure && make && make install
|
||||
|
||||
To build Tor from a just-cloned git repository:
|
||||
sh autogen.sh && ./configure && make && make install
|
||||
|
||||
Home page:
|
||||
https://www.torproject.org/
|
||||
|
||||
|
@ -26,7 +23,4 @@ Frequently Asked Questions:
|
|||
|
||||
|
||||
To get started working on Tor development:
|
||||
See the doc/HACKING directory.
|
||||
|
||||
Release timeline:
|
||||
https://trac.torproject.org/projects/tor/wiki/org/teams/NetworkTeam/CoreTorReleases
|
||||
See the doc/HACKING file.
|
||||
|
|
8254
ReleaseNotes
8254
ReleaseNotes
File diff suppressed because it is too large
Load Diff
47
acinclude.m4
47
acinclude.m4
|
@ -2,7 +2,7 @@ dnl Helper macros for Tor configure.ac
|
|||
dnl Copyright (c) 2001-2004, Roger Dingledine
|
||||
dnl Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson
|
||||
dnl Copyright (c) 2007-2008, Roger Dingledine, Nick Mathewson
|
||||
dnl Copyright (c) 2007-2017, The Tor Project, Inc.
|
||||
dnl Copyright (c) 2007-2013, The Tor Project, Inc.
|
||||
dnl See LICENSE for licensing information
|
||||
|
||||
AC_DEFUN([TOR_EXTEND_CODEPATH],
|
||||
|
@ -42,21 +42,20 @@ AC_DEFUN([TOR_DEFINE_CODEPATH],
|
|||
AC_SUBST(TOR_LDFLAGS_$2)
|
||||
])
|
||||
|
||||
dnl 1: flags
|
||||
dnl 2: try to link too if this is nonempty.
|
||||
dnl 3: what to do on success compiling
|
||||
dnl 4: what to do on failure compiling
|
||||
AC_DEFUN([TOR_TRY_COMPILE_WITH_CFLAGS], [
|
||||
dnl 1:flags
|
||||
dnl 2:also try to link (yes: non-empty string)
|
||||
dnl will set yes or no in $tor_can_link_$1 (as modified by AS_VAR_PUSHDEF)
|
||||
AC_DEFUN([TOR_CHECK_CFLAGS], [
|
||||
AS_VAR_PUSHDEF([VAR],[tor_cv_cflags_$1])
|
||||
AC_CACHE_CHECK([whether the compiler accepts $1], VAR, [
|
||||
tor_saved_CFLAGS="$CFLAGS"
|
||||
CFLAGS="$CFLAGS -pedantic -Werror $1"
|
||||
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])],
|
||||
AC_TRY_COMPILE([], [return 0;],
|
||||
[AS_VAR_SET(VAR,yes)],
|
||||
[AS_VAR_SET(VAR,no)])
|
||||
if test x$2 != x; then
|
||||
AS_VAR_PUSHDEF([can_link],[tor_can_link_$1])
|
||||
AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[]])],
|
||||
AC_TRY_LINK([], [return 0;],
|
||||
[AS_VAR_SET(can_link,yes)],
|
||||
[AS_VAR_SET(can_link,no)])
|
||||
AS_VAR_POPDEF([can_link])
|
||||
|
@ -64,20 +63,11 @@ AC_DEFUN([TOR_TRY_COMPILE_WITH_CFLAGS], [
|
|||
CFLAGS="$tor_saved_CFLAGS"
|
||||
])
|
||||
if test x$VAR = xyes; then
|
||||
$3
|
||||
else
|
||||
$4
|
||||
CFLAGS="$CFLAGS $1"
|
||||
fi
|
||||
AS_VAR_POPDEF([VAR])
|
||||
])
|
||||
|
||||
dnl 1:flags
|
||||
dnl 2:also try to link (yes: non-empty string)
|
||||
dnl will set yes or no in $tor_can_link_$1 (as modified by AS_VAR_PUSHDEF)
|
||||
AC_DEFUN([TOR_CHECK_CFLAGS], [
|
||||
TOR_TRY_COMPILE_WITH_CFLAGS($1, $2, CFLAGS="$CFLAGS $1", true)
|
||||
])
|
||||
|
||||
dnl 1:flags
|
||||
dnl 2:extra ldflags
|
||||
dnl 3:extra libraries
|
||||
|
@ -93,7 +83,7 @@ AC_DEFUN([TOR_CHECK_LDFLAGS], [
|
|||
AC_RUN_IFELSE([AC_LANG_PROGRAM([#include <stdio.h>], [fputs("", stdout)])],
|
||||
[AS_VAR_SET(VAR,yes)],
|
||||
[AS_VAR_SET(VAR,no)],
|
||||
[AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[]])],
|
||||
[AC_TRY_LINK([], [return 0;],
|
||||
[AS_VAR_SET(VAR,yes)],
|
||||
[AS_VAR_SET(VAR,no)])])
|
||||
CFLAGS="$tor_saved_CFLAGS"
|
||||
|
@ -113,21 +103,21 @@ if test x$2 = xdevpkg; then
|
|||
h=" headers for"
|
||||
fi
|
||||
if test -f /etc/debian_version && test x"$tor_$1_$2_debian" != x; then
|
||||
AC_MSG_WARN([On Debian, you can install$h $1 using "apt-get install $tor_$1_$2_debian"])
|
||||
AC_WARN([On Debian, you can install$h $1 using "apt-get install $tor_$1_$2_debian"])
|
||||
if test x"$tor_$1_$2_debian" != x"$tor_$1_devpkg_debian"; then
|
||||
AC_MSG_WARN([ You will probably need $tor_$1_devpkg_debian too.])
|
||||
AC_WARN([ You will probably need $tor_$1_devpkg_debian too.])
|
||||
fi
|
||||
fi
|
||||
if test -f /etc/fedora-release && test x"$tor_$1_$2_redhat" != x; then
|
||||
AC_MSG_WARN([On Fedora, you can install$h $1 using "dnf install $tor_$1_$2_redhat"])
|
||||
AC_WARN([On Fedora Core, you can install$h $1 using "yum install $tor_$1_$2_redhat"])
|
||||
if test x"$tor_$1_$2_redhat" != x"$tor_$1_devpkg_redhat"; then
|
||||
AC_MSG_WARN([ You will probably need to install $tor_$1_devpkg_redhat too.])
|
||||
AC_WARN([ You will probably need to install $tor_$1_devpkg_redhat too.])
|
||||
fi
|
||||
else
|
||||
if test -f /etc/redhat-release && test x"$tor_$1_$2_redhat" != x; then
|
||||
AC_MSG_WARN([On most Redhat-based systems, you can get$h $1 by installing the $tor_$1_$2_redhat RPM package])
|
||||
AC_WARN([On most Redhat-based systems, you can get$h $1 by installing the $tor_$1_$2_redhat RPM package])
|
||||
if test x"$tor_$1_$2_redhat" != x"$tor_$1_devpkg_redhat"; then
|
||||
AC_MSG_WARN([ You will probably need to install $tor_$1_devpkg_redhat too.])
|
||||
AC_WARN([ You will probably need to install $tor_$1_devpkg_redhat too.])
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
@ -147,7 +137,7 @@ dnl
|
|||
AC_DEFUN([TOR_SEARCH_LIBRARY], [
|
||||
try$1dir=""
|
||||
AC_ARG_WITH($1-dir,
|
||||
AS_HELP_STRING(--with-$1-dir=PATH, [specify path to $1 installation]),
|
||||
[ --with-$1-dir=PATH Specify path to $1 installation ],
|
||||
[
|
||||
if test x$withval != xno ; then
|
||||
try$1dir="$withval"
|
||||
|
@ -245,10 +235,7 @@ if test "$cross_compiling" != yes; then
|
|||
LDFLAGS="$tor_tryextra $orig_LDFLAGS"
|
||||
fi
|
||||
AC_RUN_IFELSE([AC_LANG_PROGRAM([$5], [$6])],
|
||||
[runnable=yes], [runnable=no],
|
||||
[AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[]])],
|
||||
[runnable=yes],
|
||||
[runnable=no])])
|
||||
[runnable=yes], [runnable=no])
|
||||
if test "$runnable" = yes; then
|
||||
tor_cv_library_$1_linker_option=$tor_tryextra
|
||||
break
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
#!/bin/sh
|
||||
|
||||
if [ -x "`which autoreconf 2>/dev/null`" ] ; then
|
||||
opt="-i -f -W all,error"
|
||||
opt="-if"
|
||||
|
||||
for i in $@; do
|
||||
case "$i" in
|
||||
-v)
|
||||
opt="${opt} -v"
|
||||
opt=$opt"v"
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
|
|
@ -1,37 +0,0 @@
|
|||
This file is here to keep git from removing the changes directory when
|
||||
all the changes files have been merged.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
"I'm Nobody! Who are you?
|
||||
Are you--Nobody--too?
|
||||
Then there's a pair of us!
|
||||
Don’t tell! they'd advertise--you know!
|
||||
|
||||
How dreary--to be--Somebody!
|
||||
How public--like a Frog--
|
||||
To tell one's name--the livelong June--
|
||||
To an admiring Bog!"
|
||||
-- Emily Dickinson
|
||||
|
|
@ -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,7 @@
|
|||
o Minor bugfixes (network layer):
|
||||
- When closing a connection via close_connection_immediately(), we
|
||||
mark it as "not blocked on bandwidth", to prevent later calls
|
||||
from trying to unblock it, and give it permission to read. This
|
||||
fixes a backtrace warning that can happen on relays under various
|
||||
circumstances. Fixes bug 24167; bugfix on 0.1.0.1-rc.
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
o Minor bugfixes (compilation):
|
||||
- Fix a signed/unsigned comparison warning introduced by our
|
||||
fix to TROVE-2017-009. Fixes bug 24480; bugfix on 0.2.5.16.
|
|
@ -0,0 +1,7 @@
|
|||
o Minor bugfixes (memory usage):
|
||||
|
||||
- When queuing DESTROY cells on a channel, only queue the
|
||||
circuit-id and reason fields: not the entire 514-byte
|
||||
cell. This fix should help mitigate any bugs or attacks that
|
||||
fill up these queues, and free more RAM for other uses. Fixes
|
||||
bug 24666; bugfix on 0.2.5.1-alpha.
|
|
@ -1,3 +0,0 @@
|
|||
o Minor bugfixes (onion services):
|
||||
- Fix a bug that blocked the creation of ephemeral v3 onion services. Fixes
|
||||
bug 25939; bugfix on 0.3.4.1-alpha.
|
|
@ -1,5 +0,0 @@
|
|||
o Minor bugfixes (test coverage tools):
|
||||
- Update our "cov-diff" script to handle output from the latest
|
||||
version of gcov, and to remove extraneous timestamp information
|
||||
from its output. Fixes bugs 26101 and 26102; bugfix on
|
||||
0.2.5.1-alpha.
|
|
@ -1,7 +0,0 @@
|
|||
o Minor bugfixes (compatibility, openssl):
|
||||
- Work around a change in OpenSSL 1.1.1 where
|
||||
return values that would previously indicate "no password" now
|
||||
indicate an empty password. Without this workaround, Tor instances
|
||||
running with OpenSSL 1.1.1 would accept descriptors that other Tor
|
||||
instances would reject. Fixes bug 26116; bugfix on 0.2.5.16.
|
||||
|
|
@ -1,6 +0,0 @@
|
|||
o Minor bugfixes (controller):
|
||||
- Improve accuracy of the BUILDTIMEOUT_SET control port event's
|
||||
TIMEOUT_RATE and CLOSE_RATE fields. (We were previously miscounting
|
||||
the total number of circuits for these field values.) Fixes bug
|
||||
26121; bugfix on 0.3.3.1-alpha.
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
o Minor bugfixes (compilation):
|
||||
- Fix compilation when building with OpenSSL 1.1.0 with the
|
||||
"no-deprecated" flag enabled. Fixes bug 26156; bugfix on 0.3.4.1-alpha.
|
|
@ -1,4 +0,0 @@
|
|||
o Minor bugfixes (hardening):
|
||||
- Prevent a possible out-of-bounds smartlist read in
|
||||
protover_compute_vote(). Fixes bug 26196; bugfix on
|
||||
0.2.9.4-alpha.
|
|
@ -1,4 +0,0 @@
|
|||
o Minor bugfixes (control port):
|
||||
- Do not count 0-length RELAY_COMMAND_DATA cells as valid data in CIRC_BW
|
||||
events. Previously, such cells were counted entirely in the OVERHEAD
|
||||
field. Now they are not. Fixes bug 26259; bugfix on 0.3.4.1-alpha.
|
|
@ -1,4 +0,0 @@
|
|||
o Documentation:
|
||||
- In code comment, point the reader to the exact section
|
||||
in Tor specification that specifies circuit close error
|
||||
code values. Resolves ticket 25237.
|
|
@ -0,0 +1,4 @@
|
|||
o Minor features (geoip):
|
||||
- Update geoip and geoip6 to the December 6 2017 Maxmind GeoLite2
|
||||
Country database.
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
o Minor features (geoip):
|
||||
- Update geoip and geoip6 to the January 5 2018 Maxmind GeoLite2
|
||||
Country database.
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
o Minor features (geoip):
|
||||
- Update geoip and geoip6 to the February 7 2018 Maxmind GeoLite2
|
||||
Country database.
|
||||
|
|
@ -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 feature (relay statistics):
|
||||
- Change relay bandwidth reporting stats interval from 4 hours to 24 hours
|
||||
in order to reduce the efficiency of guard discovery attacks. Fixes
|
||||
ticket 23856.
|
|
@ -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.
|
1840
configure.ac
1840
configure.ac
File diff suppressed because it is too large
Load Diff
|
@ -11,13 +11,6 @@ add-tor is an old script to manipulate the approved-routers file.
|
|||
nagios-check-tor-authority-cert is a nagios script to check when Tor
|
||||
authority certificates are expired or nearly expired.
|
||||
|
||||
clang/ -- Files for use with the clang compiler
|
||||
-----------------------------------------------
|
||||
|
||||
sanitize_blacklist.txt is used to build Tor with clang's dynamic
|
||||
AddressSanitizer and UndefinedBehaviorSanitizer. It contains detailed
|
||||
instructions on configuration, build, and testing with clang's sanitizers.
|
||||
|
||||
client-tools/ -- Tools for use with Tor clients
|
||||
-----------------------------------------------
|
||||
|
||||
|
|
|
@ -1,103 +0,0 @@
|
|||
# clang sanitizer special case list
|
||||
# syntax specified in http://clang.llvm.org/docs/SanitizerSpecialCaseList.html
|
||||
# for more info see http://clang.llvm.org/docs/AddressSanitizer.html
|
||||
|
||||
#
|
||||
# Tor notes: This file is obsolete!
|
||||
#
|
||||
# It was necessary in order to apply the sanitizers to all of tor. But
|
||||
# we don't believe that's a good idea: some parts of tor need constant-time
|
||||
# behavior that is hard to guarantee with these sanitizers.
|
||||
#
|
||||
# If you need this behavior, then please consider --enable-expensive-hardening,
|
||||
# and report bugs as needed.
|
||||
#
|
||||
|
||||
# usage:
|
||||
# 1. configure tor build:
|
||||
# ./configure \
|
||||
# CC=clang \
|
||||
# CFLAGS="-fsanitize-blacklist=contrib/clang/sanitize_blacklist.txt -fsanitize=undefined -fsanitize=address -fno-sanitize-recover=all -fno-omit-frame-pointer -fno-optimize-sibling-calls -fno-inline" \
|
||||
# LDFLAGS="-fsanitize=address" \
|
||||
# --disable-gcc-hardening
|
||||
# and any other flags required to build tor on your OS.
|
||||
#
|
||||
# 2. build tor:
|
||||
# make
|
||||
#
|
||||
# 3. test tor:
|
||||
# ASAN_OPTIONS=allow_user_segv_handler=1 make test
|
||||
# ASAN_OPTIONS=allow_user_segv_handler=1 make check
|
||||
# make test-network # requires chutney
|
||||
#
|
||||
# 4. the tor binary is now instrumented with clang sanitizers,
|
||||
# and can be run just like a standard tor binary
|
||||
|
||||
# Compatibility:
|
||||
# This blacklist has been tested with clang 3.7's UndefinedBehaviorSanitizer
|
||||
# and AddressSanitizer on OS X 10.10 Yosemite, with all tests passing
|
||||
# on both x86_64 and i386 (using CC="clang -arch i386")
|
||||
# It has not been tested with ThreadSanitizer or MemorySanitizer
|
||||
# Success report and patches for other sanitizers or OSs are welcome
|
||||
|
||||
# ccache and make don't account for the sanitizer blacklist as a dependency
|
||||
# you might need to set CCACHE_DISABLE=1 and/or use make clean to workaround
|
||||
|
||||
# Configuration Flags:
|
||||
# -fno-sanitize-recover=all
|
||||
# causes clang to crash on undefined behavior, rather than printing
|
||||
# a warning and continuing (the AddressSanitizer always crashes)
|
||||
# -fno-omit-frame-pointer -fno-optimize-sibling-calls -fno-inline
|
||||
# make clang backtraces easier to read
|
||||
# --disable-gcc-hardening
|
||||
# disables warnings about the redefinition of _FORTIFY_SOURCE
|
||||
# (it conflicts with the sanitizers)
|
||||
|
||||
# Turning the sanitizers off for particular functions:
|
||||
# (Unfortunately, exempting functions doesn't work for the blacklisted
|
||||
# functions below, and we can't turn the code off because it's essential)
|
||||
#
|
||||
# #if defined(__has_feature)
|
||||
# #if __has_feature(address_sanitizer)
|
||||
# /* tell clang AddressSanitizer not to instrument this function */
|
||||
# #define NOASAN __attribute__((no_sanitize_address))
|
||||
# #define _CLANG_ASAN_
|
||||
# #else
|
||||
# #define NOASAN
|
||||
# #endif
|
||||
# #else
|
||||
# #define NOASAN
|
||||
# #endif
|
||||
#
|
||||
# /* Telling AddressSanitizer to not instrument a function */
|
||||
# void func(void) NOASAN;
|
||||
#
|
||||
# /* Including or excluding sections of code */
|
||||
# #ifdef _CLANG_ASAN_
|
||||
# /* code that only runs under address sanitizer */
|
||||
# #else
|
||||
# /* code that doesn't run under address sanitizer */
|
||||
# #endif
|
||||
|
||||
# Blacklist Entries:
|
||||
|
||||
# test-memwipe.c checks if a freed buffer was properly wiped
|
||||
fun:vmemeq
|
||||
fun:check_a_buffer
|
||||
|
||||
# we need to allow the tor bt handler to catch SIGSEGV
|
||||
# otherwise address sanitizer munges the expected output and the test fails
|
||||
# we can do this by setting an environmental variable
|
||||
# See https://code.google.com/p/address-sanitizer/wiki/Flags
|
||||
# ASAN_OPTIONS=allow_user_segv_handler=1
|
||||
|
||||
# test_bt_cl.c stores to a NULL pointer to trigger a crash
|
||||
fun:crash
|
||||
|
||||
# curve25519-donna.c left-shifts 1 bits into and past the sign bit of signed
|
||||
# integers. Until #13538 is resolved, we exempt functions that do left shifts.
|
||||
# Note that x86_64 uses curve25519-donna-c64.c instead of curve25519-donna.c
|
||||
fun:freduce_coefficients
|
||||
fun:freduce_degree
|
||||
fun:s32_eq
|
||||
fun:fcontract
|
|
@ -1,35 +1,24 @@
|
|||
# tor.service -- this systemd configuration file for Tor sets up a
|
||||
# relatively conservative, hardened Tor service. You may need to
|
||||
# edit it if you are making changes to your Tor configuration that it
|
||||
# does not allow. Package maintainers: this should be a starting point
|
||||
# for your tor.service; it is not the last point.
|
||||
|
||||
[Unit]
|
||||
Description=Anonymizing overlay network for TCP
|
||||
After=syslog.target network.target nss-lookup.target
|
||||
Description = Anonymizing overlay network for TCP
|
||||
After = syslog.target network.target nss-lookup.target
|
||||
|
||||
[Service]
|
||||
Type=notify
|
||||
NotifyAccess=all
|
||||
ExecStartPre=@BINDIR@/tor -f @CONFDIR@/torrc --verify-config
|
||||
ExecStart=@BINDIR@/tor -f @CONFDIR@/torrc
|
||||
ExecReload=/bin/kill -HUP ${MAINPID}
|
||||
KillSignal=SIGINT
|
||||
TimeoutSec=30
|
||||
Restart=on-failure
|
||||
WatchdogSec=1m
|
||||
LimitNOFILE=32768
|
||||
Type = simple
|
||||
ExecStartPre = @BINDIR@/tor -f @CONFDIR@/torrc --verify-config
|
||||
# A torrc that has "RunAsDaemon 1" won't work with the "simple" service type;
|
||||
# let's explicitly override it.
|
||||
ExecStart = @BINDIR@/tor -f @CONFDIR@/torrc --RunAsDaemon 0
|
||||
ExecReload = /bin/kill -HUP ${MAINPID}
|
||||
KillSignal = SIGINT
|
||||
TimeoutSec = 30
|
||||
Restart = on-failure
|
||||
LimitNOFILE = 32768
|
||||
|
||||
# Hardening
|
||||
PrivateTmp=yes
|
||||
PrivateDevices=yes
|
||||
ProtectHome=yes
|
||||
ProtectSystem=full
|
||||
ReadOnlyDirectories=/
|
||||
ReadWriteDirectories=-@LOCALSTATEDIR@/lib/tor
|
||||
ReadWriteDirectories=-@LOCALSTATEDIR@/log/tor
|
||||
NoNewPrivileges=yes
|
||||
CapabilityBoundingSet=CAP_SETUID CAP_SETGID CAP_NET_BIND_SERVICE
|
||||
PrivateTmp = yes
|
||||
DeviceAllow = /dev/null rw
|
||||
DeviceAllow = /dev/urandom r
|
||||
InaccessibleDirectories = /home
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
WantedBy = multi-user.target
|
||||
|
|
|
@ -87,7 +87,7 @@ RATE_UP=5000
|
|||
# machine does any other network activity. That is not very fun.
|
||||
RATE_UP_TOR=1500
|
||||
|
||||
# RATE_UP_TOR_CEIL is the maximum rate allowed for all Tor traffic in
|
||||
# RATE_UP_TOR_CEIL is the maximum rate allowed for all Tor trafic in
|
||||
# kbits/sec.
|
||||
RATE_UP_TOR_CEIL=5000
|
||||
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
!include "LogicLib.nsh"
|
||||
!include "FileFunc.nsh"
|
||||
!insertmacro GetParameters
|
||||
!define VERSION "0.3.4.1-alpha-dev"
|
||||
!define VERSION "0.2.5.16-dev"
|
||||
!define INSTALLER "tor-${VERSION}-win32.exe"
|
||||
!define WEBSITE "https://www.torproject.org/"
|
||||
!define LICENSE "LICENSE"
|
||||
|
|
|
@ -0,0 +1,545 @@
|
|||
Hacking Tor: An Incomplete Guide
|
||||
================================
|
||||
|
||||
Getting started
|
||||
---------------
|
||||
|
||||
For full information on how Tor is supposed to work, look at the files in
|
||||
https://gitweb.torproject.org/torspec.git/tree
|
||||
|
||||
For an explanation of how to change Tor's design to work differently, look at
|
||||
https://gitweb.torproject.org/torspec.git/blob_plain/HEAD:/proposals/001-process.txt
|
||||
|
||||
For the latest version of the code, get a copy of git, and
|
||||
|
||||
git clone https://git.torproject.org/git/tor
|
||||
|
||||
We talk about Tor on the tor-talk mailing list. Design proposals and
|
||||
discussion belong on the tor-dev mailing list. We hang around on
|
||||
irc.oftc.net, with general discussion happening on #tor and development
|
||||
happening on #tor-dev.
|
||||
|
||||
How we use Git branches
|
||||
-----------------------
|
||||
|
||||
Each main development series (like 0.2.1, 0.2.2, etc) has its main work
|
||||
applied to a single branch. At most one series can be the development series
|
||||
at a time; all other series are maintenance series that get bug-fixes only.
|
||||
The development series is built in a git branch called "master"; the
|
||||
maintenance series are built in branches called "maint-0.2.0", "maint-0.2.1",
|
||||
and so on. We regularly merge the active maint branches forward.
|
||||
|
||||
For all series except the development series, we also have a "release" branch
|
||||
(as in "release-0.2.1"). The release series is based on the corresponding
|
||||
maintenance series, except that it deliberately lags the maint series for
|
||||
most of its patches, so that bugfix patches are not typically included in a
|
||||
maintenance release until they've been tested for a while in a development
|
||||
release. Occasionally, we'll merge an urgent bugfix into the release branch
|
||||
before it gets merged into maint, but that's rare.
|
||||
|
||||
If you're working on a bugfix for a bug that occurs in a particular version,
|
||||
base your bugfix branch on the "maint" branch for the first supported series
|
||||
that has that bug. (As of June 2013, we're supporting 0.2.3 and later.) If
|
||||
you're working on a new feature, base it on the master branch.
|
||||
|
||||
|
||||
How we log changes
|
||||
------------------
|
||||
|
||||
When you do a commit that needs a ChangeLog entry, add a new file to
|
||||
the "changes" toplevel subdirectory. It should have the format of a
|
||||
one-entry changelog section from the current ChangeLog file, as in
|
||||
|
||||
o Major bugfixes:
|
||||
- Fix a potential buffer overflow. Fixes bug 99999; bugfix on
|
||||
0.3.1.4-beta.
|
||||
|
||||
To write a changes file, first categorize the change. Some common categories
|
||||
are: Minor bugfixes, Major bugfixes, Minor features, Major features, Code
|
||||
simplifications and refactoring. Then say what the change does. If
|
||||
it's a bugfix, mention what bug it fixes and when the bug was
|
||||
introduced. To find out which Git tag the change was introduced in,
|
||||
you can use "git describe --contains <sha1 of commit>".
|
||||
|
||||
If at all possible, try to create this file in the same commit where
|
||||
you are making the change. Please give it a distinctive name that no
|
||||
other branch will use for the lifetime of your change.
|
||||
|
||||
When we go to make a release, we will concatenate all the entries
|
||||
in changes to make a draft changelog, and clear the directory. We'll
|
||||
then edit the draft changelog into a nice readable format.
|
||||
|
||||
What needs a changes file?::
|
||||
A not-exhaustive list: Anything that might change user-visible
|
||||
behavior. Anything that changes internals, documentation, or the build
|
||||
system enough that somebody could notice. Big or interesting code
|
||||
rewrites. Anything about which somebody might plausibly wonder "when
|
||||
did that happen, and/or why did we do that" 6 months down the line.
|
||||
|
||||
Why use changes files instead of Git commit messages?::
|
||||
Git commit messages are written for developers, not users, and they
|
||||
are nigh-impossible to revise after the fact.
|
||||
|
||||
Why use changes files instead of entries in the ChangeLog?::
|
||||
Having every single commit touch the ChangeLog file tended to create
|
||||
zillions of merge conflicts.
|
||||
|
||||
Useful tools
|
||||
------------
|
||||
|
||||
These aren't strictly necessary for hacking on Tor, but they can help track
|
||||
down bugs.
|
||||
|
||||
Jenkins
|
||||
~~~~~~~
|
||||
|
||||
https://jenkins.torproject.org
|
||||
|
||||
Dmalloc
|
||||
~~~~~~~
|
||||
|
||||
The dmalloc library will keep track of memory allocation, so you can find out
|
||||
if we're leaking memory, doing any double-frees, or so on.
|
||||
|
||||
dmalloc -l ~/dmalloc.log
|
||||
(run the commands it tells you)
|
||||
./configure --with-dmalloc
|
||||
|
||||
Valgrind
|
||||
~~~~~~~~
|
||||
|
||||
valgrind --leak-check=yes --error-limit=no --show-reachable=yes src/or/tor
|
||||
|
||||
(Note that if you get a zillion openssl warnings, you will also need to
|
||||
pass --undef-value-errors=no to valgrind, or rebuild your openssl
|
||||
with -DPURIFY.)
|
||||
|
||||
Running gcov for unit test coverage
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
-----
|
||||
./configure --enable-coverage
|
||||
make
|
||||
make check
|
||||
mkdir coverage-output
|
||||
./scripts/test/coverage coverage-output
|
||||
-----
|
||||
|
||||
(On OSX, you'll need to start with "--enable-coverage CC=clang".)
|
||||
|
||||
Then, look at the .gcov files in coverage-output. '-' before a line means
|
||||
that the compiler generated no code for that line. '######' means that the
|
||||
line was never reached. Lines with numbers were called that number of times.
|
||||
|
||||
If that doesn't work:
|
||||
* Try configuring Tor with --disable-gcc-hardening
|
||||
* You might need to run 'make clean' after you run './configure'.
|
||||
|
||||
If you make changes to Tor and want to get another set of coverage results,
|
||||
you can run "make reset-gcov" to clear the intermediary gcov output.
|
||||
|
||||
If you have two different "coverage-output" directories, and you want to see
|
||||
a meaningful diff between them, you can run:
|
||||
|
||||
-----
|
||||
./scripts/test/cov-diff coverage-output1 coverage-output2 | less
|
||||
-----
|
||||
|
||||
In this diff, any lines that were visited at least once will have coverage
|
||||
"1". This lets you inspect what you (probably) really want to know: which
|
||||
untested lines were changed? Are there any new untested lines?
|
||||
|
||||
Running integration tests
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
We have the beginnings of a set of scripts to run integration tests using
|
||||
Chutney. To try them, set CHUTNEY_PATH to your chutney source directory, and
|
||||
run "make test-network".
|
||||
|
||||
Profiling Tor with oprofile
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The oprofile tool runs (on Linux only!) to tell you what functions Tor is
|
||||
spending its CPU time in, so we can identify berformance pottlenecks.
|
||||
|
||||
Here are some basic instructions
|
||||
|
||||
- Build tor with debugging symbols (you probably already have, unless
|
||||
you messed with CFLAGS during the build process).
|
||||
- Build all the libraries you care about with debugging symbols
|
||||
(probably you only care about libssl, maybe zlib and Libevent).
|
||||
- Copy this tor to a new directory
|
||||
- Copy all the libraries it uses to that dir too (ldd ./tor will
|
||||
tell you)
|
||||
- Set LD_LIBRARY_PATH to include that dir. ldd ./tor should now
|
||||
show you it's using the libs in that dir
|
||||
- Run that tor
|
||||
- Reset oprofiles counters/start it
|
||||
* "opcontrol --reset; opcontrol --start", if Nick remembers right.
|
||||
- After a while, have it dump the stats on tor and all the libs
|
||||
in that dir you created.
|
||||
* "opcontrol --dump;"
|
||||
* "opreport -l that_dir/*"
|
||||
- Profit
|
||||
|
||||
|
||||
Coding conventions
|
||||
------------------
|
||||
|
||||
Patch checklist
|
||||
~~~~~~~~~~~~~~~
|
||||
|
||||
If possible, send your patch as one of these (in descending order of
|
||||
preference)
|
||||
|
||||
- A git branch we can pull from
|
||||
- Patches generated by git format-patch
|
||||
- A unified diff
|
||||
|
||||
Did you remember...
|
||||
|
||||
- To build your code while configured with --enable-gcc-warnings?
|
||||
- To run "make check-spaces" on your code?
|
||||
- To run "make check-docs" to see whether all new options are on
|
||||
the manpage?
|
||||
- To write unit tests, as possible?
|
||||
- To base your code on the appropriate branch?
|
||||
- To include a file in the "changes" directory as appropriate?
|
||||
|
||||
Whitespace and C conformance
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Invoke "make check-spaces" from time to time, so it can tell you about
|
||||
deviations from our C whitespace style. Generally, we use:
|
||||
|
||||
- Unix-style line endings
|
||||
- K&R-style indentation
|
||||
- No space before newlines
|
||||
- A blank line at the end of each file
|
||||
- Never more than one blank line in a row
|
||||
- Always spaces, never tabs
|
||||
- No more than 79-columns per line.
|
||||
- Two spaces per indent.
|
||||
- A space between control keywords and their corresponding paren
|
||||
"if (x)", "while (x)", and "switch (x)", never "if(x)", "while(x)", or
|
||||
"switch(x)".
|
||||
- A space between anything and an open brace.
|
||||
- No space between a function name and an opening paren. "puts(x)", not
|
||||
"puts (x)".
|
||||
- Function declarations at the start of the line.
|
||||
|
||||
We try hard to build without warnings everywhere. In particular, if you're
|
||||
using gcc, you should invoke the configure script with the option
|
||||
"--enable-gcc-warnings". This will give a bunch of extra warning flags to
|
||||
the compiler, and help us find divergences from our preferred C style.
|
||||
|
||||
Getting emacs to edit Tor source properly
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Nick likes to put the following snippet in his .emacs file:
|
||||
|
||||
-----
|
||||
(add-hook 'c-mode-hook
|
||||
(lambda ()
|
||||
(font-lock-mode 1)
|
||||
(set-variable 'show-trailing-whitespace t)
|
||||
|
||||
(let ((fname (expand-file-name (buffer-file-name))))
|
||||
(cond
|
||||
((string-match "^/home/nickm/src/libevent" fname)
|
||||
(set-variable 'indent-tabs-mode t)
|
||||
(set-variable 'c-basic-offset 4)
|
||||
(set-variable 'tab-width 4))
|
||||
((string-match "^/home/nickm/src/tor" fname)
|
||||
(set-variable 'indent-tabs-mode nil)
|
||||
(set-variable 'c-basic-offset 2))
|
||||
((string-match "^/home/nickm/src/openssl" fname)
|
||||
(set-variable 'indent-tabs-mode t)
|
||||
(set-variable 'c-basic-offset 8)
|
||||
(set-variable 'tab-width 8))
|
||||
))))
|
||||
-----
|
||||
|
||||
You'll note that it defaults to showing all trailing whitespace. The "cond"
|
||||
test detects whether the file is one of a few C free software projects that I
|
||||
often edit, and sets up the indentation level and tab preferences to match
|
||||
what they want.
|
||||
|
||||
If you want to try this out, you'll need to change the filename regex
|
||||
patterns to match where you keep your Tor files.
|
||||
|
||||
If you use emacs for editing Tor and nothing else, you could always just say:
|
||||
|
||||
-----
|
||||
(add-hook 'c-mode-hook
|
||||
(lambda ()
|
||||
(font-lock-mode 1)
|
||||
(set-variable 'show-trailing-whitespace t)
|
||||
(set-variable 'indent-tabs-mode nil)
|
||||
(set-variable 'c-basic-offset 2)))
|
||||
-----
|
||||
|
||||
There is probably a better way to do this. No, we are probably not going
|
||||
to clutter the files with emacs stuff.
|
||||
|
||||
|
||||
Functions to use
|
||||
~~~~~~~~~~~~~~~~
|
||||
|
||||
We have some wrapper functions like tor_malloc, tor_free, tor_strdup, and
|
||||
tor_gettimeofday; use them instead of their generic equivalents. (They
|
||||
always succeed or exit.)
|
||||
|
||||
You can get a full list of the compatibility functions that Tor provides by
|
||||
looking through src/common/util.h and src/common/compat.h. You can see the
|
||||
available containers in src/common/containers.h. You should probably
|
||||
familiarize yourself with these modules before you write too much code, or
|
||||
else you'll wind up reinventing the wheel.
|
||||
|
||||
Use 'INLINE' instead of 'inline', so that we work properly on Windows.
|
||||
|
||||
Calling and naming conventions
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Whenever possible, functions should return -1 on error and 0 on success.
|
||||
|
||||
For multi-word identifiers, use lowercase words combined with
|
||||
underscores. (e.g., "multi_word_identifier"). Use ALL_CAPS for macros and
|
||||
constants.
|
||||
|
||||
Typenames should end with "_t".
|
||||
|
||||
Function names should be prefixed with a module name or object name. (In
|
||||
general, code to manipulate an object should be a module with the same name
|
||||
as the object, so it's hard to tell which convention is used.)
|
||||
|
||||
Functions that do things should have imperative-verb names
|
||||
(e.g. buffer_clear, buffer_resize); functions that return booleans should
|
||||
have predicate names (e.g. buffer_is_empty, buffer_needs_resizing).
|
||||
|
||||
If you find that you have four or more possible return code values, it's
|
||||
probably time to create an enum. If you find that you are passing three or
|
||||
more flags to a function, it's probably time to create a flags argument that
|
||||
takes a bitfield.
|
||||
|
||||
What To Optimize
|
||||
~~~~~~~~~~~~~~~~
|
||||
|
||||
Don't optimize anything if it's not in the critical path. Right now, the
|
||||
critical path seems to be AES, logging, and the network itself. Feel free to
|
||||
do your own profiling to determine otherwise.
|
||||
|
||||
Log conventions
|
||||
~~~~~~~~~~~~~~~
|
||||
|
||||
https://trac.torproject.org/projects/tor/wiki/doc/TorFAQ#loglevel
|
||||
|
||||
No error or warning messages should be expected during normal OR or OP
|
||||
operation.
|
||||
|
||||
If a library function is currently called such that failure always means ERR,
|
||||
then the library function should log WARN and let the caller log ERR.
|
||||
|
||||
Every message of severity INFO or higher should either (A) be intelligible
|
||||
to end-users who don't know the Tor source; or (B) somehow inform the
|
||||
end-users that they aren't expected to understand the message (perhaps
|
||||
with a string like "internal error"). Option (A) is to be preferred to
|
||||
option (B).
|
||||
|
||||
Doxygen
|
||||
~~~~~~~~
|
||||
|
||||
We use the 'doxygen' utility to generate documentation from our
|
||||
source code. Here's how to use it:
|
||||
|
||||
1. Begin every file that should be documented with
|
||||
/**
|
||||
* \file filename.c
|
||||
* \brief Short description of the file.
|
||||
**/
|
||||
|
||||
(Doxygen will recognize any comment beginning with /** as special.)
|
||||
|
||||
2. Before any function, structure, #define, or variable you want to
|
||||
document, add a comment of the form:
|
||||
|
||||
/** Describe the function's actions in imperative sentences.
|
||||
*
|
||||
* Use blank lines for paragraph breaks
|
||||
* - and
|
||||
* - hyphens
|
||||
* - for
|
||||
* - lists.
|
||||
*
|
||||
* Write <b>argument_names</b> in boldface.
|
||||
*
|
||||
* \code
|
||||
* place_example_code();
|
||||
* between_code_and_endcode_commands();
|
||||
* \endcode
|
||||
*/
|
||||
|
||||
3. Make sure to escape the characters "<", ">", "\", "%" and "#" as "\<",
|
||||
"\>", "\\", "\%", and "\#".
|
||||
|
||||
4. To document structure members, you can use two forms:
|
||||
|
||||
struct foo {
|
||||
/** You can put the comment before an element; */
|
||||
int a;
|
||||
int b; /**< Or use the less-than symbol to put the comment
|
||||
* after the element. */
|
||||
};
|
||||
|
||||
5. To generate documentation from the Tor source code, type:
|
||||
|
||||
$ doxygen -g
|
||||
|
||||
To generate a file called 'Doxyfile'. Edit that file and run
|
||||
'doxygen' to generate the API documentation.
|
||||
|
||||
6. See the Doxygen manual for more information; this summary just
|
||||
scratches the surface.
|
||||
|
||||
Doxygen comment conventions
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Say what functions do as a series of one or more imperative sentences, as
|
||||
though you were telling somebody how to be the function. In other words, DO
|
||||
NOT say:
|
||||
|
||||
/** The strtol function parses a number.
|
||||
*
|
||||
* nptr -- the string to parse. It can include whitespace.
|
||||
* endptr -- a string pointer to hold the first thing that is not part
|
||||
* of the number, if present.
|
||||
* base -- the numeric base.
|
||||
* returns: the resulting number.
|
||||
*/
|
||||
long strtol(const char *nptr, char **nptr, int base);
|
||||
|
||||
Instead, please DO say:
|
||||
|
||||
/** Parse a number in radix <b>base</b> from the string <b>nptr</b>,
|
||||
* and return the result. Skip all leading whitespace. If
|
||||
* <b>endptr</b> is not NULL, set *<b>endptr</b> to the first character
|
||||
* after the number parsed.
|
||||
**/
|
||||
long strtol(const char *nptr, char **nptr, int base);
|
||||
|
||||
Doxygen comments are the contract in our abstraction-by-contract world: if
|
||||
the functions that call your function rely on it doing something, then your
|
||||
function should mention that it does that something in the documentation. If
|
||||
you rely on a function doing something beyond what is in its documentation,
|
||||
then you should watch out, or it might do something else later.
|
||||
|
||||
Putting out a new release
|
||||
-------------------------
|
||||
|
||||
Here are the steps Roger takes when putting out a new Tor release:
|
||||
|
||||
1) Use it for a while, as a client, as a relay, as a hidden service,
|
||||
and as a directory authority. See if it has any obvious bugs, and
|
||||
resolve those.
|
||||
|
||||
1.5) As applicable, merge the maint-X branch into the release-X branch.
|
||||
|
||||
2) Gather the changes/* files into a changelog entry, rewriting many
|
||||
of them and reordering to focus on what users and funders would find
|
||||
interesting and understandable.
|
||||
|
||||
2.1) Make sure that everything that wants a bug number has one.
|
||||
Make sure that everything which is a bugfix says what version
|
||||
it was a bugfix on.
|
||||
2.2) Concatenate them.
|
||||
2.3) Sort them by section. Within each section, sort by "version it's
|
||||
a bugfix on", else by numerical ticket order.
|
||||
|
||||
2.4) Clean them up:
|
||||
|
||||
Standard idioms:
|
||||
"Fixes bug 9999; bugfix on 0.3.3.3-alpha."
|
||||
|
||||
One period after a space.
|
||||
|
||||
Make stuff very terse
|
||||
|
||||
Make sure each section name ends with a colon
|
||||
|
||||
Describe the user-visible problem right away
|
||||
|
||||
Mention relevant config options by name. If they're rare or unusual,
|
||||
remind people what they're for
|
||||
|
||||
Avoid starting lines with open-paren
|
||||
|
||||
Present and imperative tense: not past.
|
||||
|
||||
'Relays', not 'servers' or 'nodes' or 'Tor relays'.
|
||||
|
||||
"Stop FOOing", not "Fix a bug where we would FOO".
|
||||
|
||||
Try not to let any given section be longer than about a page. Break up
|
||||
long sections into subsections by some sort of common subtopic. This
|
||||
guideline is especially important when organizing Release Notes for
|
||||
new stable releases.
|
||||
|
||||
If a given changes stanza showed up in a different release (e.g.
|
||||
maint-0.2.1), be sure to make the stanzas identical (so people can
|
||||
distinguish if these are the same change).
|
||||
|
||||
2.5) Merge them in.
|
||||
|
||||
2.6) Clean everything one last time.
|
||||
|
||||
2.7) Run it through fmt to make it pretty.
|
||||
|
||||
3) Compose a short release blurb to highlight the user-facing
|
||||
changes. Insert said release blurb into the ChangeLog stanza. If it's
|
||||
a stable release, add it to the ReleaseNotes file too. If we're adding
|
||||
to a release-0.2.x branch, manually commit the changelogs to the later
|
||||
git branches too.
|
||||
|
||||
4) Bump the version number in configure.ac and rebuild.
|
||||
|
||||
5) Make dist, put the tarball up somewhere, and tell #tor about it. Wait
|
||||
a while to see if anybody has problems building it. Try to get Sebastian
|
||||
or somebody to try building it on Windows.
|
||||
|
||||
6) Get at least two of weasel/arma/sebastian to put the new version number
|
||||
in their approved versions list.
|
||||
|
||||
7) Sign the tarball, then sign and push the git tag:
|
||||
gpg -ba <the_tarball>
|
||||
git tag -u <keyid> tor-0.2.x.y-status
|
||||
git push origin tag tor-0.2.x.y-status
|
||||
|
||||
8) scp the tarball and its sig to the website in the dist/ directory
|
||||
(i.e. /srv/www-master.torproject.org/htdocs/dist/ on vescum). Edit
|
||||
"include/versions.wmi" and "Makefile" to note the new version. From your
|
||||
website checkout, run ./publish to build and publish the website.
|
||||
|
||||
9) Email the packagers (cc'ing tor-assistants) that a new tarball is up.
|
||||
|
||||
10) 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
|
||||
the menu on the left. At the right, there will be an "Add version"
|
||||
box. By convention, we enter the version in the form "Tor:
|
||||
0.2.2.23-alpha" (or whatever the version is), and we select the date as
|
||||
the date in the ChangeLog.
|
||||
|
||||
11) Forward-port the ChangeLog.
|
||||
|
||||
12) Wait up to a day or two (for a development release), or until most
|
||||
packages are up (for a stable release), and mail the release blurb and
|
||||
changelog to tor-talk or tor-announce.
|
||||
|
||||
(We might be moving to faster announcements, but don't announce until
|
||||
the website is at least updated.)
|
||||
|
||||
13) If it's a stable release, bump the version number in the maint-x.y.z
|
||||
branch to "newversion-dev", and do a "merge -s ours" merge to avoid
|
||||
taking that change into master. Do a similar 'merge -s theirs'
|
||||
merge to get the change (and only that change) into release. (Some
|
||||
of the build scripts require that maint merge cleanly into release.)
|
||||
|
|
@ -1,437 +0,0 @@
|
|||
Coding conventions for Tor
|
||||
==========================
|
||||
|
||||
tl;dr:
|
||||
|
||||
- Run configure with `--enable-fatal-warnings`
|
||||
- Document your functions
|
||||
- Write unit tests
|
||||
- Run `make check` before submitting a patch
|
||||
- Run `make distcheck` if you have made changes to build system components
|
||||
- Add a file in `changes` for your branch.
|
||||
|
||||
Patch checklist
|
||||
---------------
|
||||
|
||||
If possible, send your patch as one of these (in descending order of
|
||||
preference)
|
||||
|
||||
- A git branch we can pull from
|
||||
- Patches generated by git format-patch
|
||||
- A unified diff
|
||||
|
||||
Did you remember...
|
||||
|
||||
- To build your code while configured with `--enable-fatal-warnings`?
|
||||
- To run `make check-docs` to see whether all new options are on
|
||||
the manpage?
|
||||
- To write unit tests, as possible?
|
||||
- To run `make test-full` to test against all unit and integration tests (or
|
||||
`make test-full-online` if you have a working connection to the internet)?
|
||||
- To test that the distribution will actually work via `make distcheck`?
|
||||
- To base your code on the appropriate branch?
|
||||
- To 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
|
||||
=======================
|
||||
|
||||
Each main development series (like 0.2.1, 0.2.2, etc) has its main work
|
||||
applied to a single branch. At most one series can be the development series
|
||||
at a time; all other series are maintenance series that get bug-fixes only.
|
||||
The development series is built in a git branch called "master"; the
|
||||
maintenance series are built in branches called "maint-0.2.0", "maint-0.2.1",
|
||||
and so on. We regularly merge the active maint branches forward.
|
||||
|
||||
For all series except the development series, we also have a "release" branch
|
||||
(as in "release-0.2.1"). The release series is based on the corresponding
|
||||
maintenance series, except that it deliberately lags the maint series for
|
||||
most of its patches, so that bugfix patches are not typically included in a
|
||||
maintenance release until they've been tested for a while in a development
|
||||
release. Occasionally, we'll merge an urgent bugfix into the release branch
|
||||
before it gets merged into maint, but that's rare.
|
||||
|
||||
If you're working on a bugfix for a bug that occurs in a particular version,
|
||||
base your bugfix branch on the "maint" branch for the first supported series
|
||||
that has that bug. (As of June 2013, we're supporting 0.2.3 and later.)
|
||||
|
||||
If you're working on a new feature, base it on the master branch. If you're
|
||||
working on a new feature and it will take a while to implement and/or you'd
|
||||
like to avoid the possibility of unrelated bugs in Tor while you're
|
||||
implementing your feature, consider branching off of the latest maint- branch.
|
||||
_Never_ branch off a relase- branch. Don't branch off a tag either: they come
|
||||
from release branches. Doing so will likely produce a nightmare of merge
|
||||
conflicts in the ChangeLog when it comes time to merge your branch into Tor.
|
||||
Best advice: don't try to keep an independent branch forked for more than 6
|
||||
months and expect it to merge cleanly. Try to merge pieces early and often.
|
||||
|
||||
|
||||
How we log changes
|
||||
==================
|
||||
|
||||
When you do a commit that needs a ChangeLog entry, add a new file to
|
||||
the `changes` toplevel subdirectory. It should have the format of a
|
||||
one-entry changelog section from the current ChangeLog file, as in
|
||||
|
||||
- Major bugfixes:
|
||||
- Fix a potential buffer overflow. Fixes bug 99999; bugfix on
|
||||
0.3.1.4-beta.
|
||||
|
||||
To write a changes file, first categorize the change. Some common categories
|
||||
are: Minor bugfixes, Major bugfixes, Minor features, Major features, Code
|
||||
simplifications and refactoring. Then say what the change does. If
|
||||
it's a bugfix, mention what bug it fixes and when the bug was
|
||||
introduced. To find out which Git tag the change was introduced in,
|
||||
you can use `git describe --contains <sha1 of commit>`.
|
||||
|
||||
If at all possible, try to create this file in the same commit where you are
|
||||
making the change. Please give it a distinctive name that no other branch will
|
||||
use for the lifetime of your change. To verify the format of the changes file,
|
||||
you can use `make check-changes`. This is run automatically as part of
|
||||
`make check` -- if it fails, we must fix it before we release. These
|
||||
checks are implemented in `scripts/maint/lintChanges.py`.
|
||||
|
||||
Changes file style guide:
|
||||
* Changes files begin with " o Header (subheading):". The header
|
||||
should usually be "Minor/Major bugfixes/features". The subheading is a
|
||||
particular area within Tor. See the ChangeLog for examples.
|
||||
|
||||
* Make everything terse.
|
||||
|
||||
* Write from the user's point of view: describe the user-visible changes
|
||||
right away.
|
||||
|
||||
* Mention configuration options by name. If they're rare or unusual,
|
||||
remind people what they're for.
|
||||
|
||||
* Describe changes in the present tense and in the imperative: not past.
|
||||
|
||||
* Every bugfix should have a sentence of the form "Fixes bug 1234; bugfix
|
||||
on 0.1.2.3-alpha", describing what bug was fixed and where it came from.
|
||||
|
||||
* "Relays", not "servers", "nodes", or "Tor relays".
|
||||
|
||||
When we go to make a release, we will concatenate all the entries
|
||||
in changes to make a draft changelog, and clear the directory. We'll
|
||||
then edit the draft changelog into a nice readable format.
|
||||
|
||||
What needs a changes file?
|
||||
|
||||
* A not-exhaustive list: Anything that might change user-visible
|
||||
behavior. Anything that changes internals, documentation, or the build
|
||||
system enough that somebody could notice. Big or interesting code
|
||||
rewrites. Anything about which somebody might plausibly wonder "when
|
||||
did that happen, and/or why did we do that" 6 months down the line.
|
||||
|
||||
What does not need a changes file?
|
||||
|
||||
* Bugfixes for code that hasn't shipped in any released version of Tor
|
||||
|
||||
Why use changes files instead of Git commit messages?
|
||||
|
||||
* Git commit messages are written for developers, not users, and they
|
||||
are nigh-impossible to revise after the fact.
|
||||
|
||||
Why use changes files instead of entries in the ChangeLog?
|
||||
|
||||
* Having every single commit touch the ChangeLog file tended to create
|
||||
zillions of merge conflicts.
|
||||
|
||||
Whitespace and C conformance
|
||||
----------------------------
|
||||
|
||||
Invoke `make check-spaces` from time to time, so it can tell you about
|
||||
deviations from our C whitespace style. Generally, we use:
|
||||
|
||||
- Unix-style line endings
|
||||
- K&R-style indentation
|
||||
- No space before newlines
|
||||
- A blank line at the end of each file
|
||||
- Never more than one blank line in a row
|
||||
- Always spaces, never tabs
|
||||
- No more than 79-columns per line.
|
||||
- Two spaces per indent.
|
||||
- A space between control keywords and their corresponding paren
|
||||
`if (x)`, `while (x)`, and `switch (x)`, never `if(x)`, `while(x)`, or
|
||||
`switch(x)`.
|
||||
- A space between anything and an open brace.
|
||||
- No space between a function name and an opening paren. `puts(x)`, not
|
||||
`puts (x)`.
|
||||
- Function declarations at the start of the line.
|
||||
|
||||
We try hard to build without warnings everywhere. In particular, if
|
||||
you're using gcc, you should invoke the configure script with the
|
||||
option `--enable-fatal-warnings`. This will tell the compiler
|
||||
to make all warnings into errors.
|
||||
|
||||
Functions to use; functions not to use
|
||||
--------------------------------------
|
||||
|
||||
We have some wrapper functions like `tor_malloc`, `tor_free`, `tor_strdup`, and
|
||||
`tor_gettimeofday;` use them instead of their generic equivalents. (They
|
||||
always succeed or exit.)
|
||||
|
||||
You can get a full list of the compatibility functions that Tor provides by
|
||||
looking through `src/common/util*.h` and `src/common/compat*.h`. You can see the
|
||||
available containers in `src/common/containers*.h`. You should probably
|
||||
familiarize yourself with these modules before you write too much code, or
|
||||
else you'll wind up reinventing the wheel.
|
||||
|
||||
We don't use `strcat` or `strcpy` or `sprintf` of any of those notoriously broken
|
||||
old C functions. Use `strlcat`, `strlcpy`, or `tor_snprintf/tor_asprintf` instead.
|
||||
|
||||
We don't call `memcmp()` directly. Use `fast_memeq()`, `fast_memneq()`,
|
||||
`tor_memeq()`, or `tor_memneq()` for most purposes.
|
||||
|
||||
Also see a longer list of functions to avoid in:
|
||||
https://people.torproject.org/~nickm/tor-auto/internal/this-not-that.html
|
||||
|
||||
Floating point math is hard
|
||||
---------------------------
|
||||
|
||||
Floating point arithmetic as typically implemented by computers is
|
||||
very counterintuitive. Failure to adequately analyze floating point
|
||||
usage can result in surprising behavior and even security
|
||||
vulnerabilities!
|
||||
|
||||
General advice:
|
||||
|
||||
- Don't use floating point.
|
||||
- If you must use floating point, document how the limits of
|
||||
floating point precision and calculation accuracy affect function
|
||||
outputs.
|
||||
- Try to do as much as possible of your calculations using integers
|
||||
(possibly acting as fixed-point numbers) and convert to floating
|
||||
point for display.
|
||||
- If you must send floating point numbers on the wire, serialize
|
||||
them in a platform-independent way. Tor avoids exchanging
|
||||
floating-point values, but when it does, it uses ASCII numerals,
|
||||
with a decimal point (".").
|
||||
- Binary fractions behave very differently from decimal fractions.
|
||||
Make sure you understand how these differences affect your
|
||||
calculations.
|
||||
- Every floating point arithmetic operation is an opportunity to
|
||||
lose precision, overflow, underflow, or otherwise produce
|
||||
undesired results. Addition and subtraction tend to be worse
|
||||
than multiplication and division (due to things like catastrophic
|
||||
cancellation). Try to arrange your calculations to minimize such
|
||||
effects.
|
||||
- Changing the order of operations changes the results of many
|
||||
floating-point calculations. Be careful when you simplify
|
||||
calculations! If the order is significant, document it using a
|
||||
code comment.
|
||||
- Comparing most floating point values for equality is unreliable.
|
||||
Avoid using `==`, instead, use `>=` or `<=`. If you use an
|
||||
epsilon value, make sure it's appropriate for the ranges in
|
||||
question.
|
||||
- Different environments (including compiler flags and per-thread
|
||||
state on a single platform!) can get different results from the
|
||||
same floating point calculations. This means you can't use
|
||||
floats in anything that needs to be deterministic, like consensus
|
||||
generation. This also makes reliable unit tests of
|
||||
floating-point outputs hard to write.
|
||||
|
||||
For additional useful advice (and a little bit of background), see
|
||||
[What Every Programmer Should Know About Floating-Point
|
||||
Arithmetic](http://floating-point-gui.de/).
|
||||
|
||||
A list of notable (and surprising) facts about floating point
|
||||
arithmetic is at [Floating-point
|
||||
complexities](https://randomascii.wordpress.com/2012/04/05/floating-point-complexities/).
|
||||
Most of that [series of posts on floating
|
||||
point](https://randomascii.wordpress.com/category/floating-point/) is
|
||||
helpful.
|
||||
|
||||
For more detailed (and math-intensive) background, see [What Every
|
||||
Computer Scientist Should Know About Floating-Point
|
||||
Arithmetic](https://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html).
|
||||
|
||||
Other C conventions
|
||||
-------------------
|
||||
|
||||
The `a ? b : c` trinary operator only goes inside other expressions;
|
||||
don't use it as a replacement for if. (You can ignore this inside macro
|
||||
definitions when necessary.)
|
||||
|
||||
Assignment operators shouldn't nest inside other expressions. (You can
|
||||
ignore this inside macro definitions when necessary.)
|
||||
|
||||
Functions not to write
|
||||
----------------------
|
||||
|
||||
Try to never hand-write new code to parse or generate binary
|
||||
formats. Instead, use trunnel if at all possible. See
|
||||
|
||||
https://gitweb.torproject.org/trunnel.git/tree
|
||||
|
||||
for more information about trunnel.
|
||||
|
||||
For information on adding new trunnel code to Tor, see src/trunnel/README
|
||||
|
||||
|
||||
Calling and naming conventions
|
||||
------------------------------
|
||||
|
||||
Whenever possible, functions should return -1 on error and 0 on success.
|
||||
|
||||
For multi-word identifiers, use lowercase words combined with
|
||||
underscores. (e.g., `multi_word_identifier`). Use ALL_CAPS for macros and
|
||||
constants.
|
||||
|
||||
Typenames should end with `_t`.
|
||||
|
||||
Function names should be prefixed with a module name or object name. (In
|
||||
general, code to manipulate an object should be a module with the same name
|
||||
as the object, so it's hard to tell which convention is used.)
|
||||
|
||||
Functions that do things should have imperative-verb names
|
||||
(e.g. `buffer_clear`, `buffer_resize`); functions that return booleans should
|
||||
have predicate names (e.g. `buffer_is_empty`, `buffer_needs_resizing`).
|
||||
|
||||
If you find that you have four or more possible return code values, it's
|
||||
probably time to create an enum. If you find that you are passing three or
|
||||
more flags to a function, it's probably time to create a flags argument that
|
||||
takes a bitfield.
|
||||
|
||||
What To Optimize
|
||||
----------------
|
||||
|
||||
Don't optimize anything if it's not in the critical path. Right now, the
|
||||
critical path seems to be AES, logging, and the network itself. Feel free to
|
||||
do your own profiling to determine otherwise.
|
||||
|
||||
Log conventions
|
||||
---------------
|
||||
|
||||
`https://www.torproject.org/docs/faq#LogLevel`
|
||||
|
||||
No error or warning messages should be expected during normal OR or OP
|
||||
operation.
|
||||
|
||||
If a library function is currently called such that failure always means ERR,
|
||||
then the library function should log WARN and let the caller log ERR.
|
||||
|
||||
Every message of severity INFO or higher should either (A) be intelligible
|
||||
to end-users who don't know the Tor source; or (B) somehow inform the
|
||||
end-users that they aren't expected to understand the message (perhaps
|
||||
with a string like "internal error"). Option (A) is to be preferred to
|
||||
option (B).
|
||||
|
||||
Assertions In Tor
|
||||
-----------------
|
||||
|
||||
Assertions should be used for bug-detection only. Don't use assertions to
|
||||
detect bad user inputs, network errors, resource exhaustion, or similar
|
||||
issues.
|
||||
|
||||
Tor is always built with assertions enabled, so try to only use
|
||||
`tor_assert()` for cases where you are absolutely sure that crashing is the
|
||||
least bad option. Many bugs have been caused by use of `tor_assert()` when
|
||||
another kind of check would have been safer.
|
||||
|
||||
If you're writing an assertion to test for a bug that you _can_ recover from,
|
||||
use `tor_assert_nonfatal()` in place of `tor_assert()`. If you'd like to
|
||||
write a conditional that incorporates a nonfatal assertion, use the `BUG()`
|
||||
macro, as in:
|
||||
|
||||
if (BUG(ptr == NULL))
|
||||
return -1;
|
||||
|
||||
Allocator conventions
|
||||
---------------------
|
||||
|
||||
By convention, any tor type with a name like `abc_t` should be allocated
|
||||
by a function named `abc_new()`. This function should never return
|
||||
NULL.
|
||||
|
||||
Also, a type named `abc_t` should be freed by a function named `abc_free_()`.
|
||||
Don't call this `abc_free_()` function directly -- instead, wrap it in a
|
||||
macro called `abc_free()`, using the `FREE_AND_NULL` macro:
|
||||
|
||||
void abc_free_(abc_t *obj);
|
||||
#define abc_free(obj) FREE_AND_NULL(abc_t, abc_free_, (obj))
|
||||
|
||||
This macro will free the underlying `abc_t` object, and will also set
|
||||
the object pointer to NULL.
|
||||
|
||||
You should define all `abc_free_()` functions to accept NULL inputs:
|
||||
|
||||
void
|
||||
abc_free_(abc_t *obj)
|
||||
{
|
||||
if (!obj)
|
||||
return;
|
||||
tor_free(obj->name);
|
||||
thing_free(obj->thing);
|
||||
tor_free(obj);
|
||||
}
|
||||
|
||||
If you need a free function that takes a `void *` argument (for example,
|
||||
to use it as a function callback), define it with a name like
|
||||
`abc_free_void()`:
|
||||
|
||||
static void
|
||||
abc_free_void_(void *obj)
|
||||
{
|
||||
abc_free_(obj);
|
||||
}
|
||||
|
||||
|
||||
Doxygen comment conventions
|
||||
---------------------------
|
||||
|
||||
Say what functions do as a series of one or more imperative sentences, as
|
||||
though you were telling somebody how to be the function. In other words, DO
|
||||
NOT say:
|
||||
|
||||
/** The strtol function parses a number.
|
||||
*
|
||||
* nptr -- the string to parse. It can include whitespace.
|
||||
* endptr -- a string pointer to hold the first thing that is not part
|
||||
* of the number, if present.
|
||||
* base -- the numeric base.
|
||||
* returns: the resulting number.
|
||||
*/
|
||||
long strtol(const char *nptr, char **nptr, int base);
|
||||
|
||||
Instead, please DO say:
|
||||
|
||||
/** Parse a number in radix <b>base</b> from the string <b>nptr</b>,
|
||||
* and return the result. Skip all leading whitespace. If
|
||||
* <b>endptr</b> is not NULL, set *<b>endptr</b> to the first character
|
||||
* after the number parsed.
|
||||
**/
|
||||
long strtol(const char *nptr, char **nptr, int base);
|
||||
|
||||
Doxygen comments are the contract in our abstraction-by-contract world: if
|
||||
the functions that call your function rely on it doing something, then your
|
||||
function should mention that it does that something in the documentation. If
|
||||
you rely on a function doing something beyond what is in its documentation,
|
||||
then you should watch out, or it might do something else later.
|
||||
|
|
@ -1,523 +0,0 @@
|
|||
|
||||
Rust Coding Standards
|
||||
=======================
|
||||
|
||||
You MUST follow the standards laid out in `.../doc/HACKING/CodingStandards.md`,
|
||||
where applicable.
|
||||
|
||||
Module/Crate Declarations
|
||||
---------------------------
|
||||
|
||||
Each Tor C module which is being rewritten MUST be in its own crate.
|
||||
See the structure of `.../src/rust` for examples.
|
||||
|
||||
In your crate, you MUST use `lib.rs` ONLY for pulling in external
|
||||
crates (e.g. `extern crate libc;`) and exporting public objects from
|
||||
other Rust modules (e.g. `pub use mymodule::foo;`). For example, if
|
||||
you create a crate in `.../src/rust/yourcrate`, your Rust code should
|
||||
live in `.../src/rust/yourcrate/yourcode.rs` and the public interface
|
||||
to it should be exported in `.../src/rust/yourcrate/lib.rs`.
|
||||
|
||||
If your code is to be called from Tor C code, you MUST define a safe
|
||||
`ffi.rs`. See the "Safety" section further down for more details.
|
||||
|
||||
For example, in a hypothetical `tor_addition` Rust module:
|
||||
|
||||
In `.../src/rust/tor_addition/addition.rs`:
|
||||
|
||||
pub fn get_sum(a: i32, b: i32) -> i32 {
|
||||
a + b
|
||||
}
|
||||
|
||||
In `.../src/rust/tor_addition/lib.rs`:
|
||||
|
||||
pub use addition::*;
|
||||
|
||||
In `.../src/rust/tor_addition/ffi.rs`:
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn tor_get_sum(a: c_int, b: c_int) -> c_int {
|
||||
get_sum(a, b)
|
||||
}
|
||||
|
||||
If your Rust code must call out to parts of Tor's C code, you must
|
||||
declare the functions you are calling in the `external` crate, located
|
||||
at `.../src/rust/external`.
|
||||
|
||||
<!-- XXX get better examples of how to declare these externs, when/how they -->
|
||||
<!-- XXX are unsafe, what they are expected to do —isis -->
|
||||
|
||||
Modules should strive to be below 500 lines (tests excluded). Single
|
||||
responsibility and limited dependencies should be a guiding standard.
|
||||
|
||||
If you have any external modules as dependencies (e.g. `extern crate
|
||||
libc;`), you MUST declare them in your crate's `lib.rs` and NOT in any
|
||||
other module.
|
||||
|
||||
Dependencies and versions
|
||||
---------------------------
|
||||
|
||||
In general, we use modules from only the Rust standard library
|
||||
whenever possible. We will review including external crates on a
|
||||
case-by-case basis.
|
||||
|
||||
If a crate only contains traits meant for compatibility between Rust
|
||||
crates, such as [the digest crate](https://crates.io/crates/digest) or
|
||||
[the failure crate](https://crates.io/crates/failure), it is very likely
|
||||
permissible to add it as a dependency. However, a brief review should
|
||||
be conducted as to the usefulness of implementing external traits
|
||||
(i.e. how widespread is the usage, how many other crates either
|
||||
implement the traits or have trait bounds based upon them), as well as
|
||||
the stability of the traits (i.e. if the trait is going to change, we'll
|
||||
potentially have to re-do all our implementations of it).
|
||||
|
||||
For large external libraries, especially which implement features which
|
||||
would be labour-intensive to reproduce/maintain ourselves, such as
|
||||
cryptographic or mathematical/statistics libraries, only crates which
|
||||
have stabilised to 1.0.0 should be considered, however, again, we may
|
||||
make exceptions on a case-by-case basis.
|
||||
|
||||
Currently, Tor requires that you use the latest stable Rust version. At
|
||||
some point in the future, we will freeze on a given stable Rust version,
|
||||
to ensure backward compatibility with stable distributions that ship it.
|
||||
|
||||
Updating/Adding Dependencies
|
||||
------------------------------
|
||||
|
||||
To add/remove/update dependencies, first add your dependencies,
|
||||
exactly specifying their versions, into the appropriate *crate-level*
|
||||
`Cargo.toml` in `src/rust/` (i.e. *not* `/src/rust/Cargo.toml`, but
|
||||
instead the one for your crate). Also, investigate whether your
|
||||
dependency has any optional dependencies which are unnecessary but are
|
||||
enabled by default. If so, you'll likely be able to enable/disable
|
||||
them via some feature, e.g.:
|
||||
|
||||
```toml
|
||||
[dependencies]
|
||||
foo = { version = "1.0.0", default-features = false }
|
||||
```
|
||||
|
||||
Next, run `/scripts/maint/updateRustDependencies.sh`. Then, go into
|
||||
`src/ext/rust` and commit the changes to the `tor-rust-dependencies`
|
||||
repo.
|
||||
|
||||
Documentation
|
||||
---------------
|
||||
|
||||
You MUST include `#[deny(missing_docs)]` in your crate.
|
||||
|
||||
For function/method comments, you SHOULD include a one-sentence, "first person"
|
||||
description of function behaviour (see requirements for documentation as
|
||||
described in `.../src/HACKING/CodingStandards.md`), then an `# Inputs` section
|
||||
for inputs or initialisation values, a `# Returns` section for return
|
||||
values/types, a `# Warning` section containing warnings for unsafe behaviours or
|
||||
panics that could happen. For publicly accessible
|
||||
types/constants/objects/functions/methods, you SHOULD also include an
|
||||
`# Examples` section with runnable doctests.
|
||||
|
||||
You MUST document your module with _module docstring_ comments,
|
||||
i.e. `//!` at the beginning of each line.
|
||||
|
||||
Style
|
||||
-------
|
||||
|
||||
You SHOULD consider breaking up large literal numbers with `_` when it makes it
|
||||
more human readable to do so, e.g. `let x: u64 = 100_000_000_000`.
|
||||
|
||||
Testing
|
||||
---------
|
||||
|
||||
All code MUST be unittested and integration tested.
|
||||
|
||||
Public functions/objects exported from a crate SHOULD include doctests
|
||||
describing how the function/object is expected to be used.
|
||||
|
||||
Integration tests SHOULD go into a `tests/` directory inside your
|
||||
crate. Unittests SHOULD go into their own module inside the module
|
||||
they are testing, e.g. in `.../src/rust/tor_addition/addition.rs` you
|
||||
should put:
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn addition_with_zero() {
|
||||
let sum: i32 = get_sum(5i32, 0i32);
|
||||
assert_eq!(sum, 5);
|
||||
}
|
||||
}
|
||||
|
||||
Benchmarking
|
||||
--------------
|
||||
|
||||
The external `test` crate can be used for most benchmarking. However, using
|
||||
this crate requires nightly Rust. Since we may want to switch to a more
|
||||
stable Rust compiler eventually, we shouldn't do things which will automatically
|
||||
break builds for stable compilers. Therefore, you MUST feature-gate your
|
||||
benchmarks in the following manner.
|
||||
|
||||
If you wish to benchmark some of your Rust code, you MUST put the
|
||||
following in the `[features]` section of your crate's `Cargo.toml`:
|
||||
|
||||
[features]
|
||||
bench = []
|
||||
|
||||
Next, in your crate's `lib.rs` you MUST put:
|
||||
|
||||
#[cfg(all(test, feature = "bench"))]
|
||||
extern crate test;
|
||||
|
||||
This ensures that the external crate `test`, which contains utilities
|
||||
for basic benchmarks, is only used when running benchmarks via `cargo
|
||||
bench --features bench`.
|
||||
|
||||
Finally, to write your benchmark code, in
|
||||
`.../src/rust/tor_addition/addition.rs` you SHOULD put:
|
||||
|
||||
#[cfg(all(test, features = "bench"))]
|
||||
mod bench {
|
||||
use test::Bencher;
|
||||
use super::*;
|
||||
|
||||
#[bench]
|
||||
fn addition_small_integers(b: &mut Bencher) {
|
||||
b.iter(| | get_sum(5i32, 0i32));
|
||||
}
|
||||
}
|
||||
|
||||
Fuzzing
|
||||
---------
|
||||
|
||||
If you wish to fuzz parts of your code, please see the
|
||||
[`cargo fuzz`](https://github.com/rust-fuzz/cargo-fuzz) crate, which uses
|
||||
[libfuzzer-sys](https://github.com/rust-fuzz/libfuzzer-sys).
|
||||
|
||||
Whitespace & Formatting
|
||||
-------------------------
|
||||
|
||||
You MUST run `rustfmt` (https://github.com/rust-lang-nursery/rustfmt)
|
||||
on your code before your code will be merged. You can install rustfmt
|
||||
by doing `cargo install rustfmt-nightly` and then run it with `cargo
|
||||
fmt`.
|
||||
|
||||
Safety
|
||||
--------
|
||||
|
||||
You SHOULD read [the nomicon](https://doc.rust-lang.org/nomicon/) before writing
|
||||
Rust FFI code. It is *highly advised* that you read and write normal Rust code
|
||||
before attempting to write FFI or any other unsafe code.
|
||||
|
||||
Here are some additional bits of advice and rules:
|
||||
|
||||
0. Any behaviours which Rust considers to be undefined are forbidden
|
||||
|
||||
From https://doc.rust-lang.org/reference/behavior-considered-undefined.html:
|
||||
|
||||
> Behavior considered undefined
|
||||
>
|
||||
> The following is a list of behavior which is forbidden in all Rust code,
|
||||
> including within unsafe blocks and unsafe functions. Type checking provides the
|
||||
> guarantee that these issues are never caused by safe code.
|
||||
>
|
||||
> * Data races
|
||||
> * Dereferencing a null/dangling raw pointer
|
||||
> * Reads of [undef](http://llvm.org/docs/LangRef.html#undefined-values)
|
||||
> (uninitialized) memory
|
||||
> * Breaking the
|
||||
> [pointer aliasing rules](http://llvm.org/docs/LangRef.html#pointer-aliasing-rules)
|
||||
> with raw pointers (a subset of the rules used by C)
|
||||
> * `&mut T` and `&T` follow LLVM’s scoped noalias model, except if the `&T`
|
||||
> contains an `UnsafeCell<U>`. Unsafe code must not violate these aliasing
|
||||
> guarantees.
|
||||
> * Mutating non-mutable data (that is, data reached through a shared
|
||||
> reference or data owned by a `let` binding), unless that data is
|
||||
> contained within an `UnsafeCell<U>`.
|
||||
> * Invoking undefined behavior via compiler intrinsics:
|
||||
> - Indexing outside of the bounds of an object with
|
||||
> `std::ptr::offset` (`offset` intrinsic), with the exception of
|
||||
> one byte past the end which is permitted.
|
||||
> - Using `std::ptr::copy_nonoverlapping_memory` (`memcpy32`/`memcpy64`
|
||||
> intrinsics) on overlapping buffers
|
||||
> * Invalid values in primitive types, even in private fields/locals:
|
||||
> - Dangling/null references or boxes
|
||||
> - A value other than `false` (0) or `true` (1) in a `bool`
|
||||
> - A discriminant in an `enum` not included in the type definition
|
||||
> - A value in a `char` which is a surrogate or above `char::MAX`
|
||||
> - Non-UTF-8 byte sequences in a `str`
|
||||
> * Unwinding into Rust from foreign code or unwinding from Rust into foreign
|
||||
> code. Rust's failure system is not compatible with exception handling in other
|
||||
> languages. Unwinding must be caught and handled at FFI boundaries.
|
||||
|
||||
1. `unwrap()`
|
||||
|
||||
If you call `unwrap()`, anywhere, even in a test, you MUST include
|
||||
an inline comment stating how the unwrap will either 1) never fail,
|
||||
or 2) should fail (i.e. in a unittest).
|
||||
|
||||
You SHOULD NOT use `unwrap()` anywhere in which it is possible to handle the
|
||||
potential error with either `expect()` or the eel operator, `?`.
|
||||
For example, consider a function which parses a string into an integer:
|
||||
|
||||
fn parse_port_number(config_string: &str) -> u16 {
|
||||
u16::from_str_radix(config_string, 10).unwrap()
|
||||
}
|
||||
|
||||
There are numerous ways this can fail, and the `unwrap()` will cause the
|
||||
whole program to byte the dust! Instead, either you SHOULD use `expect()`
|
||||
(or another equivalent function which will return an `Option` or a `Result`)
|
||||
and change the return type to be compatible:
|
||||
|
||||
fn parse_port_number(config_string: &str) -> Option<u16> {
|
||||
u16::from_str_radix(config_string, 10).expect("Couldn't parse port into a u16")
|
||||
}
|
||||
|
||||
or you SHOULD use `or()` (or another similar method):
|
||||
|
||||
fn parse_port_number(config_string: &str) -> Option<u16> {
|
||||
u16::from_str_radix(config_string, 10).or(Err("Couldn't parse port into a u16")
|
||||
}
|
||||
|
||||
Using methods like `or()` can be particularly handy when you must do
|
||||
something afterwards with the data, for example, if we wanted to guarantee
|
||||
that the port is high. Combining these methods with the eel operator (`?`)
|
||||
makes this even easier:
|
||||
|
||||
fn parse_port_number(config_string: &str) -> Result<u16, Err> {
|
||||
let port = u16::from_str_radix(config_string, 10).or(Err("Couldn't parse port into a u16"))?;
|
||||
|
||||
if port > 1024 {
|
||||
return Ok(port);
|
||||
} else {
|
||||
return Err("Low ports not allowed");
|
||||
}
|
||||
}
|
||||
|
||||
2. `unsafe`
|
||||
|
||||
If you use `unsafe`, you MUST describe a contract in your
|
||||
documentation which describes how and when the unsafe code may
|
||||
fail, and what expectations are made w.r.t. the interfaces to
|
||||
unsafe code. This is also REQUIRED for major pieces of FFI between
|
||||
C and Rust.
|
||||
|
||||
When creating an FFI in Rust for C code to call, it is NOT REQUIRED
|
||||
to declare the entire function `unsafe`. For example, rather than doing:
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn increment_and_combine_numbers(mut numbers: [u8; 4]) -> u32 {
|
||||
for number in &mut numbers {
|
||||
*number += 1;
|
||||
}
|
||||
std::mem::transmute::<[u8; 4], u32>(numbers)
|
||||
}
|
||||
|
||||
You SHOULD instead do:
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn increment_and_combine_numbers(mut numbers: [u8; 4]) -> u32 {
|
||||
for index in 0..numbers.len() {
|
||||
numbers[index] += 1;
|
||||
}
|
||||
unsafe {
|
||||
std::mem::transmute::<[u8; 4], u32>(numbers)
|
||||
}
|
||||
}
|
||||
|
||||
3. Pass only C-compatible primitive types and bytes over the boundary
|
||||
|
||||
Rust's C-compatible primitive types are integers and floats.
|
||||
These types are declared in the [libc crate](https://doc.rust-lang.org/libc/x86_64-unknown-linux-gnu/libc/index.html#types).
|
||||
Most Rust objects have different [representations](https://doc.rust-lang.org/libc/x86_64-unknown-linux-gnu/libc/index.html#types)
|
||||
in C and Rust, so they can't be passed using FFI.
|
||||
|
||||
Tor currently uses the following Rust primitive types from libc for FFI:
|
||||
* defined-size integers: `uint32_t`
|
||||
* native-sized integers: `c_int`
|
||||
* native-sized floats: `c_double`
|
||||
* native-sized raw pointers: `* c_void`, `* c_char`, `** c_char`
|
||||
|
||||
TODO: C smartlist to Stringlist conversion using FFI
|
||||
|
||||
The only non-primitive type which may cross the FFI boundary is
|
||||
bytes, e.g. `&[u8]`. This SHOULD be done on the Rust side by
|
||||
passing a pointer (`*mut libc::c_char`). The length can be passed
|
||||
explicitly (`libc::size_t`), or the string can be NUL-byte terminated
|
||||
C string.
|
||||
|
||||
One might be tempted to do this via doing
|
||||
`CString::new("blah").unwrap().into_raw()`. This has several problems:
|
||||
|
||||
a) If you do `CString::new("bl\x00ah")` then the unwrap() will fail
|
||||
due to the additional NULL terminator, causing a dangling
|
||||
pointer to be returned (as well as a potential use-after-free).
|
||||
|
||||
b) Returning the raw pointer will cause the CString to run its deallocator,
|
||||
which causes any C code which tries to access the contents to dereference a
|
||||
NULL pointer.
|
||||
|
||||
c) If we were to do `as_raw()` this would result in a potential double-free
|
||||
since the Rust deallocator would run and possibly Tor's deallocator.
|
||||
|
||||
d) Calling `into_raw()` without later using the same pointer in Rust to call
|
||||
`from_raw()` and then deallocate in Rust can result in a
|
||||
[memory leak](https://doc.rust-lang.org/std/ffi/struct.CString.html#method.into_raw).
|
||||
|
||||
[It was determined](https://github.com/rust-lang/rust/pull/41074) that this
|
||||
is safe to do if you use the same allocator in C and Rust and also specify
|
||||
the memory alignment for CString (except that there is no way to specify
|
||||
the alignment for CString). It is believed that the alignment is always 1,
|
||||
which would mean it's safe to dealloc the resulting `*mut c_char` in Tor's
|
||||
C code. However, the Rust developers are not willing to guarantee the
|
||||
stability of, or a contract for, this behaviour, citing concerns that this
|
||||
is potentially extremely and subtly unsafe.
|
||||
|
||||
4. Perform an allocation on the other side of the boundary
|
||||
|
||||
After crossing the boundary, the other side MUST perform an
|
||||
allocation to copy the data and is therefore responsible for
|
||||
freeing that memory later.
|
||||
|
||||
5. No touching other language's enums
|
||||
|
||||
Rust enums should never be touched from C (nor can they be safely
|
||||
`#[repr(C)]`) nor vice versa:
|
||||
|
||||
> "The chosen size is the default enum size for the target platform's C
|
||||
> ABI. Note that enum representation in C is implementation defined, so this is
|
||||
> really a "best guess". In particular, this may be incorrect when the C code
|
||||
> of interest is compiled with certain flags."
|
||||
|
||||
(from https://gankro.github.io/nomicon/other-reprs.html)
|
||||
|
||||
6. Type safety
|
||||
|
||||
Wherever possible and sensical, you SHOULD create new types in a
|
||||
manner which prevents type confusion or misuse. For example,
|
||||
rather than using an untyped mapping between strings and integers
|
||||
like so:
|
||||
|
||||
use std::collections::HashMap;
|
||||
|
||||
pub fn get_elements_with_over_9000_points(map: &HashMap<String, usize>) -> Vec<String> {
|
||||
...
|
||||
}
|
||||
|
||||
It would be safer to define a new type, such that some other usage
|
||||
of `HashMap<String, usize>` cannot be confused for this type:
|
||||
|
||||
pub struct DragonBallZPowers(pub HashMap<String, usize>);
|
||||
|
||||
impl DragonBallZPowers {
|
||||
pub fn over_nine_thousand<'a>(&'a self) -> Vec<&'a String> {
|
||||
let mut powerful_enough: Vec<&'a String> = Vec::with_capacity(5);
|
||||
|
||||
for (character, power) in &self.0 {
|
||||
if *power > 9000 {
|
||||
powerful_enough.push(character);
|
||||
}
|
||||
}
|
||||
powerful_enough
|
||||
}
|
||||
}
|
||||
|
||||
Note the following code, which uses Rust's type aliasing, is valid
|
||||
but it does NOT meet the desired type safety goals:
|
||||
|
||||
pub type Power = usize;
|
||||
|
||||
pub fn over_nine_thousand(power: &Power) -> bool {
|
||||
if *power > 9000 {
|
||||
return true;
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
// We can still do the following:
|
||||
let his_power: usize = 9001;
|
||||
over_nine_thousand(&his_power);
|
||||
|
||||
7. Unsafe mucking around with lifetimes
|
||||
|
||||
Because lifetimes are technically, in type theory terms, a kind, i.e. a
|
||||
family of types, individual lifetimes can be treated as types. For example,
|
||||
one can arbitrarily extend and shorten lifetime using `std::mem::transmute`:
|
||||
|
||||
struct R<'a>(&'a i32);
|
||||
|
||||
unsafe fn extend_lifetime<'b>(r: R<'b>) -> R<'static> {
|
||||
std::mem::transmute::<R<'b>, R<'static>>(r)
|
||||
}
|
||||
|
||||
unsafe fn shorten_invariant_lifetime<'b, 'c>(r: &'b mut R<'static>) -> &'b mut R<'c> {
|
||||
std::mem::transmute::<&'b mut R<'static>, &'b mut R<'c>>(r)
|
||||
}
|
||||
|
||||
Calling `extend_lifetime()` would cause an `R` passed into it to live forever
|
||||
for the life of the program (the `'static` lifetime). Similarly,
|
||||
`shorten_invariant_lifetime()` could be used to take something meant to live
|
||||
forever, and cause it to disappear! This is incredibly unsafe. If you're
|
||||
going to be mucking around with lifetimes like this, first, you better have
|
||||
an extremely good reason, and second, you may as be honest and explicit about
|
||||
it, and for ferris' sake just use a raw pointer.
|
||||
|
||||
In short, just because lifetimes can be treated like types doesn't mean you
|
||||
should do it.
|
||||
|
||||
8. Doing excessively unsafe things when there's a safer alternative
|
||||
|
||||
Similarly to #7, often there are excessively unsafe ways to do a task and a
|
||||
simpler, safer way. You MUST choose the safer option where possible.
|
||||
|
||||
For example, `std::mem::transmute` can be abused in ways where casting with
|
||||
`as` would be both simpler and safer:
|
||||
|
||||
// Don't do this
|
||||
let ptr = &0;
|
||||
let ptr_num_transmute = unsafe { std::mem::transmute::<&i32, usize>(ptr)};
|
||||
|
||||
// Use an `as` cast instead
|
||||
let ptr_num_cast = ptr as *const i32 as usize;
|
||||
|
||||
In fact, using `std::mem::transmute` for *any* reason is a code smell and as
|
||||
such SHOULD be avoided.
|
||||
|
||||
9. Casting integers with `as`
|
||||
|
||||
This is generally fine to do, but it has some behaviours which you should be
|
||||
aware of. Casting down chops off the high bits, e.g.:
|
||||
|
||||
let x: u32 = 4294967295;
|
||||
println!("{}", x as u16); // prints 65535
|
||||
|
||||
Some cases which you MUST NOT do include:
|
||||
|
||||
* Casting an `u128` down to an `f32` or vice versa (e.g.
|
||||
`u128::MAX as f32` but this isn't only a problem with overflowing
|
||||
as it is also undefined behaviour for `42.0f32 as u128`),
|
||||
|
||||
* Casting between integers and floats when the thing being cast
|
||||
cannot fit into the type it is being casted into, e.g.:
|
||||
|
||||
println!("{}", 42949.0f32 as u8); // prints 197 in debug mode and 0 in release
|
||||
println!("{}", 1.04E+17 as u8); // prints 0 in both modes
|
||||
println!("{}", (0.0/0.0) as i64); // prints whatever the heck LLVM wants
|
||||
|
||||
Because this behaviour is undefined, it can even produce segfaults in
|
||||
safe Rust code. For example, the following program built in release
|
||||
mode segfaults:
|
||||
|
||||
#[inline(never)]
|
||||
pub fn trigger_ub(sl: &[u8; 666]) -> &[u8] {
|
||||
// Note that the float is out of the range of `usize`, invoking UB when casting.
|
||||
let idx = 1e99999f64 as usize;
|
||||
&sl[idx..] // The bound check is elided due to `idx` being of an undefined value.
|
||||
}
|
||||
|
||||
fn main() {
|
||||
println!("{}", trigger_ub(&[1; 666])[999999]); // ~ out of bound
|
||||
}
|
||||
|
||||
And in debug mode panics with:
|
||||
|
||||
thread 'main' panicked at 'slice index starts at 140721821254240 but ends at 666', /checkout/src/libcore/slice/mod.rs:754:4
|
|
@ -1,123 +0,0 @@
|
|||
= Fuzzing Tor
|
||||
|
||||
== The simple version (no fuzzing, only tests)
|
||||
|
||||
Check out fuzzing-corpora, and set TOR_FUZZ_CORPORA to point to the place
|
||||
where you checked it out.
|
||||
|
||||
To run the fuzzing test cases in a deterministic fashion, use:
|
||||
make test-fuzz-corpora
|
||||
|
||||
This won't actually fuzz Tor! It will just run all the fuzz binaries
|
||||
on our existing set of testcases for the fuzzer.
|
||||
|
||||
|
||||
== Different kinds of fuzzing
|
||||
|
||||
Right now we support three different kinds of fuzzer.
|
||||
|
||||
First, there's American Fuzzy Lop (AFL), a fuzzer that works by forking
|
||||
a target binary and passing it lots of different inputs on stdin. It's the
|
||||
trickiest one to set up, so I'll be describing it more below.
|
||||
|
||||
Second, there's libFuzzer, a llvm-based fuzzer that you link in as a library,
|
||||
and it runs a target function over and over. To use this one, you'll need to
|
||||
have a reasonably recent clang and libfuzzer installed. At that point, you
|
||||
just build with --enable-expensive-hardening and --enable-libfuzzer. That
|
||||
will produce a set of binaries in src/test/fuzz/lf-fuzz-* . These programs
|
||||
take as input a series of directories full of fuzzing examples. For more
|
||||
information on libfuzzer, see http://llvm.org/docs/LibFuzzer.html
|
||||
|
||||
Third, there's Google's OSS-Fuzz infrastructure, which expects to get all of
|
||||
its. For more on this, see https://github.com/google/oss-fuzz and the
|
||||
projects/tor subdirectory. You'll need to mess around with Docker a bit to
|
||||
test this one out; it's meant to run on Google's infrastructure.
|
||||
|
||||
In all cases, you'll need some starting examples to give the fuzzer when it
|
||||
starts out. There's a set in the "fuzzing-corpora" git repository. Try
|
||||
setting TOR_FUZZ_CORPORA to point to a checkout of that repository
|
||||
|
||||
== Writing Tor fuzzers
|
||||
|
||||
A tor fuzzing harness should have:
|
||||
* a fuzz_init() function to set up any necessary global state.
|
||||
* a fuzz_main() function to receive input and pass it to a parser.
|
||||
* a fuzz_cleanup() function to clear global state.
|
||||
|
||||
Most fuzzing frameworks will produce many invalid inputs - a tor fuzzing
|
||||
harness should rejecting invalid inputs without crashing or behaving badly.
|
||||
|
||||
But the fuzzing harness should crash if tor fails an assertion, triggers a
|
||||
bug, or accesses memory it shouldn't. This helps fuzzing frameworks detect
|
||||
"interesting" cases.
|
||||
|
||||
|
||||
== Guided Fuzzing with AFL
|
||||
|
||||
There is no HTTPS, hash, or signature for American Fuzzy Lop's source code, so
|
||||
its integrity can't be verified. That said, you really shouldn't fuzz on a
|
||||
machine you care about, anyway.
|
||||
|
||||
To Build:
|
||||
Get AFL from http://lcamtuf.coredump.cx/afl/ and unpack it
|
||||
cd afl
|
||||
make
|
||||
cd ../tor
|
||||
PATH=$PATH:../afl/ CC="../afl/afl-gcc" ./configure --enable-expensive-hardening
|
||||
AFL_HARDEN=1 make clean fuzzers
|
||||
|
||||
To Find The ASAN Memory Limit: (64-bit only)
|
||||
|
||||
On 64-bit platforms, afl needs to know how much memory ASAN uses,
|
||||
because ASAN tends to allocate a ridiculous amount of virtual memory,
|
||||
and then not actually use it.
|
||||
|
||||
Read afl/docs/notes_for_asan.txt for more details.
|
||||
|
||||
Download recidivm from http://jwilk.net/software/recidivm
|
||||
Download the signature
|
||||
Check the signature
|
||||
tar xvzf recidivm*.tar.gz
|
||||
cd recidivm*
|
||||
make
|
||||
/path/to/recidivm -v src/test/fuzz/fuzz-http
|
||||
Use the final "ok" figure as the input to -m when calling afl-fuzz
|
||||
(Normally, recidivm would output a figure automatically, but in some cases,
|
||||
the fuzzing harness will hang when the memory limit is too small.)
|
||||
|
||||
You could also just say "none" instead of the memory limit below, if you
|
||||
don't care about memory limits.
|
||||
|
||||
|
||||
To Run:
|
||||
mkdir -p src/test/fuzz/fuzz_http_findings
|
||||
../afl/afl-fuzz -i ${TOR_FUZZ_CORPORA}/http -o src/test/fuzz/fuzz_http_findings -m <asan-memory-limit> -- src/test/fuzz/fuzz-http
|
||||
|
||||
|
||||
AFL has a multi-core mode, check the documentation for details.
|
||||
You might find the included fuzz-multi.sh script useful for this.
|
||||
|
||||
macOS (OS X) requires slightly more preparation, including:
|
||||
* using afl-clang (or afl-clang-fast from the llvm directory)
|
||||
* disabling external crash reporting (AFL will guide you through this step)
|
||||
|
||||
== Triaging Issues
|
||||
|
||||
Crashes are usually interesting, particularly if using AFL_HARDEN=1 and --enable-expensive-hardening. Sometimes crashes are due to bugs in the harness code.
|
||||
|
||||
Hangs might be interesting, but they might also be spurious machine slowdowns.
|
||||
Check if a hang is reproducible before reporting it. Sometimes, processing
|
||||
valid inputs may take a second or so, particularly with the fuzzer and
|
||||
sanitizers enabled.
|
||||
|
||||
To see what fuzz-http is doing with a test case, call it like this:
|
||||
src/test/fuzz/fuzz-http --debug < /path/to/test.case
|
||||
|
||||
(Logging is disabled while fuzzing to increase fuzzing speed.)
|
||||
|
||||
== Reporting Issues
|
||||
|
||||
Please report any issues discovered using the process in Tor's security issue
|
||||
policy:
|
||||
|
||||
https://trac.torproject.org/projects/tor/wiki/org/meetings/2016SummerDevMeeting/Notes/SecurityIssuePolicy
|
|
@ -1,188 +0,0 @@
|
|||
|
||||
Getting started in Tor development
|
||||
==================================
|
||||
|
||||
Congratulations! You've found this file, and you're reading it! This
|
||||
means that you might be interested in getting started in developing Tor.
|
||||
|
||||
(This guide is just about Tor itself--the small network program at the
|
||||
heart of the Tor network--and not about all the other programs in the
|
||||
whole Tor ecosystem.)
|
||||
|
||||
|
||||
If you are looking for a more bare-bones, less user-friendly information
|
||||
dump of important information, you might like reading the "torguts"
|
||||
documents linked to below. You should probably read it before you write
|
||||
your first patch.
|
||||
|
||||
|
||||
Required background
|
||||
-------------------
|
||||
|
||||
First, I'm going to assume that you can build Tor from source, and that
|
||||
you know enough of the C language to read and write it. (See the README
|
||||
file that comes with the Tor source for more information on building it,
|
||||
and any high-quality guide to C for information on programming.)
|
||||
|
||||
I'm also going to assume that you know a little bit about how to use
|
||||
Git, or that you're able to follow one of the several excellent guides
|
||||
at http://git-scm.org to learn.
|
||||
|
||||
Most Tor developers develop using some Unix-based system, such as Linux,
|
||||
BSD, or OSX. It's okay to develop on Windows if you want, but you're
|
||||
going to have a more difficult time.
|
||||
|
||||
|
||||
Getting your first patch into Tor
|
||||
---------------------------------
|
||||
|
||||
Once you've reached this point, here's what you need to know.
|
||||
|
||||
1. Get the source.
|
||||
|
||||
We keep our source under version control in Git. To get the latest
|
||||
version, run
|
||||
|
||||
git clone https://git.torproject.org/git/tor
|
||||
|
||||
This will give you a checkout of the master branch. If you're
|
||||
going to fix a bug that appears in a stable version, check out the
|
||||
appropriate "maint" branch, as in:
|
||||
|
||||
git checkout maint-0.2.7
|
||||
|
||||
2. Find your way around the source
|
||||
|
||||
Our overall code structure is explained in the "torguts" documents,
|
||||
currently at
|
||||
|
||||
git clone https://git.torproject.org/user/nickm/torguts.git
|
||||
|
||||
Find a part of the code that looks interesting to you, and start
|
||||
looking around it to see how it fits together!
|
||||
|
||||
We do some unusual things in our codebase. Our testing-related
|
||||
practices and kludges are explained in doc/WritingTests.txt.
|
||||
|
||||
If you see something that doesn't make sense, we love to get
|
||||
questions!
|
||||
|
||||
3. Find something cool to hack on.
|
||||
|
||||
You may already have a good idea of what you'd like to work on, or
|
||||
you might be looking for a way to contribute.
|
||||
|
||||
Many people have gotten started by looking for an area where they
|
||||
personally felt Tor was underperforming, and investigating ways to
|
||||
fix it. If you're looking for ideas, you can head to our bug
|
||||
tracker at trac.torproject.org and look for tickets that have
|
||||
received the "easy" tag: these are ones that developers think would
|
||||
be pretty simple for a new person to work on. For a bigger
|
||||
challenge, you might want to look for tickets with the "lorax"
|
||||
keyword: these are tickets that the developers think might be a
|
||||
good idea to build, but which we have no time to work on any time
|
||||
soon.
|
||||
|
||||
Or you might find another open ticket that piques your
|
||||
interest. It's all fine!
|
||||
|
||||
For your first patch, it is probably NOT a good idea to make
|
||||
something huge or invasive. In particular, you should probably
|
||||
avoid:
|
||||
|
||||
* Major changes spread across many parts of the codebase.
|
||||
* Major changes to programming practice or coding style.
|
||||
* Huge new features or protocol changes.
|
||||
|
||||
4. Meet the developers!
|
||||
|
||||
We discuss stuff on the tor-dev mailing list and on the #tor-dev
|
||||
IRC channel on OFTC. We're generally friendly and approachable,
|
||||
and we like to talk about how Tor fits together. If we have ideas
|
||||
about how something should be implemented, we'll be happy to share
|
||||
them.
|
||||
|
||||
We currently have a patch workshop at least once a week, where
|
||||
people share patches they've made and discuss how to make them
|
||||
better. The time might change in the future, but generally,
|
||||
there's no bad time to talk, and ask us about patch ideas.
|
||||
|
||||
5. Do you need to write a design proposal?
|
||||
|
||||
If your idea is very large, or it will require a change to Tor's
|
||||
protocols, there needs to be a written design proposal before it
|
||||
can be merged. (We use this process to manage changes in the
|
||||
protocols.) To write one, see the instructions at
|
||||
https://gitweb.torproject.org/torspec.git/tree/proposals/001-process.txt
|
||||
. If you'd like help writing a proposal, just ask! We're happy to
|
||||
help out with good ideas.
|
||||
|
||||
You might also like to look around the rest of that directory, to
|
||||
see more about open and past proposed changes to Tor's behavior.
|
||||
|
||||
6. Writing your patch
|
||||
|
||||
As you write your code, you'll probably want it to fit in with the
|
||||
standards of the rest of the Tor codebase so it will be easy for us
|
||||
to review and merge. You can learn our coding standards in
|
||||
doc/HACKING.
|
||||
|
||||
If your patch is large and/or is divided into multiple logical
|
||||
components, remember to divide it into a series of Git commits. A
|
||||
series of small changes is much easier to review than one big lump.
|
||||
|
||||
7. Testing your patch
|
||||
|
||||
We prefer that all new or modified code have unit tests for it to
|
||||
ensure that it runs correctly. Also, all code should actually be
|
||||
_run_ by somebody, to make sure it works.
|
||||
|
||||
See doc/WritingTests.txt for more information on how we test things
|
||||
in Tor. If you'd like any help writing tests, just ask! We're
|
||||
glad to help out.
|
||||
|
||||
8. Submitting your patch
|
||||
|
||||
We review patches through tickets on our bugtracker at
|
||||
trac.torproject.org. You can either upload your patches there, or
|
||||
put them at a public git repository somewhere we can fetch them
|
||||
(like github or bitbucket) and then paste a link on the appropriate
|
||||
trac ticket.
|
||||
|
||||
Once your patches are available, write a short explanation of what
|
||||
you've done on trac, and then change the status of the ticket to
|
||||
needs_review.
|
||||
|
||||
9. Review, Revision, and Merge
|
||||
|
||||
With any luck, somebody will review your patch soon! If not, you
|
||||
can ask on the IRC channel; sometimes we get really busy and take
|
||||
longer than we should. But don't let us slow you down: you're the
|
||||
one who's offering help here, and we should respect your time and
|
||||
contributions.
|
||||
|
||||
When your patch is reviewed, one of these things will happen:
|
||||
|
||||
* The reviewer will say "looks good to me" and your
|
||||
patch will get merged right into Tor. [Assuming we're not
|
||||
in the middle of a code-freeze window. If the codebase is
|
||||
frozen, your patch will go into the next release series.]
|
||||
|
||||
* OR the reviewer will say "looks good, just needs some small
|
||||
changes!" And then the reviewer will make those changes,
|
||||
and merge the modified patch into Tor.
|
||||
|
||||
* OR the reviewer will say "Here are some questions and
|
||||
comments," followed by a bunch of stuff that the reviewer
|
||||
thinks should change in your code, or questions that the
|
||||
reviewer has.
|
||||
|
||||
At this point, you might want to make the requested changes
|
||||
yourself, and comment on the trac ticket once you have done
|
||||
so. Or if you disagree with any of the comments, you should
|
||||
say so! And if you won't have time to make some of the
|
||||
changes, you should say that too, so that other developers
|
||||
will be able to pick up the unfinished portion.
|
||||
|
||||
Congratulations! You have now written your first patch, and gotten
|
||||
it integrated into mainline Tor.
|
|
@ -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`.
|
|
@ -1,365 +0,0 @@
|
|||
Useful tools
|
||||
============
|
||||
|
||||
These aren't strictly necessary for hacking on Tor, but they can help track
|
||||
down bugs.
|
||||
|
||||
Travis CI
|
||||
---------
|
||||
It's CI. Looks like this: https://travis-ci.org/torproject/tor.
|
||||
|
||||
Runs automatically on Pull Requests sent to torproject/tor. You can set it up
|
||||
for your fork to build commits outside of PRs too:
|
||||
|
||||
1. sign up for GitHub: https://github.com/join
|
||||
2. fork https://github.com/torproject/tor:
|
||||
https://help.github.com/articles/fork-a-repo/
|
||||
3. follow https://docs.travis-ci.com/user/getting-started/#To-get-started-with-Travis-CI.
|
||||
skip steps involving `.travis.yml` (we already have one).
|
||||
|
||||
Builds should show up on the web at travis-ci.com and on IRC at #tor-ci on
|
||||
OFTC. If they don't, ask #tor-dev (also on OFTC).
|
||||
|
||||
Jenkins
|
||||
-------
|
||||
|
||||
https://jenkins.torproject.org
|
||||
|
||||
Dmalloc
|
||||
-------
|
||||
|
||||
The dmalloc library will keep track of memory allocation, so you can find out
|
||||
if we're leaking memory, doing any double-frees, or so on.
|
||||
|
||||
dmalloc -l -/dmalloc.log
|
||||
(run the commands it tells you)
|
||||
./configure --with-dmalloc
|
||||
|
||||
Valgrind
|
||||
--------
|
||||
|
||||
valgrind --leak-check=yes --error-limit=no --show-reachable=yes src/or/tor
|
||||
|
||||
(Note that if you get a zillion openssl warnings, you will also need to
|
||||
pass `--undef-value-errors=no` to valgrind, or rebuild your openssl
|
||||
with `-DPURIFY`.)
|
||||
|
||||
Coverity
|
||||
--------
|
||||
|
||||
Nick regularly runs the coverity static analyzer on the Tor codebase.
|
||||
|
||||
The preprocessor define `__COVERITY__` is used to work around instances
|
||||
where coverity picks up behavior that we wish to permit.
|
||||
|
||||
clang Static Analyzer
|
||||
---------------------
|
||||
|
||||
The clang static analyzer can be run on the Tor codebase using Xcode (WIP)
|
||||
or a command-line build.
|
||||
|
||||
The preprocessor define `__clang_analyzer__` is used to work around instances
|
||||
where clang picks up behavior that we wish to permit.
|
||||
|
||||
clang Runtime Sanitizers
|
||||
------------------------
|
||||
|
||||
To build the Tor codebase with the clang Address and Undefined Behavior
|
||||
sanitizers, see the file `contrib/clang/sanitize_blacklist.txt`.
|
||||
|
||||
Preprocessor workarounds for instances where clang picks up behavior that
|
||||
we wish to permit are also documented in the blacklist file.
|
||||
|
||||
Running lcov for unit test coverage
|
||||
-----------------------------------
|
||||
|
||||
Lcov is a utility that generates pretty HTML reports of test code coverage.
|
||||
To generate such a report:
|
||||
|
||||
./configure --enable-coverage
|
||||
make
|
||||
make coverage-html
|
||||
$BROWSER ./coverage_html/index.html
|
||||
|
||||
This will run the tor unit test suite `./src/test/test` and generate the HTML
|
||||
coverage code report under the directory `./coverage_html/`. To change the
|
||||
output directory, use `make coverage-html HTML_COVER_DIR=./funky_new_cov_dir`.
|
||||
|
||||
Coverage diffs using lcov are not currently implemented, but are being
|
||||
investigated (as of July 2014).
|
||||
|
||||
Running the unit tests
|
||||
----------------------
|
||||
|
||||
To quickly run all the tests distributed with Tor:
|
||||
|
||||
make check
|
||||
|
||||
To run the fast unit tests only:
|
||||
|
||||
make test
|
||||
|
||||
To selectively run just some tests (the following can be combined
|
||||
arbitrarily):
|
||||
|
||||
./src/test/test <name_of_test> [<name of test 2>] ...
|
||||
./src/test/test <prefix_of_name_of_test>.. [<prefix_of_name_of_test2>..] ...
|
||||
./src/test/test :<name_of_excluded_test> [:<name_of_excluded_test2]...
|
||||
|
||||
To run all tests, including those based on Stem or Chutney:
|
||||
|
||||
make test-full
|
||||
|
||||
To run all tests, including those based on Stem or Chutney that require a
|
||||
working connection to the internet:
|
||||
|
||||
make test-full-online
|
||||
|
||||
Running gcov for unit test coverage
|
||||
-----------------------------------
|
||||
|
||||
./configure --enable-coverage
|
||||
make
|
||||
make check
|
||||
# or--- make test-full ? make test-full-online?
|
||||
mkdir coverage-output
|
||||
./scripts/test/coverage coverage-output
|
||||
|
||||
(On OSX, you'll need to start with `--enable-coverage CC=clang`.)
|
||||
|
||||
If that doesn't work:
|
||||
|
||||
* Try configuring Tor with `--disable-gcc-hardening`
|
||||
* You might need to run `make clean` after you run `./configure`.
|
||||
|
||||
Then, look at the .gcov files in `coverage-output`. '-' before a line means
|
||||
that the compiler generated no code for that line. '######' means that the
|
||||
line was never reached. Lines with numbers were called that number of times.
|
||||
|
||||
For more details about how to read gcov output, see the [Invoking
|
||||
gcov](https://gcc.gnu.org/onlinedocs/gcc/Invoking-Gcov.html) chapter
|
||||
of the GCC manual.
|
||||
|
||||
If 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.
|
||||
|
||||
If you have two different `coverage-output` directories, and you want to see
|
||||
a meaningful diff between them, you can run:
|
||||
|
||||
./scripts/test/cov-diff coverage-output1 coverage-output2 | less
|
||||
|
||||
In this diff, any lines that were visited at least once will have coverage "1",
|
||||
and line numbers are deleted. This lets you inspect what you (probably) really
|
||||
want to know: which untested lines were changed? Are there any new untested
|
||||
lines?
|
||||
|
||||
If you run ./scripts/test/cov-exclude, it marks excluded unreached
|
||||
lines with 'x', and excluded reached lines with '!!!'.
|
||||
|
||||
Running integration tests
|
||||
-------------------------
|
||||
|
||||
We have the beginnings of a set of scripts to run integration tests using
|
||||
Chutney. To try them, set CHUTNEY_PATH to your chutney source directory, and
|
||||
run `make test-network`.
|
||||
|
||||
We also have scripts to run integration tests using Stem. To try them, set
|
||||
`STEM_SOURCE_DIR` to your Stem source directory, and run `test-stem`.
|
||||
|
||||
Profiling Tor
|
||||
-------------
|
||||
|
||||
Ongoing notes about Tor profiling can be found at
|
||||
https://pad.riseup.net/p/profiling-tor
|
||||
|
||||
Profiling Tor with oprofile
|
||||
---------------------------
|
||||
|
||||
The oprofile tool runs (on Linux only!) to tell you what functions Tor is
|
||||
spending its CPU time in, so we can identify performance bottlenecks.
|
||||
|
||||
Here are some basic instructions
|
||||
|
||||
- Build tor with debugging symbols (you probably already have, unless
|
||||
you messed with CFLAGS during the build process).
|
||||
- Build all the libraries you care about with debugging symbols
|
||||
(probably you only care about libssl, maybe zlib and Libevent).
|
||||
- Copy this tor to a new directory
|
||||
- Copy all the libraries it uses to that dir too (`ldd ./tor` will
|
||||
tell you)
|
||||
- Set LD_LIBRARY_PATH to include that dir. `ldd ./tor` should now
|
||||
show you it's using the libs in that dir
|
||||
- Run that tor
|
||||
- Reset oprofiles counters/start it
|
||||
* `opcontrol --reset; opcontrol --start`, if Nick remembers right.
|
||||
- After a while, have it dump the stats on tor and all the libs
|
||||
in that dir you created.
|
||||
* `opcontrol --dump;`
|
||||
* `opreport -l that_dir/*`
|
||||
- Profit
|
||||
|
||||
Profiling Tor with perf
|
||||
-----------------------
|
||||
|
||||
This works with a running Tor, and requires root.
|
||||
|
||||
1. Decide how long you want to profile for. Start with (say) 30 seconds. If that
|
||||
works, try again with longer times.
|
||||
|
||||
2. Find the PID of your running tor process.
|
||||
|
||||
3. Run `perf record --call-graph dwarf -p <PID> sleep <SECONDS>`
|
||||
|
||||
(You may need to do this as root.)
|
||||
|
||||
You might need to add `-e cpu-clock` as an option to the perf record line
|
||||
above, if you are on an older CPU without access to hardware profiling
|
||||
events, or in a VM, or something.
|
||||
|
||||
4. Now you have a perf.data file. Have a look at it with `perf report
|
||||
--no-children --sort symbol,dso` or `perf report --no-children --sort
|
||||
symbol,dso --stdio --header`. How does it look?
|
||||
|
||||
5a. Once you have a nice big perf.data file, you can compress it, encrypt it,
|
||||
and send it to your favorite Tor developers.
|
||||
|
||||
5b. Or maybe you'd rather not send a nice big perf.data file. Who knows what's
|
||||
in that!? It's kinda scary. To generate a less scary file, you can use `perf
|
||||
report -g > <FILENAME>.out`. Then you can compress that and put it somewhere
|
||||
public.
|
||||
|
||||
Profiling Tor with gperftools aka Google-performance-tools
|
||||
----------------------------------------------------------
|
||||
|
||||
This should work on nearly any unixy system. It doesn't seem to be compatible
|
||||
with RunAsDaemon though.
|
||||
|
||||
Beforehand, install google-perftools.
|
||||
|
||||
1. You need to rebuild Tor, hack the linking steps to add `-lprofiler` to the
|
||||
libs. You can do this by adding `LIBS=-lprofiler` when you call `./configure`.
|
||||
|
||||
Now you can run Tor with profiling enabled, and use the pprof utility to look at
|
||||
performance! See the gperftools manual for more info, but basically:
|
||||
|
||||
2. Run `env CPUPROFILE=/tmp/profile src/or/tor -f <path/torrc>`. The profile file
|
||||
is not written to until Tor finishes execuction.
|
||||
|
||||
3. Run `pprof src/or/tor /tm/profile` to start the REPL.
|
||||
|
||||
Generating and analyzing a callgraph
|
||||
------------------------------------
|
||||
|
||||
0. Build Tor on linux or mac, ideally with -O0 or -fno-inline.
|
||||
|
||||
1. Clone 'https://gitweb.torproject.org/user/nickm/calltool.git/' .
|
||||
Follow the README in that repository.
|
||||
|
||||
Note that currently the callgraph generator can't detect calls that pass
|
||||
through function pointers.
|
||||
|
||||
Getting emacs to edit Tor source properly
|
||||
-----------------------------------------
|
||||
|
||||
Nick likes to put the following snippet in his .emacs file:
|
||||
|
||||
|
||||
(add-hook 'c-mode-hook
|
||||
(lambda ()
|
||||
(font-lock-mode 1)
|
||||
(set-variable 'show-trailing-whitespace t)
|
||||
|
||||
(let ((fname (expand-file-name (buffer-file-name))))
|
||||
(cond
|
||||
((string-match "^/home/nickm/src/libevent" fname)
|
||||
(set-variable 'indent-tabs-mode t)
|
||||
(set-variable 'c-basic-offset 4)
|
||||
(set-variable 'tab-width 4))
|
||||
((string-match "^/home/nickm/src/tor" fname)
|
||||
(set-variable 'indent-tabs-mode nil)
|
||||
(set-variable 'c-basic-offset 2))
|
||||
((string-match "^/home/nickm/src/openssl" fname)
|
||||
(set-variable 'indent-tabs-mode t)
|
||||
(set-variable 'c-basic-offset 8)
|
||||
(set-variable 'tab-width 8))
|
||||
))))
|
||||
|
||||
|
||||
You'll note that it defaults to showing all trailing whitespace. The `cond`
|
||||
test detects whether the file is one of a few C free software projects that I
|
||||
often edit, and sets up the indentation level and tab preferences to match
|
||||
what they want.
|
||||
|
||||
If you want to try this out, you'll need to change the filename regex
|
||||
patterns to match where you keep your Tor files.
|
||||
|
||||
If you use emacs for editing Tor and nothing else, you could always just say:
|
||||
|
||||
|
||||
(add-hook 'c-mode-hook
|
||||
(lambda ()
|
||||
(font-lock-mode 1)
|
||||
(set-variable 'show-trailing-whitespace t)
|
||||
(set-variable 'indent-tabs-mode nil)
|
||||
(set-variable 'c-basic-offset 2)))
|
||||
|
||||
|
||||
There is probably a better way to do this. No, we are probably not going
|
||||
to clutter the files with emacs stuff.
|
||||
|
||||
|
||||
Doxygen
|
||||
-------
|
||||
|
||||
We use the 'doxygen' utility to generate documentation from our
|
||||
source code. Here's how to use it:
|
||||
|
||||
1. Begin every file that should be documented with
|
||||
|
||||
/**
|
||||
* \file filename.c
|
||||
* \brief Short description of the file.
|
||||
*/
|
||||
|
||||
(Doxygen will recognize any comment beginning with /** as special.)
|
||||
|
||||
2. Before any function, structure, #define, or variable you want to
|
||||
document, add a comment of the form:
|
||||
|
||||
/** Describe the function's actions in imperative sentences.
|
||||
*
|
||||
* Use blank lines for paragraph breaks
|
||||
* - and
|
||||
* - hyphens
|
||||
* - for
|
||||
* - lists.
|
||||
*
|
||||
* Write <b>argument_names</b> in boldface.
|
||||
*
|
||||
* \code
|
||||
* place_example_code();
|
||||
* between_code_and_endcode_commands();
|
||||
* \endcode
|
||||
*/
|
||||
|
||||
3. Make sure to escape the characters `<`, `>`, `\`, `%` and `#` as `\<`,
|
||||
`\>`, `\\`, `\%` and `\#`.
|
||||
|
||||
4. To document structure members, you can use two forms:
|
||||
|
||||
struct foo {
|
||||
/** You can put the comment before an element; */
|
||||
int a;
|
||||
int b; /**< Or use the less-than symbol to put the comment
|
||||
* after the element. */
|
||||
};
|
||||
|
||||
5. To generate documentation from the Tor source code, type:
|
||||
|
||||
$ doxygen -g
|
||||
|
||||
to generate a file called `Doxyfile`. Edit that file and run
|
||||
`doxygen` to generate the API documentation.
|
||||
|
||||
6. See the Doxygen manual for more information; this summary just
|
||||
scratches the surface.
|
|
@ -1,88 +0,0 @@
|
|||
How to review a patch
|
||||
=====================
|
||||
|
||||
Some folks have said that they'd like to review patches more often, but they
|
||||
don't know how.
|
||||
|
||||
So, here are a bunch of things to check for when reviewing a patch!
|
||||
|
||||
Note that if you can't do every one of these, that doesn't mean you can't do
|
||||
a good review! Just make it clear what you checked for and what you didn't.
|
||||
|
||||
|
||||
Top-level smell-checks
|
||||
----------------------
|
||||
|
||||
(Difficulty: easy)
|
||||
|
||||
- Does it compile with `--enable-fatal-warnings`?
|
||||
|
||||
- Does `make check-spaces` pass?
|
||||
|
||||
- Does `make check-changes` pass?
|
||||
|
||||
- Does it have a reasonable amount of tests? Do they pass? Do they leak
|
||||
memory?
|
||||
|
||||
- Do all the new functions, global variables, types, and structure members have
|
||||
documentation?
|
||||
|
||||
- Do all the functions, global variables, types, and structure members with
|
||||
modified behavior have modified documentation?
|
||||
|
||||
- Do all the new torrc options have documentation?
|
||||
|
||||
- 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!
|
||||
-----------------------
|
||||
|
||||
- Does the code conform to CodingStandards.txt?
|
||||
|
||||
- Does the code leak memory?
|
||||
|
||||
- If two or more pointers ever point to the same object, is it clear which
|
||||
pointer "owns" the object?
|
||||
|
||||
- Are all allocated resources freed?
|
||||
|
||||
- Are all pointers that should be const, const?
|
||||
|
||||
- Are `#defines` used for 'magic' numbers?
|
||||
|
||||
- Can you understand what the code is trying to do?
|
||||
|
||||
- Can you convince yourself that the code really does that?
|
||||
|
||||
- Is there duplicated code that could be turned into a function?
|
||||
|
||||
|
||||
Let's look at the documentation!
|
||||
--------------------------------
|
||||
|
||||
- Does the documentation confirm to CodingStandards.txt?
|
||||
|
||||
- Does it make sense?
|
||||
|
||||
- Can you predict what the function will do from its documentation?
|
||||
|
||||
|
||||
Let's think about security!
|
||||
---------------------------
|
||||
|
||||
- If there are any arrays, buffers, are you 100% sure that they cannot
|
||||
overflow?
|
||||
|
||||
- If there is any integer math, can it overflow or underflow?
|
||||
|
||||
- If there are any allocations, are you sure there are corresponding
|
||||
deallocations?
|
||||
|
||||
- Is there a safer pattern that could be used in any case?
|
||||
|
||||
- Have they used one of the Forbidden Functions?
|
||||
|
||||
(Also see your favorite secure C programming guides.)
|
|
@ -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.
|
|
@ -1,62 +0,0 @@
|
|||
|
||||
In this directory
|
||||
-----------------
|
||||
|
||||
This directory has helpful information about what you need to know to
|
||||
hack on Tor!
|
||||
|
||||
First, read `GettingStarted.md` to learn how to get a start in Tor
|
||||
development.
|
||||
|
||||
If you've decided to write a patch, `CodingStandards.txt` will give
|
||||
you a bunch of information about how we structure our code.
|
||||
|
||||
It's important to get code right! Reading `WritingTests.md` will
|
||||
tell you how to write and run tests in the Tor codebase.
|
||||
|
||||
There are a bunch of other programs we use to help maintain and
|
||||
develop the codebase: `HelpfulTools.md` can tell you how to use them
|
||||
with Tor.
|
||||
|
||||
If it's your job to put out Tor releases, see `ReleasingTor.md` so
|
||||
that you don't miss any steps!
|
||||
|
||||
|
||||
-----------------------
|
||||
|
||||
For full information on how Tor is supposed to work, look at the files in
|
||||
`https://gitweb.torproject.org/torspec.git/tree`.
|
||||
|
||||
For an explanation of how to change Tor's design to work differently, look at
|
||||
`https://gitweb.torproject.org/torspec.git/blob_plain/HEAD:/proposals/001-process.txt`.
|
||||
|
||||
For the latest version of the code, get a copy of git, and
|
||||
|
||||
git clone https://git.torproject.org/git/tor
|
||||
|
||||
We talk about Tor on the `tor-talk` mailing list. Design proposals and
|
||||
discussion belong on the `tor-dev` mailing list. We hang around on
|
||||
irc.oftc.net, with general discussion happening on #tor and development
|
||||
happening on `#tor-dev`.
|
||||
|
||||
The other files in this `HACKING` directory may also be useful as you
|
||||
get started working with Tor.
|
||||
|
||||
Happy hacking!
|
||||
|
||||
|
||||
-----------------------
|
||||
|
||||
XXXXX also describe
|
||||
|
||||
doc/HACKING/WritingTests.md
|
||||
|
||||
torguts.git
|
||||
|
||||
torspec.git
|
||||
|
||||
The design paper
|
||||
|
||||
freehaven.net/anonbib
|
||||
|
||||
XXXX describe these and add links.
|
|
@ -1,222 +0,0 @@
|
|||
|
||||
Putting out a new release
|
||||
-------------------------
|
||||
|
||||
Here are the steps that the maintainer should take when putting out a
|
||||
new Tor release:
|
||||
|
||||
=== 0. Preliminaries
|
||||
|
||||
1. Get at least three of weasel/arma/Sebastian/Sina to put the new
|
||||
version number in their approved versions list. Give them a few
|
||||
days to do this if you can.
|
||||
|
||||
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
|
||||
|
||||
1. Use it for a while, as a client, as a relay, as a hidden service,
|
||||
and as a directory authority. See if it has any obvious bugs, and
|
||||
resolve those.
|
||||
|
||||
As applicable, merge the `maint-X` branch into the `release-X` branch.
|
||||
But you've been doing that all along, right?
|
||||
|
||||
2. Are all of the jenkins builders happy? See jenkins.torproject.org.
|
||||
|
||||
What about the bsd buildbots?
|
||||
See http://buildbot.pixelminers.net/builders/
|
||||
|
||||
What about Coverity Scan?
|
||||
|
||||
What about clang scan-build?
|
||||
|
||||
Does 'make distcheck' complain?
|
||||
|
||||
How about 'make test-stem' and 'make test-network' and
|
||||
`make test-network-full`?
|
||||
|
||||
- Are all those tests still happy with --enable-expensive-hardening ?
|
||||
|
||||
Any memory leaks?
|
||||
|
||||
|
||||
=== II. Write a changelog
|
||||
|
||||
|
||||
1a. (Alpha release variant)
|
||||
|
||||
Gather the `changes/*` files into a changelog entry, rewriting many
|
||||
of them and reordering to focus on what users and funders would find
|
||||
interesting and understandable.
|
||||
|
||||
To do this, first run `./scripts/maint/lintChanges.py changes/*` and
|
||||
fix as many warnings as you can. Then run `./scripts/maint/sortChanges.py
|
||||
changes/* > changelog.in` to combine headings and sort the entries.
|
||||
After that, it's time to hand-edit and fix the issues that lintChanges
|
||||
can't find:
|
||||
|
||||
1. Within each section, sort by "version it's a bugfix on", else by
|
||||
numerical ticket order.
|
||||
|
||||
2. Clean them up:
|
||||
|
||||
Make stuff very terse
|
||||
|
||||
Make sure each section name ends with a colon
|
||||
|
||||
Describe the user-visible problem right away
|
||||
|
||||
Mention relevant config options by name. If they're rare or unusual,
|
||||
remind people what they're for
|
||||
|
||||
Avoid starting lines with open-paren
|
||||
|
||||
Present and imperative tense: not past.
|
||||
|
||||
'Relays', not 'servers' or 'nodes' or 'Tor relays'.
|
||||
|
||||
"Stop FOOing", not "Fix a bug where we would FOO".
|
||||
|
||||
Try not to let any given section be longer than about a page. Break up
|
||||
long sections into subsections by some sort of common subtopic. This
|
||||
guideline is especially important when organizing Release Notes for
|
||||
new stable releases.
|
||||
|
||||
If a given changes stanza showed up in a different release (e.g.
|
||||
maint-0.2.1), be sure to make the stanzas identical (so people can
|
||||
distinguish if these are the same change).
|
||||
|
||||
3. Clean everything one last time.
|
||||
|
||||
4. Run `./scripts/maint/format_changelog.py --inplace` to make it prettier
|
||||
|
||||
1b. (old-stable release variant)
|
||||
|
||||
For stable releases that backport things from later, we try to compose
|
||||
their releases, we try to make sure that we keep the changelog entries
|
||||
identical to their original versions, with a 'backport from 0.x.y.z'
|
||||
note added to each section. So in this case, once you have the items
|
||||
from the changes files copied together, don't use them to build a new
|
||||
changelog: instead, look up the corrected versions that were merged
|
||||
into ChangeLog in the master branch, and use those.
|
||||
|
||||
2. Compose a short release blurb to highlight the user-facing
|
||||
changes. Insert said release blurb into the ChangeLog stanza. If it's
|
||||
a stable release, add it to the ReleaseNotes file too. If we're adding
|
||||
to a release-* branch, manually commit the changelogs to the later
|
||||
git branches too.
|
||||
|
||||
3. If there are changes that require or suggest operator intervention
|
||||
before or during the update, mail operators (either dirauth or relays
|
||||
list) with a headline that indicates that an action is required or
|
||||
appreciated.
|
||||
|
||||
4. If you're doing the first stable release in a series, you need to
|
||||
create a ReleaseNotes for the series as a whole. To get started
|
||||
there, copy all of the Changelog entries from the series into a new
|
||||
file, and run `./scripts/maint/sortChanges.py` on it. That will
|
||||
group them by category. Then kill every bugfix entry for fixing
|
||||
bugs that were introduced within that release series; those aren't
|
||||
relevant changes since the last series. At that point, it's time
|
||||
to start sorting and condensing entries. (Generally, we don't edit the
|
||||
text of existing entries, though.)
|
||||
|
||||
|
||||
=== III. Making the source release.
|
||||
|
||||
1. In `maint-0.?.x`, bump the version number in `configure.ac` and run
|
||||
`perl scripts/maint/updateVersions.pl` to update version numbers in other
|
||||
places, and commit. Then merge `maint-0.?.x` into `release-0.?.x`.
|
||||
|
||||
(NOTE: To bump the version number, edit `configure.ac`, and then run
|
||||
either `make`, or `perl scripts/maint/updateVersions.pl`, depending on
|
||||
your version.)
|
||||
|
||||
When you merge the maint branch forward to the next maint branch, or into
|
||||
master, merge it with "-s ours" to avoid a needless version bump.
|
||||
|
||||
2. Make distcheck, put the tarball up in somewhere (how about your
|
||||
homedir on your homedir on people.torproject.org?) , and tell `#tor`
|
||||
about it. Wait a while to see if anybody has problems building it.
|
||||
(Though jenkins is usually pretty good about catching these things.)
|
||||
|
||||
=== IV. Commit, upload, announce
|
||||
|
||||
1. Sign the tarball, then sign and push the git tag:
|
||||
|
||||
gpg -ba <the_tarball>
|
||||
git tag -u <keyid> tor-0.3.x.y-status
|
||||
git push origin tag tor-0.3.x.y-status
|
||||
|
||||
(You must do this before you update the website: it relies on finding
|
||||
the version by tag.)
|
||||
|
||||
2. scp the tarball and its sig to the dist website, i.e.
|
||||
`/srv/dist-master.torproject.org/htdocs/` on dist-master. When you want
|
||||
it to go live, you run "static-update-component dist.torproject.org"
|
||||
on dist-master.
|
||||
|
||||
In the webwml.git repository, `include/versions.wmi` and `Makefile`
|
||||
to note the new version.
|
||||
|
||||
(NOTE: Due to #17805, there can only be one stable version listed at
|
||||
once. Nonetheless, do not call your version "alpha" if it is stable,
|
||||
or people will get confused.)
|
||||
|
||||
3. Email the packagers (cc'ing tor-team) that a new tarball is up.
|
||||
The current list of packagers is:
|
||||
|
||||
- {weasel,gk,mikeperry} at torproject dot org
|
||||
- {blueness} at gentoo dot org
|
||||
- {paul} at invizbox dot io
|
||||
- {vincent} at invizbox dot com
|
||||
- {lfleischer} at archlinux dot org
|
||||
- {Nathan} at freitas dot net
|
||||
- {mike} at tig dot as
|
||||
- {tails-rm} at boum dot org
|
||||
- {simon} at sdeziel.info
|
||||
- {yuri} at freebsd.org
|
||||
- {mh+tor} at scrit.ch
|
||||
|
||||
Also, email tor-packagers@lists.torproject.org.
|
||||
|
||||
4. Add the version number to Trac. To do this, go to Trac, log in,
|
||||
select "Admin" near the top of the screen, then select "Versions" from
|
||||
the menu on the left. At the right, there will be an "Add version"
|
||||
box. By convention, we enter the version in the form "Tor:
|
||||
0.2.2.23-alpha" (or whatever the version is), and we select the date as
|
||||
the date in the ChangeLog.
|
||||
|
||||
5. Double-check: did the version get recommended in the consensus yet? Is
|
||||
the website updated? If not, don't announce until they have the
|
||||
up-to-date versions, or people will get confused.
|
||||
|
||||
6. Mail the release blurb and ChangeLog to tor-talk (development release) or
|
||||
tor-announce (stable).
|
||||
|
||||
Post the changelog on the blog as well. You can generate a
|
||||
blog-formatted version of the changelog with the -B option to
|
||||
format-changelog.
|
||||
|
||||
When you post, include an estimate of when the next TorBrowser
|
||||
releases will come out that include this Tor release. This will
|
||||
usually track https://wiki.mozilla.org/RapidRelease/Calendar , but it
|
||||
can vary.
|
||||
|
||||
|
||||
=== V. Aftermath and cleanup
|
||||
|
||||
1. If it's a stable release, bump the version number in the
|
||||
`maint-x.y.z` branch to "newversion-dev", and do a `merge -s ours`
|
||||
merge to avoid taking that change into master.
|
||||
|
||||
2. Forward-port the ChangeLog (and ReleaseNotes if appropriate).
|
||||
|
||||
3. Keep an eye on the blog post, to moderate comments and answer questions.
|
||||
|
|
@ -1,91 +0,0 @@
|
|||
# Tracing #
|
||||
|
||||
This document describes how the event tracing subsystem works in tor so
|
||||
developers can add events to the code base but also hook them to an event
|
||||
tracing framework.
|
||||
|
||||
## Basics ###
|
||||
|
||||
Event tracing is separated in two concepts, trace events and a tracer. The
|
||||
tracing subsystem can be found in `src/trace`. The `events.h` header file is
|
||||
the main file that maps the different tracers to trace events.
|
||||
|
||||
### Events ###
|
||||
|
||||
A trace event is basically a function from which we can pass any data that
|
||||
we want to collect. In addition, we specify a context for the event such as
|
||||
a subsystem and an event name.
|
||||
|
||||
A trace event in tor has the following standard format:
|
||||
|
||||
tor_trace(subsystem, event\_name, args...)
|
||||
|
||||
The `subsystem` parameter is the name of the subsytem the trace event is in.
|
||||
For example that could be "scheduler" or "vote" or "hs". The idea is to add
|
||||
some context to the event so when we collect them we know where it's coming
|
||||
from. The `event_name` is the name of the event which helps a lot with
|
||||
adding some semantic to the event. Finally, `args` is any number of
|
||||
arguments we want to collect.
|
||||
|
||||
Here is an example of a possible tracepoint in main():
|
||||
|
||||
tor_trace(main, init_phase, argc)
|
||||
|
||||
The above is a tracepoint in the `main` subsystem with `init_phase` as the
|
||||
event name and the `int argc` is passed to the event as well.
|
||||
|
||||
How `argc` is collected or used has nothing to do with the instrumentation
|
||||
(adding trace events to the code). It is the work of the tracer so this is why
|
||||
the trace events and collection framework (tracer) are decoupled. You _can_
|
||||
have trace events without a tracer.
|
||||
|
||||
### Tracer ###
|
||||
|
||||
In `src/trace/events.h`, we map the `tor_trace()` function to the right
|
||||
tracer. A tracer support is only enabled at compile time. For instance, the
|
||||
file `src/trace/debug.h` contains the mapping of the generic tracing function
|
||||
`tor_trace()` to the `log_debug()` function. More specialized function can be
|
||||
mapped depending on the tracepoint.
|
||||
|
||||
## Build System ##
|
||||
|
||||
This section describes how it is integrated into the build system of tor.
|
||||
|
||||
By default, every tracing events are disabled in tor that is `tor_trace()`
|
||||
is a NOP.
|
||||
|
||||
To enable a tracer, there is a configure option on the form of:
|
||||
|
||||
--enable-tracing-<tracer>
|
||||
|
||||
We have an option that will send every trace events to a `log_debug()` (as
|
||||
mentionned above) which will print you the subsystem and name of the event but
|
||||
not the arguments for technical reasons. This is useful if you want to quickly
|
||||
see if your trace event is being hit or well written. To do so, use this
|
||||
configure option:
|
||||
|
||||
--enable-tracing-debug
|
||||
|
||||
## Instrument Tor ##
|
||||
|
||||
This is pretty easy. Let's say you want to add a trace event in
|
||||
`src/or/rendcache.c`, you only have to add this include statement:
|
||||
|
||||
#include "trace/events.h"
|
||||
|
||||
Once done, you can add as many as you want `tor_trace()` that you need.
|
||||
Please use the right subsystem (here it would be `hs`) and a unique name that
|
||||
tells what the event is for. For example:
|
||||
|
||||
tor_trace(hs, store_desc_as_client, desc, desc_id);
|
||||
|
||||
If you look in `src/trace/events.h`, you'll see that if tracing is enabled it
|
||||
will be mapped to a function called:
|
||||
|
||||
tor_trace_hs_store_desc_as_client(desc, desc_id)
|
||||
|
||||
And the point of all this is for that function to be defined in a new file
|
||||
that you might want to add named `src/trace/hs.{c|h}` which would defined how
|
||||
to collect the data for the `tor_trace_hs_store_desc_as_client()` function
|
||||
like for instance sending it to a `log_debug()` or do more complex operations
|
||||
or use a userspace tracer like LTTng (https://lttng.org).
|
|
@ -1,499 +0,0 @@
|
|||
|
||||
Writing tests for Tor: an incomplete guide
|
||||
==========================================
|
||||
|
||||
Tor uses a variety of testing frameworks and methodologies to try to
|
||||
keep from introducing bugs. The major ones are:
|
||||
|
||||
1. Unit tests written in C and shipped with the Tor distribution.
|
||||
|
||||
2. Integration tests written in Python and shipped with the Tor
|
||||
distribution.
|
||||
|
||||
3. Integration tests written in Python and shipped with the Stem
|
||||
library. Some of these use the Tor controller protocol.
|
||||
|
||||
4. System tests written in Python and SH, and shipped with the
|
||||
Chutney package. These work by running many instances of Tor
|
||||
locally, and sending traffic through them.
|
||||
|
||||
5. The Shadow network simulator.
|
||||
|
||||
How to run these tests
|
||||
----------------------
|
||||
|
||||
### The easy version
|
||||
|
||||
To run all the tests that come bundled with Tor, run `make check`.
|
||||
|
||||
To run the Stem tests as well, fetch stem from the git repository,
|
||||
set `STEM_SOURCE_DIR` to the checkout, and run `make test-stem`.
|
||||
|
||||
To run the Chutney tests as well, fetch chutney from the git repository,
|
||||
set `CHUTNEY_PATH` to the checkout, and run `make test-network`.
|
||||
|
||||
To run all of the above, run `make test-full`.
|
||||
|
||||
To run all of the above, plus tests that require a working connection to the
|
||||
internet, run `make test-full-online`.
|
||||
|
||||
### Running particular subtests
|
||||
|
||||
The Tor unit tests are divided into separate programs and a couple of
|
||||
bundled unit test programs.
|
||||
|
||||
Separate programs are easy. For example, to run the memwipe tests in
|
||||
isolation, you just run `./src/test/test-memwipe`.
|
||||
|
||||
To run tests within the unit test programs, you can specify the name
|
||||
of the test. The string ".." can be used as a wildcard at the end of the
|
||||
test name. For example, to run all the cell format tests, enter
|
||||
`./src/test/test cellfmt/..`.
|
||||
|
||||
Many tests that need to mess with global state run in forked subprocesses in
|
||||
order to keep from contaminating one another. But when debugging a failing test,
|
||||
you might want to run it without forking a subprocess. To do so, use the
|
||||
`--no-fork` option with a single test. (If you specify it along with
|
||||
multiple tests, they might interfere.)
|
||||
|
||||
You can turn on logging in the unit tests by passing one of `--debug`,
|
||||
`--info`, `--notice`, or `--warn`. By default only errors are displayed.
|
||||
|
||||
Unit tests are divided into `./src/test/test` and `./src/test/test-slow`.
|
||||
The former are those that should finish in a few seconds; the latter tend to
|
||||
take more time, and may include CPU-intensive operations, deliberate delays,
|
||||
and stuff like that.
|
||||
|
||||
### Finding test coverage
|
||||
|
||||
Test coverage is a measurement of which lines your tests actually visit.
|
||||
|
||||
When you configure Tor with the `--enable-coverage` option, it should
|
||||
build with support for coverage in the unit tests, and in a special
|
||||
`tor-cov` binary.
|
||||
|
||||
Then, run the tests you'd like to see coverage from. If you have old
|
||||
coverage output, you may need to run `reset-gcov` first.
|
||||
|
||||
Now you've got a bunch of files scattered around your build directories
|
||||
called `*.gcda`. In order to extract the coverage output from them, make a
|
||||
temporary directory for them and run `./scripts/test/coverage ${TMPDIR}`,
|
||||
where `${TMPDIR}` is the temporary directory you made. This will create a
|
||||
`.gcov` file for each source file under tests, containing that file's source
|
||||
annotated with the number of times the tests hit each line. (You'll need to
|
||||
have gcov installed.)
|
||||
|
||||
You can get a summary of the test coverage for each file by running
|
||||
`./scripts/test/cov-display ${TMPDIR}/*` . Each line lists the file's name,
|
||||
the number of uncovered lines, the number of uncovered lines, and the
|
||||
coverage percentage.
|
||||
|
||||
For a summary of the test coverage for each _function_, run
|
||||
`./scripts/test/cov-display -f ${TMPDIR}/*`.
|
||||
|
||||
For more details on using gcov, including the helper scripts in
|
||||
scripts/test, see HelpfulTools.md.
|
||||
|
||||
### Comparing test coverage
|
||||
|
||||
Sometimes it's useful to compare test coverage for a branch you're writing to
|
||||
coverage from another branch (such as git master, for example). But you
|
||||
can't run `diff` on the two coverage outputs directly, since the actual
|
||||
number of times each line is executed aren't so important, and aren't wholly
|
||||
deterministic.
|
||||
|
||||
Instead, follow the instructions above for each branch, creating a separate
|
||||
temporary directory for each. Then, run `./scripts/test/cov-diff ${D1}
|
||||
${D2}`, where D1 and D2 are the directories you want to compare. This will
|
||||
produce a diff of the two directories, with all lines normalized to be either
|
||||
covered or uncovered.
|
||||
|
||||
To count new or modified uncovered lines in D2, you can run:
|
||||
|
||||
./scripts/test/cov-diff ${D1} ${D2}" | grep '^+ *\#' | wc -l
|
||||
|
||||
### Marking lines as unreachable by tests
|
||||
|
||||
You can mark a specific line as unreachable by using the special
|
||||
string LCOV_EXCL_LINE. You can mark a range of lines as unreachable
|
||||
with LCOV_EXCL_START... LCOV_EXCL_STOP. Note that older versions of
|
||||
lcov don't understand these lines.
|
||||
|
||||
You can post-process .gcov files to make these lines 'unreached' by
|
||||
running ./scripts/test/cov-exclude on them. It marks excluded
|
||||
unreached lines with 'x', and excluded reached lines with '!!!'.
|
||||
|
||||
Note: you should never do this unless the line is meant to 100%
|
||||
unreachable by actual code.
|
||||
|
||||
|
||||
What kinds of test should I write?
|
||||
----------------------------------
|
||||
|
||||
Integration testing and unit testing are complementary: it's probably a
|
||||
good idea to make sure that your code is hit by both if you can.
|
||||
|
||||
If your code is very-low level, and its behavior is easily described in
|
||||
terms of a relation between inputs and outputs, or a set of state
|
||||
transitions, then it's a natural fit for unit tests. (If not, please
|
||||
consider refactoring it until most of it _is_ a good fit for unit
|
||||
tests!)
|
||||
|
||||
If your code adds new externally visible functionality to Tor, it would
|
||||
be great to have a test for that functionality. That's where
|
||||
integration tests more usually come in.
|
||||
|
||||
Unit and regression tests: Does this function do what it's supposed to?
|
||||
-----------------------------------------------------------------------
|
||||
|
||||
Most of Tor's unit tests are made using the "tinytest" testing framework.
|
||||
You can see a guide to using it in the tinytest manual at
|
||||
|
||||
https://github.com/nmathewson/tinytest/blob/master/tinytest-manual.md
|
||||
|
||||
To add a new test of this kind, either edit an existing C file in `src/test/`,
|
||||
or create a new C file there. Each test is a single function that must
|
||||
be indexed in the table at the end of the file. We use the label "done:" as
|
||||
a cleanup point for all test functions.
|
||||
|
||||
If you have created a new test file, you will need to:
|
||||
1. Add the new test file to include.am
|
||||
2. In `test.h`, include the new test cases (testcase_t)
|
||||
3. In `test.c`, add the new test cases to testgroup_t testgroups
|
||||
|
||||
(Make sure you read `tinytest-manual.md` before proceeding.)
|
||||
|
||||
I use the term "unit test" and "regression tests" very sloppily here.
|
||||
|
||||
### A simple example
|
||||
|
||||
Here's an example of a test function for a simple function in util.c:
|
||||
|
||||
static void
|
||||
test_util_writepid(void *arg)
|
||||
{
|
||||
(void) arg;
|
||||
|
||||
char *contents = NULL;
|
||||
const char *fname = get_fname("tmp_pid");
|
||||
unsigned long pid;
|
||||
char c;
|
||||
|
||||
write_pidfile(fname);
|
||||
|
||||
contents = read_file_to_str(fname, 0, NULL);
|
||||
tt_assert(contents);
|
||||
|
||||
int n = sscanf(contents, "%lu\n%c", &pid, &c);
|
||||
tt_int_op(n, OP_EQ, 1);
|
||||
tt_int_op(pid, OP_EQ, getpid());
|
||||
|
||||
done:
|
||||
tor_free(contents);
|
||||
}
|
||||
|
||||
This should look pretty familiar to you if you've read the tinytest
|
||||
manual. One thing to note here is that we use the testing-specific
|
||||
function `get_fname` to generate a file with respect to a temporary
|
||||
directory that the tests use. You don't need to delete the file;
|
||||
it will get removed when the tests are done.
|
||||
|
||||
Also note our use of `OP_EQ` instead of `==` in the `tt_int_op()` calls.
|
||||
We define `OP_*` macros to use instead of the binary comparison
|
||||
operators so that analysis tools can more easily parse our code.
|
||||
(Coccinelle really hates to see `==` used as a macro argument.)
|
||||
|
||||
Finally, remember that by convention, all `*_free()` functions that
|
||||
Tor defines are defined to accept NULL harmlessly. Thus, you don't
|
||||
need to say `if (contents)` in the cleanup block.
|
||||
|
||||
### Exposing static functions for testing
|
||||
|
||||
Sometimes you need to test a function, but you don't want to expose
|
||||
it outside its usual module.
|
||||
|
||||
To support this, Tor's build system compiles a testing version of
|
||||
each module, with extra identifiers exposed. If you want to
|
||||
declare a function as static but available for testing, use the
|
||||
macro `STATIC` instead of `static`. Then, make sure there's a
|
||||
macro-protected declaration of the function in the module's header.
|
||||
|
||||
For example, `crypto_curve25519.h` contains:
|
||||
|
||||
#ifdef CRYPTO_CURVE25519_PRIVATE
|
||||
STATIC int curve25519_impl(uint8_t *output, const uint8_t *secret,
|
||||
const uint8_t *basepoint);
|
||||
#endif
|
||||
|
||||
The `crypto_curve25519.c` file and the `test_crypto.c` file both define
|
||||
`CRYPTO_CURVE25519_PRIVATE`, so they can see this declaration.
|
||||
|
||||
### STOP! Does this test really test?
|
||||
|
||||
When writing tests, it's not enough to just generate coverage on all the
|
||||
lines of the code that you're testing: It's important to make sure that
|
||||
the test _really tests_ the code.
|
||||
|
||||
For example, here is a _bad_ test for the unlink() function (which is
|
||||
supposed to remove a file).
|
||||
|
||||
static void
|
||||
test_unlink_badly(void *arg)
|
||||
{
|
||||
(void) arg;
|
||||
int r;
|
||||
|
||||
const char *fname = get_fname("tmpfile");
|
||||
|
||||
/* If the file isn't there, unlink returns -1 and sets ENOENT */
|
||||
r = unlink(fname);
|
||||
tt_int_op(n, OP_EQ, -1);
|
||||
tt_int_op(errno, OP_EQ, ENOENT);
|
||||
|
||||
/* If the file DOES exist, unlink returns 0. */
|
||||
write_str_to_file(fname, "hello world", 0);
|
||||
r = unlink(fnme);
|
||||
tt_int_op(r, OP_EQ, 0);
|
||||
|
||||
done:
|
||||
tor_free(contents);
|
||||
}
|
||||
|
||||
|
||||
This test might get very high coverage on unlink(). So why is it a
|
||||
bad test? Because it doesn't check that unlink() *actually removes the
|
||||
named file*!
|
||||
|
||||
Remember, the purpose of a test is to succeed if the code does what
|
||||
it's supposed to do, and fail otherwise. Try to design your tests so
|
||||
that they check for the code's intended and documented functionality
|
||||
as much as possible.
|
||||
|
||||
|
||||
### Mock functions for testing in isolation
|
||||
|
||||
Often we want to test that a function works right, but the function to
|
||||
be tested depends on other functions whose behavior is hard to observe,
|
||||
or which require a working Tor network, or something like that.
|
||||
|
||||
To write tests for this case, you can replace the underlying functions
|
||||
with testing stubs while your unit test is running. You need to declare
|
||||
the underlying function as 'mockable', as follows:
|
||||
|
||||
MOCK_DECL(returntype, functionname, (argument list));
|
||||
|
||||
and then later implement it as:
|
||||
|
||||
MOCK_IMPL(returntype, functionname, (argument list))
|
||||
{
|
||||
/* implementation here */
|
||||
}
|
||||
|
||||
For example, if you had a 'connect to remote server' function, you could
|
||||
declare it as:
|
||||
|
||||
|
||||
MOCK_DECL(int, connect_to_remote, (const char *name, status_t *status));
|
||||
|
||||
When you declare a function this way, it will be declared as normal in
|
||||
regular builds, but when the module is built for testing, it is declared
|
||||
as a function pointer initialized to the actual implementation.
|
||||
|
||||
In your tests, if you want to override the function with a temporary
|
||||
replacement, you say:
|
||||
|
||||
MOCK(functionname, replacement_function_name);
|
||||
|
||||
And later, you can restore the original function with:
|
||||
|
||||
UNMOCK(functionname);
|
||||
|
||||
For more information, see the definitions of this mocking logic in
|
||||
`testsupport.h`.
|
||||
|
||||
### Okay but what should my tests actually do?
|
||||
|
||||
We talk above about "test coverage" -- making sure that your tests visit
|
||||
every line of code, or every branch of code. But visiting the code isn't
|
||||
enough: we want to verify that it's correct.
|
||||
|
||||
So when writing tests, try to make tests that should pass with any correct
|
||||
implementation of the code, and that should fail if the code doesn't do what
|
||||
it's supposed to do.
|
||||
|
||||
You can write "black-box" tests or "glass-box" tests. A black-box test is
|
||||
one that you write without looking at the structure of the function. A
|
||||
glass-box one is one you implement while looking at how the function is
|
||||
implemented.
|
||||
|
||||
In either case, make sure to consider common cases *and* edge cases; success
|
||||
cases and failure csaes.
|
||||
|
||||
For example, consider testing this function:
|
||||
|
||||
/** Remove all elements E from sl such that E==element. Preserve
|
||||
* the order of any elements before E, but elements after E can be
|
||||
* rearranged.
|
||||
*/
|
||||
void smartlist_remove(smartlist_t *sl, const void *element);
|
||||
|
||||
In order to test it well, you should write tests for at least all of the
|
||||
following cases. (These would be black-box tests, since we're only looking
|
||||
at the declared behavior for the function:
|
||||
|
||||
* Remove an element that is in the smartlist.
|
||||
* Remove an element that is not in the smartlist.
|
||||
* Remove an element that appears in the smartlist more than once.
|
||||
|
||||
And your tests should verify that it behaves correct. At minimum, you should
|
||||
test:
|
||||
|
||||
* That other elements before E are in the same order after you call the
|
||||
functions.
|
||||
* That the target element is really removed.
|
||||
* That _only_ the target element is removed.
|
||||
|
||||
When you consider edge cases, you might try:
|
||||
|
||||
* Remove an element from an empty list.
|
||||
* Remove an element from a singleton list containing that element.
|
||||
* Remove an element for a list containing several instances of that
|
||||
element, and nothing else.
|
||||
|
||||
Now let's look at the implementation:
|
||||
|
||||
void
|
||||
smartlist_remove(smartlist_t *sl, const void *element)
|
||||
{
|
||||
int i;
|
||||
if (element == NULL)
|
||||
return;
|
||||
for (i=0; i < sl->num_used; i++)
|
||||
if (sl->list[i] == element) {
|
||||
sl->list[i] = sl->list[--sl->num_used]; /* swap with the end */
|
||||
i--; /* so we process the new i'th element */
|
||||
sl->list[sl->num_used] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
Based on the implementation, we now see three more edge cases to test:
|
||||
|
||||
* Removing NULL from the list.
|
||||
* Removing an element from the end of the list
|
||||
* Removing an element from a position other than the end of the list.
|
||||
|
||||
|
||||
### What should my tests NOT do?
|
||||
|
||||
Tests shouldn't require a network connection.
|
||||
|
||||
Whenever possible, tests shouldn't take more than a second. Put the test
|
||||
into test/slow if it genuinely needs to be run.
|
||||
|
||||
Tests should not alter global state unless they run with `TT_FORK`: Tests
|
||||
should not require other tests to be run before or after them.
|
||||
|
||||
Tests should not leak memory or other resources. To find out if your tests
|
||||
are leaking memory, run them under valgrind (see HelpfulTools.txt for more
|
||||
information on how to do that).
|
||||
|
||||
When possible, tests should not be over-fit to the implementation. That is,
|
||||
the test should verify that the documented behavior is implemented, but
|
||||
should not break if other permissible behavior is later implemented.
|
||||
|
||||
|
||||
### Advanced techniques: Namespaces
|
||||
|
||||
Sometimes, when you're doing a lot of mocking at once, it's convenient to
|
||||
isolate your identifiers within a single namespace. If this were C++, we'd
|
||||
already have namespaces, but for C, we do the best we can with macros and
|
||||
token-pasting.
|
||||
|
||||
We have some macros defined for this purpose in `src/test/test.h`. To use
|
||||
them, you define `NS_MODULE` to a prefix to be used for your identifiers, and
|
||||
then use other macros in place of identifier names. See `src/test/test.h` for
|
||||
more documentation.
|
||||
|
||||
|
||||
Integration tests: Calling Tor from the outside
|
||||
-----------------------------------------------
|
||||
|
||||
Some tests need to invoke Tor from the outside, and shouldn't run from the
|
||||
same process as the Tor test program. Reasons for doing this might include:
|
||||
|
||||
* Testing the actual behavior of Tor when run from the command line
|
||||
* Testing that a crash-handler correctly logs a stack trace
|
||||
* Verifying that violating a sandbox or capability requirement will
|
||||
actually crash the program.
|
||||
* Needing to run as root in order to test capability inheritance or
|
||||
user switching.
|
||||
|
||||
To add one of these, you generally want a new C program in `src/test`. Add it
|
||||
to `TESTS` and `noinst_PROGRAMS` if it can run on its own and return success or
|
||||
failure. If it needs to be invoked multiple times, or it needs to be
|
||||
wrapped, add a new shell script to `TESTS`, and the new program to
|
||||
`noinst_PROGRAMS`. If you need access to any environment variable from the
|
||||
makefile (eg `${PYTHON}` for a python interpreter), then make sure that the
|
||||
makefile exports them.
|
||||
|
||||
Writing integration tests with Stem
|
||||
-----------------------------------
|
||||
|
||||
The 'stem' library includes extensive tests for the Tor controller protocol.
|
||||
You can run stem tests from tor with `make test-stem`, or see
|
||||
`https://stem.torproject.org/faq.html#how-do-i-run-the-tests`.
|
||||
|
||||
To see what tests are available, have a look around the `test/*` directory in
|
||||
stem. The first thing you'll notice is that there are both `unit` and `integ`
|
||||
tests. The former are for tests of the facilities provided by stem itself that
|
||||
can be tested on their own, without the need to hook up a tor process. These
|
||||
are less relevant, unless you want to develop a new stem feature. The latter,
|
||||
however, are a very useful tool to write tests for controller features. They
|
||||
provide a default environment with a connected tor instance that can be
|
||||
modified and queried. Adding more integration tests is a great way to increase
|
||||
the test coverage inside Tor, especially for controller features.
|
||||
|
||||
Let's assume you actually want to write a test for a previously untested
|
||||
controller feature. I'm picking the `exit-policy/*` GETINFO queries. Since
|
||||
these are a controller feature that we want to write an integration test for,
|
||||
the right file to modify is
|
||||
`https://gitweb.torproject.org/stem.git/tree/test/integ/control/controller.py`.
|
||||
|
||||
First off we notice that there is an integration test called
|
||||
`test_get_exit_policy()` that's already written. This exercises the interaction
|
||||
of stem's `Controller.get_exit_policy()` method, and is not relevant for our
|
||||
test since there are no stem methods to make use of all `exit-policy/*`
|
||||
queries (if there were, likely they'd be tested already. Maybe you want to
|
||||
write a stem feature, but I chose to just add tests).
|
||||
|
||||
Our test requires a tor controller connection, so we'll use the
|
||||
`@require_controller` annotation for our `test_exit_policy()` method. We need a
|
||||
controller instance, which we get from
|
||||
`test.runner.get_runner().get_tor_controller()`. The attached Tor instance is
|
||||
configured as a client, but the exit-policy GETINFO queries need a relay to
|
||||
work, so we have to change the config (using `controller.set_options()`). This
|
||||
is OK for us to do, we just have to remember to set DisableNetwork so we don't
|
||||
actually start an exit relay and also to undo the changes we made (by calling
|
||||
`controller.reset_conf()` at the end of our test). Additionally, we have to
|
||||
configure a static Address for Tor to use, because it refuses to build a
|
||||
descriptor when it can't guess a suitable IP address. Unfortunately, these
|
||||
kinds of tripwires are everywhere. Don't forget to file appropriate tickets if
|
||||
you notice any strange behaviour that seems totally unreasonable.
|
||||
|
||||
Check out the `test_exit_policy()` function in abovementioned file to see the
|
||||
final implementation for this test.
|
||||
|
||||
System testing with Chutney
|
||||
---------------------------
|
||||
|
||||
The 'chutney' program configures and launches a set of Tor relays,
|
||||
authorities, and clients on your local host. It has a `test network`
|
||||
functionality to send traffic through them and verify that the traffic
|
||||
arrives correctly.
|
||||
|
||||
You can write new test networks by adding them to `networks`. To add
|
||||
them to Tor's tests, add them to the `test-network` or `test-network-all`
|
||||
targets in `Makefile.am`.
|
||||
|
||||
(Adding new kinds of program to chutney will still require hacking the
|
||||
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
|
||||
|
86
doc/TUNING
86
doc/TUNING
|
@ -1,86 +0,0 @@
|
|||
Most operating systems limit an amount of TCP sockets that can be used
|
||||
simultaneously. It is possible for a busy Tor relay to run into these
|
||||
limits, thus being unable to fully utilize the bandwidth resources it
|
||||
has at its disposal. Following system-specific tips might be helpful
|
||||
to alleviate the aforementioned problem.
|
||||
|
||||
Linux
|
||||
-----
|
||||
|
||||
Use 'ulimit -n' to raise an allowed number of file descriptors to be
|
||||
opened on your host at the same time.
|
||||
|
||||
FreeBSD
|
||||
-------
|
||||
|
||||
Tune the followind sysctl(8) variables:
|
||||
* kern.maxfiles - maximum allowed file descriptors (for entire system)
|
||||
* kern.maxfilesperproc - maximum file descriptors one process is allowed
|
||||
to use
|
||||
* kern.ipc.maxsockets - overall maximum numbers of sockets for entire
|
||||
system
|
||||
* kern.ipc.somaxconn - size of listen queue for incoming TCP connections
|
||||
for entire system
|
||||
|
||||
See also:
|
||||
* https://www.freebsd.org/doc/handbook/configtuning-kernel-limits.html
|
||||
* https://wiki.freebsd.org/NetworkPerformanceTuning
|
||||
|
||||
Mac OS X
|
||||
--------
|
||||
|
||||
Since Mac OS X is BSD-based system, most of the above hold for OS X as well.
|
||||
However, launchd(8) is known to modify kern.maxfiles and kern.maxfilesperproc
|
||||
when it launches tor service (see launchd.plist(5) manpage). Also,
|
||||
kern.ipc.maxsockets is determined dynamically by the system and thus is
|
||||
read-only on OS X.
|
||||
|
||||
OpenBSD
|
||||
-------
|
||||
|
||||
Because OpenBSD is primarily focused on security and stability, it uses default
|
||||
resource limits stricter than those of more popular Unix-like operating systems.
|
||||
|
||||
OpenBSD stores a kernel-level file descriptor limit in the sysctl variable
|
||||
kern.maxfiles. It defaults to 7,030. To change it to, for example, 16,000 while
|
||||
the system is running, use the command 'sudo sysctl kern.maxfiles=16000'.
|
||||
kern.maxfiles will reset to the default value upon system reboot unless you also
|
||||
add 'kern.maxfiles=16000' to the file /etc/sysctl.conf.
|
||||
|
||||
There are stricter resource limits set on user classes, which are stored in
|
||||
/etc/login.conf. This config file also allows limit sets for daemons started
|
||||
with scripts in the /etc/rc.d directory, which presumably includes Tor.
|
||||
|
||||
To increase the file descriptor limit from its default of 1,024, add the
|
||||
following to /etc/login.conf:
|
||||
|
||||
tor:\
|
||||
:openfiles-max=13500:\
|
||||
:tc=daemon:
|
||||
|
||||
Upon restarting Tor, it will be able to open up to 13,500 file descriptors.
|
||||
|
||||
This will work *only* if you are starting Tor with the script /etc/rc.d/tor. If
|
||||
you're using a custom build instead of the package, you can easily copy the rc.d
|
||||
script from the Tor port directory. Alternatively, you can ensure that the Tor's
|
||||
daemon user has its own user class and make a /etc/login.conf entry for it.
|
||||
|
||||
High-bandwidth relays sometimes give the syslog warning:
|
||||
|
||||
/bsd: WARNING: mclpools limit reached; increase kern.maxclusters
|
||||
|
||||
In this case, increase kern.maxclusters with the sysctl command and in the file
|
||||
/etc/sysctl.conf, as described with kern.maxfiles above. Use 'sysctl
|
||||
kern.maxclusters' to query the current value. Increasing by about 15% per day
|
||||
until the error no longer appears is a good guideline.
|
||||
|
||||
Disclaimer
|
||||
----------
|
||||
|
||||
Do note that this document is a draft and above information may be
|
||||
technically incorrect and/or incomplete. If so, please open a ticket
|
||||
on https://trac.torproject.org or post to tor-relays mailing list.
|
||||
|
||||
Are you running a busy Tor relay? Let us know how you are solving
|
||||
the out-of-sockets problem on your system.
|
||||
|
|
@ -19,7 +19,7 @@ if [ "$1" = "html" ]; then
|
|||
base=${output%%.html.in}
|
||||
|
||||
if [ "$2" != none ]; then
|
||||
TZ=UTC "$2" -d manpage -o $output $input;
|
||||
"$2" -d manpage -o $output $input;
|
||||
else
|
||||
echo "==================================";
|
||||
echo;
|
||||
|
|
|
@ -1,122 +0,0 @@
|
|||
Building Tor with MSVC.
|
||||
=======================
|
||||
|
||||
NOTE: This is not the preferred method for building Tor on windows: we use
|
||||
mingw for our packages.
|
||||
|
||||
Last updated 9 September 2014.
|
||||
|
||||
|
||||
Requirements:
|
||||
-------------
|
||||
|
||||
* Visual Studio 2010
|
||||
http://go.microsoft.com/fwlink/?LinkId=323467
|
||||
* CMake 2.8.12.2
|
||||
http://www.cmake.org/download/
|
||||
* Perl 5.16
|
||||
http://www.activestate.com/activeperl/downloads
|
||||
* Latest stable OpenSSL tarball
|
||||
https://www.openssl.org/source/
|
||||
* Latest stable zlib tarball
|
||||
http://zlib.net/
|
||||
* Latest stable libevent Libevent tarball
|
||||
https://github.com/libevent/libevent/releases
|
||||
|
||||
Make sure you check signatures for all these packages.
|
||||
|
||||
Steps:
|
||||
------
|
||||
|
||||
Building OpenSSL from source as a shared library:
|
||||
|
||||
cd <openssl source dir>
|
||||
perl Configure VC-WIN32
|
||||
perl util\mkfiles.pl >MINFO
|
||||
perl util\mk1mf.pl no-asm dll VC-WIN32 >32dll.mak
|
||||
perl util\mkdef.pl 32 libeay > ms\libeay32.def
|
||||
perl util\mkdef.pl 32 ssleay > ms\ssleay32.def
|
||||
nmake -f 32dll.mak
|
||||
|
||||
Making OpenSSL final package:
|
||||
|
||||
Create <openssl final package dir>, I'd recommend using a name like <openssl
|
||||
source dir>-vc10.
|
||||
|
||||
Copy the following directories and files to their respective locations
|
||||
<openssl source dir>\inc32\openssl => <openssl final package dir>\include\openssl
|
||||
<openssl source dir>\out32dll\libeay32.lib => <openssl final package dir>\lib\libeay32.lib
|
||||
<openssl source dir>\out32dll\ssleay32.lib => <openssl final package dir>\lib\ssleay32.lib
|
||||
<openssl source dir>\out32dll\libeay32.dll => <openssl final package dir>\bin\libeay32.dll
|
||||
<openssl source dir>\out32dll\openssl.exe => <openssl final package dir>\bin\openssl.exe
|
||||
<openssl source dir>\out32dll\ssleay32.dll => <openssl final package dir>\bin\ssleay32.dll
|
||||
|
||||
Building Zlib from source:
|
||||
|
||||
cd <zlib source dir>
|
||||
nmake -f win32/Makefile.msc
|
||||
|
||||
Building libevent:
|
||||
|
||||
cd <libevent source dir>
|
||||
mkdir build && cd build
|
||||
SET OPENSSL_ROOT_DIR=<openssl final package dir>
|
||||
cmake -G "NMake Makefiles" .. -DCMAKE_BUILD_TYPE:STRING=RelWithDebInfo -DCMAKE_C_FLAGS_RELWITHDEBINFO:STRING="/MT /Zi /O2 /Ob1 /D NDEBUG" -DZLIB_LIBRARY:FILEPATH="<zlib source dir>\zdll.lib" -DZLIB_INCLUDE_DIR:PATH="<zlib source dir>"
|
||||
nmake event
|
||||
|
||||
Building Tor:
|
||||
|
||||
Create a dir above tor source dir named build-alpha and two subdirs include
|
||||
and lib.
|
||||
|
||||
Your build tree should now be similar to this one:
|
||||
* build-alpha
|
||||
- include
|
||||
- lib
|
||||
* <libevent source dir>
|
||||
- build
|
||||
- cmake
|
||||
- ...
|
||||
* <openssl source dir>
|
||||
- ...
|
||||
- ms
|
||||
- util
|
||||
- ...
|
||||
* <openssl final package dir>
|
||||
- bin
|
||||
- include
|
||||
- lib
|
||||
* <tor source dir>
|
||||
- ...
|
||||
- src
|
||||
- ...
|
||||
* <zlib source dir>
|
||||
- ...
|
||||
- win32
|
||||
- ...
|
||||
|
||||
Copy the following dirs and files to the following locations:
|
||||
<openssl final package dir>\include\openssl => build-alpha\include\openssl
|
||||
<libevent source dir>\include => build-alpha\include
|
||||
<libevent source dir>\WIN32-Code\nmake\event2 => build-alpha\include\event2
|
||||
<zlib source dir>\z*.h => build-alpha\include\z*.h
|
||||
|
||||
Now copy the following files to the following locations and rename them
|
||||
according new names:
|
||||
|
||||
<libevent source dir>\build\lib\event.lib => build-alpha\lib\libevent.lib
|
||||
<openssl final package dir>\lib\libeay32.lib => build-alpha\lib\libcrypto.lib
|
||||
<openssl final package dir>\lib\ssleay32.lib => build-alpha\lib\libssl.lib
|
||||
<zlib source dir>\zdll.lib => build-alpha\lib\libz.lib
|
||||
|
||||
And we are now ready for the build process:
|
||||
|
||||
cd <tor source dir>
|
||||
nmake -f Makefile.nmake
|
||||
|
||||
After the above process is completed there should be a tor.exe in <tor
|
||||
source dir>\src\or
|
||||
|
||||
Copy tor.exe to desired location and also copy zlib1.dll, libeay32.dll and
|
||||
ssleay32.dll from built zlib and openssl packages
|
||||
|
|
@ -42,7 +42,7 @@ Here's a workaround:
|
|||
Before even building the source RPM, install fedora-packager and instruct
|
||||
the build system to use rpmbuild-md5 like this:
|
||||
|
||||
dnf install fedora-packager
|
||||
yum install fedora-packager
|
||||
export RPMBUILD=rpmbuild-md5
|
||||
|
||||
Then proceed as usual to create the source RPM and binary RPMs:
|
||||
|
|
|
@ -12,11 +12,17 @@
|
|||
# part of the source distribution, so that people without asciidoc can
|
||||
# just use the .1 and .html files.
|
||||
|
||||
all_mans = doc/tor doc/tor-gencert doc/tor-resolve doc/torify
|
||||
base_mans = doc/tor doc/tor-gencert doc/tor-resolve doc/torify
|
||||
all_mans = $(base_mans) doc/tor-fw-helper
|
||||
if USE_FW_HELPER
|
||||
install_mans = $(all_mans)
|
||||
else
|
||||
install_mans = $(base_mans)
|
||||
endif
|
||||
|
||||
if USE_ASCIIDOC
|
||||
nodist_man1_MANS = $(all_mans:=.1)
|
||||
doc_DATA = $(all_mans:=.html)
|
||||
nodist_man1_MANS = $(install_mans:=.1)
|
||||
doc_DATA = $(install_mans:=.html)
|
||||
html_in = $(all_mans:=.html.in)
|
||||
man_in = $(all_mans:=.1.in)
|
||||
txt_in = $(all_mans:=.1.txt)
|
||||
|
@ -28,23 +34,9 @@ nodist_man1_MANS =
|
|||
doc_DATA =
|
||||
endif
|
||||
|
||||
EXTRA_DIST+= doc/asciidoc-helper.sh \
|
||||
EXTRA_DIST+= doc/HACKING doc/asciidoc-helper.sh \
|
||||
$(html_in) $(man_in) $(txt_in) \
|
||||
doc/state-contents.txt \
|
||||
doc/torrc_format.txt \
|
||||
doc/TUNING \
|
||||
doc/HACKING/README.1st.md \
|
||||
doc/HACKING/CodingStandards.md \
|
||||
doc/HACKING/CodingStandardsRust.md \
|
||||
doc/HACKING/Fuzzing.md \
|
||||
doc/HACKING/GettingStarted.md \
|
||||
doc/HACKING/GettingStartedRust.md \
|
||||
doc/HACKING/HelpfulTools.md \
|
||||
doc/HACKING/HowToReview.md \
|
||||
doc/HACKING/Module.md \
|
||||
doc/HACKING/ReleasingTor.md \
|
||||
doc/HACKING/Tracing.md \
|
||||
doc/HACKING/WritingTests.md
|
||||
doc/state-contents.txt
|
||||
|
||||
docdir = @docdir@
|
||||
|
||||
|
@ -64,30 +56,34 @@ doc/tor.1.in: doc/tor.1.txt
|
|||
doc/torify.1.in: doc/torify.1.txt
|
||||
doc/tor-gencert.1.in: doc/tor-gencert.1.txt
|
||||
doc/tor-resolve.1.in: doc/tor-resolve.1.txt
|
||||
doc/tor-fw-helper.1.in: doc/tor-fw-helper.1.txt
|
||||
|
||||
doc/tor.html.in: doc/tor.1.txt
|
||||
doc/torify.html.in: doc/torify.1.txt
|
||||
doc/tor-gencert.html.in: doc/tor-gencert.1.txt
|
||||
doc/tor-resolve.html.in: doc/tor-resolve.1.txt
|
||||
doc/tor-fw-helper.html.in: doc/tor-fw-helper.1.txt
|
||||
|
||||
# use config.status to swap all machine-specific magic strings
|
||||
# use ../config.status to swap all machine-specific magic strings
|
||||
# in the asciidoc with their replacements.
|
||||
$(asciidoc_product) :
|
||||
$(AM_V_GEN)$(MKDIR_P) $(@D)
|
||||
$(AM_V_at)if test -e $(top_srcdir)/$@.in && ! test -e $@.in ; then \
|
||||
cp $(top_srcdir)/$@.in $@; \
|
||||
fi
|
||||
$(AM_V_at)$(top_builddir)/config.status -q --file=$@;
|
||||
$(AM_V_at)./config.status -q --file=$@;
|
||||
|
||||
doc/tor.html: doc/tor.html.in
|
||||
doc/tor-gencert.html: doc/tor-gencert.html.in
|
||||
doc/tor-resolve.html: doc/tor-resolve.html.in
|
||||
doc/torify.html: doc/torify.html.in
|
||||
doc/tor-fw-helper.html: doc/tor-fw-helper.html.in
|
||||
|
||||
doc/tor.1: doc/tor.1.in
|
||||
doc/tor-gencert.1: doc/tor-gencert.1.in
|
||||
doc/tor-resolve.1: doc/tor-resolve.1.in
|
||||
doc/torify.1: doc/torify.1.in
|
||||
doc/tor-fw-helper.1: doc/tor-fw-helper.1.in
|
||||
|
||||
CLEANFILES+= $(asciidoc_product)
|
||||
CLEANFILES+= $(asciidoc_product) config.log
|
||||
DISTCLEANFILES+= $(html_in) $(man_in)
|
||||
|
|
|
@ -0,0 +1,60 @@
|
|||
// Copyright (c) The Tor Project, Inc.
|
||||
// See LICENSE for licensing information
|
||||
// This is an asciidoc file used to generate the manpage/html reference.
|
||||
// Learn asciidoc on http://www.methods.co.nz/asciidoc/userguide.html
|
||||
:man source: Tor
|
||||
:man manual: Tor Manual
|
||||
tor-fw-helper(1)
|
||||
================
|
||||
Jacob Appelbaum
|
||||
|
||||
NAME
|
||||
----
|
||||
tor-fw-helper - Manage upstream firewall/NAT devices
|
||||
|
||||
SYNOPSIS
|
||||
--------
|
||||
**tor-fw-helper** [-h|--help] [-T|--test-commandline] [-v|--verbose] [-g|--fetch-public-ip]
|
||||
[-p __external port__:__internal_port__]
|
||||
|
||||
DESCRIPTION
|
||||
-----------
|
||||
**tor-fw-helper** currently supports Apple's NAT-PMP protocol and the UPnP
|
||||
standard for TCP port mapping. It is written as the reference implementation of
|
||||
tor-fw-helper-spec.txt and conforms to that loose plugin API. If your network
|
||||
supports either NAT-PMP or UPnP, tor-fw-helper will attempt to automatically
|
||||
map the required TCP ports for Tor's Or and Dir ports. +
|
||||
|
||||
OPTIONS
|
||||
-------
|
||||
**-h** or **--help**::
|
||||
Display help text and exit.
|
||||
|
||||
**-v** or **--verbose**::
|
||||
Display verbose output.
|
||||
|
||||
**-T** or **--test-commandline**::
|
||||
Display test information and print the test information in
|
||||
tor-fw-helper.log
|
||||
|
||||
**-g** or **--fetch-public-ip**::
|
||||
Fetch the the public ip address for each supported NAT helper method.
|
||||
|
||||
**-p** or **--port** __external_port__:__internal_port__::
|
||||
Forward external_port to internal_port. This option can appear
|
||||
more than once.
|
||||
|
||||
BUGS
|
||||
----
|
||||
This probably doesn't run on Windows. That's not a big issue, since we don't
|
||||
really want to deal with Windows before October 2010 anyway.
|
||||
|
||||
SEE ALSO
|
||||
--------
|
||||
**tor**(1) +
|
||||
|
||||
See also the "tor-fw-helper-spec.txt" file, distributed with Tor.
|
||||
|
||||
AUTHORS
|
||||
-------
|
||||
Jacob Appelbaum <jacob@torproject.org>, Steven J. Murdoch <Steven.Murdoch@cl.cam.ac.uk>
|
|
@ -68,7 +68,7 @@ OPTIONS
|
|||
Number of months that the certificate should be valid. Default: 12.
|
||||
|
||||
**--passphrase-fd** __FILEDES__::
|
||||
Filedescriptor to read the passphrase from. Ends at the first NUL or
|
||||
Filedescriptor to read the file descriptor from. Ends at the first NUL or
|
||||
newline. Default: read from the terminal.
|
||||
|
||||
**-a** __address__:__port__::
|
||||
|
|
|
@ -14,7 +14,7 @@ tor-resolve - resolve a hostname to an IP address via tor
|
|||
|
||||
SYNOPSIS
|
||||
--------
|
||||
**tor-resolve** [-4|-5] [-v] [-x] [-p __socksport__] __hostname__ [__sockshost__[:__socksport__]]
|
||||
**tor-resolve** [-4|-5] [-v] [-x] __hostname__ [__sockshost__[:__socksport__]]
|
||||
|
||||
DESCRIPTION
|
||||
-----------
|
||||
|
@ -40,9 +40,6 @@ OPTIONS
|
|||
Use the SOCKS4a protocol rather than the default SOCKS5 protocol. Doesn't
|
||||
support reverse DNS.
|
||||
|
||||
**-p** __socksport__::
|
||||
Override the default SOCKS port without setting the hostname.
|
||||
|
||||
SEE ALSO
|
||||
--------
|
||||
**tor**(1), **torify**(1). +
|
||||
|
|
2270
doc/tor.1.txt
2270
doc/tor.1.txt
File diff suppressed because it is too large
Load Diff
|
@ -17,23 +17,25 @@ SYNOPSIS
|
|||
|
||||
DESCRIPTION
|
||||
-----------
|
||||
**torify** is a simple wrapper that calls torsocks with a tor-specific
|
||||
configuration file.
|
||||
**torify** is a simple wrapper that attempts to find the best underlying Tor
|
||||
wrapper available on a system. It calls torsocks with a tor specific
|
||||
configuration file. +
|
||||
|
||||
It is provided for backward compatibility; instead you should use torsocks.
|
||||
torsocks is an improved wrapper that explicitly rejects UDP, safely resolves DNS
|
||||
lookups and properly socksifies your TCP connections. +
|
||||
|
||||
Please note that since both method use LD_PRELOAD, torify cannot be applied to
|
||||
suid binaries.
|
||||
|
||||
WARNING
|
||||
-------
|
||||
When used with torsocks, torify should not leak DNS requests or UDP data.
|
||||
When used with torsocks, torify should not leak DNS requests or UDP data. +
|
||||
|
||||
torify can leak ICMP data.
|
||||
|
||||
torify will not ensure that different requests are processed on
|
||||
different circuits.
|
||||
Both will leak ICMP data.
|
||||
|
||||
SEE ALSO
|
||||
--------
|
||||
**tor**(1), **torsocks**(1)
|
||||
**tor**(1), **tor-resolve**(1), **torsocks**(1)
|
||||
|
||||
AUTHORS
|
||||
-------
|
||||
|
|
|
@ -1,212 +0,0 @@
|
|||
|
||||
This document specifies the current format and semantics of the torrc
|
||||
file, as of July 2015. Note that we make no guarantee about the
|
||||
stability of this format. If you write something designed for strict
|
||||
compatibility with this document, please expect us to break it sooner or
|
||||
later.
|
||||
|
||||
Yes, some of this is quite stupid. My goal here is to explain what it
|
||||
does, not what it should do.
|
||||
|
||||
- Nick
|
||||
|
||||
|
||||
|
||||
1. File Syntax
|
||||
|
||||
; The syntax here is defined an Augmented Backus-Naur form, as
|
||||
; specified in RFC5234.
|
||||
|
||||
; A file is interpreted as every Entry in the file, in order.
|
||||
TorrcFile = *Line [ UnterminatedLine ]
|
||||
|
||||
Line = BlankLine LF / Entry LF
|
||||
UnterminatedLine = BlankLine / Entry
|
||||
|
||||
BlankLine = *WSP OptComment LF
|
||||
BlankLine =/ *WSP LF
|
||||
|
||||
OptComment = [ Comment ]
|
||||
|
||||
Comment = "#" *NonLF
|
||||
|
||||
; Each Entry is interpreted as an optional "Magic" flag, a key, and a
|
||||
; value.
|
||||
Entry = *WSP [ Magic ] Key 1*(1*WSP / "\" NL *WSP) Val LF
|
||||
Entry =/ *WSP [ Magic ] Key *( *WSP / "\" NL *WSP) LF
|
||||
|
||||
Magic = "+" / "/"
|
||||
|
||||
; Keys are always specified verbatim. They are case insensitive. It
|
||||
; is an error to specify a key that Tor does not recognize.
|
||||
Key = 1*KC
|
||||
|
||||
; Sadly, every kind of value is decoded differently...
|
||||
Val = QuotedVal / ContinuedVal / PlainVal
|
||||
|
||||
; The text of a PlainVal is the text of its PVBody portion,
|
||||
; plus the optional trailing backslash.
|
||||
PlainVal = PVBody [ "\" ] *WSP OptComment
|
||||
|
||||
; Note that a PVBody is copied verbatim. Slashes are included
|
||||
; verbatim. No changes are made. Note that a body may be empty.
|
||||
PVBody = * (VC / "\" NonLF )
|
||||
|
||||
; The text of a ContinuedVal is the text of each of its PVBody
|
||||
; sub-elements, in order, concatenated.
|
||||
ContinuedVal = CVal1 *CVal2 CVal3
|
||||
|
||||
CVal1 = PVBody "\" LF
|
||||
CVal2 = PVBody ( "\" LF / Comment LF )
|
||||
CVal3 = PVBody
|
||||
|
||||
; The text of a QuotedVal is decoded as if it were a C string.
|
||||
QuotedVal = DQ QVBody DQ *WSP Comment
|
||||
|
||||
QVBody = QC
|
||||
QVBody =/ "\" ( "n" / "r" / "t" / "\" / "'" / DQUOTE )
|
||||
QVBOdy =/ "\" ( "x" 2HEXDIG / 1*3OCTDIG )
|
||||
|
||||
; Anything besides NUL and LF
|
||||
NonLF = %x01-%x09 / %x0b - %xff
|
||||
|
||||
; Note that on windows, we open our configuration files in "text" mode,
|
||||
; which causes CRLF pairs to be interpreted as LF. So, on windows:
|
||||
; LF = [ %x0d ] %x0a
|
||||
; but everywhere else,
|
||||
LF = %0x0a
|
||||
|
||||
OCTDIG = '0' - '7'
|
||||
|
||||
KC = Any character except an isspace() character or '#' or NUL
|
||||
VC = Any character except '\\', '\n', '#', or NUL
|
||||
QC = Any character except '\n', '\\', '\"', or NUL
|
||||
|
||||
2. Mid-level Semantics
|
||||
|
||||
|
||||
There are four configuration "domains", from lowest to highest priority:
|
||||
|
||||
* Built-in defaults
|
||||
* The "torrc_defaults" file, if any
|
||||
* The "torrc" file, if any
|
||||
* Arguments provided on the command line, if any.
|
||||
|
||||
Normally, values from high-priority domains override low-priority
|
||||
domains, but see 'magic' below.
|
||||
|
||||
Configuration keys fall into three categories: singletons, lists, and
|
||||
groups.
|
||||
|
||||
A singleton key may appear at most once in any domain. Its
|
||||
corresponding value is equal to its value in the highest-priority
|
||||
domain in which it occurs.
|
||||
|
||||
A list key may appear any number of times in a domain. By default,
|
||||
its corresponding value is equal to all of the values specified for
|
||||
it in the highest-priority domain in which it appears. (See 'magic'
|
||||
below).
|
||||
|
||||
A group key may appear any number of times in a domain. It is
|
||||
associated with a number of other keys in the same group. The
|
||||
relative positions of entries with the keys in a single group
|
||||
matters, but entries with keys not in the group may be freely
|
||||
interspersed. By default, the group has a value equal to all keys
|
||||
and values it contains, from the highest-priority domain in which any
|
||||
of its keys occurs.
|
||||
|
||||
Magic:
|
||||
|
||||
If the '/' flag is specified for an entry, it sets the value for
|
||||
that entry to an empty list. (This will cause a higher-priority
|
||||
domain to clear a list from a lower-priority domain, without
|
||||
actually adding any entries.)
|
||||
|
||||
If the '+' flag is specified for the first entry in a list or a
|
||||
group that appears in a given domain, that list or group is
|
||||
appended to the list or group from the next-lowest-priority
|
||||
domain, rather than replacing it.
|
||||
|
||||
3. High-level semantics
|
||||
|
||||
There are further constraints on the values that each entry can take.
|
||||
These constraints are out-of-scope for this document.
|
||||
|
||||
4. Examples
|
||||
|
||||
(Indentation is removed in this section, to avoid confusion.)
|
||||
|
||||
4.1. Syntax examples
|
||||
|
||||
# Here is a simple configuration entry. The key is "Foo"; the value is
|
||||
# "Bar"
|
||||
|
||||
Foo Bar
|
||||
|
||||
# A configuration entry can have spaces in its value, as below. Here the
|
||||
# key is "Foo" and the value is "Bar Baz"
|
||||
Foo Bar Baz
|
||||
|
||||
# This configuration entry has space at the end of the line, but those
|
||||
# spaces don't count, so the key and value are still "Foo" and "Bar Baz"
|
||||
Foo Bar Baz
|
||||
|
||||
# There can be an escaped newline between the value and the key. This
|
||||
# is another way to say key="Hello", value="World"
|
||||
Hello\
|
||||
World
|
||||
|
||||
# In regular entries of this kind, you can have a comment at the end of
|
||||
# the line, either with a space before it or not. Each of these is a
|
||||
# different spelling of key="Hello", value="World"
|
||||
|
||||
Hello World #today
|
||||
Hello World#tomorrow
|
||||
|
||||
# One way to encode a complex entry is as a C string. This is the same
|
||||
# as key="Hello", value="World!"
|
||||
Hello "World!"
|
||||
|
||||
# The string can contain the usual set of C escapes. This entry has
|
||||
# key="Hello", and value="\"World\"\nand\nuniverse"
|
||||
Hello "\"World\"\nand\nuniverse"
|
||||
|
||||
# And now we get to the more-or-less awful part.
|
||||
#
|
||||
# Multi-line entries ending with a backslash on each line aren't so
|
||||
# bad. The backslash is removed, and everything else is included
|
||||
# verbatim. So this entry has key="Hello" and value="Worldandfriends"
|
||||
Hello\
|
||||
World\
|
||||
and\
|
||||
friends
|
||||
|
||||
# Backslashes in the middle of a line are included as-is. The key of
|
||||
# this one is "Too" and the value is "Many\\Backsl\ashes \here" (with
|
||||
# backslashes in that last string as-is)
|
||||
Too \
|
||||
Many\\\
|
||||
Backsl\ashes \\
|
||||
here
|
||||
|
||||
# And here's the really yucky part. If a comment appears in a multi-line
|
||||
# entry, the entry is still able to continue on the next line, as in the
|
||||
# following, where the key is "This" and the value is
|
||||
# "entry and some are silly"
|
||||
This entry \
|
||||
# has comments \
|
||||
and some \
|
||||
are # generally \
|
||||
silly
|
||||
|
||||
# But you can also write that without the backslashes at the end of the
|
||||
# comment lines. That is to say, this entry is exactly the same as the
|
||||
# one above!
|
||||
This entry \
|
||||
# has comments
|
||||
and some \
|
||||
are # generally
|
||||
silly
|
||||
|
||||
|
||||
|
|
@ -41,8 +41,8 @@ AU_ALIAS([VL_CHECK_SIGN], [AX_CHECK_SIGN])
|
|||
AC_DEFUN([AX_CHECK_SIGN], [
|
||||
typename=`echo $1 | sed "s/@<:@^a-zA-Z0-9_@:>@/_/g"`
|
||||
AC_CACHE_CHECK([whether $1 is signed], ax_cv_decl_${typename}_signed, [
|
||||
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[$4]],
|
||||
[[ int foo @<:@ 1 - 2 * !((($1) -1) < 0) @:>@ ]])],
|
||||
AC_TRY_COMPILE([$4],
|
||||
[ int foo @<:@ 1 - 2 * !((($1) -1) < 0) @:>@ ],
|
||||
[ eval "ax_cv_decl_${typename}_signed=\"yes\"" ],
|
||||
[ eval "ax_cv_decl_${typename}_signed=\"no\"" ])])
|
||||
symbolname=`echo $1 | sed "s/@<:@^a-zA-Z0-9_@:>@/_/g" | tr "a-z" "A-Z"`
|
||||
|
|
|
@ -79,29 +79,32 @@ AC_DEFUN([AC_PC_FROM_UCONTEXT],
|
|||
if ! $pc_field_found; then
|
||||
# Prefer sys/ucontext.h to ucontext.h, for OS X's sake.
|
||||
if test "x$ac_cv_header_cygwin_signal_h" = xyes; then
|
||||
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <cygwin/signal.h>]],
|
||||
[[ucontext_t u; return u.$pc_field == 0;]])],
|
||||
AC_TRY_COMPILE([#define _GNU_SOURCE 1
|
||||
#include <cygwin/signal.h>],
|
||||
[ucontext_t u; return u.$pc_field == 0;],
|
||||
AC_DEFINE_UNQUOTED(PC_FROM_UCONTEXT, $pc_field,
|
||||
How to access the PC from a struct ucontext)
|
||||
AC_MSG_RESULT([$pc_field])
|
||||
pc_field_found=true)
|
||||
elif test "x$ac_cv_header_sys_ucontext_h" = xyes; then
|
||||
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <sys/ucontext.h>]],
|
||||
[[ucontext_t u; return u.$pc_field == 0;]])],
|
||||
AC_TRY_COMPILE([#define _GNU_SOURCE 1
|
||||
#include <sys/ucontext.h>],
|
||||
[ucontext_t u; return u.$pc_field == 0;],
|
||||
AC_DEFINE_UNQUOTED(PC_FROM_UCONTEXT, $pc_field,
|
||||
How to access the PC from a struct ucontext)
|
||||
AC_MSG_RESULT([$pc_field])
|
||||
pc_field_found=true)
|
||||
elif test "x$ac_cv_header_ucontext_h" = xyes; then
|
||||
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <ucontext.h>]],
|
||||
[[ucontext_t u; return u.$pc_field == 0;]])],
|
||||
AC_TRY_COMPILE([#define _GNU_SOURCE 1
|
||||
#include <ucontext.h>],
|
||||
[ucontext_t u; return u.$pc_field == 0;],
|
||||
AC_DEFINE_UNQUOTED(PC_FROM_UCONTEXT, $pc_field,
|
||||
How to access the PC from a struct ucontext)
|
||||
AC_MSG_RESULT([$pc_field])
|
||||
pc_field_found=true)
|
||||
else # hope some standard header gives it to us
|
||||
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]],
|
||||
[[ucontext_t u; return u.$pc_field == 0;]])],
|
||||
AC_TRY_COMPILE([],
|
||||
[ucontext_t u; return u.$pc_field == 0;],
|
||||
AC_DEFINE_UNQUOTED(PC_FROM_UCONTEXT, $pc_field,
|
||||
How to access the PC from a struct ucontext)
|
||||
AC_MSG_RESULT([$pc_field])
|
||||
|
@ -114,8 +117,8 @@ AC_DEFUN([AC_PC_FROM_UCONTEXT],
|
|||
pc_fields="$pc_fields sc_rip" # OpenBSD (x86_64)
|
||||
for pc_field in $pc_fields; do
|
||||
if ! $pc_field_found; then
|
||||
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <signal.h>]],
|
||||
[[ucontext_t u; return u.$pc_field == 0;]])],
|
||||
AC_TRY_COMPILE([#include <signal.h>],
|
||||
[ucontext_t u; return u.$pc_field == 0;],
|
||||
AC_DEFINE_UNQUOTED(PC_FROM_UCONTEXT, $pc_field,
|
||||
How to access the PC from a struct ucontext)
|
||||
AC_MSG_RESULT([$pc_field])
|
||||
|
|
214
m4/pkg.m4
214
m4/pkg.m4
|
@ -1,214 +0,0 @@
|
|||
# pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*-
|
||||
# serial 1 (pkg-config-0.24)
|
||||
#
|
||||
# Copyright © 2004 Scott James Remnant <scott@netsplit.com>.
|
||||
#
|
||||
# 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
#
|
||||
# As a special exception to the GNU General Public License, if you
|
||||
# distribute this file as part of a program that contains a
|
||||
# configuration script generated by Autoconf, you may include it under
|
||||
# the same distribution terms that you use for the rest of that program.
|
||||
|
||||
# PKG_PROG_PKG_CONFIG([MIN-VERSION])
|
||||
# ----------------------------------
|
||||
AC_DEFUN([PKG_PROG_PKG_CONFIG],
|
||||
[m4_pattern_forbid([^_?PKG_[A-Z_]+$])
|
||||
m4_pattern_allow([^PKG_CONFIG(_(PATH|LIBDIR|SYSROOT_DIR|ALLOW_SYSTEM_(CFLAGS|LIBS)))?$])
|
||||
m4_pattern_allow([^PKG_CONFIG_(DISABLE_UNINSTALLED|TOP_BUILD_DIR|DEBUG_SPEW)$])
|
||||
AC_ARG_VAR([PKG_CONFIG], [path to pkg-config utility])
|
||||
AC_ARG_VAR([PKG_CONFIG_PATH], [directories to add to pkg-config's search path])
|
||||
AC_ARG_VAR([PKG_CONFIG_LIBDIR], [path overriding pkg-config's built-in search path])
|
||||
|
||||
if test "x$ac_cv_env_PKG_CONFIG_set" != "xset"; then
|
||||
AC_PATH_TOOL([PKG_CONFIG], [pkg-config])
|
||||
fi
|
||||
if test -n "$PKG_CONFIG"; then
|
||||
_pkg_min_version=m4_default([$1], [0.9.0])
|
||||
AC_MSG_CHECKING([pkg-config is at least version $_pkg_min_version])
|
||||
if $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then
|
||||
AC_MSG_RESULT([yes])
|
||||
else
|
||||
AC_MSG_RESULT([no])
|
||||
PKG_CONFIG=""
|
||||
fi
|
||||
fi[]dnl
|
||||
])# PKG_PROG_PKG_CONFIG
|
||||
|
||||
# PKG_CHECK_EXISTS(MODULES, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])
|
||||
#
|
||||
# Check to see whether a particular set of modules exists. Similar
|
||||
# to PKG_CHECK_MODULES(), but does not set variables or print errors.
|
||||
#
|
||||
# Please remember that m4 expands AC_REQUIRE([PKG_PROG_PKG_CONFIG])
|
||||
# only at the first occurence in configure.ac, so if the first place
|
||||
# it's called might be skipped (such as if it is within an "if", you
|
||||
# have to call PKG_CHECK_EXISTS manually
|
||||
# --------------------------------------------------------------
|
||||
AC_DEFUN([PKG_CHECK_EXISTS],
|
||||
[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
|
||||
if test -n "$PKG_CONFIG" && \
|
||||
AC_RUN_LOG([$PKG_CONFIG --exists --print-errors "$1"]); then
|
||||
m4_default([$2], [:])
|
||||
m4_ifvaln([$3], [else
|
||||
$3])dnl
|
||||
fi])
|
||||
|
||||
# _PKG_CONFIG([VARIABLE], [COMMAND], [MODULES])
|
||||
# ---------------------------------------------
|
||||
m4_define([_PKG_CONFIG],
|
||||
[if test -n "$$1"; then
|
||||
pkg_cv_[]$1="$$1"
|
||||
elif test -n "$PKG_CONFIG"; then
|
||||
PKG_CHECK_EXISTS([$3],
|
||||
[pkg_cv_[]$1=`$PKG_CONFIG --[]$2 "$3" 2>/dev/null`
|
||||
test "x$?" != "x0" && pkg_failed=yes ],
|
||||
[pkg_failed=yes])
|
||||
else
|
||||
pkg_failed=untried
|
||||
fi[]dnl
|
||||
])# _PKG_CONFIG
|
||||
|
||||
# _PKG_SHORT_ERRORS_SUPPORTED
|
||||
# -----------------------------
|
||||
AC_DEFUN([_PKG_SHORT_ERRORS_SUPPORTED],
|
||||
[AC_REQUIRE([PKG_PROG_PKG_CONFIG])
|
||||
if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then
|
||||
_pkg_short_errors_supported=yes
|
||||
else
|
||||
_pkg_short_errors_supported=no
|
||||
fi[]dnl
|
||||
])# _PKG_SHORT_ERRORS_SUPPORTED
|
||||
|
||||
|
||||
# PKG_CHECK_MODULES(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND],
|
||||
# [ACTION-IF-NOT-FOUND])
|
||||
#
|
||||
#
|
||||
# Note that if there is a possibility the first call to
|
||||
# PKG_CHECK_MODULES might not happen, you should be sure to include an
|
||||
# explicit call to PKG_PROG_PKG_CONFIG in your configure.ac
|
||||
#
|
||||
#
|
||||
# --------------------------------------------------------------
|
||||
AC_DEFUN([PKG_CHECK_MODULES],
|
||||
[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
|
||||
AC_ARG_VAR([$1][_CFLAGS], [C compiler flags for $1, overriding pkg-config])dnl
|
||||
AC_ARG_VAR([$1][_LIBS], [linker flags for $1, overriding pkg-config])dnl
|
||||
|
||||
pkg_failed=no
|
||||
AC_MSG_CHECKING([for $1])
|
||||
|
||||
_PKG_CONFIG([$1][_CFLAGS], [cflags], [$2])
|
||||
_PKG_CONFIG([$1][_LIBS], [libs], [$2])
|
||||
|
||||
m4_define([_PKG_TEXT], [Alternatively, you may set the environment variables $1[]_CFLAGS
|
||||
and $1[]_LIBS to avoid the need to call pkg-config.
|
||||
See the pkg-config man page for more details.])
|
||||
|
||||
if test $pkg_failed = yes; then
|
||||
AC_MSG_RESULT([no])
|
||||
_PKG_SHORT_ERRORS_SUPPORTED
|
||||
if test $_pkg_short_errors_supported = yes; then
|
||||
$1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "$2" 2>&1`
|
||||
else
|
||||
$1[]_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "$2" 2>&1`
|
||||
fi
|
||||
# Put the nasty error message in config.log where it belongs
|
||||
echo "$$1[]_PKG_ERRORS" >&AS_MESSAGE_LOG_FD
|
||||
|
||||
m4_default([$4], [AC_MSG_ERROR(
|
||||
[Package requirements ($2) were not met:
|
||||
|
||||
$$1_PKG_ERRORS
|
||||
|
||||
Consider adjusting the PKG_CONFIG_PATH environment variable if you
|
||||
installed software in a non-standard prefix.
|
||||
|
||||
_PKG_TEXT])[]dnl
|
||||
])
|
||||
elif test $pkg_failed = untried; then
|
||||
AC_MSG_RESULT([no])
|
||||
m4_default([$4], [AC_MSG_FAILURE(
|
||||
[The pkg-config script could not be found or is too old. Make sure it
|
||||
is in your PATH or set the PKG_CONFIG environment variable to the full
|
||||
path to pkg-config.
|
||||
|
||||
_PKG_TEXT
|
||||
|
||||
To get pkg-config, see <http://pkg-config.freedesktop.org/>.])[]dnl
|
||||
])
|
||||
else
|
||||
$1[]_CFLAGS=$pkg_cv_[]$1[]_CFLAGS
|
||||
$1[]_LIBS=$pkg_cv_[]$1[]_LIBS
|
||||
AC_MSG_RESULT([yes])
|
||||
$3
|
||||
fi[]dnl
|
||||
])# PKG_CHECK_MODULES
|
||||
|
||||
|
||||
# PKG_INSTALLDIR(DIRECTORY)
|
||||
# -------------------------
|
||||
# Substitutes the variable pkgconfigdir as the location where a module
|
||||
# should install pkg-config .pc files. By default the directory is
|
||||
# $libdir/pkgconfig, but the default can be changed by passing
|
||||
# DIRECTORY. The user can override through the --with-pkgconfigdir
|
||||
# parameter.
|
||||
AC_DEFUN([PKG_INSTALLDIR],
|
||||
[m4_pushdef([pkg_default], [m4_default([$1], ['${libdir}/pkgconfig'])])
|
||||
m4_pushdef([pkg_description],
|
||||
[pkg-config installation directory @<:@]pkg_default[@:>@])
|
||||
AC_ARG_WITH([pkgconfigdir],
|
||||
[AS_HELP_STRING([--with-pkgconfigdir], pkg_description)],,
|
||||
[with_pkgconfigdir=]pkg_default)
|
||||
AC_SUBST([pkgconfigdir], [$with_pkgconfigdir])
|
||||
m4_popdef([pkg_default])
|
||||
m4_popdef([pkg_description])
|
||||
]) dnl PKG_INSTALLDIR
|
||||
|
||||
|
||||
# PKG_NOARCH_INSTALLDIR(DIRECTORY)
|
||||
# -------------------------
|
||||
# Substitutes the variable noarch_pkgconfigdir as the location where a
|
||||
# module should install arch-independent pkg-config .pc files. By
|
||||
# default the directory is $datadir/pkgconfig, but the default can be
|
||||
# changed by passing DIRECTORY. The user can override through the
|
||||
# --with-noarch-pkgconfigdir parameter.
|
||||
AC_DEFUN([PKG_NOARCH_INSTALLDIR],
|
||||
[m4_pushdef([pkg_default], [m4_default([$1], ['${datadir}/pkgconfig'])])
|
||||
m4_pushdef([pkg_description],
|
||||
[pkg-config arch-independent installation directory @<:@]pkg_default[@:>@])
|
||||
AC_ARG_WITH([noarch-pkgconfigdir],
|
||||
[AS_HELP_STRING([--with-noarch-pkgconfigdir], pkg_description)],,
|
||||
[with_noarch_pkgconfigdir=]pkg_default)
|
||||
AC_SUBST([noarch_pkgconfigdir], [$with_noarch_pkgconfigdir])
|
||||
m4_popdef([pkg_default])
|
||||
m4_popdef([pkg_description])
|
||||
]) dnl PKG_NOARCH_INSTALLDIR
|
||||
|
||||
|
||||
# PKG_CHECK_VAR(VARIABLE, MODULE, CONFIG-VARIABLE,
|
||||
# [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])
|
||||
# -------------------------------------------
|
||||
# Retrieves the value of the pkg-config variable for the given module.
|
||||
AC_DEFUN([PKG_CHECK_VAR],
|
||||
[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
|
||||
AC_ARG_VAR([$1], [value of $3 for $2, overriding pkg-config])dnl
|
||||
|
||||
_PKG_CONFIG([$1], [variable="][$3]["], [$2])
|
||||
AS_VAR_COPY([$1], [pkg_cv_][$1])
|
||||
|
||||
AS_VAR_IF([$1], [""], [$5], [$4])dnl
|
||||
])# PKG_CHECK_VAR
|
|
@ -56,8 +56,3 @@ for servers to choose from.
|
|||
codegen/get_mozilla_ciphers.py -- Generate a list of TLS ciphersuites for
|
||||
clients to use in order to look like Firefox.
|
||||
|
||||
Code transformation scripts
|
||||
---------------------------
|
||||
|
||||
coccinelle/calloc.cocci -- Transform code to replace variants of
|
||||
malloc(a*b) with calloc(a,b)
|
||||
|
|
|
@ -1,23 +0,0 @@
|
|||
// Use calloc or realloc as appropriate instead of multiply-and-alloc
|
||||
|
||||
@malloc_to_calloc@
|
||||
identifier f =~ "(tor_malloc|tor_malloc_zero)";
|
||||
expression a;
|
||||
constant b;
|
||||
@@
|
||||
- f(a * b)
|
||||
+ tor_calloc(a, b)
|
||||
|
||||
@calloc_arg_order@
|
||||
expression a;
|
||||
type t;
|
||||
@@
|
||||
- tor_calloc(sizeof(t), a)
|
||||
+ tor_calloc(a, sizeof(t))
|
||||
|
||||
@realloc_to_reallocarray@
|
||||
expression a, b;
|
||||
expression p;
|
||||
@@
|
||||
- tor_realloc(p, a * b)
|
||||
+ tor_reallocarray(p, a, b)
|
|
@ -1,6 +0,0 @@
|
|||
@@
|
||||
expression n, d;
|
||||
@@
|
||||
|
||||
- (((n) + (d) - 1) / (d))
|
||||
+ CEIL_DIV(n, d)
|
|
@ -1,38 +0,0 @@
|
|||
@cast_malloc@
|
||||
expression e;
|
||||
type T;
|
||||
@@
|
||||
- (T *)tor_malloc(e)
|
||||
+ tor_malloc(e)
|
||||
|
||||
@cast_malloc_zero@
|
||||
expression e;
|
||||
type T;
|
||||
identifier func;
|
||||
@@
|
||||
- (T *)tor_malloc_zero(e)
|
||||
+ tor_malloc_zero(e)
|
||||
|
||||
@cast_calloc@
|
||||
expression a, b;
|
||||
type T;
|
||||
identifier func;
|
||||
@@
|
||||
- (T *)tor_calloc(a, b)
|
||||
+ tor_calloc(a, b)
|
||||
|
||||
@cast_realloc@
|
||||
expression e;
|
||||
expression p;
|
||||
type T;
|
||||
@@
|
||||
- (T *)tor_realloc(p, e)
|
||||
+ tor_realloc(p, e)
|
||||
|
||||
@cast_reallocarray@
|
||||
expression a,b;
|
||||
expression p;
|
||||
type T;
|
||||
@@
|
||||
- (T *)tor_reallocarray(p, a, b)
|
||||
+ tor_reallocarray(p, a, b)
|
|
@ -1,11 +0,0 @@
|
|||
#!/usr/bin/perl -w -p -i
|
||||
|
||||
next if m#^ */\*# or m#^ *\* #;
|
||||
|
||||
s/<([,)])/OP_LT$1/;
|
||||
s/(?<=[\s,])>([,)])/OP_GT$1/;
|
||||
#s/>([,)])/OP_GT$1/;
|
||||
s/==([,)])/OP_EQ$1/;
|
||||
s/>=([,)])/OP_GE$1/;
|
||||
s/<=([,)])/OP_LE$1/;
|
||||
s/!=([,)])/OP_NE$1/;
|
|
@ -1,49 +0,0 @@
|
|||
@@
|
||||
int e;
|
||||
constant c;
|
||||
@@
|
||||
|
||||
(
|
||||
- tt_assert(e == c)
|
||||
+ tt_int_op(e, OP_EQ, c)
|
||||
|
|
||||
- tt_assert(e != c)
|
||||
+ tt_int_op(e, OP_NE, c)
|
||||
|
|
||||
- tt_assert(e < c)
|
||||
+ tt_int_op(e, OP_LT, c)
|
||||
|
|
||||
- tt_assert(e <= c)
|
||||
+ tt_int_op(e, OP_LE, c)
|
||||
|
|
||||
- tt_assert(e > c)
|
||||
+ tt_int_op(e, OP_GT, c)
|
||||
|
|
||||
- tt_assert(e >= c)
|
||||
+ tt_int_op(e, OP_GE, c)
|
||||
)
|
||||
|
||||
@@
|
||||
unsigned int e;
|
||||
constant c;
|
||||
@@
|
||||
|
||||
(
|
||||
- tt_assert(e == c)
|
||||
+ tt_uint_op(e, OP_EQ, c)
|
||||
|
|
||||
- tt_assert(e != c)
|
||||
+ tt_uint_op(e, OP_NE, c)
|
||||
|
|
||||
- tt_assert(e < c)
|
||||
+ tt_uint_op(e, OP_LT, c)
|
||||
|
|
||||
- tt_assert(e <= c)
|
||||
+ tt_uint_op(e, OP_LE, c)
|
||||
|
|
||||
- tt_assert(e > c)
|
||||
+ tt_uint_op(e, OP_GT, c)
|
||||
|
|
||||
- tt_assert(e >= c)
|
||||
+ tt_uint_op(e, OP_GE, c)
|
||||
)
|
|
@ -1,11 +0,0 @@
|
|||
@@
|
||||
expression * e;
|
||||
@@
|
||||
|
||||
(
|
||||
- tt_assert(e != NULL)
|
||||
+ tt_ptr_op(e, OP_NE, NULL)
|
||||
|
|
||||
- tt_assert(e == NULL)
|
||||
+ tt_ptr_op(e, OP_EQ, NULL)
|
||||
)
|
|
@ -1,5 +0,0 @@
|
|||
@@
|
||||
@@
|
||||
|
||||
- tt_assert(0)
|
||||
+ tt_abort()
|
|
@ -1,13 +0,0 @@
|
|||
|
||||
@@
|
||||
expression a;
|
||||
@@
|
||||
- tor_calloc(1, a)
|
||||
+ tor_malloc_zero(a)
|
||||
|
||||
@@
|
||||
expression a;
|
||||
@@
|
||||
- tor_calloc(a, 1)
|
||||
+ tor_malloc_zero(a)
|
||||
|
|
@ -1,160 +0,0 @@
|
|||
#!/usr/bin/python
|
||||
|
||||
FUZZERS = """
|
||||
consensus
|
||||
descriptor
|
||||
diff
|
||||
diff-apply
|
||||
extrainfo
|
||||
hsdescv2
|
||||
hsdescv3
|
||||
http
|
||||
http-connect
|
||||
iptsv2
|
||||
microdesc
|
||||
vrs
|
||||
"""
|
||||
|
||||
|
||||
PREAMBLE = r"""
|
||||
FUZZING_CPPFLAGS = \
|
||||
$(src_test_AM_CPPFLAGS) $(TEST_CPPFLAGS)
|
||||
FUZZING_CFLAGS = \
|
||||
$(AM_CFLAGS) $(TEST_CFLAGS)
|
||||
FUZZING_LDFLAG = \
|
||||
@TOR_LDFLAGS_zlib@ @TOR_LDFLAGS_openssl@ @TOR_LDFLAGS_libevent@
|
||||
FUZZING_LIBS = \
|
||||
src/or/libtor-testing.a \
|
||||
src/common/libor-crypto-testing.a \
|
||||
$(LIBKECCAK_TINY) \
|
||||
$(LIBDONNA) \
|
||||
src/common/libor-testing.a \
|
||||
src/common/libor-ctime-testing.a \
|
||||
src/common/libor-event-testing.a \
|
||||
src/trunnel/libor-trunnel-testing.a \
|
||||
$(rust_ldadd) \
|
||||
@TOR_ZLIB_LIBS@ @TOR_LIB_MATH@ \
|
||||
@TOR_LIBEVENT_LIBS@ \
|
||||
@TOR_OPENSSL_LIBS@ @TOR_LIB_WS32@ @TOR_LIB_GDI@ @TOR_LIB_USERENV@ \
|
||||
@CURVE25519_LIBS@ \
|
||||
@TOR_SYSTEMD_LIBS@ \
|
||||
@TOR_LZMA_LIBS@ \
|
||||
@TOR_ZSTD_LIBS@
|
||||
|
||||
oss-fuzz-prereqs: \
|
||||
src/or/libtor-testing.a \
|
||||
src/common/libor-crypto-testing.a \
|
||||
$(LIBKECCAK_TINY) \
|
||||
$(LIBDONNA) \
|
||||
src/common/libor-testing.a \
|
||||
src/common/libor-ctime-testing.a \
|
||||
src/common/libor-event-testing.a \
|
||||
src/trunnel/libor-trunnel-testing.a
|
||||
|
||||
noinst_HEADERS += \
|
||||
src/test/fuzz/fuzzing.h
|
||||
|
||||
LIBFUZZER = -lFuzzer
|
||||
LIBFUZZER_CPPFLAGS = $(FUZZING_CPPFLAGS) -DLLVM_FUZZ
|
||||
LIBFUZZER_CFLAGS = $(FUZZING_CFLAGS)
|
||||
LIBFUZZER_LDFLAG = $(FUZZING_LDFLAG)
|
||||
LIBFUZZER_LIBS = $(FUZZING_LIBS) $(LIBFUZZER) -lstdc++
|
||||
|
||||
LIBOSS_FUZZ_CPPFLAGS = $(FUZZING_CPPFLAGS) -DLLVM_FUZZ
|
||||
LIBOSS_FUZZ_CFLAGS = $(FUZZING_CFLAGS)
|
||||
"""
|
||||
|
||||
POSTAMBLE = r"""
|
||||
noinst_PROGRAMS += $(FUZZERS) $(LIBFUZZER_FUZZERS)
|
||||
noinst_LIBRARIES += $(OSS_FUZZ_FUZZERS)
|
||||
oss-fuzz-fuzzers: oss-fuzz-prereqs $(OSS_FUZZ_FUZZERS)
|
||||
fuzzers: $(FUZZERS) $(LIBFUZZER_FUZZERS)
|
||||
|
||||
test-fuzz-corpora: $(FUZZERS)
|
||||
$(top_srcdir)/src/test/fuzz_static_testcases.sh
|
||||
"""
|
||||
|
||||
########### No user serviceable parts will follow.
|
||||
|
||||
PREAMBLE = PREAMBLE.strip()
|
||||
POSTAMBLE = POSTAMBLE.strip() # If I use it, it's a word!
|
||||
FUZZERS = FUZZERS.split()
|
||||
FUZZERS.sort()
|
||||
|
||||
WARNING = """
|
||||
# This file was generated by fuzzing_include_am.py; do not hand-edit unless
|
||||
# you enjoy having your changes erased.
|
||||
""".strip()
|
||||
|
||||
print(WARNING)
|
||||
|
||||
print(PREAMBLE)
|
||||
|
||||
print("\n# ===== AFL fuzzers")
|
||||
|
||||
def get_id_name(s):
|
||||
return s.replace("-", "_")
|
||||
|
||||
for fuzzer in FUZZERS:
|
||||
idname = get_id_name(fuzzer)
|
||||
print("""\
|
||||
src_test_fuzz_fuzz_{name}_SOURCES = \\
|
||||
src/test/fuzz/fuzzing_common.c \\
|
||||
src/test/fuzz/fuzz_{name}.c
|
||||
src_test_fuzz_fuzz_{name}_CPPFLAGS = $(FUZZING_CPPFLAGS)
|
||||
src_test_fuzz_fuzz_{name}_CFLAGS = $(FUZZING_CFLAGS)
|
||||
src_test_fuzz_fuzz_{name}_LDFLAGS = $(FUZZING_LDFLAG)
|
||||
src_test_fuzz_fuzz_{name}_LDADD = $(FUZZING_LIBS)
|
||||
""".format(name=idname))
|
||||
|
||||
print("FUZZERS = \\")
|
||||
print(" \\\n".join("\tsrc/test/fuzz/fuzz-{name}".format(name=fuzzer)
|
||||
for fuzzer in FUZZERS))
|
||||
|
||||
print("\n# ===== libfuzzer")
|
||||
print("\nif LIBFUZZER_ENABLED")
|
||||
|
||||
for fuzzer in FUZZERS:
|
||||
idname = get_id_name(fuzzer)
|
||||
print("""\
|
||||
src_test_fuzz_lf_fuzz_{name}_SOURCES = \\
|
||||
$(src_test_fuzz_fuzz_{name}_SOURCES)
|
||||
src_test_fuzz_lf_fuzz_{name}_CPPFLAGS = $(LIBFUZZER_CPPFLAGS)
|
||||
src_test_fuzz_lf_fuzz_{name}_CFLAGS = $(LIBFUZZER_CFLAGS)
|
||||
src_test_fuzz_lf_fuzz_{name}_LDFLAGS = $(LIBFUZZER_LDFLAG)
|
||||
src_test_fuzz_lf_fuzz_{name}_LDADD = $(LIBFUZZER_LIBS)
|
||||
""".format(name=idname))
|
||||
|
||||
print("LIBFUZZER_FUZZERS = \\")
|
||||
print(" \\\n".join("\tsrc/test/fuzz/lf-fuzz-{name}".format(name=fuzzer)
|
||||
for fuzzer in FUZZERS))
|
||||
|
||||
print("""
|
||||
else
|
||||
LIBFUZZER_FUZZERS =
|
||||
endif""")
|
||||
|
||||
print("\n# ===== oss-fuzz\n")
|
||||
print("if OSS_FUZZ_ENABLED")
|
||||
|
||||
for fuzzer in FUZZERS:
|
||||
idname = get_id_name(fuzzer)
|
||||
print("""\
|
||||
src_test_fuzz_liboss_fuzz_{name}_a_SOURCES = \\
|
||||
$(src_test_fuzz_fuzz_{name}_SOURCES)
|
||||
src_test_fuzz_liboss_fuzz_{name}_a_CPPFLAGS = $(LIBOSS_FUZZ_CPPFLAGS)
|
||||
src_test_fuzz_liboss_fuzz_{name}_a_CFLAGS = $(LIBOSS_FUZZ_CFLAGS)
|
||||
""".format(name=idname))
|
||||
|
||||
print("OSS_FUZZ_FUZZERS = \\")
|
||||
print(" \\\n".join("\tsrc/test/fuzz/liboss-fuzz-{name}.a".format(name=fuzzer)
|
||||
for fuzzer in FUZZERS))
|
||||
|
||||
print("""
|
||||
else
|
||||
OSS_FUZZ_FUZZERS =
|
||||
endif""")
|
||||
|
||||
print("")
|
||||
|
||||
print(POSTAMBLE)
|
|
@ -1,5 +1,5 @@
|
|||
#!/usr/bin/python
|
||||
# Copyright 2014-2017, The Tor Project, Inc
|
||||
# Copyright 2014, The Tor Project, Inc
|
||||
# See LICENSE for licensing information
|
||||
|
||||
# This script parses openssl headers to find ciphersuite names, determines
|
||||
|
@ -13,13 +13,13 @@ import sys
|
|||
|
||||
EPHEMERAL_INDICATORS = [ "_EDH_", "_DHE_", "_ECDHE_" ]
|
||||
BAD_STUFF = [ "_DES_40_", "MD5", "_RC4_", "_DES_64_",
|
||||
"_SEED_", "_CAMELLIA_", "_NULL",
|
||||
"_CCM_8", "_DES_", ]
|
||||
"_SEED_", "_CAMELLIA_", "_NULL" ]
|
||||
|
||||
# these never get #ifdeffed.
|
||||
MANDATORY = [
|
||||
"TLS1_TXT_DHE_RSA_WITH_AES_256_SHA",
|
||||
"TLS1_TXT_DHE_RSA_WITH_AES_128_SHA",
|
||||
"SSL3_TXT_EDH_RSA_DES_192_CBC3_SHA",
|
||||
]
|
||||
|
||||
def find_ciphers(filename):
|
||||
|
@ -48,23 +48,15 @@ def usable_cipher(ciph):
|
|||
# All fields we sort on, in order of priority.
|
||||
FIELDS = [ 'cipher', 'fwsec', 'mode', 'digest', 'bitlength' ]
|
||||
# Map from sorted fields to recognized value in descending order of goodness
|
||||
FIELD_VALS = { 'cipher' : [ 'AES', 'CHACHA20' ],
|
||||
FIELD_VALS = { 'cipher' : [ 'AES', 'DES'],
|
||||
'fwsec' : [ 'ECDHE', 'DHE' ],
|
||||
'mode' : [ 'POLY1305', 'GCM', 'CCM', 'CBC', ],
|
||||
'digest' : [ 'n/a', 'SHA384', 'SHA256', 'SHA', ],
|
||||
'mode' : [ 'GCM', 'CBC' ],
|
||||
'digest' : [ 'SHA384', 'SHA256', 'SHA' ],
|
||||
'bitlength' : [ '256', '128', '192' ],
|
||||
}
|
||||
|
||||
class Ciphersuite(object):
|
||||
def __init__(self, name, fwsec, cipher, bitlength, mode, digest):
|
||||
if fwsec == 'EDH':
|
||||
fwsec = 'DHE'
|
||||
|
||||
if mode in [ '_CBC3', '_CBC', '' ]:
|
||||
mode = 'CBC'
|
||||
elif mode == '_GCM':
|
||||
mode = 'GCM'
|
||||
|
||||
self.name = name
|
||||
self.fwsec = fwsec
|
||||
self.cipher = cipher
|
||||
|
@ -82,50 +74,42 @@ class Ciphersuite(object):
|
|||
def parse_cipher(ciph):
|
||||
m = re.match('(?:TLS1|SSL3)_TXT_(EDH|DHE|ECDHE)_RSA(?:_WITH)?_(AES|DES)_(256|128|192)(|_CBC|_CBC3|_GCM)_(SHA|SHA256|SHA384)$', ciph)
|
||||
|
||||
if m:
|
||||
fwsec, cipher, bits, mode, digest = m.groups()
|
||||
return Ciphersuite(ciph, fwsec, cipher, bits, mode, digest)
|
||||
if not m:
|
||||
print "/* Couldn't parse %s ! */"%ciph
|
||||
return None
|
||||
|
||||
m = re.match('(?:TLS1|SSL3)_TXT_(EDH|DHE|ECDHE)_RSA(?:_WITH)?_(AES|DES)_(256|128|192)_CCM', ciph)
|
||||
if m:
|
||||
fwsec, cipher, bits = m.groups()
|
||||
return Ciphersuite(ciph, fwsec, cipher, bits, "CCM", "n/a")
|
||||
fwsec, cipher, bits, mode, digest = m.groups()
|
||||
if fwsec == 'EDH':
|
||||
fwsec = 'DHE'
|
||||
|
||||
m = re.match('(?:TLS1|SSL3)_TXT_(EDH|DHE|ECDHE)_RSA(?:_WITH)?_CHACHA20_POLY1305', ciph)
|
||||
if m:
|
||||
fwsec, = m.groups()
|
||||
return Ciphersuite(ciph, fwsec, "CHACHA20", "256", "POLY1305", "n/a")
|
||||
|
||||
print "/* Couldn't parse %s ! */"%ciph
|
||||
return None
|
||||
if mode in [ '_CBC3', '_CBC', '' ]:
|
||||
mode = 'CBC'
|
||||
elif mode == '_GCM':
|
||||
mode = 'GCM'
|
||||
|
||||
return Ciphersuite(ciph, fwsec, cipher, bits, mode, digest)
|
||||
|
||||
ALL_CIPHERS = []
|
||||
|
||||
for fname in sys.argv[1:]:
|
||||
for c in find_ciphers(fname):
|
||||
if usable_cipher(c):
|
||||
parsed = parse_cipher(c)
|
||||
if parsed != None:
|
||||
ALL_CIPHERS.append(parsed)
|
||||
ALL_CIPHERS += (parse_cipher(c)
|
||||
for c in find_ciphers(fname)
|
||||
if usable_cipher(c) )
|
||||
|
||||
ALL_CIPHERS.sort(key=Ciphersuite.sort_key)
|
||||
|
||||
indent = " "*7
|
||||
|
||||
for c in ALL_CIPHERS:
|
||||
if c is ALL_CIPHERS[-1]:
|
||||
colon = ''
|
||||
colon = ';'
|
||||
else:
|
||||
colon = ' ":"'
|
||||
|
||||
if c.name in MANDATORY:
|
||||
print "%s/* Required */"%indent
|
||||
print '%s%s%s'%(indent,c.name,colon)
|
||||
print " /* Required */"
|
||||
print ' %s%s'%(c.name,colon)
|
||||
else:
|
||||
print "#ifdef %s"%c.name
|
||||
print '%s%s%s'%(indent,c.name,colon)
|
||||
print ' %s%s'%(c.name,colon)
|
||||
print "#endif"
|
||||
|
||||
print '%s;'%indent
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#!/usr/bin/python
|
||||
# coding=utf-8
|
||||
# Copyright 2011-2017, The Tor Project, Inc
|
||||
# Copyright 2011, The Tor Project, Inc
|
||||
# original version by Arturo Filastò
|
||||
# See LICENSE for licensing information
|
||||
|
||||
|
@ -29,7 +29,7 @@ def ossl(s):
|
|||
#####
|
||||
# Read the cpp file to understand what Ciphers map to what name :
|
||||
# Make "ciphers" a map from name used in the javascript to a cipher macro name
|
||||
fileA = open(ff('security/manager/ssl/nsNSSComponent.cpp'),'r')
|
||||
fileA = open(ff('security/manager/ssl/src/nsNSSComponent.cpp'),'r')
|
||||
|
||||
# The input format is a file containing exactly one section of the form:
|
||||
# static CipherPref CipherPrefs[] = {
|
||||
|
@ -71,7 +71,7 @@ for line in cipherLines:
|
|||
assert not key_pending
|
||||
key_pending = m.group(1)
|
||||
continue
|
||||
m = re.search(r'^\s*(\S+)(?:,\s*(true|false))+\s*}', line)
|
||||
m = re.search(r'^\s*(\S+)(?:,\s*(true|false))?\s*}', line)
|
||||
if m:
|
||||
assert key_pending
|
||||
key = key_pending
|
||||
|
@ -107,7 +107,7 @@ fileC.close()
|
|||
# Build a map enabled_ciphers from javascript name to "true" or "false",
|
||||
# and an (unordered!) list of the macro names for those ciphers that are
|
||||
# enabled.
|
||||
fileB = open(ff('netwerk/base/security-prefs.js'), 'r')
|
||||
fileB = open(ff('netwerk/base/public/security-prefs.js'), 'r')
|
||||
|
||||
enabled_ciphers = {}
|
||||
for line in fileB:
|
||||
|
@ -127,9 +127,9 @@ for k, v in enabled_ciphers.items():
|
|||
#oSSLinclude = ('/usr/include/openssl/ssl3.h', '/usr/include/openssl/ssl.h',
|
||||
# '/usr/include/openssl/ssl2.h', '/usr/include/openssl/ssl23.h',
|
||||
# '/usr/include/openssl/tls1.h')
|
||||
oSSLinclude = ['ssl3.h', 'ssl.h'
|
||||
'ssl2.h', 'ssl23.h',
|
||||
'tls1.h']
|
||||
oSSLinclude = ('ssl/ssl3.h', 'ssl/ssl.h',
|
||||
'ssl/ssl2.h', 'ssl/ssl23.h',
|
||||
'ssl/tls1.h')
|
||||
|
||||
#####
|
||||
# This reads the hex code for the ciphers that are used by firefox.
|
||||
|
@ -155,12 +155,9 @@ for x in used_ciphers:
|
|||
openssl_macro_by_hex = {}
|
||||
all_openssl_macros = {}
|
||||
for fl in oSSLinclude:
|
||||
fname = ossl("include/openssl/"+fl)
|
||||
if not os.path.exists(fname):
|
||||
continue
|
||||
fp = open(fname, 'r')
|
||||
fp = open(ossl(fl), 'r')
|
||||
for line in fp.readlines():
|
||||
m = re.match('# *define\s+(\S+)\s+(\S+)', line)
|
||||
m = re.match('#define\s+(\S+)\s+(\S+)', line)
|
||||
if m:
|
||||
value,key = m.groups()
|
||||
if key.startswith('0x') and "_CK_" in value:
|
||||
|
|
|
@ -1,351 +0,0 @@
|
|||
#!/usr/bin/python
|
||||
# Copyright 2014-2017, The Tor Project, Inc.
|
||||
# See LICENSE for license information
|
||||
|
||||
# This is a kludgey python script that uses ctypes and openssl to sign
|
||||
# router descriptors and extrainfo documents and put all the keys in
|
||||
# the right places. There are examples at the end of the file.
|
||||
|
||||
# I've used this to make inputs for unit tests. I wouldn't suggest
|
||||
# using it for anything else.
|
||||
|
||||
import base64
|
||||
import binascii
|
||||
import ctypes
|
||||
import ctypes.util
|
||||
import hashlib
|
||||
import optparse
|
||||
import os
|
||||
import re
|
||||
import struct
|
||||
import time
|
||||
import UserDict
|
||||
|
||||
import slow_ed25519
|
||||
import slownacl_curve25519
|
||||
import ed25519_exts_ref
|
||||
|
||||
# Pull in the openssl stuff we need.
|
||||
|
||||
crypt = ctypes.CDLL(ctypes.util.find_library('crypto'))
|
||||
BIO_s_mem = crypt.BIO_s_mem
|
||||
BIO_s_mem.argtypes = []
|
||||
BIO_s_mem.restype = ctypes.c_void_p
|
||||
|
||||
BIO_new = crypt.BIO_new
|
||||
BIO_new.argtypes = [ctypes.c_void_p]
|
||||
BIO_new.restype = ctypes.c_void_p
|
||||
|
||||
crypt.BIO_free.argtypes = [ctypes.c_void_p]
|
||||
crypt.BIO_free.restype = ctypes.c_int
|
||||
|
||||
crypt.BIO_ctrl.argtypes = [ctypes.c_void_p, ctypes.c_int, ctypes.c_long, ctypes.c_void_p ]
|
||||
crypt.BIO_ctrl.restype = ctypes.c_long
|
||||
|
||||
crypt.PEM_write_bio_RSAPublicKey.argtypes = [ ctypes.c_void_p, ctypes.c_void_p ]
|
||||
crypt.PEM_write_bio_RSAPublicKey.restype = ctypes.c_int
|
||||
|
||||
RSA_generate_key = crypt.RSA_generate_key
|
||||
RSA_generate_key.argtypes = [ctypes.c_int, ctypes.c_ulong, ctypes.c_void_p, ctypes.c_void_p]
|
||||
RSA_generate_key.restype = ctypes.c_void_p
|
||||
|
||||
RSA_private_encrypt = crypt.RSA_private_encrypt
|
||||
RSA_private_encrypt.argtypes = [
|
||||
ctypes.c_int, ctypes.c_char_p, ctypes.c_void_p, ctypes.c_void_p, ctypes.c_int ]
|
||||
RSA_private_encrypt.restype = ctypes.c_int
|
||||
|
||||
i2d_RSAPublicKey = crypt.i2d_RSAPublicKey
|
||||
i2d_RSAPublicKey.argtypes = [
|
||||
ctypes.c_void_p, ctypes.POINTER(ctypes.c_char_p)
|
||||
]
|
||||
i2d_RSAPublicKey.restype = ctypes.c_int
|
||||
|
||||
|
||||
def rsa_sign(msg, rsa):
|
||||
buf = ctypes.create_string_buffer(1024)
|
||||
n = RSA_private_encrypt(len(msg), msg, buf, rsa, 1)
|
||||
if n <= 0:
|
||||
raise Exception()
|
||||
return buf.raw[:n]
|
||||
|
||||
def b64(x):
|
||||
x = base64.b64encode(x)
|
||||
res = []
|
||||
for i in xrange(0, len(x), 64):
|
||||
res.append(x[i:i+64]+"\n")
|
||||
return "".join(res)
|
||||
|
||||
def bio_extract(bio):
|
||||
buf = ctypes.c_char_p()
|
||||
length = crypt.BIO_ctrl(bio, 3, 0, ctypes.byref(buf))
|
||||
return ctypes.string_at(buf, length)
|
||||
|
||||
def make_rsa_key(e=65537):
|
||||
rsa = crypt.RSA_generate_key(1024, e, None, None)
|
||||
bio = BIO_new(BIO_s_mem())
|
||||
crypt.PEM_write_bio_RSAPublicKey(bio, rsa)
|
||||
pem = bio_extract(bio).rstrip()
|
||||
crypt.BIO_free(bio)
|
||||
buf = ctypes.create_string_buffer(1024)
|
||||
pBuf = ctypes.c_char_p(ctypes.addressof(buf))
|
||||
n = crypt.i2d_RSAPublicKey(rsa, ctypes.byref(pBuf))
|
||||
s = buf.raw[:n]
|
||||
digest = hashlib.sha1(s).digest()
|
||||
return (rsa,pem,digest)
|
||||
|
||||
def makeEdSigningKeyCert(sk_master, pk_master, pk_signing, date,
|
||||
includeSigning=False, certType=1):
|
||||
assert len(pk_signing) == len(pk_master) == 32
|
||||
expiration = struct.pack("!L", date//3600)
|
||||
if includeSigning:
|
||||
extensions = "\x01\x00\x20\x04\x00%s"%(pk_master)
|
||||
else:
|
||||
extensions = "\x00"
|
||||
signed = "\x01%s%s\x01%s%s" % (
|
||||
chr(certType), expiration, pk_signing, extensions)
|
||||
signature = ed25519_exts_ref.signatureWithESK(signed, sk_master, pk_master)
|
||||
assert len(signature) == 64
|
||||
return signed+signature
|
||||
|
||||
def objwrap(identifier, body):
|
||||
return ("-----BEGIN {0}-----\n"
|
||||
"{1}"
|
||||
"-----END {0}-----").format(identifier, body)
|
||||
|
||||
MAGIC1 = "<<<<<<MAGIC>>>>>>"
|
||||
MAGIC2 = "<<<<<!#!#!#XYZZY#!#!#!>>>>>"
|
||||
|
||||
class OnDemandKeys(object):
|
||||
def __init__(self, certDate=None):
|
||||
if certDate is None:
|
||||
certDate = time.time() + 86400
|
||||
self.certDate = certDate
|
||||
self.rsa_id = None
|
||||
self.rsa_onion_key = None
|
||||
self.ed_id_sk = None
|
||||
self.ntor_sk = None
|
||||
self.ntor_crosscert = None
|
||||
self.rsa_crosscert_ed = None
|
||||
self.rsa_crosscert_noed = None
|
||||
|
||||
@property
|
||||
def RSA_IDENTITY(self):
|
||||
if self.rsa_id is None:
|
||||
self.rsa_id, self.rsa_ident_pem, self.rsa_id_digest = make_rsa_key()
|
||||
|
||||
return self.rsa_ident_pem
|
||||
|
||||
@property
|
||||
def RSA_ID_DIGEST(self):
|
||||
self.RSA_IDENTITY
|
||||
return self.rsa_id_digest
|
||||
|
||||
@property
|
||||
def RSA_FINGERPRINT_NOSPACE(self):
|
||||
return binascii.b2a_hex(self.RSA_ID_DIGEST).upper()
|
||||
|
||||
@property
|
||||
def RSA_ONION_KEY(self):
|
||||
if self.rsa_onion_key is None:
|
||||
self.rsa_onion_key, self.rsa_onion_pem, _ = make_rsa_key()
|
||||
|
||||
return self.rsa_onion_pem
|
||||
|
||||
@property
|
||||
def RSA_FINGERPRINT(self):
|
||||
hexdigest = self.RSA_FINGERPRINT_NOSPACEK
|
||||
return " ".join(hexdigest[i:i+4] for i in range(0,len(hexdigest),4))
|
||||
|
||||
@property
|
||||
def RSA_SIGNATURE(self):
|
||||
return MAGIC1
|
||||
|
||||
@property
|
||||
def ED_SIGNATURE(self):
|
||||
return MAGIC2
|
||||
|
||||
@property
|
||||
def NTOR_ONION_KEY(self):
|
||||
if self.ntor_sk is None:
|
||||
self.ntor_sk = slownacl_curve25519.Private()
|
||||
self.ntor_pk = self.ntor_sk.get_public()
|
||||
return base64.b64encode(self.ntor_pk.serialize())
|
||||
|
||||
@property
|
||||
def ED_CERT(self):
|
||||
if self.ed_id_sk is None:
|
||||
self.ed_id_sk = ed25519_exts_ref.expandSK(os.urandom(32))
|
||||
self.ed_signing_sk = ed25519_exts_ref.expandSK(os.urandom(32))
|
||||
self.ed_id_pk = ed25519_exts_ref.publickeyFromESK(self.ed_id_sk)
|
||||
self.ed_signing_pk = ed25519_exts_ref.publickeyFromESK(self.ed_signing_sk)
|
||||
self.ed_cert = makeEdSigningKeyCert(self.ed_id_sk, self.ed_id_pk, self.ed_signing_pk, self.certDate, includeSigning=True, certType=4)
|
||||
|
||||
return objwrap('ED25519 CERT', b64(self.ed_cert))
|
||||
|
||||
@property
|
||||
def NTOR_CROSSCERT(self):
|
||||
if self.ntor_crosscert is None:
|
||||
self.ED_CERT
|
||||
self.NTOR_ONION_KEY
|
||||
|
||||
ed_privkey = self.ntor_sk.serialize() + os.urandom(32)
|
||||
ed_pub0 = ed25519_exts_ref.publickeyFromESK(ed_privkey)
|
||||
sign = (ord(ed_pub0[31]) & 255) >> 7
|
||||
|
||||
self.ntor_crosscert = makeEdSigningKeyCert(self.ntor_sk.serialize() + os.urandom(32), ed_pub0, self.ed_id_pk, self.certDate, certType=10)
|
||||
self.ntor_crosscert_sign = sign
|
||||
|
||||
return objwrap('ED25519 CERT', b64(self.ntor_crosscert))
|
||||
|
||||
@property
|
||||
def NTOR_CROSSCERT_SIGN(self):
|
||||
self.NTOR_CROSSCERT
|
||||
return self.ntor_crosscert_sign
|
||||
|
||||
@property
|
||||
def RSA_CROSSCERT_NOED(self):
|
||||
if self.rsa_crosscert_noed is None:
|
||||
self.RSA_ONION_KEY
|
||||
signed = self.RSA_ID_DIGEST
|
||||
self.rsa_crosscert_noed = rsa_sign(signed, self.rsa_onion_key)
|
||||
return objwrap("CROSSCERT",b64(self.rsa_crosscert_noed))
|
||||
|
||||
@property
|
||||
def RSA_CROSSCERT_ED(self):
|
||||
if self.rsa_crosscert_ed is None:
|
||||
self.RSA_ONION_KEY
|
||||
self.ED_CERT
|
||||
signed = self.RSA_ID_DIGEST + self.ed_id_pk
|
||||
self.rsa_crosscert_ed = rsa_sign(signed, self.rsa_onion_key)
|
||||
return objwrap("CROSSCERT",b64(self.rsa_crosscert_ed))
|
||||
|
||||
def sign_desc(self, body):
|
||||
idx = body.rfind("\nrouter-sig-ed25519 ")
|
||||
if idx >= 0:
|
||||
self.ED_CERT
|
||||
signed_part = body[:idx+len("\nrouter-sig-ed25519 ")]
|
||||
signed_part = "Tor router descriptor signature v1" + signed_part
|
||||
digest = hashlib.sha256(signed_part).digest()
|
||||
ed_sig = ed25519_exts_ref.signatureWithESK(digest,
|
||||
self.ed_signing_sk, self.ed_signing_pk)
|
||||
|
||||
body = body.replace(MAGIC2, base64.b64encode(ed_sig).replace("=",""))
|
||||
|
||||
idx = body.rindex("\nrouter-signature")
|
||||
end_of_sig = body.index("\n", idx+1)
|
||||
|
||||
signed_part = body[:end_of_sig+1]
|
||||
|
||||
digest = hashlib.sha1(signed_part).digest()
|
||||
assert len(digest) == 20
|
||||
|
||||
rsasig = rsa_sign(digest, self.rsa_id)
|
||||
|
||||
body = body.replace(MAGIC1, objwrap("SIGNATURE", b64(rsasig)))
|
||||
|
||||
return body
|
||||
|
||||
|
||||
def signdesc(body, args_out=None):
|
||||
rsa, ident_pem, id_digest = make_key()
|
||||
_, onion_pem, _ = make_key()
|
||||
|
||||
need_ed = '{ED25519-CERT}' in body or '{ED25519-SIGNATURE}' in body
|
||||
if need_ed:
|
||||
sk_master = os.urandom(32)
|
||||
sk_signing = os.urandom(32)
|
||||
pk_master = slow_ed25519.pubkey(sk_master)
|
||||
pk_signing = slow_ed25519.pubkey(sk_signing)
|
||||
|
||||
hexdigest = binascii.b2a_hex(id_digest).upper()
|
||||
fingerprint = " ".join(hexdigest[i:i+4] for i in range(0,len(hexdigest),4))
|
||||
|
||||
MAGIC = "<<<<<<MAGIC>>>>>>"
|
||||
MORE_MAGIC = "<<<<<!#!#!#XYZZY#!#!#!>>>>>"
|
||||
args = {
|
||||
"RSA-IDENTITY" : ident_pem,
|
||||
"ONION-KEY" : onion_pem,
|
||||
"FINGERPRINT" : fingerprint,
|
||||
"FINGERPRINT-NOSPACE" : hexdigest,
|
||||
"RSA-SIGNATURE" : MAGIC
|
||||
}
|
||||
if need_ed:
|
||||
args['ED25519-CERT'] = makeEdSigningKeyCert(
|
||||
sk_master, pk_master, pk_signing)
|
||||
args['ED25519-SIGNATURE'] = MORE_MAGIC
|
||||
|
||||
if args_out:
|
||||
args_out.update(args)
|
||||
body = body.format(**args)
|
||||
|
||||
idx = body.rindex("\nrouter-signature")
|
||||
end_of_sig = body.index("\n", idx+1)
|
||||
|
||||
signed_part = body[:end_of_sig+1]
|
||||
|
||||
digest = hashlib.sha1(signed_part).digest()
|
||||
assert len(digest) == 20
|
||||
|
||||
buf = ctypes.create_string_buffer(1024)
|
||||
n = RSA_private_encrypt(20, digest, buf, rsa, 1)
|
||||
sig = buf.raw[:n]
|
||||
|
||||
sig = """-----BEGIN SIGNATURE-----
|
||||
%s
|
||||
-----END SIGNATURE-----""" % b64(sig).rstrip()
|
||||
body = body.replace(MAGIC, sig)
|
||||
|
||||
return body.rstrip()
|
||||
|
||||
def print_c_string(ident, body):
|
||||
print "static const char %s[] =" % ident
|
||||
for line in body.split("\n"):
|
||||
print ' "%s\\n"' %(line)
|
||||
print " ;"
|
||||
|
||||
def emit_ri(name, body):
|
||||
info = OnDemandKeys()
|
||||
body = body.format(d=info)
|
||||
body = info.sign_desc(body)
|
||||
print_c_string("EX_RI_%s"%name.upper(), body)
|
||||
|
||||
def emit_ei(name, body):
|
||||
info = OnDemandKeys()
|
||||
body = body.format(d=info)
|
||||
body = info.sign_desc(body)
|
||||
print_c_string("EX_EI_%s"%name.upper(), body)
|
||||
|
||||
print 'const char EX_EI_{NAME}_FP[] = "{d.RSA_FINGERPRINT_NOSPACE}";'.format(
|
||||
d=info, NAME=name.upper())
|
||||
print_c_string("EX_EI_%s_KEY"%name.upper(), info.RSA_IDENTITY)
|
||||
|
||||
def analyze(s):
|
||||
fields = {}
|
||||
while s.startswith(":::"):
|
||||
first,s=s.split("\n", 1)
|
||||
m = re.match(r'^:::(\w+)=(.*)',first)
|
||||
if not m:
|
||||
raise ValueError(first)
|
||||
k,v = m.groups()
|
||||
fields[k] = v
|
||||
return fields, s
|
||||
|
||||
def process_file(s):
|
||||
fields, s = analyze(s)
|
||||
try:
|
||||
name = fields['name']
|
||||
tp = fields['type']
|
||||
except KeyError:
|
||||
raise ValueError("missing required field")
|
||||
|
||||
if tp == 'ei':
|
||||
emit_ei(name, s)
|
||||
elif tp == 'ri':
|
||||
emit_ri(name, s)
|
||||
else:
|
||||
raise ValueError("unrecognized type")
|
||||
|
||||
if __name__ == '__main__':
|
||||
import sys
|
||||
for fn in sys.argv[1:]:
|
||||
process_file(open(fn).read())
|
|
@ -1,17 +0,0 @@
|
|||
#!/bin/sh
|
||||
|
||||
if test "x$TRUNNEL_PATH" != "x"; then
|
||||
PYTHONPATH="${TRUNNEL_PATH}:${PYTHONPATH}"
|
||||
export PYTHONPATH
|
||||
fi
|
||||
|
||||
OPTIONS="--require-version=1.5.1"
|
||||
|
||||
# Get all .trunnel files recursively from that directory so we can support
|
||||
# multiple sub-directories.
|
||||
for file in `find ./src/trunnel/ -name '*.trunnel'`; do
|
||||
python -m trunnel ${OPTIONS} $file
|
||||
done
|
||||
|
||||
python -m trunnel ${OPTIONS} --write-c-files --target-dir=./src/ext/trunnel/
|
||||
|
|
@ -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)
|
||||
|
8
scripts/maint/checkOptionDocs.pl.in → scripts/maint/checkOptionDocs.pl
Normal file → Executable file
8
scripts/maint/checkOptionDocs.pl.in → scripts/maint/checkOptionDocs.pl
Normal file → Executable file
|
@ -7,7 +7,7 @@ my %torrcSampleOptions = ();
|
|||
my %manPageOptions = ();
|
||||
|
||||
# Load the canonical list as actually accepted by Tor.
|
||||
open(F, "@abs_top_builddir@/src/or/tor --list-torrc-options |") or die;
|
||||
open(F, "./src/or/tor --list-torrc-options |") or die;
|
||||
while (<F>) {
|
||||
next if m!\[notice\] Tor v0\.!;
|
||||
if (m!^([A-Za-z0-9_]+)!) {
|
||||
|
@ -34,12 +34,12 @@ sub loadTorrc {
|
|||
0;
|
||||
}
|
||||
|
||||
loadTorrc("@abs_top_srcdir@/src/config/torrc.sample.in", \%torrcSampleOptions);
|
||||
loadTorrc("./src/config/torrc.sample.in", \%torrcSampleOptions);
|
||||
|
||||
# Try to figure out what's in the man page.
|
||||
|
||||
my $considerNextLine = 0;
|
||||
open(F, "@abs_top_srcdir@/doc/tor.1.txt") or die;
|
||||
open(F, "./doc/tor.1.txt") or die;
|
||||
while (<F>) {
|
||||
if (m!^(?:\[\[([A-za-z0-9_]+)\]\] *)?\*\*([A-Za-z0-9_]+)\*\*!) {
|
||||
$manPageOptions{$2} = 1;
|
||||
|
@ -67,3 +67,5 @@ subtractHashes("Orphaned in torrc.sample.in", \%torrcSampleOptions, \%options);
|
|||
|
||||
subtractHashes("Not in man page", \%options, \%manPageOptions);
|
||||
subtractHashes("Orphaned in man page", \%manPageOptions, \%options);
|
||||
|
||||
|
|
@ -1,86 +1,57 @@
|
|||
#!/usr/bin/perl
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
my $found = 0;
|
||||
sub msg {
|
||||
$found = 1;
|
||||
print "$_[0]";
|
||||
}
|
||||
|
||||
my $C = 0;
|
||||
#!/usr/bin/perl -w
|
||||
|
||||
if ($ARGV[0] =~ /^-/) {
|
||||
my $lang = shift @ARGV;
|
||||
$lang = shift @ARGV;
|
||||
$C = ($lang eq '-C');
|
||||
# $TXT = ($lang eq '-txt');
|
||||
}
|
||||
|
||||
for my $fn (@ARGV) {
|
||||
for $fn (@ARGV) {
|
||||
open(F, "$fn");
|
||||
my $lastnil = 0;
|
||||
my $lastline = "";
|
||||
my $incomment = 0;
|
||||
my $in_func_head = 0;
|
||||
$lastnil = 0;
|
||||
$lastline = "";
|
||||
$incomment = 0;
|
||||
while (<F>) {
|
||||
## Warn about windows-style newlines.
|
||||
# (We insist on lines that end with a single LF character, not
|
||||
# CR LF.)
|
||||
if (/\r/) {
|
||||
msg " CR:$fn:$.\n";
|
||||
print " CR:$fn:$.\n";
|
||||
}
|
||||
## Warn about tabs.
|
||||
# (We only use spaces)
|
||||
if (/\t/) {
|
||||
msg " TAB:$fn:$.\n";
|
||||
print " TAB:$fn:$.\n";
|
||||
}
|
||||
## Warn about labels that don't have a space in front of them
|
||||
# (We indent every label at least one space)
|
||||
## Warn about markers that don't have a space in front of them
|
||||
if (/^[a-zA-Z_][a-zA-Z_0-9]*:/) {
|
||||
msg "nosplabel:$fn:$.\n";
|
||||
print "nosplabel:$fn:$.\n";
|
||||
}
|
||||
## Warn about trailing whitespace.
|
||||
# (We don't allow whitespace at the end of the line; make your
|
||||
# editor highlight it for you so you can stop adding it in.)
|
||||
if (/ +$/) {
|
||||
msg "Space\@EOL:$fn:$.\n";
|
||||
print "Space\@EOL:$fn:$.\n";
|
||||
}
|
||||
## Warn about control keywords without following space.
|
||||
# (We put a space after every 'if', 'while', 'for', 'switch', etc)
|
||||
if ($C && /\s(?:if|while|for|switch)\(/) {
|
||||
msg " KW(:$fn:$.\n";
|
||||
print " KW(:$fn:$.\n";
|
||||
}
|
||||
## Warn about #else #if instead of #elif.
|
||||
# (We only allow #elif)
|
||||
if (($lastline =~ /^\# *else/) and ($_ =~ /^\# *if/)) {
|
||||
msg " #else#if:$fn:$.\n";
|
||||
print " #else#if:$fn:$.\n";
|
||||
}
|
||||
## Warn about some K&R violations
|
||||
# (We use K&R-style C, where open braces go on the same line as
|
||||
# the statement that introduces them. In other words:
|
||||
# if (a) {
|
||||
# stuff;
|
||||
# } else {
|
||||
# other stuff;
|
||||
# }
|
||||
if (/^\s+\{/ and $lastline =~ /^\s*(if|while|for|else if)/ and
|
||||
$lastline !~ /\{$/) {
|
||||
msg "non-K&R {:$fn:$.\n";
|
||||
}
|
||||
$lastline !~ /\{$/) {
|
||||
print "non-K&R {:$fn:$.\n";
|
||||
}
|
||||
if (/^\s*else/ and $lastline =~ /\}$/) {
|
||||
msg " }\\nelse:$fn:$.\n";
|
||||
}
|
||||
print " }\\nelse:$fn:$.\n";
|
||||
}
|
||||
$lastline = $_;
|
||||
## Warn about unnecessary empty lines.
|
||||
# (Don't put an empty line before a line that contains nothing
|
||||
# but a closing brace.)
|
||||
if ($lastnil && /^\s*}\n/) {
|
||||
msg " UnnecNL:$fn:$.\n";
|
||||
print " UnnecNL:$fn:$.\n";
|
||||
}
|
||||
## Warn about multiple empty lines.
|
||||
# (At most one blank line in a row.)
|
||||
if ($lastnil && /^$/) {
|
||||
msg " DoubleNL:$fn:$.\n";
|
||||
print " DoubleNL:$fn:$.\n";
|
||||
} elsif (/^$/) {
|
||||
$lastnil = 1;
|
||||
} else {
|
||||
|
@ -88,9 +59,8 @@ for my $fn (@ARGV) {
|
|||
}
|
||||
## Terminals are still 80 columns wide in my world. I refuse to
|
||||
## accept double-line lines.
|
||||
# (Don't make lines wider than 80 characters, including newline.)
|
||||
if (/^.{80}/) {
|
||||
msg " Wide:$fn:$.\n";
|
||||
print " Wide:$fn:$.\n";
|
||||
}
|
||||
### Juju to skip over comments and strings, since the tests
|
||||
### we're about to do are okay there.
|
||||
|
@ -113,52 +83,39 @@ for my $fn (@ARGV) {
|
|||
s!"(?:[^\"]+|\\.)*"!"X"!g;
|
||||
next if /^\#/;
|
||||
## Warn about C++-style comments.
|
||||
# (Use C style comments only.)
|
||||
if (m!//!) {
|
||||
# msg " //:$fn:$.\n";
|
||||
# print " //:$fn:$.\n";
|
||||
s!//.*!!;
|
||||
}
|
||||
## Warn about unquoted braces preceded by non-space.
|
||||
# (No character except a space should come before a {)
|
||||
if (/([^\s'])\{/) {
|
||||
msg " $1\{:$fn:$.\n";
|
||||
print " $1\{:$fn:$.\n";
|
||||
}
|
||||
## Warn about double semi-colons at the end of a line.
|
||||
if (/;;$/) {
|
||||
msg " double semi-colons at the end of $. in $fn\n"
|
||||
}
|
||||
## Warn about multiple internal spaces.
|
||||
#if (/[^\s,:]\s{2,}[^\s\\=]/) {
|
||||
# msg " X X:$fn:$.\n";
|
||||
# print " X X:$fn:$.\n";
|
||||
#}
|
||||
## Warn about { with stuff after.
|
||||
#s/\s+$//;
|
||||
#if (/\{[^\}\\]+$/) {
|
||||
# msg " {X:$fn:$.\n";
|
||||
# print " {X:$fn:$.\n";
|
||||
#}
|
||||
## Warn about function calls with space before parens.
|
||||
# (Don't put a space between the name of a function and its
|
||||
# arguments.)
|
||||
if (/(\w+)\s\(([A-Z]*)/) {
|
||||
if ($1 ne "if" and $1 ne "while" and $1 ne "for" 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 "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 "workqueue_reply_t") {
|
||||
msg " fn ():$fn:$.\n";
|
||||
$1 ne "void" and $1 ne "__attribute__" and $1 ne "op") {
|
||||
print " fn ():$fn:$.\n";
|
||||
}
|
||||
}
|
||||
## Warn about functions not declared at start of line.
|
||||
# (When you're declaring functions, put "static" and "const"
|
||||
# and the return type on one line, and the function name at
|
||||
# the start of a new line.)
|
||||
if ($in_func_head ||
|
||||
($fn !~ /\.h$/ && /^[a-zA-Z0-9_]/ &&
|
||||
! /^(?:const |static )*(?:typedef|struct|union)[^\(]*$/ &&
|
||||
! /= *\{$/ && ! /;$/)) {
|
||||
if (/.\{$/){
|
||||
msg "fn() {:$fn:$.\n";
|
||||
print "fn() {:$fn:$.\n";
|
||||
$in_func_head = 0;
|
||||
} elsif (/^\S[^\(]* +\**[a-zA-Z0-9_]+\(/) {
|
||||
$in_func_head = -1; # started with tp fn
|
||||
|
@ -166,38 +123,16 @@ for my $fn (@ARGV) {
|
|||
$in_func_head = 0;
|
||||
} elsif (/\{/) {
|
||||
if ($in_func_head == -1) {
|
||||
msg "tp fn():$fn:$.\n";
|
||||
print "tp fn():$fn:$.\n";
|
||||
}
|
||||
$in_func_head = 0;
|
||||
}
|
||||
}
|
||||
|
||||
## Check for forbidden functions except when they are
|
||||
# explicitly permitted
|
||||
if (/\bassert\(/ && not /assert OK/) {
|
||||
msg "assert :$fn:$. (use tor_assert)\n";
|
||||
}
|
||||
if (/\bmemcmp\(/ && not /memcmp OK/) {
|
||||
msg "memcmp :$fn:$. (use {tor,fast}_mem{eq,neq,cmp}\n";
|
||||
}
|
||||
# always forbidden.
|
||||
if (not /\ OVERRIDE\ /) {
|
||||
if (/\bstrcat\(/ or /\bstrcpy\(/ or /\bsprintf\(/) {
|
||||
msg "$& :$fn:$.\n";
|
||||
}
|
||||
if (/\bmalloc\(/ or /\bfree\(/ or /\brealloc\(/ or
|
||||
/\bstrdup\(/ or /\bstrndup\(/ or /\bcalloc\(/) {
|
||||
msg "$& :$fn:$. (use tor_malloc, tor_free, etc)\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
## Warn if the file doesn't end with a blank line.
|
||||
# (End each file with a single blank line.)
|
||||
if (! $lastnil) {
|
||||
msg " EOL\@EOF:$fn:$.\n";
|
||||
print " EOL\@EOF:$fn:$.\n";
|
||||
}
|
||||
close(F);
|
||||
}
|
||||
|
||||
exit $found;
|
||||
|
|
|
@ -1,232 +0,0 @@
|
|||
# updateFallbackDirs.py directory mirror blacklist
|
||||
#
|
||||
# Format:
|
||||
# [ IPv4[:DirPort] ] [ orport=<ORPort> ] [ id=<ID> ] ...
|
||||
# [ ipv6=<IPv6>[:<IPv6 ORPort>] ]
|
||||
# or use:
|
||||
# scripts/maint/generateFallbackDirLine.py fingerprint ...
|
||||
#
|
||||
# If a sufficiently specific group of attributes matches, the directory mirror
|
||||
# will be excluded: (each group is listed on its own line)
|
||||
# <IPv4>, <DirPort>
|
||||
# <IPv4>, <ORPort>
|
||||
# <ID>
|
||||
# <IPv6>, <DirPort>
|
||||
# <IPv6>, <IPv6 ORPort>
|
||||
# If DirPort and ORPort are not present, the entire IP address is blacklisted.
|
||||
# (The blacklist overrides the whitelist.)
|
||||
|
||||
# If a relay operator doesn't want their relay to be a FallbackDir,
|
||||
# enter the following information here:
|
||||
# <IPv4>:<DirPort> orport=<ORPort> id=<ID> ipv6=<IPv6>:<IPv6 ORPort>
|
||||
|
||||
# https://lists.torproject.org/pipermail/tor-relays/2015-December/008364.html
|
||||
87.181.248.227:9030 orport=443 id=8827944C4BDCBDAC9079803F47823403C11A9B7A
|
||||
|
||||
# https://lists.torproject.org/pipermail/tor-relays/2015-December/008368.html
|
||||
149.18.2.82:9030 orport=9001 id=953DB709F2A2DECC8D7560661F934E64411444F7
|
||||
|
||||
# https://lists.torproject.org/pipermail/tor-relays/2015-December/008384.html
|
||||
80.82.215.199:80 orport=443 id=3BEFAB76461B6B99DCF34C285E933562F5712AE4 ipv6=[2001:4ba0:cafe:a18::1]:443
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
5.34.183.168:80 orport=443 id=601C92108A568742A7A6D9473FE3A414F7149070
|
||||
217.12.199.208:8080 orport=22 id=BCFB0933367D626715DA32A147F417194A5D48D6
|
||||
|
||||
# https://lists.torproject.org/pipermail/tor-relays/2016-January/008555.html
|
||||
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
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
216.17.99.183:80 orport=443 id=D52CD431CEF28E01B11F545A84347EE45524BCA7
|
||||
216.17.99.183:8080 orport=9001 id=EE21F83AB6F76E3B3FFCBA5C2496F789CB84E7C6
|
||||
65.19.167.130:80 orport=443 id=890E2EA65455FBF0FAAB4159FAC4412BDCB24295
|
||||
65.19.167.131:80 orport=443 id=0DA9BD201766EDB19F57F49F1A013A8A5432C008
|
||||
65.19.167.132:80 orport=443 id=12B80ABF019354A9D25EE8BE85EB3C0AD8F7DFC1
|
||||
65.19.167.133:80 orport=443 id=C170AE5A886C5A09D6D1CF5CF284653632EEF25D
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
213.136.83.225:80 orport=443 id=B411027C926A9BFFCF7DA91E3CAF1856A321EFFD
|
||||
195.154.126.78:80 orport=443 id=F6556156E2B3837248E03FDB770441CF64DBBFBE
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
178.63.198.113:80 orport=443 id=872B18761953254914F77C71846E8A2623C52591
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
63.141.226.34:80 orport=9001 id=5EF131C0C82270F40B756987FDB5D54D9C966238
|
||||
185.75.56.103:80 orport=9001 id=3763CE5C3F574670D4296573744F821C0FFFB98E
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
81.7.14.227:9030 orport=9001 id=BCA197C43A44B7B9D14509637F96A45B13C233D0
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
84.245.32.195:9030 orport=9001 id=4CD4DFFEF3971C902A22100D911CAC639BE2EF5C
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
185.21.217.10:9030 orport=9001 id=41537E1D3DD3CAE86F5A3F0882F1C647FE8FC0A0
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
185.21.216.140:9030 orport=9001 id=921DA852C95141F8964B359F774B35502E489869
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
46.101.220.161:80 orport=443 id=7DDFE5B2C306B19A79832FBE581EAA245BAE90C6 ipv6=[2a03:b0c0:3:d0::8b:3001]:443
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
195.154.107.23:80 orport=443 id=A1F89F26E82209169E4037B035AE7B6C94A49AEB ipv6=[2001:bc8:3829:300::1]:443
|
||||
195.154.92.70:80 orport=443 id=E7FF4ECEEFCFE3A40A6D3594898A4A3DE018BBF5 ipv6=[2001:bc8:3829:500::1]:443
|
||||
195.154.113.200:80 orport=443 id=D1A4763FA0BD71978901B1951FEE1DC29777F95A ipv6=[2001:bc8:3829:600::1]:443
|
||||
195.154.92.155:110 orport=993 id=4477D3466FE136B7FE6F7FF8EBD0D6E2FFE3288B ipv6=[2001:bc8:3829:100::1]:993
|
||||
195.154.117.182:110 orport=993 id=B1A0F1143789466AADD5FAE5948C8138548EECEC ipv6=[2001:bc8:3829:400::1]:993
|
||||
195.154.97.163:80 orport=443 id=8A2994A63B20813B7724817A8FB8C444D10BA2E2
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
5.135.154.206:9030 orport=9001 id=7D67B342DC1158F4CFFEE8BC530A2448848026E3
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
85.24.215.117:9030 orport=9001 id=5989521A85C94EE101E88B8DB2E68321673F9405 ipv6=[2001:9b0:20:2106:21a:4aff:fea5:ad05]:9001
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
62.210.137.230:8888 orport=8843 id=CD6B850159CFF4C068A8D0F1BA5296AE4EDCAB39 ipv6=[2001:bc8:31d3:100::1]:3443
|
||||
62.210.137.230:8080 orport=8443 id=F596E1B1EF98E1DDBBDC934DB722AF54069868F6 ipv6=[2001:bc8:31d3:100::1]:8443
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
195.154.99.80:80 orport=443 id=6E7CB6E783C1B67B79D0EBBE7D48BC09BD441201
|
||||
195.154.127.60:80 orport=443 id=D74ABE34845190E242EC74BA28B8C89B0A480D4B
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
212.51.143.20:80 orport=443 id=62DA0256BBC28992D41CBAFB549FFD7C9B846A99
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
195.154.90.122:80 orport=443 id=3A0D88024A30152E6F6372CFDF8F9B725F984362
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
188.166.118.215:9030 orport=443 id=FB5FF60F5EBA010F8A45AC6ED31A4393718A2C31 ipv6=[2a03:b0c0:2:d0::72:9001]:443
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
185.87.185.245:40001 orport=40000 id=2A499AEEA95FB10F07544383D562368E49BE32CA
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
82.161.109.71:9030 orport=9001 id=BD9CE352648B940E788A8E45393C5400CC3E87E7
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
212.83.40.239:9030 orport=9001 id=6DC5616BD3FC463329DCE87DD7AAAEA112C264B5
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
178.32.53.53:80 orport=443 id=10582C360E972EE76B0DB1C246F4E892A6BF5465
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
85.114.135.20:9030 orport=9001 id=ED8A9291A3139E34BBD35037B082081EC6C26C80 ipv6=[2001:4ba0:fff5:2d::8]:9001
|
||||
148.251.128.156:9030 orport=9001 id=E382042E06A0A68AFC533E5AD5FB6867A12DF9FF ipv6=[2a01:4f8:210:238a::8]:9001
|
||||
62.210.115.147:9030 orport=9001 id=7F1D94E2C36F8CC595C2AB00022A5AE38171D50B ipv6=[2001:bc8:3182:101::8]:9001
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
74.208.220.222:60000 orport=59999 id=4AA22235F0E9B3795A33930343CBB3EDAC60C5B0
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
89.163.140.168:9030 orport=9001 id=839C1212DB15723263BE96C83DA7E1B24FA395E8
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
212.47.246.211:9030 orport=9001 id=AA34219475E41282095DD3C088009EE562AF14E5
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
85.195.235.148:9030 orport=9001 id=103336165A0D2EFCAD3605339843A0A7710B8B92
|
||||
85.195.235.148:19030 orport=19001 id=713235638AB6C64715EAFD1B4772685E38AFD52A
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
163.172.7.30:9030 orport=9001 id=E2EACD4752B2583202F374A34CACC844A3AECAC4
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
178.62.90.111:22 orport=25 id=3254D1DC1F1531D9C07C535E4991F38EE99B99E1
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
213.200.106.131:9030 orport=4443 id=B07CE79FD215129C381F6645B16E76DCA0845CAB
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
198.51.75.165:80 orport=9001 id=DABCB84A524A22FDDD3AFCB090E3090CC12D9770
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
204.194.29.4:80 orport=9001 id=78C7C299DB4C4BD119A22B87B57D5AF5F3741A79
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
104.207.132.109:9030 orport=9001 id=12D5737383C23E756A7AA1A90BB24413BA428DA7 ipv6=[2001:19f0:300:2261::1]:9001
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
46.252.25.249:9030 orport=443 id=80DCBB6EF4E86A7CD4FBCBDEE64979645509A610
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
176.10.99.200:8080 orport=443 id=2B44FD1742D26E4F28D4CACF1F0CF8A686270E45
|
||||
176.10.99.200:8000 orport=22 id=EB79F07792A065D3C534063773E83268E069F5EB
|
||||
176.10.99.201:667 orport=666 id=3EAAAB35932610411E24FA4317603CB5780B80BC
|
||||
176.10.99.201:990 orport=989 id=7C3A4CFF09C1981D41173CDE2A2ADD4A5CA109FD
|
||||
176.10.99.202:992 orport=991 id=615EBC4B48F03858FA50A3E23E5AF569D0D2308A
|
||||
176.10.99.202:994 orport=993 id=E34E25D958D46DDE5092385B14117C9B301DC0E9
|
||||
176.10.99.203:1194 orport=995 id=AD368442E9FF33C08C7407DF2DA7DB958F406CE2
|
||||
176.10.99.203:43 orport=53 id=79CF377F0ACEC5F0002D85335E4192B34202A269
|
||||
176.10.99.204:1755 orport=1723 id=69DF3CDA1CDA460C17ECAD9D6F0C117A42384FA0
|
||||
176.10.99.204:1293 orport=4321 id=3F061400B6FB1F55E7F19BB3C713884D677E55B7
|
||||
176.10.99.205:426 orport=425 id=C30B284784BF11D0D58C6A250240EE58D2084AD0
|
||||
176.10.99.205:109 orport=110 id=12D17D9F9E30FA901DE68806950A0EA278716CED
|
||||
176.10.99.206:24 orport=23 id=2C804AAB0C02F971A4386B3A1F2AC00F9E080679
|
||||
176.10.99.206:20 orport=21 id=237588726AB6BEA37FF23CA00F5BD178586CA68E
|
||||
176.10.99.207:3390 orport=3389 id=A838D5B8890B10172429ECE92EB5677DF93DC4DD
|
||||
176.10.99.207:1415 orport=1414 id=377E5E817A84FAE0F4DC3427805DB2E8A6CBBFC0
|
||||
176.10.99.208:390 orport=389 id=7C288587BA0D99CC6B8537CDC2C4639FA827B907
|
||||
176.10.99.208:3307 orport=3306 id=1F0D2A44C56F42816DED2022EFD631878C29905B
|
||||
176.10.99.209:1434 orport=1433 id=BDA7A91FF3806DE5109FDAE74CFEFB3BABB9E10F
|
||||
176.10.99.209:220 orport=219 id=B8C2030001D832066A648269CFBA94171951D34B
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
78.193.40.205:8080 orport=8443 id=C91450840E75AC1B654A3096744338A573A239C6
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
37.187.22.172:9030 orport=9035 id=335E4117BD9A4966403C2AFA31CFDD1BC13BD46A
|
||||
|
||||
# https://lists.torproject.org/pipermail/tor-relays/2015-December/008367.html
|
||||
# Email sent directly to teor to opt-out
|
||||
88.198.38.226:22 orport=443 id=4B9E2C56FB42B891794FE2CD2FCAD08A320CC3BB ipv6=[2a01:4f8:a0:1351::2]:80
|
||||
213.239.210.204:22 orport=443 id=5BFDECCE9B4A23AE14EC767C5A2C1E10558B00B9 ipv6=[2a01:4f8:a0:9474::2]:80
|
||||
213.239.220.25:22 orport=443 id=BEE2317AE127EB681C5AE1551C1EA0630580638A ipv6=[2a01:4f8:a0:710c::2]:80
|
||||
85.10.201.38:22 orport=443 id=F6279A203C1950ACF592322A235647A05BFBCF91 ipv6=[2a01:4f8:a0:43cc::2]:80
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
88.190.208.4:30555 orport=30556 id=030A6EB24725C05D8E0FCE21923CBA5223E75E0E
|
||||
|
||||
# Fallback was on 0.2.8.2-alpha list, but opted-out before 0.2.8.6
|
||||
37.187.1.149:9030 orport=9001 id=08DC0F3C6E3D9C527C1FC8745D35DD1B0DE1875D ipv6=[2001:41d0:a:195::1]:9001
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
195.154.15.227:9030 orport=9001 id=6C3E3AB2F5F03CD71B637D433BAD924A1ECC5796
|
||||
|
||||
# Fallback was on 0.2.8.6 list, but opted-out before 0.2.9
|
||||
144.76.73.140:9030 orport=9001 id=6A640018EABF3DA9BAD9321AA37C2C87BBE1F907
|
||||
|
||||
# https://lists.torproject.org/pipermail/tor-relays/2016-December/011114.html
|
||||
# no dirport
|
||||
86.107.110.34:0 orport=9001 id=A0E3D30A660DB70CA0B6D081BA54D094DED6F28D
|
||||
94.242.59.147:80 orport=9001 id=674DCBB0D9C1C4C4DBFB4A9AE024AF59FE4E7F46 ipv6=[2a00:1838:35:42::b648]:9001
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
167.114.152.100:9030 orport=443 id=0EF5E5FFC5D1EABCBDA1AFF6F6D6325C5756B0B2 ipv6=[2607:5300:100:200::1608]:443
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
163.172.35.245:80 orport=443 id=B771AA877687F88E6F1CA5354756DF6C8A7B6B24
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
104.243.35.196:9030 orport=9001 id=FA3415659444AE006E7E9E5375E82F29700CFDFD
|
||||
|
||||
# Emails sent directly to teor, verified using relay contact info
|
||||
217.12.199.208:80 orport=443 id=DF3AED4322B1824BF5539AE54B2D1B38E080FF05 ipv6=[2a02:27a8:0:2::7e]:443
|
||||
|
||||
# Emails sent directly to teor, verified using relay contact info
|
||||
195.154.75.84:9030 orport=9001 id=F80FDE27EFCB3F6A7B4E2CC517133DBFFA78BA2D
|
||||
195.154.127.246:9030 orport=9001 id=4FEE77AFFD157BBCF2D896AE417FBF647860466C
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
5.35.251.247:9030 orport=9001 id=9B1F5187DFBA89DC24B37EA7BF896C12B43A27AE
|
||||
|
||||
#https://lists.torproject.org/pipermail/tor-relays/2017-May/012281.html
|
||||
62.210.124.124:9030 orport=9001 id=86E78DD3720C78DA8673182EF96C54B162CD660C ipv6=[2001:bc8:3f23:100::1]:9001
|
||||
62.210.124.124:9130 orport=9101 id=2EBD117806EE43C3CC885A8F1E4DC60F207E7D3E ipv6=[2001:bc8:3f23:100::1]:9101
|
||||
|
||||
# Email sent directly to teor
|
||||
212.51.156.193:995 orport=110 id=32E7AAF1F602814D699BEF6761AD03E387758D49 ipv6=[2a02:168:4a01::49]:110
|
|
@ -1,996 +0,0 @@
|
|||
# updateFallbackDirs.py directory mirror whitelist
|
||||
#
|
||||
# Format:
|
||||
# IPv4:DirPort orport=<ORPort> id=<ID> [ ipv6=<IPv6>:<IPv6 ORPort> ]
|
||||
# or use:
|
||||
# scripts/maint/generateFallbackDirLine.py fingerprint ...
|
||||
#
|
||||
# All attributes must match for the directory mirror to be included.
|
||||
# If the fallback has an ipv6 key, the whitelist line must also have
|
||||
# it, and vice versa, otherwise they don't match.
|
||||
# (The blacklist overrides the whitelist.)
|
||||
|
||||
# To replace this list with the hard-coded fallback list (for testing), use
|
||||
# a command similar to:
|
||||
# cat src/or/fallback_dirs.inc | grep \" | grep -v weight | tr -d '\n' | \
|
||||
# sed 's/"" / /g' | sed 's/""/"/g' | tr \" '\n' | grep -v '^$' \
|
||||
# > scripts/maint/fallback.whitelist
|
||||
#
|
||||
# When testing before a release, exclusions due to changed details will result
|
||||
# in a warning, unless the IPv4 address or port change happened recently.
|
||||
# Then it is only logged at info level, as part of the eligibility check.
|
||||
# Exclusions due to stability also are only shown at info level.
|
||||
#
|
||||
# Add the number of selected, slow, and excluded relays, and compare that to
|
||||
# the number of hard-coded relays. If it's less, use info-level logs to find
|
||||
# out why each of the missing relays was excluded.
|
||||
|
||||
# If a relay operator wants their relay to be a FallbackDir,
|
||||
# enter the following information here:
|
||||
# <IPv4>:<DirPort> orport=<ORPort> id=<ID> [ ipv6=<IPv6>:<IPv6 ORPort> ]
|
||||
|
||||
# https://lists.torproject.org/pipermail/tor-relays/2015-December/008362.html
|
||||
# https://trac.torproject.org/projects/tor/ticket/22321#comment:22
|
||||
78.47.18.110:443 orport=80 id=F8D27B163B9247B232A2EEE68DD8B698695C28DE ipv6=[2a01:4f8:120:4023::110]:80 # fluxe3
|
||||
131.188.40.188:1443 orport=80 id=EBE718E1A49EE229071702964F8DB1F318075FF8 ipv6=[2001:638:a000:4140::ffff:188]:80 # fluxe4
|
||||
|
||||
# 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
|
||||
|
||||
# https://lists.torproject.org/pipermail/tor-relays/2015-December/008370.html
|
||||
# https://lists.torproject.org/pipermail/tor-relays/2016-January/008517.html
|
||||
# https://lists.torproject.org/pipermail/tor-relays/2016-January/008555.html
|
||||
212.47.237.95:9030 orport=9001 id=3F5D8A879C58961BB45A3D26AC41B543B40236D6
|
||||
212.47.237.95:9130 orport=9101 id=6FB38EB22E57EF7ED5EF00238F6A48E553735D88
|
||||
|
||||
# https://lists.torproject.org/pipermail/tor-relays/2015-December/008372.html
|
||||
# IPv6 tunnel available on request (is this a good idea?)
|
||||
108.53.208.157:80 orport=443 id=4F0DB7E687FC7C0AE55C8F243DA8B0EB27FBF1F2
|
||||
|
||||
# https://lists.torproject.org/pipermail/tor-relays/2015-December/008373.html
|
||||
167.114.35.28:9030 orport=9001 id=E65D300F11E1DB12C534B0146BDAB6972F1A8A48
|
||||
|
||||
# https://lists.torproject.org/pipermail/tor-relays/2015-December/008378.html
|
||||
144.76.14.145:110 orport=143 id=14419131033443AE6E21DA82B0D307F7CAE42BDB ipv6=[2a01:4f8:190:9490::dead]:443
|
||||
|
||||
# https://lists.torproject.org/pipermail/tor-relays/2015-December/008379.html
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
91.121.84.137:4951 orport=4051 id=6DE61A6F72C1E5418A66BFED80DFB63E4C77668F
|
||||
91.121.84.137:4952 orport=4052 id=9FBEB75E8BC142565F12CBBE078D63310236A334
|
||||
|
||||
# https://lists.torproject.org/pipermail/tor-relays/2015-December/008381.html
|
||||
# Sent additional emails to teor with updated relays
|
||||
81.7.11.96:9030 orport=9001 id=8FA37B93397015B2BC5A525C908485260BE9F422 # Doedel22
|
||||
# 9F5068310818ED7C70B0BC4087AB55CB12CB4377 not found in current consensus
|
||||
178.254.19.101:80 orport=443 id=F9246DEF2B653807236DA134F2AEAB103D58ABFE # Freebird31
|
||||
178.254.19.101:9030 orport=9001 id=0C475BA4D3AA3C289B716F95954CAD616E50C4E5 # Freebird32
|
||||
81.7.14.253:9001 orport=443 id=1AE039EE0B11DB79E4B4B29CBA9F752864A0259E # Ichotolot60
|
||||
81.7.11.186:1080 orport=443 id=B86137AE9681701901C6720E55C16805B46BD8E3 # BeastieJoy60
|
||||
85.25.213.211:465 orport=80 id=CE47F0356D86CF0A1A2008D97623216D560FB0A8 # BeastieJoy61
|
||||
85.25.159.65:995 orport=80 id=52BFADA8BEAA01BA46C8F767F83C18E2FE50C1B9 # BeastieJoy63
|
||||
81.7.3.67:993 orport=443 id=A2E6BB5C391CD46B38C55B4329C35304540771F1 # BeastieJoy62
|
||||
81.7.14.31:9001 orport=443 id=7600680249A22080ECC6173FBBF64D6FCF330A61 # Ichotolot62
|
||||
|
||||
# https://lists.torproject.org/pipermail/tor-relays/2015-December/008382.html
|
||||
51.255.33.237:9091 orport=9001 id=A360C21FA87FFA2046D92C17086A6B47E5C68109
|
||||
|
||||
# https://lists.torproject.org/pipermail/tor-relays/2015-December/008383.html
|
||||
81.7.14.246:80 orport=443 id=CE75BF0972ADD52AF8807602374E495C815DB304 ipv6=[2a02:180:a:51::dead]:443
|
||||
|
||||
# https://lists.torproject.org/pipermail/tor-relays/2015-December/008384.html
|
||||
# Sent additional email to teor with fingerprint change
|
||||
149.202.98.161:80 orport=443 id=FC64CD763F8C1A319BFBBF62551684F4E1E42332 ipv6=[2001:41d0:8:4528::161]:443
|
||||
193.111.136.162:80 orport=443 id=C79552275DFCD486B942510EF663ED36ACA1A84B ipv6=[2001:4ba0:cafe:10d0::1]:443
|
||||
|
||||
# https://lists.torproject.org/pipermail/tor-relays/2015-December/008416.html
|
||||
185.100.84.212:80 orport=443 id=330CD3DB6AD266DC70CDB512B036957D03D9BC59 ipv6=[2a06:1700:0:7::1]:443
|
||||
|
||||
# https://lists.torproject.org/pipermail/tor-relays/2015-December/008417.html
|
||||
178.16.208.56:80 orport=443 id=2CDCFED0142B28B002E89D305CBA2E26063FADE2 ipv6=[2a00:1c20:4089:1234:cd49:b58a:9ebe:67ec]:443
|
||||
178.16.208.57:80 orport=443 id=92CFD9565B24646CAC2D172D3DB503D69E777B8A ipv6=[2a00:1c20:4089:1234:7825:2c5d:1ecd:c66f]:443
|
||||
|
||||
# https://lists.torproject.org/pipermail/tor-relays/2016-January/008513.html
|
||||
178.62.173.203:9030 orport=9001 id=DD85503F2D1F52EF9EAD621E942298F46CD2FC10 ipv6=[2a03:b0c0:0:1010::a4:b001]:9001
|
||||
|
||||
# https://lists.torproject.org/pipermail/tor-relays/2016-January/008534.html
|
||||
5.9.110.236:9030 orport=9001 id=0756B7CD4DFC8182BE23143FAC0642F515182CEB ipv6=[2a01:4f8:162:51e2::2]:9001
|
||||
|
||||
# https://lists.torproject.org/pipermail/tor-relays/2016-January/008542.html
|
||||
178.62.199.226:80 orport=443 id=CBEFF7BA4A4062045133C053F2D70524D8BBE5BE ipv6=[2a03:b0c0:2:d0::b7:5001]:443
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
94.23.204.175:9030 orport=9001 id=5665A3904C89E22E971305EE8C1997BCA4123C69
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
171.25.193.77:80 orport=443 id=A10C4F666D27364036B562823E5830BC448E046A ipv6=[2001:67c:289c:3::77]:443
|
||||
171.25.193.78:80 orport=443 id=A478E421F83194C114F41E94F95999672AED51FE ipv6=[2001:67c:289c:3::78]:443
|
||||
171.25.193.20:80 orport=443 id=DD8BD7307017407FCC36F8D04A688F74A0774C02 ipv6=[2001:67c:289c::20]:443
|
||||
# same machine as DD8BD7307017407FCC36F8D04A688F74A0774C02
|
||||
171.25.193.25:80 orport=443 id=185663B7C12777F052B2C2D23D7A239D8DA88A0F ipv6=[2001:67c:289c::25]:443
|
||||
|
||||
# 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
|
||||
93.115.97.242:9030 orport=9001 id=B5212DB685A2A0FCFBAE425738E478D12361710D
|
||||
46.28.109.231:9030 orport=9001 id=F70B7C5CD72D74C7F9F2DC84FA9D20D51BA13610 ipv6=[2a02:2b88:2:1::4205:1]:9001
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
85.235.250.88:80 orport=443 id=72B2B12A3F60408BDBC98C6DF53988D3A0B3F0EE # TykRelay01
|
||||
185.96.88.29:80 orport=443 id=86C281AD135058238D7A337D546C902BE8505DDE # TykRelay051
|
||||
# This fallback opted-in in previous releases, then changed its details,
|
||||
# and so we blacklisted it. Now we want to whitelist changes.
|
||||
# Assume details update is permanent
|
||||
185.96.180.29:80 orport=443 id=F93D8F37E35C390BCAD9F9069E13085B745EC216 # TykRelay06
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
185.11.180.67:80 orport=9001 id=794D8EA8343A4E820320265D05D4FA83AB6D1778
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
178.16.208.62:80 orport=443 id=5CF8AFA5E4B0BB88942A44A3F3AAE08C3BDFD60B ipv6=[2a00:1c20:4089:1234:a6a4:2926:d0af:dfee]:443
|
||||
46.165.221.166:80 orport=443 id=EE5F897C752D46BCFF531641B853FC6BC78DD4A7
|
||||
178.16.208.60:80 orport=443 id=B44FBE5366AD98B46D829754FA4AC599BAE41A6A ipv6=[2a00:1c20:4089:1234:67bc:79f3:61c0:6e49]:443
|
||||
178.16.208.55:80 orport=443 id=C4AEA05CF380BAD2230F193E083B8869B4A29937 ipv6=[2a00:1c20:4089:1234:7b2c:11c5:5221:903e]:443
|
||||
178.16.208.61:80 orport=443 id=3B52392E2256C35CDCF7801FF898FC88CE6D431A ipv6=[2a00:1c20:4089:1234:2712:a3d0:666b:88a6]:443
|
||||
81.89.96.88:80 orport=443 id=55ED4BB49F6D3F36D8D9499BE43500E017A5EF82 ipv6=[2a02:180:1:1:14c5:b0b7:2d7d:5f3a]:443
|
||||
209.222.8.196:80 orport=443 id=C86D2F3DEFE287A0EEB28D4887AF14E35C172733 ipv6=[2001:19f0:1620:41c1:426c:5adf:2ed5:4e88]:443
|
||||
81.89.96.89:80 orport=443 id=28651F419F5A1CF74511BB500C58112192DD4943 ipv6=[2a02:180:1:1:2ced:24e:32ea:a03b]:443
|
||||
46.165.221.166:9030 orport=9001 id=8C7106C880FE8AA1319DD71B59623FCB8914C9F1
|
||||
178.16.208.62:80 orport=443 id=5CF8AFA5E4B0BB88942A44A3F3AAE08C3BDFD60B ipv6=[2a00:1c20:4089:1234:a6a4:2926:d0af:dfee]:443"
|
||||
46.165.221.166:80 orport=443 id=EE5F897C752D46BCFF531641B853FC6BC78DD4A7
|
||||
178.16.208.60:80 orport=443 id=B44FBE5366AD98B46D829754FA4AC599BAE41A6A ipv6=[2a00:1c20:4089:1234:67bc:79f3:61c0:6e49]:443
|
||||
178.16.208.55:80 orport=443 id=C4AEA05CF380BAD2230F193E083B8869B4A29937 ipv6=[2a00:1c20:4089:1234:7b2c:11c5:5221:903e]:443
|
||||
178.16.208.61:80 orport=443 id=3B52392E2256C35CDCF7801FF898FC88CE6D431A ipv6=[2a00:1c20:4089:1234:2712:a3d0:666b:88a6]:443
|
||||
81.89.96.88:80 orport=443 id=55ED4BB49F6D3F36D8D9499BE43500E017A5EF82 ipv6=[2a02:180:1:1:14c5:b0b7:2d7d:5f3a]:443
|
||||
209.222.8.196:80 orport=443 id=C86D2F3DEFE287A0EEB28D4887AF14E35C172733 ipv6=[2001:19f0:1620:41c1:426c:5adf:2ed5:4e88]:443
|
||||
81.89.96.89:80 orport=443 id=28651F419F5A1CF74511BB500C58112192DD4943 ipv6=[2a02:180:1:1:2ced:24e:32ea:a03b]:443
|
||||
46.165.221.166:9030 orport=9001 id=8C7106C880FE8AA1319DD71B59623FCB8914C9F1
|
||||
178.16.208.56:80 orport=443 id=2CDCFED0142B28B002E89D305CBA2E26063FADE2 ipv6=[2a00:1c20:4089:1234:cd49:b58a:9ebe:67ec]:443
|
||||
178.16.208.58:80 orport=443 id=A4C98CEA3F34E05299417E9F885A642C88EF6029 ipv6=[2a00:1c20:4089:1234:cdae:1b3e:cc38:3d45]:443
|
||||
178.16.208.57:80 orport=443 id=92CFD9565B24646CAC2D172D3DB503D69E777B8A ipv6=[2a00:1c20:4089:1234:7825:2c5d:1ecd:c66f]:443
|
||||
178.16.208.59:80 orport=443 id=136F9299A5009A4E0E96494E723BDB556FB0A26B ipv6=[2a00:1c20:4089:1234:bff6:e1bb:1ce3:8dc6]:443
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
5.39.76.158:80 orport=443 id=C41F60F8B00E7FEF5CCC5BC6BB514CA1B8AAB651
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
109.163.234.2:80 orport=443 id=14F92FF956105932E9DEC5B82A7778A0B1BD9A52
|
||||
109.163.234.4:80 orport=443 id=4888770464F0E900EFEF1BA181EA873D13F7713C
|
||||
109.163.234.5:80 orport=443 id=5EB8D862E70981B8690DEDEF546789E26AB2BD24
|
||||
109.163.234.7:80 orport=443 id=23038A7F2845EBA2234ECD6651BD4A7762F51B18
|
||||
109.163.234.8:80 orport=443 id=0818DAE0E2DDF795AEDEAC60B15E71901084F281
|
||||
109.163.234.9:80 orport=443 id=ABF7FBF389C9A747938B639B20E80620B460B2A9
|
||||
62.102.148.67:80 orport=443 id=4A0C3E177AF684581EF780981AEAF51A98A6B5CF
|
||||
# Assume details update is permanent
|
||||
77.247.181.166:80 orport=443 id=77131D7E2EC1CA9B8D737502256DA9103599CE51 # CriticalMass
|
||||
77.247.181.164:80 orport=443 id=204DFD2A2C6A0DC1FA0EACB495218E0B661704FD # HaveHeart
|
||||
77.247.181.162:80 orport=443 id=7BFB908A3AA5B491DA4CA72CCBEE0E1F2A939B55 # sofia
|
||||
|
||||
# https://twitter.com/biotimylated/status/718994247500718080
|
||||
212.47.252.149:9030 orport=9001 id=2CAC39BAA996791CEFAADC9D4754D65AF5EB77C0
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
46.165.230.5:80 orport=443 id=A0F06C2FADF88D3A39AA3072B406F09D7095AC9E
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
94.242.246.24:23 orport=8080 id=EC116BCB80565A408CE67F8EC3FE3B0B02C3A065 ipv6=[2a01:608:ffff:ff07::1:24]:9004
|
||||
176.126.252.11:443 orport=9001 id=B0279A521375F3CB2AE210BDBFC645FDD2E1973A ipv6=[2a02:59e0:0:7::11]:9003
|
||||
176.126.252.12:21 orport=8080 id=379FB450010D17078B3766C2273303C358C3A442 ipv6=[2a02:59e0:0:7::12]:81
|
||||
94.242.246.23:443 orport=9001 id=F65E0196C94DFFF48AFBF2F5F9E3E19AAE583FD0 ipv6=[2a01:608:ffff:ff07::1:23]:9003
|
||||
85.248.227.164:444 orport=9002 id=B84F248233FEA90CAD439F292556A3139F6E1B82 ipv6=[2a00:1298:8011:212::164]:9004
|
||||
85.248.227.163:443 orport=9001 id=C793AB88565DDD3C9E4C6F15CCB9D8C7EF964CE9 ipv6=[2a00:1298:8011:212::163]:9003
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
148.251.190.229:9030 orport=9010 id=BF0FB582E37F738CD33C3651125F2772705BB8E8 ipv6=[2a01:4f8:211:c68::2]:9010
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
5.79.68.161:81 orport=443 id=9030DCF419F6E2FBF84F63CBACBA0097B06F557E ipv6=[2001:1af8:4700:a012:1::1]:443
|
||||
5.79.68.161:9030 orport=9001 id=B7EC0C02D7D9F1E31B0C251A6B058880778A0CD1 ipv6=[2001:1af8:4700:a012:1::1]:9001
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
62.210.92.11:9030 orport=9001 id=0266B0660F3F20A7D1F3D8335931C95EF50F6C6B ipv6=[2001:bc8:338c::1]:9001
|
||||
62.210.92.11:9130 orport=9101 id=387B065A38E4DAA16D9D41C2964ECBC4B31D30FF ipv6=[2001:bc8:338c::1]:9101
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
188.165.194.195:9030 orport=9001 id=49E7AD01BB96F6FE3AB8C3B15BD2470B150354DF
|
||||
|
||||
# Message sent directly to teor, verified using relay contact info
|
||||
95.215.44.110:80 orport=443 id=D56AA4A1AA71961F5279FB70A6DCF7AD7B993EB5
|
||||
95.215.44.122:80 orport=443 id=998D8FE06B867AA3F8D257A7D28FFF16964D53E2
|
||||
95.215.44.111:80 orport=443 id=A7C7FD510B20BC8BE8F2A1D911364E1A23FBD09F
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
86.59.119.88:80 orport=443 id=ACD889D86E02EDDAB1AFD81F598C0936238DC6D0
|
||||
86.59.119.83:80 orport=443 id=FC9AC8EA0160D88BCCFDE066940D7DD9FA45495B
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
193.11.164.243:9030 orport=9001 id=FFA72BD683BC2FCF988356E6BEC1E490F313FB07 ipv6=[2001:6b0:7:125::243]:9001
|
||||
109.105.109.162:52860 orport=60784 id=32EE911D968BE3E016ECA572BB1ED0A9EE43FC2F ipv6=[2001:948:7:2::163]:5001
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
146.0.32.144:9030 orport=9001 id=35E8B344F661F4F2E68B17648F35798B44672D7E
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
46.252.26.2:45212 orport=49991 id=E589316576A399C511A9781A73DA4545640B479D
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
89.187.142.208:80 orport=443 id=64186650FFE4469EBBE52B644AE543864D32F43C
|
||||
|
||||
# Email sent directly to teor
|
||||
# Assume details update is permanent
|
||||
212.51.134.123:9030 orport=9001 id=50586E25BE067FD1F739998550EDDCB1A14CA5B2 # Jans
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
46.101.143.173:80 orport=443 id=F960DF50F0FD4075AC9B505C1D4FFC8384C490FB
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
193.171.202.146:9030 orport=9001 id=01A9258A46E97FF8B2CAC7910577862C14F2C524
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
# Assume details update is permanent
|
||||
197.231.221.211:9030 orport=443 id=BC630CBBB518BE7E9F4E09712AB0269E9DC7D626 # IPredator
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
185.61.138.18:8080 orport=4443 id=2541759BEC04D37811C2209A88E863320271EC9C
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
193.11.114.45:9031 orport=9002 id=80AAF8D5956A43C197104CEF2550CD42D165C6FB
|
||||
193.11.114.43:9030 orport=9001 id=12AD30E5D25AA67F519780E2111E611A455FDC89 ipv6=[2001:6b0:30:1000::99]:9050
|
||||
193.11.114.46:9032 orport=9003 id=B83DC1558F0D34353BB992EF93AFEAFDB226A73E
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
138.201.250.33:9012 orport=9011 id=2BA2C8E96B2590E1072AECE2BDB5C48921BF8510
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
37.221.162.226:9030 orport=9001 id=D64366987CB39F61AD21DBCF8142FA0577B92811
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
91.219.237.244:80 orport=443 id=92ECC9E0E2AF81BB954719B189AC362E254AD4A5
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
185.21.100.50:9030 orport=9001 id=58ED9C9C35E433EE58764D62892B4FFD518A3CD0 ipv6=[2a00:1158:2:cd00:0:74:6f:72]:443
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
193.35.52.53:9030 orport=9001 id=DAA39FC00B196B353C2A271459C305C429AF09E4
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
134.119.3.164:9030 orport=9001 id=D1B8AAA98C65F3DF7D8BB3AF881CAEB84A33D8EE
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
173.212.254.192:31336 orport=31337 id=99E246DB480B313A3012BC3363093CC26CD209C7
|
||||
|
||||
# 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
|
||||
188.166.23.127:80 orport=443 id=8672E8A01B4D3FA4C0BBE21C740D4506302EA487 ipv6=[2a03:b0c0:2:d0::27b:7001]:9050
|
||||
198.199.64.217:80 orport=443 id=B1D81825CFD7209BD1B4520B040EF5653C204A23 ipv6=[2604:a880:400:d0::1a9:b001]:9050
|
||||
159.203.32.149:80 orport=443 id=55C7554AFCEC1062DCBAC93E67B2E03C6F330EFC ipv6=[2604:a880:cad:d0::105:f001]:9050
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
5.196.31.80:9030 orport=9900 id=DFB2EB472643FAFCD5E73D2E37D51DB67203A695 ipv6=[2001:41d0:52:400::a65]:9900
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
188.138.112.60:1433 orport=1521 id=C414F28FD2BEC1553024299B31D4E726BEB8E788
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
213.61.66.118:9031 orport=9001 id=30648BC64CEDB3020F4A405E4AB2A6347FB8FA22
|
||||
213.61.66.117:9032 orport=9002 id=6E44A52E3D1FF7683FE5C399C3FB5E912DE1C6B4
|
||||
213.61.66.115:9034 orport=9004 id=480CCC94CEA04D2DEABC0D7373868E245D4C2AE2
|
||||
213.61.66.116:9033 orport=9003 id=A9DEB920B42B4EC1DE6249034039B06D61F38690
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
136.243.187.165:9030 orport=443 id=1AC65257D7BFDE7341046625470809693A8ED83E
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
212.47.230.49:9030 orport=9001 id=3D6D0771E54056AEFC28BB1DE816951F11826E97
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
192.99.55.69:80 orport=443 id=0682DE15222A4A4A0D67DBA72A8132161992C023
|
||||
192.99.59.140:80 orport=443 id=3C9148DA49F20654730FAC83FFF693A4D49D0244
|
||||
51.254.215.13:80 orport=443 id=73C30C8ABDD6D9346C822966DE73B9F82CB6178A
|
||||
51.254.215.129:80 orport=443 id=7B4491D05144B20AE8519AE784B94F0525A8BB79
|
||||
192.99.59.139:80 orport=443 id=82EC878ADA7C205146B9F5193A7310867FAA0D7B
|
||||
51.254.215.124:80 orport=443 id=98999EBE89B5FA9AA0C58421F0B46C3D0AF51CBA
|
||||
51.254.214.208:80 orport=443 id=C3F0D1417848EAFC41277A73DEB4A9F2AEC23DDF
|
||||
192.99.59.141:80 orport=443 id=F45426551795B9DA78BEDB05CD5F2EACED8132E4
|
||||
192.99.59.14:80 orport=443 id=161A1B29A37EBF096D2F8A9B1E176D6487FE42AE
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
151.80.42.103:9030 orport=9001 id=9007C1D8E4F03D506A4A011B907A9E8D04E3C605 ipv6=[2001:41d0:e:f67::114]:9001
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
5.39.92.199:80 orport=443 id=0BEA4A88D069753218EAAAD6D22EA87B9A1319D6 ipv6=[2001:41d0:8:b1c7::1]:443
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
176.31.159.231:80 orport=443 id=D5DBCC0B4F029F80C7B8D33F20CF7D97F0423BB1
|
||||
176.31.159.230:80 orport=443 id=631748AFB41104D77ADBB7E5CD4F8E8AE876E683
|
||||
195.154.79.128:80 orport=443 id=C697612CA5AED06B8D829FCC6065B9287212CB2F
|
||||
195.154.9.161:80 orport=443 id=B6295A9960F89BD0C743EEBC5670450EA6A34685
|
||||
46.148.18.74:8080 orport=443 id=6CACF0B5F03C779672F3C5C295F37C8D234CA3F7
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
37.187.102.108:80 orport=443 id=F4263275CF54A6836EE7BD527B1328836A6F06E1 ipv6=[2001:41d0:a:266c::1]:443 # EvilMoe
|
||||
212.47.241.21:80 orport=443 id=892F941915F6A0C6E0958E52E0A9685C190CF45C # EvilMoe
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
212.129.38.254:9030 orport=9001 id=FDF845FC159C0020E2BDDA120C30C5C5038F74B4
|
||||
|
||||
# Email sent directly to teor
|
||||
37.157.195.87:8030 orport=443 id=12FD624EE73CEF37137C90D38B2406A66F68FAA2 # thanatosCZ
|
||||
5.189.169.190:8030 orport=8080 id=8D79F73DCD91FC4F5017422FAC70074D6DB8DD81 # thanatosDE
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
37.187.7.74:80 orport=443 id=AEA43CB1E47BE5F8051711B2BF01683DB1568E05 ipv6=[2001:41d0:a:74a::1]:443
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
185.66.250.141:9030 orport=9001 id=B1726B94885CE3AC3910CA8B60622B97B98E2529
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
185.104.120.7:9030 orport=443 id=445F1C853966624FB3CF1E12442570DC553CC2EC ipv6=[2a06:3000::120:7]:443
|
||||
185.104.120.2:9030 orport=21 id=518FF8708698E1DA09C823C36D35DF89A2CAD956
|
||||
185.104.120.4:9030 orport=9001 id=F92B3CB9BBE0CB22409843FB1AE4DBCD5EFAC835
|
||||
185.104.120.3:9030 orport=21 id=707C1B61AC72227B34487B56D04BAA3BA1179CE8 ipv6=[2a06:3000::120:3]:21
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
37.187.102.186:9030 orport=9001 id=489D94333DF66D57FFE34D9D59CC2D97E2CB0053 ipv6=[2001:41d0:a:26ba::1]:9001
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
198.96.155.3:8080 orport=5001 id=BCEDF6C193AA687AE471B8A22EBF6BC57C2D285E
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
212.83.154.33:8888 orport=443 id=3C79699D4FBC37DE1A212D5033B56DAE079AC0EF
|
||||
212.83.154.33:8080 orport=8443 id=322C6E3A973BC10FC36DE3037AD27BC89F14723B
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
51.255.41.65:9030 orport=9001 id=9231DF741915AA1630031A93026D88726877E93A
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
78.142.142.246:80 orport=443 id=5A5E03355C1908EBF424CAF1F3ED70782C0D2F74
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
195.154.97.91:80 orport=443 id=BD33C50D50DCA2A46AAED54CA319A1EFEBF5D714
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
62.210.129.246:80 orport=443 id=79E169B25E4C7CE99584F6ED06F379478F23E2B8
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
5.196.74.215:9030 orport=9001 id=5818055DFBAF0FA7F67E8125FD63E3E7F88E28F6
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
212.47.233.86:9030 orport=9001 id=B4CAFD9CBFB34EC5DAAC146920DC7DFAFE91EA20
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
85.214.206.219:9030 orport=9001 id=98F8D5F359949E41DE8DF3DBB1975A86E96A84A0
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
46.166.170.4:80 orport=443 id=19F42DB047B72C7507F939F5AEA5CD1FA4656205
|
||||
46.166.170.5:80 orport=443 id=DA705AD4591E7B4708FA2CAC3D53E81962F3E6F6
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
5.189.157.56:80 orport=443 id=77F6D6A6B6EAFB8F5DADDC07A918BBF378ED6725
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
46.28.110.244:80 orport=443 id=9F7D6E6420183C2B76D3CE99624EBC98A21A967E
|
||||
185.13.39.197:80 orport=443 id=001524DD403D729F08F7E5D77813EF12756CFA8D
|
||||
95.130.12.119:80 orport=443 id=587E0A9552E4274B251F29B5B2673D38442EE4BF
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
212.129.62.232:80 orport=443 id=B143D439B72D239A419F8DCE07B8A8EB1B486FA7
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
91.219.237.229:80 orport=443 id=1ECD73B936CB6E6B3CD647CC204F108D9DF2C9F7
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
46.101.151.222:80 orport=443 id=1DBAED235E3957DE1ABD25B4206BE71406FB61F8
|
||||
178.62.60.37:80 orport=443 id=175921396C7C426309AB03775A9930B6F611F794
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
178.62.197.82:80 orport=443 id=0D3EBA17E1C78F1E9900BABDB23861D46FCAF163
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
82.223.21.74:9030 orport=9001 id=7A32C9519D80CA458FC8B034A28F5F6815649A98 ipv6=[2001:470:53e0::cafe]:9050
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
146.185.177.103:80 orport=9030 id=9EC5E097663862DF861A18C32B37C5F82284B27D
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
37.187.22.87:9030 orport=9001 id=36B9E7AC1E36B62A9D6F330ABEB6012BA7F0D400 ipv6=[2001:41d0:a:1657::1]:9001
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
37.59.46.159:9030 orport=9001 id=CBD0D1BD110EC52963082D839AC6A89D0AE243E7
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
212.47.250.243:9030 orport=9001 id=5B33EDBAEA92F446768B3753549F3B813836D477
|
||||
# Confirm with operator before adding these
|
||||
#163.172.133.36:9030 orport=9001 id=D8C2BD36F01FA86F4401848A0928C4CB7E5FDFF9
|
||||
#158.69.216.70:9030 orport=9001 id=0ACE25A978D4422C742D6BC6345896719BF6A7EB
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
5.199.142.236:9030 orport=9001 id=F4C0EDAA0BF0F7EC138746F8FEF1CE26C7860265
|
||||
|
||||
# Email sent directly to teor
|
||||
188.166.133.133:9030 orport=9001 id=774555642FDC1E1D4FDF2E0C31B7CA9501C5C9C7 ipv6=[2a03:b0c0:2:d0::26c0:1]:9001 # dropsy
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
46.8.249.10:80 orport=443 id=31670150090A7C3513CB7914B9610E786391A95D
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
144.76.163.93:9030 orport=9001 id=22F08CF09764C4E8982640D77F71ED72FF26A9AC
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
46.4.24.161:9030 orport=9001 id=DB4C76A3AD7E234DA0F00D6F1405D8AFDF4D8DED
|
||||
46.4.24.161:9031 orport=9002 id=7460F3D12EBE861E4EE073F6233047AACFE46AB4
|
||||
46.38.51.132:9030 orport=9001 id=810DEFA7E90B6C6C383C063028EC397A71D7214A
|
||||
163.172.194.53:9030 orport=9001 id=8C00FA7369A7A308F6A137600F0FA07990D9D451 ipv6=[2001:bc8:225f:142:6c69:7461:7669:73]:9001
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
176.10.107.180:9030 orport=9001 id=3D7E274A87D9A89AF064C13D1EE4CA1F184F2600
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
46.28.207.19:80 orport=443 id=5B92FA5C8A49D46D235735504C72DBB3472BA321
|
||||
46.28.207.141:80 orport=443 id=F69BED36177ED727706512BA6A97755025EEA0FB
|
||||
46.28.205.170:80 orport=443 id=AF322D83A4D2048B22F7F1AF5F38AFF4D09D0B76
|
||||
95.183.48.12:80 orport=443 id=7187CED1A3871F837D0E60AC98F374AC541CB0DA
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
93.180.156.84:9030 orport=9001 id=8844D87E9B038BE3270938F05AF797E1D3C74C0F
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
37.187.115.157:9030 orport=9001 id=D5039E1EBFD96D9A3F9846BF99EC9F75EDDE902A
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
5.34.183.205:80 orport=443 id=DDD7871C1B7FA32CB55061E08869A236E61BDDF8
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
51.254.246.203:9030 orport=9001 id=47B596B81C9E6277B98623A84B7629798A16E8D5
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
5.9.146.203:80 orport=443 id=1F45542A24A61BF9408F1C05E0DCE4E29F2CBA11
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
# Updated details from atlas based on ticket #20010
|
||||
163.172.176.167:80 orport=443 id=230A8B2A8BA861210D9B4BA97745AEC217A94207
|
||||
163.172.149.155:80 orport=443 id=0B85617241252517E8ECF2CFC7F4C1A32DCD153F
|
||||
163.172.149.122:80 orport=443 id=A9406A006D6E7B5DA30F2C6D4E42A338B5E340B2
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
204.11.50.131:9030 orport=9001 id=185F2A57B0C4620582602761097D17DB81654F70
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
151.236.222.217:44607 orport=9001 id=94D58704C2589C130C9C39ED148BD8EA468DBA54
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
185.35.202.221:9030 orport=9001 id=C13B91384CDD52A871E3ECECE4EF74A7AC7DCB08 ipv6=[2a02:ed06::221]:9001
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
5.9.151.241:9030 orport=4223 id=9BF04559224F0F1C3C953D641F1744AF0192543A ipv6=[2a01:4f8:190:34f0::2]:4223
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
89.40.71.149:8081 orport=8080 id=EC639EDAA5121B47DBDF3D6B01A22E48A8CB6CC7
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
92.222.20.130:80 orport=443 id=0639612FF149AA19DF3BCEA147E5B8FED6F3C87C
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
80.112.155.100:9030 orport=9001 id=53B000310984CD86AF47E5F3CD0BFF184E34B383 ipv6=[2001:470:7b02::38]:9001
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
83.212.99.68:80 orport=443 id=DDBB2A38252ADDA53E4492DDF982CA6CC6E10EC0 ipv6=[2001:648:2ffc:1225:a800:bff:fe3d:67b5]:443
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
95.130.11.147:9030 orport=443 id=6B697F3FF04C26123466A5C0E5D1F8D91925967A
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
128.199.55.207:9030 orport=9001 id=BCEF908195805E03E92CCFE669C48738E556B9C5 ipv6=[2a03:b0c0:2:d0::158:3001]:9001
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
178.32.216.146:9030 orport=9001 id=17898F9A2EBC7D69DAF87C00A1BD2FABF3C9E1D2
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
212.83.40.238:9030 orport=9001 id=F409FA7902FD89270E8DE0D7977EA23BC38E5887
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
204.8.156.142:80 orport=443 id=94C4B7B8C50C86A92B6A20107539EE2678CF9A28
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
80.240.139.111:80 orport=443 id=DD3BE7382C221F31723C7B294310EF9282B9111B
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
185.97.32.18:9030 orport=9001 id=04250C3835019B26AA6764E85D836088BE441088
|
||||
|
||||
# Email sent directly to teor
|
||||
149.56.45.200:9030 orport=9001 id=FE296180018833AF03A8EACD5894A614623D3F76 ipv6=[2607:5300:201:3000::17d3]:9002 # PiotrTorpotkinOne
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
81.2.209.10:443 orport=80 id=B6904ADD4C0D10CDA7179E051962350A69A63243 ipv6=[2001:15e8:201:1::d10a]:80
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
# IPv6 address unreliable
|
||||
195.154.164.243:80 orport=443 id=AC66FFA4AB35A59EBBF5BF4C70008BF24D8A7A5C #ipv6=[2001:bc8:399f:f000::1]:993
|
||||
138.201.26.2:80 orport=443 id=6D3A3ED5671E4E3F58D4951438B10AE552A5FA0F
|
||||
81.7.16.182:80 orport=443 id=51E1CF613FD6F9F11FE24743C91D6F9981807D82 ipv6=[2a02:180:1:1::517:10b6]:993
|
||||
134.119.36.135:80 orport=443 id=763C9556602BD6207771A7A3D958091D44C43228 ipv6=[2a00:1158:3::2a8]:993
|
||||
46.228.199.19:80 orport=443 id=E26AFC5F718E21AC502899B20C653AEFF688B0D2 ipv6=[2001:4ba0:cafe:4a::1]:993
|
||||
37.200.98.5:80 orport=443 id=231C2B9C8C31C295C472D031E06964834B745996 ipv6=[2a00:1158:3::11a]:993
|
||||
46.23.70.195:80 orport=443 id=C9933B3725239B6FAB5227BA33B30BE7B48BB485
|
||||
185.15.244.124:80 orport=443 id=935BABE2564F82016C19AEF63C0C40B5753BA3D2 ipv6=[2001:4ba0:cafe:e35::1]:993
|
||||
195.154.116.232:80 orport=443 id=B35C5739C8C5AB72094EB2B05738FD1F8EEF6EBD ipv6=[2001:bc8:399f:200::1]:993
|
||||
195.154.121.198:80 orport=443 id=0C77421C890D16B6D201283A2244F43DF5BC89DD ipv6=[2001:bc8:399f:100::1]:993
|
||||
37.187.20.59:80 orport=443 id=91D23D8A539B83D2FB56AA67ECD4D75CC093AC55 ipv6=[2001:41d0:a:143b::1]:993
|
||||
217.12.208.117:80 orport=443 id=E6E18151300F90C235D3809F90B31330737CEB43 ipv6=[2a00:1ca8:a7::1bb]:993
|
||||
81.7.10.251:80 orport=443 id=8073670F8F852971298F8AF2C5B23AE012645901 ipv6=[2a02:180:1:1::517:afb]:993
|
||||
46.36.39.50:80 orport=443 id=ED4B0DBA79AEF5521564FA0231455DCFDDE73BB6 ipv6=[2a02:25b0:aaaa:aaaa:8d49:b692:4852:0]:995
|
||||
91.194.90.103:80 orport=443 id=75C4495F4D80522CA6F6A3FB349F1B009563F4B7 ipv6=[2a02:c205:3000:5449::1]:993
|
||||
163.172.25.118:80 orport=22 id=0CF8F3E6590F45D50B70F2F7DA6605ECA6CD408F
|
||||
188.138.88.42:80 orport=443 id=70C55A114C0EF3DC5784A4FAEE64388434A3398F
|
||||
81.7.13.84:80 orport=443 id=0C1E7DD9ED0676C788933F68A9985ED853CA5812 ipv6=[2a02:180:1:1::5b8f:538c]:993
|
||||
213.246.56.95:80 orport=443 id=27E6E8E19C46751E7312420723C6162FF3356A4C ipv6=[2a00:c70:1:213:246:56:95:1]:993
|
||||
94.198.100.18:80 orport=443 id=BAACCB29197DB833F107E410E2BFAE5009EE7583
|
||||
217.12.203.46:80 orport=443 id=6A29FD8C00D573E6C1D47852345B0E5275BA3307
|
||||
212.117.180.107:80 orport=443 id=0B454C7EBA58657B91133A587C1BDAEDC6E23142
|
||||
217.12.199.190:80 orport=443 id=A37C47B03FF31CA6937D3D68366B157997FE7BCD ipv6=[2a02:27a8:0:2::486]:993
|
||||
216.230.230.247:80 orport=443 id=4C7BF55B1BFF47993DFF995A2926C89C81E4F04A
|
||||
69.30.215.42:80 orport=443 id=510176C07005D47B23E6796F02C93241A29AA0E9 ipv6=[2604:4300:a:2e::2]:993
|
||||
89.46.100.162:80 orport=443 id=6B7191639E179965FD694612C9B2C8FB4267B27D
|
||||
107.181.174.22:80 orport=443 id=5A551BF2E46BF26CC50A983F7435CB749C752553 ipv6=[2607:f7a0:3:4::4e]:993
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
212.238.208.48:9030 orport=9001 id=F406219CDD339026D160E53FCA0EF6857C70F109 ipv6=[2001:984:a8fb:1:ba27:ebff:feac:c109]:9001
|
||||
|
||||
# Email sent directly to teor
|
||||
176.158.236.102:9030 orport=9001 id=DC163DDEF4B6F0C6BC226F9F6656A5A30C5C5686 # Underworld
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
91.229.20.27:9030 orport=9001 id=9A0D54D3A6D2E0767596BF1515E6162A75B3293F
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
80.127.137.19:80 orport=443 id=6EF897645B79B6CB35E853B32506375014DE3621 ipv6=[2001:981:47c1:1::6]:443
|
||||
|
||||
# Email sent directly to teor
|
||||
163.172.138.22:80 orport=443 id=16102E458460349EE45C0901DAA6C30094A9BBEA ipv6=[2001:bc8:4400:2100::1:3]:443 # mkultra
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
97.74.237.196:9030 orport=9001 id=2F0F32AB1E5B943CA7D062C03F18960C86E70D94
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
192.187.124.98:9030 orport=9001 id=FD1871854BFC06D7B02F10742073069F0528B5CC
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
178.62.98.160:9030 orport=9001 id=8B92044763E880996A988831B15B2B0E5AD1544A
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
163.172.217.50:9030 orport=9001 id=02ECD99ECD596013A8134D46531560816ECC4BE6
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
185.100.86.100:80 orport=443 id=0E8C0C8315B66DB5F703804B3889A1DD66C67CE0
|
||||
185.100.84.82:80 orport=443 id=7D05A38E39FC5D29AFE6BE487B9B4DC9E635D09E
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
164.132.77.175:9030 orport=9001 id=3B33F6FCA645AD4E91428A3AF7DC736AD9FB727B
|
||||
78.24.75.53:9030 orport=9001 id=DEB73705B2929AE9BE87091607388939332EF123
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
46.101.237.246:9030 orport=9001 id=75F1992FD3F403E9C082A5815EB5D12934CDF46C ipv6=[2a03:b0c0:3:d0::208:5001]:9050
|
||||
178.62.86.96:9030 orport=9001 id=439D0447772CB107B886F7782DBC201FA26B92D1 ipv6=[2a03:b0c0:1:d0::3cf:7001]:9050
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
# Very low bandwidth, stale consensues, excluded to cut down on warnings
|
||||
#91.233.106.121:80 orport=443 id=896364B7996F5DFBA0E15D1A2E06D0B98B555DD6
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
167.114.113.48:9030 orport=403 id=2EC0C66EA700C44670444280AABAB1EC78B722A0
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
# Assume details update is permanent
|
||||
213.141.138.174:9030 orport=9001 id=BD552C165E2ED2887D3F1CCE9CFF155DDA2D86E6 # Schakalium
|
||||
|
||||
# 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
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
166.82.21.200:9030 orport=9029 id=D5C33F3E203728EDF8361EA868B2939CCC43FAFB
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
91.121.54.8:9030 orport=9001 id=CBEE0F3303C8C50462A12107CA2AE061831931BC
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
178.217.184.32:8080 orport=443 id=8B7F47AE1A5D954A3E58ACDE0865D09DBA5B738D
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
85.10.201.47:9030 orport=9001 id=D8B7A3A6542AA54D0946B9DC0257C53B6C376679 ipv6=[2a01:4f8:a0:43eb::beef]:9001
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
120.29.217.46:80 orport=443 id=5E853C94AB1F655E9C908924370A0A6707508C62
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
37.153.1.10:9030 orport=9001 id=9772EFB535397C942C3AB8804FB35CFFAD012438
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
92.222.4.102:9030 orport=9001 id=1A6B8B8272632D8AD38442027F822A367128405C
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
31.31.78.49:80 orport=443 id=46791D156C9B6C255C2665D4D8393EC7DBAA7798
|
||||
|
||||
# Email sent directly to teor
|
||||
192.160.102.169:80 orport=9001 id=C0192FF43E777250084175F4E59AC1BA2290CE38 ipv6=[2620:132:300c:c01d::9]:9002 # manipogo
|
||||
192.160.102.166:80 orport=9001 id=547DA56F6B88B6C596B3E3086803CDA4F0EF8F21 ipv6=[2620:132:300c:c01d::6]:9002 # chaucer
|
||||
192.160.102.170:80 orport=9001 id=557ACEC850F54EEE65839F83CACE2B0825BE811E ipv6=[2620:132:300c:c01d::a]:9002 # ogopogo
|
||||
192.160.102.164:80 orport=9001 id=823AA81E277F366505545522CEDC2F529CE4DC3F ipv6=[2620:132:300c:c01d::4]:9002 # snowfall
|
||||
192.160.102.165:80 orport=9001 id=C90CA3B7FE01A146B8268D56977DC4A2C024B9EA ipv6=[2620:132:300c:c01d::5]:9002 # cowcat
|
||||
192.160.102.168:80 orport=9001 id=F6A358DD367B3282D6EF5824C9D45E1A19C7E815 ipv6=[2620:132:300c:c01d::8]:9002 # prawksi
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
136.243.214.137:80 orport=443 id=B291D30517D23299AD7CEE3E60DFE60D0E3A4664
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
192.87.28.28:9030 orport=9001 id=ED2338CAC2711B3E331392E1ED2831219B794024
|
||||
192.87.28.82:9030 orport=9001 id=844AE9CAD04325E955E2BE1521563B79FE7094B7
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
192.87.28.28:9030 orport=9001 id=ED2338CAC2711B3E331392E1ED2831219B794024
|
||||
# same machine as ED2338CAC2711B3E331392E1ED2831219B794024
|
||||
192.87.28.82:9030 orport=9001 id=844AE9CAD04325E955E2BE1521563B79FE7094B7
|
||||
|
||||
# https://twitter.com/kosjoli/status/719507270904758272
|
||||
85.10.202.87:9030 orport=9001 id=971AFB23C168DCD8EDA17473C1C452B359DE3A5A
|
||||
176.9.5.116:9030 orport=9001 id=A1EB8D8F1EE28DB98BBB1EAA3B4BEDD303BAB911
|
||||
46.4.111.124:9030 orport=9001 id=D9065F9E57899B3D272AA212317AF61A9B14D204
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
185.100.85.61:80 orport=443 id=025B66CEBC070FCB0519D206CF0CF4965C20C96E
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
108.166.168.158:80 orport=443 id=CDAB3AE06A8C9C6BF817B3B0F1877A4B91465699
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
91.219.236.222:80 orport=443 id=20704E7DD51501DC303FA51B738D7B7E61397CF6
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
185.14.185.240:9030 orport=443 id=D62FB817B0288085FAC38A6DC8B36DCD85B70260
|
||||
192.34.63.137:9030 orport=443 id=ABCB4965F1FEE193602B50A365425105C889D3F8
|
||||
128.199.197.16:9030 orport=443 id=DEE5298B3BA18CDE651421CD2DCB34A4A69F224D
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
185.13.38.75:9030 orport=9001 id=D2A1703758A0FBBA026988B92C2F88BAB59F9361
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
128.204.39.106:9030 orport=9001 id=6F0F3C09AF9580F7606B34A7678238B3AF7A57B7
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
198.50.191.95:80 orport=443 id=39F096961ED2576975C866D450373A9913AFDC92
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
167.114.66.61:9696 orport=443 id=DE6CD5F09DF26076F26321B0BDFBE78ACD935C65 ipv6=[2607:5300:100::78d]:443
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
66.111.2.20:9030 orport=9001 id=9A68B85A02318F4E7E87F2828039FBD5D75B0142
|
||||
66.111.2.16:9030 orport=9001 id=3F092986E9B87D3FDA09B71FA3A602378285C77A
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
92.222.38.67:80 orport=443 id=DED6892FF89DBD737BA689698A171B2392EB3E82
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
212.47.228.115:9030 orport=443 id=BCA017ACDA48330D02BB70716639ED565493E36E
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
185.100.84.175:80 orport=443 id=39B59AF4FE54FAD8C5085FA9C15FDF23087250DB
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
166.70.207.2:9030 orport=9001 id=E3DB2E354B883B59E8DC56B3E7A353DDFD457812
|
||||
|
||||
# Emails sent directly to teor, verified using relay contact info
|
||||
69.162.139.9:9030 orport=9001 id=4791FC0692EAB60DF2BCCAFF940B95B74E7654F6 ipv6=[2607:f128:40:1212::45a2:8b09]:9001
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
213.239.217.18:1338 orport=1337 id=C37BC191AC389179674578C3E6944E925FE186C2 ipv6=[2a01:4f8:a0:746a:101:1:1:1]:1337
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
# Assume details update is permanent
|
||||
188.40.128.246:9030 orport=9001 id=AD19490C7DBB26D3A68EFC824F67E69B0A96E601 ipv6=[2a01:4f8:221:1ac1:dead:beef:7005:9001]:9001 # sputnik
|
||||
|
||||
# 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
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
185.100.86.128:9030 orport=9001 id=9B31F1F1C1554F9FFB3455911F82E818EF7C7883
|
||||
46.36.36.127:9030 orport=9001 id=C80DF89B21FF932DEC0D7821F679B6C79E1449C3
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
176.10.104.240:80 orport=443 id=0111BA9B604669E636FFD5B503F382A4B7AD6E80
|
||||
176.10.104.240:8080 orport=8443 id=AD86CD1A49573D52A7B6F4A35750F161AAD89C88
|
||||
176.10.104.243:80 orport=443 id=88487BDD980BF6E72092EE690E8C51C0AA4A538C
|
||||
176.10.104.243:8080 orport=8443 id=95DA61AEF23A6C851028C1AA88AD8593F659E60F
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
107.170.101.39:9030 orport=443 id=30973217E70AF00EBE51797FF6D9AA720A902EAA
|
||||
|
||||
# Email sent directly to teor
|
||||
193.70.112.165:80 orport=443 id=F10BDE279AE71515DDCCCC61DC19AC8765F8A3CC # ParkBenchInd001
|
||||
|
||||
# Email sent directly to teor
|
||||
185.220.101.6:10006 orport=20006 id=C08DE49658E5B3CFC6F2A952B453C4B608C9A16A # niftyvolcanorabbit
|
||||
185.220.101.13:10013 orport=20013 id=71AB4726D830FAE776D74AEF790CF04D8E0151B4 # niftycottontail
|
||||
185.220.101.5:10005 orport=20005 id=1084200B44021D308EA4253F256794671B1D099A # niftyhedgehog
|
||||
185.220.101.9:10009 orport=20009 id=14877C6384A9E793F422C8D1DDA447CACA4F7C4B # niftywoodmouse
|
||||
185.220.101.8:10008 orport=20008 id=24E91955D969AEA1D80413C64FE106FAE7FD2EA9 # niftymouse
|
||||
185.220.101.1:10001 orport=20001 id=28F4F392F8F19E3FBDE09616D9DB8143A1E2DDD3 # niftycottonmouse
|
||||
185.220.101.21:10021 orport=20021 id=348B89013EDDD99E4755951D1EC284D9FED71226 # niftysquirrel
|
||||
185.220.101.10:10010 orport=20010 id=4031460683AE9E0512D3620C2758D98758AC6C93 # niftyeuropeanrabbit
|
||||
185.220.101.34:10034 orport=20034 id=47C42E2094EE482E7C9B586B10BABFB67557030B # niftyquokka
|
||||
185.220.101.18:10018 orport=20018 id=5D5006E4992F2F97DF4F8B926C3688870EB52BD8 # niftyplagiodontia
|
||||
185.220.101.28:10028 orport=20028 id=609E598FB6A00BCF7872906B602B705B64541C50 # niftychipmunk
|
||||
185.220.101.20:10020 orport=20020 id=619349D82424C601CAEB94161A4CF778993DAEE7 # niftytucotuco
|
||||
185.220.101.17:10017 orport=20017 id=644DECC5A1879C0FE23DE927DD7049F58BBDF349 # niftyhutia
|
||||
185.220.101.0:10000 orport=20000 id=6E94866ED8CA098BACDFD36D4E8E2B459B8A734E # niftybeaver
|
||||
185.220.101.30:10030 orport=20030 id=71CFDEB4D9E00CCC3E31EC4E8A29E109BBC1FB36 # niftypedetidae
|
||||
185.220.101.29:10029 orport=20029 id=7DC52AE6667A30536BA2383CD102CFC24F20AD71 # niftyllipika
|
||||
185.220.101.41:10041 orport=20041 id=7E281CD2C315C4F7A84BC7C8721C3BC974DDBFA3 # niftyporcupine
|
||||
185.220.101.25:10025 orport=20025 id=8EE0534532EA31AA5172B1892F53B2F25C76EB02 # niftyjerboa
|
||||
185.220.101.33:10033 orport=20033 id=906DCB390F2BA987AE258D745E60BAAABAD31DE8 # niftyquokka
|
||||
185.220.101.26:10026 orport=20026 id=92A6085EABAADD928B6F8E871540A1A41CBC08BA # niftypedetes
|
||||
185.220.101.40:10040 orport=20040 id=9A857254F379194D1CD76F4A79A20D2051BEDA3F # niftynutria
|
||||
185.220.101.42:10042 orport=20042 id=9B816A5B3EB20B8E4E9B9D1FBA299BD3F40F0320 # niftypygmyjerboa
|
||||
185.220.101.2:10002 orport=20002 id=B740BCECC4A9569232CDD45C0E1330BA0D030D33 # niftybunny
|
||||
185.220.101.32:10032 orport=20032 id=B771AA877687F88E6F1CA5354756DF6C8A7B6B24 # niftypika
|
||||
185.220.101.12:10012 orport=20012 id=BC82F2190DE2E97DE65F49B4A95572374BDC0789 # niftycapybara
|
||||
185.220.101.22:10022 orport=20022 id=CA37CD46799449D83B6B98B8C22C649906307888 # niftyjackrabbit
|
||||
185.220.101.4:10004 orport=20004 id=CDA2EA326E2272C57ACB26773D7252C211795B78 # niftygerbil
|
||||
185.220.101.14:10014 orport=20014 id=E7EBA5D8A4E09684D11A1DF24F75362817333768 # niftyhare
|
||||
185.220.101.16:10016 orport=20016 id=EC1997D51892E4607C68E800549A1E7E4694005A # niftyguineapig
|
||||
185.220.101.24:10024 orport=20024 id=FDA70EC93DB01E3CB418CB6943B0C68464B18B4C # niftyrat
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
64.113.32.29:9030 orport=9001 id=30C19B81981F450C402306E2E7CFB6C3F79CB6B2
|
||||
|
||||
# Emails sent directly to teor, verified using relay contact info
|
||||
51.254.101.242:9002 orport=9001 id=4CC9CC9195EC38645B699A33307058624F660CCF
|
||||
|
||||
# Emails sent directly to teor, verified using relay contact info
|
||||
85.214.62.48:80 orport=443 id=6A7551EEE18F78A9813096E82BF84F740D32B911
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
173.255.245.116:9030 orport=9001 id=91E4015E1F82DAF0121D62267E54A1F661AB6DC7
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
62.216.5.120:9030 orport=9001 id=D032D4D617140D6B828FC7C4334860E45E414FBE
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
51.254.136.195:80 orport=443 id=7BB70F8585DFC27E75D692970C0EEB0F22983A63
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
163.172.13.165:9030 orport=9001 id=33DA0CAB7C27812EFF2E22C9705630A54D101FEB ipv6=[2001:bc8:38cb:201::8]:9001
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
5.196.88.122:9030 orport=9001 id=0C2C599AFCB26F5CFC2C7592435924C1D63D9484 ipv6=[2001:41d0:a:fb7a::1]:9001
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
5.9.158.75:80 orport=443 id=1AF72E8906E6C49481A791A6F8F84F8DFEBBB2BA ipv6=[2a01:4f8:190:514a::2]:443
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
46.101.169.151:9030 orport=9001 id=D760C5B436E42F93D77EF2D969157EEA14F9B39C ipv6=[2a03:b0c0:3:d0::74f:a001]:9001
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
199.249.223.81:80 orport=443 id=F7447E99EB5CBD4D5EB913EE0E35AC642B5C1EF3
|
||||
199.249.223.79:80 orport=443 id=D33292FEDE24DD40F2385283E55C87F85C0943B6
|
||||
199.249.223.78:80 orport=443 id=EC15DB62D9101481F364DE52EB8313C838BDDC29
|
||||
199.249.223.77:80 orport=443 id=CC4A3AE960E3617F49BF9887B79186C14CBA6813
|
||||
199.249.223.76:80 orport=443 id=43209F6D50C657A56FE79AF01CA69F9EF19BD338
|
||||
199.249.223.75:80 orport=443 id=60D3667F56AEC5C69CF7E8F557DB21DDF6C36060
|
||||
199.249.223.74:80 orport=443 id=5F4CD12099AF20FAF9ADFDCEC65316A376D0201C
|
||||
199.249.223.73:80 orport=443 id=5649CB2158DA94FB747415F26628BEC07FA57616
|
||||
199.249.223.72:80 orport=443 id=B028707969D8ED84E6DEA597A884F78AAD471971
|
||||
199.249.223.71:80 orport=443 id=B6320E44A230302C7BF9319E67597A9B87882241
|
||||
199.249.223.60:80 orport=443 id=B7047FBDE9C53C39011CA84E5CB2A8E3543066D0
|
||||
199.249.223.61:80 orport=443 id=40E7D6CE5085E4CDDA31D51A29D1457EB53F12AD
|
||||
199.249.223.62:80 orport=443 id=0077BCBA7244DB3E6A5ED2746E86170066684887
|
||||
199.249.223.63:80 orport=443 id=1DB25DF59DAA01B5BE3D3CEB8AFED115940EBE8B
|
||||
199.249.223.64:80 orport=443 id=9F2856F6D2B89AD4EF6D5723FAB167DB5A53519A
|
||||
199.249.223.65:80 orport=443 id=9D21F034C3BFF4E7737D08CF775DC1745706801F
|
||||
199.249.223.66:80 orport=443 id=C5A53BCC174EF8FD0DCB223E4AA929FA557DEDB2
|
||||
199.249.223.67:80 orport=443 id=155D6F57425F16C0624D77777641E4EB1B47C6F0
|
||||
199.249.223.68:80 orport=443 id=DF20497E487A979995D851A5BCEC313DF7E5BC51
|
||||
199.249.223.69:80 orport=443 id=7FA8E7E44F1392A4E40FFC3B69DB3B00091B7FD3
|
||||
|
||||
# https://lists.torproject.org/pipermail/tor-relays/2016-December/011114.html
|
||||
86.105.212.130:9030 orport=443 id=9C900A7F6F5DD034CFFD192DAEC9CCAA813DB022
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
178.33.183.251:80 orport=443 id=DD823AFB415380A802DCAEB9461AE637604107FB ipv6=[2001:41d0:2:a683::251]:443
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
31.185.104.19:80 orport=443 id=9EAD5B2D3DBD96DBC80DCE423B0C345E920A758D
|
||||
# same machine as 9EAD5B2D3DBD96DBC80DCE423B0C345E920A758D
|
||||
31.185.104.20:80 orport=443 id=ADB2C26629643DBB9F8FE0096E7D16F9414B4F8D
|
||||
31.185.104.21:80 orport=443 id=C2AAB088555850FC434E68943F551072042B85F1
|
||||
31.185.104.22:80 orport=443 id=5BA3A52760A0EABF7E7C3ED3048A77328FF0F148
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
185.34.60.114:80 orport=443 id=7F7A695DF6F2B8640A70B6ADD01105BC2EBC5135
|
||||
|
||||
# https://lists.torproject.org/pipermail/tor-relays/2017-December/013939.html
|
||||
94.142.242.84:80 orport=443 id=AA0D167E03E298F9A8CD50F448B81FBD7FA80D56 ipv6=[2a02:898:24:84::1]:443 # rejozenger
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
185.129.62.62:9030 orport=9001 id=ACDD9E85A05B127BA010466C13C8C47212E8A38F ipv6=[2a06:d380:0:3700::62]:9001
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
# The e84 part of the IPv6 address does not have a leading 0 in the consensus
|
||||
81.30.158.213:9030 orport=9001 id=789EA6C9AE9ADDD8760903171CFA9AC5741B0C70 ipv6=[2001:4ba0:cafe:e84::1]:9001
|
||||
|
||||
# https://lists.torproject.org/pipermail/tor-relays/2016-December/011209.html
|
||||
5.9.159.14:9030 orport=9001 id=0F100F60C7A63BED90216052324D29B08CFCF797
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
45.62.255.25:80 orport=443 id=3473ED788D9E63361D1572B7E82EC54338953D2A
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
217.79.179.177:9030 orport=9001 id=3E53D3979DB07EFD736661C934A1DED14127B684 ipv6=[2001:4ba0:fff9:131:6c4f::90d3]:9001
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
212.47.244.38:8080 orport=443 id=E81EF60A73B3809F8964F73766B01BAA0A171E20
|
||||
163.172.157.213:8080 orport=443 id=4623A9EC53BFD83155929E56D6F7B55B5E718C24
|
||||
163.172.139.104:8080 orport=443 id=68F175CCABE727AA2D2309BCD8789499CEE36ED7
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
163.172.223.200:80 orport=443 id=998BF3ED7F70E33D1C307247B9626D9E7573C438
|
||||
195.154.122.54:80 orport=443 id=64E99CB34C595A02A3165484BD1215E7389322C6
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
185.100.86.128:9030 orport=9001 id=9B31F1F1C1554F9FFB3455911F82E818EF7C7883
|
||||
185.100.85.101:9030 orport=9001 id=4061C553CA88021B8302F0814365070AAE617270
|
||||
31.171.155.108:9030 orport=9001 id=D3E5EDDBE5159388704D6785BE51930AAFACEC6F
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
89.163.247.43:9030 orport=9001 id=BC7ACFAC04854C77167C7D66B7E471314ED8C410 ipv6=[2001:4ba0:fff7:25::5]:9001
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
95.85.8.226:80 orport=443 id=1211AC1BBB8A1AF7CBA86BCE8689AA3146B86423
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
85.214.151.72:9030 orport=9001 id=722D365140C8C52DBB3C9FF6986E3CEFFE2BA812
|
||||
|
||||
# email sent directly to teor
|
||||
72.52.75.27:9030 orport=9001 id=8567AD0A6369ED08527A8A8533A5162AC00F7678 # piecoopdotnet
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
5.9.146.203:80 orport=443 id=1F45542A24A61BF9408F1C05E0DCE4E29F2CBA11
|
||||
5.9.159.14:9030 orport=9001 id=0F100F60C7A63BED90216052324D29B08CFCF797
|
||||
|
||||
# Email sent directly to teor, verified using relay contact info
|
||||
# Assume details update is permanent
|
||||
5.9.147.226:9030 orport=9001 id=B0553175AADB0501E5A61FC61CEA3970BE130FF2 ipv6=[2a01:4f8:190:30e1::2]:9001 # zwiubel
|
||||
|
||||
# https://trac.torproject.org/projects/tor/ticket/22527#comment:1
|
||||
199.184.246.250:80 orport=443 id=1F6ABD086F40B890A33C93CC4606EE68B31C9556 ipv6=[2620:124:1009:1::171]:443
|
||||
|
||||
# https://trac.torproject.org/projects/tor/ticket/24695
|
||||
163.172.53.84:143 orport=21 id=1C90D3AEADFF3BCD079810632C8B85637924A58E ipv6=[2001:bc8:24f8::]:21 # Multivac
|
||||
|
||||
# Email sent directly to teor
|
||||
54.36.237.163:80 orport=443 id=DB2682153AC0CCAECD2BD1E9EBE99C6815807A1E # GermanCraft2
|
||||
|
||||
# Email sent directly to teor
|
||||
62.138.7.171:9030 orport=9001 id=9844B981A80B3E4B50897098E2D65167E6AEF127 # 0x3d004
|
||||
62.138.7.171:8030 orport=8001 id=9285B22F7953D7874604EEE2B470609AD81C74E9 # 0x3d005
|
||||
91.121.23.100:9030 orport=9001 id=3711E80B5B04494C971FB0459D4209AB7F2EA799 # 0x3d002
|
||||
91.121.23.100:8030 orport=8001 id=CFBBA0D858F02E40B1432A65F6D13C9BDFE7A46B # 0x3d001
|
||||
51.15.13.245:9030 orport=9001 id=CED527EAC230E7B56E5B363F839671829C3BA01B # 0x3d006
|
||||
51.15.13.245:8030 orport=8001 id=8EBB8D1CF48FE2AB95C451DA8F10DB6235F40F8A # 0x3d007
|
||||
|
||||
# Email sent directly to teor
|
||||
104.192.5.248:9030 orport=9001 id=BF735F669481EE1CCC348F0731551C933D1E2278 # Freeway11
|
||||
|
||||
# Email sent directly to teor
|
||||
# https://lists.torproject.org/pipermail/tor-relays/2017-December/013961.html
|
||||
178.17.174.14:9030 orport=9001 id=B06F093A3D4DFAD3E923F4F28A74901BD4F74EB1 # TorExitMoldova
|
||||
178.17.170.156:9030 orport=9001 id=41C59606AFE1D1AA6EC6EF6719690B856F0B6587 # TorExitMoldova2
|
||||
|
||||
# Email sent directly to teor
|
||||
163.172.221.44:59030 orport=59001 id=164604F5C86FC8CC9C0288BD9C02311958427597 # altego
|
||||
|
||||
# Email sent directly to teor
|
||||
46.38.237.221:9030 orport=9001 id=D30E9D4D639068611D6D96861C95C2099140B805 # mine
|
||||
|
||||
# https://lists.torproject.org/pipermail/tor-relays/2017-December/013911.html
|
||||
# https://lists.torproject.org/pipermail/tor-relays/2017-December/013912.html
|
||||
199.249.223.62:80 orport=443 id=0077BCBA7244DB3E6A5ED2746E86170066684887 # Quintex13
|
||||
199.249.224.45:80 orport=443 id=041646640AB306EA74B001966E86169B04CC88D2 # QuintexAirVPN26
|
||||
199.249.223.67:80 orport=443 id=155D6F57425F16C0624D77777641E4EB1B47C6F0 # Quintex18
|
||||
199.249.223.45:80 orport=443 id=1AE949967F82BBE7534A3D6BA77A7EBE1CED4369 # Quintex36
|
||||
199.249.223.63:80 orport=443 id=1DB25DF59DAA01B5BE3D3CEB8AFED115940EBE8B # Quintex14
|
||||
199.249.224.63:80 orport=443 id=1E5136DDC52FAE1219208F0A6BADB0BA62587EE6 # Quintex43
|
||||
199.249.224.46:80 orport=443 id=2ED4D25766973713EB8C56A290BF07E06B85BF12 # QuintexAirVPN27
|
||||
199.249.223.42:80 orport=443 id=3687FEC7E73F61AC66F7AE251E7DEE6BBD8C0252 # Quintex33
|
||||
199.249.223.49:80 orport=443 id=36D68478366CB8627866757EBCE7FB3C17FC1CB8 # Quintex40
|
||||
199.249.224.49:80 orport=443 id=3CA0D15567024D2E0B557DC0CF3E962B37999A79 # QuintexAirVPN30
|
||||
199.249.223.61:80 orport=443 id=40E7D6CE5085E4CDDA31D51A29D1457EB53F12AD # Quintex12
|
||||
199.249.223.76:80 orport=443 id=43209F6D50C657A56FE79AF01CA69F9EF19BD338 # QuintexAirVPN5
|
||||
199.249.224.41:80 orport=443 id=54A4820B46E65509BF3E2B892E66930A41759DE9 # QuintexAirVPN22
|
||||
199.249.223.73:80 orport=443 id=5649CB2158DA94FB747415F26628BEC07FA57616 # QuintexAirVPN8
|
||||
199.249.223.74:80 orport=443 id=5F4CD12099AF20FAF9ADFDCEC65316A376D0201C # QuintexAirVPN7
|
||||
199.249.223.75:80 orport=443 id=60D3667F56AEC5C69CF7E8F557DB21DDF6C36060 # QuintexAirVPN6
|
||||
199.249.223.46:80 orport=443 id=66E19E8C4773086F669A1E06A3F8C23B6C079129 # Quintex37
|
||||
199.249.224.65:80 orport=443 id=764BF8A03868F84C8F323C1A676AA254B80DC3BF # Quintex45
|
||||
199.249.223.48:80 orport=443 id=7A3DD280EA4CD4DD16EF8C67B93D9BDE184D1A81 # Quintex39
|
||||
199.249.224.68:80 orport=443 id=7E6E9A6FDDB8DC7C92F0CFCC3CBE76C29F061799 # Quintex48
|
||||
199.249.223.69:80 orport=443 id=7FA8E7E44F1392A4E40FFC3B69DB3B00091B7FD3 # Quintex20
|
||||
199.249.223.44:80 orport=443 id=8B80169BEF71450FC4069A190853523B7AEA45E1 # Quintex35
|
||||
199.249.224.60:80 orport=443 id=9314BD9503B9014261A65C221D77E57389DBCCC1 # Quintex50
|
||||
199.249.224.40:80 orport=443 id=9C1E7D92115D431385B8CAEA6A7C15FB89CE236B # QuintexAirVPN21
|
||||
199.249.223.65:80 orport=443 id=9D21F034C3BFF4E7737D08CF775DC1745706801F # Quintex16
|
||||
199.249.224.67:80 orport=443 id=9E2D7C6981269404AA1970B53891701A20424EF8 # Quintex47
|
||||
199.249.223.64:80 orport=443 id=9F2856F6D2B89AD4EF6D5723FAB167DB5A53519A # Quintex15
|
||||
199.249.224.48:80 orport=443 id=A0DB820FEC87C0405F7BF05DEE5E4ADED2BB9904 # QuintexAirVPN29
|
||||
199.249.224.64:80 orport=443 id=A4A393FEF48640961AACE92D041934B55348CEF9 # Quintex44
|
||||
199.249.223.72:80 orport=443 id=B028707969D8ED84E6DEA597A884F78AAD471971 # QuintexAirVPN9
|
||||
199.249.223.40:80 orport=443 id=B0CD9F9B5B60651ADC5919C0F1EAA87DBA1D9249 # Quintex31
|
||||
199.249.224.61:80 orport=443 id=B2197C23A4FF5D1C49EE45BA7688BA8BCCD89A0B # Quintex41
|
||||
199.249.223.71:80 orport=443 id=B6320E44A230302C7BF9319E67597A9B87882241 # QuintexAirVPN10
|
||||
199.249.223.60:80 orport=443 id=B7047FBDE9C53C39011CA84E5CB2A8E3543066D0 # Quintex11
|
||||
199.249.224.66:80 orport=443 id=C78AFFEEE320EA0F860961763E613FD2FAC855F5 # Quintex46
|
||||
199.249.224.44:80 orport=443 id=CB7C0D841FE376EF43F7845FF201B0290C0A239E # QuintexAirVPN25
|
||||
199.249.223.47:80 orport=443 id=CC14C97F1D23EE97766828FC8ED8582E21E11665 # Quintex38
|
||||
199.249.223.77:80 orport=443 id=CC4A3AE960E3617F49BF9887B79186C14CBA6813 # QuintexAirVPN4
|
||||
199.249.223.41:80 orport=443 id=D25210CE07C49F2A4F2BC7A506EB0F5EA7F5E2C2 # Quintex32
|
||||
199.249.223.79:80 orport=443 id=D33292FEDE24DD40F2385283E55C87F85C0943B6 # QuintexAirVPN2
|
||||
199.249.224.47:80 orport=443 id=D6FF2697CEA5C0C7DA84797C2E71163814FC2466 # QuintexAirVPN28
|
||||
199.249.223.68:80 orport=443 id=DF20497E487A979995D851A5BCEC313DF7E5BC51 # Quintex19
|
||||
199.249.223.43:80 orport=443 id=E480D577F58E782A5BC4FA6F49A6650E9389302F # Quintex34
|
||||
199.249.224.69:80 orport=443 id=EABC2DD0D47B5DB11F2D37EB3C60C2A4D91C10F2 # Quintex49
|
||||
199.249.223.78:80 orport=443 id=EC15DB62D9101481F364DE52EB8313C838BDDC29 # QuintexAirVPN3
|
||||
199.249.224.42:80 orport=443 id=F21DE9C7DE31601D9716781E17E24380887883D1 # QuintexAirVPN23
|
||||
199.249.223.81:80 orport=443 id=F7447E99EB5CBD4D5EB913EE0E35AC642B5C1EF3 # QuintexAirVPN1
|
||||
199.249.224.43:80 orport=443 id=FDD700C791CC6BB0AC1C2099A82CBC367AD4B764 # QuintexAirVPN24
|
||||
199.249.224.62:80 orport=443 id=FE00A3A835680E67FBBC895A724E2657BB253E97 # Quintex42
|
||||
199.249.223.66:80 orport=443 id=C5A53BCC174EF8FD0DCB223E4AA929FA557DEDB2 # Quintex17
|
||||
|
||||
# https://lists.torproject.org/pipermail/tor-relays/2017-December/013914.html
|
||||
5.196.23.64:9030 orport=9001 id=775B0FAFDE71AADC23FFC8782B7BEB1D5A92733E # Aerodynamik01
|
||||
217.182.75.181:9030 orport=9001 id=EFEACD781604EB80FBC025EDEDEA2D523AEAAA2F # Aerodynamik02
|
||||
193.70.43.76:9030 orport=9001 id=484A10BA2B8D48A5F0216674C8DD50EF27BC32F3 # Aerodynamik03
|
||||
149.56.141.138:9030 orport=9001 id=1938EBACBB1A7BFA888D9623C90061130E63BB3F # Aerodynamik04
|
||||
|
||||
# https://lists.torproject.org/pipermail/tor-relays/2017-December/013917.html
|
||||
104.200.20.46:80 orport=9001 id=78E2BE744A53631B4AAB781468E94C52AB73968B # bynumlawtor
|
||||
|
||||
# https://lists.torproject.org/pipermail/tor-relays/2017-December/013929.html
|
||||
139.99.130.178:80 orport=443 id=867B95CACD64653FEEC4D2CEFC5C49B4620307A7 # coffswifi2
|
||||
|
||||
# https://lists.torproject.org/pipermail/tor-relays/2017-December/013946.html
|
||||
172.98.193.43:80 orport=443 id=5E56738E7F97AA81DEEF59AF28494293DFBFCCDF # Backplane
|
||||
|
||||
# Email sent directly to teor
|
||||
62.210.254.132:80 orport=443 id=8456DFA94161CDD99E480C2A2992C366C6564410 # turingmachine
|
||||
|
||||
# Email sent directly to teor
|
||||
80.127.117.180:80 orport=443 id=328E54981C6DDD7D89B89E418724A4A7881E3192 ipv6=[2001:985:e77:10::4]:443 # sjc01
|
||||
|
||||
# https://lists.torproject.org/pipermail/tor-relays/2017-December/013960.html
|
||||
51.15.205.214:9030 orport=9001 id=8B6556601612F1E2AFCE2A12FFFAF8482A76DD1F ipv6=[2001:bc8:4400:2500::5:b07]:9001 # titania1
|
||||
51.15.205.214:9031 orport=9002 id=5E363D72488276160D062DDD2DFA25CFEBAF5EA9 ipv6=[2001:bc8:4400:2500::5:b07]:9002 # titania2
|
||||
|
||||
# Email sent directly to teor
|
||||
185.129.249.124:9030 orport=9001 id=1FA8F638298645BE58AC905276680889CB795A94 # treadstone
|
||||
|
||||
# https://lists.torproject.org/pipermail/tor-relays/2017-December/014000.html
|
||||
24.117.231.229:34175 orport=45117 id=CE24412AD69444954B4015E293AE53DDDAFEA3D6 # Anosognosia
|
||||
|
||||
# https://lists.torproject.org/pipermail/tor-relays/2018-January/014012.html
|
||||
128.31.0.13:80 orport=443 id=A53C46F5B157DD83366D45A8E99A244934A14C46 # csailmitexit
|
||||
|
||||
# Email sent directly to teor
|
||||
82.247.103.117:110 orport=995 id=C9B3C1661A9577BA24C1C2C6123918921A495509 # Casper01
|
||||
109.238.2.79:110 orport=995 id=7520892E3DD133D0B0464D01A158B54B8E2A8B75 # Casper02
|
||||
51.15.179.153:110 orport=995 id=BB60F5BA113A0B8B44B7B37DE3567FE561E92F78 # Casper04
|
||||
|
||||
# Email sent directly to teor
|
||||
80.127.107.179:80 orport=443 id=BC6B2E2F62ACC5EDECBABE64DA1E48F84DD98B78 ipv6=[2001:981:4a22:c::6]:443 # TVISION02
|
||||
|
||||
# https://lists.torproject.org/pipermail/tor-relays/2018-January/014020.html
|
||||
37.120.174.249:80 orport=443 id=11DF0017A43AF1F08825CD5D973297F81AB00FF3 ipv6=[2a03:4000:6:724c:df98:15f9:b34d:443]:443 # gGDHjdcC6zAlM8k08lX
|
||||
|
||||
# These fallbacks opted-in in previous releases, then changed their details,
|
||||
# and so we blacklisted them. Now we want to whitelist changes.
|
||||
# Assume details update is permanent
|
||||
85.230.184.93:9030 orport=443 id=855BC2DABE24C861CD887DB9B2E950424B49FC34 # Logforme
|
||||
176.31.180.157:143 orport=22 id=E781F4EC69671B3F1864AE2753E0890351506329 ipv6=[2001:41d0:8:eb9d::1]:22 # armbrust
|
||||
|
||||
# https://lists.torproject.org/pipermail/tor-relays/2018-January/014024.html
|
||||
82.161.212.209:9030 orport=9001 id=4E8CE6F5651E7342C1E7E5ED031E82078134FB0D ipv6=[2001:980:d7ed:1:ff:b0ff:fe00:d0b]:9001 # ymkeo
|
|
@ -1,5 +1,5 @@
|
|||
#!/usr/bin/python
|
||||
# Copyright (c) 2014-2017, The Tor Project, Inc.
|
||||
# Copyright (c) 2014, The Tor Project, Inc.
|
||||
# See LICENSE for licensing information
|
||||
#
|
||||
# This script reformats a section of the changelog to wrap everything to
|
||||
|
@ -12,7 +12,6 @@
|
|||
import os
|
||||
import re
|
||||
import sys
|
||||
import optparse
|
||||
|
||||
# ==============================
|
||||
# Oh, look! It's a cruddy approximation to Knuth's elegant text wrapping
|
||||
|
@ -34,8 +33,6 @@ import optparse
|
|||
|
||||
NO_HYPHENATE=set("""
|
||||
pf-divert
|
||||
tor-resolve
|
||||
tor-gencert
|
||||
""".split())
|
||||
|
||||
LASTLINE_UNDERFLOW_EXPONENT = 1
|
||||
|
@ -58,7 +55,7 @@ def generate_wrapping(words, divisions):
|
|||
w = words[last:i]
|
||||
last = i
|
||||
line = " ".join(w).replace("\xff ","-").replace("\xff","-")
|
||||
lines.append(line.strip())
|
||||
lines.append(line)
|
||||
return lines
|
||||
|
||||
def wrapping_quality(words, divisions, width1, width2):
|
||||
|
@ -118,10 +115,7 @@ def wrap_graf(words, prefix_len1=0, prefix_len2=0, width=72):
|
|||
|
||||
return lines
|
||||
|
||||
def hyphenatable(word):
|
||||
if "--" in word:
|
||||
return False
|
||||
|
||||
def hyphenateable(word):
|
||||
if re.match(r'^[^\d\-]\D*-', word):
|
||||
stripped = re.sub(r'^\W+','',word)
|
||||
stripped = re.sub(r'\W+$','',word)
|
||||
|
@ -134,7 +128,7 @@ def split_paragraph(s):
|
|||
|
||||
r = []
|
||||
for word in s.split():
|
||||
if hyphenatable(word):
|
||||
if hyphenateable(word):
|
||||
while "-" in word:
|
||||
a,word = word.split("-",1)
|
||||
r.append(a+"\xff")
|
||||
|
@ -162,13 +156,10 @@ TP_SECHEAD = 3
|
|||
TP_ITEMFIRST = 4
|
||||
TP_ITEMBODY = 5
|
||||
TP_END = 6
|
||||
TP_PREHEAD = 7
|
||||
|
||||
def head_parser(line):
|
||||
if re.match(r'^Changes in', line):
|
||||
if re.match(r'^[A-Z]', line):
|
||||
return TP_MAINHEAD
|
||||
elif re.match(r'^[A-Za-z]', line):
|
||||
return TP_PREHEAD
|
||||
elif re.match(r'^ o ', line):
|
||||
return TP_SECHEAD
|
||||
elif re.match(r'^\s*$', line):
|
||||
|
@ -187,69 +178,17 @@ def body_parser(line):
|
|||
return TP_BLANK
|
||||
elif re.match(r'^Changes in', line):
|
||||
return TP_END
|
||||
elif re.match(r'^\s+\S', line):
|
||||
return TP_HEADTEXT
|
||||
else:
|
||||
print "Weird line %r"%line
|
||||
|
||||
def clean_head(head):
|
||||
return head
|
||||
|
||||
def head_score(s):
|
||||
m = re.match(r'^ +o (.*)', s)
|
||||
if not m:
|
||||
print >>sys.stderr, "Can't score %r"%s
|
||||
return 99999
|
||||
lw = m.group(1).lower()
|
||||
if lw.startswith("security") and "feature" not in lw:
|
||||
score = -300
|
||||
elif lw.startswith("deprecated version"):
|
||||
score = -200
|
||||
elif lw.startswith("directory auth"):
|
||||
score = -150
|
||||
elif (('new' in lw and 'requirement' in lw) or
|
||||
('new' in lw and 'dependenc' in lw) or
|
||||
('build' in lw and 'requirement' in lw) or
|
||||
('removed' in lw and 'platform' in lw)):
|
||||
score = -100
|
||||
elif lw.startswith("major feature"):
|
||||
score = 00
|
||||
elif lw.startswith("major bug"):
|
||||
score = 50
|
||||
elif lw.startswith("major"):
|
||||
score = 70
|
||||
elif lw.startswith("minor feature"):
|
||||
score = 200
|
||||
elif lw.startswith("minor bug"):
|
||||
score = 250
|
||||
elif lw.startswith("minor"):
|
||||
score = 270
|
||||
else:
|
||||
score = 1000
|
||||
|
||||
if 'secur' in lw:
|
||||
score -= 2
|
||||
|
||||
if "(other)" in lw:
|
||||
score += 2
|
||||
|
||||
if '(' not in lw:
|
||||
score -= 1
|
||||
|
||||
return score
|
||||
|
||||
class ChangeLog(object):
|
||||
def __init__(self, wrapText=True, blogOrder=True, drupalBreak=False):
|
||||
self.prehead = []
|
||||
def __init__(self):
|
||||
self.mainhead = None
|
||||
self.headtext = []
|
||||
self.curgraf = None
|
||||
self.sections = []
|
||||
self.cursection = None
|
||||
self.lineno = 0
|
||||
self.wrapText = wrapText
|
||||
self.blogOrder = blogOrder
|
||||
self.drupalBreak = drupalBreak
|
||||
|
||||
def addLine(self, tp, line):
|
||||
self.lineno += 1
|
||||
|
@ -258,9 +197,6 @@ class ChangeLog(object):
|
|||
assert not self.mainhead
|
||||
self.mainhead = line
|
||||
|
||||
elif tp == TP_PREHEAD:
|
||||
self.prehead.append(line)
|
||||
|
||||
elif tp == TP_HEADTEXT:
|
||||
if self.curgraf is None:
|
||||
self.curgraf = []
|
||||
|
@ -304,11 +240,6 @@ class ChangeLog(object):
|
|||
self.lint_item(item_line, grafs, head_type)
|
||||
|
||||
def dumpGraf(self,par,indent1,indent2=-1):
|
||||
if not self.wrapText:
|
||||
for line in par:
|
||||
print line
|
||||
return
|
||||
|
||||
if indent2 == -1:
|
||||
indent2 = indent1
|
||||
text = " ".join(re.sub(r'\s+', ' ', line.strip()) for line in par)
|
||||
|
@ -318,218 +249,38 @@ class ChangeLog(object):
|
|||
initial_indent=" "*indent1,
|
||||
subsequent_indent=" "*indent2))
|
||||
|
||||
def dumpPreheader(self, graf):
|
||||
self.dumpGraf(graf, 0)
|
||||
print
|
||||
|
||||
def dumpMainhead(self, head):
|
||||
print head
|
||||
|
||||
def dumpHeadGraf(self, graf):
|
||||
self.dumpGraf(graf, 2)
|
||||
print
|
||||
|
||||
def dumpSectionHeader(self, header):
|
||||
print header
|
||||
|
||||
def dumpStartOfSections(self):
|
||||
pass
|
||||
|
||||
def dumpEndOfSections(self):
|
||||
pass
|
||||
|
||||
def dumpEndOfSection(self):
|
||||
print
|
||||
|
||||
def dumpEndOfChangelog(self):
|
||||
print
|
||||
|
||||
def dumpDrupalBreak(self):
|
||||
pass
|
||||
|
||||
def dumpItem(self, grafs):
|
||||
self.dumpGraf(grafs[0],4,6)
|
||||
for par in grafs[1:]:
|
||||
print
|
||||
self.dumpGraf(par,6,6)
|
||||
|
||||
def collateAndSortSections(self):
|
||||
heads = []
|
||||
sectionsByHead = { }
|
||||
for _, head, items in self.sections:
|
||||
head = clean_head(head)
|
||||
try:
|
||||
s = sectionsByHead[head]
|
||||
except KeyError:
|
||||
s = sectionsByHead[head] = []
|
||||
heads.append( (head_score(head), head.lower(), head, s) )
|
||||
|
||||
s.extend(items)
|
||||
|
||||
heads.sort()
|
||||
self.sections = [ (0, head, items) for _1,_2,head,items in heads ]
|
||||
|
||||
def dump(self):
|
||||
if self.prehead:
|
||||
self.dumpPreheader(self.prehead)
|
||||
|
||||
if not self.blogOrder:
|
||||
self.dumpMainhead(self.mainhead)
|
||||
|
||||
print self.mainhead
|
||||
for par in self.headtext:
|
||||
self.dumpHeadGraf(par)
|
||||
|
||||
if self.blogOrder:
|
||||
self.dumpMainhead(self.mainhead)
|
||||
|
||||
drupalBreakAfter = None
|
||||
if self.drupalBreak and len(self.sections) > 4:
|
||||
drupalBreakAfter = self.sections[1][2]
|
||||
|
||||
self.dumpStartOfSections()
|
||||
self.dumpGraf(par, 2)
|
||||
print
|
||||
for _,head,items in self.sections:
|
||||
if not head.endswith(':'):
|
||||
print >>sys.stderr, "adding : to %r"%head
|
||||
head = head + ":"
|
||||
self.dumpSectionHeader(head)
|
||||
print head
|
||||
for _,grafs in items:
|
||||
self.dumpItem(grafs)
|
||||
self.dumpEndOfSection()
|
||||
if items is drupalBreakAfter:
|
||||
self.dumpDrupalBreak()
|
||||
self.dumpEndOfSections()
|
||||
self.dumpEndOfChangelog()
|
||||
|
||||
# Let's turn bugs to html.
|
||||
BUG_PAT = re.compile('(bug|ticket|feature)\s+(\d{4,5})', re.I)
|
||||
def bug_html(m):
|
||||
return "%s <a href='https://bugs.torproject.org/%s'>%s</a>" % (m.group(1), m.group(2), m.group(2))
|
||||
|
||||
class HTMLChangeLog(ChangeLog):
|
||||
def __init__(self, *args, **kwargs):
|
||||
ChangeLog.__init__(self, *args, **kwargs)
|
||||
|
||||
def htmlText(self, graf):
|
||||
output = []
|
||||
for line in graf:
|
||||
line = line.rstrip().replace("&","&")
|
||||
line = line.rstrip().replace("<","<").replace(">",">")
|
||||
output.append(line.strip())
|
||||
output = " ".join(output)
|
||||
output = BUG_PAT.sub(bug_html, output)
|
||||
sys.stdout.write(output)
|
||||
|
||||
def htmlPar(self, graf):
|
||||
sys.stdout.write("<p>")
|
||||
self.htmlText(graf)
|
||||
sys.stdout.write("</p>\n")
|
||||
|
||||
def dumpPreheader(self, graf):
|
||||
self.htmlPar(graf)
|
||||
|
||||
def dumpMainhead(self, head):
|
||||
sys.stdout.write("<h2>%s</h2>"%head)
|
||||
|
||||
def dumpHeadGraf(self, graf):
|
||||
self.htmlPar(graf)
|
||||
|
||||
def dumpSectionHeader(self, header):
|
||||
header = header.replace(" o ", "", 1).lstrip()
|
||||
sys.stdout.write(" <li>%s\n"%header)
|
||||
sys.stdout.write(" <ul>\n")
|
||||
|
||||
def dumpEndOfSection(self):
|
||||
sys.stdout.write(" </ul>\n\n")
|
||||
|
||||
def dumpEndOfChangelog(self):
|
||||
pass
|
||||
|
||||
def dumpStartOfSections(self):
|
||||
print "<ul>\n"
|
||||
|
||||
def dumpEndOfSections(self):
|
||||
print "</ul>\n"
|
||||
|
||||
def dumpDrupalBreak(self):
|
||||
print "\n</ul>\n"
|
||||
print "<p> </p>"
|
||||
print "\n<!--break-->\n\n"
|
||||
print "<ul>"
|
||||
|
||||
def dumpItem(self, grafs):
|
||||
grafs[0][0] = grafs[0][0].replace(" - ", "", 1).lstrip()
|
||||
sys.stdout.write(" <li>")
|
||||
if len(grafs) > 1:
|
||||
for par in grafs:
|
||||
self.htmlPar(par)
|
||||
else:
|
||||
self.htmlText(grafs[0])
|
||||
self.dumpGraf(grafs[0],4,6)
|
||||
for par in grafs[1:]:
|
||||
print
|
||||
self.dumpGraf(par,6,6)
|
||||
print
|
||||
print
|
||||
|
||||
op = optparse.OptionParser(usage="usage: %prog [options] [filename]")
|
||||
op.add_option('-W', '--no-wrap', action='store_false',
|
||||
dest='wrapText', default=True,
|
||||
help='Do not re-wrap paragraphs')
|
||||
op.add_option('-S', '--no-sort', action='store_false',
|
||||
dest='sort', default=True,
|
||||
help='Do not sort or collate sections')
|
||||
op.add_option('-o', '--output', dest='output',
|
||||
default='-', metavar='FILE', help="write output to FILE")
|
||||
op.add_option('-H', '--html', action='store_true',
|
||||
dest='html', default=False,
|
||||
help="generate an HTML fragment")
|
||||
op.add_option('-1', '--first', action='store_true',
|
||||
dest='firstOnly', default=False,
|
||||
help="write only the first section")
|
||||
op.add_option('-b', '--blog-header', action='store_true',
|
||||
dest='blogOrder', default=False,
|
||||
help="Write the header in blog order")
|
||||
op.add_option('-B', '--blog', action='store_true',
|
||||
dest='blogFormat', default=False,
|
||||
help="Set all other options as appropriate for a blog post")
|
||||
op.add_option('--inplace', action='store_true',
|
||||
dest='inplace', default=False,
|
||||
help="Alter the ChangeLog in place")
|
||||
op.add_option('--drupal-break', action='store_true',
|
||||
dest='drupalBreak', default=False,
|
||||
help='Insert a drupal-friendly <!--break--> as needed')
|
||||
CL = ChangeLog()
|
||||
parser = head_parser
|
||||
|
||||
options,args = op.parse_args()
|
||||
|
||||
if options.blogFormat:
|
||||
options.blogOrder = True
|
||||
options.html = True
|
||||
options.sort = False
|
||||
options.wrapText = False
|
||||
options.firstOnly = True
|
||||
options.drupalBreak = True
|
||||
|
||||
if len(args) > 1:
|
||||
op.error("Too many arguments")
|
||||
elif len(args) == 0:
|
||||
if len(sys.argv) == 1:
|
||||
fname = 'ChangeLog'
|
||||
else:
|
||||
fname = args[0]
|
||||
fname = sys.argv[1]
|
||||
|
||||
if options.inplace:
|
||||
assert options.output == '-'
|
||||
options.output = fname
|
||||
fname_new = fname+".new"
|
||||
|
||||
if fname != '-':
|
||||
sys.stdin = open(fname, 'r')
|
||||
sys.stdin = open(fname, 'r')
|
||||
|
||||
nextline = None
|
||||
|
||||
if options.html:
|
||||
ChangeLogClass = HTMLChangeLog
|
||||
else:
|
||||
ChangeLogClass = ChangeLog
|
||||
|
||||
CL = ChangeLogClass(wrapText=options.wrapText,
|
||||
blogOrder=options.blogOrder,
|
||||
drupalBreak=options.drupalBreak)
|
||||
parser = head_parser
|
||||
|
||||
for line in sys.stdin:
|
||||
line = line.rstrip()
|
||||
tp = parser(line)
|
||||
|
@ -544,26 +295,14 @@ for line in sys.stdin:
|
|||
|
||||
CL.lint()
|
||||
|
||||
if options.output != '-':
|
||||
fname_new = options.output+".new"
|
||||
fname_out = options.output
|
||||
sys.stdout = open(fname_new, 'w')
|
||||
else:
|
||||
fname_new = fname_out = None
|
||||
|
||||
if options.sort:
|
||||
CL.collateAndSortSections()
|
||||
sys.stdout = open(fname_new, 'w')
|
||||
|
||||
CL.dump()
|
||||
|
||||
if options.firstOnly:
|
||||
sys.exit(0)
|
||||
|
||||
if nextline is not None:
|
||||
print nextline
|
||||
|
||||
for line in sys.stdin:
|
||||
sys.stdout.write(line)
|
||||
|
||||
if fname_new is not None:
|
||||
os.rename(fname_new, fname_out)
|
||||
os.rename(fname_new, fname)
|
||||
|
|
|
@ -1,38 +0,0 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
# Generate a fallback directory whitelist/blacklist line for every fingerprint
|
||||
# passed as an argument.
|
||||
#
|
||||
# Usage:
|
||||
# generateFallbackDirLine.py fingerprint ...
|
||||
|
||||
import sys
|
||||
import urllib2
|
||||
|
||||
import stem.descriptor.remote
|
||||
import stem.util.tor_tools
|
||||
|
||||
if len(sys.argv) <= 1:
|
||||
print('Usage: %s fingerprint ...' % sys.argv[0])
|
||||
sys.exit(1)
|
||||
|
||||
for fingerprint in sys.argv[1:]:
|
||||
if not stem.util.tor_tools.is_valid_fingerprint(fingerprint):
|
||||
print("'%s' isn't a valid relay fingerprint" % fingerprint)
|
||||
sys.exit(1)
|
||||
|
||||
try:
|
||||
desc = stem.descriptor.remote.get_server_descriptors(fingerprint).run()[0]
|
||||
except urllib2.HTTPError as exc:
|
||||
if exc.code == 404:
|
||||
print('# %s not found in recent descriptors' % fingerprint)
|
||||
continue
|
||||
else:
|
||||
raise
|
||||
|
||||
if not desc.dir_port:
|
||||
print("# %s needs a DirPort" % fingerprint)
|
||||
else:
|
||||
ipv6_addresses = [(address, port) for address, port, is_ipv6 in desc.or_addresses if is_ipv6]
|
||||
ipv6_field = ' ipv6=[%s]:%s' % ipv6_addresses[0] if ipv6_addresses else ''
|
||||
print('%s:%s orport=%s id=%s%s # %s' % (desc.address, desc.dir_port, desc.or_port, fingerprint, ipv6_field, desc.nickname))
|
|
@ -1,117 +0,0 @@
|
|||
#!/usr/bin/python
|
||||
|
||||
from __future__ import print_function
|
||||
from __future__ import with_statement
|
||||
import sys
|
||||
import re
|
||||
import os
|
||||
|
||||
|
||||
KNOWN_GROUPS = set([
|
||||
"Minor bugfix",
|
||||
"Minor bugfixes",
|
||||
"Major bugfix",
|
||||
"Major bugfixes",
|
||||
"Minor feature",
|
||||
"Minor features",
|
||||
"Major feature",
|
||||
"Major features",
|
||||
"New system requirements",
|
||||
"Testing",
|
||||
"Documentation",
|
||||
"Code simplification and refactoring",
|
||||
"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):
|
||||
have_warned = []
|
||||
|
||||
def warn(s):
|
||||
if not have_warned:
|
||||
have_warned.append(1)
|
||||
print("{}:".format(fname))
|
||||
print("\t{}".format(s))
|
||||
|
||||
m = re.search(r'(\d{3,})', os.path.basename(fname))
|
||||
if m:
|
||||
bugnum = m.group(1)
|
||||
else:
|
||||
bugnum = None
|
||||
|
||||
with open(fname) as f:
|
||||
contents = f.read()
|
||||
|
||||
if bugnum and bugnum not in contents:
|
||||
warn("bug number {} does not appear".format(bugnum))
|
||||
|
||||
m = re.match(r'^[ ]{2}o ([^\(:]*)([^:]*):', contents)
|
||||
if not m:
|
||||
warn("Header not in format expected. (' o Foo:' or ' o Foo (Bar):')")
|
||||
elif m.group(1).strip() not in KNOWN_GROUPS:
|
||||
warn("Unrecognized header: %r" % m.group(1))
|
||||
elif (m.group(1) in NEEDS_SUBCATEGORIES and '(' not in m.group(2)):
|
||||
warn("Missing subcategory on %r" % m.group(1))
|
||||
|
||||
if m:
|
||||
isBug = ("bug" in m.group(1).lower() or "fix" in m.group(1).lower())
|
||||
else:
|
||||
isBug = False
|
||||
|
||||
contents = " ".join(contents.split())
|
||||
|
||||
if re.search(r'\#\d{2,}', contents):
|
||||
warn("Don't use a # before ticket numbers. ('bug 1234' not '#1234')")
|
||||
|
||||
if isBug and not re.search(r'(\d+)', contents):
|
||||
warn("Ticket marked as bugfix, but does not mention a number.")
|
||||
elif isBug and not re.search(r'Fixes ([a-z ]*)bugs? (\d+)', contents):
|
||||
warn("Ticket marked as bugfix, but does not say 'Fixes bug XXX'")
|
||||
|
||||
if re.search(r'[bB]ug (\d+)', contents):
|
||||
if not re.search(r'[Bb]ugfix on ', contents):
|
||||
warn("Bugfix does not say 'bugfix on X.Y.Z'")
|
||||
elif not re.search('[fF]ixes ([a-z ]*)bugs? (\d+)((, \d+)* and \d+)?; bugfix on ',
|
||||
contents):
|
||||
warn("Bugfix does not say 'Fixes bug X; bugfix on Y'")
|
||||
elif re.search('tor-([0-9]+)', contents):
|
||||
warn("Do not prefix versions with 'tor-'. ('0.1.2', not 'tor-0.1.2'.)")
|
||||
|
||||
return have_warned != []
|
||||
|
||||
def files(args):
|
||||
"""Walk through the arguments: for directories, yield their contents;
|
||||
for files, just yield the files. Only search one level deep, because
|
||||
that's how the changes directory is laid out."""
|
||||
for f in args:
|
||||
if os.path.isdir(f):
|
||||
for item in os.listdir(f):
|
||||
if item.startswith("."): #ignore dotfiles
|
||||
continue
|
||||
yield os.path.join(f, item)
|
||||
else:
|
||||
yield f
|
||||
|
||||
if __name__ == '__main__':
|
||||
problems = 0
|
||||
for fname in files(sys.argv[1:]):
|
||||
if fname.endswith("~"):
|
||||
continue
|
||||
if lintfile(fname):
|
||||
problems += 1
|
||||
|
||||
if problems:
|
||||
sys.exit(1)
|
||||
else:
|
||||
sys.exit(0)
|
|
@ -1,74 +0,0 @@
|
|||
#!/usr/bin/python
|
||||
|
||||
"""
|
||||
This script parses the stderr output of doxygen and looks for undocumented
|
||||
stuff. By default, it just counts the undocumented things per file. But with
|
||||
the -A option, it rewrites the files to stick in /*DOCDOC*/ comments
|
||||
to highlight the undocumented stuff.
|
||||
"""
|
||||
|
||||
import os
|
||||
import re
|
||||
import shutil
|
||||
import sys
|
||||
|
||||
warning_pattern = re.compile(r'^([^:]+):(\d+): warning: (.*) is not documented')
|
||||
|
||||
def readDoxygenOutput(f):
|
||||
" yields (cfilename, lineno, thingname) "
|
||||
for line in f:
|
||||
m = warning_pattern.match(line)
|
||||
if m:
|
||||
yield m.groups()
|
||||
|
||||
warnings = {}
|
||||
|
||||
def buildWarnings():
|
||||
for fn, lineno, what in list(readDoxygenOutput(sys.stdin)):
|
||||
warnings.setdefault(fn, []).append( (int(lineno), what) )
|
||||
|
||||
def count(fn):
|
||||
if os.path.abspath(fn) not in warnings:
|
||||
print "0\t%s"%fn
|
||||
else:
|
||||
n = len(warnings[os.path.abspath(fn)])
|
||||
print "%d\t%s"%(n,fn)
|
||||
|
||||
def getIndentation(line):
|
||||
s = line.lstrip()
|
||||
return line[:len(line)-len(s)]
|
||||
|
||||
def annotate(filename):
|
||||
if os.path.abspath(filename) not in warnings:
|
||||
return
|
||||
with open(filename) as f:
|
||||
lines = f.readlines()
|
||||
w = warnings[os.path.abspath(filename)][:]
|
||||
w.sort()
|
||||
w.reverse()
|
||||
|
||||
for lineno, what in w:
|
||||
lineno -= 1 # list is 0-indexed.
|
||||
if 'DOCDOC' in lines[lineno]:
|
||||
continue
|
||||
ind = getIndentation(lines[lineno])
|
||||
lines.insert(lineno, "%s/* DOCDOC %s */\n"%(ind,what))
|
||||
|
||||
shutil.copy(filename, filename+".orig")
|
||||
with open(filename, 'w') as f:
|
||||
for l in lines:
|
||||
f.write(l)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
if len(sys.argv) == 1:
|
||||
print "Usage: locatemissingdoxygen.py [-A] filename... <doxygen_log"
|
||||
sys.exit(1)
|
||||
buildWarnings()
|
||||
if sys.argv[1] == '-A':
|
||||
del sys.argv[1]
|
||||
func = annotate
|
||||
else:
|
||||
func = count
|
||||
for fname in sys.argv[1:]:
|
||||
func(fname)
|
|
@ -1,28 +0,0 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
# Lookup fallback directory contact lines for every fingerprint passed as an
|
||||
# argument.
|
||||
#
|
||||
# Usage:
|
||||
# lookupFallbackDirContact.py fingerprint ...
|
||||
|
||||
import sys
|
||||
|
||||
import stem.descriptor.remote as remote
|
||||
|
||||
if len(sys.argv) <= 1:
|
||||
print "Usage: {} fingerprint ...".format(sys.argv[0])
|
||||
sys.exit(-1)
|
||||
|
||||
# we need descriptors, because the consensus does not have contact infos
|
||||
descriptor_list = remote.get_server_descriptors(fingerprints=sys.argv[1:]).run()
|
||||
|
||||
descriptor_list_fingerprints = []
|
||||
for d in descriptor_list:
|
||||
assert d.fingerprint in sys.argv[1:]
|
||||
descriptor_list_fingerprints.append(d.fingerprint)
|
||||
print "{} {}".format(d.fingerprint, d.contact)
|
||||
|
||||
for fingerprint in sys.argv[1:]:
|
||||
if fingerprint not in descriptor_list_fingerprints:
|
||||
print "{} not found in current descriptors".format(fingerprint)
|
|
@ -1,6 +1,6 @@
|
|||
#!/usr/bin/python
|
||||
#
|
||||
# Copyright (c) 2008-2017, The Tor Project, Inc.
|
||||
# Copyright (c) 2008-2013, The Tor Project, Inc.
|
||||
# See LICENSE for licensing information.
|
||||
#
|
||||
# Hi!
|
||||
|
@ -33,6 +33,8 @@
|
|||
# files that we've snarfed in from somebody else, whose C we do no intend
|
||||
# to document for them.
|
||||
SKIP_FILES = [ "OpenBSD_malloc_Linux.c",
|
||||
"eventdns.c",
|
||||
"eventdns.h",
|
||||
"strlcat.c",
|
||||
"strlcpy.c",
|
||||
"sha256.c",
|
||||
|
@ -101,7 +103,7 @@ def read():
|
|||
|
||||
def findline(lines, lineno, ident):
|
||||
"""Given a list of all the lines in the file (adjusted so 1-indexing works),
|
||||
a line number that ident is allegedly on, and ident, I figure out
|
||||
a line number that ident is alledgedly on, and ident, I figure out
|
||||
the line where ident was really declared."""
|
||||
lno = lineno
|
||||
for lineno in xrange(lineno, 0, -1):
|
||||
|
|
|
@ -1,29 +0,0 @@
|
|||
#!/bin/sh
|
||||
|
||||
# You can find calltool at https://gitweb.torproject.org/user/nickm/calltool.git
|
||||
|
||||
set -e
|
||||
|
||||
if test "x$CALLTOOL_PATH" != "x"; then
|
||||
PYTHONPATH="${CALLTOOL_PATH}:${PYTHONPATH}"
|
||||
export PYTHONPATH
|
||||
fi
|
||||
|
||||
mkdir -p callgraph
|
||||
|
||||
SUBITEMS="fn_graph fn_invgraph fn_scc fn_scc_weaklinks module_graph module_invgraph module_scc module_scc_weaklinks"
|
||||
|
||||
for calculation in $SUBITEMS; do
|
||||
echo "======== $calculation"
|
||||
python -m calltool $calculation > callgraph/$calculation
|
||||
done
|
||||
|
||||
echo <<EOF > callgraph/README
|
||||
This directory holds output from calltool, as run on Tor. For more
|
||||
information about each of these files, see the NOTES and README files in
|
||||
the calltool distribution.
|
||||
|
||||
You can find calltool at
|
||||
https://gitweb.torproject.org/user/nickm/calltool.git
|
||||
EOF
|
||||
|
|
@ -1,10 +1,12 @@
|
|||
#!/usr/bin/python
|
||||
# Copyright (c) 2014-2017, The Tor Project, Inc.
|
||||
# Copyright (c) 2014, The Tor Project, Inc.
|
||||
# See LICENSE for licensing information
|
||||
|
||||
"""This script sorts a bunch of changes files listed on its command
|
||||
line into roughly the order in which they should appear in the
|
||||
changelog.
|
||||
|
||||
TODO: collation support.
|
||||
"""
|
||||
|
||||
import re
|
||||
|
@ -16,36 +18,10 @@ def fetch(fn):
|
|||
s = "%s\n" % s.rstrip()
|
||||
return s
|
||||
|
||||
CSR='Code simplification and refactoring'
|
||||
|
||||
REPLACEMENTS = {
|
||||
# plurals
|
||||
'Minor bugfix' : 'Minor bugfixes',
|
||||
'Major bugfix' : 'Major bugfixes',
|
||||
'Minor feature' : 'Minor features',
|
||||
'Major feature' : 'Major features',
|
||||
'Removed feature' : 'Removed features',
|
||||
'Code simplification and refactorings' : CSR,
|
||||
'Code simplifications and refactoring' : CSR,
|
||||
'Code simplifications and refactorings' : CSR,
|
||||
|
||||
# wrong words
|
||||
'Minor fix' : 'Minor bugfixes',
|
||||
'Major fix' : 'Major bugfixes',
|
||||
'Minor fixes' : 'Minor bugfixes',
|
||||
'Major fixes' : 'Major bugfixes',
|
||||
'Minor enhancement' : 'Minor features',
|
||||
'Minor enhancements' : 'Minor features',
|
||||
'Major enhancement' : 'Major features',
|
||||
'Major enhancements' : 'Major features',
|
||||
}
|
||||
|
||||
def score(s,fname=None):
|
||||
m = re.match(r'^ +o ([^\n]*)\n(.*)', s, re.M|re.S)
|
||||
def score(s):
|
||||
m = re.match(r'^ +o (.*)', s)
|
||||
if not m:
|
||||
print >>sys.stderr, "Can't score %r from %s"%(s,fname)
|
||||
heading = m.group(1)
|
||||
heading = REPLACEMENTS.get(heading, heading)
|
||||
print >>sys.stderr, "Can't score %r"%s
|
||||
lw = m.group(1).lower()
|
||||
if lw.startswith("major feature"):
|
||||
score = 0
|
||||
|
@ -62,47 +38,12 @@ def score(s,fname=None):
|
|||
else:
|
||||
score = 100
|
||||
|
||||
return (score, lw, heading, m.group(2))
|
||||
|
||||
def splitChanges(s):
|
||||
this_entry = []
|
||||
for line in s.split("\n"):
|
||||
if line.strip() == "":
|
||||
continue
|
||||
if re.match(r" +o ", line):
|
||||
if len(this_entry) > 2:
|
||||
yield "".join(this_entry)
|
||||
curHeader = line
|
||||
this_entry = [ curHeader, "\n" ]
|
||||
continue
|
||||
elif re.match(r" +- ", line):
|
||||
if len(this_entry) > 2:
|
||||
yield "".join(this_entry)
|
||||
this_entry = [ curHeader, "\n" ]
|
||||
|
||||
this_entry.append(line)
|
||||
this_entry.append("\n")
|
||||
|
||||
if len(this_entry) > 2:
|
||||
yield "".join(this_entry)
|
||||
return (score, lw, s)
|
||||
|
||||
|
||||
changes = []
|
||||
|
||||
for fn in sys.argv[1:]:
|
||||
if fn.endswith('~'):
|
||||
continue
|
||||
for change in splitChanges(fetch(fn)):
|
||||
changes.append(score(change,fn))
|
||||
changes = [ score(fetch(fn)) for fn in sys.argv[1:] if not fn.endswith('~') ]
|
||||
|
||||
changes.sort()
|
||||
|
||||
last_lw = "this is not a header"
|
||||
for _, lw, header, rest in changes:
|
||||
if lw == last_lw:
|
||||
print rest,
|
||||
else:
|
||||
print
|
||||
print " o",header
|
||||
print rest,
|
||||
last_lw = lw
|
||||
for _, _, s in changes:
|
||||
print s
|
||||
|
|
|
@ -1,7 +0,0 @@
|
|||
#!/usr/bin/perl -i -w -p
|
||||
|
||||
$NEWYEAR=2017;
|
||||
|
||||
s/Copyright(.*) (201[^7]), The Tor Project/Copyright$1 $2-${NEWYEAR}, The Tor Project/;
|
||||
|
||||
s/Copyright(.*)-(20..), The Tor Project/Copyright$1-${NEWYEAR}, The Tor Project/;
|
File diff suppressed because it is too large
Load Diff
|
@ -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,8 +1,8 @@
|
|||
#!/usr/bin/perl -w
|
||||
|
||||
$CONFIGURE_IN = '@abs_top_srcdir@/configure.ac';
|
||||
$ORCONFIG_H = '@abs_top_srcdir@/src/win32/orconfig.h';
|
||||
$TOR_NSI = '@abs_top_srcdir@/contrib/win32build/tor-mingw.nsi.in';
|
||||
$CONFIGURE_IN = './configure.ac';
|
||||
$ORCONFIG_H = './src/win32/orconfig.h';
|
||||
$TOR_NSI = './contrib/win32build/tor-mingw.nsi.in';
|
||||
|
||||
$quiet = 1;
|
||||
|
|
@ -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())
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue