summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.travis.yml3
-rw-r--r--Makefile.am2
-rw-r--r--changes/prop2977
-rw-r--r--changes/ticket248035
-rw-r--r--changes/ticket248053
-rw-r--r--changes/ticket248386
-rw-r--r--changes/ticket2740210
-rw-r--r--changes/ticket280073
-rw-r--r--changes/ticket285513
-rw-r--r--changes/ticket287684
-rw-r--r--configure.ac10
-rw-r--r--doc/HACKING/ReleasingTor.md6
-rw-r--r--scripts/maint/fallback.whitelist175
-rwxr-xr-xscripts/maint/updateFallbackDirs.py302
-rwxr-xr-xscripts/maint/updateVersions.pl.in59
-rwxr-xr-xscripts/maint/update_versions.py133
-rwxr-xr-xscripts/test/scan-build.sh5
-rw-r--r--src/app/config/fallback_dirs.inc581
-rw-r--r--src/core/include.am1
-rw-r--r--src/core/or/versions.c19
-rw-r--r--src/core/or/versions.h2
-rw-r--r--src/feature/control/control.c373
-rw-r--r--src/feature/control/control.h2
-rw-r--r--src/feature/control/control_bootstrap.c358
-rw-r--r--src/feature/nodelist/networkstatus.c5
25 files changed, 1255 insertions, 822 deletions
diff --git a/.travis.yml b/.travis.yml
index b5713d6933..2ea529e252 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -193,6 +193,9 @@ install:
- if [[ "$RUST_OPTIONS" != "" ]]; then rustup --version; fi
- if [[ "$RUST_OPTIONS" != "" ]]; then rustc --version; fi
- if [[ "$RUST_OPTIONS" != "" ]]; then cargo --version; fi
+ ## Get python version
+ - python --version
+ ## run stem tests if they are enabled.
- if [[ "$TEST_STEM" != "" ]]; then pushd stem; python -c "from stem import stem; print(stem.__version__);"; git log -1; popd; fi
script:
diff --git a/Makefile.am b/Makefile.am
index cc81be18b5..a945130213 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -418,7 +418,7 @@ endif
.PHONY: update-versions
update-versions:
- $(PERL) $(top_builddir)/scripts/maint/updateVersions.pl
+ abs_top_srcdir="$(abs_top_srcdir)" $(PYTHON) $(top_srcdir)/scripts/maint/update_versions.py
.PHONY: callgraph
callgraph:
diff --git a/changes/prop297 b/changes/prop297
new file mode 100644
index 0000000000..4f93b232d2
--- /dev/null
+++ b/changes/prop297
@@ -0,0 +1,7 @@
+ o Minor features (required protocols):
+ - Tor no longer exits if it is missing a required protocol, if the
+ consensus that requires the protocol predates the release date of the
+ version of Tor. This change prevents Tor releases from exiting because
+ of an old cached consensus, on the theory that a newer cached
+ consensus might not require the protocol. Implements proposal 297;
+ closes ticket 27735.
diff --git a/changes/ticket24803 b/changes/ticket24803
new file mode 100644
index 0000000000..e76a9eeab9
--- /dev/null
+++ b/changes/ticket24803
@@ -0,0 +1,5 @@
+ o Minor features (fallback directory list):
+ - Replace the 150 fallbacks originally introduced in Tor 0.3.3.1-alpha in
+ January 2018 (of which ~115 were still functional), with a list of
+ 157 fallbacks (92 new, 65 existing, 85 removed) generated in
+ December 2018. Closes ticket 24803.
diff --git a/changes/ticket24805 b/changes/ticket24805
new file mode 100644
index 0000000000..4ba6f6ecd4
--- /dev/null
+++ b/changes/ticket24805
@@ -0,0 +1,3 @@
+ o Minor features (fallback directory list):
+ - Update the fallback whitelist based on operator opt-ins and opt-outs.
+ Closes ticket 24805, patch by Phoul.
diff --git a/changes/ticket24838 b/changes/ticket24838
new file mode 100644
index 0000000000..d068e31b91
--- /dev/null
+++ b/changes/ticket24838
@@ -0,0 +1,6 @@
+ o Minor features (fallback directory mirrors):
+ - Accept relays that are a fuzzy match to a fallback whitelist entry.
+ If a relay matches at least one fingerprint, IPv4 address, or IPv6
+ address in the fallback whitelist, it can become a fallback. This
+ reduces the work required to keep the list up to date.
+ Closes ticket 24838.
diff --git a/changes/ticket27402 b/changes/ticket27402
new file mode 100644
index 0000000000..b79fb56760
--- /dev/null
+++ b/changes/ticket27402
@@ -0,0 +1,10 @@
+ o Minor feature (bootstrap):
+ - When reporting bootstrap progress, stop distinguishing between
+ situations where it seems that only internal paths are available
+ and situations where it seems that external paths are available.
+ Previously, tor would often erroneously report that it had only
+ internal paths. Closes ticket 27402.
+
+ o Code simplification and refactoring:
+ - Split out bootstrap progress reporting from control.c into a
+ separate file. Part of ticket 27402.
diff --git a/changes/ticket28007 b/changes/ticket28007
new file mode 100644
index 0000000000..1ac87862eb
--- /dev/null
+++ b/changes/ticket28007
@@ -0,0 +1,3 @@
+ o Code simplification and refactoring:
+ - Cleanup scan-build.sh to silence shellcheck warnings.
+ Closes ticket 28007.
diff --git a/changes/ticket28551 b/changes/ticket28551
new file mode 100644
index 0000000000..46ba9d713b
--- /dev/null
+++ b/changes/ticket28551
@@ -0,0 +1,3 @@
+ o Minor features (Continuous Integration):
+ - Log Python version during each Travis CI job. Resolves issue
+ 28551.
diff --git a/changes/ticket28768 b/changes/ticket28768
new file mode 100644
index 0000000000..27d90febc8
--- /dev/null
+++ b/changes/ticket28768
@@ -0,0 +1,4 @@
+ o Minor features (fallback directory mirrors):
+ - Accept fallbacks that deliver reasonably live consensuses.
+ (Consensuses that will become valid less than 24 hours in the future,
+ or that expired less than 24 hours ago.) Closes ticket 28768.
diff --git a/configure.ac b/configure.ac
index 31e41c3bbc..7f0d375440 100644
--- a/configure.ac
+++ b/configure.ac
@@ -8,6 +8,15 @@ AC_INIT([tor],[0.4.0.0-alpha-dev])
AC_CONFIG_SRCDIR([src/app/main/tor_main.c])
AC_CONFIG_MACRO_DIR([m4])
+# DO NOT EDIT THIS DEFINITION BY HAND UNLESS YOU KNOW WHAT YOU'RE DOING.
+#
+# The update_versions.py script updates this definition when the
+# version number changes. Tor uses it to make sure that it
+# only shuts down for missing "required protocols" when those protocols
+# are listed as required by a consensus after this date.
+AC_DEFINE(APPROX_RELEASE_DATE, ["2019-01-15"], # for 0.4.0.0-alpha-dev
+ [Approximate date when this software was released. (Updated when the version changes.)])
+
# "foreign" means we don't follow GNU package layout standards
# "1.11" means we require automake version 1.11 or newer
# "subdir-objects" means put .o files in the same directory as the .c files
@@ -2417,7 +2426,6 @@ AC_CONFIG_FILES([
src/config/torrc.minimal
src/rust/.cargo/config
scripts/maint/checkOptionDocs.pl
- scripts/maint/updateVersions.pl
])
if test "x$asciidoc" = "xtrue" && test "$ASCIIDOC" = "none"; then
diff --git a/doc/HACKING/ReleasingTor.md b/doc/HACKING/ReleasingTor.md
index 3073cfb108..7334b1b34a 100644
--- a/doc/HACKING/ReleasingTor.md
+++ b/doc/HACKING/ReleasingTor.md
@@ -135,13 +135,9 @@ new Tor release:
=== III. Making the source release.
1. In `maint-0.?.x`, bump the version number in `configure.ac` and run
- `perl scripts/maint/updateVersions.pl` to update version numbers in other
+ `make update-versions` 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.
diff --git a/scripts/maint/fallback.whitelist b/scripts/maint/fallback.whitelist
index 79551948c6..60d3e7bb85 100644
--- a/scripts/maint/fallback.whitelist
+++ b/scripts/maint/fallback.whitelist
@@ -1,34 +1,23 @@
# updateFallbackDirs.py directory mirror whitelist
#
-# Format:
-# IPv4:DirPort orport=<ORPort> id=<ID> [ ipv6=<IPv6>:<IPv6 ORPort> ]
-# or use:
-# scripts/maint/generateFallbackDirLine.py fingerprint ...
+# At least one of these keys must match for a directory mirror to be included
+# in the fallback list:
+# id
+# ipv4
+# ipv6
+# The ports and nickname are ignored. Missing or extra ipv6 addresses
+# are ignored.
#
-# 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/app/config/fallback_dirs.inc | grep \" | grep -v weight | \
-# tr -d '\n' | \
-# sed 's/"" / /g' | sed 's/""/"/g' | tr \" '\n' | grep -v '^$' \
-# > scripts/maint/fallback.whitelist
+# The latest relay details from Onionoo are included in the generated list.
#
-# 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.
+# To check the hard-coded fallback list (for testing), use:
+# $ updateFallbackDirs.py check_existing
#
-# 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> ]
+# <IPv4>:<DirPort> orport=<ORPort> id=<ID> ( ipv6=[<IPv6>]:<IPv6 ORPort> )?
+# or use:
+# scripts/maint/generateFallbackDirLine.py fingerprint ...
# https://lists.torproject.org/pipermail/tor-relays/2015-December/008362.html
# https://trac.torproject.org/projects/tor/ticket/22321#comment:22
@@ -57,7 +46,6 @@
# 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
@@ -173,8 +161,6 @@
# 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
@@ -297,9 +283,6 @@
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
@@ -324,10 +307,14 @@
185.66.250.141:9030 orport=9001 id=B1726B94885CE3AC3910CA8B60622B97B98E2529
# Email sent directly to teor, verified using relay contact info
+# Email sent directly to Phoul
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
+185.104.120.2:9030 orport=21 id=518FF8708698E1DA09C823C36D35DF89A2CAD956 ipv6=[2a06:3000::120:2]:443
+185.104.120.4:9030 orport=9001 id=F92B3CB9BBE0CB22409843FB1AE4DBCD5EFAC835 ipv6=[2a06:3000::120:4]:443
+185.104.120.3:9030 orport=21 id=707C1B61AC72227B34487B56D04BAA3BA1179CE8 ipv6=[2a06:3000::120:3]:443
+185.104.120.5:80 orport=443 id=3EBDF84DE3B16F0EBF7D51450F07913A02EFDA6C ipv6=[2a06:3000::120:5]:443
+185.104.120.60:80 orport=443 id=D05C9C7068EB5A45F670D5E38A14907EE6223141 ipv6=[2a06:3000::120:60]:443
+
# 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
@@ -379,10 +366,6 @@
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
@@ -406,9 +389,6 @@
# 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
@@ -564,7 +544,6 @@
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
@@ -685,6 +664,7 @@
# 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
+129.13.131.140:80 orport=443 id=F2DFE5FA1E4CF54F8E761A6D304B9B4EC69BDAE8 ipv6=[2a00:1398:5:f604:cafe:cafe:cafe:9001]:443 # AlleKochenKaffee
# 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
@@ -696,8 +676,8 @@
# 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
+94.230.208.147:80 orport=443 id=9AA3FF35E7A549D2337E962333D366E102FE4D50 ipv6=[2a02:418:6017::147]:443
# Email sent directly to teor, verified using relay contact info
107.170.101.39:9030 orport=443 id=30973217E70AF00EBE51797FF6D9AA720A902EAA
@@ -738,13 +718,14 @@
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
+198.232.165.2: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
+# Updated IP https://trac.torproject.org/projects/tor/ticket/24805#comment:16
+94.130.186.5:80 orport=443 id=6A7551EEE18F78A9813096E82BF84F740D32B911
# Email sent directly to teor, verified using relay contact info
173.255.245.116:9030 orport=9001 id=91E4015E1F82DAF0121D62267E54A1F661AB6DC7
@@ -756,13 +737,11 @@
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
+5.9.158.75:9030 orport=9001 id=D11D11877769B9E617537B4B46BFB92B443DE33D ipv6=[2a01:4f8:190:514a::2]:9001
# 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
@@ -834,9 +813,9 @@
195.154.122.54:80 orport=443 id=64E99CB34C595A02A3165484BD1215E7389322C6
# Email sent directly to teor, verified using relay contact info
+# Email sent directly to Phoul
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
@@ -943,10 +922,13 @@
199.249.223.66:80 orport=443 id=C5A53BCC174EF8FD0DCB223E4AA929FA557DEDB2 # Quintex17
# https://lists.torproject.org/pipermail/tor-relays/2017-December/013914.html
+# https://lists.torproject.org/pipermail/tor-relays/2018-January/014063.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
+54.37.73.111:9030 orport=9001 id=92412EA1B9AA887D462B51D816777002F4D58907 # Aerodynamik05
+54.37.17.235:9030 orport=9001 id=360CBA08D1E24F513162047BDB54A1015E531534 # Aerodynamik06
# https://lists.torproject.org/pipermail/tor-relays/2017-December/013917.html
104.200.20.46:80 orport=9001 id=78E2BE744A53631B4AAB781468E94C52AB73968B # bynumlawtor
@@ -960,16 +942,10 @@
# 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
@@ -995,3 +971,94 @@
# 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
+
+# https://lists.torproject.org/pipermail/tor-relays/2018-January/014055.html
+37.157.255.35:9030 orport=9090 id=361D33C96D0F161275EE67E2C91EE10B276E778B # cxx4freedom
+
+# https://lists.torproject.org/pipermail/tor-relays/2018-January/014064.html
+87.118.122.120:80 orport=443 id=A2A6616723B511D8E068BB71705191763191F6B2 # otheontelth
+
+# https://lists.torproject.org/pipermail/tor-relays/2018-January/014069.html
+185.100.86.182:9030 orport=8080 id=E51620B90DCB310138ED89EDEDD0A5C361AAE24E # NormalCitizen
+
+# https://lists.torproject.org/pipermail/tor-relays/2018-January/014267.html
+51.15.72.211:80 orport=9001 id=D122094E396DF8BA560843E7B983B0EA649B7DF9 ipv6=[2001:bc8:4700:2300::1b:f09]:9001 # gjtorrelay
+
+# Email sent directly to Phoul
+185.34.33.2:9265 orport=31415 id=D71B1CA1C9DC7E8CA64158E106AD770A21160FEE # lqdn
+
+# Email sent directly to Phoul
+78.156.110.135:9091 orport=9090 id=F48FD1AED068496D51D1384BC7497C04E4985DA6 # SkynetC2
+
+# Email sent directly to Phoul
+5.200.21.144:80 orport=443 id=0C039F35C2E40DCB71CD8A07E97C7FD7787D42D6 # libel
+64.79.152.132:80 orport=443 id=375DCBB2DBD94E5263BC0C015F0C9E756669617E # ebola
+
+# https://lists.torproject.org/pipermail/tor-relays/2018-June/015524.html
+132.248.241.5:9030 orport=9001 id=4661DE96D3F8E923994B05218F23760C8D7935A4
+
+# https://lists.torproject.org/pipermail/tor-relays/2018-June/015522.html
+96.253.78.108:80 orport=442 id=924B24AFA7F075D059E8EEB284CC400B33D3D036
+
+# Email sent directly to Phoul
+163.172.218.10:9030 orport=9001 id=78809B6C50CB6491DB3A72C60EC39DC85BF72D1F ipv6=[2001:bc8:3f23:1100::1]:9001
+163.172.218.10:9130 orport=9101 id=B247BA9E0AEA93E6D7BF4080CFBB964034AF2B28 ipv6=[2001:bc8:3f23:1100::1]:9101
+
+# Email sent directly to Phoul
+158.255.212.178:8080 orport=8443 id=D941D380E5228E7B4D372AF4D484629A96DC48B9 ipv6=[2a03:f80:ed15:158:255:212:178:2]:8443
+
+# Email sent directly to Phoul
+45.79.108.130:9030 orport=9001 id=AEDAC7081AE14B8D241ECF0FF17A2858AB4383D0 ipv6=[2600:3c01:e000:131::8000:0]:9001
+
+# Email sent directly to Phoul
+51.254.147.57:80 orport=443 id=EB80A8D52F07238B576C42CEAB98ADD084EE075E
+217.182.51.248:80 orport=443 id=D6BA940D3255AB40DC5EE5B0B285FA143E1F9865
+
+# https://lists.torproject.org/pipermail/tor-relays/2018-June/015541.html
+195.191.81.7:9030 orport=9001 id=41A3C16269C7B63DB6EB741DBDDB4E1F586B1592 ipv6=[2a00:1908:fffc:ffff:c0a6:ccff:fe62:e1a1]:9001
+51.254.96.208:9030 orport=9001 id=8101421BEFCCF4C271D5483C5AABCAAD245BBB9D ipv6=[2001:41d0:401:3100::30dc]:9001
+163.172.154.162:9030 orport=9001 id=F741E5124CB12700DA946B78C9B2DD175D6CD2A1 ipv6=[2001:bc8:4400:2100::17:419]:9001
+51.15.78.0:9030 orport=9001 id=15BE17C99FACE24470D40AF782D6A9C692AB36D6 ipv6=[2001:bc8:4700:2300::16:c0b]:9001
+54.37.139.118:9030 orport=9001 id=90A5D1355C4B5840E950EB61E673863A6AE3ACA1 ipv6=[2001:41d0:601:1100::1b8]:9001
+51.38.65.160:9030 orport=9001 id=3CB4193EF4E239FCEDC4DC43468E0B0D6B67ACC3 ipv6=[2001:41d0:801:2000::f6e]:9001
+
+# Email sent directly to Phoul
+54.37.138.138:8080 orport=993 id=1576BE143D8727745BB2BCDDF183291B3C3EFEFC
+
+# Email sent directly to Phoul
+67.215.255.140:9030 orport=9001 id=23917BB3F3994BC61F0C9D7AD19B069F9E150D26
+
+# Email sent directly to Phoul
+195.154.105.170:9030 orport=9001 id=E947C029087FA1C3499BEF5D4372947C51223D8F
+
+# Email sent directly to Phoul
+23.129.64.101:80 orport=443 id=2EB20285FE55927B7AECC47BB94F22534FBC3941 ipv6=[2620:18c:0:1001::101]:443
+23.129.64.102:80 orport=443 id=CA9739E2805A3CD73CF75BBCB6785C32394240E3 ipv6=[2620:18c:0:1001::102]:443
+23.129.64.103:80 orport=443 id=8ED84B53BD9556CCBB036073A1AD508EC27CBE52 ipv6=[2620:18c:0:1001::103]:443
+
+# Email sent directly to Phoul
+37.139.8.104:9030 orport=9001 id=7088D485934E8A403B81531F8C90BDC75FA43C98 ipv6=[2a03:b0c0:0:1010::24c:1001]:9001
+
+# Email sent directly to Phoul
+178.254.7.88:9030 orpport=9001 id=85A885433E50B1874F11CEC9BE98451E24660976
+
+# https://lists.torproject.org/pipermail/tor-relays/2018-August/015869.html
+5.45.111.149:80 orport=443 id=D405FCCF06ADEDF898DF2F29C9348DCB623031BA ipv6=[2a03:4000:6:2388:df98:15f9:b34d:443]:443
+
+# https://trac.torproject.org/projects/tor/ticket/27297
+37.252.185.182:9030 orport=8080 id=113143469021882C3A4B82F084F8125B08EE471E ipv6=[2a00:63c1:a:182::2]:8080
+
+# Email sent directly to Phoul
+139.99.130.178:80 orport=443 id=867B95CACD64653FEEC4D2CEFC5C49B4620307A7
+
+# Email sent directly to Phoul
+104.131.11.214:9030 orport=8080 id=32828476F4F84E15C42B4C360A5CD8DE4C3C2BE7
+
+# Email sent directly to Phoul / Teor
+178.175.139.122:80 orport=443 id=490FB3FAAF8837407D94CA7E1DEF025DEF0F3516 ipv6=[2a00:1dc0:3002::3]:443
+
+# Email sent directly to Phoul
+192.42.116.16:80 orport=443 id=81B75D534F91BFB7C57AB67DA10BCEF622582AE8
+
+# https://lists.torproject.org/pipermail/tor-relays/2018-November/016610.html
+24.117.194.80:80 orport=443 id=B6C4C9A43658F686F8892CA5666717532F72979C
diff --git a/scripts/maint/updateFallbackDirs.py b/scripts/maint/updateFallbackDirs.py
index 0ea3992d8f..14372d0e83 100755
--- a/scripts/maint/updateFallbackDirs.py
+++ b/scripts/maint/updateFallbackDirs.py
@@ -18,8 +18,8 @@
# Optionally uses ipaddress (python 3 builtin) or py2-ipaddress (package)
# for netblock analysis.
#
-# Then read the logs to make sure the fallbacks aren't dominated by a single
-# netblock or port.
+# After running this script, read the logs to make sure the fallbacks aren't
+# dominated by a single netblock or port.
# Script by weasel, April 2015
# Portions by gsathya & karsten, 2013
@@ -39,8 +39,6 @@ import urllib
import urllib2
import hashlib
import dateutil.parser
-# bson_lazy provides bson
-#from bson import json_util
import copy
import re
@@ -100,19 +98,29 @@ MUST_BE_RUNNING_NOW = (PERFORM_IPV4_DIRPORT_CHECKS
# Clients have been using microdesc consensuses by default for a while now
DOWNLOAD_MICRODESC_CONSENSUS = True
-# If a relay delivers an expired consensus, if it expired less than this many
-# seconds ago, we still allow the relay. This should never be less than -90,
-# as all directory mirrors should have downloaded a consensus 90 minutes
-# before it expires. It should never be more than 24 hours, because clients
-# reject consensuses that are older than REASONABLY_LIVE_TIME.
-# For the consensus expiry check to be accurate, the machine running this
-# script needs an accurate clock.
+# If a relay delivers an invalid consensus, if it will become valid less than
+# this many seconds in the future, or expired less than this many seconds ago,
+# accept the relay as a fallback. For the consensus expiry check to be
+# accurate, the machine running this script needs an accurate clock.
#
-# Relays on 0.3.0 and later return a 404 when they are about to serve an
-# expired consensus. This makes them fail the download check.
-# We use a tolerance of 0, so that 0.2.x series relays also fail the download
-# check if they serve an expired consensus.
-CONSENSUS_EXPIRY_TOLERANCE = 0
+# Relays on 0.3.0 and later return a 404 when they are about to serve a
+# consensus that expired more than 24 hours ago. 0.2.9 and earlier relays
+# will serve consensuses that are very old.
+#
+# Relays on 0.3.5.6-rc? and later return a 404 when they are about to serve a
+# consensus that will become valid more than 24 hours in the future. Older
+# relays don't serve future consensuses.
+#
+# A 404 makes relays fail the download check. We use a tolerance of 24 hours,
+# so that 0.2.9 relays also fail the download check if they serve a consensus
+# that is not reasonably live.
+#
+# REASONABLY_LIVE_TIME should never be more than Tor's REASONABLY_LIVE_TIME,
+# (24 hours), because clients reject consensuses that are older than that.
+# Clients on 0.3.5.5-alpha? and earlier also won't select guards from
+# consensuses that have expired, but can bootstrap if they already have guards
+# in their state file.
+REASONABLY_LIVE_TIME = 24*60*60
# Output fallback name, flags, bandwidth, and ContactInfo in a C comment?
OUTPUT_COMMENTS = True if OUTPUT_CANDIDATES else False
@@ -912,61 +920,181 @@ class Candidate(object):
return False
return True
- def is_in_whitelist(self, relaylist):
- """ A fallback matches if each key in the whitelist line matches:
+ def id_matches(self, id, exact=False):
+ """ Does this fallback's id match id?
+ exact is ignored. """
+ return self._fpr == id
+
+ def ipv4_addr_matches(self, ipv4_addr, exact=False):
+ """ Does this fallback's IPv4 address match ipv4_addr?
+ exact is ignored. """
+ return self.dirip == ipv4_addr
+
+ def ipv4_dirport_matches(self, ipv4_dirport, exact=False):
+ """ Does this fallback's IPv4 dirport match ipv4_dirport?
+ If exact is False, always return True. """
+ if exact:
+ return self.dirport == int(ipv4_dirport)
+ else:
+ return True
+
+ def ipv4_and_dirport_matches(self, ipv4_addr, ipv4_dirport, exact=False):
+ """ Does this fallback's IPv4 address match ipv4_addr?
+ If exact is True, also check ipv4_dirport. """
+ ipv4_match = self.ipv4_addr_matches(ipv4_addr, exact=exact)
+ if exact:
+ return ipv4_match and self.ipv4_dirport_matches(ipv4_dirport,
+ exact=exact)
+ else:
+ return ipv4_match
+
+ def ipv4_orport_matches(self, ipv4_orport, exact=False):
+ """ Does this fallback's IPv4 orport match ipv4_orport?
+ If exact is False, always return True. """
+ if exact:
+ return self.orport == int(ipv4_orport)
+ else:
+ return True
+
+ def ipv4_and_orport_matches(self, ipv4_addr, ipv4_orport, exact=False):
+ """ Does this fallback's IPv4 address match ipv4_addr?
+ If exact is True, also check ipv4_orport. """
+ ipv4_match = self.ipv4_addr_matches(ipv4_addr, exact=exact)
+ if exact:
+ return ipv4_match and self.ipv4_orport_matches(ipv4_orport,
+ exact=exact)
+ else:
+ return ipv4_match
+
+ def ipv6_addr_matches(self, ipv6_addr, exact=False):
+ """ Does this fallback's IPv6 address match ipv6_addr?
+ Both addresses must be present to match.
+ exact is ignored. """
+ if self.has_ipv6() and ipv6_addr is not None:
+ # Check that we have a bracketed IPv6 address without a port
+ assert(ipv6_addr.startswith('[') and ipv6_addr.endswith(']'))
+ return self.ipv6addr == ipv6_addr
+ else:
+ return False
+
+ def ipv6_orport_matches(self, ipv6_orport, exact=False):
+ """ Does this fallback's IPv6 orport match ipv6_orport?
+ Both ports must be present to match.
+ If exact is False, always return True. """
+ if exact:
+ return (self.has_ipv6() and ipv6_orport is not None and
+ self.ipv6orport == int(ipv6_orport))
+ else:
+ return True
+
+ def ipv6_and_orport_matches(self, ipv6_addr, ipv6_orport, exact=False):
+ """ Does this fallback's IPv6 address match ipv6_addr?
+ If exact is True, also check ipv6_orport. """
+ ipv6_match = self.ipv6_addr_matches(ipv6_addr, exact=exact)
+ if exact:
+ return ipv6_match and self.ipv6_orport_matches(ipv6_orport,
+ exact=exact)
+ else:
+ return ipv6_match
+
+ def entry_matches_exact(self, entry):
+ """ Is entry an exact match for this fallback?
+ A fallback is an exact match for entry if each key in entry matches:
ipv4
dirport
orport
id
- ipv6 address and port (if present)
+ ipv6 address and port (if present in the fallback or the whitelist)
If the fallback has an ipv6 key, the whitelist line must also have
- it, and vice versa, otherwise they don't match. """
- ipv6 = None
- if self.has_ipv6():
- ipv6 = '%s:%d'%(self.ipv6addr, self.ipv6orport)
- for entry in relaylist:
- if entry['id'] != self._fpr:
- # can't log here unless we match an IP and port, because every relay's
- # fingerprint is compared to every entry's fingerprint
- if entry['ipv4'] == self.dirip and int(entry['orport']) == self.orport:
- logging.warning('%s excluded: has OR %s:%d changed fingerprint to ' +
- '%s?', entry['id'], self.dirip, self.orport,
- self._fpr)
- if self.has_ipv6() and entry.has_key('ipv6') and entry['ipv6'] == ipv6:
- logging.warning('%s excluded: has OR %s changed fingerprint to ' +
- '%s?', entry['id'], ipv6, self._fpr)
- continue
- if entry['ipv4'] != self.dirip:
- logging.warning('%s excluded: has it changed IPv4 from %s to %s?',
- self._fpr, entry['ipv4'], self.dirip)
- continue
- if int(entry['dirport']) != self.dirport:
- logging.warning('%s excluded: has it changed DirPort from %s:%d to ' +
- '%s:%d?', self._fpr, self.dirip, int(entry['dirport']),
- self.dirip, self.dirport)
- continue
- if int(entry['orport']) != self.orport:
- logging.warning('%s excluded: has it changed ORPort from %s:%d to ' +
- '%s:%d?', self._fpr, self.dirip, int(entry['orport']),
- self.dirip, self.orport)
- continue
- if entry.has_key('ipv6') and self.has_ipv6():
- # if both entry and fallback have an ipv6 address, compare them
- if entry['ipv6'] != ipv6:
- logging.warning('%s excluded: has it changed IPv6 ORPort from %s ' +
- 'to %s?', self._fpr, entry['ipv6'], ipv6)
- continue
- # if the fallback has an IPv6 address but the whitelist entry
- # doesn't, or vice versa, the whitelist entry doesn't match
- elif entry.has_key('ipv6') and not self.has_ipv6():
- logging.warning('%s excluded: has it lost its former IPv6 address %s?',
- self._fpr, entry['ipv6'])
- continue
- elif not entry.has_key('ipv6') and self.has_ipv6():
- logging.warning('%s excluded: has it gained an IPv6 address %s?',
- self._fpr, ipv6)
- continue
+ it, otherwise they don't match.
+
+ Logs a warning-level message if the fallback would be an exact match,
+ but one of the id, ipv4, ipv4 orport, ipv4 dirport, or ipv6 orport
+ have changed. """
+ if not self.id_matches(entry['id'], exact=True):
+ # can't log here unless we match an IP and port, because every relay's
+ # fingerprint is compared to every entry's fingerprint
+ if self.ipv4_and_orport_matches(entry['ipv4'],
+ entry['orport'],
+ exact=True):
+ logging.warning('%s excluded: has OR %s:%d changed fingerprint to ' +
+ '%s?', entry['id'], self.dirip, self.orport,
+ self._fpr)
+ if self.ipv6_and_orport_matches(entry.get('ipv6_addr'),
+ entry.get('ipv6_orport'),
+ exact=True):
+ logging.warning('%s excluded: has OR %s changed fingerprint to ' +
+ '%s?', entry['id'], entry['ipv6'], self._fpr)
+ return False
+ if not self.ipv4_addr_matches(entry['ipv4'], exact=True):
+ logging.warning('%s excluded: has it changed IPv4 from %s to %s?',
+ self._fpr, entry['ipv4'], self.dirip)
+ return False
+ if not self.ipv4_dirport_matches(entry['dirport'], exact=True):
+ logging.warning('%s excluded: has it changed DirPort from %s:%d to ' +
+ '%s:%d?', self._fpr, self.dirip, int(entry['dirport']),
+ self.dirip, self.dirport)
+ return False
+ if not self.ipv4_orport_matches(entry['orport'], exact=True):
+ logging.warning('%s excluded: has it changed ORPort from %s:%d to ' +
+ '%s:%d?', self._fpr, self.dirip, int(entry['orport']),
+ self.dirip, self.orport)
+ return False
+ if entry.has_key('ipv6') and self.has_ipv6():
+ # if both entry and fallback have an ipv6 address, compare them
+ if not self.ipv6_and_orport_matches(entry['ipv6_addr'],
+ entry['ipv6_orport'],
+ exact=True):
+ logging.warning('%s excluded: has it changed IPv6 ORPort from %s ' +
+ 'to %s:%d?', self._fpr, entry['ipv6'],
+ self.ipv6addr, self.ipv6orport)
+ return False
+ # if the fallback has an IPv6 address but the whitelist entry
+ # doesn't, or vice versa, the whitelist entry doesn't match
+ elif entry.has_key('ipv6') and not self.has_ipv6():
+ logging.warning('%s excluded: has it lost its former IPv6 address %s?',
+ self._fpr, entry['ipv6'])
+ return False
+ elif not entry.has_key('ipv6') and self.has_ipv6():
+ logging.warning('%s excluded: has it gained an IPv6 address %s:%d?',
+ self._fpr, self.ipv6addr, self.ipv6orport)
+ return False
+ return True
+
+ def entry_matches_fuzzy(self, entry):
+ """ Is entry a fuzzy match for this fallback?
+ A fallback is a fuzzy match for entry if at least one of these keys
+ in entry matches:
+ id
+ ipv4
+ ipv6 (if present in both the fallback and whitelist)
+ The ports and nickname are ignored. Missing or extra ipv6 addresses
+ are ignored.
+
+ Doesn't log any warning messages. """
+ if self.id_matches(entry['id'], exact=False):
return True
+ if self.ipv4_addr_matches(entry['ipv4'], exact=False):
+ return True
+ if entry.has_key('ipv6') and self.has_ipv6():
+ # if both entry and fallback have an ipv6 address, compare them
+ if self.ipv6_addr_matches(entry['ipv6_addr'], exact=False):
+ return True
+ return False
+
+ def is_in_whitelist(self, relaylist, exact=False):
+ """ If exact is True (existing fallback list), check if this fallback is
+ an exact match for any whitelist entry, using entry_matches_exact().
+
+ If exact is False (new fallback whitelist), check if this fallback is
+ a fuzzy match for any whitelist entry, using entry_matches_fuzzy(). """
+ for entry in relaylist:
+ if exact:
+ if self.entry_matches_exact(entry):
+ return True
+ else:
+ if self.entry_matches_fuzzy(entry):
+ return True
return False
def cw_to_bw_factor(self):
@@ -1124,6 +1252,7 @@ class Candidate(object):
).run()[0]
end = datetime.datetime.utcnow()
time_since_expiry = (end - consensus.valid_until).total_seconds()
+ time_until_valid = (consensus.valid_after - end).total_seconds()
except Exception, stem_error:
end = datetime.datetime.utcnow()
log_excluded('Unable to retrieve a consensus from %s: %s', nickname,
@@ -1141,8 +1270,17 @@ class Candidate(object):
download_failed = True
elif (time_since_expiry > 0):
status = 'outdated consensus, expired %ds ago'%(int(time_since_expiry))
- if time_since_expiry <= CONSENSUS_EXPIRY_TOLERANCE:
- status += ', tolerating up to %ds'%(CONSENSUS_EXPIRY_TOLERANCE)
+ if time_since_expiry <= REASONABLY_LIVE_TIME:
+ status += ', tolerating up to %ds'%(REASONABLY_LIVE_TIME)
+ level = logging.INFO
+ else:
+ status += ', invalid'
+ level = logging.WARNING
+ download_failed = True
+ elif (time_until_valid > 0):
+ status = 'future consensus, valid in %ds'%(int(time_until_valid))
+ if time_until_valid <= REASONABLY_LIVE_TIME:
+ status += ', tolerating up to %ds'%(REASONABLY_LIVE_TIME)
level = logging.INFO
else:
status += ', invalid'
@@ -1400,7 +1538,7 @@ class CandidateList(dict):
each line's key/value pairs are placed in a dictonary,
(of string -> string key/value pairs),
and these dictionaries are placed in an array.
- comments start with # and are ignored """
+ comments start with # and are ignored. """
file_data = file_obj['data']
file_name = file_obj['name']
relaylist = []
@@ -1440,18 +1578,28 @@ class CandidateList(dict):
relay_entry['dirport'] = ipv4_maybe_dirport_split[1]
elif kvl == 2:
relay_entry[key_value_split[0]] = key_value_split[1]
+ # split ipv6 addresses and orports
+ if key_value_split[0] == 'ipv6':
+ ipv6_orport_split = key_value_split[1].rsplit(':', 1)
+ ipv6l = len(ipv6_orport_split)
+ if ipv6l != 2:
+ print '#error Bad %s IPv6 item: %s, format is [ipv6]:orport.'%(
+ file_name, item)
+ relay_entry['ipv6_addr'] = ipv6_orport_split[0]
+ relay_entry['ipv6_orport'] = ipv6_orport_split[1]
relaylist.append(relay_entry)
return relaylist
- # apply the fallback whitelist
- def apply_filter_lists(self, whitelist_obj):
+ def apply_filter_lists(self, whitelist_obj, exact=False):
+ """ Apply the fallback whitelist_obj to this fallback list,
+ passing exact to is_in_whitelist(). """
excluded_count = 0
logging.debug('Applying whitelist')
# parse the whitelist
whitelist = self.load_relaylist(whitelist_obj)
filtered_fallbacks = []
for f in self.fallbacks:
- in_whitelist = f.is_in_whitelist(whitelist)
+ in_whitelist = f.is_in_whitelist(whitelist, exact=exact)
if in_whitelist:
# include
filtered_fallbacks.append(f)
@@ -2064,14 +2212,14 @@ def process_existing():
logging.getLogger('stem').setLevel(logging.INFO)
whitelist = {'data': parse_fallback_file(FALLBACK_FILE_NAME),
'name': FALLBACK_FILE_NAME}
- list_fallbacks(whitelist)
+ list_fallbacks(whitelist, exact=True)
def process_default():
logging.basicConfig(level=logging.WARNING)
logging.getLogger('stem').setLevel(logging.WARNING)
whitelist = {'data': read_from_file(WHITELIST_FILE_NAME, MAX_LIST_FILE_SIZE),
'name': WHITELIST_FILE_NAME}
- list_fallbacks(whitelist)
+ list_fallbacks(whitelist, exact=False)
## Main Function
def main():
@@ -2092,10 +2240,10 @@ def log_excluded(msg, *args):
else:
logging.info(msg, *args)
-def list_fallbacks(whitelist):
+def list_fallbacks(whitelist, exact=False):
""" Fetches required onionoo documents and evaluates the
- fallback directory criteria for each of the relays """
-
+ fallback directory criteria for each of the relays,
+ passing exact to apply_filter_lists(). """
print "/* type=fallback */"
print ("/* version={} */"
.format(cleanse_c_multiline_comment(FALLBACK_FORMAT_VERSION)))
@@ -2135,7 +2283,7 @@ def list_fallbacks(whitelist):
# warning that the details have changed from those in the whitelist.
# instead, there will be an info-level log during the eligibility check.
initial_count = len(candidates.fallbacks)
- excluded_count = candidates.apply_filter_lists(whitelist)
+ excluded_count = candidates.apply_filter_lists(whitelist, exact=exact)
print candidates.summarise_filters(initial_count, excluded_count)
eligible_count = len(candidates.fallbacks)
diff --git a/scripts/maint/updateVersions.pl.in b/scripts/maint/updateVersions.pl.in
deleted file mode 100755
index 65c51a1f2d..0000000000
--- a/scripts/maint/updateVersions.pl.in
+++ /dev/null
@@ -1,59 +0,0 @@
-#!/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';
-
-$quiet = 1;
-
-sub demand {
- my $fn = shift;
- die "Missing file $fn" unless (-f $fn);
-}
-
-demand($CONFIGURE_IN);
-demand($ORCONFIG_H);
-demand($TOR_NSI);
-
-# extract version from configure.ac
-
-open(F, $CONFIGURE_IN) or die "$!";
-$version = undef;
-while (<F>) {
- if (/AC_INIT\(\[tor\],\s*\[([^\]]*)\]\)/) {
- $version = $1;
- last;
- }
-}
-die "No version found" unless $version;
-print "Tor version is $version\n" unless $quiet;
-close F;
-
-sub correctversion {
- my ($fn, $defchar) = @_;
- undef $/;
- open(F, $fn) or die "$!";
- my $s = <F>;
- close F;
- if ($s =~ /^$defchar(?:)define\s+VERSION\s+\"([^\"]+)\"/m) {
- $oldver = $1;
- if ($oldver ne $version) {
- print "Version mismatch in $fn: It thinks that the version is $oldver. I think it's $version. Fixing.\n";
- $line = $defchar . "define VERSION \"$version\"";
- open(F, ">$fn.bak");
- print F $s;
- close F;
- $s =~ s/^$defchar(?:)define\s+VERSION.*?$/$line/m;
- open(F, ">$fn");
- print F $s;
- close F;
- } else {
- print "$fn has the correct version. Good.\n" unless $quiet;
- }
- } else {
- print "Didn't find a version line in $fn -- uh oh.\n";
- }
-}
-
-correctversion($TOR_NSI, "!");
-correctversion($ORCONFIG_H, "#");
diff --git a/scripts/maint/update_versions.py b/scripts/maint/update_versions.py
new file mode 100755
index 0000000000..8067f2c6c8
--- /dev/null
+++ b/scripts/maint/update_versions.py
@@ -0,0 +1,133 @@
+#!/usr/bin/env python
+
+from __future__ import print_function
+
+import io
+import os
+import re
+import sys
+import time
+
+def P(path):
+ """
+ Give 'path' as a path relative to the abs_top_srcdir environment
+ variable.
+ """
+ return os.path.join(
+ os.environ.get('abs_top_srcdir', "."),
+ path)
+
+def warn(msg):
+ """
+ Print an warning message.
+ """
+ print("WARNING: {}".format(msg), file=sys.stderr)
+
+def find_version(infile):
+ """
+ Given an open file (or some other iterator of lines) holding a
+ configure.ac file, find the current version line.
+ """
+ for line in infile:
+ m = re.search(r'AC_INIT\(\[tor\],\s*\[([^\]]*)\]\)', line)
+ if m:
+ return m.group(1)
+
+ return None
+
+def update_version_in(infile, outfile, regex, versionline):
+ """
+ Copy every line from infile to outfile. If any line matches 'regex',
+ replace it with 'versionline'. Return True if any line was changed;
+ false otherwise.
+
+ 'versionline' is either a string -- in which case it is used literally,
+ or a function that receives the output of 'regex.match'.
+ """
+ found = False
+ have_changed = False
+ for line in infile:
+ m = regex.match(line)
+ if m:
+ found = True
+ oldline = line
+ if type(versionline) == type(u""):
+ line = versionline
+ else:
+ line = versionline(m)
+ if not line.endswith("\n"):
+ line += "\n"
+ if oldline != line:
+ have_changed = True
+ outfile.write(line)
+
+ if not found:
+ warn("didn't find any version line to replace in {}".format(infile.name))
+
+ return have_changed
+
+def replace_on_change(fname, change):
+ """
+ If "change" is true, replace fname with fname.tmp. Otherwise,
+ delete fname.tmp. Log what we're doing to stderr.
+ """
+ if not change:
+ print("No change in {}".format(fname))
+ os.unlink(fname+".tmp")
+ else:
+ print("Updating {}".format(fname))
+ os.rename(fname+".tmp", fname)
+
+
+def update_file(fname,
+ regex,
+ versionline,
+ encoding="utf-8"):
+ """
+ Replace any line matching 'regex' in 'fname' with 'versionline'.
+ Do not modify 'fname' if there are no changes made. Use the
+ provided encoding to read and write.
+ """
+ with io.open(fname, "r", encoding=encoding) as f, \
+ io.open(fname+".tmp", "w", encoding=encoding) as outf:
+ have_changed = update_version_in(f, outf, regex, versionline)
+
+ replace_on_change(fname, have_changed)
+
+# Find out our version
+with open("configure.ac") as f:
+ version = find_version(f)
+
+# If we have no version, we can't proceed.
+if version == None:
+ print("No version found in configure.ac", file=sys.stderr())
+ sys.exit(1)
+
+print("The version is {}".format(version))
+
+today = time.strftime("%Y-%m-%d", time.gmtime())
+
+# In configure.ac, we replace the definition of APPROX_RELEASE_DATE
+# with "{today} for {version}", but only if the version does not match
+# what is already there.
+def replace_fn(m):
+ if m.group(1) != version:
+ # The version changed -- we change the date.
+ return u'AC_DEFINE(APPROX_RELEASE_DATE, ["{}"], # for {}'.format(today, version)
+ else:
+ # No changes.
+ return m.group(0)
+update_file(P("configure.ac"),
+ re.compile(r'AC_DEFINE\(APPROX_RELEASE_DATE.* for (.*)'),
+ replace_fn)
+
+# In tor-mingw.nsi.in, we replace the definition of VERSION.
+update_file(P("contrib/win32build/tor-mingw.nsi.in"),
+ re.compile(r'!define VERSION .*'),
+ u'!define VERSION "{}"'.format(version),
+ encoding="iso-8859-1")
+
+# In src/win32/orconfig.h, we replace the definition of VERSION.
+update_file(P("src/win32/orconfig.h"),
+ re.compile(r'#define VERSION .*'),
+ u'#define VERSION "{}"'.format(version))
diff --git a/scripts/test/scan-build.sh b/scripts/test/scan-build.sh
index 8d126cbcee..26e05ff101 100755
--- a/scripts/test/scan-build.sh
+++ b/scripts/test/scan-build.sh
@@ -33,6 +33,7 @@ CHECKERS="\
-enable-checker security.insecureAPI.strcpy \
"
+# shellcheck disable=SC2034
# These have high false-positive rates.
EXTRA_CHECKERS="\
-enable-checker alpha.security.ArrayBoundV2 \
@@ -40,6 +41,7 @@ EXTRA_CHECKERS="\
-enable-checker alpha.core.CastSize \
"
+# shellcheck disable=SC2034
# These don't seem to generate anything useful
NOISY_CHECKERS="\
-enable-checker alpha.clone.CloneChecker \
@@ -52,6 +54,7 @@ else
OUTPUTARG=""
fi
+# shellcheck disable=SC2086
scan-build \
$CHECKERS \
./configure
@@ -61,11 +64,13 @@ scan-build \
# Make this not get scanned for dead assignments, since it has lots of
# dead assignments we don't care about.
+# shellcheck disable=SC2086
scan-build \
$CHECKERS \
-disable-checker deadcode.DeadStores \
make -j5 -k ./src/ext/ed25519/ref10/libed25519_ref10.a
+# shellcheck disable=SC2086
scan-build \
$CHECKERS $OUTPUTARG \
make -j5 -k
diff --git a/src/app/config/fallback_dirs.inc b/src/app/config/fallback_dirs.inc
index c446152e6a..9f60f309f8 100644
--- a/src/app/config/fallback_dirs.inc
+++ b/src/app/config/fallback_dirs.inc
@@ -1,73 +1,82 @@
/* type=fallback */
/* version=2.0.0 */
-/* timestamp=20180106205601 */
-/* ===== */
-/* Whitelist & blacklist excluded 810 of 1009 candidates. */
+/* timestamp=20181207055710 */
+/* timestamp0=20181207055710 */
+/* timestamp1=20181207193756 */
+/* timestamp2=20181207195255 */
+/* ===== */
+/* 0: Whitelist excluded 1275 of 1462 candidates. */
+/* 1: Whitelist excluded 1279 of 1470 candidates. */
+/* 2: Whitelist excluded 1278 of 1469 candidates. */
/* Checked IPv4 DirPorts served a consensus within 15.0s. */
/*
-Final Count: 143 (Eligible 198, Target 230 (1154 * 0.20), Max 200)
-Excluded: 55 (Same Operator 34, Failed/Skipped Download 14, Excess 7)
-Bandwidth Range: 0.9 - 131.1 MByte/s
+0:
+Final Count: 148 (Eligible 187, Target 351 (1757 * 0.20), Max 200)
+Excluded: 39 (Same Operator 28, Failed/Skipped Download 7, Excess 4)
+Bandwidth Range: 0.8 - 43.8 MByte/s
+
+MERGED WITH:
+
+1:
+Final Count: 138 (Eligible 191, Target 353 (1768 * 0.20), Max 200)
+Excluded: 53 (Same Operator 29, Failed/Skipped Download 20, Excess 4)
+Bandwidth Range: 1.0 - 46.9 MByte/s
MERGED WITH:
-Final Count: 139 (Eligible 199, Target 232 (1161 * 0.20), Max 200)
-Excluded: 60 (Same Operator 34, Failed/Skipped Download 19, Excess 7)
-Bandwidth Range: 1.1 - 131.1 MByte/s
+2:
+Final Count: 145 (Eligible 191, Target 353 (1768 * 0.20), Max 200)
+Excluded: 46 (Same Operator 29, Failed/Skipped Download 13, Excess 4)
+Bandwidth Range: 1.0 - 46.9 MByte/s
*/
/*
-Onionoo Source: details Date: 2018-01-06 20:00:00 Version: 5.0
+0: Onionoo Source: details Date: 2018-12-07 05:00:00 Version: 7.0
+1: Onionoo Source: details Date: 2018-12-07 18:00:00 Version: 7.0
+2: Onionoo Source: details Date: 2018-12-07 18:00:00 Version: 7.0
URL: https:onionoo.torproject.orgdetails?fieldsfingerprint%2Cnickname%2Ccontact%2Clast_changed_address_or_port%2Cconsensus_weight%2Cadvertised_bandwidth%2Cor_addresses%2Cdir_address%2Crecommended_version%2Cflags%2Ceffective_family%2Cplatform&flagV2Dir&typerelay&last_seen_days-0&first_seen_days90-
*/
/*
-Onionoo Source: uptime Date: 2018-01-06 20:00:00 Version: 5.0
+0: Onionoo Source: uptime Date: 2018-12-07 05:00:00 Version: 7.0
+1: Onionoo Source: uptime Date: 2018-12-07 18:00:00 Version: 7.0
+2: Onionoo Source: uptime Date: 2018-12-07 18:00:00 Version: 7.0
URL: https:onionoo.torproject.orguptime?first_seen_days90-&flagV2Dir&typerelay&last_seen_days-0
*/
/* ===== */
-"185.13.39.197:80 orport=443 id=001524DD403D729F08F7E5D77813EF12756CFA8D"
-/* nickname=Neldoreth */
-/* extrainfo=0 */
-/* ===== */
-,
"176.10.104.240:80 orport=443 id=0111BA9B604669E636FFD5B503F382A4B7AD6E80"
/* nickname=DigiGesTor1e1 */
/* extrainfo=0 */
/* ===== */
,
-"185.100.85.61:80 orport=443 id=025B66CEBC070FCB0519D206CF0CF4965C20C96E"
-/* nickname=nibbana */
+"193.171.202.146:9030 orport=9001 id=01A9258A46E97FF8B2CAC7910577862C14F2C524"
+" ipv6=[2001:628:200a:f001:20::146]:9001"
+/* nickname=ins0 */
/* extrainfo=0 */
/* ===== */
,
-"5.9.110.236:9030 orport=9001 id=0756B7CD4DFC8182BE23143FAC0642F515182CEB"
-" ipv6=[2a01:4f8:162:51e2::2]:9001"
-/* nickname=rueckgrat */
-/* extrainfo=1 */
-/* ===== */
-,
"163.172.149.155:80 orport=443 id=0B85617241252517E8ECF2CFC7F4C1A32DCD153F"
/* nickname=niij02 */
/* extrainfo=0 */
/* ===== */
,
-"5.39.92.199:80 orport=443 id=0BEA4A88D069753218EAAAD6D22EA87B9A1319D6"
-" ipv6=[2001:41d0:8:b1c7::1]:443"
-/* nickname=BaelorTornodePw */
+"5.200.21.144:80 orport=443 id=0C039F35C2E40DCB71CD8A07E97C7FD7787D42D6"
+/* nickname=libel */
/* extrainfo=0 */
/* ===== */
,
-"163.172.25.118:80 orport=22 id=0CF8F3E6590F45D50B70F2F7DA6605ECA6CD408F"
-/* nickname=torpidsFRonline4 */
+"5.196.88.122:9030 orport=9001 id=0C2C599AFCB26F5CFC2C7592435924C1D63D9484"
+" ipv6=[2001:41d0:a:fb7a::1]:9001"
+/* nickname=ATo */
/* extrainfo=0 */
/* ===== */
,
-"178.62.197.82:80 orport=443 id=0D3EBA17E1C78F1E9900BABDB23861D46FCAF163"
-/* nickname=HY100 */
+"185.100.86.100:80 orport=443 id=0E8C0C8315B66DB5F703804B3889A1DD66C67CE0"
+/* nickname=saveyourprivacyex1 */
/* extrainfo=0 */
/* ===== */
,
-"185.100.86.100:80 orport=443 id=0E8C0C8315B66DB5F703804B3889A1DD66C67CE0"
-/* nickname=saveyourprivacyex1 */
+"37.252.185.182:9030 orport=8080 id=113143469021882C3A4B82F084F8125B08EE471E"
+" ipv6=[2a00:63c1:a:182::2]:8080"
+/* nickname=parasol */
/* extrainfo=0 */
/* ===== */
,
@@ -83,31 +92,36 @@ URL: https:onionoo.torproject.orguptime?first_seen_days90-&flagV2Dir&typerelay&l
/* extrainfo=0 */
/* ===== */
,
-"37.157.195.87:8030 orport=443 id=12FD624EE73CEF37137C90D38B2406A66F68FAA2"
-/* nickname=thanatosCZ */
+"193.234.15.59:80 orport=443 id=136F9299A5009A4E0E96494E723BDB556FB0A26B"
+" ipv6=[2a00:1c20:4089:1234:bff6:e1bb:1ce3:8dc6]:443"
+/* nickname=bakunin2 */
/* extrainfo=0 */
/* ===== */
,
-"178.16.208.59:80 orport=443 id=136F9299A5009A4E0E96494E723BDB556FB0A26B"
-" ipv6=[2a00:1c20:4089:1234:bff6:e1bb:1ce3:8dc6]:443"
-/* nickname=bakunin2 */
+"144.76.14.145:110 orport=143 id=14419131033443AE6E21DA82B0D307F7CAE42BDB"
+" ipv6=[2a01:4f8:190:9490::dead]:443"
+/* nickname=PedicaboMundi */
/* extrainfo=0 */
/* ===== */
,
-"163.172.138.22:80 orport=443 id=16102E458460349EE45C0901DAA6C30094A9BBEA"
-" ipv6=[2001:bc8:4400:2100::1:3]:443"
-/* nickname=mkultra */
+"185.220.101.9:10009 orport=20009 id=14877C6384A9E793F422C8D1DDA447CACA4F7C4B"
+/* nickname=niftywoodmouse */
/* extrainfo=0 */
/* ===== */
,
-"178.62.60.37:80 orport=443 id=175921396C7C426309AB03775A9930B6F611F794"
-/* nickname=lovejoy */
+"54.37.138.138:8080 orport=993 id=1576BE143D8727745BB2BCDDF183291B3C3EFEFC"
+/* nickname=anotherone */
/* extrainfo=0 */
/* ===== */
,
-"171.25.193.25:80 orport=443 id=185663B7C12777F052B2C2D23D7A239D8DA88A0F"
-" ipv6=[2001:67c:289c::25]:443"
-/* nickname=DFRI5 */
+"51.15.78.0:9030 orport=9001 id=15BE17C99FACE24470D40AF782D6A9C692AB36D6"
+" ipv6=[2001:bc8:4700:2300::16:c0b]:9001"
+/* nickname=rofltor07 */
+/* extrainfo=0 */
+/* ===== */
+,
+"204.11.50.131:9030 orport=9001 id=185F2A57B0C4620582602761097D17DB81654F70"
+/* nickname=BoingBoing */
/* extrainfo=0 */
/* ===== */
,
@@ -118,7 +132,7 @@ URL: https:onionoo.torproject.orguptime?first_seen_days90-&flagV2Dir&typerelay&l
,
"81.7.14.253:9001 orport=443 id=1AE039EE0B11DB79E4B4B29CBA9F752864A0259E"
/* nickname=Ichotolot60 */
-/* extrainfo=0 */
+/* extrainfo=1 */
/* ===== */
,
"163.172.53.84:143 orport=21 id=1C90D3AEADFF3BCD079810632C8B85637924A58E"
@@ -127,46 +141,25 @@ URL: https:onionoo.torproject.orguptime?first_seen_days90-&flagV2Dir&typerelay&l
/* extrainfo=0 */
/* ===== */
,
-"46.101.151.222:80 orport=443 id=1DBAED235E3957DE1ABD25B4206BE71406FB61F8"
-/* nickname=flanders */
-/* extrainfo=0 */
-/* ===== */
-,
-"91.219.237.229:80 orport=443 id=1ECD73B936CB6E6B3CD647CC204F108D9DF2C9F7"
-/* nickname=JakeDidNothingWrong */
-/* extrainfo=0 */
-/* ===== */
-,
"199.184.246.250:80 orport=443 id=1F6ABD086F40B890A33C93CC4606EE68B31C9556"
" ipv6=[2620:124:1009:1::171]:443"
/* nickname=dao */
/* extrainfo=0 */
/* ===== */
,
-"185.129.249.124:9030 orport=9001 id=1FA8F638298645BE58AC905276680889CB795A94"
-/* nickname=treadstone */
-/* extrainfo=0 */
-/* ===== */
-,
"212.47.229.2:9030 orport=9001 id=20462CBA5DA4C2D963567D17D0B7249718114A68"
" ipv6=[2001:bc8:4400:2100::f03]:9001"
/* nickname=scaletor */
/* extrainfo=0 */
/* ===== */
,
-"77.247.181.164:80 orport=443 id=204DFD2A2C6A0DC1FA0EACB495218E0B661704FD"
-/* nickname=HaveHeart */
-/* extrainfo=0 */
-/* ===== */
-,
"163.172.176.167:80 orport=443 id=230A8B2A8BA861210D9B4BA97745AEC217A94207"
/* nickname=niij01 */
/* extrainfo=0 */
/* ===== */
,
-"37.200.98.5:80 orport=443 id=231C2B9C8C31C295C472D031E06964834B745996"
-" ipv6=[2a00:1158:3::11a]:993"
-/* nickname=torpidsDEdomainf */
+"185.220.101.8:10008 orport=20008 id=24E91955D969AEA1D80413C64FE106FAE7FD2EA9"
+/* nickname=niftymouse */
/* extrainfo=0 */
/* ===== */
,
@@ -175,7 +168,7 @@ URL: https:onionoo.torproject.orguptime?first_seen_days90-&flagV2Dir&typerelay&l
/* extrainfo=0 */
/* ===== */
,
-"178.16.208.56:80 orport=443 id=2CDCFED0142B28B002E89D305CBA2E26063FADE2"
+"193.234.15.56:80 orport=443 id=2CDCFED0142B28B002E89D305CBA2E26063FADE2"
" ipv6=[2a00:1c20:4089:1234:cd49:b58a:9ebe:67ec]:443"
/* nickname=jaures */
/* extrainfo=0 */
@@ -186,14 +179,14 @@ URL: https:onionoo.torproject.orguptime?first_seen_days90-&flagV2Dir&typerelay&l
/* extrainfo=0 */
/* ===== */
,
-"64.113.32.29:9030 orport=9001 id=30C19B81981F450C402306E2E7CFB6C3F79CB6B2"
-/* nickname=Libero */
+"94.230.208.147:8080 orport=8443 id=311A4533F7A2415F42346A6C8FA77E6FD279594C"
+" ipv6=[2a02:418:6017::147]:8443"
+/* nickname=DigiGesTor3e2 */
/* extrainfo=0 */
/* ===== */
,
-"80.127.117.180:80 orport=443 id=328E54981C6DDD7D89B89E418724A4A7881E3192"
-" ipv6=[2001:985:e77:10::4]:443"
-/* nickname=sjc01 */
+"212.83.154.33:8080 orport=8443 id=322C6E3A973BC10FC36DE3037AD27BC89F14723B"
+/* nickname=bauruine204 */
/* extrainfo=0 */
/* ===== */
,
@@ -203,21 +196,25 @@ URL: https:onionoo.torproject.orguptime?first_seen_days90-&flagV2Dir&typerelay&l
/* extrainfo=0 */
/* ===== */
,
-"163.172.13.165:9030 orport=9001 id=33DA0CAB7C27812EFF2E22C9705630A54D101FEB"
-" ipv6=[2001:bc8:38cb:201::8]:9001"
-/* nickname=mullbinde9 */
+"54.37.17.235:9030 orport=9001 id=360CBA08D1E24F513162047BDB54A1015E531534"
+/* nickname=Aerodynamik06 */
/* extrainfo=0 */
/* ===== */
,
-"91.121.23.100:9030 orport=9001 id=3711E80B5B04494C971FB0459D4209AB7F2EA799"
-/* nickname=0x3d002 */
+"37.157.255.35:9030 orport=9090 id=361D33C96D0F161275EE67E2C91EE10B276E778B"
+/* nickname=cxx4freedom */
/* extrainfo=0 */
/* ===== */
,
-"176.126.252.12:21 orport=8080 id=379FB450010D17078B3766C2273303C358C3A442"
-" ipv6=[2a02:59e0:0:7::12]:81"
-/* nickname=aurora */
-/* extrainfo=1 */
+"37.187.22.87:9030 orport=9001 id=36B9E7AC1E36B62A9D6F330ABEB6012BA7F0D400"
+" ipv6=[2001:41d0:a:1657::1]:9001"
+/* nickname=kimsufi321 */
+/* extrainfo=0 */
+/* ===== */
+,
+"64.79.152.132:80 orport=443 id=375DCBB2DBD94E5263BC0C015F0C9E756669617E"
+/* nickname=ebola */
+/* extrainfo=0 */
/* ===== */
,
"62.210.92.11:9130 orport=9101 id=387B065A38E4DAA16D9D41C2964ECBC4B31D30FF"
@@ -231,24 +228,9 @@ URL: https:onionoo.torproject.orguptime?first_seen_days90-&flagV2Dir&typerelay&l
/* extrainfo=0 */
/* ===== */
,
-"164.132.77.175:9030 orport=9001 id=3B33F6FCA645AD4E91428A3AF7DC736AD9FB727B"
-/* nickname=rofltor1 */
-/* extrainfo=0 */
-/* ===== */
-,
-"212.83.154.33:8888 orport=443 id=3C79699D4FBC37DE1A212D5033B56DAE079AC0EF"
-/* nickname=bauruine203 */
-/* extrainfo=0 */
-/* ===== */
-,
-"176.10.107.180:9030 orport=9001 id=3D7E274A87D9A89AF064C13D1EE4CA1F184F2600"
-/* nickname=schokomilch */
-/* extrainfo=0 */
-/* ===== */
-,
-"217.79.179.177:9030 orport=9001 id=3E53D3979DB07EFD736661C934A1DED14127B684"
-" ipv6=[2001:4ba0:fff9:131:6c4f::90d3]:9001"
-/* nickname=Unnamed */
+"66.111.2.16:9030 orport=9001 id=3F092986E9B87D3FDA09B71FA3A602378285C77A"
+" ipv6=[2610:1c0:0:5::16]:9001"
+/* nickname=NYCBUG1 */
/* extrainfo=0 */
/* ===== */
,
@@ -257,19 +239,21 @@ URL: https:onionoo.torproject.orguptime?first_seen_days90-&flagV2Dir&typerelay&l
/* extrainfo=0 */
/* ===== */
,
-"199.249.223.61:80 orport=443 id=40E7D6CE5085E4CDDA31D51A29D1457EB53F12AD"
-/* nickname=Quintex12 */
+"195.191.81.7:9030 orport=9001 id=41A3C16269C7B63DB6EB741DBDDB4E1F586B1592"
+" ipv6=[2a00:1908:fffc:ffff:c0a6:ccff:fe62:e1a1]:9001"
+/* nickname=rofltor02 */
/* extrainfo=0 */
/* ===== */
,
"178.17.170.156:9030 orport=9001 id=41C59606AFE1D1AA6EC6EF6719690B856F0B6587"
+" ipv6=[2a00:1dc0:caff:48::9257]:9001"
/* nickname=TorExitMoldova2 */
/* extrainfo=0 */
/* ===== */
,
-"178.62.86.96:9030 orport=9001 id=439D0447772CB107B886F7782DBC201FA26B92D1"
-" ipv6=[2a03:b0c0:1:d0::3cf:7001]:9050"
-/* nickname=pablobm001 */
+"81.7.10.251:80 orport=443 id=45362E8ECD651CCAC521156FFBD2FF7F27FA8E88"
+" ipv6=[2a02:180:1:1::517:afb]:443"
+/* nickname=torpidsDEisppro2 */
/* extrainfo=0 */
/* ===== */
,
@@ -278,19 +262,23 @@ URL: https:onionoo.torproject.orguptime?first_seen_days90-&flagV2Dir&typerelay&l
/* extrainfo=0 */
/* ===== */
,
+"132.248.241.5:9030 orport=9001 id=4661DE96D3F8E923994B05218F23760C8D7935A4"
+/* nickname=toritounam */
+/* extrainfo=0 */
+/* ===== */
+,
"31.31.78.49:80 orport=443 id=46791D156C9B6C255C2665D4D8393EC7DBAA7798"
/* nickname=KrigHaBandolo */
/* extrainfo=0 */
/* ===== */
,
-"193.70.43.76:9030 orport=9001 id=484A10BA2B8D48A5F0216674C8DD50EF27BC32F3"
-/* nickname=Aerodynamik03 */
+"185.220.101.34:10034 orport=20034 id=47C42E2094EE482E7C9B586B10BABFB67557030B"
+/* nickname=niftysugarglider */
/* extrainfo=0 */
/* ===== */
,
-"37.187.102.186:9030 orport=9001 id=489D94333DF66D57FFE34D9D59CC2D97E2CB0053"
-" ipv6=[2001:41d0:a:26ba::1]:9001"
-/* nickname=txtfileTorNode65536 */
+"193.70.43.76:9030 orport=9001 id=484A10BA2B8D48A5F0216674C8DD50EF27BC32F3"
+/* nickname=Aerodynamik03 */
/* extrainfo=0 */
/* ===== */
,
@@ -299,9 +287,10 @@ URL: https:onionoo.torproject.orguptime?first_seen_days90-&flagV2Dir&typerelay&l
/* extrainfo=0 */
/* ===== */
,
-"108.53.208.157:80 orport=443 id=4F0DB7E687FC7C0AE55C8F243DA8B0EB27FBF1F2"
-/* nickname=Binnacle */
-/* extrainfo=1 */
+"81.7.13.84:80 orport=443 id=4EB55679FA91363B97372554F8DC7C63F4E5B101"
+" ipv6=[2a02:180:1:1::5b8f:538c]:443"
+/* nickname=torpidsDEisppro */
+/* extrainfo=0 */
/* ===== */
,
"212.51.134.123:9030 orport=9001 id=50586E25BE067FD1F739998550EDDCB1A14CA5B2"
@@ -320,6 +309,18 @@ URL: https:onionoo.torproject.orguptime?first_seen_days90-&flagV2Dir&typerelay&l
/* extrainfo=0 */
/* ===== */
,
+"192.160.102.166:80 orport=9001 id=547DA56F6B88B6C596B3E3086803CDA4F0EF8F21"
+" ipv6=[2620:132:300c:c01d::6]:9002"
+/* nickname=chaucer */
+/* extrainfo=0 */
+/* ===== */
+,
+"192.160.102.170:80 orport=9001 id=557ACEC850F54EEE65839F83CACE2B0825BE811E"
+" ipv6=[2620:132:300c:c01d::a]:9002"
+/* nickname=ogopogo */
+/* extrainfo=0 */
+/* ===== */
+,
"95.130.12.119:80 orport=443 id=587E0A9552E4274B251F29B5B2673D38442EE4BF"
/* nickname=Nuath */
/* extrainfo=0 */
@@ -331,19 +332,19 @@ URL: https:onionoo.torproject.orguptime?first_seen_days90-&flagV2Dir&typerelay&l
/* extrainfo=0 */
/* ===== */
,
-"172.98.193.43:80 orport=443 id=5E56738E7F97AA81DEEF59AF28494293DFBFCCDF"
-/* nickname=Backplane */
+"193.234.15.62:80 orport=443 id=5CF8AFA5E4B0BB88942A44A3F3AAE08C3BDFD60B"
+" ipv6=[2a00:1c20:4089:1234:a6a4:2926:d0af:dfee]:443"
+/* nickname=jaures4 */
/* extrainfo=0 */
/* ===== */
,
-"199.249.223.74:80 orport=443 id=5F4CD12099AF20FAF9ADFDCEC65316A376D0201C"
-/* nickname=QuintexAirVPN7 */
+"172.98.193.43:80 orport=443 id=5E56738E7F97AA81DEEF59AF28494293DFBFCCDF"
+/* nickname=Backplane */
/* extrainfo=0 */
/* ===== */
,
-"95.128.43.164:80 orport=443 id=616081EC829593AF4232550DE6FFAA1D75B37A90"
-" ipv6=[2a02:ec0:209:10::4]:443"
-/* nickname=AquaRayTerminus */
+"185.220.101.28:10028 orport=20028 id=609E598FB6A00BCF7872906B602B705B64541C50"
+/* nickname=niftychipmunk */
/* extrainfo=0 */
/* ===== */
,
@@ -352,88 +353,84 @@ URL: https:onionoo.torproject.orguptime?first_seen_days90-&flagV2Dir&typerelay&l
/* extrainfo=0 */
/* ===== */
,
-"85.214.62.48:80 orport=443 id=6A7551EEE18F78A9813096E82BF84F740D32B911"
-/* nickname=TorMachine */
-/* extrainfo=0 */
-/* ===== */
-,
"80.127.137.19:80 orport=443 id=6EF897645B79B6CB35E853B32506375014DE3621"
" ipv6=[2001:981:47c1:1::6]:443"
/* nickname=d6relay */
/* extrainfo=0 */
/* ===== */
,
-"85.235.250.88:80 orport=443 id=72B2B12A3F60408BDBC98C6DF53988D3A0B3F0EE"
-/* nickname=TykRelay01 */
+"37.139.8.104:9030 orport=9001 id=7088D485934E8A403B81531F8C90BDC75FA43C98"
+" ipv6=[2a03:b0c0:0:1010::24c:1001]:9001"
+/* nickname=Basil */
/* extrainfo=0 */
/* ===== */
,
-"81.7.14.31:9001 orport=443 id=7600680249A22080ECC6173FBBF64D6FCF330A61"
-/* nickname=Ichotolot62 */
+"188.138.88.42:80 orport=443 id=70C55A114C0EF3DC5784A4FAEE64388434A3398F"
+/* nickname=torpidsFRplusserver */
/* extrainfo=0 */
/* ===== */
,
-"134.119.36.135:80 orport=443 id=763C9556602BD6207771A7A3D958091D44C43228"
-" ipv6=[2a00:1158:3::2a8]:993"
-/* nickname=torpidsDEdomainf2 */
+"185.220.101.30:10030 orport=20030 id=71CFDEB4D9E00CCC3E31EC4E8A29E109BBC1FB36"
+/* nickname=niftypedetidae */
/* extrainfo=0 */
/* ===== */
,
-"188.166.133.133:9030 orport=9001 id=774555642FDC1E1D4FDF2E0C31B7CA9501C5C9C7"
-" ipv6=[2a03:b0c0:2:d0::26c0:1]:9001"
-/* nickname=dropsy */
+"85.235.250.88:80 orport=443 id=72B2B12A3F60408BDBC98C6DF53988D3A0B3F0EE"
+/* nickname=TykRelay01 */
/* extrainfo=0 */
/* ===== */
,
+"81.7.14.31:9001 orport=443 id=7600680249A22080ECC6173FBBF64D6FCF330A61"
+/* nickname=Ichotolot62 */
+/* extrainfo=1 */
+/* ===== */
+,
"5.196.23.64:9030 orport=9001 id=775B0FAFDE71AADC23FFC8782B7BEB1D5A92733E"
/* nickname=Aerodynamik01 */
/* extrainfo=0 */
/* ===== */
,
-"81.30.158.213:9030 orport=9001 id=789EA6C9AE9ADDD8760903171CFA9AC5741B0C70"
-" ipv6=[2001:4ba0:cafe:e84::1]:9001"
-/* nickname=dumpster */
+"51.254.136.195:80 orport=443 id=7BB70F8585DFC27E75D692970C0EEB0F22983A63"
+/* nickname=torproxy02 */
/* extrainfo=0 */
/* ===== */
,
-"104.200.20.46:80 orport=9001 id=78E2BE744A53631B4AAB781468E94C52AB73968B"
-/* nickname=bynumlawtor */
+"185.100.84.82:80 orport=443 id=7D05A38E39FC5D29AFE6BE487B9B4DC9E635D09E"
+/* nickname=saveyourprivacyexit */
/* extrainfo=0 */
/* ===== */
,
-"62.210.129.246:80 orport=443 id=79E169B25E4C7CE99584F6ED06F379478F23E2B8"
-/* nickname=MilesPrower */
+"193.11.114.45:9031 orport=9002 id=80AAF8D5956A43C197104CEF2550CD42D165C6FB"
+/* nickname=mdfnet2 */
/* extrainfo=0 */
/* ===== */
,
-"82.223.21.74:9030 orport=9001 id=7A32C9519D80CA458FC8B034A28F5F6815649A98"
-" ipv6=[2001:470:53e0::cafe]:9050"
-/* nickname=silentrocket */
+"51.254.96.208:9030 orport=9001 id=8101421BEFCCF4C271D5483C5AABCAAD245BBB9D"
+" ipv6=[2001:41d0:401:3100::30dc]:9001"
+/* nickname=rofltor01 */
/* extrainfo=0 */
/* ===== */
,
-"51.254.136.195:80 orport=443 id=7BB70F8585DFC27E75D692970C0EEB0F22983A63"
-/* nickname=torproxy02 */
+"217.12.199.190:80 orport=443 id=81AFA888F8F8F4A024AB58ECA0ADDEBB93FF01DA"
+" ipv6=[2a02:27a8:0:2::486]:993"
+/* nickname=torpidsUAitlas */
/* extrainfo=0 */
/* ===== */
,
-"77.247.181.162:80 orport=443 id=7BFB908A3AA5B491DA4CA72CCBEE0E1F2A939B55"
-/* nickname=sofia */
+"192.42.116.16:80 orport=443 id=81B75D534F91BFB7C57AB67DA10BCEF622582AE8"
+/* nickname=hviv104 */
/* extrainfo=0 */
/* ===== */
,
-"185.100.84.82:80 orport=443 id=7D05A38E39FC5D29AFE6BE487B9B4DC9E635D09E"
-/* nickname=saveyourprivacyexit */
+"192.160.102.164:80 orport=9001 id=823AA81E277F366505545522CEDC2F529CE4DC3F"
+" ipv6=[2620:132:300c:c01d::4]:9002"
+/* nickname=snowfall */
/* extrainfo=0 */
/* ===== */
,
-"199.249.223.69:80 orport=443 id=7FA8E7E44F1392A4E40FFC3B69DB3B00091B7FD3"
-/* nickname=Quintex20 */
-/* extrainfo=0 */
-/* ===== */
-,
-"193.11.114.45:9031 orport=9002 id=80AAF8D5956A43C197104CEF2550CD42D165C6FB"
-/* nickname=mdfnet2 */
+"192.87.28.82:9030 orport=9001 id=844AE9CAD04325E955E2BE1521563B79FE7094B7"
+" ipv6=[2001:678:230:3028:192:87:28:82]:9001"
+/* nickname=Smeerboel */
/* extrainfo=0 */
/* ===== */
,
@@ -442,23 +439,19 @@ URL: https:onionoo.torproject.orguptime?first_seen_days90-&flagV2Dir&typerelay&l
/* extrainfo=0 */
/* ===== */
,
-"85.230.184.93:9030 orport=443 id=855BC2DABE24C861CD887DB9B2E950424B49FC34"
-/* nickname=Logforme */
-/* extrainfo=0 */
-/* ===== */
-,
-"72.52.75.27:9030 orport=9001 id=8567AD0A6369ED08527A8A8533A5162AC00F7678"
-/* nickname=piecoopdotnet */
+"185.96.88.29:80 orport=443 id=86C281AD135058238D7A337D546C902BE8505DDE"
+/* nickname=TykRelay05 */
/* extrainfo=0 */
/* ===== */
,
-"185.96.88.29:80 orport=443 id=86C281AD135058238D7A337D546C902BE8505DDE"
-/* nickname=TykRelay05 */
+"93.180.156.84:9030 orport=9001 id=8844D87E9B038BE3270938F05AF797E1D3C74C0F"
+/* nickname=BARACUDA */
/* extrainfo=0 */
/* ===== */
,
-"176.10.104.243:80 orport=443 id=88487BDD980BF6E72092EE690E8C51C0AA4A538C"
-/* nickname=DigiGesTor2e1 */
+"51.15.205.214:9030 orport=9001 id=8B6556601612F1E2AFCE2A12FFFAF8482A76DD1F"
+" ipv6=[2001:bc8:4400:2500::5:b07]:9001"
+/* nickname=titania1 */
/* extrainfo=0 */
/* ===== */
,
@@ -468,14 +461,8 @@ URL: https:onionoo.torproject.orguptime?first_seen_days90-&flagV2Dir&typerelay&l
/* extrainfo=0 */
/* ===== */
,
-"5.189.169.190:8030 orport=8080 id=8D79F73DCD91FC4F5017422FAC70074D6DB8DD81"
-/* nickname=thanatosDE */
-/* extrainfo=0 */
-/* ===== */
-,
-"151.80.42.103:9030 orport=9001 id=9007C1D8E4F03D506A4A011B907A9E8D04E3C605"
-" ipv6=[2001:41d0:e:f67::114]:9001"
-/* nickname=matlink */
+"81.7.11.96:9030 orport=9001 id=8FA37B93397015B2BC5A525C908485260BE9F422"
+/* nickname=Doedel22 */
/* extrainfo=0 */
/* ===== */
,
@@ -485,19 +472,29 @@ URL: https:onionoo.torproject.orguptime?first_seen_days90-&flagV2Dir&typerelay&l
/* extrainfo=0 */
/* ===== */
,
-"62.138.7.171:8030 orport=8001 id=9285B22F7953D7874604EEE2B470609AD81C74E9"
-/* nickname=0x3d005 */
+"51.255.41.65:9030 orport=9001 id=9231DF741915AA1630031A93026D88726877E93A"
+/* nickname=PrisnCellRelayFR1 */
+/* extrainfo=0 */
+/* ===== */
+,
+"54.37.73.111:9030 orport=9001 id=92412EA1B9AA887D462B51D816777002F4D58907"
+/* nickname=Aerodynamik05 */
/* extrainfo=0 */
/* ===== */
,
-"178.16.208.57:80 orport=443 id=92CFD9565B24646CAC2D172D3DB503D69E777B8A"
+"96.253.78.108:80 orport=443 id=924B24AFA7F075D059E8EEB284CC400B33D3D036"
+/* nickname=NSDFreedom */
+/* extrainfo=0 */
+/* ===== */
+,
+"193.234.15.57:80 orport=443 id=92CFD9565B24646CAC2D172D3DB503D69E777B8A"
" ipv6=[2a00:1c20:4089:1234:7825:2c5d:1ecd:c66f]:443"
/* nickname=bakunin */
/* extrainfo=0 */
/* ===== */
,
-"91.219.237.244:80 orport=443 id=92ECC9E0E2AF81BB954719B189AC362E254AD4A5"
-/* nickname=lewwerDuarUesSlaav */
+"204.8.156.142:80 orport=443 id=94C4B7B8C50C86A92B6A20107539EE2678CF9A28"
+/* nickname=BostonUCompSci */
/* extrainfo=0 */
/* ===== */
,
@@ -506,8 +503,8 @@ URL: https:onionoo.torproject.orguptime?first_seen_days90-&flagV2Dir&typerelay&l
/* extrainfo=0 */
/* ===== */
,
-"163.172.223.200:80 orport=443 id=998BF3ED7F70E33D1C307247B9626D9E7573C438"
-/* nickname=Outfall2 */
+"173.212.254.192:31336 orport=31337 id=99E246DB480B313A3012BC3363093CC26CD209C7"
+/* nickname=ViDiSrv */
/* extrainfo=0 */
/* ===== */
,
@@ -517,22 +514,24 @@ URL: https:onionoo.torproject.orguptime?first_seen_days90-&flagV2Dir&typerelay&l
/* ===== */
,
"66.111.2.20:9030 orport=9001 id=9A68B85A02318F4E7E87F2828039FBD5D75B0142"
+" ipv6=[2610:1c0:0:5::20]:9001"
/* nickname=NYCBUG0 */
/* extrainfo=0 */
/* ===== */
,
"185.100.86.128:9030 orport=9001 id=9B31F1F1C1554F9FFB3455911F82E818EF7C7883"
+" ipv6=[2a06:1700:1::11]:9001"
/* nickname=TorExitFinland */
/* extrainfo=0 */
/* ===== */
,
-"146.185.177.103:80 orport=9030 id=9EC5E097663862DF861A18C32B37C5F82284B27D"
-/* nickname=Winter */
+"86.105.212.130:9030 orport=443 id=9C900A7F6F5DD034CFFD192DAEC9CCAA813DB022"
+/* nickname=firstor2 */
/* extrainfo=0 */
/* ===== */
,
-"199.249.223.64:80 orport=443 id=9F2856F6D2B89AD4EF6D5723FAB167DB5A53519A"
-/* nickname=Quintex15 */
+"31.185.104.19:80 orport=443 id=9EAD5B2D3DBD96DBC80DCE423B0C345E920A758D"
+/* nickname=Digitalcourage3ip1 */
/* extrainfo=0 */
/* ===== */
,
@@ -541,11 +540,6 @@ URL: https:onionoo.torproject.orguptime?first_seen_days90-&flagV2Dir&typerelay&l
/* extrainfo=0 */
/* ===== */
,
-"91.121.84.137:4952 orport=4052 id=9FBEB75E8BC142565F12CBBE078D63310236A334"
-/* nickname=lindon */
-/* extrainfo=0 */
-/* ===== */
-,
"46.165.230.5:80 orport=443 id=A0F06C2FADF88D3A39AA3072B406F09D7095AC9E"
/* nickname=Dhalgren */
/* extrainfo=1 */
@@ -557,9 +551,14 @@ URL: https:onionoo.torproject.orguptime?first_seen_days90-&flagV2Dir&typerelay&l
/* extrainfo=0 */
/* ===== */
,
+"87.118.122.120:80 orport=443 id=A2A6616723B511D8E068BB71705191763191F6B2"
+/* nickname=otheontelth */
+/* extrainfo=0 */
+/* ===== */
+,
"81.7.3.67:993 orport=443 id=A2E6BB5C391CD46B38C55B4329C35304540771F1"
/* nickname=BeastieJoy62 */
-/* extrainfo=0 */
+/* extrainfo=1 */
/* ===== */
,
"171.25.193.78:80 orport=443 id=A478E421F83194C114F41E94F95999672AED51FE"
@@ -568,23 +567,31 @@ URL: https:onionoo.torproject.orguptime?first_seen_days90-&flagV2Dir&typerelay&l
/* extrainfo=0 */
/* ===== */
,
-"178.16.208.58:80 orport=443 id=A4C98CEA3F34E05299417E9F885A642C88EF6029"
+"193.234.15.58:80 orport=443 id=A4C98CEA3F34E05299417E9F885A642C88EF6029"
" ipv6=[2a00:1c20:4089:1234:cdae:1b3e:cc38:3d45]:443"
/* nickname=jaures2 */
/* extrainfo=0 */
/* ===== */
,
-"163.172.149.122:80 orport=443 id=A9406A006D6E7B5DA30F2C6D4E42A338B5E340B2"
-/* nickname=niij03 */
+"128.31.0.13:80 orport=443 id=A53C46F5B157DD83366D45A8E99A244934A14C46"
+/* nickname=csailmitexit */
+/* extrainfo=0 */
+/* ===== */
+,
+"94.142.242.84:80 orport=443 id=AA0D167E03E298F9A8CD50F448B81FBD7FA80D56"
+" ipv6=[2a02:898:24:84::1]:443"
+/* nickname=rejozenger */
/* extrainfo=0 */
/* ===== */
,
"195.154.164.243:80 orport=443 id=AC66FFA4AB35A59EBBF5BF4C70008BF24D8A7A5C"
+" ipv6=[2001:bc8:399f:f000::1]:993"
/* nickname=torpidsFRonline3 */
/* extrainfo=0 */
/* ===== */
,
"86.59.119.88:80 orport=443 id=ACD889D86E02EDDAB1AFD81F598C0936238DC6D0"
+" ipv6=[2001:858:2:30:86:59:119:88]:443"
/* nickname=ph3x */
/* extrainfo=0 */
/* ===== */
@@ -601,10 +608,15 @@ URL: https:onionoo.torproject.orguptime?first_seen_days90-&flagV2Dir&typerelay&l
/* extrainfo=0 */
/* ===== */
,
-"176.126.252.11:443 orport=9001 id=B0279A521375F3CB2AE210BDBFC645FDD2E1973A"
-" ipv6=[2a02:59e0:0:7::11]:9003"
-/* nickname=chulak */
-/* extrainfo=1 */
+"31.185.104.20:80 orport=443 id=ADB2C26629643DBB9F8FE0096E7D16F9414B4F8D"
+/* nickname=Digitalcourage3ip2 */
+/* extrainfo=0 */
+/* ===== */
+,
+"45.79.108.130:9030 orport=9001 id=AEDAC7081AE14B8D241ECF0FF17A2858AB4383D0"
+" ipv6=[2600:3c01:e000:131::8000:0]:9001"
+/* nickname=linss */
+/* extrainfo=0 */
/* ===== */
,
"5.9.147.226:9030 orport=9001 id=B0553175AADB0501E5A61FC61CEA3970BE130FF2"
@@ -614,15 +626,11 @@ URL: https:onionoo.torproject.orguptime?first_seen_days90-&flagV2Dir&typerelay&l
/* ===== */
,
"178.17.174.14:9030 orport=9001 id=B06F093A3D4DFAD3E923F4F28A74901BD4F74EB1"
+" ipv6=[2a00:1dc0:caff:8b::5b9a]:9001"
/* nickname=TorExitMoldova */
/* extrainfo=0 */
/* ===== */
,
-"199.249.223.40:80 orport=443 id=B0CD9F9B5B60651ADC5919C0F1EAA87DBA1D9249"
-/* nickname=Quintex31 */
-/* extrainfo=0 */
-/* ===== */
-,
"212.129.62.232:80 orport=443 id=B143D439B72D239A419F8DCE07B8A8EB1B486FA7"
/* nickname=wardsback */
/* extrainfo=0 */
@@ -633,8 +641,9 @@ URL: https:onionoo.torproject.orguptime?first_seen_days90-&flagV2Dir&typerelay&l
/* extrainfo=0 */
/* ===== */
,
-"212.47.233.86:9030 orport=9001 id=B4CAFD9CBFB34EC5DAAC146920DC7DFAFE91EA20"
-/* nickname=netimanmu */
+"193.234.15.60:80 orport=443 id=B44FBE5366AD98B46D829754FA4AC599BAE41A6A"
+" ipv6=[2a00:1c20:4089:1234:67bc:79f3:61c0:6e49]:443"
+/* nickname=jaures3 */
/* extrainfo=0 */
/* ===== */
,
@@ -649,39 +658,51 @@ URL: https:onionoo.torproject.orguptime?first_seen_days90-&flagV2Dir&typerelay&l
/* extrainfo=0 */
/* ===== */
,
+"185.220.101.32:10032 orport=20032 id=B771AA877687F88E6F1CA5354756DF6C8A7B6B24"
+/* nickname=niftypika */
+/* extrainfo=0 */
+/* ===== */
+,
"193.11.114.46:9032 orport=9003 id=B83DC1558F0D34353BB992EF93AFEAFDB226A73E"
/* nickname=mdfnet3 */
/* extrainfo=0 */
/* ===== */
,
+"85.248.227.164:444 orport=9002 id=B84F248233FEA90CAD439F292556A3139F6E1B82"
+" ipv6=[2a00:1298:8011:212::164]:9004"
+/* nickname=tollana */
+/* extrainfo=0 */
+/* ===== */
+,
"81.7.11.186:1080 orport=443 id=B86137AE9681701901C6720E55C16805B46BD8E3"
/* nickname=BeastieJoy60 */
-/* extrainfo=0 */
+/* extrainfo=1 */
/* ===== */
,
-"197.231.221.211:9030 orport=443 id=BC630CBBB518BE7E9F4E09712AB0269E9DC7D626"
-/* nickname=IPredator */
+"213.141.138.174:9030 orport=9001 id=BD552C165E2ED2887D3F1CCE9CFF155DDA2D86E6"
+/* nickname=Schakalium */
/* extrainfo=0 */
/* ===== */
,
-"198.96.155.3:8080 orport=5001 id=BCEDF6C193AA687AE471B8A22EBF6BC57C2D285E"
-/* nickname=gurgle */
+"148.251.190.229:9030 orport=9010 id=BF0FB582E37F738CD33C3651125F2772705BB8E8"
+" ipv6=[2a01:4f8:211:c68::2]:9010"
+/* nickname=quadhead */
/* extrainfo=0 */
/* ===== */
,
-"128.199.55.207:9030 orport=9001 id=BCEF908195805E03E92CCFE669C48738E556B9C5"
-" ipv6=[2a03:b0c0:2:d0::158:3001]:9001"
-/* nickname=EldritchReaper */
+"104.192.5.248:9030 orport=443 id=BF735F669481EE1CCC348F0731551C933D1E2278"
+/* nickname=Freeway1a1 */
/* extrainfo=0 */
/* ===== */
,
-"213.141.138.174:9030 orport=9001 id=BD552C165E2ED2887D3F1CCE9CFF155DDA2D86E6"
-/* nickname=Schakalium */
+"192.160.102.169:80 orport=9001 id=C0192FF43E777250084175F4E59AC1BA2290CE38"
+" ipv6=[2620:132:300c:c01d::9]:9002"
+/* nickname=manipogo */
/* extrainfo=0 */
/* ===== */
,
-"104.192.5.248:9030 orport=9001 id=BF735F669481EE1CCC348F0731551C933D1E2278"
-/* nickname=Freeway11 */
+"185.220.101.6:10006 orport=20006 id=C08DE49658E5B3CFC6F2A952B453C4B608C9A16A"
+/* nickname=niftyvolcanorabbit */
/* extrainfo=0 */
/* ===== */
,
@@ -701,18 +722,31 @@ URL: https:onionoo.torproject.orguptime?first_seen_days90-&flagV2Dir&typerelay&l
/* extrainfo=0 */
/* ===== */
,
-"199.249.223.66:80 orport=443 id=C5A53BCC174EF8FD0DCB223E4AA929FA557DEDB2"
-/* nickname=Quintex17 */
+"193.234.15.55:80 orport=443 id=C4AEA05CF380BAD2230F193E083B8869B4A29937"
+" ipv6=[2a00:1c20:4089:1234:7b2c:11c5:5221:903e]:443"
+/* nickname=bakunin4 */
/* extrainfo=0 */
/* ===== */
,
-"85.25.213.211:465 orport=80 id=CE47F0356D86CF0A1A2008D97623216D560FB0A8"
-/* nickname=BeastieJoy61 */
+"85.248.227.163:443 orport=9001 id=C793AB88565DDD3C9E4C6F15CCB9D8C7EF964CE9"
+" ipv6=[2a00:1298:8011:212::163]:9003"
+/* nickname=ori */
+/* extrainfo=0 */
+/* ===== */
+,
+"192.160.102.165:80 orport=9001 id=C90CA3B7FE01A146B8268D56977DC4A2C024B9EA"
+" ipv6=[2620:132:300c:c01d::5]:9002"
+/* nickname=cowcat */
/* extrainfo=0 */
/* ===== */
,
-"51.15.13.245:9030 orport=9001 id=CED527EAC230E7B56E5B363F839671829C3BA01B"
-/* nickname=0x3d006 */
+"176.31.103.150:9030 orport=9001 id=CBD0D1BD110EC52963082D839AC6A89D0AE243E7"
+/* nickname=UV74S7mjxRcYVrGsAMw */
+/* extrainfo=0 */
+/* ===== */
+,
+"85.25.213.211:465 orport=80 id=CE47F0356D86CF0A1A2008D97623216D560FB0A8"
+/* nickname=BeastieJoy61 */
/* extrainfo=0 */
/* ===== */
,
@@ -721,19 +755,24 @@ URL: https:onionoo.torproject.orguptime?first_seen_days90-&flagV2Dir&typerelay&l
/* extrainfo=0 */
/* ===== */
,
-"31.171.155.108:9030 orport=9001 id=D3E5EDDBE5159388704D6785BE51930AAFACEC6F"
-/* nickname=TorNodeAlbania */
+"5.45.111.149:80 orport=443 id=D405FCCF06ADEDF898DF2F29C9348DCB623031BA"
+" ipv6=[2a03:4000:6:2388:df98:15f9:b34d:443]:443"
+/* nickname=gGDHjdcC6zAlM8k08lY */
/* extrainfo=0 */
/* ===== */
,
-"37.221.162.226:9030 orport=9001 id=D64366987CB39F61AD21DBCF8142FA0577B92811"
-/* nickname=kasperskytor01 */
+"37.187.115.157:9030 orport=9001 id=D5039E1EBFD96D9A3F9846BF99EC9F75EDDE902A"
+/* nickname=Janky328891 */
/* extrainfo=0 */
/* ===== */
,
-"46.101.169.151:9030 orport=9001 id=D760C5B436E42F93D77EF2D969157EEA14F9B39C"
-" ipv6=[2a03:b0c0:3:d0::74f:a001]:9001"
-/* nickname=DanWin1210 */
+"217.182.51.248:80 orport=443 id=D6BA940D3255AB40DC5EE5B0B285FA143E1F9865"
+/* nickname=Cosworth02 */
+/* extrainfo=0 */
+/* ===== */
+,
+"185.34.33.2:9265 orport=31415 id=D71B1CA1C9DC7E8CA64158E106AD770A21160FEE"
+/* nickname=lqdn */
/* extrainfo=0 */
/* ===== */
,
@@ -748,6 +787,11 @@ URL: https:onionoo.torproject.orguptime?first_seen_days90-&flagV2Dir&typerelay&l
/* extrainfo=0 */
/* ===== */
,
+"54.36.237.163:80 orport=443 id=DB2682153AC0CCAECD2BD1E9EBE99C6815807A1E"
+/* nickname=GermanCraft2 */
+/* extrainfo=0 */
+/* ===== */
+,
"178.33.183.251:80 orport=443 id=DD823AFB415380A802DCAEB9461AE637604107FB"
" ipv6=[2001:41d0:2:a683::251]:443"
/* nickname=grenouille */
@@ -760,34 +804,36 @@ URL: https:onionoo.torproject.orguptime?first_seen_days90-&flagV2Dir&typerelay&l
/* extrainfo=0 */
/* ===== */
,
-"92.222.38.67:80 orport=443 id=DED6892FF89DBD737BA689698A171B2392EB3E82"
-/* nickname=ThorExit */
+"83.212.99.68:80 orport=443 id=DDBB2A38252ADDA53E4492DDF982CA6CC6E10EC0"
+" ipv6=[2001:648:2ffc:1225:a800:bff:fe3d:67b5]:443"
+/* nickname=zouzounella */
/* extrainfo=0 */
/* ===== */
,
-"166.70.207.2:9030 orport=9001 id=E3DB2E354B883B59E8DC56B3E7A353DDFD457812"
-/* nickname=xmission */
+"92.222.38.67:80 orport=443 id=DED6892FF89DBD737BA689698A171B2392EB3E82"
+" ipv6=[2001:41d0:52:100::112a]:443"
+/* nickname=ThorExit */
/* extrainfo=0 */
/* ===== */
,
-"199.249.223.43:80 orport=443 id=E480D577F58E782A5BC4FA6F49A6650E9389302F"
-/* nickname=Quintex34 */
+"185.100.86.182:9030 orport=8080 id=E51620B90DCB310138ED89EDEDD0A5C361AAE24E"
+/* nickname=NormalCitizen */
/* extrainfo=0 */
/* ===== */
,
-"46.252.26.2:45212 orport=49991 id=E589316576A399C511A9781A73DA4545640B479D"
-/* nickname=marlen */
+"212.47.244.38:8080 orport=443 id=E81EF60A73B3809F8964F73766B01BAA0A171E20"
+/* nickname=Chimborazo */
/* extrainfo=0 */
/* ===== */
,
-"176.31.180.157:143 orport=22 id=E781F4EC69671B3F1864AE2753E0890351506329"
-" ipv6=[2001:41d0:8:eb9d::1]:22"
-/* nickname=armbrust */
+"51.254.147.57:80 orport=443 id=EB80A8D52F07238B576C42CEAB98ADD084EE075E"
+/* nickname=Cosworth01 */
/* extrainfo=0 */
/* ===== */
,
-"212.47.244.38:8080 orport=443 id=E81EF60A73B3809F8964F73766B01BAA0A171E20"
-/* nickname=Chimborazo */
+"192.87.28.28:9030 orport=9001 id=ED2338CAC2711B3E331392E1ED2831219B794024"
+" ipv6=[2001:678:230:3028:192:87:28:28]:9001"
+/* nickname=SEC6xFreeBSD64 */
/* extrainfo=0 */
/* ===== */
,
@@ -796,31 +842,60 @@ URL: https:onionoo.torproject.orguptime?first_seen_days90-&flagV2Dir&typerelay&l
/* extrainfo=0 */
/* ===== */
,
+"193.70.112.165:80 orport=443 id=F10BDE279AE71515DDCCCC61DC19AC8765F8A3CC"
+/* nickname=ParkBenchInd001 */
+/* extrainfo=0 */
+/* ===== */
+,
+"129.13.131.140:80 orport=443 id=F2DFE5FA1E4CF54F8E761A6D304B9B4EC69BDAE8"
+" ipv6=[2a00:1398:5:f604:cafe:cafe:cafe:9001]:443"
+/* nickname=AlleKochenKaffee */
+/* extrainfo=0 */
+/* ===== */
+,
"37.187.102.108:80 orport=443 id=F4263275CF54A6836EE7BD527B1328836A6F06E1"
" ipv6=[2001:41d0:a:266c::1]:443"
/* nickname=EvilMoe */
/* extrainfo=0 */
/* ===== */
,
-"46.28.109.231:9030 orport=9001 id=F70B7C5CD72D74C7F9F2DC84FA9D20D51BA13610"
-" ipv6=[2a02:2b88:2:1::4205:1]:9001"
-/* nickname=wedostor */
+"192.160.102.168:80 orport=9001 id=F6A358DD367B3282D6EF5824C9D45E1A19C7E815"
+" ipv6=[2620:132:300c:c01d::8]:9002"
+/* nickname=prawksi */
+/* extrainfo=0 */
+/* ===== */
+,
+"163.172.154.162:9030 orport=9001 id=F741E5124CB12700DA946B78C9B2DD175D6CD2A1"
+" ipv6=[2001:bc8:4400:2100::17:419]:9001"
+/* nickname=rofltor06 */
/* extrainfo=0 */
/* ===== */
,
+"78.47.18.110:443 orport=80 id=F8D27B163B9247B232A2EEE68DD8B698695C28DE"
+" ipv6=[2a01:4f8:120:4023::110]:80"
+/* nickname=fluxe3 */
+/* extrainfo=1 */
+/* ===== */
+,
+"178.254.19.101:80 orport=443 id=F9246DEF2B653807236DA134F2AEAB103D58ABFE"
+/* nickname=Freebird31 */
+/* extrainfo=1 */
+/* ===== */
+,
"185.96.180.29:80 orport=443 id=F93D8F37E35C390BCAD9F9069E13085B745EC216"
/* nickname=TykRelay06 */
/* extrainfo=0 */
/* ===== */
,
"86.59.119.83:80 orport=443 id=FC9AC8EA0160D88BCCFDE066940D7DD9FA45495B"
+" ipv6=[2001:858:2:30:86:59:119:83]:443"
/* nickname=ph3x */
/* extrainfo=0 */
/* ===== */
,
"149.56.45.200:9030 orport=9001 id=FE296180018833AF03A8EACD5894A614623D3F76"
" ipv6=[2607:5300:201:3000::17d3]:9002"
-/* nickname=PiotrTorpotkinOne */
+/* nickname=PyotrTorpotkinOne */
/* extrainfo=0 */
/* ===== */
,
diff --git a/src/core/include.am b/src/core/include.am
index 48d75618ad..3cd6e83ed5 100644
--- a/src/core/include.am
+++ b/src/core/include.am
@@ -62,6 +62,7 @@ LIBTOR_APP_A_SOURCES = \
src/feature/client/entrynodes.c \
src/feature/client/transports.c \
src/feature/control/control.c \
+ src/feature/control/control_bootstrap.c \
src/feature/control/fmt_serverstatus.c \
src/feature/control/getinfo_geoip.c \
src/feature/dirauth/keypin.c \
diff --git a/src/core/or/versions.c b/src/core/or/versions.c
index a1336c7a78..7bd1f5899f 100644
--- a/src/core/or/versions.c
+++ b/src/core/or/versions.c
@@ -16,6 +16,25 @@
#include "core/or/tor_version_st.h"
+/**
+ * Return the approximate date when this release came out, or was
+ * scheduled to come out, according to the APPROX_RELEASE_DATE set in
+ * configure.ac
+ **/
+time_t
+tor_get_approx_release_date(void)
+{
+ char tbuf[ISO_TIME_LEN+1];
+ tor_snprintf(tbuf, sizeof(tbuf),
+ "%s 00:00:00", APPROX_RELEASE_DATE);
+ time_t result = 0;
+ int r = parse_iso_time(tbuf, &result);
+ if (BUG(r < 0)) {
+ result = 0;
+ }
+ return result;
+}
+
/** Return VS_RECOMMENDED if <b>myversion</b> is contained in
* <b>versionlist</b>. Else, return VS_EMPTY if versionlist has no
* entries. Else, return VS_OLD if every member of
diff --git a/src/core/or/versions.h b/src/core/or/versions.h
index 4fc50a0018..acd8998918 100644
--- a/src/core/or/versions.h
+++ b/src/core/or/versions.h
@@ -26,6 +26,8 @@ typedef enum version_status_t {
VS_UNKNOWN, /**< We have no idea. */
} version_status_t;
+time_t tor_get_approx_release_date(void);
+
version_status_t tor_version_is_obsolete(const char *myversion,
const char *versionlist);
int tor_version_parse_platform(const char *platform,
diff --git a/src/feature/control/control.c b/src/feature/control/control.c
index 26d2e54fed..c2da7fe48b 100644
--- a/src/feature/control/control.c
+++ b/src/feature/control/control.c
@@ -179,13 +179,6 @@ static uint8_t *authentication_cookie = NULL;
*/
static smartlist_t *detached_onion_services = NULL;
-/** A sufficiently large size to record the last bootstrap phase string. */
-#define BOOTSTRAP_MSG_LEN 1024
-
-/** What was the last bootstrap phase message we sent? We keep track
- * of this so we can respond to getinfo status/bootstrap-phase queries. */
-static char last_sent_bootstrap_message[BOOTSTRAP_MSG_LEN];
-
static void connection_printf_to_buf(control_connection_t *conn,
const char *format, ...)
CHECK_PRINTF(2,3);
@@ -3044,7 +3037,7 @@ getinfo_helper_events(control_connection_t *control_conn,
check_whether_orport_reachable(options) ? 1 : 0,
check_whether_dirport_reachable(options) ? 1 : 0);
} else if (!strcmp(question, "status/bootstrap-phase")) {
- *answer = tor_strdup(last_sent_bootstrap_message);
+ *answer = control_event_boot_last_msg();
} else if (!strcmpstart(question, "status/version/")) {
int is_server = server_mode(options);
networkstatus_t *c = networkstatus_get_latest_consensus();
@@ -7015,361 +7008,6 @@ monitor_owning_controller_process(const char *process_spec)
}
}
-/** Convert the name of a bootstrapping phase <b>s</b> into strings
- * <b>tag</b> and <b>summary</b> suitable for display by the controller. */
-static int
-bootstrap_status_to_string(bootstrap_status_t s, const char **tag,
- const char **summary)
-{
- switch (s) {
- case BOOTSTRAP_STATUS_UNDEF:
- *tag = "undef";
- *summary = "Undefined";
- break;
- case BOOTSTRAP_STATUS_STARTING:
- *tag = "starting";
- *summary = "Starting";
- break;
- case BOOTSTRAP_STATUS_CONN_DIR:
- *tag = "conn_dir";
- *summary = "Connecting to directory server";
- break;
- case BOOTSTRAP_STATUS_HANDSHAKE:
- *tag = "status_handshake";
- *summary = "Finishing handshake";
- break;
- case BOOTSTRAP_STATUS_HANDSHAKE_DIR:
- *tag = "handshake_dir";
- *summary = "Finishing handshake with directory server";
- break;
- case BOOTSTRAP_STATUS_ONEHOP_CREATE:
- *tag = "onehop_create";
- *summary = "Establishing an encrypted directory connection";
- break;
- case BOOTSTRAP_STATUS_REQUESTING_STATUS:
- *tag = "requesting_status";
- *summary = "Asking for networkstatus consensus";
- break;
- case BOOTSTRAP_STATUS_LOADING_STATUS:
- *tag = "loading_status";
- *summary = "Loading networkstatus consensus";
- break;
- case BOOTSTRAP_STATUS_LOADING_KEYS:
- *tag = "loading_keys";
- *summary = "Loading authority key certs";
- break;
- case BOOTSTRAP_STATUS_REQUESTING_DESCRIPTORS:
- *tag = "requesting_descriptors";
- /* XXXX this appears to incorrectly report internal on most loads */
- *summary = router_have_consensus_path() == CONSENSUS_PATH_INTERNAL ?
- "Asking for relay descriptors for internal paths" :
- "Asking for relay descriptors";
- break;
- /* If we're sure there are no exits in the consensus,
- * inform the controller by adding "internal"
- * to the status summaries.
- * (We only check this while loading descriptors,
- * so we may not know in the earlier stages.)
- * But if there are exits, we can't be sure whether
- * we're creating internal or exit paths/circuits.
- * XXXX Or should be use different tags or statuses
- * for internal and exit/all? */
- case BOOTSTRAP_STATUS_LOADING_DESCRIPTORS:
- *tag = "loading_descriptors";
- *summary = router_have_consensus_path() == CONSENSUS_PATH_INTERNAL ?
- "Loading relay descriptors for internal paths" :
- "Loading relay descriptors";
- break;
- case BOOTSTRAP_STATUS_CONN_OR:
- *tag = "conn_or";
- *summary = router_have_consensus_path() == CONSENSUS_PATH_INTERNAL ?
- "Connecting to the Tor network internally" :
- "Connecting to the Tor network";
- break;
- case BOOTSTRAP_STATUS_HANDSHAKE_OR:
- *tag = "handshake_or";
- *summary = router_have_consensus_path() == CONSENSUS_PATH_INTERNAL ?
- "Finishing handshake with first hop of internal circuit" :
- "Finishing handshake with first hop";
- break;
- case BOOTSTRAP_STATUS_CIRCUIT_CREATE:
- *tag = "circuit_create";
- *summary = router_have_consensus_path() == CONSENSUS_PATH_INTERNAL ?
- "Establishing an internal Tor circuit" :
- "Establishing a Tor circuit";
- break;
- case BOOTSTRAP_STATUS_DONE:
- *tag = "done";
- *summary = "Done";
- break;
- default:
-// log_warn(LD_BUG, "Unrecognized bootstrap status code %d", s);
- *tag = *summary = "unknown";
- return -1;
- }
- return 0;
-}
-
-/** What percentage through the bootstrap process are we? We remember
- * this so we can avoid sending redundant bootstrap status events, and
- * so we can guess context for the bootstrap messages which are
- * ambiguous. It starts at 'undef', but gets set to 'starting' while
- * Tor initializes. */
-static int bootstrap_percent = BOOTSTRAP_STATUS_UNDEF;
-
-/** Like bootstrap_percent, but only takes on the enumerated values in
- * bootstrap_status_t.
- */
-static int bootstrap_phase = BOOTSTRAP_STATUS_UNDEF;
-
-/** As bootstrap_percent, but holds the bootstrapping level at which we last
- * logged a NOTICE-level message. We use this, plus BOOTSTRAP_PCT_INCREMENT,
- * to avoid flooding the log with a new message every time we get a few more
- * microdescriptors */
-static int notice_bootstrap_percent = 0;
-
-/** How many problems have we had getting to the next bootstrapping phase?
- * These include failure to establish a connection to a Tor relay,
- * failures to finish the TLS handshake, failures to validate the
- * consensus document, etc. */
-static int bootstrap_problems = 0;
-
-/** We only tell the controller once we've hit a threshold of problems
- * for the current phase. */
-#define BOOTSTRAP_PROBLEM_THRESHOLD 10
-
-/** When our bootstrapping progress level changes, but our bootstrapping
- * status has not advanced, we only log at NOTICE when we have made at least
- * this much progress.
- */
-#define BOOTSTRAP_PCT_INCREMENT 5
-
-/** Do the actual logging and notifications for
- * control_event_bootstrap(). Doesn't change any state beyond that.
- */
-static void
-control_event_bootstrap_core(int loglevel, bootstrap_status_t status,
- int progress)
-{
- char buf[BOOTSTRAP_MSG_LEN];
- const char *tag, *summary;
-
- bootstrap_status_to_string(status, &tag, &summary);
- /* Locally reset status if there's incremental progress */
- if (progress)
- status = progress;
-
- tor_log(loglevel, LD_CONTROL,
- "Bootstrapped %d%%: %s", status, summary);
- tor_snprintf(buf, sizeof(buf),
- "BOOTSTRAP PROGRESS=%d TAG=%s SUMMARY=\"%s\"",
- status, tag, summary);
- tor_snprintf(last_sent_bootstrap_message,
- sizeof(last_sent_bootstrap_message),
- "NOTICE %s", buf);
- control_event_client_status(LOG_NOTICE, "%s", buf);
-}
-
-/** Called when Tor has made progress at bootstrapping its directory
- * information and initial circuits.
- *
- * <b>status</b> is the new status, that is, what task we will be doing
- * next. <b>progress</b> is zero if we just started this task, else it
- * represents progress on the task.
- */
-void
-control_event_bootstrap(bootstrap_status_t status, int progress)
-{
- int loglevel = LOG_NOTICE;
-
- if (bootstrap_percent == BOOTSTRAP_STATUS_DONE)
- return; /* already bootstrapped; nothing to be done here. */
-
- /* special case for handshaking status, since our TLS handshaking code
- * can't distinguish what the connection is going to be for. */
- if (status == BOOTSTRAP_STATUS_HANDSHAKE) {
- if (bootstrap_percent < BOOTSTRAP_STATUS_CONN_OR) {
- status = BOOTSTRAP_STATUS_HANDSHAKE_DIR;
- } else {
- status = BOOTSTRAP_STATUS_HANDSHAKE_OR;
- }
- }
-
- if (status <= bootstrap_percent) {
- /* If there's no new progress, return early. */
- if (!progress || progress <= bootstrap_percent)
- return;
- /* Log at INFO if not enough progress happened. */
- if (progress < notice_bootstrap_percent + BOOTSTRAP_PCT_INCREMENT)
- loglevel = LOG_INFO;
- }
-
- control_event_bootstrap_core(loglevel, status, progress);
-
- if (status > bootstrap_percent) {
- bootstrap_phase = status; /* new milestone reached */
- bootstrap_percent = status;
- }
- if (progress > bootstrap_percent) {
- /* incremental progress within a milestone */
- bootstrap_percent = progress;
- bootstrap_problems = 0; /* Progress! Reset our problem counter. */
- }
- if (loglevel == LOG_NOTICE &&
- bootstrap_percent > notice_bootstrap_percent) {
- /* Remember that we gave a notice at this level. */
- notice_bootstrap_percent = bootstrap_percent;
- }
-}
-
-/** Flag whether we've opened an OR_CONN yet */
-static int bootstrap_first_orconn = 0;
-
-/** Like bootstrap_phase, but for (possibly deferred) directory progress */
-static int bootstrap_dir_phase = BOOTSTRAP_STATUS_UNDEF;
-
-/** Like bootstrap_problems, but for (possibly deferred) directory progress */
-static int bootstrap_dir_progress = BOOTSTRAP_STATUS_UNDEF;
-
-/** Defer directory info bootstrap events until we have successfully
- * completed our first connection to a router. */
-void
-control_event_boot_dir(bootstrap_status_t status, int progress)
-{
- if (status > bootstrap_dir_progress) {
- bootstrap_dir_progress = status;
- bootstrap_dir_phase = status;
- }
- if (progress && progress >= bootstrap_dir_progress) {
- bootstrap_dir_progress = progress;
- }
-
- /* Don't report unless we have successfully opened at least one OR_CONN */
- if (!bootstrap_first_orconn)
- return;
-
- control_event_bootstrap(status, progress);
-}
-
-/** Set a flag to allow reporting of directory bootstrap progress.
- * (Code that reports completion of an OR_CONN calls this.) Also,
- * report directory progress so far. */
-void
-control_event_boot_first_orconn(void)
-{
- bootstrap_first_orconn = 1;
- control_event_bootstrap(bootstrap_dir_phase, bootstrap_dir_progress);
-}
-
-/** Called when Tor has failed to make bootstrapping progress in a way
- * that indicates a problem. <b>warn</b> gives a human-readable hint
- * as to why, and <b>reason</b> provides a controller-facing short
- * tag. <b>conn</b> is the connection that caused this problem and
- * can be NULL if a connection cannot be easily identified.
- */
-void
-control_event_bootstrap_problem(const char *warn, const char *reason,
- const connection_t *conn, int dowarn)
-{
- int status = bootstrap_percent;
- const char *tag = "", *summary = "";
- char buf[BOOTSTRAP_MSG_LEN];
- const char *recommendation = "ignore";
- int severity;
- char *or_id = NULL, *hostaddr = NULL;
- or_connection_t *or_conn = NULL;
-
- /* bootstrap_percent must not be in "undefined" state here. */
- tor_assert(status >= 0);
-
- if (bootstrap_percent == 100)
- return; /* already bootstrapped; nothing to be done here. */
-
- bootstrap_problems++;
-
- if (bootstrap_problems >= BOOTSTRAP_PROBLEM_THRESHOLD)
- dowarn = 1;
-
- /* Don't warn about our bootstrapping status if we are hibernating or
- * shutting down. */
- if (we_are_hibernating())
- dowarn = 0;
-
- tor_assert(bootstrap_status_to_string(bootstrap_phase, &tag, &summary) == 0);
-
- severity = dowarn ? LOG_WARN : LOG_INFO;
-
- if (dowarn)
- recommendation = "warn";
-
- if (conn && conn->type == CONN_TYPE_OR) {
- /* XXX TO_OR_CONN can't deal with const */
- or_conn = TO_OR_CONN((connection_t *)conn);
- or_id = tor_strdup(hex_str(or_conn->identity_digest, DIGEST_LEN));
- } else {
- or_id = tor_strdup("?");
- }
-
- if (conn)
- tor_asprintf(&hostaddr, "%s:%d", conn->address, (int)conn->port);
- else
- hostaddr = tor_strdup("?");
-
- log_fn(severity,
- LD_CONTROL, "Problem bootstrapping. Stuck at %d%%: %s. (%s; %s; "
- "count %d; recommendation %s; host %s at %s)",
- status, summary, warn, reason,
- bootstrap_problems, recommendation,
- or_id, hostaddr);
-
- connection_or_report_broken_states(severity, LD_HANDSHAKE);
-
- tor_snprintf(buf, sizeof(buf),
- "BOOTSTRAP PROGRESS=%d TAG=%s SUMMARY=\"%s\" WARNING=\"%s\" REASON=%s "
- "COUNT=%d RECOMMENDATION=%s HOSTID=\"%s\" HOSTADDR=\"%s\"",
- bootstrap_percent, tag, summary, warn, reason, bootstrap_problems,
- recommendation,
- or_id, hostaddr);
-
- tor_snprintf(last_sent_bootstrap_message,
- sizeof(last_sent_bootstrap_message),
- "WARN %s", buf);
- control_event_client_status(LOG_WARN, "%s", buf);
-
- tor_free(hostaddr);
- tor_free(or_id);
-}
-
-/** Called when Tor has failed to make bootstrapping progress in a way
- * that indicates a problem. <b>warn</b> gives a hint as to why, and
- * <b>reason</b> provides an "or_conn_end_reason" tag. <b>or_conn</b>
- * is the connection that caused this problem.
- */
-MOCK_IMPL(void,
-control_event_bootstrap_prob_or, (const char *warn, int reason,
- or_connection_t *or_conn))
-{
- int dowarn = 0;
-
- if (or_conn->have_noted_bootstrap_problem)
- return;
-
- or_conn->have_noted_bootstrap_problem = 1;
-
- if (reason == END_OR_CONN_REASON_NO_ROUTE)
- dowarn = 1;
-
- /* If we are using bridges and all our OR connections are now
- closed, it means that we totally failed to connect to our
- bridges. Throw a warning. */
- if (get_options()->UseBridges && !any_other_active_or_conns(or_conn))
- dowarn = 1;
-
- control_event_bootstrap_problem(warn,
- orconn_end_reason_to_control_string(reason),
- TO_CONN(or_conn), dowarn);
-}
-
/** We just generated a new summary of which countries we've seen clients
* from recently. Send a copy to the controller in case it wants to
* display it for the user. */
@@ -7886,17 +7524,10 @@ control_free_all(void)
mainloop_event_free(flush_queued_events_event);
flush_queued_events_event = NULL;
}
- bootstrap_percent = BOOTSTRAP_STATUS_UNDEF;
- bootstrap_phase = BOOTSTRAP_STATUS_UNDEF;
- notice_bootstrap_percent = 0;
- bootstrap_problems = 0;
- bootstrap_first_orconn = 0;
- bootstrap_dir_progress = BOOTSTRAP_STATUS_UNDEF;
- bootstrap_dir_phase = BOOTSTRAP_STATUS_UNDEF;
+ control_event_bootstrap_reset();
authentication_cookie_is_set = 0;
global_event_mask = 0;
disable_log_messages = 0;
- memset(last_sent_bootstrap_message, 0, sizeof(last_sent_bootstrap_message));
}
#ifdef TOR_UNIT_TESTS
diff --git a/src/feature/control/control.h b/src/feature/control/control.h
index cd5402d455..4ad245e8e5 100644
--- a/src/feature/control/control.h
+++ b/src/feature/control/control.h
@@ -200,6 +200,8 @@ void control_event_boot_dir(bootstrap_status_t status, int progress);
void control_event_boot_first_orconn(void);
void control_event_bootstrap_problem(const char *warn, const char *reason,
const connection_t *conn, int dowarn);
+char *control_event_boot_last_msg(void);
+void control_event_bootstrap_reset(void);
void control_event_clients_seen(const char *controller_str);
void control_event_transport_launched(const char *mode,
diff --git a/src/feature/control/control_bootstrap.c b/src/feature/control/control_bootstrap.c
new file mode 100644
index 0000000000..7299757f91
--- /dev/null
+++ b/src/feature/control/control_bootstrap.c
@@ -0,0 +1,358 @@
+/* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
+ * Copyright (c) 2007-2018, The Tor Project, Inc. */
+/* See LICENSE for licensing information */
+
+/**
+ * \file control_bootstrap.c
+ * \brief Provide bootstrap progress events for the control port.
+ */
+#include "core/or/or.h"
+
+#include "app/config/config.h"
+#include "core/mainloop/connection.h"
+#include "core/or/connection_or.h"
+#include "core/or/connection_st.h"
+#include "core/or/or_connection_st.h"
+#include "core/or/reasons.h"
+#include "feature/control/control.h"
+#include "feature/hibernate/hibernate.h"
+#include "lib/malloc/malloc.h"
+
+/** A sufficiently large size to record the last bootstrap phase string. */
+#define BOOTSTRAP_MSG_LEN 1024
+
+/** What was the last bootstrap phase message we sent? We keep track
+ * of this so we can respond to getinfo status/bootstrap-phase queries. */
+static char last_sent_bootstrap_message[BOOTSTRAP_MSG_LEN];
+
+/** Table to convert bootstrap statuses to strings. */
+static const struct {
+ bootstrap_status_t status;
+ const char *tag;
+ const char *summary;
+} boot_to_str_tab[] = {
+ { BOOTSTRAP_STATUS_UNDEF, "undef", "Undefined" },
+ { BOOTSTRAP_STATUS_STARTING, "starting", "Starting" },
+ { BOOTSTRAP_STATUS_CONN_DIR, "conn_dir", "Connecting to directory server" },
+ { BOOTSTRAP_STATUS_HANDSHAKE, "status_handshake", "Finishing handshake" },
+ { BOOTSTRAP_STATUS_HANDSHAKE_DIR, "handshake_dir",
+ "Finishing handshake with directory server" },
+ { BOOTSTRAP_STATUS_ONEHOP_CREATE, "onehop_create",
+ "Establishing an encrypted directory connection" },
+ { BOOTSTRAP_STATUS_REQUESTING_STATUS, "requesting_status",
+ "Asking for networkstatus consensus" },
+ { BOOTSTRAP_STATUS_LOADING_STATUS, "loading_status",
+ "Loading networkstatus consensus" },
+ { BOOTSTRAP_STATUS_LOADING_KEYS, "loading_keys",
+ "Loading authority key certs" },
+ { BOOTSTRAP_STATUS_REQUESTING_DESCRIPTORS, "requesting_descriptors",
+ "Asking for relay descriptors" },
+ { BOOTSTRAP_STATUS_LOADING_DESCRIPTORS, "loading_descriptors",
+ "Loading relay descriptors" },
+ { BOOTSTRAP_STATUS_CONN_OR, "conn_or", "Connecting to the Tor network" },
+ { BOOTSTRAP_STATUS_HANDSHAKE_OR, "handshake_or",
+ "Finishing handshake with first hop" },
+ { BOOTSTRAP_STATUS_CIRCUIT_CREATE, "circuit_create",
+ "Establishing a Tor circuit" },
+ { BOOTSTRAP_STATUS_DONE, "done", "Done" },
+};
+#define N_BOOT_TO_STR (sizeof(boot_to_str_tab)/sizeof(boot_to_str_tab[0]))
+
+/** Convert the name of a bootstrapping phase <b>s</b> into strings
+ * <b>tag</b> and <b>summary</b> suitable for display by the controller. */
+static int
+bootstrap_status_to_string(bootstrap_status_t s, const char **tag,
+ const char **summary)
+{
+ for (size_t i = 0; i < N_BOOT_TO_STR; i++) {
+ if (s == boot_to_str_tab[i].status) {
+ *tag = boot_to_str_tab[i].tag;
+ *summary = boot_to_str_tab[i].summary;
+ return 0;
+ }
+ }
+
+ *tag = *summary = "unknown";
+ return -1;
+}
+
+/** What percentage through the bootstrap process are we? We remember
+ * this so we can avoid sending redundant bootstrap status events, and
+ * so we can guess context for the bootstrap messages which are
+ * ambiguous. It starts at 'undef', but gets set to 'starting' while
+ * Tor initializes. */
+static int bootstrap_percent = BOOTSTRAP_STATUS_UNDEF;
+
+/** Like bootstrap_percent, but only takes on the enumerated values in
+ * bootstrap_status_t.
+ */
+static int bootstrap_phase = BOOTSTRAP_STATUS_UNDEF;
+
+/** As bootstrap_percent, but holds the bootstrapping level at which we last
+ * logged a NOTICE-level message. We use this, plus BOOTSTRAP_PCT_INCREMENT,
+ * to avoid flooding the log with a new message every time we get a few more
+ * microdescriptors */
+static int notice_bootstrap_percent = 0;
+
+/** How many problems have we had getting to the next bootstrapping phase?
+ * These include failure to establish a connection to a Tor relay,
+ * failures to finish the TLS handshake, failures to validate the
+ * consensus document, etc. */
+static int bootstrap_problems = 0;
+
+/** We only tell the controller once we've hit a threshold of problems
+ * for the current phase. */
+#define BOOTSTRAP_PROBLEM_THRESHOLD 10
+
+/** When our bootstrapping progress level changes, but our bootstrapping
+ * status has not advanced, we only log at NOTICE when we have made at least
+ * this much progress.
+ */
+#define BOOTSTRAP_PCT_INCREMENT 5
+
+/** Do the actual logging and notifications for
+ * control_event_bootstrap(). Doesn't change any state beyond that.
+ */
+static void
+control_event_bootstrap_core(int loglevel, bootstrap_status_t status,
+ int progress)
+{
+ char buf[BOOTSTRAP_MSG_LEN];
+ const char *tag, *summary;
+
+ bootstrap_status_to_string(status, &tag, &summary);
+ /* Locally reset status if there's incremental progress */
+ if (progress)
+ status = progress;
+
+ tor_log(loglevel, LD_CONTROL,
+ "Bootstrapped %d%%: %s", status, summary);
+ tor_snprintf(buf, sizeof(buf),
+ "BOOTSTRAP PROGRESS=%d TAG=%s SUMMARY=\"%s\"",
+ status, tag, summary);
+ tor_snprintf(last_sent_bootstrap_message,
+ sizeof(last_sent_bootstrap_message),
+ "NOTICE %s", buf);
+ control_event_client_status(LOG_NOTICE, "%s", buf);
+}
+
+/** Called when Tor has made progress at bootstrapping its directory
+ * information and initial circuits.
+ *
+ * <b>status</b> is the new status, that is, what task we will be doing
+ * next. <b>progress</b> is zero if we just started this task, else it
+ * represents progress on the task.
+ */
+void
+control_event_bootstrap(bootstrap_status_t status, int progress)
+{
+ int loglevel = LOG_NOTICE;
+
+ if (bootstrap_percent == BOOTSTRAP_STATUS_DONE)
+ return; /* already bootstrapped; nothing to be done here. */
+
+ /* special case for handshaking status, since our TLS handshaking code
+ * can't distinguish what the connection is going to be for. */
+ if (status == BOOTSTRAP_STATUS_HANDSHAKE) {
+ if (bootstrap_percent < BOOTSTRAP_STATUS_CONN_OR) {
+ status = BOOTSTRAP_STATUS_HANDSHAKE_DIR;
+ } else {
+ status = BOOTSTRAP_STATUS_HANDSHAKE_OR;
+ }
+ }
+
+ if (status <= bootstrap_percent) {
+ /* If there's no new progress, return early. */
+ if (!progress || progress <= bootstrap_percent)
+ return;
+ /* Log at INFO if not enough progress happened. */
+ if (progress < notice_bootstrap_percent + BOOTSTRAP_PCT_INCREMENT)
+ loglevel = LOG_INFO;
+ }
+
+ control_event_bootstrap_core(loglevel, status, progress);
+
+ if (status > bootstrap_percent) {
+ bootstrap_phase = status; /* new milestone reached */
+ bootstrap_percent = status;
+ }
+ if (progress > bootstrap_percent) {
+ /* incremental progress within a milestone */
+ bootstrap_percent = progress;
+ bootstrap_problems = 0; /* Progress! Reset our problem counter. */
+ }
+ if (loglevel == LOG_NOTICE &&
+ bootstrap_percent > notice_bootstrap_percent) {
+ /* Remember that we gave a notice at this level. */
+ notice_bootstrap_percent = bootstrap_percent;
+ }
+}
+
+/** Flag whether we've opened an OR_CONN yet */
+static int bootstrap_first_orconn = 0;
+
+/** Like bootstrap_phase, but for (possibly deferred) directory progress */
+static int bootstrap_dir_phase = BOOTSTRAP_STATUS_UNDEF;
+
+/** Like bootstrap_problems, but for (possibly deferred) directory progress */
+static int bootstrap_dir_progress = BOOTSTRAP_STATUS_UNDEF;
+
+/** Defer directory info bootstrap events until we have successfully
+ * completed our first connection to a router. */
+void
+control_event_boot_dir(bootstrap_status_t status, int progress)
+{
+ if (status > bootstrap_dir_progress) {
+ bootstrap_dir_progress = status;
+ bootstrap_dir_phase = status;
+ }
+ if (progress && progress >= bootstrap_dir_progress) {
+ bootstrap_dir_progress = progress;
+ }
+
+ /* Don't report unless we have successfully opened at least one OR_CONN */
+ if (!bootstrap_first_orconn)
+ return;
+
+ control_event_bootstrap(status, progress);
+}
+
+/** Set a flag to allow reporting of directory bootstrap progress.
+ * (Code that reports completion of an OR_CONN calls this.) Also,
+ * report directory progress so far. */
+void
+control_event_boot_first_orconn(void)
+{
+ bootstrap_first_orconn = 1;
+ control_event_bootstrap(bootstrap_dir_phase, bootstrap_dir_progress);
+}
+
+/** Called when Tor has failed to make bootstrapping progress in a way
+ * that indicates a problem. <b>warn</b> gives a human-readable hint
+ * as to why, and <b>reason</b> provides a controller-facing short
+ * tag. <b>conn</b> is the connection that caused this problem and
+ * can be NULL if a connection cannot be easily identified.
+ */
+void
+control_event_bootstrap_problem(const char *warn, const char *reason,
+ const connection_t *conn, int dowarn)
+{
+ int status = bootstrap_percent;
+ const char *tag = "", *summary = "";
+ char buf[BOOTSTRAP_MSG_LEN];
+ const char *recommendation = "ignore";
+ int severity;
+ char *or_id = NULL, *hostaddr = NULL;
+ or_connection_t *or_conn = NULL;
+
+ /* bootstrap_percent must not be in "undefined" state here. */
+ tor_assert(status >= 0);
+
+ if (bootstrap_percent == 100)
+ return; /* already bootstrapped; nothing to be done here. */
+
+ bootstrap_problems++;
+
+ if (bootstrap_problems >= BOOTSTRAP_PROBLEM_THRESHOLD)
+ dowarn = 1;
+
+ /* Don't warn about our bootstrapping status if we are hibernating or
+ * shutting down. */
+ if (we_are_hibernating())
+ dowarn = 0;
+
+ tor_assert(bootstrap_status_to_string(bootstrap_phase, &tag, &summary) == 0);
+
+ severity = dowarn ? LOG_WARN : LOG_INFO;
+
+ if (dowarn)
+ recommendation = "warn";
+
+ if (conn && conn->type == CONN_TYPE_OR) {
+ /* XXX TO_OR_CONN can't deal with const */
+ or_conn = TO_OR_CONN((connection_t *)conn);
+ or_id = tor_strdup(hex_str(or_conn->identity_digest, DIGEST_LEN));
+ } else {
+ or_id = tor_strdup("?");
+ }
+
+ if (conn)
+ tor_asprintf(&hostaddr, "%s:%d", conn->address, (int)conn->port);
+ else
+ hostaddr = tor_strdup("?");
+
+ log_fn(severity,
+ LD_CONTROL, "Problem bootstrapping. Stuck at %d%%: %s. (%s; %s; "
+ "count %d; recommendation %s; host %s at %s)",
+ status, summary, warn, reason,
+ bootstrap_problems, recommendation,
+ or_id, hostaddr);
+
+ connection_or_report_broken_states(severity, LD_HANDSHAKE);
+
+ tor_snprintf(buf, sizeof(buf),
+ "BOOTSTRAP PROGRESS=%d TAG=%s SUMMARY=\"%s\" WARNING=\"%s\" REASON=%s "
+ "COUNT=%d RECOMMENDATION=%s HOSTID=\"%s\" HOSTADDR=\"%s\"",
+ bootstrap_percent, tag, summary, warn, reason, bootstrap_problems,
+ recommendation,
+ or_id, hostaddr);
+
+ tor_snprintf(last_sent_bootstrap_message,
+ sizeof(last_sent_bootstrap_message),
+ "WARN %s", buf);
+ control_event_client_status(LOG_WARN, "%s", buf);
+
+ tor_free(hostaddr);
+ tor_free(or_id);
+}
+
+/** Called when Tor has failed to make bootstrapping progress in a way
+ * that indicates a problem. <b>warn</b> gives a hint as to why, and
+ * <b>reason</b> provides an "or_conn_end_reason" tag. <b>or_conn</b>
+ * is the connection that caused this problem.
+ */
+MOCK_IMPL(void,
+control_event_bootstrap_prob_or, (const char *warn, int reason,
+ or_connection_t *or_conn))
+{
+ int dowarn = 0;
+
+ if (or_conn->have_noted_bootstrap_problem)
+ return;
+
+ or_conn->have_noted_bootstrap_problem = 1;
+
+ if (reason == END_OR_CONN_REASON_NO_ROUTE)
+ dowarn = 1;
+
+ /* If we are using bridges and all our OR connections are now
+ closed, it means that we totally failed to connect to our
+ bridges. Throw a warning. */
+ if (get_options()->UseBridges && !any_other_active_or_conns(or_conn))
+ dowarn = 1;
+
+ control_event_bootstrap_problem(warn,
+ orconn_end_reason_to_control_string(reason),
+ TO_CONN(or_conn), dowarn);
+}
+
+/** Return a copy of the last sent bootstrap message. */
+char *
+control_event_boot_last_msg(void)
+{
+ return tor_strdup(last_sent_bootstrap_message);
+}
+
+/** Reset bootstrap tracking state. */
+void
+control_event_bootstrap_reset(void)
+{
+ bootstrap_percent = BOOTSTRAP_STATUS_UNDEF;
+ bootstrap_phase = BOOTSTRAP_STATUS_UNDEF;
+ notice_bootstrap_percent = 0;
+ bootstrap_problems = 0;
+ bootstrap_first_orconn = 0;
+ bootstrap_dir_progress = BOOTSTRAP_STATUS_UNDEF;
+ bootstrap_dir_phase = BOOTSTRAP_STATUS_UNDEF;
+ memset(last_sent_bootstrap_message, 0, sizeof(last_sent_bootstrap_message));
+}
diff --git a/src/feature/nodelist/networkstatus.c b/src/feature/nodelist/networkstatus.c
index ed01576242..65ea3cc491 100644
--- a/src/feature/nodelist/networkstatus.c
+++ b/src/feature/nodelist/networkstatus.c
@@ -2681,6 +2681,9 @@ networkstatus_check_required_protocols(const networkstatus_t *ns,
const char *required, *recommended;
char *missing = NULL;
+ const bool consensus_postdates_this_release =
+ ns->valid_after >= tor_get_approx_release_date();
+
tor_assert(warning_out);
if (client_mode) {
@@ -2698,7 +2701,7 @@ networkstatus_check_required_protocols(const networkstatus_t *ns,
"%s on the Tor network. The missing protocols are: %s",
func, missing);
tor_free(missing);
- return 1;
+ return consensus_postdates_this_release ? 1 : 0;
}
if (! protover_all_supported(recommended, &missing)) {