Compare commits

..

143 Commits

Author SHA1 Message Date
Nick Mathewson 279fa65d34 Merge branch 'maint-0.2.5' into release-0.2.5 2018-04-05 08:22:33 -04:00
Nick Mathewson 1d281eb933 Merge branch 'maint-0.2.5' into release-0.2.5 2018-03-19 05:42:43 -04:00
Nick Mathewson 0d63a60643 Merge branch 'maint-0.2.5' into release-0.2.5 2018-03-13 10:58:02 -04:00
Nick Mathewson b2c220a623 Merge branch 'maint-0.2.5' into release-0.2.5 2018-02-08 10:29:05 -05:00
Nick Mathewson 7d1d868ea0 Merge branch 'maint-0.2.5' into release-0.2.5 2018-01-19 10:18:59 -05:00
Nick Mathewson e212c752f2 Merge branch 'maint-0.2.5' into release-0.2.5 2018-01-08 09:34:56 -05:00
Nick Mathewson eb0c7ab433 Merge branch 'maint-0.2.5' into release-0.2.5 2017-12-21 10:58:20 -05:00
Nick Mathewson ba0c0ef771 Merge branch 'maint-0.2.5' into release-0.2.5 2017-12-20 12:15:23 -05:00
Nick Mathewson beeeeb0afa Merge branch 'maint-0.2.5' into release-0.2.5 2017-12-11 16:56:31 -05:00
Nick Mathewson ca19b2115a Merge branch 'maint-0.2.5' into release-0.2.5 2017-12-11 16:53:07 -05:00
Nick Mathewson 20ca62ffb5 Merge branch 'maint-0.2.5' into release-0.2.5 2017-12-01 12:13:39 -05:00
Nick Mathewson 9cb1c2b4ad Merge branch 'maint-0.2.5' into release-0.2.5 2017-12-01 09:35:43 -05:00
Nick Mathewson 7d83cfb3ab copy changelog to releasenotes 2017-12-01 09:14:18 -05:00
Nick Mathewson b97fb313a9 changelog for 0.2.5.16 2017-11-30 15:26:33 -05:00
Nick Mathewson 4902cfcf19 Merge branch 'maint-0.2.5' into release-0.2.5 2017-11-30 12:28:39 -05:00
Nick Mathewson 6d0f332a2e Merge branch 'maint-0.2.5' into release-0.2.5 2017-11-30 12:07:59 -05:00
Nick Mathewson 6177674a5b Merge branch 'maint-0.2.5' into release-0.2.5 2017-11-18 11:03:16 -05:00
Nick Mathewson e26f387026 Merge branch 'maint-0.2.5' into release-0.2.5 2017-11-11 12:23:33 -05:00
Nick Mathewson 765fd0845f Merge branch 'maint-0.2.5' into release-0.2.5 2017-10-25 09:29:00 -04:00
Nick Mathewson 5a0e73c75b Set a date; make releasenotes (025) 2017-10-25 08:07:19 -04:00
Nick Mathewson 078604630d Merge branch 'maint-0.2.5' into release-0.2.5 2017-10-24 09:10:42 -04:00
Nick Mathewson 8669a1ea50 Warn that 025 will become deprecated next may. 2017-10-24 09:05:23 -04:00
Nick Mathewson 55c918e7d2 begin a changelog for 0.2.5.15 2017-10-24 09:01:43 -04:00
Nick Mathewson 5e1bad3259 Merge branch 'maint-0.2.5' into release-0.2.5 2017-10-23 09:03:58 -04:00
Nick Mathewson 533ae56fcf Merge branch 'maint-0.2.5' into release-0.2.5 2017-10-23 08:57:22 -04:00
Nick Mathewson 558eafe56e Merge branch 'maint-0.2.5' into release-0.2.5 2017-10-05 11:04:59 -04:00
Nick Mathewson e2979ebe25 Merge branch 'maint-0.2.5' into release-0.2.5 2017-10-05 11:03:35 -04:00
Nick Mathewson e17659b701 Merge branch 'maint-0.2.5' into release-0.2.5 2017-09-07 15:18:00 -04:00
Nick Mathewson 4e10ada1e8 Merge branch 'maint-0.2.5' into release-0.2.5 2017-08-03 08:44:31 -04:00
Nick Mathewson 2e2ec4cb5e Merge branch 'maint-0.2.5' into release-0.2.5 2017-08-01 11:19:28 -04:00
Nick Mathewson 0c44446c40 Merge branch 'maint-0.2.5' into release-0.2.5 2017-07-26 15:39:55 -04:00
Nick Mathewson d1340423fa Merge branch 'maint-0.2.5' into release-0.2.5 2017-07-26 15:38:48 -04:00
Nick Mathewson e4d7f97c40 Merge branch 'maint-0.2.5' into release-0.2.5 2017-07-07 10:51:28 -04:00
Nick Mathewson 9c96dbe7b0 Merge branch 'maint-0.2.5' into release-0.2.5 2017-07-05 13:43:31 -04:00
Nick Mathewson e6d77520ef Merge branch 'maint-0.2.5' into release-0.2.5 2017-06-27 11:04:44 -04:00
Nick Mathewson c1195d42bc Merge branch 'maint-0.2.5' into release-0.2.5 2017-06-09 09:58:45 -04:00
Nick Mathewson 24bc8caf35 Merge branch 'maint-0.2.5' into release-0.2.5 2017-06-08 14:06:56 -04:00
Nick Mathewson e14006a545 changelog for 0.2.5.14 2017-06-08 09:47:44 -04:00
Nick Mathewson d9dd67e216 Merge branch 'maint-0.2.5' into release-0.2.5 2017-06-08 09:29:49 -04:00
Nick Mathewson 0a78d2947c Merge branch 'maint-0.2.5' into release-0.2.5 2017-06-08 09:21:15 -04:00
Nick Mathewson 020c003a63 Merge branch 'maint-0.2.5' into release-0.2.5 2017-06-05 14:39:00 -04:00
Nick Mathewson b104ea724d Merge branch 'maint-0.2.5' into release-0.2.5 2017-06-05 12:00:14 -04:00
Nick Mathewson 33b69e6884 Merge branch 'maint-0.2.5' into release-0.2.5 2017-05-08 08:08:01 -04:00
Nick Mathewson 148d76c092 Merge branch 'maint-0.2.5' into release-0.2.5 2017-04-06 08:32:36 -04:00
Nick Mathewson 51ca3dc811 Merge branch 'maint-0.2.5' into release-0.2.5 2017-03-08 10:10:36 -05:00
Nick Mathewson 45245fe29e Pick a date, update ReleaseNotes. (0.2.5) 2017-03-03 14:56:01 -05:00
Nick Mathewson 5c5298e4ff Merge branch 'maint-0.2.5' into release-0.2.5 2017-02-28 10:25:24 -05:00
Nick Mathewson 30844dd51a Sort changelog in release-0.2.5 2017-02-28 10:11:38 -05:00
Nick Mathewson 8e0bf7fac1 Adjust 0.2.5.13 changelog entry from 0.3.0.4-rc to match 2017-02-28 10:05:50 -05:00
Nick Mathewson b909aed534 Fix 025 EOL date 2017-02-23 16:48:15 -05:00
Nick Mathewson 7b1762481b Begin an 0.2.5.13 changelog
To build this changelog, I've gone through the entries in
release-0.2.5's changes subdirectory, and looked up the ChangeLog
entry for each.  I have not sorted them yet.
2017-02-23 15:50:27 -05:00
Nick Mathewson a8a1e7e8da Merge branch 'maint-0.2.5' into release-0.2.5 2017-02-15 07:53:05 -05:00
Nick Mathewson c0ff59f870 Merge branch 'maint-0.2.5' into release-0.2.5 2017-02-15 07:50:48 -05:00
Nick Mathewson c0257f14cd Merge branch 'maint-0.2.5' into release-0.2.5 2017-02-13 14:39:13 -05:00
Nick Mathewson 2f6a66a174 Merge branch 'maint-0.2.5' into release-0.2.5 2017-02-07 10:39:50 -05:00
Nick Mathewson 72d9e057c3 Merge branch 'maint-0.2.5' into release-0.2.5 2017-02-07 09:21:13 -05:00
Nick Mathewson 9203b3e4ed Merge branch 'maint-0.2.5' into release-0.2.5 2017-02-07 08:56:39 -05:00
Nick Mathewson 2393e67b2e Merge branch 'maint-0.2.5' into release-0.2.5 2017-02-07 08:41:33 -05:00
Nick Mathewson e89163845a Merge branch 'maint-0.2.5' into release-0.2.5 2017-01-11 09:12:06 -05:00
Nick Mathewson 2e02b59772 Merge branch 'maint-0.2.5' into release-0.2.5 2016-12-20 18:21:40 -05:00
Nick Mathewson 056978c31c Merge branch 'maint-0.2.5' into release-0.2.5 2016-12-20 18:11:16 -05:00
Nick Mathewson 5322713b48 Merge branch 'maint-0.2.5' into release-0.2.5 2016-12-09 08:34:45 -05:00
Nick Mathewson 1ffe29ff8d Merge branch 'maint-0.2.5' into release-0.2.5 2016-11-07 09:30:05 -05:00
Nick Mathewson d27160b407 Merge branch 'maint-0.2.5' into release-0.2.5 2016-10-06 10:00:18 -04:00
Nick Mathewson 53947389a7 Merge branch 'maint-0.2.5' into release-0.2.5 2016-07-05 13:51:40 -04:00
Nick Mathewson 8c2cad52c4 Merge branch 'maint-0.2.5' into release-0.2.5 2016-07-05 12:25:11 -04:00
Nick Mathewson 77abd68855 Merge branch 'maint-0.2.5' into release-0.2.5 2016-05-09 14:55:31 -04:00
Nick Mathewson c0c92c3e2a Merge branch 'maint-0.2.5' into release-0.2.5 2016-04-07 10:46:32 -04:00
Nick Mathewson 01d5921435 Merge branch 'maint-0.2.5' into release-0.2.5 2016-01-07 09:47:44 -08:00
Nick Mathewson c79976bc9b Merge remote-tracking branch 'origin/maint-0.2.4' into release-0.2.5 2015-04-27 14:16:15 -04:00
Nick Mathewson 99d0579ff5 changelog for 0.2.5.12 2015-04-06 09:58:07 -04:00
Nick Mathewson c1237ed516 Merge branch 'maint-0.2.5' into release-0.2.5 2015-04-06 09:57:08 -04:00
Nick Mathewson 5a4caad88d Merge remote-tracking branch 'origin/maint-0.2.5' into release-0.2.5 2015-04-06 09:31:09 -04:00
Nick Mathewson 53a605ee00 Merge branch 'maint-0.2.5' into release-0.2.5 2015-04-03 09:52:15 -04:00
Nick Mathewson cfb61f909a forward-part 0.2.4 changelog; copy changelog into release notes 2015-03-17 09:40:44 -04:00
Nick Mathewson 4dcfc3ded6 Pick a release date; add a sentence. 2015-03-17 09:22:53 -04:00
Nick Mathewson 8ba0ea4419 Another entry for the 0.2.5.11 changelog 2015-03-12 12:53:06 -04:00
Nick Mathewson e573a51916 Merge branch 'maint-0.2.5' into release-0.2.5 2015-03-12 12:52:10 -04:00
Nick Mathewson 6bf06c5656 Merge branch 'maint-0.2.5' into release-0.2.5
Conflicts:
	configure.ac
	contrib/win32build/tor-mingw.nsi.in
	src/win32/orconfig.h
2015-03-12 10:53:21 -04:00
Nick Mathewson 78d9af302e fold entries into changelog for 025 2015-03-12 10:46:18 -04:00
Nick Mathewson a286fbd711 Merge branch 'maint-0.2.5' into release-0.2.5 2015-03-09 16:24:54 -04:00
Nick Mathewson 2f962b9309 Copy changelog entries from the 0.2.6 changelog into the 0.2.5.11 changelog 2015-03-09 15:42:39 -04:00
Nick Mathewson b0fff2a9c5 Merge remote-tracking branch 'origin/maint-0.2.5' into release-0.2.5 2015-03-09 13:36:57 -04:00
Nick Mathewson 4b54ad017d Merge remote-tracking branch 'origin/maint-0.2.5' into release-0.2.5 2014-12-22 10:27:08 -05:00
Nick Mathewson 1d02f64932 Merge branch 'maint-0.2.5' into release-0.2.5 2014-10-24 09:23:29 -04:00
Roger Dingledine 42b42605f8 declare 0.2.3.x end-of-life more clearly 2014-10-23 22:05:54 -04:00
Nick Mathewson 7fd7a2c7c3 Note 0.2.3.x deprecation 2014-10-23 15:57:37 -04:00
Nick Mathewson 495d201c36 I plan to release Tor 0.2.5.10 tomorrow. 2014-10-23 12:13:45 -04:00
Nick Mathewson 44b933cf01 Write a first-draft for an 0.2.5.10 blurb 2014-10-20 12:33:42 -04:00
Nick Mathewson 0829e05630 Start work on summarizing 0.2.5.10 stuff. Remove a bugfix-on-0.2.5 entry 2014-10-20 12:22:29 -04:00
Nick Mathewson 023ce9e0f8 Merge branch 'maint-0.2.5' into release-0.2.5
Conflicts:
	configure.ac
	contrib/win32build/tor-mingw.nsi.in
	src/win32/orconfig.h
2014-10-20 10:33:18 -04:00
Nick Mathewson 334f4f60e8 forward-port the 0.2.4.25 changelog to release-0.2.5 changelog and releasenotes 2014-10-20 10:00:49 -04:00
Nick Mathewson e6ae154ab4 Better release blurb, maybe. 2014-10-19 21:55:51 -04:00
Nick Mathewson f69c7a152f Bump version to 0.2.5.9-rc 2014-10-19 21:45:59 -04:00
Nick Mathewson 056ff52c53 Re-run format-changelog and set the release date 2014-10-19 21:40:53 -04:00
Nick Mathewson b82be6cf66 Fold 13471 into changelog and releasenotes 2014-10-19 21:39:50 -04:00
Nick Mathewson 095080360f Merge branch 'maint-0.2.5' into release-0.2.5 2014-10-19 21:38:17 -04:00
Nick Mathewson 9ffb2d8818 Change 0.2.5.9 to 0.2.5.9-rc in the changelog; write a draft blurb 2014-10-19 14:25:45 -04:00
Nick Mathewson 42336f32f0 Sort and collate the ReleaseNotes sections again. 2014-10-19 14:21:43 -04:00
Nick Mathewson 6a58a380f9 Recategorize some uncategorized things in the releasenotes 2014-10-19 14:17:34 -04:00
Nick Mathewson e6c16e6267 Move around some entries in the ReleaseNotes between sections 2014-10-19 13:25:22 -04:00
Nick Mathewson 6880aaf0a9 Automatically sort and collate ReleaseNotes.
No entries have been removed or edited or added in this commit; no
section names have been changed.  We may need another round of
removal/editing/etc after we edit some section names.  We may want to
re-order items within sections.
2014-10-19 12:56:12 -04:00
Nick Mathewson dfcdb34b8e Copy 0.2.5.9 entries into ReleaseNotes 2014-10-19 12:55:05 -04:00
Nick Mathewson f17167ac0a Tidy an entry in the 0259 changelog. Now I like the entries. 2014-10-19 12:53:56 -04:00
Nick Mathewson 96f46922c7 Format_changelog on the 0.2.5.9 changelog 2014-10-19 12:52:24 -04:00
Nick Mathewson c82aaaa48a Copy changes/* into the ChangeLog file for 0.2.5.9 2014-10-19 12:50:12 -04:00
Nick Mathewson f77d8901fc Merge remote-tracking branch 'origin/maint-0.2.5' into release-0.2.5 2014-10-19 11:13:09 -04:00
Roger Dingledine a64f3ab3ee put an ordering on 0.2.4.24 vs 0.2.5.8-rc 2014-09-22 14:19:34 -04:00
Roger Dingledine 36b979bb8d bump version to 0.2.5.8-rc 2014-09-22 14:01:50 -04:00
Roger Dingledine 347a9f98b8 commit my in-progress 0.2.5.x release notes
they're far from done, but this way i won't lose them
2014-09-21 16:23:48 -04:00
Roger Dingledine 9fe7395984 merge in the next changes entry 2014-09-20 17:11:43 -04:00
Roger Dingledine 70762a0e9c Merge branch 'maint-0.2.5' into release-0.2.5 2014-09-20 16:51:41 -04:00
Roger Dingledine 22a82164b1 fold in existing changes entry 2014-09-19 21:45:14 -04:00
Roger Dingledine 0b004ba5c0 Merge branch 'maint-0.2.5' into release-0.2.5 2014-09-19 21:44:23 -04:00
Nick Mathewson 396ac67f62 Merge branch 'maint-0.2.5' into release-0.2.5
This is a "theirs" merge, to get the version number bumped to
0.2.5.7-rc-dev.
2014-09-11 21:44:03 -04:00
Roger Dingledine 40233cadbb 0.2.5.7-rc is not the first release candidate for 0.2.5.7-rc 2014-09-11 20:26:38 -04:00
Nick Mathewson 76f72e3b41 Add a release blurb and increment the version in the changelog.
(Remember, this isn't the final release until it's tagged.)
2014-09-11 11:33:36 -04:00
Nick Mathewson 5958261f23 Remove bug12693 changelog entry.
It looks like this was stale and sitting around uncommitted in my
changes directory, having not been committed on my bug12693_025
branch.  The fix for bug12693_025 is not in fact merged.
2014-09-11 11:23:47 -04:00
Nick Mathewson 102c7d7b2c Edit changelog a bit. 2014-09-11 11:23:19 -04:00
Nick Mathewson 2fbaa2f9d6 Fold changes entries into 0.2.5.7 changelog 2014-09-11 09:12:42 -04:00
Nick Mathewson 8e7ee0e2c0 Merge remote-tracking branch 'origin/maint-0.2.5' into release-0.2.5 2014-09-11 09:08:50 -04:00
Nick Mathewson 351f245e2a Add new changes entries to 0.2.5.7-rc changelog 2014-09-09 10:54:50 -04:00
Nick Mathewson 04755ff764 Merge remote-tracking branch 'origin/maint-0.2.5' into release-0.2.5 2014-09-09 10:52:21 -04:00
Roger Dingledine 83e069fd52 Merge branch 'maint-0.2.5' into release-0.2.5 2014-09-09 07:17:28 -04:00
Nick Mathewson 32c5806e1c Recategorize a couple of items in the changelogs 2014-09-03 13:53:22 -04:00
Nick Mathewson 37516391be Reflow changelog 2014-09-03 13:51:04 -04:00
Nick Mathewson 43bf511c31 Fold new entries into 0.2.5.7 changelog 2014-09-03 13:50:10 -04:00
Nick Mathewson 06e8f4b370 Merge remote-tracking branch 'origin/maint-0.2.5' into release-0.2.5 2014-09-03 13:46:31 -04:00
Nick Mathewson 475c95f28a Merge remote-tracking branch 'origin/maint-0.2.5' into release-0.2.5 2014-09-02 12:07:39 -04:00
Nick Mathewson b969ee9dad Merge remote-tracking branch 'origin/maint-0.2.5' into release-0.2.5 2014-08-29 16:45:10 -04:00
Roger Dingledine ef89fd142c Merge branch 'maint-0.2.5' into release-0.2.5 2014-08-21 22:17:23 -04:00
Nick Mathewson f8ca81c04f Sort the 0257 changelog entries by section; combine two. 2014-08-19 12:29:13 -04:00
Nick Mathewson ad8281cb8b Continue 0.2.5.7 changelog: reflow and sort with format_changelog 2014-08-19 12:26:04 -04:00
Nick Mathewson 9fc5dd8ae7 Start on the 0.2.5 changelog: add changes/* unchanged. 2014-08-19 12:24:58 -04:00
Nick Mathewson 9f950d80c3 Merge remote-tracking branch 'origin/maint-0.2.5' into release-0.2.5 2014-08-18 09:39:32 -04:00
Roger Dingledine 390728d856 forward-port the 0.2.4.23 changelog 2014-07-28 04:20:18 -04:00
Roger Dingledine 0b586b44dd Merge branch 'maint-0.2.5' into release-0.2.5 2014-07-28 04:15:24 -04:00
Roger Dingledine 6c84b124aa give 0.2.5.6-alpha a blurb and release date 2014-07-28 03:48:36 -04:00
Roger Dingledine bf372578c1 fold in a few more 2014-07-28 03:08:35 -04:00
Roger Dingledine f4992beb56 Merge branch 'maint-0.2.5' into release-0.2.5 2014-07-28 02:48:11 -04:00
Roger Dingledine 2be259fabf fold in changes for 0.2.5.6-alpha so far 2014-07-24 17:05:53 -04:00
Roger Dingledine c0411e1c89 Merge branch 'maint-0.2.5' into release-0.2.5 2014-07-24 16:31:09 -04:00
Nick Mathewson d14fcdc5e8 add stub changelog entry for 0.2.5.6-?? 2014-06-18 15:15:53 -04:00
853 changed files with 53809 additions and 274604 deletions

View File

@ -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

76
.gitignore vendored
View File

@ -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

View File

@ -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

3
.gitmodules vendored
View File

@ -1,3 +0,0 @@
[submodule "src/ext/rust"]
path = src/ext/rust
url = https://git.torproject.org/tor-rust-dependencies

View File

@ -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

View File

@ -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

10750
ChangeLog

File diff suppressed because it is too large Load Diff

View File

@ -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
View File

@ -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

View File

@ -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
View File

@ -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.

File diff suppressed because it is too large Load Diff

View File

@ -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

View File

@ -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

View File

@ -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!
Dont 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

View File

@ -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.

7
changes/bug24167 Normal file
View File

@ -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.

3
changes/bug24480 Normal file
View File

@ -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.

7
changes/bug24666 Normal file
View File

@ -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.

View File

@ -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.

View File

@ -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.

View File

@ -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.

View File

@ -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.

View File

@ -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.

View File

@ -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.

View File

@ -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.

View File

@ -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.

4
changes/geoip-2017-12-06 Normal file
View File

@ -0,0 +1,4 @@
o Minor features (geoip):
- Update geoip and geoip6 to the December 6 2017 Maxmind GeoLite2
Country database.

4
changes/geoip-2018-01-05 Normal file
View File

@ -0,0 +1,4 @@
o Minor features (geoip):
- Update geoip and geoip6 to the January 5 2018 Maxmind GeoLite2
Country database.

4
changes/geoip-2018-02-07 Normal file
View File

@ -0,0 +1,4 @@
o Minor features (geoip):
- Update geoip and geoip6 to the February 7 2018 Maxmind GeoLite2
Country database.

4
changes/geoip-2018-03-08 Normal file
View File

@ -0,0 +1,4 @@
o Minor features (geoip):
- Update geoip and geoip6 to the March 8 2018 Maxmind GeoLite2
Country database. Closes ticket 25469.

4
changes/geoip-2018-04-03 Normal file
View File

@ -0,0 +1,4 @@
o Minor features (geoip):
- Update geoip and geoip6 to the April 3 2018 Maxmind GeoLite2
Country database. Closes ticket 25718.

4
changes/ticket23856 Normal file
View File

@ -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.

View File

@ -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.

File diff suppressed because it is too large Load Diff

View File

@ -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
-----------------------------------------------

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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"

545
doc/HACKING Normal file
View File

@ -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.)

View File

@ -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.

View File

@ -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 LLVMs 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

View File

@ -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

View File

@ -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.

View File

@ -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`.

View File

@ -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.

View File

@ -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.)

View File

@ -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.

View File

@ -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.

View File

@ -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.

View File

@ -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).

View File

@ -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.)

View File

@ -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

View File

@ -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.

View File

@ -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;

View File

@ -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

View File

@ -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:

View File

@ -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)

60
doc/tor-fw-helper.1.txt Normal file
View File

@ -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>

View File

@ -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__::

View File

@ -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). +

File diff suppressed because it is too large Load Diff

View File

@ -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
-------

View File

@ -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

View File

@ -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"`

View File

@ -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
View File

@ -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

View File

@ -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)

View File

@ -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)

View File

@ -1,6 +0,0 @@
@@
expression n, d;
@@
- (((n) + (d) - 1) / (d))
+ CEIL_DIV(n, d)

View File

@ -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)

View File

@ -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/;

View File

@ -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)
)

View File

@ -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)
)

View File

@ -1,5 +0,0 @@
@@
@@
- tt_assert(0)
+ tt_abort()

View File

@ -1,13 +0,0 @@
@@
expression a;
@@
- tor_calloc(1, a)
+ tor_malloc_zero(a)
@@
expression a;
@@
- tor_calloc(a, 1)
+ tor_malloc_zero(a)

View File

@ -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)

View File

@ -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

21
scripts/codegen/get_mozilla_ciphers.py Executable file → Normal file
View File

@ -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:

View File

@ -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())

View File

@ -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/

View File

@ -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)

View 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);

View File

@ -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;

View File

@ -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

View File

@ -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

View File

@ -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("&","&amp;")
line = line.rstrip().replace("<","&lt;").replace(">","&gt;")
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>&nbsp;</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)

View File

@ -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))

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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):

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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