diff -Nur tor-0.3.5.10/ChangeLog tor-0.3.5.12/ChangeLog
--- tor-0.3.5.10/ChangeLog	2020-03-18 14:02:16.000000000 +0100
+++ tor-0.3.5.12/ChangeLog	2020-11-09 23:03:48.000000000 +0100
@@ -1,3 +1,205 @@
+Changes in version 0.3.5.12 - 2020-11-12
+  Tor 0.4.3.7 backports several bugfixes from later releases. It
+  includes a fix for TROVE-2020-005, a security issue that could be
+  used, under certain cases, by an adversary to observe traffic patterns
+  on a limited number of circuits intended for a different relay.
+
+  o Major features (fallback directory list, backport form 0.4.4.3-alpha):
+    - Replace the 148 fallback directories originally included in Tor
+      0.4.1.4-rc (of which around 105 are still functional) with a list
+      of 144 fallbacks generated in July 2020. Closes ticket 40061.
+
+  o Major bugfixes (security, backport from 0.4.5.1-alpha):
+    - When completing a channel, relays now check more thoroughly to
+      make sure that it matches any pending circuits before attaching
+      those circuits. Previously, address correctness and Ed25519
+      identities were not checked in this case, but only when extending
+      circuits on an existing channel. Fixes bug 40080; bugfix on
+      0.2.7.2-alpha. Resolves TROVE-2020-005.
+
+  o Major bugfixes (NSS, backport from 0.4.4.3-alpha):
+    - When running with NSS enabled, make sure that NSS knows to expect
+      nonblocking sockets. Previously, we set our TCP sockets as
+      nonblocking, but did not tell NSS, which in turn could lead to
+      unexpected blocking behavior. Fixes bug 40035; bugfix
+      on 0.3.5.1-alpha.
+
+  o Minor features (security, backport from 0.4.4.4-rc):
+    - Channels using obsolete versions of the Tor link protocol are no
+      longer allowed to circumvent address-canonicity checks. (This is
+      only a minor issue, since such channels have no way to set ed25519
+      keys, and therefore should always be rejected for circuits that
+      specify ed25519 identities.) Closes ticket 40081.
+
+  o Minor features (debugging, directory system):
+    - Don't crash when we find a non-guard with a guard-fraction value
+      set. Instead, log a bug warning, in an attempt to figure out how
+      this happened. Diagnostic for ticket 32868.
+
+  o Minor features (subprotocol versions, backport from 0.4.5.1-alpha):
+    - Tor no longer allows subprotocol versions larger than 63.
+      Previously version numbers up to UINT32_MAX were allowed, which
+      significantly complicated our code. Implements proposal 318;
+      closes ticket 40133.
+
+  o Minor features (tests, backport from 0.4.4.5):
+    - Our "make check" target now runs the unit tests in 8 parallel
+      chunks. Doing this speeds up hardened CI builds by more than a
+      factor of two. Closes ticket 40098.
+
+  o Minor features (tests, v2 onion services, backport from 0.4.5.1-alpha):
+    - Fix a rendezvous cache unit test that was triggering an underflow
+      on the global rend cache allocation. Fixes bug 40125; bugfix
+      on 0.2.8.1-alpha.
+    - Fix another rendezvous cache unit test that was triggering an
+      underflow on the global rend cache allocation. Fixes bug 40126;
+      bugfix on 0.2.8.1-alpha.
+
+  o Minor bugfixes (correctness, buffers, backport from 0.4.4.4-rc):
+    - Fix a correctness bug that could cause an assertion failure if we
+      ever tried using the buf_move_all() function with an empty input
+      buffer. As far as we know, no released versions of Tor do this.
+      Fixes bug 40076; bugfix on 0.3.3.1-alpha.
+
+  o Minor bugfixes (logging, backport from 0.4.5.1-alpha):
+    - Remove a debug logging statement that uselessly spammed the logs.
+      Fixes bug 40135; bugfix on 0.3.5.0-alpha.
+
+  o Minor bugfixes (rate limiting, bridges, pluggable transports, backport from 0.4.4.4-rc):
+    - On a bridge, treat all connections from an ExtORPort as remote by
+      default for the purposes of rate-limiting. Previously, bridges
+      would treat the connection as local unless they explicitly
+      received a "USERADDR" command. ExtORPort connections still count
+      as local if there is a USERADDR command with an explicit local
+      address. Fixes bug 33747; bugfix on 0.2.5.1-alpha.
+
+  o Minor bugfixes (relay configuration, crash, backport from 0.4.5.1-alpha):
+    - Avoid a fatal assert() when failing to create a listener
+      connection for an address that was in use. Fixes bug 40073; bugfix
+      on 0.3.5.1-alpha.
+
+  o Minor bugfixes (relay, usability, backport from 0.4.4.3-alpha):
+    - Adjust the rules for when to warn about having too many
+      connections to other relays. Previously we'd tolerate up to 1.5
+      connections per relay on average. Now we tolerate more connections
+      for directory authorities, and raise the number of total
+      connections we need to see before we warn. Fixes bug 33880; bugfix
+      on 0.3.1.1-alpha.
+
+  o Minor bugfixes (relays, backport from 0.4.4.1-alpha):
+    - Stop advertising incorrect IPv6 ORPorts in relay and bridge
+      descriptors, when the IPv6 port was configured as "auto". Fixes
+      bug 32588; bugfix on 0.2.3.9-alpha.
+
+  o Minor bugfixes (tests, 0.4.4.5):
+    - Fix the behavior of the rend_cache/clean_v2_descs_as_dir when run
+      on its own. Previously, it would exit with an error. Fixes bug
+      40099; bugfix on 0.2.8.1-alpha.
+
+  o Minor bugfixes (windows, backport from 0.4.4.4-rc):
+    - Fix a bug that prevented Tor from starting if its log file grew
+      above 2GB. Fixes bug 31036; bugfix on 0.2.1.8-alpha.
+
+  o Deprecated features (onion service v2, backport form 0.4.4.2-alpha):
+    - Add a deprecation warning for version 2 onion services. Closes
+      ticket 40003.
+
+
+Changes in version 0.3.5.11 - 2020-07-09
+  Tor 0.3.5.11 backports fixes from later tor releases, including several
+  usability, portability, and reliability fixes.
+
+  This release also fixes TROVE-2020-001, a medium-severity denial of
+  service vulnerability affecting all versions of Tor when compiled with
+  the NSS encryption library. (This is not the default configuration.)
+  Using this vulnerability, an attacker could cause an affected Tor
+  instance to crash remotely. This issue is also tracked as CVE-2020-
+  15572. Anybody running a version of Tor built with the NSS library
+  should upgrade to 0.3.5.11, 0.4.2.8, 0.4.3.6, or 0.4.4.2-alpha
+  or later.
+
+  o Major bugfixes (NSS, security, backport from 0.4.4.2-alpha):
+    - Fix a crash due to an out-of-bound memory access when Tor is
+      compiled with NSS support. Fixes bug 33119; bugfix on
+      0.3.5.1-alpha. This issue is also tracked as TROVE-2020-001
+      and CVE-2020-15572.
+
+  o Major bugfixes (DoS defenses, bridges, pluggable transport, backport from 0.4.3.4-rc):
+    - Fix a bug that was preventing DoS defenses from running on bridges
+      with a pluggable transport. Previously, the DoS subsystem was not
+      given the transport name of the client connection, thus failed to
+      find the GeoIP cache entry for that client address. Fixes bug
+      33491; bugfix on 0.3.3.2-alpha.
+
+  o Minor features (testing, backport from 0.4.3.4-rc):
+    - The unit tests now support a "TOR_SKIP_TESTCASES" environment
+      variable to specify a list of space-separated test cases that
+      should not be executed. We will use this to disable certain tests
+      that are failing on Appveyor because of mismatched OpenSSL
+      libraries. Part of ticket 33643.
+
+  o Minor bugfix (CI, Windows, backport from 0.4.4.2-alpha):
+    - Use the correct 64-bit printf format when compiling with MINGW on
+      Appveyor. Fixes bug 40026; bugfix on 0.3.5.5-alpha.
+
+  o Minor bugfix (relay, configuration, backport from 0.4.3.3-alpha):
+    - Warn if the ContactInfo field is not set, and tell the relay
+      operator that not having a ContactInfo field set might cause their
+      relay to get rejected in the future. Fixes bug 33361; bugfix
+      on 0.1.1.10-alpha.
+
+  o Minor bugfixes (client performance, backport from 0.4.4.1-alpha):
+    - Resume use of preemptively-built circuits when UseEntryGuards is set
+      to 0. We accidentally disabled this feature with that config
+      setting, leading to slower load times. Fixes bug 34303; bugfix
+      on 0.3.3.2-alpha.
+
+  o Minor bugfixes (compiler compatibility, backport from 0.4.3.5):
+    - Avoid compiler warnings from Clang 10 related to the use of GCC-
+      style "/* falls through */" comments. Both Clang and GCC allow
+      __attribute__((fallthrough)) instead, so that's what we're using
+      now. Fixes bug 34078; bugfix on 0.3.1.3-alpha.
+
+  o Minor bugfixes (compiler warnings, backport from 0.4.4.2-alpha):
+    - Fix a compiler warning on platforms with 32-bit time_t values.
+      Fixes bug 40028; bugfix on 0.3.2.8-rc.
+
+  o Minor bugfixes (embedded Tor, backport from 0.4.3.1-alpha):
+    - When starting Tor any time after the first time in a process,
+      register the thread in which it is running as the main thread.
+      Previously, we only did this on Windows, which could lead to bugs
+      like 23081 on non-Windows platforms. Fixes bug 32884; bugfix
+      on 0.3.3.1-alpha.
+
+  o Minor bugfixes (key portability, backport from 0.4.3.4-rc):
+    - When reading PEM-encoded key data, tolerate CRLF line-endings even
+      if we are not running on Windows. Previously, non-Windows hosts
+      would reject these line-endings in certain positions, making
+      certain key files hard to move from one host to another. Fixes bug
+      33032; bugfix on 0.3.5.1-alpha.
+
+  o Minor bugfixes (logging, backport from 0.4.4.2-alpha):
+    - Downgrade a noisy log message that could occur naturally when
+      receiving an extrainfo document that we no longer want. Fixes bug
+      16016; bugfix on 0.2.6.3-alpha.
+
+  o Minor bugfixes (onion service v3, client, backport from 0.4.3.3-alpha):
+    - Remove a BUG() warning that would cause a stack trace if an onion
+      service descriptor was freed while we were waiting for a
+      rendezvous circuit to complete. Fixes bug 28992; bugfix
+      on 0.3.2.1-alpha.
+
+  o Testing (CI, backport from 0.4.3.4-rc):
+    - In our Appveyor Windows CI, copy required DLLs to test and app
+      directories, before running tor's tests. This ensures that tor.exe
+      and test*.exe use the correct version of each DLL. This fix is not
+      required, but we hope it will avoid DLL search issues in future.
+      Fixes bug 33673; bugfix on 0.3.4.2-alpha.
+    - On Appveyor, skip the crypto/openssl_version test, which is
+      failing because of a mismatched library installation. Fix
+      for 33643.
+
+
 Changes in version 0.3.5.10 - 2020-03-18
   Tor 0.3.5.10 backports many fixes from later Tor releases, including a
   fix for TROVE-2020-002, a major denial-of-service vulnerability that
diff -Nur tor-0.3.5.10/Makefile.am tor-0.3.5.12/Makefile.am
--- tor-0.3.5.10/Makefile.am	2019-10-11 23:48:21.000000000 +0200
+++ tor-0.3.5.12/Makefile.am	2020-08-12 18:29:17.000000000 +0200
@@ -149,6 +149,8 @@
 include doc/include.am
 include contrib/include.am
 
+manpages: $(nodist_man1_MANS)
+
 EXTRA_DIST+= \
 	ChangeLog					\
 	CONTRIBUTING					\
diff -Nur tor-0.3.5.10/Makefile.in tor-0.3.5.12/Makefile.in
--- tor-0.3.5.10/Makefile.in	2020-03-17 20:37:58.000000000 +0100
+++ tor-0.3.5.12/Makefile.in	2020-11-09 23:16:27.000000000 +0100
@@ -1,7 +1,7 @@
-# Makefile.in generated by automake 1.16.1 from Makefile.am.
+# Makefile.in generated by automake 1.16.2 from Makefile.am.
 # @configure_input@
 
-# Copyright (C) 1994-2018 Free Software Foundation, Inc.
+# Copyright (C) 1994-2020 Free Software Foundation, Inc.
 
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -114,8 +114,7 @@
 bin_PROGRAMS = src/app/tor$(EXEEXT) src/tools/tor-resolve$(EXEEXT) \
 	src/tools/tor-print-ed-signing-cert$(EXEEXT) $(am__EXEEXT_1)
 EXTRA_PROGRAMS =
-TESTS = src/test/test$(EXEEXT) src/test/test-slow$(EXEEXT) \
-	src/test/test-memwipe$(EXEEXT) \
+TESTS = src/test/test-slow$(EXEEXT) src/test/test-memwipe$(EXEEXT) \
 	src/test/test_workqueue$(EXEEXT) src/test/test_keygen.sh \
 	src/test/test_key_expiration.sh src/test/test-timers$(EXEEXT) \
 	$(TESTSCRIPTS)
@@ -3687,8 +3686,8 @@
 	src/test/test_hs_descriptor.inc src/test/vote_descriptors.inc \
 	src/test/fuzz/fuzzing.h
 HEADERS = $(noinst_HEADERS)
-am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) \
-	$(LISP)orconfig.h.in
+am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) \
+	orconfig.h.in
 # Read a list of newline-separated strings from the standard input,
 # and print each of them once, without duplicates.  Input order is
 # *not* preserved.
@@ -4153,8 +4152,6 @@
 	src/trunnel/libor-trunnel.a $(am__append_46) \
 	src/core/libtor-app.a $(am__append_47) $(am__append_62) \
 	$(OSS_FUZZ_FUZZERS)
-
-# All libraries used to link tor-cov
 EXTRA_DIST = src/ext/README src/ext/timeouts/bench/bench-add.lua \
 	src/ext/timeouts/bench/bench-aux.lua \
 	src/ext/timeouts/bench/bench.c \
@@ -4205,12 +4202,17 @@
 	src/test/test_workqueue_efd.sh src/test/test_workqueue_efd2.sh \
 	src/test/test_workqueue_pipe.sh \
 	src/test/test_workqueue_pipe2.sh \
-	src/test/test_workqueue_socketpair.sh src/win32/orconfig.h \
-	src/config/geoip src/config/geoip6 src/config/torrc.minimal.in \
-	src/config/torrc.sample.in src/config/README \
-	doc/asciidoc-helper.sh $(html_in) $(man_in) $(txt_in) \
-	doc/state-contents.txt doc/torrc_format.txt doc/TUNING \
-	doc/HACKING/README.1st.md doc/HACKING/CodingStandards.md \
+	src/test/test_workqueue_socketpair.sh \
+	src/test/unittest_part1.sh src/test/unittest_part2.sh \
+	src/test/unittest_part3.sh src/test/unittest_part4.sh \
+	src/test/unittest_part5.sh src/test/unittest_part6.sh \
+	src/test/unittest_part7.sh src/test/unittest_part8.sh \
+	src/win32/orconfig.h src/config/geoip src/config/geoip6 \
+	src/config/torrc.minimal.in src/config/torrc.sample.in \
+	src/config/README doc/asciidoc-helper.sh $(html_in) $(man_in) \
+	$(txt_in) doc/state-contents.txt doc/torrc_format.txt \
+	doc/TUNING doc/HACKING/README.1st.md \
+	doc/HACKING/CodingStandards.md \
 	doc/HACKING/CodingStandardsRust.md \
 	doc/HACKING/CodeStructure.md doc/HACKING/Fuzzing.md \
 	doc/HACKING/GettingStarted.md \
@@ -5223,7 +5225,11 @@
 	src/test/test_workqueue_pipe.sh \
 	src/test/test_workqueue_pipe2.sh \
 	src/test/test_workqueue_socketpair.sh \
-	src/test/test_switch_id.sh $(am__append_52) $(am__append_53)
+	src/test/test_switch_id.sh src/test/unittest_part1.sh \
+	src/test/unittest_part2.sh src/test/unittest_part3.sh \
+	src/test/unittest_part4.sh src/test/unittest_part5.sh \
+	src/test/unittest_part6.sh src/test/unittest_part7.sh \
+	src/test/unittest_part8.sh $(am__append_52) $(am__append_53)
 
 # These flavors are run using automake's test-driver and test-network.sh
 TEST_CHUTNEY_FLAVORS = basic-min bridges-min hs-v2-min hs-v3-min \
@@ -17907,13 +17913,6 @@
 	        am__force_recheck=am--force-recheck \
 	        TEST_LOGS="$$log_list"; \
 	exit $$?
-src/test/test.log: src/test/test$(EXEEXT)
-	@p='src/test/test$(EXEEXT)'; \
-	b='src/test/test'; \
-	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
-	--log-file $$b.log --trs-file $$b.trs \
-	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
-	"$$tst" $(AM_TESTS_FD_REDIRECT)
 src/test/test-slow.log: src/test/test-slow$(EXEEXT)
 	@p='src/test/test-slow$(EXEEXT)'; \
 	b='src/test/test-slow'; \
@@ -18019,6 +18018,62 @@
 	--log-file $$b.log --trs-file $$b.trs \
 	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
 	"$$tst" $(AM_TESTS_FD_REDIRECT)
+src/test/unittest_part1.sh.log: src/test/unittest_part1.sh
+	@p='src/test/unittest_part1.sh'; \
+	b='src/test/unittest_part1.sh'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+src/test/unittest_part2.sh.log: src/test/unittest_part2.sh
+	@p='src/test/unittest_part2.sh'; \
+	b='src/test/unittest_part2.sh'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+src/test/unittest_part3.sh.log: src/test/unittest_part3.sh
+	@p='src/test/unittest_part3.sh'; \
+	b='src/test/unittest_part3.sh'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+src/test/unittest_part4.sh.log: src/test/unittest_part4.sh
+	@p='src/test/unittest_part4.sh'; \
+	b='src/test/unittest_part4.sh'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+src/test/unittest_part5.sh.log: src/test/unittest_part5.sh
+	@p='src/test/unittest_part5.sh'; \
+	b='src/test/unittest_part5.sh'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+src/test/unittest_part6.sh.log: src/test/unittest_part6.sh
+	@p='src/test/unittest_part6.sh'; \
+	b='src/test/unittest_part6.sh'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+src/test/unittest_part7.sh.log: src/test/unittest_part7.sh
+	@p='src/test/unittest_part7.sh'; \
+	b='src/test/unittest_part7.sh'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
+src/test/unittest_part8.sh.log: src/test/unittest_part8.sh
+	@p='src/test/unittest_part8.sh'; \
+	b='src/test/unittest_part8.sh'; \
+	$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
+	--log-file $$b.log --trs-file $$b.trs \
+	$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
+	"$$tst" $(AM_TESTS_FD_REDIRECT)
 src/test/test_rust.sh.log: src/test/test_rust.sh
 	@p='src/test/test_rust.sh'; \
 	b='src/test/test_rust.sh'; \
@@ -18127,6 +18182,10 @@
 	tardir=$(distdir) && $(am__tar) | XZ_OPT=$${XZ_OPT--e} xz -c >$(distdir).tar.xz
 	$(am__post_remove_distdir)
 
+dist-zstd: distdir
+	tardir=$(distdir) && $(am__tar) | zstd -c $${ZSTD_CLEVEL-$${ZSTD_OPT--19}} >$(distdir).tar.zst
+	$(am__post_remove_distdir)
+
 dist-tarZ: distdir
 	@echo WARNING: "Support for distribution archives compressed with" \
 		       "legacy program 'compress' is deprecated." >&2
@@ -18169,6 +18228,8 @@
 	  eval GZIP= gzip $(GZIP_ENV) -dc $(distdir).shar.gz | unshar ;;\
 	*.zip*) \
 	  unzip $(distdir).zip ;;\
+	*.tar.zst*) \
+	  zstd -dc $(distdir).tar.zst | $(am__untar) ;;\
 	esac
 	chmod -R a-w $(distdir)
 	chmod u+w $(distdir)
@@ -20065,22 +20126,23 @@
 	clean-cscope clean-generic clean-local clean-noinstLIBRARIES \
 	clean-noinstPROGRAMS cscope cscopelist-am ctags ctags-am dist \
 	dist-all dist-bzip2 dist-gzip dist-lzip dist-shar dist-tarZ \
-	dist-xz dist-zip distcheck distclean distclean-compile \
-	distclean-generic distclean-hdr distclean-local distclean-tags \
-	distcleancheck distdir distuninstallcheck dvi dvi-am html \
-	html-am info info-am install install-am install-binPROGRAMS \
-	install-binSCRIPTS install-confDATA install-data \
-	install-data-am install-docDATA install-dvi install-dvi-am \
-	install-exec install-exec-am install-html install-html-am \
-	install-info install-info-am install-man install-man1 \
-	install-pdf install-pdf-am install-ps install-ps-am \
-	install-strip install-tordataDATA installcheck installcheck-am \
-	installdirs maintainer-clean maintainer-clean-generic \
-	mostlyclean mostlyclean-compile mostlyclean-generic \
-	mostlyclean-local pdf pdf-am ps ps-am recheck tags tags-am \
-	uninstall uninstall-am uninstall-binPROGRAMS \
-	uninstall-binSCRIPTS uninstall-confDATA uninstall-docDATA \
-	uninstall-man uninstall-man1 uninstall-tordataDATA
+	dist-xz dist-zip dist-zstd distcheck distclean \
+	distclean-compile distclean-generic distclean-hdr \
+	distclean-local distclean-tags distcleancheck distdir \
+	distuninstallcheck dvi dvi-am html html-am info info-am \
+	install install-am install-binPROGRAMS install-binSCRIPTS \
+	install-confDATA install-data install-data-am install-docDATA \
+	install-dvi install-dvi-am install-exec install-exec-am \
+	install-html install-html-am install-info install-info-am \
+	install-man install-man1 install-pdf install-pdf-am install-ps \
+	install-ps-am install-strip install-tordataDATA installcheck \
+	installcheck-am installdirs maintainer-clean \
+	maintainer-clean-generic mostlyclean mostlyclean-compile \
+	mostlyclean-generic mostlyclean-local pdf pdf-am ps ps-am \
+	recheck tags tags-am uninstall uninstall-am \
+	uninstall-binPROGRAMS uninstall-binSCRIPTS uninstall-confDATA \
+	uninstall-docDATA uninstall-man uninstall-man1 \
+	uninstall-tordataDATA
 
 .PRECIOUS: Makefile
 
@@ -20190,6 +20252,10 @@
 doc/tor-print-ed-signing-cert.1: doc/tor-print-ed-signing-cert.1.in
 doc/torify.1: doc/torify.1.in
 
+# All libraries used to link tor-cov
+
+manpages: $(nodist_man1_MANS)
+
 #install-data-local:
 #	$(INSTALL) -m 755 -d $(LOCALSTATEDIR)/lib/tor
 
diff -Nur tor-0.3.5.10/ReleaseNotes tor-0.3.5.12/ReleaseNotes
--- tor-0.3.5.10/ReleaseNotes	2020-03-18 14:02:20.000000000 +0100
+++ tor-0.3.5.12/ReleaseNotes	2020-11-12 13:34:12.000000000 +0100
@@ -2,6 +2,208 @@
 release of Tor. If you want to see more detailed descriptions of the
 changes in each development snapshot, see the ChangeLog file.
 
+Changes in version 0.3.5.12 - 2020-11-12
+  Tor 0.4.3.7 backports several bugfixes from later releases. It
+  includes a fix for TROVE-2020-005, a security issue that could be
+  used, under certain cases, by an adversary to observe traffic patterns
+  on a limited number of circuits intended for a different relay.
+
+  o Major features (fallback directory list, backport form 0.4.4.3-alpha):
+    - Replace the 148 fallback directories originally included in Tor
+      0.4.1.4-rc (of which around 105 are still functional) with a list
+      of 144 fallbacks generated in July 2020. Closes ticket 40061.
+
+  o Major bugfixes (security, backport from 0.4.5.1-alpha):
+    - When completing a channel, relays now check more thoroughly to
+      make sure that it matches any pending circuits before attaching
+      those circuits. Previously, address correctness and Ed25519
+      identities were not checked in this case, but only when extending
+      circuits on an existing channel. Fixes bug 40080; bugfix on
+      0.2.7.2-alpha. Resolves TROVE-2020-005.
+
+  o Major bugfixes (NSS, backport from 0.4.4.3-alpha):
+    - When running with NSS enabled, make sure that NSS knows to expect
+      nonblocking sockets. Previously, we set our TCP sockets as
+      nonblocking, but did not tell NSS, which in turn could lead to
+      unexpected blocking behavior. Fixes bug 40035; bugfix
+      on 0.3.5.1-alpha.
+
+  o Minor features (security, backport from 0.4.4.4-rc):
+    - Channels using obsolete versions of the Tor link protocol are no
+      longer allowed to circumvent address-canonicity checks. (This is
+      only a minor issue, since such channels have no way to set ed25519
+      keys, and therefore should always be rejected for circuits that
+      specify ed25519 identities.) Closes ticket 40081.
+
+  o Minor features (debugging, directory system):
+    - Don't crash when we find a non-guard with a guard-fraction value
+      set. Instead, log a bug warning, in an attempt to figure out how
+      this happened. Diagnostic for ticket 32868.
+
+  o Minor features (subprotocol versions, backport from 0.4.5.1-alpha):
+    - Tor no longer allows subprotocol versions larger than 63.
+      Previously version numbers up to UINT32_MAX were allowed, which
+      significantly complicated our code. Implements proposal 318;
+      closes ticket 40133.
+
+  o Minor features (tests, backport from 0.4.4.5):
+    - Our "make check" target now runs the unit tests in 8 parallel
+      chunks. Doing this speeds up hardened CI builds by more than a
+      factor of two. Closes ticket 40098.
+
+  o Minor features (tests, v2 onion services, backport from 0.4.5.1-alpha):
+    - Fix a rendezvous cache unit test that was triggering an underflow
+      on the global rend cache allocation. Fixes bug 40125; bugfix
+      on 0.2.8.1-alpha.
+    - Fix another rendezvous cache unit test that was triggering an
+      underflow on the global rend cache allocation. Fixes bug 40126;
+      bugfix on 0.2.8.1-alpha.
+
+  o Minor bugfixes (correctness, buffers, backport from 0.4.4.4-rc):
+    - Fix a correctness bug that could cause an assertion failure if we
+      ever tried using the buf_move_all() function with an empty input
+      buffer. As far as we know, no released versions of Tor do this.
+      Fixes bug 40076; bugfix on 0.3.3.1-alpha.
+
+  o Minor bugfixes (logging, backport from 0.4.5.1-alpha):
+    - Remove a debug logging statement that uselessly spammed the logs.
+      Fixes bug 40135; bugfix on 0.3.5.0-alpha.
+
+  o Minor bugfixes (rate limiting, bridges, pluggable transports, backport from 0.4.4.4-rc):
+    - On a bridge, treat all connections from an ExtORPort as remote by
+      default for the purposes of rate-limiting. Previously, bridges
+      would treat the connection as local unless they explicitly
+      received a "USERADDR" command. ExtORPort connections still count
+      as local if there is a USERADDR command with an explicit local
+      address. Fixes bug 33747; bugfix on 0.2.5.1-alpha.
+
+  o Minor bugfixes (relay configuration, crash, backport from 0.4.5.1-alpha):
+    - Avoid a fatal assert() when failing to create a listener
+      connection for an address that was in use. Fixes bug 40073; bugfix
+      on 0.3.5.1-alpha.
+
+  o Minor bugfixes (relay, usability, backport from 0.4.4.3-alpha):
+    - Adjust the rules for when to warn about having too many
+      connections to other relays. Previously we'd tolerate up to 1.5
+      connections per relay on average. Now we tolerate more connections
+      for directory authorities, and raise the number of total
+      connections we need to see before we warn. Fixes bug 33880; bugfix
+      on 0.3.1.1-alpha.
+
+  o Minor bugfixes (relays, backport from 0.4.4.1-alpha):
+    - Stop advertising incorrect IPv6 ORPorts in relay and bridge
+      descriptors, when the IPv6 port was configured as "auto". Fixes
+      bug 32588; bugfix on 0.2.3.9-alpha.
+
+  o Minor bugfixes (tests, 0.4.4.5):
+    - Fix the behavior of the rend_cache/clean_v2_descs_as_dir when run
+      on its own. Previously, it would exit with an error. Fixes bug
+      40099; bugfix on 0.2.8.1-alpha.
+
+  o Minor bugfixes (windows, backport from 0.4.4.4-rc):
+    - Fix a bug that prevented Tor from starting if its log file grew
+      above 2GB. Fixes bug 31036; bugfix on 0.2.1.8-alpha.
+
+  o Deprecated features (onion service v2, backport form 0.4.4.2-alpha):
+    - Add a deprecation warning for version 2 onion services. Closes
+      ticket 40003.
+
+
+Changes in version 0.3.5.11 - 2020-07-09
+  Tor 0.3.5.11 backports fixes from later tor releases, including several
+  usability, portability, and reliability fixes.
+
+  This release also fixes TROVE-2020-001, a medium-severity denial of
+  service vulnerability affecting all versions of Tor when compiled with
+  the NSS encryption library. (This is not the default configuration.)
+  Using this vulnerability, an attacker could cause an affected Tor
+  instance to crash remotely. This issue is also tracked as CVE-2020-
+  15572. Anybody running a version of Tor built with the NSS library
+  should upgrade to 0.3.5.11, 0.4.2.8, 0.4.3.6, or 0.4.4.2-alpha
+  or later.
+
+  o Major bugfixes (NSS, security, backport from 0.4.4.2-alpha):
+    - Fix a crash due to an out-of-bound memory access when Tor is
+      compiled with NSS support. Fixes bug 33119; bugfix on
+      0.3.5.1-alpha. This issue is also tracked as TROVE-2020-001
+      and CVE-2020-15572.
+
+  o Major bugfixes (DoS defenses, bridges, pluggable transport, backport from 0.4.3.4-rc):
+    - Fix a bug that was preventing DoS defenses from running on bridges
+      with a pluggable transport. Previously, the DoS subsystem was not
+      given the transport name of the client connection, thus failed to
+      find the GeoIP cache entry for that client address. Fixes bug
+      33491; bugfix on 0.3.3.2-alpha.
+
+  o Minor features (testing, backport from 0.4.3.4-rc):
+    - The unit tests now support a "TOR_SKIP_TESTCASES" environment
+      variable to specify a list of space-separated test cases that
+      should not be executed. We will use this to disable certain tests
+      that are failing on Appveyor because of mismatched OpenSSL
+      libraries. Part of ticket 33643.
+
+  o Minor bugfix (CI, Windows, backport from 0.4.4.2-alpha):
+    - Use the correct 64-bit printf format when compiling with MINGW on
+      Appveyor. Fixes bug 40026; bugfix on 0.3.5.5-alpha.
+
+  o Minor bugfix (relay, configuration, backport from 0.4.3.3-alpha):
+    - Warn if the ContactInfo field is not set, and tell the relay
+      operator that not having a ContactInfo field set might cause their
+      relay to get rejected in the future. Fixes bug 33361; bugfix
+      on 0.1.1.10-alpha.
+
+  o Minor bugfixes (client performance, backport from 0.4.4.1-alpha):
+    - Resume use of preemptively-built circuits when UseEntryGuards is set
+      to 0. We accidentally disabled this feature with that config
+      setting, leading to slower load times. Fixes bug 34303; bugfix
+      on 0.3.3.2-alpha.
+
+  o Minor bugfixes (compiler compatibility, backport from 0.4.3.5):
+    - Avoid compiler warnings from Clang 10 related to the use of GCC-
+      style "/* falls through */" comments. Both Clang and GCC allow
+      __attribute__((fallthrough)) instead, so that's what we're using
+      now. Fixes bug 34078; bugfix on 0.3.1.3-alpha.
+
+  o Minor bugfixes (compiler warnings, backport from 0.4.4.2-alpha):
+    - Fix a compiler warning on platforms with 32-bit time_t values.
+      Fixes bug 40028; bugfix on 0.3.2.8-rc.
+
+  o Minor bugfixes (embedded Tor, backport from 0.4.3.1-alpha):
+    - When starting Tor any time after the first time in a process,
+      register the thread in which it is running as the main thread.
+      Previously, we only did this on Windows, which could lead to bugs
+      like 23081 on non-Windows platforms. Fixes bug 32884; bugfix
+      on 0.3.3.1-alpha.
+
+  o Minor bugfixes (key portability, backport from 0.4.3.4-rc):
+    - When reading PEM-encoded key data, tolerate CRLF line-endings even
+      if we are not running on Windows. Previously, non-Windows hosts
+      would reject these line-endings in certain positions, making
+      certain key files hard to move from one host to another. Fixes bug
+      33032; bugfix on 0.3.5.1-alpha.
+
+  o Minor bugfixes (logging, backport from 0.4.4.2-alpha):
+    - Downgrade a noisy log message that could occur naturally when
+      receiving an extrainfo document that we no longer want. Fixes bug
+      16016; bugfix on 0.2.6.3-alpha.
+
+  o Minor bugfixes (onion service v3, client, backport from 0.4.3.3-alpha):
+    - Remove a BUG() warning that would cause a stack trace if an onion
+      service descriptor was freed while we were waiting for a
+      rendezvous circuit to complete. Fixes bug 28992; bugfix
+      on 0.3.2.1-alpha.
+
+  o Testing (CI, backport from 0.4.3.4-rc):
+    - In our Appveyor Windows CI, copy required DLLs to test and app
+      directories, before running tor's tests. This ensures that tor.exe
+      and test*.exe use the correct version of each DLL. This fix is not
+      required, but we hope it will avoid DLL search issues in future.
+      Fixes bug 33673; bugfix on 0.3.4.2-alpha.
+    - On Appveyor, skip the crypto/openssl_version test, which is
+      failing because of a mismatched library installation. Fix
+      for 33643.
+
+
 Changes in version 0.3.5.10 - 2020-03-18
   Tor 0.3.5.10 backports many fixes from later Tor releases, including a
   fix for TROVE-2020-002, a major denial-of-service vulnerability that
diff -Nur tor-0.3.5.10/aclocal.m4 tor-0.3.5.12/aclocal.m4
--- tor-0.3.5.10/aclocal.m4	2020-03-17 20:37:56.000000000 +0100
+++ tor-0.3.5.12/aclocal.m4	2020-11-09 23:16:25.000000000 +0100
@@ -1,6 +1,6 @@
-# generated automatically by aclocal 1.16.1 -*- Autoconf -*-
+# generated automatically by aclocal 1.16.2 -*- Autoconf -*-
 
-# Copyright (C) 1996-2018 Free Software Foundation, Inc.
+# Copyright (C) 1996-2020 Free Software Foundation, Inc.
 
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -20,7 +20,7 @@
 If you have problems, you may need to regenerate the build system entirely.
 To do so, use the procedure documented by the package, typically 'autoreconf'.])])
 
-# Copyright (C) 2002-2018 Free Software Foundation, Inc.
+# Copyright (C) 2002-2020 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -35,7 +35,7 @@
 [am__api_version='1.16'
 dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to
 dnl require some minimum version.  Point them to the right macro.
-m4_if([$1], [1.16.1], [],
+m4_if([$1], [1.16.2], [],
       [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl
 ])
 
@@ -51,12 +51,12 @@
 # Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced.
 # This function is AC_REQUIREd by AM_INIT_AUTOMAKE.
 AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],
-[AM_AUTOMAKE_VERSION([1.16.1])dnl
+[AM_AUTOMAKE_VERSION([1.16.2])dnl
 m4_ifndef([AC_AUTOCONF_VERSION],
   [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
 _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))])
 
-# Copyright (C) 2011-2018 Free Software Foundation, Inc.
+# Copyright (C) 2011-2020 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -118,7 +118,7 @@
 
 # AM_AUX_DIR_EXPAND                                         -*- Autoconf -*-
 
-# Copyright (C) 2001-2018 Free Software Foundation, Inc.
+# Copyright (C) 2001-2020 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -170,7 +170,7 @@
 
 # AM_CONDITIONAL                                            -*- Autoconf -*-
 
-# Copyright (C) 1997-2018 Free Software Foundation, Inc.
+# Copyright (C) 1997-2020 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -201,7 +201,7 @@
 Usually this means the macro was only invoked conditionally.]])
 fi])])
 
-# Copyright (C) 1999-2018 Free Software Foundation, Inc.
+# Copyright (C) 1999-2020 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -392,7 +392,7 @@
 
 # Generate code to set up dependency tracking.              -*- Autoconf -*-
 
-# Copyright (C) 1999-2018 Free Software Foundation, Inc.
+# Copyright (C) 1999-2020 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -431,7 +431,9 @@
   done
   if test $am_rc -ne 0; then
     AC_MSG_FAILURE([Something went wrong bootstrapping makefile fragments
-    for automatic dependency tracking.  Try re-running configure with the
+    for automatic dependency tracking.  If GNU make was not used, consider
+    re-running the configure script with MAKE="gmake" (or whatever is
+    necessary).  You can also try re-running configure with the
     '--disable-dependency-tracking' option to at least be able to build
     the package (albeit without support for automatic dependency tracking).])
   fi
@@ -458,7 +460,7 @@
 
 # Do all the work for Automake.                             -*- Autoconf -*-
 
-# Copyright (C) 1996-2018 Free Software Foundation, Inc.
+# Copyright (C) 1996-2020 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -655,7 +657,7 @@
 done
 echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count])
 
-# Copyright (C) 2001-2018 Free Software Foundation, Inc.
+# Copyright (C) 2001-2020 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -676,7 +678,7 @@
 fi
 AC_SUBST([install_sh])])
 
-# Copyright (C) 2003-2018 Free Software Foundation, Inc.
+# Copyright (C) 2003-2020 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -697,7 +699,7 @@
 
 # Check to see how 'make' treats includes.	            -*- Autoconf -*-
 
-# Copyright (C) 2001-2018 Free Software Foundation, Inc.
+# Copyright (C) 2001-2020 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -740,7 +742,7 @@
 
 # Fake the existence of programs that GNU maintainers use.  -*- Autoconf -*-
 
-# Copyright (C) 1997-2018 Free Software Foundation, Inc.
+# Copyright (C) 1997-2020 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -779,7 +781,7 @@
 
 # Helper functions for option handling.                     -*- Autoconf -*-
 
-# Copyright (C) 2001-2018 Free Software Foundation, Inc.
+# Copyright (C) 2001-2020 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -808,7 +810,7 @@
 AC_DEFUN([_AM_IF_OPTION],
 [m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])])
 
-# Copyright (C) 1999-2018 Free Software Foundation, Inc.
+# Copyright (C) 1999-2020 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -855,7 +857,7 @@
 # For backward compatibility.
 AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])])
 
-# Copyright (C) 2001-2018 Free Software Foundation, Inc.
+# Copyright (C) 2001-2020 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -874,7 +876,7 @@
 
 # Check to make sure that the build environment is sane.    -*- Autoconf -*-
 
-# Copyright (C) 1996-2018 Free Software Foundation, Inc.
+# Copyright (C) 1996-2020 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -955,7 +957,7 @@
 rm -f conftest.file
 ])
 
-# Copyright (C) 2009-2018 Free Software Foundation, Inc.
+# Copyright (C) 2009-2020 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -1015,7 +1017,7 @@
 _AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl
 ])
 
-# Copyright (C) 2001-2018 Free Software Foundation, Inc.
+# Copyright (C) 2001-2020 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -1043,7 +1045,7 @@
 INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s"
 AC_SUBST([INSTALL_STRIP_PROGRAM])])
 
-# Copyright (C) 2006-2018 Free Software Foundation, Inc.
+# Copyright (C) 2006-2020 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
@@ -1062,7 +1064,7 @@
 
 # Check how to create a tarball.                            -*- Autoconf -*-
 
-# Copyright (C) 2004-2018 Free Software Foundation, Inc.
+# Copyright (C) 2004-2020 Free Software Foundation, Inc.
 #
 # This file is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
diff -Nur tor-0.3.5.10/configure tor-0.3.5.12/configure
--- tor-0.3.5.10/configure	2020-03-17 20:37:57.000000000 +0100
+++ tor-0.3.5.12/configure	2020-11-09 23:16:27.000000000 +0100
@@ -1,6 +1,6 @@
 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for tor 0.3.5.10.
+# Generated by GNU Autoconf 2.69 for tor 0.3.5.12.
 #
 #
 # Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
@@ -577,8 +577,8 @@
 # Identity of this package.
 PACKAGE_NAME='tor'
 PACKAGE_TARNAME='tor'
-PACKAGE_VERSION='0.3.5.10'
-PACKAGE_STRING='tor 0.3.5.10'
+PACKAGE_VERSION='0.3.5.12'
+PACKAGE_STRING='tor 0.3.5.12'
 PACKAGE_BUGREPORT=''
 PACKAGE_URL=''
 
@@ -1458,7 +1458,7 @@
   # Omit some internal or obsolete options to make the list less imposing.
   # This message is too long to be a string in the A/UX 3.1 sh.
   cat <<_ACEOF
-\`configure' configures tor 0.3.5.10 to adapt to many kinds of systems.
+\`configure' configures tor 0.3.5.12 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1528,7 +1528,7 @@
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of tor 0.3.5.10:";;
+     short | recursive ) echo "Configuration of tor 0.3.5.12:";;
    esac
   cat <<\_ACEOF
 
@@ -1737,7 +1737,7 @@
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-tor configure 0.3.5.10
+tor configure 0.3.5.12
 generated by GNU Autoconf 2.69
 
 Copyright (C) 2012 Free Software Foundation, Inc.
@@ -2442,7 +2442,7 @@
 This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
 
-It was created by tor $as_me 0.3.5.10, which was
+It was created by tor $as_me 0.3.5.12, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   $ $0 $@
@@ -3311,7 +3311,7 @@
 
 # Define the identity of the package.
  PACKAGE='tor'
- VERSION='0.3.5.10'
+ VERSION='0.3.5.12'
 
 
 cat >>confdefs.h <<_ACEOF
@@ -7581,6 +7581,42 @@
   as_fn_error $? "Your compiler doesn't support c99 designated initializers. This is required as of Tor 0.2.6.x" "$LINENO" 5
 fi
 
+saved_CFLAGS="$CFLAGS"
+CFLAGS="$CFLAGS -Werror"
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for __attribute__((fallthrough))" >&5
+$as_echo_n "checking for __attribute__((fallthrough))... " >&6; }
+if ${tor_cv_c_attr_fallthrough+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+extern int x; void fn(void) ;
+int
+main ()
+{
+ switch (x) { case 1: fn(); __attribute__((fallthrough));
+                               case 2: fn(); break; }
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  tor_cv_c_attr_fallthrough=yes
+else
+  tor_cv_c_attr_fallthrough=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tor_cv_c_attr_fallthrough" >&5
+$as_echo "$tor_cv_c_attr_fallthrough" >&6; }
+CFLAGS="$saved_CFLAGS"
+
+if test "$tor_cv_c_attr_fallthrough" = "yes"; then
+
+$as_echo "#define HAVE_ATTR_FALLTHROUGH 1" >>confdefs.h
+
+fi
+
 TORUSER=_tor
 
 # Check whether --with-tor-user was given.
@@ -28233,7 +28269,7 @@
 # report actual input values of CONFIG_FILES etc. instead of their
 # values after options handling.
 ac_log="
-This file was extended by tor $as_me 0.3.5.10, which was
+This file was extended by tor $as_me 0.3.5.12, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -28299,7 +28335,7 @@
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
 ac_cs_version="\\
-tor config.status 0.3.5.10
+tor config.status 0.3.5.12
 configured by $0, generated by GNU Autoconf 2.69,
   with options \\"\$ac_cs_config\\"
 
@@ -29121,7 +29157,9 @@
     { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
 as_fn_error $? "Something went wrong bootstrapping makefile fragments
-    for automatic dependency tracking.  Try re-running configure with the
+    for automatic dependency tracking.  If GNU make was not used, consider
+    re-running the configure script with MAKE=\"gmake\" (or whatever is
+    necessary).  You can also try re-running configure with the
     '--disable-dependency-tracking' option to at least be able to build
     the package (albeit without support for automatic dependency tracking).
 See \`config.log' for more details" "$LINENO" 5; }
diff -Nur tor-0.3.5.10/configure.ac tor-0.3.5.12/configure.ac
--- tor-0.3.5.10/configure.ac	2020-03-13 21:57:42.000000000 +0100
+++ tor-0.3.5.12/configure.ac	2020-11-09 23:14:58.000000000 +0100
@@ -4,7 +4,7 @@
 dnl See LICENSE for licensing information
 
 AC_PREREQ([2.63])
-AC_INIT([tor],[0.3.5.10])
+AC_INIT([tor],[0.3.5.12])
 AC_CONFIG_SRCDIR([src/app/main/tor_main.c])
 AC_CONFIG_MACRO_DIR([m4])
 
@@ -356,6 +356,22 @@
   AC_MSG_ERROR([Your compiler doesn't support c99 designated initializers. This is required as of Tor 0.2.6.x])
 fi
 
+saved_CFLAGS="$CFLAGS"
+CFLAGS="$CFLAGS -Werror"
+AC_CACHE_CHECK([for __attribute__((fallthrough))],
+      tor_cv_c_attr_fallthrough,
+      [AC_COMPILE_IFELSE(
+         [AC_LANG_PROGRAM([extern int x; void fn(void) ;],
+	       [[ switch (x) { case 1: fn(); __attribute__((fallthrough));
+                               case 2: fn(); break; } ]])],
+	 [tor_cv_c_attr_fallthrough=yes],
+	 [tor_cv_c_attr_fallthrough=no] )])
+CFLAGS="$saved_CFLAGS"
+
+if test "$tor_cv_c_attr_fallthrough" = "yes"; then
+  AC_DEFINE(HAVE_ATTR_FALLTHROUGH, [1], [defined if we have the fallthrough attribute.])
+fi
+
 TORUSER=_tor
 AC_ARG_WITH(tor-user,
         AS_HELP_STRING(--with-tor-user=NAME, [specify username for tor daemon]),
diff -Nur tor-0.3.5.10/contrib/win32build/tor-mingw.nsi.in tor-0.3.5.12/contrib/win32build/tor-mingw.nsi.in
--- tor-0.3.5.10/contrib/win32build/tor-mingw.nsi.in	2020-03-13 21:57:42.000000000 +0100
+++ tor-0.3.5.12/contrib/win32build/tor-mingw.nsi.in	2020-11-09 23:14:58.000000000 +0100
@@ -8,7 +8,7 @@
 !include "LogicLib.nsh"
 !include "FileFunc.nsh"
 !insertmacro GetParameters
-!define VERSION "0.3.5.10"
+!define VERSION "0.3.5.12"
 !define INSTALLER "tor-${VERSION}-win32.exe"
 !define WEBSITE "https://www.torproject.org/"
 !define LICENSE "LICENSE"
diff -Nur tor-0.3.5.10/orconfig.h.in tor-0.3.5.12/orconfig.h.in
--- tor-0.3.5.10/orconfig.h.in	2020-03-17 20:38:16.000000000 +0100
+++ tor-0.3.5.12/orconfig.h.in	2020-11-09 23:16:42.000000000 +0100
@@ -57,6 +57,9 @@
 /* Define to 1 if you have the <arpa/inet.h> header file. */
 #undef HAVE_ARPA_INET_H
 
+/* defined if we have the fallthrough attribute. */
+#undef HAVE_ATTR_FALLTHROUGH
+
 /* Define to 1 if you have the `backtrace' function. */
 #undef HAVE_BACKTRACE
 
diff -Nur tor-0.3.5.10/src/app/config/config.c tor-0.3.5.12/src/app/config/config.c
--- tor-0.3.5.10/src/app/config/config.c	2020-02-12 14:28:47.000000000 +0100
+++ tor-0.3.5.12/src/app/config/config.c	2020-10-07 15:29:17.000000000 +0200
@@ -809,9 +809,6 @@
                                    char **msg);
 static char *get_bindaddr_from_transport_listen_line(const char *line,
                                                      const char *transport);
-static int parse_ports(or_options_t *options, int validate_only,
-                              char **msg_out, int *n_ports_out,
-                              int *world_writable_control_socket);
 static int check_server_ports(const smartlist_t *ports,
                               const or_options_t *options,
                               int *num_low_ports_out);
@@ -3433,10 +3430,15 @@
     }
   }
 
-  if (server_mode(options) && !options->ContactInfo)
-    log_notice(LD_CONFIG, "Your ContactInfo config option is not set. "
-        "Please consider setting it, so we can contact you if your server is "
-        "misconfigured or something else goes wrong.");
+  if (server_mode(options) && !options->ContactInfo) {
+    log_warn(LD_CONFIG,
+             "Your ContactInfo config option is not set. Please strongly "
+             "consider setting it, so we can contact you if your relay is "
+             "misconfigured, end-of-life, or something else goes wrong. "
+             "It is also possible that your relay might get rejected from "
+             "the network due to a missing valid contact address.");
+  }
+
   const char *ContactInfo = options->ContactInfo;
   if (ContactInfo && !string_is_utf8(ContactInfo, strlen(ContactInfo)))
     REJECT("ContactInfo config option must be UTF-8.");
@@ -7370,7 +7372,7 @@
  * If <b>validate_only</b> is false, set configured_client_ports to the
  * new list of ports parsed from <b>options</b>.
  **/
-static int
+STATIC int
 parse_ports(or_options_t *options, int validate_only,
             char **msg, int *n_ports_out,
             int *world_writable_control_socket)
diff -Nur tor-0.3.5.10/src/app/config/config.h tor-0.3.5.12/src/app/config/config.h
--- tor-0.3.5.10/src/app/config/config.h	2019-10-11 23:48:21.000000000 +0200
+++ tor-0.3.5.12/src/app/config/config.h	2020-10-07 15:29:17.000000000 +0200
@@ -295,6 +295,10 @@
                                  const char *fname,
                                  int truncate_log);
 
+STATIC int parse_ports(or_options_t *options, int validate_only,
+                       char **msg, int *n_ports_out,
+                       int *world_writable_control_socket);
+
 #endif /* defined(CONFIG_PRIVATE) */
 
 #endif /* !defined(TOR_CONFIG_H) */
diff -Nur tor-0.3.5.10/src/app/config/confparse.c tor-0.3.5.12/src/app/config/confparse.c
--- tor-0.3.5.10/src/app/config/confparse.c	2019-10-11 23:48:21.000000000 +0200
+++ tor-0.3.5.12/src/app/config/confparse.c	2020-05-06 22:58:12.000000000 +0200
@@ -179,7 +179,7 @@
       *(int *)lvalue = CFG_AUTO_PORT;
       break;
     }
-    /* fall through */
+    FALLTHROUGH;
   case CONFIG_TYPE_INT:
   case CONFIG_TYPE_UINT:
     i = (int)tor_parse_long(c->value, 10,
@@ -577,7 +577,7 @@
         escape_val = 0;
         break;
       }
-      /* fall through */
+      FALLTHROUGH;
     case CONFIG_TYPE_CSV_INTERVAL:
     case CONFIG_TYPE_INTERVAL:
     case CONFIG_TYPE_MSEC_INTERVAL:
@@ -588,7 +588,7 @@
       tor_asprintf(&result->value, "%d", *(int*)value);
       escape_val = 0; /* Can't need escape. */
       break;
-    case CONFIG_TYPE_UINT64: /* Fall through */
+    case CONFIG_TYPE_UINT64: FALLTHROUGH;
     case CONFIG_TYPE_MEMUNIT:
       tor_asprintf(&result->value, "%"PRIu64,
                    (*(uint64_t*)value));
@@ -605,7 +605,7 @@
         escape_val = 0;
         break;
       }
-      /* fall through */
+      FALLTHROUGH;
     case CONFIG_TYPE_BOOL:
       result->value = tor_strdup(*(int*)value ? "1" : "0");
       escape_val = 0; /* Can't need escape. */
diff -Nur tor-0.3.5.10/src/app/config/fallback_dirs.inc tor-0.3.5.12/src/app/config/fallback_dirs.inc
--- tor-0.3.5.10/src/app/config/fallback_dirs.inc	2019-10-11 23:48:21.000000000 +0200
+++ tor-0.3.5.12/src/app/config/fallback_dirs.inc	2020-07-27 18:56:18.000000000 +0200
@@ -1,65 +1,35 @@
 /* type=fallback */
-/* version=2.0.0 */
-/* timestamp=20190625114911 */
-/* timestamp0=20190625114911 */
-/* timestamp1=20190628085927 */
-/* source=whitelist */
+/* version=3.0.0 */
+/* timestamp=20200723133610 */
+/* source=offer-list */
 /* ===== */
-/* 0: Whitelist excluded 1550 of 1711 candidates. */
-/* 1: Whitelist excluded 1601 of 1765 candidates. */
+/* Offer list excluded 1807 of 1978 candidates. */
 /* Checked IPv4 DirPorts served a consensus within 15.0s. */
 /*
-0:
-Final Count: 140 (Eligible 161, Target 414 (2072 * 0.20), Max 200)
-Excluded: 21 (Same Operator 16, Failed/Skipped Download 3, Excess 2)
-Bandwidth Range: 0.5 - 54.5 MByte/s
-
-MERGED WITH:
-
-1:
-Final Count: 140 (Eligible 164, Target 414 (2073 * 0.20), Max 200)
-Excluded: 24 (Same Operator 16, Failed/Skipped Download 4, Excess 4)
-Bandwidth Range: 0.8 - 54.5 MByte/s
+Final Count: 144 (Eligible 171, Target 447 (2239 * 0.20), Max 200)
+Excluded: 27 (Same Operator 15, Failed/Skipped Download 6, Excess 6)
+Bandwidth Range: 0.6 - 96.1 MByte/s
 */
 /*
-):
-Onionoo Source: details Date: 2019-06-25 10: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-
-
-MERGED WITH:
-
-1:
-Onionoo Source: details Date: 2019-06-28 07: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&last_seen_days-0&flagV2Dir&first_seen_days90-&typerelay&order-consensus_weight%2Cfirst_seen
+Onionoo Source: details Date: 2020-07-23 13:00:00 Version: 8.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&typerelay&first_seen_days90-&last_seen_days-0&flagV2Dir&order-consensus_weight%2Cfirst_seen
 */
 /*
-0:
-Onionoo Source: uptime Date: 2019-06-25 10:00:00 Version: 7.0
-URL: https:onionoo.torproject.orguptime?first_seen_days90-&flagV2Dir&typerelay&last_seen_days-0
-
-MERGED WITH:
-
-1:
-Onionoo Source: uptime Date: 2019-06-28 07:00:00 Version: 7.0
-URL: https:onionoo.torproject.orguptime?first_seen_days90-&flagV2Dir&typerelay&order-consensus_weight%2Cfirst_seen&last_seen_days-0
+Onionoo Source: uptime Date: 2020-07-23 13:00:00 Version: 8.0
+URL: https:onionoo.torproject.orguptime?typerelay&first_seen_days90-&last_seen_days-0&flagV2Dir&order-consensus_weight%2Cfirst_seen
 */
 /* ===== */
-"185.13.39.197:80 orport=443 id=001524DD403D729F08F7E5D77813EF12756CFA8D"
-/* nickname=Neldoreth */
-/* extrainfo=0 */
-/* ===== */
-,
-"185.100.85.61:80 orport=443 id=025B66CEBC070FCB0519D206CF0CF4965C20C96E"
-/* nickname=nibbana */
-/* extrainfo=0 */
-/* ===== */
-,
 "185.225.17.3:80 orport=443 id=0338F9F55111FE8E3570E7DE117EF3AF999CC1D7"
 " ipv6=[2a0a:c800:1:5::3]:443"
 /* nickname=Nebuchadnezzar */
 /* extrainfo=0 */
 /* ===== */
 ,
+"81.7.10.193:9002 orport=993 id=03C3069E814E296EB18776EB61B1ECB754ED89FE"
+/* nickname=Ichotolot61 */
+/* extrainfo=1 */
+/* ===== */
+,
 "163.172.149.155:80 orport=443 id=0B85617241252517E8ECF2CFC7F4C1A32DCD153F"
 /* nickname=niij02 */
 /* extrainfo=0 */
@@ -70,8 +40,19 @@
 /* extrainfo=0 */
 /* ===== */
 ,
-"37.252.185.182:9030 orport=8080 id=113143469021882C3A4B82F084F8125B08EE471E"
-" ipv6=[2a00:63c1:a:182::2]:8080"
+"81.7.18.7:9030 orport=9001 id=0C475BA4D3AA3C289B716F95954CAD616E50C4E5"
+/* nickname=Freebird32 */
+/* extrainfo=1 */
+/* ===== */
+,
+"193.234.15.60:80 orport=443 id=0F6E5CA4BF5565D9AA9FDDCA165AFC6A5305763D"
+" ipv6=[2a00:1c20:4089:1234:67bc:79f3:61c0:6e49]:443"
+/* nickname=jaures3 */
+/* extrainfo=0 */
+/* ===== */
+,
+"93.177.67.71:9030 orport=8080 id=113143469021882C3A4B82F084F8125B08EE471E"
+" ipv6=[2a03:4000:38:559::2]:8080"
 /* nickname=parasol */
 /* extrainfo=0 */
 /* ===== */
@@ -82,11 +63,6 @@
 /* extrainfo=0 */
 /* ===== */
 ,
-"95.85.8.226:80 orport=443 id=1211AC1BBB8A1AF7CBA86BCE8689AA3146B86423"
-/* nickname=ccrelaycc */
-/* extrainfo=0 */
-/* ===== */
-,
 "193.11.114.43:9030 orport=9001 id=12AD30E5D25AA67F519780E2111E611A455FDC89"
 " ipv6=[2001:6b0:30:1000::99]:9050"
 /* nickname=mdfnet1 */
@@ -98,27 +74,23 @@
 /* extrainfo=0 */
 /* ===== */
 ,
-"217.182.51.248:80 orport=443 id=183005F78229D94EE51CE7795A42280070A48D0D"
-/* nickname=Cosworth02 */
+"193.234.15.61:80 orport=443 id=158581827034DEF1BAB1FC248D180165452E53D3"
+" ipv6=[2a00:1c20:4089:1234:2712:a3d0:666b:88a6]:443"
+/* nickname=bakunin3 */
 /* 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:1824:c4b::1]:9001"
+/* nickname=rofltor07 */
 /* extrainfo=0 */
 /* ===== */
 ,
-"149.56.141.138:9030 orport=9001 id=1938EBACBB1A7BFA888D9623C90061130E63BB3F"
-/* nickname=Aerodynamik04 */
+"204.11.50.131:9030 orport=9001 id=185F2A57B0C4620582602761097D17DB81654F70"
+/* nickname=BoingBoing */
 /* extrainfo=0 */
 /* ===== */
 ,
-"81.7.14.253:9001 orport=443 id=1AE039EE0B11DB79E4B4B29CBA9F752864A0259E"
-/* nickname=Ichotolot60 */
-/* extrainfo=1 */
-/* ===== */
-,
 "50.7.74.171:9030 orport=9001 id=1CD17CB202063C51C7DAD3BACEF87ECE81C2350F"
 " ipv6=[2001:49f0:d002:2::51]:443"
 /* nickname=theia1 */
@@ -132,7 +104,7 @@
 /* ===== */
 ,
 "212.47.229.2:9030 orport=9001 id=20462CBA5DA4C2D963567D17D0B7249718114A68"
-" ipv6=[2001:bc8:4400:2100::f03]:9001"
+" ipv6=[2001:bc8:47ac:23a::1]:9001"
 /* nickname=scaletor */
 /* extrainfo=0 */
 /* ===== */
@@ -147,13 +119,37 @@
 /* extrainfo=0 */
 /* ===== */
 ,
+"193.234.15.57:80 orport=443 id=24D0491A2ADAAB52C17625FBC926D84477AEA322"
+" ipv6=[2a00:1c20:4089:1234:7825:2c5d:1ecd:c66f]:443"
+/* nickname=bakunin */
+/* extrainfo=0 */
+/* ===== */
+,
+"185.220.101.137:20137 orport=10137 id=28F4F392F8F19E3FBDE09616D9DB8143A1E2DDD3"
+" ipv6=[2a0b:f4c2:1::137]:10137"
+/* nickname=niftycottonmouse */
+/* extrainfo=0 */
+/* ===== */
+,
+"138.201.250.33:9012 orport=9011 id=2BA2C8E96B2590E1072AECE2BDB5C48921BF8510"
+/* nickname=storm */
+/* extrainfo=0 */
+/* ===== */
+,
+"5.181.50.99:80 orport=443 id=2BB85DC5BD3C6F0D81A4F2B5882176C6BF7ECF5A"
+" ipv6=[2a03:4000:3f:16c:3851:6bff:fe07:bd2]:443"
+/* nickname=AlanTuring */
+/* extrainfo=0 */
+/* ===== */
+,
 "97.74.237.196:9030 orport=9001 id=2F0F32AB1E5B943CA7D062C03F18960C86E70D94"
 /* nickname=Minotaur */
 /* extrainfo=0 */
 /* ===== */
 ,
-"212.83.154.33:8080 orport=8443 id=322C6E3A973BC10FC36DE3037AD27BC89F14723B"
-/* nickname=bauruine204 */
+"94.230.208.147:8080 orport=8443 id=311A4533F7A2415F42346A6C8FA77E6FD279594C"
+" ipv6=[2a02:418:6017::147]:8443"
+/* nickname=DigiGesTor3e2 */
 /* extrainfo=0 */
 /* ===== */
 ,
@@ -169,18 +165,13 @@
 /* extrainfo=0 */
 /* ===== */
 ,
-"37.157.255.35:9030 orport=9090 id=361D33C96D0F161275EE67E2C91EE10B276E778B"
-/* nickname=cxx4freedom */
-/* extrainfo=0 */
-/* ===== */
-,
 "64.79.152.132:80 orport=443 id=375DCBB2DBD94E5263BC0C015F0C9E756669617E"
 /* nickname=ebola */
 /* extrainfo=0 */
 /* ===== */
 ,
-"213.183.60.21:9030 orport=443 id=39F91959416763AFD34DBEEC05474411B964B2DC"
-/* nickname=angeltest11 */
+"198.50.191.95:80 orport=443 id=39F096961ED2576975C866D450373A9913AFDC92"
+/* nickname=shhovh */
 /* extrainfo=0 */
 /* ===== */
 ,
@@ -190,9 +181,9 @@
 /* extrainfo=0 */
 /* ===== */
 ,
-"199.249.230.83:80 orport=443 id=3CA0D15567024D2E0B557DC0CF3E962B37999A79"
-" ipv6=[2620:7:6001::ffff:c759:e653]:80"
-/* nickname=QuintexAirVPN30 */
+"212.83.154.33:8888 orport=443 id=3C79699D4FBC37DE1A212D5033B56DAE079AC0EF"
+" ipv6=[2001:bc8:31d3:1dd::1]:443"
+/* nickname=bauruine203 */
 /* extrainfo=0 */
 /* ===== */
 ,
@@ -202,6 +193,12 @@
 /* extrainfo=0 */
 /* ===== */
 ,
+"95.216.211.81:80 orport=443 id=3CCF9573F59137E52787D9C322AC19D2BD090B70"
+" ipv6=[2a01:4f9:c010:4dfa::1]:443"
+/* nickname=BurningMan */
+/* extrainfo=0 */
+/* ===== */
+,
 "217.79.179.177:9030 orport=9001 id=3E53D3979DB07EFD736661C934A1DED14127B684"
 " ipv6=[2001:4ba0:fff9:131:6c4f::90d3]:9001"
 /* nickname=Unnamed */
@@ -224,24 +221,14 @@
 /* extrainfo=0 */
 /* ===== */
 ,
-"195.123.245.141:9030 orport=443 id=465D17C6FC297E3857B5C6F152006A1E212944EA"
-/* nickname=angeltest14 */
-/* 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 */
 /* extrainfo=0 */
 /* ===== */
 ,
-"37.187.102.186:9030 orport=9001 id=489D94333DF66D57FFE34D9D59CC2D97E2CB0053"
-" ipv6=[2001:41d0:a:26ba::1]:9001"
-/* nickname=txtfileTorNode65536 */
+"109.70.100.4:80 orport=443 id=4BFC9C631A93FF4BA3AA84BC6931B4310C38A263"
+" ipv6=[2a03:e600:100::4]:443"
+/* nickname=karotte */
 /* extrainfo=0 */
 /* ===== */
 ,
@@ -262,38 +249,36 @@
 /* extrainfo=1 */
 /* ===== */
 ,
-"81.7.16.182:80 orport=443 id=51E1CF613FD6F9F11FE24743C91D6F9981807D82"
-" ipv6=[2a02:180:1:1::517:10b6]:993"
-/* nickname=torpidsDEisppro3 */
+"69.30.215.42:80 orport=443 id=510176C07005D47B23E6796F02C93241A29AA0E9"
+" ipv6=[2604:4300:a:2e:21b:21ff:fe11:392]:443"
+/* nickname=torpidsUSwholesale */
 /* extrainfo=0 */
 /* ===== */
 ,
-"192.160.102.166:80 orport=9001 id=547DA56F6B88B6C596B3E3086803CDA4F0EF8F21"
-" ipv6=[2620:132:300c:c01d::6]:9002"
-/* nickname=chaucer */
+"176.223.141.106:80 orport=443 id=5262556D44A7F2434990FDE1AE7973C67DF49E58"
+/* nickname=Theoden */
 /* extrainfo=0 */
 /* ===== */
 ,
-"192.160.102.170:80 orport=9001 id=557ACEC850F54EEE65839F83CACE2B0825BE811E"
-" ipv6=[2620:132:300c:c01d::a]:9002"
-/* nickname=ogopogo */
+"85.25.159.65:995 orport=80 id=52BFADA8BEAA01BA46C8F767F83C18E2FE50C1B9"
+/* nickname=BeastieJoy63 */
 /* extrainfo=0 */
 /* ===== */
 ,
-"50.7.74.170:80 orport=443 id=5BF17163CBE73D8CD9FDBE030C944EA05707DA93"
-" ipv6=[2001:49f0:d002:2::58]:443"
-/* nickname=theia8 */
+"193.234.15.59:80 orport=443 id=562434D987CF49D45649B76ADCA993BEA8F78471"
+" ipv6=[2a00:1c20:4089:1234:bff6:e1bb:1ce3:8dc6]:443"
+/* nickname=bakunin2 */
 /* extrainfo=0 */
 /* ===== */
 ,
-"172.98.193.43:80 orport=443 id=5E56738E7F97AA81DEEF59AF28494293DFBFCCDF"
-/* nickname=Backplane */
+"89.234.157.254:80 orport=443 id=578E007E5E4535FBFEF7758D8587B07B4C8C5D06"
+" ipv6=[2001:67c:2608::1]:443"
+/* nickname=marylou1 */
 /* extrainfo=0 */
 /* ===== */
 ,
-"95.128.43.164:80 orport=443 id=616081EC829593AF4232550DE6FFAA1D75B37A90"
-" ipv6=[2a02:ec0:209:10::4]:443"
-/* nickname=AquaRayTerminus */
+"172.98.193.43:80 orport=443 id=5E56738E7F97AA81DEEF59AF28494293DFBFCCDF"
+/* nickname=Backplane */
 /* extrainfo=0 */
 /* ===== */
 ,
@@ -302,26 +287,14 @@
 /* extrainfo=0 */
 /* ===== */
 ,
-"94.130.186.5:80 orport=443 id=6A7551EEE18F78A9813096E82BF84F740D32B911"
-" ipv6=[2a01:4f8:1c0c:45f7::1]:443"
+"95.217.16.212:80 orport=443 id=6A7551EEE18F78A9813096E82BF84F740D32B911"
+" ipv6=[2a01:4f9:c010:609a::1]:443"
 /* nickname=TorMachine */
 /* extrainfo=0 */
 /* ===== */
 ,
-"80.127.137.19:80 orport=443 id=6EF897645B79B6CB35E853B32506375014DE3621"
-" ipv6=[2001:981:47c1:1::6]:443"
-/* nickname=d6relay */
-/* extrainfo=0 */
-/* ===== */
-,
-"37.139.8.104:9030 orport=9001 id=7088D485934E8A403B81531F8C90BDC75FA43C98"
-" ipv6=[2a03:b0c0:0:1010::24c:1001]:9001"
-/* nickname=Basil */
-/* extrainfo=0 */
-/* ===== */
-,
-"188.138.88.42:80 orport=443 id=70C55A114C0EF3DC5784A4FAEE64388434A3398F"
-/* nickname=torpidsFRplusserver */
+"78.156.110.135:9093 orport=9092 id=7262B9D2EDE0B6A266C4B43D6202209BF6BBA888"
+/* nickname=SkynetRenegade */
 /* extrainfo=0 */
 /* ===== */
 ,
@@ -337,9 +310,14 @@
 /* extrainfo=0 */
 /* ===== */
 ,
-"50.7.74.173:9030 orport=9001 id=745369332749021C6FAF100D327BC3BF1DF4707B"
-" ipv6=[2001:49f0:d002:2::55]:443"
-/* nickname=theia5 */
+"81.7.14.31:9001 orport=443 id=7600680249A22080ECC6173FBBF64D6FCF330A61"
+/* nickname=Ichotolot62 */
+/* extrainfo=1 */
+/* ===== */
+,
+"62.171.144.155:80 orport=443 id=7614EF326635DA810638E2F5D449D10AE2BB7158"
+" ipv6=[2a02:c207:3004:8874::1]:443"
+/* nickname=Nicenstein */
 /* extrainfo=0 */
 /* ===== */
 ,
@@ -359,6 +337,12 @@
 /* extrainfo=0 */
 /* ===== */
 ,
+"82.223.21.74:9030 orport=9001 id=7A32C9519D80CA458FC8B034A28F5F6815649A98"
+" ipv6=[2001:ba0:1800:6c::1]:9001"
+/* nickname=silentrocket */
+/* extrainfo=0 */
+/* ===== */
+,
 "51.254.136.195:80 orport=443 id=7BB70F8585DFC27E75D692970C0EEB0F22983A63"
 /* nickname=torproxy02 */
 /* extrainfo=0 */
@@ -369,11 +353,6 @@
 /* extrainfo=0 */
 /* ===== */
 ,
-"185.220.101.48:10048 orport=20048 id=7E281CD2C315C4F7A84BC7C8721C3BC974DDBFA3"
-/* nickname=niftyporcupine */
-/* extrainfo=0 */
-/* ===== */
-,
 "193.11.114.45:9031 orport=9002 id=80AAF8D5956A43C197104CEF2550CD42D165C6FB"
 /* nickname=mdfnet2 */
 /* extrainfo=0 */
@@ -385,14 +364,14 @@
 /* extrainfo=0 */
 /* ===== */
 ,
-"192.42.116.16:80 orport=443 id=81B75D534F91BFB7C57AB67DA10BCEF622582AE8"
-/* nickname=hviv104 */
+"152.89.106.147:9030 orport=9001 id=8111FEB45EF2950EB8F84BFD8FF070AB07AEE9DD"
+" ipv6=[2a03:4000:39:605:c4f2:c9ff:fe64:c215]:9001"
+/* nickname=TugaOnionMR3 */
 /* extrainfo=0 */
 /* ===== */
 ,
-"192.160.102.164:80 orport=9001 id=823AA81E277F366505545522CEDC2F529CE4DC3F"
-" ipv6=[2620:132:300c:c01d::4]:9002"
-/* nickname=snowfall */
+"192.42.116.16:80 orport=443 id=81B75D534F91BFB7C57AB67DA10BCEF622582AE8"
+/* nickname=hviv104 */
 /* extrainfo=0 */
 /* ===== */
 ,
@@ -402,12 +381,7 @@
 /* extrainfo=0 */
 /* ===== */
 ,
-"62.210.254.132:80 orport=443 id=8456DFA94161CDD99E480C2A2992C366C6564410"
-/* nickname=turingmachine */
-/* extrainfo=0 */
-/* ===== */
-,
-"85.230.178.139:9030 orport=443 id=855BC2DABE24C861CD887DB9B2E950424B49FC34"
+"85.228.136.92:9030 orport=443 id=855BC2DABE24C861CD887DB9B2E950424B49FC34"
 /* nickname=Logforme */
 /* extrainfo=0 */
 /* ===== */
@@ -417,42 +391,37 @@
 /* extrainfo=0 */
 /* ===== */
 ,
-"185.96.88.29:80 orport=443 id=86C281AD135058238D7A337D546C902BE8505DDE"
-" ipv6=[2a00:4020::185:96:88:29]:443"
-/* nickname=TykRelay05 */
-/* extrainfo=0 */
-/* ===== */
-,
 "163.172.194.53:9030 orport=9001 id=8C00FA7369A7A308F6A137600F0FA07990D9D451"
 " ipv6=[2001:bc8:225f:142:6c69:7461:7669:73]:9001"
 /* nickname=GrmmlLitavis */
 /* extrainfo=0 */
 /* ===== */
 ,
-"5.189.169.190:8030 orport=8080 id=8D79F73DCD91FC4F5017422FAC70074D6DB8DD81"
-/* nickname=thanatosDE */
+"188.138.102.98:465 orport=443 id=8CAA470B905758742203E3EB45941719FCA9FEEC"
+/* nickname=BeastieJoy64 */
 /* extrainfo=0 */
 /* ===== */
 ,
-"81.7.11.96:9030 orport=9001 id=8FA37B93397015B2BC5A525C908485260BE9F422"
-/* nickname=Doedel22 */
+"109.70.100.6:80 orport=443 id=8CF987FF43FB7F3D9AA4C4F3D96FFDF247A9A6C2"
+" ipv6=[2a03:e600:100::6]:443"
+/* nickname=zucchini */
 /* extrainfo=0 */
 /* ===== */
 ,
-"54.37.139.118:9030 orport=9001 id=90A5D1355C4B5840E950EB61E673863A6AE3ACA1"
-" ipv6=[2001:41d0:601:1100::1b8]:9001"
-/* nickname=rofltor09 */
+"5.189.169.190:8030 orport=8080 id=8D79F73DCD91FC4F5017422FAC70074D6DB8DD81"
+/* nickname=thanatosDE */
 /* extrainfo=0 */
 /* ===== */
 ,
-"37.187.20.59:80 orport=443 id=91D23D8A539B83D2FB56AA67ECD4D75CC093AC55"
-" ipv6=[2001:41d0:a:143b::1]:993"
-/* nickname=torpidsFRovh */
+"80.67.172.162:80 orport=443 id=8E6EDA78D8E3ABA88D877C3E37D6D4F0938C7B9F"
+" ipv6=[2001:910:1410:600::1]:443"
+/* nickname=AlGrothendieck */
 /* extrainfo=0 */
 /* ===== */
 ,
-"173.255.245.116:9030 orport=9001 id=91E4015E1F82DAF0121D62267E54A1F661AB6DC7"
-/* nickname=IWorshipHisShadow */
+"54.37.139.118:9030 orport=9001 id=90A5D1355C4B5840E950EB61E673863A6AE3ACA1"
+" ipv6=[2001:41d0:601:1100::1b8]:9001"
+/* nickname=rofltor09 */
 /* extrainfo=0 */
 /* ===== */
 ,
@@ -461,29 +430,21 @@
 /* extrainfo=0 */
 /* ===== */
 ,
-"92.38.163.21:9030 orport=443 id=9288B75B5FF8861EFF32A6BE8825CC38A4F9F8C2"
-/* nickname=angeltest9 */
+"109.70.100.5:80 orport=443 id=9661AC95717798884F3E3727D360DD98D66727CC"
+" ipv6=[2a03:e600:100::5]:443"
+/* nickname=erdapfel */
 /* extrainfo=0 */
 /* ===== */
 ,
-"163.172.53.84:80 orport=443 id=935F589545B8A271A722E330445BB99F67DBB058"
-" ipv6=[2001:bc8:24f8::]:443"
-/* nickname=Multivac0 */
-/* extrainfo=0 */
-/* ===== */
-,
-"204.8.156.142:80 orport=443 id=94C4B7B8C50C86A92B6A20107539EE2678CF9A28"
-/* nickname=BostonUCompSci */
-/* extrainfo=0 */
-/* ===== */
-,
-"37.153.1.10:9030 orport=9001 id=9772EFB535397C942C3AB8804FB35CFFAD012438"
-/* nickname=smallsweatnode */
+"173.212.254.192:31336 orport=31337 id=99E246DB480B313A3012BC3363093CC26CD209C7"
+" ipv6=[2a02:c207:3002:3972::1]:31337"
+/* nickname=ViDiSrv */
 /* extrainfo=0 */
 /* ===== */
 ,
-"173.212.254.192:31336 orport=31337 id=99E246DB480B313A3012BC3363093CC26CD209C7"
-/* nickname=ViDiSrv */
+"188.127.69.60:80 orport=443 id=9B2BC7EFD661072AFADC533BE8DCF1C19D8C2DCC"
+" ipv6=[2a02:29d0:8008:c0de:bad:beef::]:443"
+/* nickname=MIGHTYWANG */
 /* extrainfo=0 */
 /* ===== */
 ,
@@ -493,8 +454,9 @@
 /* extrainfo=0 */
 /* ===== */
 ,
-"185.220.101.49:10049 orport=20049 id=9B816A5B3EB20B8E4E9B9D1FBA299BD3F40F0320"
-/* nickname=niftypygmyjerboa */
+"95.142.161.63:80 orport=443 id=9BA84E8C90083676F86C7427C8D105925F13716C"
+" ipv6=[2001:4b98:dc0:47:216:3eff:fe3d:888c]:443"
+/* nickname=ekumen */
 /* extrainfo=0 */
 /* ===== */
 ,
@@ -503,11 +465,6 @@
 /* extrainfo=0 */
 /* ===== */
 ,
-"31.185.104.19:80 orport=443 id=9EAD5B2D3DBD96DBC80DCE423B0C345E920A758D"
-/* nickname=Digitalcourage3ip1 */
-/* extrainfo=0 */
-/* ===== */
-,
 "46.28.110.244:80 orport=443 id=9F7D6E6420183C2B76D3CE99624EBC98A21A967E"
 /* nickname=Nivrim */
 /* extrainfo=0 */
@@ -518,9 +475,10 @@
 /* extrainfo=1 */
 /* ===== */
 ,
-"81.7.3.67:993 orport=443 id=A2E6BB5C391CD46B38C55B4329C35304540771F1"
-/* nickname=BeastieJoy62 */
-/* extrainfo=1 */
+"193.234.15.55:80 orport=443 id=A1B28D636A56AAFFE92ADCCA937AA4BD5333BB4C"
+" ipv6=[2a00:1c20:4089:1234:7b2c:11c5:5221:903e]:443"
+/* nickname=bakunin4 */
+/* extrainfo=0 */
 /* ===== */
 ,
 "128.31.0.13:80 orport=443 id=A53C46F5B157DD83366D45A8E99A244934A14C46"
@@ -528,8 +486,8 @@
 /* extrainfo=0 */
 /* ===== */
 ,
-"185.246.152.22:9030 orport=443 id=A86EC24F5B8B964F67AC7C27CE92842025983274"
-/* nickname=angeltest19 */
+"212.47.233.86:9130 orport=9101 id=A68097FE97D3065B1A6F4CE7187D753F8B8513F5"
+/* nickname=olabobamanmu */
 /* extrainfo=0 */
 /* ===== */
 ,
@@ -543,26 +501,26 @@
 /* extrainfo=0 */
 /* ===== */
 ,
-"185.129.62.62:9030 orport=9001 id=ACDD9E85A05B127BA010466C13C8C47212E8A38F"
-" ipv6=[2a06:d380:0:3700::62]:9001"
-/* nickname=kramse */
+"195.154.164.243:80 orport=443 id=AC66FFA4AB35A59EBBF5BF4C70008BF24D8A7A5C"
+" ipv6=[2001:bc8:399f:f000::1]:993"
+/* nickname=torpidsFRonline3 */
 /* extrainfo=0 */
 /* ===== */
 ,
-"31.185.104.20:80 orport=443 id=ADB2C26629643DBB9F8FE0096E7D16F9414B4F8D"
-/* nickname=Digitalcourage3ip2 */
+"185.129.62.62:9030 orport=9001 id=ACDD9E85A05B127BA010466C13C8C47212E8A38F"
+" ipv6=[2a06:d380:0:3700::62]:9001"
+/* nickname=kramse */
 /* extrainfo=0 */
 /* ===== */
 ,
-"45.79.108.130:9030 orport=9001 id=AEDAC7081AE14B8D241ECF0FF17A2858AB4383D0"
-" ipv6=[2600:3c01:e000:131::8000:0]:9001"
-/* nickname=linss */
+"188.40.128.246:9030 orport=9001 id=AD19490C7DBB26D3A68EFC824F67E69B0A96E601"
+" ipv6=[2a01:4f8:221:1ac1:dead:beef:7005:9001]:9001"
+/* nickname=sputnik */
 /* extrainfo=0 */
 /* ===== */
 ,
-"5.9.147.226:9030 orport=9001 id=B0553175AADB0501E5A61FC61CEA3970BE130FF2"
-" ipv6=[2a01:4f8:190:30e1::2]:9001"
-/* nickname=zwiubel */
+"176.10.104.240:8080 orport=8443 id=AD86CD1A49573D52A7B6F4A35750F161AAD89C88"
+/* nickname=DigiGesTor1e2 */
 /* extrainfo=0 */
 /* ===== */
 ,
@@ -577,9 +535,9 @@
 /* extrainfo=0 */
 /* ===== */
 ,
-"199.249.230.64:80 orport=443 id=B2197C23A4FF5D1C49EE45BA7688BA8BCCD89A0B"
-" ipv6=[2620:7:6001::ffff:c759:e640]:80"
-/* nickname=Quintex41 */
+"109.70.100.2:80 orport=443 id=B27CF1DCEECD50F7992B07D720D7F6BF0EDF9D40"
+" ipv6=[2a03:e600:100::2]:443"
+/* nickname=radieschen */
 /* extrainfo=0 */
 /* ===== */
 ,
@@ -588,21 +546,11 @@
 /* extrainfo=0 */
 /* ===== */
 ,
-"212.47.233.86:9030 orport=9001 id=B4CAFD9CBFB34EC5DAAC146920DC7DFAFE91EA20"
-/* nickname=netimanmu */
-/* extrainfo=0 */
-/* ===== */
-,
 "93.115.97.242:9030 orport=9001 id=B5212DB685A2A0FCFBAE425738E478D12361710D"
 /* nickname=firstor */
 /* extrainfo=0 */
 /* ===== */
 ,
-"51.38.134.104:9030 orport=443 id=B57A87009FA838471FB2227DDE68165AB2A2FCC4"
-/* nickname=angeltest5 */
-/* extrainfo=0 */
-/* ===== */
-,
 "193.11.114.46:9032 orport=9003 id=B83DC1558F0D34353BB992EF93AFEAFDB226A73E"
 /* nickname=mdfnet3 */
 /* extrainfo=0 */
@@ -614,12 +562,8 @@
 /* extrainfo=0 */
 /* ===== */
 ,
-"81.7.11.186:1080 orport=443 id=B86137AE9681701901C6720E55C16805B46BD8E3"
-/* nickname=BeastieJoy60 */
-/* extrainfo=1 */
-/* ===== */
-,
 "51.15.179.153:110 orport=995 id=BB60F5BA113A0B8B44B7B37DE3567FE561E92F78"
+" ipv6=[2001:bc8:3fec:500:7ea::]:995"
 /* nickname=Casper04 */
 /* extrainfo=0 */
 /* ===== */
@@ -648,13 +592,7 @@
 ,
 "212.47.233.250:9030 orport=9001 id=BF735F669481EE1CCC348F0731551C933D1E2278"
 " ipv6=[2001:bc8:4400:2b00::1c:629]:9001"
-/* nickname=FreewaySca */
-/* extrainfo=0 */
-/* ===== */
-,
-"192.160.102.169:80 orport=9001 id=C0192FF43E777250084175F4E59AC1BA2290CE38"
-" ipv6=[2620:132:300c:c01d::9]:9002"
-/* nickname=manipogo */
+/* nickname=freeway */
 /* extrainfo=0 */
 /* ===== */
 ,
@@ -663,8 +601,9 @@
 /* extrainfo=0 */
 /* ===== */
 ,
-"31.185.104.21:80 orport=443 id=C2AAB088555850FC434E68943F551072042B85F1"
-/* nickname=Digitalcourage3ip3 */
+"109.70.100.3:80 orport=443 id=C282248597D1C8522A2A7525E61C8B77BBC37614"
+" ipv6=[2a03:e600:100::3]:443"
+/* nickname=erbse */
 /* extrainfo=0 */
 /* ===== */
 ,
@@ -674,15 +613,25 @@
 /* extrainfo=0 */
 /* ===== */
 ,
+"188.138.112.60:1433 orport=1521 id=C414F28FD2BEC1553024299B31D4E726BEB8E788"
+/* nickname=zebra620 */
+/* extrainfo=0 */
+/* ===== */
+,
+"178.20.55.18:80 orport=443 id=C656B41AEFB40A141967EBF49D6E69603C9B4A11"
+/* nickname=marcuse2 */
+/* extrainfo=0 */
+/* ===== */
+,
 "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 */
+"50.7.74.173:80 orport=443 id=C87A4D8B534F78FDF0F4639B55F121401FEF259C"
+" ipv6=[2001:49f0:d002:2::54]:443"
+/* nickname=theia4 */
 /* extrainfo=0 */
 /* ===== */
 ,
@@ -691,8 +640,14 @@
 /* extrainfo=0 */
 /* ===== */
 ,
-"51.254.147.57:80 orport=443 id=D15AFF44BE641368B958A32FB6B071AC2136B8B1"
-/* nickname=Cosworth01 */
+"193.234.15.62:80 orport=443 id=CD0F9AA1A5064430B1DE8E645CBA7A502B27ED5F"
+" ipv6=[2a00:1c20:4089:1234:a6a4:2926:d0af:dfee]:443"
+/* nickname=jaures4 */
+/* extrainfo=0 */
+/* ===== */
+,
+"85.25.213.211:465 orport=80 id=CE47F0356D86CF0A1A2008D97623216D560FB0A8"
+/* nickname=BeastieJoy61 */
 /* extrainfo=0 */
 /* ===== */
 ,
@@ -702,9 +657,9 @@
 /* extrainfo=0 */
 /* ===== */
 ,
-"62.141.38.69:9030 orport=443 id=D379A1CB8285748FFF64AE94296CA89878F25B22"
-" ipv6=[2001:4ba0:cafe:ac5::1]:443"
-/* nickname=angeltest3 */
+"66.111.2.20:9030 orport=9001 id=D317C7889162E9EC4A1DA1A1095C2A0F377536D9"
+" ipv6=[2610:1c0:0:5::20]:9001"
+/* nickname=NYCBUG0 */
 /* extrainfo=0 */
 /* ===== */
 ,
@@ -714,25 +669,13 @@
 /* extrainfo=0 */
 /* ===== */
 ,
-"50.7.74.174:80 orport=443 id=D50101A2ABD09DC245F7E96C0818D003CDD62351"
-" ipv6=[2001:49f0:d002:2::56]:443"
-/* nickname=theia6 */
+"12.235.151.200:9030 orport=9029 id=D5C33F3E203728EDF8361EA868B2939CCC43FAFB"
+/* nickname=nx1tor */
 /* extrainfo=0 */
 /* ===== */
 ,
-"37.187.115.157:9030 orport=9001 id=D5039E1EBFD96D9A3F9846BF99EC9F75EDDE902A"
-/* nickname=Janky328891 */
-/* extrainfo=0 */
-/* ===== */
-,
-"85.10.201.47:9030 orport=9001 id=D8B7A3A6542AA54D0946B9DC0257C53B6C376679"
-" ipv6=[2a01:4f8:a0:43eb::beef]:9001"
-/* nickname=sif */
-/* extrainfo=0 */
-/* ===== */
-,
-"193.35.52.53:9030 orport=9001 id=DAA39FC00B196B353C2A271459C305C429AF09E4"
-/* nickname=Arne */
+"212.83.166.62:80 orport=443 id=D7082DB97E7F0481CBF4B88CA5F5683399E196A3"
+/* nickname=shhop */
 /* extrainfo=0 */
 /* ===== */
 ,
@@ -741,26 +684,15 @@
 /* extrainfo=0 */
 /* ===== */
 ,
-"176.158.236.102:9030 orport=9001 id=DC163DDEF4B6F0C6BC226F9F6656A5A30C5C5686"
-/* nickname=Underworld */
-/* extrainfo=0 */
-/* ===== */
-,
-"178.33.183.251:80 orport=443 id=DD823AFB415380A802DCAEB9461AE637604107FB"
-" ipv6=[2001:41d0:2:a683::251]:443"
-/* nickname=grenouille */
-/* extrainfo=0 */
-/* ===== */
-,
 "171.25.193.20:80 orport=443 id=DD8BD7307017407FCC36F8D04A688F74A0774C02"
 " ipv6=[2001:67c:289c::20]:443"
 /* nickname=DFRI0 */
 /* extrainfo=0 */
 /* ===== */
 ,
-"92.222.38.67:80 orport=443 id=DED6892FF89DBD737BA689698A171B2392EB3E82"
-" ipv6=[2001:41d0:52:100::112a]:443"
-/* 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 */
 /* ===== */
 ,
@@ -785,8 +717,13 @@
 /* extrainfo=0 */
 /* ===== */
 ,
-"131.188.40.188:1443 orport=80 id=EBE718E1A49EE229071702964F8DB1F318075FF8"
-" ipv6=[2001:638:a000:4140::ffff:188]:80"
+"195.154.105.170:9030 orport=9001 id=E947C029087FA1C3499BEF5D4372947C51223D8F"
+/* nickname=dgplug */
+/* extrainfo=0 */
+/* ===== */
+,
+"131.188.40.188:1443 orport=11180 id=EBE718E1A49EE229071702964F8DB1F318075FF8"
+" ipv6=[2001:638:a000:4140::ffff:188]:11180"
 /* nickname=fluxe4 */
 /* extrainfo=1 */
 /* ===== */
@@ -797,9 +734,8 @@
 /* extrainfo=0 */
 /* ===== */
 ,
-"37.252.187.111:9030 orport=443 id=EE4AF632058F0734C1426B1AD689F47445CA2056"
-" ipv6=[2a00:63c1:c:111::2]:443"
-/* nickname=angeltest7 */
+"178.20.55.16:80 orport=443 id=EFAE44728264982224445E96214C15F9075DEE1D"
+/* nickname=marcuse1 */
 /* extrainfo=0 */
 /* ===== */
 ,
@@ -808,8 +744,15 @@
 /* extrainfo=0 */
 /* ===== */
 ,
-"193.70.112.165:80 orport=443 id=F10BDE279AE71515DDCCCC61DC19AC8765F8A3CC"
-/* nickname=ParkBenchInd001 */
+"193.234.15.58:80 orport=443 id=F24F8BEA2779A79111F33F6832B062BED306B9CB"
+" ipv6=[2a00:1c20:4089:1234:cdae:1b3e:cc38:3d45]:443"
+/* nickname=jaures2 */
+/* 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 */
 /* ===== */
 ,
@@ -824,9 +767,9 @@
 /* extrainfo=0 */
 /* ===== */
 ,
-"192.160.102.168:80 orport=9001 id=F6A358DD367B3282D6EF5824C9D45E1A19C7E815"
-" ipv6=[2620:132:300c:c01d::8]:9002"
-/* nickname=prawksi */
+"163.172.154.162:9030 orport=9001 id=F741E5124CB12700DA946B78C9B2DD175D6CD2A1"
+" ipv6=[2001:bc8:47a0:162a::1]:9001"
+/* nickname=rofltor06 */
 /* extrainfo=0 */
 /* ===== */
 ,
@@ -836,10 +779,9 @@
 /* extrainfo=1 */
 /* ===== */
 ,
-"185.96.180.29:80 orport=443 id=F93D8F37E35C390BCAD9F9069E13085B745EC216"
-" ipv6=[2a00:4820::185:96:180:29]:443"
-/* nickname=TykRelay06 */
-/* extrainfo=0 */
+"91.143.88.62:80 orport=443 id=F9246DEF2B653807236DA134F2AEAB103D58ABFE"
+/* nickname=Freebird31 */
+/* extrainfo=1 */
 /* ===== */
 ,
 "149.56.45.200:9030 orport=9001 id=FE296180018833AF03A8EACD5894A614623D3F76"
@@ -848,6 +790,12 @@
 /* extrainfo=0 */
 /* ===== */
 ,
+"62.141.38.69:80 orport=443 id=FF9FC6D130FA26AE3AE8B23688691DC419F0F22E"
+" ipv6=[2001:4ba0:cafe:ac5::]:443"
+/* nickname=rinderwahnRelay3L */
+/* extrainfo=0 */
+/* ===== */
+,
 "193.11.164.243:9030 orport=9001 id=FFA72BD683BC2FCF988356E6BEC1E490F313FB07"
 " ipv6=[2001:6b0:7:125::243]:9001"
 /* nickname=Lule */
diff -Nur tor-0.3.5.10/src/core/mainloop/connection.c tor-0.3.5.12/src/core/mainloop/connection.c
--- tor-0.3.5.10/src/core/mainloop/connection.c	2019-12-05 17:54:24.000000000 +0100
+++ tor-0.3.5.12/src/core/mainloop/connection.c	2020-10-07 14:26:04.000000000 +0200
@@ -379,8 +379,12 @@
 
   connection_or_set_canonical(or_conn, 0);
 
-  if (type == CONN_TYPE_EXT_OR)
+  if (type == CONN_TYPE_EXT_OR) {
+    /* If we aren't told an address for this connection, we should
+     * presume it isn't local, and should be rate-limited. */
+    TO_CONN(or_conn)->always_rate_limit_as_remote = 1;
     connection_or_set_ext_or_identifier(or_conn);
+  }
 
   return or_conn;
 }
@@ -2923,7 +2927,14 @@
                                                   &skip, &addr_in_use);
     }
 
-    tor_assert(new_conn);
+    /* There are many reasons why we can't open a new listener port so in case
+     * we hit those, bail early so tor can stop. */
+    if (!new_conn) {
+      log_warn(LD_NET, "Unable to create listener port: %s:%d",
+               fmt_addr(&r->new_port->addr), r->new_port->port);
+      retval = -1;
+      break;
+    }
 
     smartlist_add(new_conns, new_conn);
 
@@ -3025,6 +3036,7 @@
   if (conn->linked)
     return 0; /* Internal connection */
   else if (! options->CountPrivateBandwidth &&
+           ! conn->always_rate_limit_as_remote &&
            (tor_addr_family(&conn->addr) == AF_UNSPEC || /* no address */
             tor_addr_family(&conn->addr) == AF_UNIX ||   /* no address */
             tor_addr_is_internal(&conn->addr, 0)))
diff -Nur tor-0.3.5.10/src/core/or/channel.c tor-0.3.5.12/src/core/or/channel.c
--- tor-0.3.5.10/src/core/or/channel.c	2019-10-11 23:48:21.000000000 +0200
+++ tor-0.3.5.12/src/core/or/channel.c	2020-11-09 22:13:42.000000000 +0100
@@ -72,6 +72,7 @@
 #include "core/or/relay.h"
 #include "core/or/scheduler.h"
 #include "feature/client/entrynodes.h"
+#include "feature/nodelist/dirlist.h"
 #include "feature/nodelist/networkstatus.h"
 #include "feature/nodelist/nodelist.h"
 #include "feature/nodelist/routerlist.h"
@@ -663,7 +664,7 @@
 
 /** Return true iff <b>chan</b> matches <b>rsa_id_digest</b> and <b>ed_id</b>.
  * as its identity keys.  If either is NULL, do not check for a match. */
-static int
+int
 channel_remote_identity_matches(const channel_t *chan,
                                 const char *rsa_id_digest,
                                 const ed25519_public_key_t *ed_id)
@@ -749,6 +750,7 @@
 {
   channel_idmap_entry_t **iter;
   channel_t *chan;
+  int total_dirauth_connections = 0, total_dirauths = 0;
   int total_relay_connections = 0, total_relays = 0, total_canonical = 0;
   int total_half_canonical = 0;
   int total_gt_one_connection = 0, total_gt_two_connections = 0;
@@ -756,13 +758,18 @@
 
   HT_FOREACH(iter, channel_idmap, &channel_identity_map) {
     int connections_to_relay = 0;
+    const char *id_digest = (char *) (*iter)->digest;
 
     /* Only consider relay connections */
-    if (!connection_or_digest_is_known_relay((char*)(*iter)->digest))
+    if (!connection_or_digest_is_known_relay(id_digest))
       continue;
 
     total_relays++;
 
+    const bool is_dirauth = router_digest_is_trusted_dir(id_digest);
+    if (is_dirauth)
+      total_dirauths++;
+
     for (chan = TOR_LIST_FIRST(&(*iter)->channel_list); chan;
         chan = channel_next_with_rsa_identity(chan)) {
 
@@ -771,11 +778,12 @@
 
       connections_to_relay++;
       total_relay_connections++;
+      if (is_dirauth)
+        total_dirauth_connections++;
 
-      if (chan->is_canonical(chan, 0)) total_canonical++;
+      if (chan->is_canonical(chan)) total_canonical++;
 
-      if (!chan->is_canonical_to_peer && chan->is_canonical(chan, 0)
-          && chan->is_canonical(chan, 1)) {
+      if (!chan->is_canonical_to_peer && chan->is_canonical(chan)) {
         total_half_canonical++;
       }
     }
@@ -785,11 +793,28 @@
     if (connections_to_relay > 4) total_gt_four_connections++;
   }
 
-#define MIN_RELAY_CONNECTIONS_TO_WARN 5
+  /* Don't bother warning about excessive connections unless we have
+   * at least this many connections, total.
+   */
+#define MIN_RELAY_CONNECTIONS_TO_WARN 25
+  /* If the average number of connections for a regular relay is more than
+   * this, that's too high.
+   */
+#define MAX_AVG_RELAY_CONNECTIONS 1.5
+  /* If the average number of connections for a dirauth is more than
+   * this, that's too high.
+   */
+#define MAX_AVG_DIRAUTH_CONNECTIONS 4
+
+  /* How many connections total would be okay, given the number of
+   * relays and dirauths that we have connections to? */
+  const int max_tolerable_connections = (int)(
+    (total_relays-total_dirauths) * MAX_AVG_RELAY_CONNECTIONS +
+    total_dirauths * MAX_AVG_DIRAUTH_CONNECTIONS);
 
   /* If we average 1.5 or more connections per relay, something is wrong */
   if (total_relays > MIN_RELAY_CONNECTIONS_TO_WARN &&
-          total_relay_connections >= 1.5*total_relays) {
+      total_relay_connections > max_tolerable_connections) {
     log_notice(LD_OR,
         "Your relay has a very large number of connections to other relays. "
         "Is your outbound address the same as your relay address? "
@@ -1871,7 +1896,7 @@
         tor_free(transport_name);
         /* Notify the DoS subsystem of a new client. */
         if (tlschan && tlschan->conn) {
-          dos_new_client_conn(tlschan->conn);
+          dos_new_client_conn(tlschan->conn, transport_name);
         }
       }
       /* Otherwise the underlying transport can't tell us this, so skip it */
@@ -2431,21 +2456,9 @@
       continue;
     }
 
-    /* Never return a non-canonical connection using a recent link protocol
-     * if the address is not what we wanted.
-     *
-     * The channel_is_canonical_is_reliable() function asks the lower layer
-     * if we should trust channel_is_canonical().  The below is from the
-     * comments of the old circuit_or_get_for_extend() and applies when
-     * the lower-layer transport is channel_tls_t.
-     *
-     * (For old link protocols, we can't rely on is_canonical getting
-     * set properly if we're talking to the right address, since we might
-     * have an out-of-date descriptor, and we will get no NETINFO cell to
-     * tell us about the right address.)
-     */
+    /* Only return canonical connections or connections where the address
+     * is the address we wanted. */
     if (!channel_is_canonical(chan) &&
-         channel_is_canonical_is_reliable(chan) &&
         !channel_matches_target_addr_for_extend(chan, target_addr)) {
       ++n_noncanonical;
       continue;
@@ -2587,16 +2600,12 @@
 
   /* Handle marks */
   tor_log(severity, LD_GENERAL,
-      " * Channel %"PRIu64 " has these marks: %s %s %s "
-      "%s %s %s",
+      " * Channel %"PRIu64 " has these marks: %s %s %s %s %s",
       (chan->global_identifier),
       channel_is_bad_for_new_circs(chan) ?
         "bad_for_new_circs" : "!bad_for_new_circs",
       channel_is_canonical(chan) ?
         "canonical" : "!canonical",
-      channel_is_canonical_is_reliable(chan) ?
-        "is_canonical_is_reliable" :
-        "!is_canonical_is_reliable",
       channel_is_client(chan) ?
         "client" : "!client",
       channel_is_local(chan) ?
@@ -2955,22 +2964,7 @@
   tor_assert(chan);
   tor_assert(chan->is_canonical);
 
-  return chan->is_canonical(chan, 0);
-}
-
-/**
- * Test if the canonical flag is reliable.
- *
- * This function asks if the lower layer thinks it's safe to trust the
- * result of channel_is_canonical().
- */
-int
-channel_is_canonical_is_reliable(channel_t *chan)
-{
-  tor_assert(chan);
-  tor_assert(chan->is_canonical);
-
-  return chan->is_canonical(chan, 1);
+  return chan->is_canonical(chan);
 }
 
 /**
diff -Nur tor-0.3.5.10/src/core/or/channel.h tor-0.3.5.12/src/core/or/channel.h
--- tor-0.3.5.10/src/core/or/channel.h	2019-10-11 23:48:21.000000000 +0200
+++ tor-0.3.5.12/src/core/or/channel.h	2020-11-09 22:13:42.000000000 +0100
@@ -351,12 +351,10 @@
   /** Check if the lower layer has queued writes */
   int (*has_queued_writes)(channel_t *);
   /**
-   * If the second param is zero, ask the lower layer if this is
-   * 'canonical', for a transport-specific definition of canonical; if
-   * it is 1, ask if the answer to the preceding query is safe to rely
-   * on.
+   * Ask the lower layer if this is 'canonical', for a transport-specific
+   * definition of canonical.
    */
-  int (*is_canonical)(channel_t *, int);
+  int (*is_canonical)(channel_t *);
   /** Check if this channel matches a specified extend_info_t */
   int (*matches_extend_info)(channel_t *, extend_info_t *);
   /** Check if this channel matches a target address when extending */
@@ -733,7 +731,6 @@
 int channel_is_bad_for_new_circs(channel_t *chan);
 void channel_mark_bad_for_new_circs(channel_t *chan);
 int channel_is_canonical(channel_t *chan);
-int channel_is_canonical_is_reliable(channel_t *chan);
 int channel_is_client(const channel_t *chan);
 int channel_is_local(channel_t *chan);
 int channel_is_incoming(channel_t *chan);
@@ -741,6 +738,9 @@
 void channel_mark_client(channel_t *chan);
 void channel_clear_client(channel_t *chan);
 int channel_matches_extend_info(channel_t *chan, extend_info_t *extend_info);
+int channel_remote_identity_matches(const channel_t *chan,
+                                    const char *rsa_id_digest,
+                                    const ed25519_public_key_t *ed_id);
 int channel_matches_target_addr_for_extend(channel_t *chan,
                                            const tor_addr_t *target);
 unsigned int channel_num_circuits(channel_t *chan);
diff -Nur tor-0.3.5.10/src/core/or/channeltls.c tor-0.3.5.12/src/core/or/channeltls.c
--- tor-0.3.5.10/src/core/or/channeltls.c	2019-11-06 14:22:43.000000000 +0100
+++ tor-0.3.5.12/src/core/or/channeltls.c	2020-10-07 14:05:40.000000000 +0200
@@ -106,7 +106,7 @@
 static const char *
 channel_tls_get_remote_descr_method(channel_t *chan, int flags);
 static int channel_tls_has_queued_writes_method(channel_t *chan);
-static int channel_tls_is_canonical_method(channel_t *chan, int req);
+static int channel_tls_is_canonical_method(channel_t *chan);
 static int
 channel_tls_matches_extend_info_method(channel_t *chan,
                                        extend_info_t *extend_info);
@@ -643,12 +643,11 @@
 /**
  * Tell the upper layer if we're canonical.
  *
- * This implements the is_canonical method for channel_tls_t; if req is zero,
- * it returns whether this is a canonical channel, and if it is one it returns
- * whether that can be relied upon.
+ * This implements the is_canonical method for channel_tls_t:
+ * it returns whether this is a canonical channel.
  */
 static int
-channel_tls_is_canonical_method(channel_t *chan, int req)
+channel_tls_is_canonical_method(channel_t *chan)
 {
   int answer = 0;
   channel_tls_t *tlschan = BASE_CHAN_TO_TLS(chan);
@@ -656,24 +655,13 @@
   tor_assert(tlschan);
 
   if (tlschan->conn) {
-    switch (req) {
-      case 0:
-        answer = tlschan->conn->is_canonical;
-        break;
-      case 1:
-        /*
-         * Is the is_canonical bit reliable?  In protocols version 2 and up
-         * we get the canonical address from a NETINFO cell, but in older
-         * versions it might be based on an obsolete descriptor.
-         */
-        answer = (tlschan->conn->link_proto >= 2);
-        break;
-      default:
-        /* This shouldn't happen; channel.c is broken if it does */
-        tor_assert_nonfatal_unreached_once();
-    }
+    /* If this bit is set to 0, and link_proto is sufficiently old, then we
+     * can't actually _rely_ on this being a non-canonical channel.
+     * Nonetheless, we're going to believe that this is a non-canonical
+     * channel in this case, since nobody should be using these link protocols
+     * any more. */
+    answer = tlschan->conn->is_canonical;
   }
-  /* else return 0 for tlschan->conn == NULL */
 
   return answer;
 }
@@ -1238,7 +1226,7 @@
       /* But that should be happening any longer've disabled bufferevents. */
       tor_assert_nonfatal_unreached_once();
 
-      /* fall through */
+      FALLTHROUGH;
     case OR_CONN_STATE_TLS_SERVER_RENEGOTIATING:
       if (!(command_allowed_before_handshake(var_cell->command))) {
         log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL,
diff -Nur tor-0.3.5.10/src/core/or/circuitbuild.c tor-0.3.5.12/src/core/or/circuitbuild.c
--- tor-0.3.5.10/src/core/or/circuitbuild.c	2019-10-11 23:48:21.000000000 +0200
+++ tor-0.3.5.12/src/core/or/circuitbuild.c	2020-11-09 22:13:42.000000000 +0100
@@ -623,21 +623,37 @@
           circ->state != CIRCUIT_STATE_CHAN_WAIT)
         continue;
 
-      if (tor_digest_is_zero(circ->n_hop->identity_digest)) {
+      const char *rsa_ident = NULL;
+      const ed25519_public_key_t *ed_ident = NULL;
+      if (! tor_digest_is_zero(circ->n_hop->identity_digest)) {
+        rsa_ident = circ->n_hop->identity_digest;
+      }
+      if (! ed25519_public_key_is_zero(&circ->n_hop->ed_identity)) {
+        ed_ident = &circ->n_hop->ed_identity;
+      }
+
+      if (rsa_ident == NULL && ed_ident == NULL) {
         /* Look at addr/port. This is an unkeyed connection. */
         if (!channel_matches_extend_info(chan, circ->n_hop))
           continue;
       } else {
-        /* We expected a key. See if it's the right one. */
-        if (tor_memneq(chan->identity_digest,
-                   circ->n_hop->identity_digest, DIGEST_LEN))
+        /* We expected a key or keys. See if they matched. */
+        if (!channel_remote_identity_matches(chan, rsa_ident, ed_ident))
+          continue;
+
+        /* If the channel is canonical, great.  If not, it needs to match
+         * the requested address exactly. */
+        if (! chan->is_canonical &&
+            ! channel_matches_extend_info(chan, circ->n_hop)) {
           continue;
+        }
       }
       if (!status) { /* chan failed; close circ */
         log_info(LD_CIRC,"Channel failed; closing circ.");
         circuit_mark_for_close(circ, END_CIRC_REASON_CHANNEL_CLOSED);
         continue;
       }
+
       if (close_origin_circuits && CIRCUIT_IS_ORIGIN(circ)) {
         log_info(LD_CIRC,"Channel deprecated for origin circs; closing circ.");
         circuit_mark_for_close(circ, END_CIRC_REASON_CHANNEL_CLOSED);
@@ -707,6 +723,8 @@
     goto error;
   }
 
+  tor_assert_nonfatal_once(circ->n_chan->is_canonical);
+
   memset(&cell, 0, sizeof(cell_t));
   r = relayed ? create_cell_format_relayed(&cell, create_cell)
               : create_cell_format(&cell, create_cell);
@@ -2106,7 +2124,7 @@
       /* For these three, we want to pick the exit like a middle hop,
        * since it should be random. */
       tor_assert_nonfatal(is_internal);
-      /* Falls through */
+      FALLTHROUGH;
     case CIRCUIT_PURPOSE_C_GENERAL:
       if (is_internal) /* pick it like a middle hop */
         return router_choose_random_node(NULL, options->ExcludeNodes, flags);
diff -Nur tor-0.3.5.10/src/core/or/circuitlist.c tor-0.3.5.12/src/core/or/circuitlist.c
--- tor-0.3.5.10/src/core/or/circuitlist.c	2019-10-11 23:48:21.000000000 +0200
+++ tor-0.3.5.12/src/core/or/circuitlist.c	2020-06-30 16:27:01.000000000 +0200
@@ -787,7 +787,7 @@
              "Unrecognized circuit purpose: %d",
              (int)purpose);
       tor_fragile_assert();
-      /* fall through */
+      FALLTHROUGH;
 
     case CIRCUIT_PURPOSE_OR:
     case CIRCUIT_PURPOSE_C_GENERAL:
@@ -1883,7 +1883,7 @@
       }
 
       /* Ignore any circuits for which we can't use the Guard. It is possible
-       * that the Guard was removed from the samepled set after the circuit
+       * that the Guard was removed from the sampled set after the circuit
        * was created so avoid using it. */
       if (!entry_guard_could_succeed(circ->guard_state)) {
         goto next;
@@ -2738,7 +2738,7 @@
     {
     case CPATH_STATE_OPEN:
       relay_crypto_assert_ok(&cp->crypto);
-      /* fall through */
+      FALLTHROUGH;
     case CPATH_STATE_CLOSED:
       /*XXXX Assert that there's no handshake_state either. */
       tor_assert(!cp->rend_dh_handshake_state);
diff -Nur tor-0.3.5.10/src/core/or/circuituse.c tor-0.3.5.12/src/core/or/circuituse.c
--- tor-0.3.5.10/src/core/or/circuituse.c	2019-10-11 23:48:21.000000000 +0200
+++ tor-0.3.5.12/src/core/or/circuituse.c	2020-05-06 22:58:12.000000000 +0200
@@ -780,7 +780,7 @@
             TO_ORIGIN_CIRCUIT(victim)->build_state->pending_final_cpath ==
             NULL)
           break;
-        /* fallthrough! */
+        FALLTHROUGH;
       case CIRCUIT_PURPOSE_C_INTRODUCE_ACK_WAIT:
       case CIRCUIT_PURPOSE_C_REND_READY_INTRO_ACKED:
         /* If we have reached this line, we want to spare the circ for now. */
diff -Nur tor-0.3.5.10/src/core/or/connection_edge.c tor-0.3.5.12/src/core/or/connection_edge.c
--- tor-0.3.5.10/src/core/or/connection_edge.c	2019-11-06 14:22:43.000000000 +0100
+++ tor-0.3.5.12/src/core/or/connection_edge.c	2020-05-06 22:58:12.000000000 +0200
@@ -324,7 +324,7 @@
       }
       /* Fall through if the connection is on a circuit without optimistic
        * data support. */
-      /* Falls through. */
+      FALLTHROUGH;
     case EXIT_CONN_STATE_CONNECTING:
     case AP_CONN_STATE_RENDDESC_WAIT:
     case AP_CONN_STATE_CIRCUIT_WAIT:
diff -Nur tor-0.3.5.10/src/core/or/connection_st.h tor-0.3.5.12/src/core/or/connection_st.h
--- tor-0.3.5.10/src/core/or/connection_st.h	2019-10-11 23:48:21.000000000 +0200
+++ tor-0.3.5.12/src/core/or/connection_st.h	2020-10-07 14:26:04.000000000 +0200
@@ -64,6 +64,9 @@
   /** True if connection_handle_write is currently running on this connection.
    */
   unsigned int in_connection_handle_write:1;
+  /** If true, then we treat this connection as remote for the purpose of
+   * rate-limiting, no matter what its address is. */
+  unsigned int always_rate_limit_as_remote:1;
 
   /* For linked connections:
    */
diff -Nur tor-0.3.5.10/src/core/or/dos.c tor-0.3.5.12/src/core/or/dos.c
--- tor-0.3.5.10/src/core/or/dos.c	2019-10-11 23:48:21.000000000 +0200
+++ tor-0.3.5.12/src/core/or/dos.c	2020-04-09 14:18:54.000000000 +0200
@@ -671,7 +671,7 @@
 /* Called when a new client connection has been established on the given
  * address. */
 void
-dos_new_client_conn(or_connection_t *or_conn)
+dos_new_client_conn(or_connection_t *or_conn, const char *transport_name)
 {
   clientmap_entry_t *entry;
 
@@ -692,7 +692,7 @@
   }
 
   /* We are only interested in client connection from the geoip cache. */
-  entry = geoip_lookup_client(&or_conn->real_addr, NULL,
+  entry = geoip_lookup_client(&or_conn->real_addr, transport_name,
                               GEOIP_CLIENT_CONNECT);
   if (BUG(entry == NULL)) {
     /* Should never happen because we note down the address in the geoip
diff -Nur tor-0.3.5.10/src/core/or/dos.h tor-0.3.5.12/src/core/or/dos.h
--- tor-0.3.5.10/src/core/or/dos.h	2019-10-11 23:48:21.000000000 +0200
+++ tor-0.3.5.12/src/core/or/dos.h	2020-04-09 14:18:54.000000000 +0200
@@ -53,7 +53,8 @@
 void dos_log_heartbeat(void);
 void dos_geoip_entry_about_to_free(const struct clientmap_entry_t *geoip_ent);
 
-void dos_new_client_conn(or_connection_t *or_conn);
+void dos_new_client_conn(or_connection_t *or_conn,
+                         const char *transport_name);
 void dos_close_client_conn(const or_connection_t *or_conn);
 
 int dos_should_refuse_single_hop_client(void);
diff -Nur tor-0.3.5.10/src/core/or/onion.c tor-0.3.5.12/src/core/or/onion.c
--- tor-0.3.5.10/src/core/or/onion.c	2019-10-11 23:48:21.000000000 +0200
+++ tor-0.3.5.12/src/core/or/onion.c	2020-05-06 22:58:12.000000000 +0200
@@ -509,7 +509,7 @@
       p += 16;
       space -= 16;
     }
-    /* Fall through */
+    FALLTHROUGH;
   case CELL_CREATE_FAST:
     tor_assert(cell_in->handshake_len <= space);
     memcpy(p, cell_in->onionskin, cell_in->handshake_len);
diff -Nur tor-0.3.5.10/src/core/or/protover.c tor-0.3.5.12/src/core/or/protover.c
--- tor-0.3.5.10/src/core/or/protover.c	2019-10-11 23:48:21.000000000 +0200
+++ tor-0.3.5.12/src/core/or/protover.c	2020-11-09 14:55:53.000000000 +0100
@@ -113,13 +113,13 @@
 }
 
 /** The largest possible protocol version. */
-#define MAX_PROTOCOL_VERSION (UINT32_MAX-1)
+#define MAX_PROTOCOL_VERSION (63)
 
 /**
  * Given a string <b>s</b> and optional end-of-string pointer
  * <b>end_of_range</b>, parse the protocol range and store it in
  * <b>low_out</b> and <b>high_out</b>.  A protocol range has the format U, or
- * U-U, where U is an unsigned 32-bit integer.
+ * U-U, where U is an unsigned integer between 0 and 63 inclusive.
  */
 static int
 parse_version_range(const char *s, const char *end_of_range,
diff -Nur tor-0.3.5.10/src/core/or/reasons.c tor-0.3.5.12/src/core/or/reasons.c
--- tor-0.3.5.10/src/core/or/reasons.c	2019-10-11 23:48:21.000000000 +0200
+++ tor-0.3.5.12/src/core/or/reasons.c	2020-05-06 22:58:12.000000000 +0200
@@ -489,7 +489,7 @@
       return "HTTP/1.0 502 Bad Gateway (tor protocol violation)\r\n\r\n";
     case END_STREAM_REASON_ENTRYPOLICY:
       return "HTTP/1.0 403 Forbidden (entry policy violation)\r\n\r\n";
-    case END_STREAM_REASON_NOTDIRECTORY: /* Fall Through */
+    case END_STREAM_REASON_NOTDIRECTORY: FALLTHROUGH;
     default:
       tor_assert_nonfatal_unreached();
       return "HTTP/1.0 500 Internal Server Error (weird end reason)\r\n\r\n";
diff -Nur tor-0.3.5.10/src/core/or/relay.c tor-0.3.5.12/src/core/or/relay.c
--- tor-0.3.5.10/src/core/or/relay.c	2019-10-11 23:48:21.000000000 +0200
+++ tor-0.3.5.12/src/core/or/relay.c	2020-05-06 22:58:12.000000000 +0200
@@ -866,7 +866,7 @@
           break; /* break means it'll close, below */
         /* Else fall through: expire this circuit, clear the
          * chosen_exit_name field, and try again. */
-        /* Falls through. */
+        FALLTHROUGH;
       case END_STREAM_REASON_RESOLVEFAILED:
       case END_STREAM_REASON_TIMEOUT:
       case END_STREAM_REASON_MISC:
diff -Nur tor-0.3.5.10/src/core/or/scheduler.c tor-0.3.5.12/src/core/or/scheduler.c
--- tor-0.3.5.10/src/core/or/scheduler.c	2019-10-11 23:48:21.000000000 +0200
+++ tor-0.3.5.12/src/core/or/scheduler.c	2020-05-06 22:58:12.000000000 +0200
@@ -192,7 +192,7 @@
   case SCHEDULER_KIST_LITE:
     return "KISTLite";
   case SCHEDULER_NONE:
-    /* fallthrough */
+    FALLTHROUGH;
   default:
     tor_assert_unreached();
     return "(N/A)";
@@ -288,7 +288,7 @@
       scheduler_kist_set_lite_mode();
       goto end;
     case SCHEDULER_NONE:
-      /* fallthrough */
+      FALLTHROUGH;
     default:
       /* Our option validation should have caught this. */
       tor_assert_unreached();
diff -Nur tor-0.3.5.10/src/core/proto/proto_socks.c tor-0.3.5.12/src/core/proto/proto_socks.c
--- tor-0.3.5.10/src/core/proto/proto_socks.c	2019-10-11 23:48:21.000000000 +0200
+++ tor-0.3.5.12/src/core/proto/proto_socks.c	2020-05-06 22:58:12.000000000 +0200
@@ -856,7 +856,7 @@
       case SOCKS_RESULT_TRUNCATED:
         if (datalen == n_pullup)
           return 0;
-        /* FALLTHRU */
+        FALLTHROUGH;
       case SOCKS_RESULT_MORE_EXPECTED:
         res = 0;
         break;
@@ -962,7 +962,7 @@
       strlcpy((char*)req->reply, SOCKS_PROXY_IS_NOT_AN_HTTP_PROXY_MSG,
               MAX_SOCKS_REPLY_LEN);
       req->replylen = strlen((char*)req->reply)+1;
-      /* fall through */
+      FALLTHROUGH;
     default: /* version is not socks4 or socks5 */
       log_warn(LD_APP,
                "Socks version %d not recognized. (This port is not an "
@@ -1067,7 +1067,10 @@
           log_info(LD_NET, "SOCKS 5 client: need authentication.");
           *drain_out = -1;
           return 2;
-        /* fall through */
+        default:
+          /* This wasn't supposed to be exhaustive; there are other
+           * authentication methods too. */
+          ;
       }
 
       *reason = tor_strdup("server doesn't support any of our available "
diff -Nur tor-0.3.5.10/src/ext/csiphash.c tor-0.3.5.12/src/ext/csiphash.c
--- tor-0.3.5.10/src/ext/csiphash.c	2019-10-11 23:48:21.000000000 +0200
+++ tor-0.3.5.12/src/ext/csiphash.c	2020-05-06 22:58:12.000000000 +0200
@@ -88,13 +88,13 @@
 	}
 
 	switch (src_sz - blocks) {
-		case 7: last7 |= (uint64_t)m[i + 6] << 48; /* Falls through. */
-		case 6: last7 |= (uint64_t)m[i + 5] << 40; /* Falls through. */
-		case 5:	last7 |= (uint64_t)m[i + 4] << 32; /* Falls through. */
-		case 4: last7 |= (uint64_t)m[i + 3] << 24; /* Falls through. */
-		case 3:	last7 |= (uint64_t)m[i + 2] << 16; /* Falls through. */
-		case 2:	last7 |= (uint64_t)m[i + 1] <<  8; /* Falls through. */
-		case 1: last7 |= (uint64_t)m[i + 0]      ; /* Falls through. */
+		case 7: last7 |= (uint64_t)m[i + 6] << 48; FALLTHROUGH;
+		case 6: last7 |= (uint64_t)m[i + 5] << 40; FALLTHROUGH;
+		case 5:	last7 |= (uint64_t)m[i + 4] << 32; FALLTHROUGH;
+		case 4: last7 |= (uint64_t)m[i + 3] << 24; FALLTHROUGH;
+		case 3:	last7 |= (uint64_t)m[i + 2] << 16; FALLTHROUGH;
+		case 2:	last7 |= (uint64_t)m[i + 1] <<  8; FALLTHROUGH;
+		case 1: last7 |= (uint64_t)m[i + 0]      ; FALLTHROUGH;
 		case 0:
 		default:;
 	}
diff -Nur tor-0.3.5.10/src/ext/ed25519/donna/ed25519_tor.c tor-0.3.5.12/src/ext/ed25519/donna/ed25519_tor.c
--- tor-0.3.5.10/src/ext/ed25519/donna/ed25519_tor.c	2019-10-11 23:48:21.000000000 +0200
+++ tor-0.3.5.12/src/ext/ed25519/donna/ed25519_tor.c	2020-05-06 22:47:03.000000000 +0200
@@ -35,6 +35,9 @@
 #define ED25519_FN(fn)         ED25519_FN2(fn,ED25519_SUFFIX)
 
 #include "orconfig.h"
+
+#include "lib/cc/compat_compiler.h"
+
 #include "ed25519-donna.h"
 #include "ed25519_donna_tor.h"
 #include "ed25519-randombytes.h"
@@ -366,4 +369,3 @@
 }
 
 #include "test-internals.c"
-
diff -Nur tor-0.3.5.10/src/ext/ed25519/donna/modm-donna-32bit.h tor-0.3.5.12/src/ext/ed25519/donna/modm-donna-32bit.h
--- tor-0.3.5.10/src/ext/ed25519/donna/modm-donna-32bit.h	2019-10-11 23:48:21.000000000 +0200
+++ tor-0.3.5.12/src/ext/ed25519/donna/modm-donna-32bit.h	2020-05-06 22:58:12.000000000 +0200
@@ -385,14 +385,14 @@
 	size_t i = 0;
 	bignum256modm_element_t carry = 0;
 	switch (limbsize) {
-		case 8: out[i] = (a[i] - b[i]) - carry; carry = (out[i] >> 31); out[i] &= 0x3fffffff; i++; /* Falls through. */
-		case 7: out[i] = (a[i] - b[i]) - carry; carry = (out[i] >> 31); out[i] &= 0x3fffffff; i++; /* Falls through. */
-		case 6: out[i] = (a[i] - b[i]) - carry; carry = (out[i] >> 31); out[i] &= 0x3fffffff; i++; /* Falls through. */
-		case 5: out[i] = (a[i] - b[i]) - carry; carry = (out[i] >> 31); out[i] &= 0x3fffffff; i++; /* Falls through. */
-		case 4: out[i] = (a[i] - b[i]) - carry; carry = (out[i] >> 31); out[i] &= 0x3fffffff; i++; /* Falls through. */
-		case 3: out[i] = (a[i] - b[i]) - carry; carry = (out[i] >> 31); out[i] &= 0x3fffffff; i++; /* Falls through. */
-		case 2: out[i] = (a[i] - b[i]) - carry; carry = (out[i] >> 31); out[i] &= 0x3fffffff; i++; /* Falls through. */
-		case 1: out[i] = (a[i] - b[i]) - carry; carry = (out[i] >> 31); out[i] &= 0x3fffffff; i++; /* Falls through. */
+		case 8: out[i] = (a[i] - b[i]) - carry; carry = (out[i] >> 31); out[i] &= 0x3fffffff; i++; FALLTHROUGH;
+		case 7: out[i] = (a[i] - b[i]) - carry; carry = (out[i] >> 31); out[i] &= 0x3fffffff; i++; FALLTHROUGH;
+		case 6: out[i] = (a[i] - b[i]) - carry; carry = (out[i] >> 31); out[i] &= 0x3fffffff; i++; FALLTHROUGH;
+		case 5: out[i] = (a[i] - b[i]) - carry; carry = (out[i] >> 31); out[i] &= 0x3fffffff; i++; FALLTHROUGH;
+		case 4: out[i] = (a[i] - b[i]) - carry; carry = (out[i] >> 31); out[i] &= 0x3fffffff; i++; FALLTHROUGH;
+		case 3: out[i] = (a[i] - b[i]) - carry; carry = (out[i] >> 31); out[i] &= 0x3fffffff; i++; FALLTHROUGH;
+		case 2: out[i] = (a[i] - b[i]) - carry; carry = (out[i] >> 31); out[i] &= 0x3fffffff; i++; FALLTHROUGH;
+		case 1: out[i] = (a[i] - b[i]) - carry; carry = (out[i] >> 31); out[i] &= 0x3fffffff; i++; FALLTHROUGH;
 		case 0: 
 		default: out[i] = (a[i] - b[i]) - carry;
 	}
@@ -403,14 +403,14 @@
 static int
 lt256_modm_batch(const bignum256modm a, const bignum256modm b, size_t limbsize) {
 	switch (limbsize) {
-		case 8: if (a[8] > b[8]) return 0; if (a[8] < b[8]) return 1; /* Falls through. */
-		case 7: if (a[7] > b[7]) return 0; if (a[7] < b[7]) return 1; /* Falls through. */
-		case 6: if (a[6] > b[6]) return 0; if (a[6] < b[6]) return 1; /* Falls through. */
-		case 5: if (a[5] > b[5]) return 0; if (a[5] < b[5]) return 1; /* Falls through. */
-		case 4: if (a[4] > b[4]) return 0; if (a[4] < b[4]) return 1; /* Falls through. */
-		case 3: if (a[3] > b[3]) return 0; if (a[3] < b[3]) return 1; /* Falls through. */
-		case 2: if (a[2] > b[2]) return 0; if (a[2] < b[2]) return 1; /* Falls through. */
-		case 1: if (a[1] > b[1]) return 0; if (a[1] < b[1]) return 1; /* Falls through. */
+		case 8: if (a[8] > b[8]) return 0; if (a[8] < b[8]) return 1; FALLTHROUGH;
+		case 7: if (a[7] > b[7]) return 0; if (a[7] < b[7]) return 1; FALLTHROUGH;
+		case 6: if (a[6] > b[6]) return 0; if (a[6] < b[6]) return 1; FALLTHROUGH;
+		case 5: if (a[5] > b[5]) return 0; if (a[5] < b[5]) return 1; FALLTHROUGH;
+		case 4: if (a[4] > b[4]) return 0; if (a[4] < b[4]) return 1; FALLTHROUGH;
+		case 3: if (a[3] > b[3]) return 0; if (a[3] < b[3]) return 1; FALLTHROUGH;
+		case 2: if (a[2] > b[2]) return 0; if (a[2] < b[2]) return 1; FALLTHROUGH;
+		case 1: if (a[1] > b[1]) return 0; if (a[1] < b[1]) return 1; FALLTHROUGH;
 		case 0: if (a[0] > b[0]) return 0; if (a[0] < b[0]) return 1;
 	}
 	return 0;
@@ -420,14 +420,14 @@
 static int
 lte256_modm_batch(const bignum256modm a, const bignum256modm b, size_t limbsize) {
 	switch (limbsize) {
-		case 8: if (a[8] > b[8]) return 0; if (a[8] < b[8]) return 1; /* Falls through. */
-		case 7: if (a[7] > b[7]) return 0; if (a[7] < b[7]) return 1; /* Falls through. */
-		case 6: if (a[6] > b[6]) return 0; if (a[6] < b[6]) return 1; /* Falls through. */
-		case 5: if (a[5] > b[5]) return 0; if (a[5] < b[5]) return 1; /* Falls through. */
-		case 4: if (a[4] > b[4]) return 0; if (a[4] < b[4]) return 1; /* Falls through. */
-		case 3: if (a[3] > b[3]) return 0; if (a[3] < b[3]) return 1; /* Falls through. */
-		case 2: if (a[2] > b[2]) return 0; if (a[2] < b[2]) return 1; /* Falls through. */
-		case 1: if (a[1] > b[1]) return 0; if (a[1] < b[1]) return 1; /* Falls through. */
+		case 8: if (a[8] > b[8]) return 0; if (a[8] < b[8]) return 1; FALLTHROUGH;
+		case 7: if (a[7] > b[7]) return 0; if (a[7] < b[7]) return 1; FALLTHROUGH;
+		case 6: if (a[6] > b[6]) return 0; if (a[6] < b[6]) return 1; FALLTHROUGH;
+		case 5: if (a[5] > b[5]) return 0; if (a[5] < b[5]) return 1; FALLTHROUGH;
+		case 4: if (a[4] > b[4]) return 0; if (a[4] < b[4]) return 1; FALLTHROUGH;
+		case 3: if (a[3] > b[3]) return 0; if (a[3] < b[3]) return 1; FALLTHROUGH;
+		case 2: if (a[2] > b[2]) return 0; if (a[2] < b[2]) return 1; FALLTHROUGH;
+		case 1: if (a[1] > b[1]) return 0; if (a[1] < b[1]) return 1; FALLTHROUGH;
 		case 0: if (a[0] > b[0]) return 0; if (a[0] < b[0]) return 1;
 	}
 	return 1;
diff -Nur tor-0.3.5.10/src/ext/ed25519/donna/modm-donna-64bit.h tor-0.3.5.12/src/ext/ed25519/donna/modm-donna-64bit.h
--- tor-0.3.5.10/src/ext/ed25519/donna/modm-donna-64bit.h	2019-10-11 23:48:21.000000000 +0200
+++ tor-0.3.5.12/src/ext/ed25519/donna/modm-donna-64bit.h	2020-05-06 22:58:12.000000000 +0200
@@ -294,10 +294,10 @@
 	size_t i = 0;
 	bignum256modm_element_t carry = 0;
 	switch (limbsize) {
-		case 4: out[i] = (a[i] - b[i])        ; carry = (out[i] >> 63); out[i] &= 0xffffffffffffff; i++; /* Falls through. */
-		case 3: out[i] = (a[i] - b[i]) - carry; carry = (out[i] >> 63); out[i] &= 0xffffffffffffff; i++; /* Falls through. */
-		case 2:	out[i] = (a[i] - b[i]) - carry; carry = (out[i] >> 63); out[i] &= 0xffffffffffffff; i++; /* Falls through. */
-		case 1:	out[i] = (a[i] - b[i]) - carry; carry = (out[i] >> 63); out[i] &= 0xffffffffffffff; i++; /* Falls through. */
+		case 4: out[i] = (a[i] - b[i])        ; carry = (out[i] >> 63); out[i] &= 0xffffffffffffff; i++; FALLTHROUGH;
+		case 3: out[i] = (a[i] - b[i]) - carry; carry = (out[i] >> 63); out[i] &= 0xffffffffffffff; i++; FALLTHROUGH;
+		case 2:	out[i] = (a[i] - b[i]) - carry; carry = (out[i] >> 63); out[i] &= 0xffffffffffffff; i++; FALLTHROUGH;
+		case 1:	out[i] = (a[i] - b[i]) - carry; carry = (out[i] >> 63); out[i] &= 0xffffffffffffff; i++; FALLTHROUGH;
 		case 0: 
 		default: out[i] = (a[i] - b[i]) - carry;
 	}
@@ -310,10 +310,10 @@
 	size_t i = 0;
 	bignum256modm_element_t t, carry = 0;
 	switch (limbsize) {
-		case 4: t = (a[i] - b[i])        ; carry = (t >> 63); i++; /* Falls through. */
-		case 3: t = (a[i] - b[i]) - carry; carry = (t >> 63); i++; /* Falls through. */
-		case 2: t = (a[i] - b[i]) - carry; carry = (t >> 63); i++; /* Falls through. */
-		case 1: t = (a[i] - b[i]) - carry; carry = (t >> 63); i++; /* Falls through. */
+		case 4: t = (a[i] - b[i])        ; carry = (t >> 63); i++; FALLTHROUGH;
+		case 3: t = (a[i] - b[i]) - carry; carry = (t >> 63); i++; FALLTHROUGH;
+		case 2: t = (a[i] - b[i]) - carry; carry = (t >> 63); i++; FALLTHROUGH;
+		case 1: t = (a[i] - b[i]) - carry; carry = (t >> 63); i++; FALLTHROUGH;
 		case 0: t = (a[i] - b[i]) - carry; carry = (t >> 63);
 	}
 	return (int)carry;
@@ -325,10 +325,10 @@
 	size_t i = 0;
 	bignum256modm_element_t t, carry = 0;
 	switch (limbsize) {
-		case 4: t = (b[i] - a[i])        ; carry = (t >> 63); i++; /* Falls through. */
-		case 3: t = (b[i] - a[i]) - carry; carry = (t >> 63); i++; /* Falls through. */
-		case 2: t = (b[i] - a[i]) - carry; carry = (t >> 63); i++; /* Falls through. */
-		case 1: t = (b[i] - a[i]) - carry; carry = (t >> 63); i++; /* Falls through. */
+		case 4: t = (b[i] - a[i])        ; carry = (t >> 63); i++; FALLTHROUGH;
+		case 3: t = (b[i] - a[i]) - carry; carry = (t >> 63); i++; FALLTHROUGH;
+		case 2: t = (b[i] - a[i]) - carry; carry = (t >> 63); i++; FALLTHROUGH;
+		case 1: t = (b[i] - a[i]) - carry; carry = (t >> 63); i++; FALLTHROUGH;
 		case 0: t = (b[i] - a[i]) - carry; carry = (t >> 63);
 	}
 	return (int)!carry;
diff -Nur tor-0.3.5.10/src/feature/client/entrynodes.c tor-0.3.5.12/src/feature/client/entrynodes.c
--- tor-0.3.5.10/src/feature/client/entrynodes.c	2019-10-11 23:48:21.000000000 +0200
+++ tor-0.3.5.12/src/feature/client/entrynodes.c	2020-06-30 16:27:01.000000000 +0200
@@ -2263,7 +2263,7 @@
       break;
     default:
       tor_assert_nonfatal_unreached();
-      /* Fall through. */
+      FALLTHROUGH;
     case GUARD_CIRC_STATE_USABLE_IF_NO_BETTER_GUARD:
       if (guard->is_primary) {
         /* XXXX #20832 -- I don't actually like this logic. It seems to make
@@ -3452,10 +3452,16 @@
   entry_guards_dirty = 0;
 }
 
-/** Return true iff the circuit's guard can succeed that is can be used. */
+/** Return true iff the circuit's guard can succeed, that is, can be used. */
 int
 entry_guard_could_succeed(const circuit_guard_state_t *guard_state)
 {
+  if (get_options()->UseEntryGuards == 0) {
+    /* we're fine with this circuit's first hop, because we're not
+     * configured to use entry guards. */
+    return 1;
+  }
+
   if (!guard_state) {
     return 0;
   }
diff -Nur tor-0.3.5.10/src/feature/control/control.c tor-0.3.5.12/src/feature/control/control.c
--- tor-0.3.5.10/src/feature/control/control.c	2019-10-11 23:48:21.000000000 +0200
+++ tor-0.3.5.12/src/feature/control/control.c	2020-05-06 22:58:12.000000000 +0200
@@ -4934,7 +4934,7 @@
   case RSAE_BADAUTH:
     connection_printf_to_buf(conn, "512 Invalid client authorization\r\n");
     break;
-  case RSAE_INTERNAL: /* FALLSTHROUGH */
+  case RSAE_INTERNAL: FALLTHROUGH;
   default:
     connection_printf_to_buf(conn, "551 Failed to add Onion Service\r\n");
   }
diff -Nur tor-0.3.5.10/src/feature/dirauth/keypin.c tor-0.3.5.12/src/feature/dirauth/keypin.c
--- tor-0.3.5.10/src/feature/dirauth/keypin.c	2019-10-11 23:48:21.000000000 +0200
+++ tor-0.3.5.12/src/feature/dirauth/keypin.c	2020-05-06 22:47:03.000000000 +0200
@@ -267,7 +267,7 @@
     }
     tor_free(ent2);
     r = -1;
-    /* Fall through */
+    /* Note lack of return here: we fall through to the next line. */
   }
 
   keypin_add_entry_to_map(ent);
diff -Nur tor-0.3.5.10/src/feature/dirclient/dirclient.c tor-0.3.5.12/src/feature/dirclient/dirclient.c
--- tor-0.3.5.10/src/feature/dirclient/dirclient.c	2019-10-11 23:48:21.000000000 +0200
+++ tor-0.3.5.12/src/feature/dirclient/dirclient.c	2020-05-06 22:58:12.000000000 +0200
@@ -1369,7 +1369,7 @@
       case 1:
         /* start flushing conn */
         conn->base_.state = DIR_CONN_STATE_CLIENT_SENDING;
-        /* fall through */
+        FALLTHROUGH;
       case 0:
         /* queue the command on the outbuf */
         directory_send_command(conn, 1, request);
diff -Nur tor-0.3.5.10/src/feature/dirparse/parsecommon.c tor-0.3.5.12/src/feature/dirparse/parsecommon.c
--- tor-0.3.5.10/src/feature/dirparse/parsecommon.c	2020-03-17 20:22:35.000000000 +0100
+++ tor-0.3.5.12/src/feature/dirparse/parsecommon.c	2020-05-06 22:58:12.000000000 +0200
@@ -222,7 +222,7 @@
                      kwd, crypto_pk_num_bits(tok->key));
         RET_ERR(ebuf);
       }
-      /* fall through */
+      FALLTHROUGH;
     case NEED_KEY: /* There must be some kind of key. */
       if (!tok->key) {
         tor_snprintf(ebuf, sizeof(ebuf), "Missing public key for %s", kwd);
diff -Nur tor-0.3.5.10/src/feature/hs/hs_client.c tor-0.3.5.12/src/feature/hs/hs_client.c
--- tor-0.3.5.10/src/feature/hs/hs_client.c	2020-03-17 16:45:16.000000000 +0100
+++ tor-0.3.5.12/src/feature/hs/hs_client.c	2020-06-29 18:55:35.000000000 +0200
@@ -596,9 +596,14 @@
   /* We need to find which intro point in the descriptor we are connected to
    * on intro_circ. */
   ip = find_desc_intro_point_by_ident(intro_circ->hs_ident, desc);
-  if (BUG(ip == NULL)) {
-    /* If we can find a descriptor from this introduction circuit ident, we
-     * must have a valid intro point object. Permanent error. */
+  if (ip == NULL) {
+    /* The following is possible if the descriptor was changed while we had
+     * this introduction circuit open and waiting for the rendezvous circuit to
+     * be ready. Which results in this situation where we can't find the
+     * corresponding intro point within the descriptor of the service. */
+    log_info(LD_REND, "Unable to find introduction point for service %s "
+                      "while trying to send an INTRODUCE1 cell.",
+             safe_str_client(onion_address));
     goto perm_err;
   }
 
diff -Nur tor-0.3.5.10/src/feature/hs_common/shared_random_client.c tor-0.3.5.12/src/feature/hs_common/shared_random_client.c
--- tor-0.3.5.10/src/feature/hs_common/shared_random_client.c	2019-10-11 23:48:21.000000000 +0200
+++ tor-0.3.5.12/src/feature/hs_common/shared_random_client.c	2020-09-28 16:34:04.000000000 +0200
@@ -255,10 +255,6 @@
      protocol run */
   time_t time_elapsed_since_start_of_run = curr_round_slot * voting_interval;
 
-  log_debug(LD_GENERAL, "Current SRV proto run: Start of current round: %u. "
-            "Time elapsed: %u (%d)", (unsigned) beginning_of_curr_round,
-            (unsigned) time_elapsed_since_start_of_run, voting_interval);
-
   return beginning_of_curr_round - time_elapsed_since_start_of_run;
 }
 
diff -Nur tor-0.3.5.10/src/feature/nodelist/node_select.c tor-0.3.5.12/src/feature/nodelist/node_select.c
--- tor-0.3.5.10/src/feature/nodelist/node_select.c	2019-10-11 23:48:21.000000000 +0200
+++ tor-0.3.5.12/src/feature/nodelist/node_select.c	2020-10-07 14:16:19.000000000 +0200
@@ -540,6 +540,51 @@
   return result;
 }
 
+/**
+ * We have found an instance of bug 32868: log our best guess about where the
+ * routerstatus was found.
+ **/
+static void
+log_buggy_rs_source(const routerstatus_t *rs)
+{
+  static ratelim_t buggy_rs_ratelim = RATELIM_INIT(1200);
+  char *m;
+  if ((m = rate_limit_log(&buggy_rs_ratelim, approx_time()))) {
+    log_warn(LD_BUG,
+             "Found a routerstatus %p with has_guardfraction=%u "
+             " and guardfraction_percentage=%u, but is_possible_guard=%u.%s",
+             rs,
+             rs->has_guardfraction,
+             rs->guardfraction_percentage,
+             rs->is_possible_guard,
+             m);
+    tor_free(m);
+    networkstatus_t *ns;
+    int in_ns_count = 0;
+    if ((ns = networkstatus_get_latest_consensus_by_flavor(FLAV_NS))) {
+      int pos = smartlist_pos(ns->routerstatus_list, rs);
+      if (pos >= 0) {
+        ++in_ns_count;
+        log_warn(LD_BUG, "Found the routerstatus at position %d of the "
+                 "NS consensus.", pos);
+      }
+    }
+    if ((ns = networkstatus_get_latest_consensus_by_flavor(FLAV_MICRODESC))) {
+      int pos = smartlist_pos(ns->routerstatus_list, rs);
+      if (pos >= 0) {
+        ++in_ns_count;
+        log_warn(LD_BUG, "Found the routerstatus at position %d of the "
+                 "MD consensus.", pos);
+      }
+    }
+    if (in_ns_count == 0) {
+      log_warn(LD_BUG, "Could not find the routerstatus in any "
+               "latest consensus.");
+    }
+    tor_assert_nonfatal_unreached();
+  }
+}
+
 /** Given a list of routers and a weighting rule as in
  * smartlist_choose_node_by_bandwidth_weights, compute weighted bandwidth
  * values for each node and store them in a freshly allocated
@@ -715,10 +760,11 @@
      *    choose N proportionally to F*Wpf*B + (1-F)*Wpn*B.
      */
     if (node->rs && node->rs->has_guardfraction && rule != WEIGHT_FOR_GUARD) {
-      /* XXX The assert should actually check for is_guard. However,
-       * that crashes dirauths because of #13297. This should be
-       * equivalent: */
-      tor_assert(node->rs->is_possible_guard);
+      /* We should only have guardfraction set if the node has the Guard
+         flag. */
+      if (! node->rs->is_possible_guard) {
+        log_buggy_rs_source(node->rs);
+      }
 
       guard_get_guardfraction_bandwidth(&guardfraction_bw,
                                         this_bw,
diff -Nur tor-0.3.5.10/src/feature/nodelist/routerlist.c tor-0.3.5.12/src/feature/nodelist/routerlist.c
--- tor-0.3.5.10/src/feature/nodelist/routerlist.c	2019-10-11 23:48:21.000000000 +0200
+++ tor-0.3.5.12/src/feature/nodelist/routerlist.c	2020-07-02 16:14:08.000000000 +0200
@@ -1087,7 +1087,11 @@
      * This just won't work. */;
     static ratelim_t no_sd_ratelim = RATELIM_INIT(1800);
     r = ROUTER_BAD_EI;
-    log_fn_ratelim(&no_sd_ratelim, severity, LD_BUG,
+    /* This is a DEBUG because it can happen naturally, if we tried
+     * to add an extrainfo for which we no longer have the
+     * corresponding routerinfo.
+     */
+    log_fn_ratelim(&no_sd_ratelim, LOG_DEBUG, LD_DIR,
                    "No entry found in extrainfo map.");
     goto done;
   }
diff -Nur tor-0.3.5.10/src/feature/relay/dns.c tor-0.3.5.12/src/feature/relay/dns.c
--- tor-0.3.5.10/src/feature/relay/dns.c	2019-10-11 23:48:21.000000000 +0200
+++ tor-0.3.5.12/src/feature/relay/dns.c	2020-05-06 22:58:12.000000000 +0200
@@ -546,9 +546,9 @@
         break;
       } else {
         answer_type = RESOLVED_TYPE_ERROR;
-        /* fall through. */
+        /* We let this fall through and treat it as an error. */
       }
-      /* Falls through. */
+      FALLTHROUGH;
     case RESOLVED_TYPE_ERROR_TRANSIENT:
     case RESOLVED_TYPE_ERROR:
       {
diff -Nur tor-0.3.5.10/src/feature/relay/ext_orport.c tor-0.3.5.12/src/feature/relay/ext_orport.c
--- tor-0.3.5.10/src/feature/relay/ext_orport.c	2019-10-11 23:48:21.000000000 +0200
+++ tor-0.3.5.12/src/feature/relay/ext_orport.c	2020-10-07 14:26:04.000000000 +0200
@@ -494,6 +494,10 @@
   }
   conn->address = tor_addr_to_str_dup(&addr);
 
+  /* Now that we know the address, we don't have to manually override rate
+   * limiting. */
+  conn->always_rate_limit_as_remote = 0;
+
   return 0;
 }
 
@@ -659,4 +663,3 @@
   if (ext_or_auth_cookie) /* Free the auth cookie */
     tor_free(ext_or_auth_cookie);
 }
-
diff -Nur tor-0.3.5.10/src/feature/relay/router.c tor-0.3.5.12/src/feature/relay/router.c
--- tor-0.3.5.10/src/feature/relay/router.c	2020-02-12 14:28:47.000000000 +0100
+++ tor-0.3.5.12/src/feature/relay/router.c	2020-10-07 15:29:17.000000000 +0200
@@ -1433,6 +1433,50 @@
   return port;
 }
 
+/** As router_get_advertised_or_port(), but returns the IPv6 address and
+ *  port in ipv6_ap_out, which must not be NULL. Returns a null address and
+ * zero port, if no ORPort is found. */
+void
+router_get_advertised_ipv6_or_ap(const or_options_t *options,
+                                 tor_addr_port_t *ipv6_ap_out)
+{
+  /* Bug in calling function, we can't return a sensible result, and it
+   * shouldn't use the NULL pointer once we return. */
+  tor_assert(ipv6_ap_out);
+
+  /* If there is no valid IPv6 ORPort, return a null address and port. */
+  tor_addr_make_null(&ipv6_ap_out->addr, AF_INET6);
+  ipv6_ap_out->port = 0;
+
+  const tor_addr_t *addr = get_first_advertised_addr_by_type_af(
+                                                      CONN_TYPE_OR_LISTENER,
+                                                      AF_INET6);
+  const uint16_t port = router_get_advertised_or_port_by_af(
+                                                      options,
+                                                      AF_INET6);
+
+  if (!addr || port == 0) {
+    log_info(LD_CONFIG, "There is no advertised IPv6 ORPort.");
+    return;
+  }
+
+  /* If the relay is configured using the default authorities, disallow
+   * internal IPs. Otherwise, allow them. For IPv4 ORPorts and DirPorts,
+   * this check is done in resolve_my_address(). See #33681. */
+  const int default_auth = using_default_dir_authorities(options);
+  if (tor_addr_is_internal(addr, 0) && default_auth) {
+    log_warn(LD_CONFIG,
+             "Unable to use configured IPv6 ORPort \"%s\" in a "
+             "descriptor. Skipping it. "
+             "Try specifying a globally reachable address explicitly.",
+             fmt_addrport(addr, port));
+    return;
+  }
+
+  tor_addr_copy(&ipv6_ap_out->addr, addr);
+  ipv6_ap_out->port = port;
+}
+
 /** Return the port that we should advertise as our DirPort;
  * this is one of three possibilities:
  * The one that is passed as <b>dirport</b> if the DirPort option is 0, or
@@ -1848,34 +1892,11 @@
                sizeof(curve25519_public_key_t));
 
   /* For now, at most one IPv6 or-address is being advertised. */
-  {
-    const port_cfg_t *ipv6_orport = NULL;
-    SMARTLIST_FOREACH_BEGIN(get_configured_ports(), const port_cfg_t *, p) {
-      if (p->type == CONN_TYPE_OR_LISTENER &&
-          ! p->server_cfg.no_advertise &&
-          ! p->server_cfg.bind_ipv4_only &&
-          tor_addr_family(&p->addr) == AF_INET6) {
-        /* Like IPv4, if the relay is configured using the default
-         * authorities, disallow internal IPs. Otherwise, allow them. */
-        const int default_auth = using_default_dir_authorities(options);
-        if (! tor_addr_is_internal(&p->addr, 0) || ! default_auth) {
-          ipv6_orport = p;
-          break;
-        } else {
-          char addrbuf[TOR_ADDR_BUF_LEN];
-          log_warn(LD_CONFIG,
-                   "Unable to use configured IPv6 address \"%s\" in a "
-                   "descriptor. Skipping it. "
-                   "Try specifying a globally reachable address explicitly.",
-                   tor_addr_to_str(addrbuf, &p->addr, sizeof(addrbuf), 1));
-        }
-      }
-    } SMARTLIST_FOREACH_END(p);
-    if (ipv6_orport) {
-      tor_addr_copy(&ri->ipv6_addr, &ipv6_orport->addr);
-      ri->ipv6_orport = ipv6_orport->port;
-    }
-  }
+  tor_addr_port_t ipv6_orport;
+  router_get_advertised_ipv6_or_ap(options, &ipv6_orport);
+  /* If there is no valud IPv6 ORPort, the address and port are null. */
+  tor_addr_copy(&ri->ipv6_addr, &ipv6_orport.addr);
+  ri->ipv6_orport = ipv6_orport.port;
 
   ri->identity_pkey = crypto_pk_dup_key(get_server_identity_key());
   if (BUG(crypto_pk_get_digest(ri->identity_pkey,
diff -Nur tor-0.3.5.10/src/feature/relay/router.h tor-0.3.5.12/src/feature/relay/router.h
--- tor-0.3.5.10/src/feature/relay/router.h	2019-10-11 23:48:21.000000000 +0200
+++ tor-0.3.5.12/src/feature/relay/router.h	2020-10-07 15:29:17.000000000 +0200
@@ -59,6 +59,8 @@
 uint16_t router_get_active_listener_port_by_type_af(int listener_type,
                                                     sa_family_t family);
 uint16_t router_get_advertised_or_port(const or_options_t *options);
+void router_get_advertised_ipv6_or_ap(const or_options_t *options,
+                                      tor_addr_port_t *ipv6_ap_out);
 uint16_t router_get_advertised_or_port_by_af(const or_options_t *options,
                                              sa_family_t family);
 uint16_t router_get_advertised_dir_port(const or_options_t *options,
diff -Nur tor-0.3.5.10/src/feature/rend/rendclient.c tor-0.3.5.12/src/feature/rend/rendclient.c
--- tor-0.3.5.10/src/feature/rend/rendclient.c	2019-10-11 23:48:21.000000000 +0200
+++ tor-0.3.5.12/src/feature/rend/rendclient.c	2020-08-11 01:31:56.000000000 +0200
@@ -261,8 +261,8 @@
             > MAX_NICKNAME_LEN)) {
       goto perm_err;
     }
-    strncpy(tmp, rendcirc->build_state->chosen_exit->nickname,
-            (MAX_NICKNAME_LEN+1)); /* nul pads */
+    strlcpy(tmp, rendcirc->build_state->chosen_exit->nickname,
+            sizeof(tmp));
     memcpy(tmp+MAX_NICKNAME_LEN+1, rendcirc->rend_data->rend_cookie,
            REND_COOKIE_LEN);
     dh_offset = MAX_NICKNAME_LEN+1+REND_COOKIE_LEN;
@@ -819,7 +819,7 @@
         log_warn(LD_BUG, "Unknown failure type %u. Removing intro point.",
                  failure_type);
         tor_fragile_assert();
-        /* fall through */
+        FALLTHROUGH;
       case INTRO_POINT_FAILURE_GENERIC:
         rend_cache_intro_failure_note(failure_type,
                                       (uint8_t *)failed_intro->identity_digest,
diff -Nur tor-0.3.5.10/src/feature/rend/rendservice.c tor-0.3.5.12/src/feature/rend/rendservice.c
--- tor-0.3.5.10/src/feature/rend/rendservice.c	2019-10-23 18:05:45.000000000 +0200
+++ tor-0.3.5.12/src/feature/rend/rendservice.c	2020-10-07 14:38:30.000000000 +0200
@@ -130,6 +130,22 @@
  * service on config reload. */
 static smartlist_t *rend_service_staging_list = NULL;
 
+/** Helper: log the deprecation warning for version 2 only once. */
+static void
+log_once_deprecation_warning(void)
+{
+  static bool logged_once = false;
+  if (!logged_once) {
+    log_warn(LD_REND, "DEPRECATED: Onion service version 2 are deprecated. "
+             "Please use version 3 which is the default now. "
+             "Currently, version 2 is planned to be obsolete in "
+             "the Tor version 0.4.6 stable series.");
+    logged_once = true;
+  }
+}
+/** Macro to make it very explicit that we are warning about deprecation. */
+#define WARN_ONCE_DEPRECATION() log_once_deprecation_warning()
+
 /* Like rend_get_service_list_mutable, but returns a read-only list. */
 static const smartlist_t*
 rend_get_service_list(const smartlist_t* substitute_service_list)
@@ -731,6 +747,9 @@
   tor_assert(options);
   tor_assert(config);
 
+  /* We are about to configure a version 2 service. Warn of deprecation. */
+  WARN_ONCE_DEPRECATION();
+
   /* Use the staging service list so that we can check then do the pruning
    * process using the main list at the end. */
   if (rend_service_staging_list == NULL) {
diff -Nur tor-0.3.5.10/src/lib/cc/compat_compiler.h tor-0.3.5.12/src/lib/cc/compat_compiler.h
--- tor-0.3.5.10/src/lib/cc/compat_compiler.h	2019-10-11 23:48:21.000000000 +0200
+++ tor-0.3.5.12/src/lib/cc/compat_compiler.h	2020-05-06 22:47:03.000000000 +0200
@@ -50,6 +50,12 @@
 #define CHECK_SCANF(formatIdx, firstArg)
 #endif /* defined(__GNUC__) */
 
+#if defined(HAVE_ATTR_FALLTHROUGH)
+#define FALLTHROUGH __attribute__((fallthrough))
+#else
+#define FALLTHROUGH
+#endif
+
 /* What GCC do we have? */
 #ifdef __GNUC__
 #define GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__)
diff -Nur tor-0.3.5.10/src/lib/container/buffers.c tor-0.3.5.12/src/lib/container/buffers.c
--- tor-0.3.5.10/src/lib/container/buffers.c	2019-10-11 23:48:21.000000000 +0200
+++ tor-0.3.5.12/src/lib/container/buffers.c	2020-08-01 18:18:03.000000000 +0200
@@ -689,6 +689,8 @@
   tor_assert(buf_out);
   if (!buf_in)
     return;
+  if (buf_datalen(buf_in) == 0)
+    return;
   if (BUG(buf_out->datalen >= INT_MAX || buf_in->datalen >= INT_MAX))
     return;
   if (BUG(buf_out->datalen >= INT_MAX - buf_in->datalen))
diff -Nur tor-0.3.5.10/src/lib/crypt_ops/crypto_digest.c tor-0.3.5.12/src/lib/crypt_ops/crypto_digest.c
--- tor-0.3.5.10/src/lib/crypt_ops/crypto_digest.c	2019-10-11 23:48:21.000000000 +0200
+++ tor-0.3.5.12/src/lib/crypt_ops/crypto_digest.c	2020-05-06 22:58:12.000000000 +0200
@@ -50,8 +50,8 @@
     case DIGEST_SHA1: return SEC_OID_SHA1;
     case DIGEST_SHA256: return SEC_OID_SHA256;
     case DIGEST_SHA512: return SEC_OID_SHA512;
-    case DIGEST_SHA3_256: /* Fall through */
-    case DIGEST_SHA3_512: /* Fall through */
+    case DIGEST_SHA3_256: FALLTHROUGH;
+    case DIGEST_SHA3_512: FALLTHROUGH;
     default:
       return SEC_OID_UNKNOWN;
   }
@@ -98,12 +98,12 @@
 library_supports_digest(digest_algorithm_t alg)
 {
   switch (alg) {
-    case DIGEST_SHA1: /* Fall through */
-    case DIGEST_SHA256: /* Fall through */
-    case DIGEST_SHA512: /* Fall through */
+    case DIGEST_SHA1: FALLTHROUGH;
+    case DIGEST_SHA256: FALLTHROUGH;
+    case DIGEST_SHA512:
       return true;
-    case DIGEST_SHA3_256: /* Fall through */
-    case DIGEST_SHA3_512: /* Fall through */
+    case DIGEST_SHA3_256: FALLTHROUGH;
+    case DIGEST_SHA3_512: FALLTHROUGH;
     default:
       return false;
   }
@@ -313,8 +313,8 @@
                          STRUCT_FIELD_SIZE(crypto_digest_t, f))
   switch (alg) {
 #ifdef ENABLE_NSS
-    case DIGEST_SHA1: /* Fall through */
-    case DIGEST_SHA256: /* Fall through */
+    case DIGEST_SHA1: FALLTHROUGH;
+    case DIGEST_SHA256: FALLTHROUGH;
     case DIGEST_SHA512:
       return END_OF_FIELD(d.ctx);
 #else
@@ -349,8 +349,8 @@
   switch (algorithm)
     {
 #ifdef ENABLE_NSS
-    case DIGEST_SHA1: /* fall through */
-    case DIGEST_SHA256: /* fall through */
+    case DIGEST_SHA1: FALLTHROUGH;
+    case DIGEST_SHA256: FALLTHROUGH;
     case DIGEST_SHA512:
       r->d.ctx = PK11_CreateDigestContext(digest_alg_to_nss_oid(algorithm));
       if (BUG(!r->d.ctx)) {
@@ -451,8 +451,8 @@
    */
   switch (digest->algorithm) {
 #ifdef ENABLE_NSS
-    case DIGEST_SHA1: /* fall through */
-    case DIGEST_SHA256: /* fall through */
+    case DIGEST_SHA1: FALLTHROUGH;
+    case DIGEST_SHA256: FALLTHROUGH;
     case DIGEST_SHA512:
       tor_assert(len <= UINT_MAX);
       SECStatus s = PK11_DigestOp(digest->d.ctx,
@@ -471,7 +471,7 @@
       SHA512_Update(&digest->d.sha512, (void*)data, len);
       break;
 #endif
-    case DIGEST_SHA3_256: /* FALLSTHROUGH */
+    case DIGEST_SHA3_256: FALLTHROUGH;
     case DIGEST_SHA3_512:
       keccak_digest_update(&digest->d.sha3, (const uint8_t *)data, len);
       break;
@@ -540,7 +540,7 @@
       SHA512_Final(r, &tmpenv.d.sha512);
       break;
 //LCOV_EXCL_START
-    case DIGEST_SHA3_256: /* FALLSTHROUGH */
+    case DIGEST_SHA3_256: FALLTHROUGH;
     case DIGEST_SHA3_512:
     default:
       log_warn(LD_BUG, "Handling unexpected algorithm %d", digest->algorithm);
diff -Nur tor-0.3.5.10/src/lib/encoding/pem.c tor-0.3.5.12/src/lib/encoding/pem.c
--- tor-0.3.5.10/src/lib/encoding/pem.c	2019-10-11 23:48:21.000000000 +0200
+++ tor-0.3.5.12/src/lib/encoding/pem.c	2020-06-30 16:27:01.000000000 +0200
@@ -85,13 +85,19 @@
   src = eat_whitespace_eos(src, eos);
 
   char *tag = NULL;
-  tor_asprintf(&tag, "-----BEGIN %s-----\n", objtype);
+  tor_asprintf(&tag, "-----BEGIN %s-----", objtype);
   if ((size_t)(eos-src) < strlen(tag) || fast_memneq(src, tag, strlen(tag))) {
     tor_free(tag);
     return -1;
   }
   src += strlen(tag);
   tor_free(tag);
+  /* At this point we insist on spaces (including CR), then an LF. */
+  src = eat_whitespace_eos_no_nl(src, eos);
+  if (src == eos || *src != '\n') {
+    /* Extra junk at end of line: this isn't valid. */
+    return -1;
+  }
 
   // NOTE lack of trailing \n.  We do not enforce its presence.
   tor_asprintf(&tag, "\n-----END %s-----", objtype);
diff -Nur tor-0.3.5.10/src/lib/fdio/fdio.c tor-0.3.5.12/src/lib/fdio/fdio.c
--- tor-0.3.5.10/src/lib/fdio/fdio.c	2019-10-11 23:48:21.000000000 +0200
+++ tor-0.3.5.12/src/lib/fdio/fdio.c	2020-07-29 18:37:07.000000000 +0200
@@ -43,7 +43,7 @@
 tor_fd_getpos(int fd)
 {
 #ifdef _WIN32
-  return (off_t) _lseek(fd, 0, SEEK_CUR);
+  return (off_t) _lseeki64(fd, 0, SEEK_CUR);
 #else
   return (off_t) lseek(fd, 0, SEEK_CUR);
 #endif
@@ -56,7 +56,7 @@
 tor_fd_seekend(int fd)
 {
 #ifdef _WIN32
-  return _lseek(fd, 0, SEEK_END) < 0 ? -1 : 0;
+  return _lseeki64(fd, 0, SEEK_END) < 0 ? -1 : 0;
 #else
   off_t rc = lseek(fd, 0, SEEK_END) < 0 ? -1 : 0;
 #ifdef ESPIPE
@@ -75,7 +75,7 @@
 tor_fd_setpos(int fd, off_t pos)
 {
 #ifdef _WIN32
-  return _lseek(fd, pos, SEEK_SET) < 0 ? -1 : 0;
+  return _lseeki64(fd, pos, SEEK_SET) < 0 ? -1 : 0;
 #else
   return lseek(fd, pos, SEEK_SET) < 0 ? -1 : 0;
 #endif
diff -Nur tor-0.3.5.10/src/lib/net/address.c tor-0.3.5.12/src/lib/net/address.c
--- tor-0.3.5.10/src/lib/net/address.c	2019-10-11 23:48:21.000000000 +0200
+++ tor-0.3.5.12/src/lib/net/address.c	2020-08-11 01:31:56.000000000 +0200
@@ -337,7 +337,7 @@
       break;
     case AF_INET6:
       /* Shortest addr [ :: ] + \0 */
-      if (len < (3 + (decorate ? 2 : 0)))
+      if (len < (3 + (decorate ? 2u : 0u)))
         return NULL;
 
       if (decorate)
@@ -926,6 +926,7 @@
       break;
     case AF_INET6:
       memcpy(dest->addr.in6_addr.s6_addr, src->addr.in6_addr.s6_addr, 16);
+      break;
     case AF_UNSPEC:
       break;
       // LCOV_EXCL_START
diff -Nur tor-0.3.5.10/src/lib/thread/compat_pthreads.c tor-0.3.5.12/src/lib/thread/compat_pthreads.c
--- tor-0.3.5.10/src/lib/thread/compat_pthreads.c	2019-10-11 23:48:21.000000000 +0200
+++ tor-0.3.5.12/src/lib/thread/compat_pthreads.c	2020-06-30 15:42:58.000000000 +0200
@@ -265,6 +265,6 @@
       pthread_attr_setdetachstate(&attr_detached, PTHREAD_CREATE_DETACHED);
     tor_assert(ret2 == 0);
     threads_initialized = 1;
-    set_main_thread();
   }
+  set_main_thread();
 }
diff -Nur tor-0.3.5.10/src/lib/tls/tortls_nss.c tor-0.3.5.12/src/lib/tls/tortls_nss.c
--- tor-0.3.5.10/src/lib/tls/tortls_nss.c	2019-10-11 23:48:21.000000000 +0200
+++ tor-0.3.5.12/src/lib/tls/tortls_nss.c	2020-10-07 14:10:08.000000000 +0200
@@ -418,6 +418,16 @@
     return NULL;
   }
 
+  /* even if though the socket is already nonblocking, we need to tell NSS
+   * about the fact, so that it knows what to do when it says EAGAIN. */
+  PRSocketOptionData data;
+  data.option = PR_SockOpt_Nonblocking;
+  data.value.non_blocking = 1;
+  if (PR_SetSocketOption(ssl, &data) != PR_SUCCESS) {
+    PR_Close(ssl);
+    return NULL;
+  }
+
   tor_tls_t *tls = tor_malloc_zero(sizeof(tor_tls_t));
   tls->magic = TOR_TLS_MAGIC;
   tls->context = ctx;
@@ -713,23 +723,58 @@
 tor_tls_cert_matches_key,(const tor_tls_t *tls,
                           const struct tor_x509_cert_t *cert))
 {
-  tor_assert(tls);
   tor_assert(cert);
+  tor_assert(cert->cert);
+
   int rv = 0;
 
-  CERTCertificate *peercert = SSL_PeerCertificate(tls->ssl);
-  if (!peercert)
+  tor_x509_cert_t *peercert = tor_tls_get_peer_cert((tor_tls_t *)tls);
+
+  if (!peercert || !peercert->cert)
     goto done;
-  CERTSubjectPublicKeyInfo *peer_info = &peercert->subjectPublicKeyInfo;
+
+  CERTSubjectPublicKeyInfo *peer_info = &peercert->cert->subjectPublicKeyInfo;
   CERTSubjectPublicKeyInfo *cert_info = &cert->cert->subjectPublicKeyInfo;
+
+  /* NSS stores the `len` field in bits, instead of bytes, for the
+   * `subjectPublicKey` field in CERTSubjectPublicKeyInfo, but
+   * `SECITEM_ItemsAreEqual()` compares the two bitstrings using a length field
+   * defined in bytes.
+   *
+   * We convert the `len` field from bits to bytes, do our comparison with
+   * `SECITEM_ItemsAreEqual()`, and reset the length field from bytes to bits
+   * again.
+   *
+   * See also NSS's own implementation of `SECKEY_CopySubjectPublicKeyInfo()`
+   * in seckey.c in the NSS source tree. This function also does the conversion
+   * between bits and bytes.
+   */
+  const unsigned int peer_info_orig_len = peer_info->subjectPublicKey.len;
+  const unsigned int cert_info_orig_len = cert_info->subjectPublicKey.len;
+
+  /* We convert the length from bits to bytes, but instead of using NSS's
+   * `DER_ConvertBitString()` macro on both of peer_info->subjectPublicKey and
+   * cert_info->subjectPublicKey, we have to do the conversion explicitly since
+   * both of the two subjectPublicKey fields are allowed to point to the same
+   * memory address. Otherwise, the bits to bytes conversion would potentially
+   * be applied twice, which would lead to us comparing too few of the bytes
+   * when we call SECITEM_ItemsAreEqual(), which would be catastrophic.
+   */
+  peer_info->subjectPublicKey.len = ((peer_info_orig_len + 7) >> 3);
+  cert_info->subjectPublicKey.len = ((cert_info_orig_len + 7) >> 3);
+
   rv = SECOID_CompareAlgorithmID(&peer_info->algorithm,
                                  &cert_info->algorithm) == 0 &&
        SECITEM_ItemsAreEqual(&peer_info->subjectPublicKey,
                              &cert_info->subjectPublicKey);
 
+  /* Convert from bytes back to bits. */
+  peer_info->subjectPublicKey.len = peer_info_orig_len;
+  cert_info->subjectPublicKey.len = cert_info_orig_len;
+
  done:
-  if (peercert)
-    CERT_DestroyCertificate(peercert);
+  tor_x509_cert_free(peercert);
+
   return rv;
 }
 
diff -Nur tor-0.3.5.10/src/lib/tls/x509.c tor-0.3.5.12/src/lib/tls/x509.c
--- tor-0.3.5.10/src/lib/tls/x509.c	2019-10-11 23:48:21.000000000 +0200
+++ tor-0.3.5.12/src/lib/tls/x509.c	2020-07-09 15:17:48.000000000 +0200
@@ -23,6 +23,7 @@
                                   time_t *start_time_out,
                                   time_t *end_time_out)
 {
+  tor_assert(cert_lifetime < INT_MAX);
   time_t start_time, end_time;
   /* Make sure we're part-way through the certificate lifetime, rather
    * than having it start right now. Don't choose quite uniformly, since
@@ -36,7 +37,7 @@
   const time_t start_granularity = 24*3600;
   time_t earliest_start_time;
   /* Don't actually start in the future! */
-  if (cert_lifetime <= min_real_lifetime + start_granularity) {
+  if ((int)cert_lifetime <= min_real_lifetime + start_granularity) {
     earliest_start_time = now - 1;
   } else {
     earliest_start_time = now + min_real_lifetime + start_granularity
diff -Nur tor-0.3.5.10/src/rust/protover/errors.rs tor-0.3.5.12/src/rust/protover/errors.rs
--- tor-0.3.5.10/src/rust/protover/errors.rs	2019-10-11 23:48:21.000000000 +0200
+++ tor-0.3.5.12/src/rust/protover/errors.rs	2020-11-09 14:55:53.000000000 +0100
@@ -36,7 +36,7 @@
             ProtoverError::Unparseable => write!(f, "The protover string was unparseable."),
             ProtoverError::ExceedsMax => write!(
                 f,
-                "The high in a (low, high) protover range exceeds u32::MAX."
+                "The high in a (low, high) protover range exceeds 63."
             ),
             ProtoverError::ExceedsExpansionLimit => write!(
                 f,
diff -Nur tor-0.3.5.10/src/rust/protover/protoset.rs tor-0.3.5.12/src/rust/protover/protoset.rs
--- tor-0.3.5.10/src/rust/protover/protoset.rs	2019-10-11 23:48:21.000000000 +0200
+++ tor-0.3.5.12/src/rust/protover/protoset.rs	2020-11-09 14:55:53.000000000 +0100
@@ -294,6 +294,10 @@
     }
 }
 
+/// Largest allowed protocol version.
+/// C_RUST_COUPLED: protover.c `MAX_PROTOCOL_VERSION`
+const MAX_PROTOCOL_VERSION: Version = 63;
+
 impl FromStr for ProtoSet {
     type Err = ProtoverError;
 
@@ -370,7 +374,7 @@
         let pieces: ::std::str::Split<char> = version_string.split(',');
 
         for p in pieces {
-            if p.contains('-') {
+            let (lo,hi) = if p.contains('-') {
                 let mut pair = p.splitn(2, '-');
 
                 let low = pair.next().ok_or(ProtoverError::Unparseable)?;
@@ -379,12 +383,17 @@
                 let lo: Version = low.parse().or(Err(ProtoverError::Unparseable))?;
                 let hi: Version = high.parse().or(Err(ProtoverError::Unparseable))?;
 
-                pairs.push((lo, hi));
+                (lo,hi)
             } else {
                 let v: u32 = p.parse().or(Err(ProtoverError::Unparseable))?;
 
-                pairs.push((v, v));
+                (v, v)
+            };
+
+            if lo > MAX_PROTOCOL_VERSION || hi > MAX_PROTOCOL_VERSION {
+                return Err(ProtoverError::ExceedsMax);
             }
+            pairs.push((lo, hi));
         }
 
         ProtoSet::from_slice(&pairs[..])
@@ -674,12 +683,11 @@
 
     #[test]
     fn test_protoset_into_vec() {
-        let ps: ProtoSet = "1-13,42,9001,4294967294".parse().unwrap();
+        let ps: ProtoSet = "1-13,42".parse().unwrap();
         let v: Vec<Version> = ps.into();
 
         assert!(v.contains(&7));
-        assert!(v.contains(&9001));
-        assert!(v.contains(&4294967294));
+        assert!(v.contains(&42));
     }
 }
 
diff -Nur tor-0.3.5.10/src/rust/protover/protover.rs tor-0.3.5.12/src/rust/protover/protover.rs
--- tor-0.3.5.10/src/rust/protover/protover.rs	2020-02-10 20:17:09.000000000 +0100
+++ tor-0.3.5.12/src/rust/protover/protover.rs	2020-11-09 14:55:53.000000000 +0100
@@ -866,12 +866,12 @@
 
     #[test]
     fn test_protoentry_from_str_allowed_number_of_versions() {
-        assert_protoentry_is_parseable!("Desc=1-4294967294");
+        assert_protoentry_is_parseable!("Desc=1-63");
     }
 
     #[test]
     fn test_protoentry_from_str_too_many_versions() {
-        assert_protoentry_is_unparseable!("Desc=1-4294967295");
+        assert_protoentry_is_unparseable!("Desc=1-64");
     }
 
     #[test]
@@ -910,10 +910,10 @@
 
     #[test]
     fn test_protoentry_all_supported_unsupported_high_version() {
-        let protocols: UnvalidatedProtoEntry = "HSDir=12-100".parse().unwrap();
+        let protocols: UnvalidatedProtoEntry = "HSDir=12-60".parse().unwrap();
         let unsupported: Option<UnvalidatedProtoEntry> = protocols.all_supported();
         assert_eq!(true, unsupported.is_some());
-        assert_eq!("HSDir=12-100", &unsupported.unwrap().to_string());
+        assert_eq!("HSDir=12-60", &unsupported.unwrap().to_string());
     }
 
     #[test]
@@ -962,7 +962,7 @@
             ProtoSet::from_str(&versions).unwrap().to_string()
         );
 
-        versions = "1-3,500";
+        versions = "1-3,50";
         assert_eq!(
             String::from(versions),
             ProtoSet::from_str(&versions).unwrap().to_string()
diff -Nur tor-0.3.5.10/src/rust/protover/tests/protover.rs tor-0.3.5.12/src/rust/protover/tests/protover.rs
--- tor-0.3.5.10/src/rust/protover/tests/protover.rs	2019-10-11 23:48:21.000000000 +0200
+++ tor-0.3.5.12/src/rust/protover/tests/protover.rs	2020-11-09 14:55:53.000000000 +0100
@@ -98,10 +98,10 @@
 
 #[test]
 fn protocol_all_supported_with_unsupported_versions() {
-    let protocols: UnvalidatedProtoEntry = "Link=3-999".parse().unwrap();
+    let protocols: UnvalidatedProtoEntry = "Link=3-63".parse().unwrap();
     let unsupported: Option<UnvalidatedProtoEntry> = protocols.all_supported();
     assert_eq!(true, unsupported.is_some());
-    assert_eq!("Link=6-999", &unsupported.unwrap().to_string());
+    assert_eq!("Link=6-63", &unsupported.unwrap().to_string());
 }
 
 #[test]
@@ -114,10 +114,10 @@
 
 #[test]
 fn protocol_all_supported_with_unsupported_high_version() {
-    let protocols: UnvalidatedProtoEntry = "Cons=1-2,999".parse().unwrap();
+    let protocols: UnvalidatedProtoEntry = "Cons=1-2,60".parse().unwrap();
     let unsupported: Option<UnvalidatedProtoEntry> = protocols.all_supported();
     assert_eq!(true, unsupported.is_some());
-    assert_eq!("Cons=999", &unsupported.unwrap().to_string());
+    assert_eq!("Cons=60", &unsupported.unwrap().to_string());
 }
 
 #[test]
@@ -195,27 +195,27 @@
 
 #[test]
 fn protover_compute_vote_returns_matching_for_mix() {
-    let protocols: &[UnvalidatedProtoEntry] = &["Link=1-10,500 Cons=1,3-7,8".parse().unwrap()];
+    let protocols: &[UnvalidatedProtoEntry] = &["Link=1-10,50 Cons=1,3-7,8".parse().unwrap()];
     let listed = ProtoverVote::compute(protocols, &1);
-    assert_eq!("Cons=1,3-8 Link=1-10,500", listed.to_string());
+    assert_eq!("Cons=1,3-8 Link=1-10,50", listed.to_string());
 }
 
 #[test]
 fn protover_compute_vote_returns_matching_for_longer_mix() {
     let protocols: &[UnvalidatedProtoEntry] = &[
-        "Desc=1-10,500 Cons=1,3-7,8".parse().unwrap(),
-        "Link=123-456,78 Cons=2-6,8 Desc=9".parse().unwrap(),
+        "Desc=1-10,50 Cons=1,3-7,8".parse().unwrap(),
+        "Link=12-45,8 Cons=2-6,8 Desc=9".parse().unwrap(),
     ];
 
     let listed = ProtoverVote::compute(protocols, &1);
-    assert_eq!("Cons=1-8 Desc=1-10,500 Link=78,123-456", listed.to_string());
+    assert_eq!("Cons=1-8 Desc=1-10,50 Link=8,12-45", listed.to_string());
 }
 
 #[test]
 fn protover_compute_vote_returns_matching_for_longer_mix_with_threshold_two() {
     let protocols: &[UnvalidatedProtoEntry] = &[
-        "Desc=1-10,500 Cons=1,3-7,8".parse().unwrap(),
-        "Link=123-456,78 Cons=2-6,8 Desc=9".parse().unwrap(),
+        "Desc=1-10,50 Cons=1,3-7,8".parse().unwrap(),
+        "Link=8,12-45 Cons=2-6,8 Desc=9".parse().unwrap(),
     ];
 
     let listed = ProtoverVote::compute(protocols, &2);
@@ -320,30 +320,20 @@
     assert_eq!(true, unsupported.is_none());
 }
 
-// By allowing us to add to votes, the C implementation allows us to
-// exceed the limit.
-#[test]
-fn protover_compute_vote_may_exceed_limit() {
-    let proto1: UnvalidatedProtoEntry = "Sleen=1-65535".parse().unwrap();
-    let proto2: UnvalidatedProtoEntry = "Sleen=100000".parse().unwrap();
-
-    let _result: UnvalidatedProtoEntry = ProtoverVote::compute(&[proto1, proto2], &1);
-}
-
 #[test]
 fn protover_all_supported_should_exclude_versions_we_actually_do_support() {
-    let proto: UnvalidatedProtoEntry = "Link=3-999".parse().unwrap();
+    let proto: UnvalidatedProtoEntry = "Link=3-63".parse().unwrap();
     let result: String = proto.all_supported().unwrap().to_string();
 
-    assert_eq!(result, "Link=6-999".to_string());
+    assert_eq!(result, "Link=6-63".to_string());
 }
 
 #[test]
 fn protover_all_supported_should_exclude_versions_we_actually_do_support_complex1() {
-    let proto: UnvalidatedProtoEntry = "Link=1-3,345-666".parse().unwrap();
+    let proto: UnvalidatedProtoEntry = "Link=1-3,30-63".parse().unwrap();
     let result: String = proto.all_supported().unwrap().to_string();
 
-    assert_eq!(result, "Link=345-666".to_string());
+    assert_eq!(result, "Link=30-63".to_string());
 }
 
 #[test]
@@ -356,26 +346,10 @@
 
 #[test]
 fn protover_all_supported_should_exclude_some_versions_and_entire_protocols() {
-    let proto: UnvalidatedProtoEntry = "Link=1-3,5-12 Quokka=9000-9001".parse().unwrap();
-    let result: String = proto.all_supported().unwrap().to_string();
-
-    assert_eq!(result, "Link=6-12 Quokka=9000-9001".to_string());
-}
-
-#[test]
-fn protover_all_supported_should_not_dos_anyones_computer() {
-    let proto: UnvalidatedProtoEntry = "Link=1-2147483648".parse().unwrap();
-    let result: String = proto.all_supported().unwrap().to_string();
-
-    assert_eq!(result, "Link=6-2147483648".to_string());
-}
-
-#[test]
-fn protover_all_supported_should_not_dos_anyones_computer_max_versions() {
-    let proto: UnvalidatedProtoEntry = "Link=1-4294967294".parse().unwrap();
+    let proto: UnvalidatedProtoEntry = "Link=1-3,5-12 Quokka=50-51".parse().unwrap();
     let result: String = proto.all_supported().unwrap().to_string();
 
-    assert_eq!(result, "Link=6-4294967294".to_string());
+    assert_eq!(result, "Link=6-12 Quokka=50-51".to_string());
 }
 
 #[test]
diff -Nur tor-0.3.5.10/src/test/include.am tor-0.3.5.12/src/test/include.am
--- tor-0.3.5.10/src/test/include.am	2019-10-11 23:48:21.000000000 +0200
+++ tor-0.3.5.12/src/test/include.am	2020-10-07 14:03:52.000000000 +0200
@@ -23,7 +23,15 @@
 	src/test/test_workqueue_pipe.sh \
 	src/test/test_workqueue_pipe2.sh \
 	src/test/test_workqueue_socketpair.sh \
-	src/test/test_switch_id.sh
+	src/test/test_switch_id.sh \
+        src/test/unittest_part1.sh \
+        src/test/unittest_part2.sh \
+        src/test/unittest_part3.sh \
+        src/test/unittest_part4.sh \
+        src/test/unittest_part5.sh \
+        src/test/unittest_part6.sh \
+        src/test/unittest_part7.sh \
+        src/test/unittest_part8.sh
 
 if USE_RUST
 TESTSCRIPTS += \
@@ -35,7 +43,7 @@
 TESTSCRIPTS += src/test/test_rebind.sh
 endif
 
-TESTS += src/test/test src/test/test-slow src/test/test-memwipe \
+TESTS += src/test/test-slow src/test/test-memwipe \
 	src/test/test_workqueue \
 	src/test/test_keygen.sh \
 	src/test/test_key_expiration.sh \
@@ -369,7 +377,15 @@
 	src/test/test_workqueue_efd2.sh \
 	src/test/test_workqueue_pipe.sh \
 	src/test/test_workqueue_pipe2.sh \
-	src/test/test_workqueue_socketpair.sh
+	src/test/test_workqueue_socketpair.sh \
+        src/test/unittest_part1.sh \
+        src/test/unittest_part2.sh \
+        src/test/unittest_part3.sh \
+        src/test/unittest_part4.sh \
+        src/test/unittest_part5.sh \
+        src/test/unittest_part6.sh \
+        src/test/unittest_part7.sh \
+        src/test/unittest_part8.sh
 
 test-rust:
 	$(TESTS_ENVIRONMENT) "$(abs_top_srcdir)/src/test/test_rust.sh"
diff -Nur tor-0.3.5.10/src/test/test_buffers.c tor-0.3.5.12/src/test/test_buffers.c
--- tor-0.3.5.10/src/test/test_buffers.c	2019-10-11 23:48:21.000000000 +0200
+++ tor-0.3.5.12/src/test/test_buffers.c	2020-08-01 18:18:03.000000000 +0200
@@ -303,6 +303,69 @@
 }
 
 static void
+test_buffers_move_all(void *arg)
+{
+  (void)arg;
+  buf_t *input = buf_new();
+  buf_t *output = buf_new();
+  char *s = NULL;
+
+  /* Move from empty buffer to nonempty buffer. (This is a regression test for
+   * #40076) */
+  buf_add(output, "abc", 3);
+  buf_assert_ok(input);
+  buf_assert_ok(output);
+  buf_move_all(output, input);
+  buf_assert_ok(input);
+  buf_assert_ok(output);
+  tt_int_op(buf_datalen(output), OP_EQ, 3);
+  s = buf_extract(output, NULL);
+  tt_str_op(s, OP_EQ, "abc");
+  buf_free(output);
+  buf_free(input);
+  tor_free(s);
+
+  /* Move from empty to empty. */
+  output = buf_new();
+  input = buf_new();
+  buf_move_all(output, input);
+  buf_assert_ok(input);
+  buf_assert_ok(output);
+  tt_int_op(buf_datalen(output), OP_EQ, 0);
+  buf_free(output);
+  buf_free(input);
+
+  /* Move from nonempty to empty. */
+  output = buf_new();
+  input = buf_new();
+  buf_add(input, "longstanding bugs", 17);
+  buf_move_all(output, input);
+  buf_assert_ok(input);
+  buf_assert_ok(output);
+  s = buf_extract(output, NULL);
+  tt_str_op(s, OP_EQ, "longstanding bugs");
+  buf_free(output);
+  buf_free(input);
+  tor_free(s);
+
+  /* Move from nonempty to nonempty. */
+  output = buf_new();
+  input = buf_new();
+  buf_add(output, "the start of", 12);
+  buf_add(input, " a string", 9);
+  buf_move_all(output, input);
+  buf_assert_ok(input);
+  buf_assert_ok(output);
+  s = buf_extract(output, NULL);
+  tt_str_op(s, OP_EQ, "the start of a string");
+
+ done:
+  buf_free(output);
+  buf_free(input);
+  tor_free(s);
+}
+
+static void
 test_buffer_copy(void *arg)
 {
   buf_t *buf=NULL, *buf2=NULL;
@@ -799,6 +862,7 @@
   { "basic", test_buffers_basic, TT_FORK, NULL, NULL },
   { "copy", test_buffer_copy, TT_FORK, NULL, NULL },
   { "pullup", test_buffer_pullup, TT_FORK, NULL, NULL },
+  { "move_all", test_buffers_move_all, 0, NULL, NULL },
   { "startswith", test_buffer_peek_startswith, 0, NULL, NULL },
   { "allocation_tracking", test_buffer_allocation_tracking, TT_FORK,
     NULL, NULL },
diff -Nur tor-0.3.5.10/src/test/test_channel.c tor-0.3.5.12/src/test/test_channel.c
--- tor-0.3.5.10/src/test/test_channel.c	2019-10-11 23:48:21.000000000 +0200
+++ tor-0.3.5.12/src/test/test_channel.c	2020-10-07 14:05:40.000000000 +0200
@@ -46,7 +46,6 @@
 static int test_close_called = 0;
 static int test_chan_should_be_canonical = 0;
 static int test_chan_should_match_target = 0;
-static int test_chan_canonical_should_be_reliable = 0;
 static int test_chan_listener_close_fn_called = 0;
 static int test_chan_listener_fn_called = 0;
 
@@ -357,14 +356,10 @@
 }
 
 static int
-test_chan_is_canonical(channel_t *chan, int req)
+test_chan_is_canonical(channel_t *chan)
 {
   tor_assert(chan);
 
-  if (req && test_chan_canonical_should_be_reliable) {
-    return 1;
-  }
-
   if (test_chan_should_be_canonical) {
     return 1;
   }
@@ -1381,6 +1376,9 @@
   /* Make it older than chan1. */
   chan2->timestamp_created = chan1->timestamp_created - 1;
 
+  /* Say it's all canonical. */
+  test_chan_should_be_canonical = 1;
+
   /* Set channel identities and add it to the channel map. The last one to be
    * added is made the first one in the list so the lookup will always return
    * that one first. */
@@ -1475,8 +1473,8 @@
   chan2->is_bad_for_new_circs = 0;
 
   /* Non canonical channels. */
+  test_chan_should_be_canonical = 0;
   test_chan_should_match_target = 0;
-  test_chan_canonical_should_be_reliable = 1;
   ret_chan = channel_get_for_extend(digest, &ed_id, &addr, &msg, &launch);
   tt_assert(!ret_chan);
   tt_str_op(msg, OP_EQ, "Connections all too old, or too non-canonical. "
@@ -1567,4 +1565,3 @@
     NULL, NULL },
   END_OF_TESTCASES
 };
-
diff -Nur tor-0.3.5.10/src/test/test_config.c tor-0.3.5.12/src/test/test_config.c
--- tor-0.3.5.10/src/test/test_config.c	2020-02-12 14:28:47.000000000 +0100
+++ tor-0.3.5.12/src/test/test_config.c	2020-10-07 15:29:17.000000000 +0200
@@ -4861,6 +4861,71 @@
 }
 
 static void
+test_config_get_first_advertised(void *data)
+{
+  (void)data;
+  int r, w=0, n=0;
+  char *msg=NULL;
+  or_options_t *opts = options_new();
+  int port;
+  const tor_addr_t *addr;
+
+  // no ports are configured? We get NULL.
+  port = get_first_advertised_port_by_type_af(CONN_TYPE_OR_LISTENER,
+                                              AF_INET);
+  tt_int_op(port, OP_EQ, 0);
+  addr = get_first_advertised_addr_by_type_af(CONN_TYPE_OR_LISTENER,
+                                              AF_INET);
+  tt_ptr_op(addr, OP_EQ, NULL);
+
+  port = get_first_advertised_port_by_type_af(CONN_TYPE_OR_LISTENER,
+                                              AF_INET6);
+  tt_int_op(port, OP_EQ, 0);
+  addr = get_first_advertised_addr_by_type_af(CONN_TYPE_OR_LISTENER,
+                                              AF_INET6);
+  tt_ptr_op(addr, OP_EQ, NULL);
+
+  config_line_append(&opts->ORPort_lines, "ORPort", "[1234::5678]:8080");
+  config_line_append(&opts->ORPort_lines, "ORPort",
+                     "1.2.3.4:9999 noadvertise");
+  config_line_append(&opts->ORPort_lines, "ORPort",
+                     "5.6.7.8:9911 nolisten");
+
+  r = parse_ports(opts, 0, &msg, &n, &w);
+  tt_assert(r == 0);
+
+  // UNSPEC gets us nothing.
+  port = get_first_advertised_port_by_type_af(CONN_TYPE_OR_LISTENER,
+                                              AF_UNSPEC);
+  tt_int_op(port, OP_EQ, 0);
+  addr = get_first_advertised_addr_by_type_af(CONN_TYPE_OR_LISTENER,
+                                              AF_UNSPEC);
+  tt_ptr_op(addr, OP_EQ, NULL);
+
+  // Try AF_INET.
+  port = get_first_advertised_port_by_type_af(CONN_TYPE_OR_LISTENER,
+                                              AF_INET);
+  tt_int_op(port, OP_EQ, 9911);
+  addr = get_first_advertised_addr_by_type_af(CONN_TYPE_OR_LISTENER,
+                                              AF_INET);
+  tt_ptr_op(addr, OP_NE, NULL);
+  tt_str_op(fmt_addrport(addr,port), OP_EQ, "5.6.7.8:9911");
+
+  // Try AF_INET6
+  port = get_first_advertised_port_by_type_af(CONN_TYPE_OR_LISTENER,
+                                              AF_INET6);
+  tt_int_op(port, OP_EQ, 8080);
+  addr = get_first_advertised_addr_by_type_af(CONN_TYPE_OR_LISTENER,
+                                              AF_INET6);
+  tt_ptr_op(addr, OP_NE, NULL);
+  tt_str_op(fmt_addrport(addr,port), OP_EQ, "[1234::5678]:8080");
+
+ done:
+  or_options_free(opts);
+  config_free_all();
+}
+
+static void
 test_config_parse_log_severity(void *data)
 {
   int ret;
@@ -5920,6 +5985,7 @@
   CONFIG_TEST(parse_port_config__ports__no_ports_given, 0),
   CONFIG_TEST(parse_port_config__ports__server_options, 0),
   CONFIG_TEST(parse_port_config__ports__ports_given, 0),
+  CONFIG_TEST(get_first_advertised, TT_FORK),
   CONFIG_TEST(parse_log_severity, 0),
   CONFIG_TEST(include_limit, 0),
   CONFIG_TEST(include_does_not_exist, 0),
diff -Nur tor-0.3.5.10/src/test/test_dos.c tor-0.3.5.12/src/test/test_dos.c
--- tor-0.3.5.10/src/test/test_dos.c	2019-10-11 23:48:21.000000000 +0200
+++ tor-0.3.5.12/src/test/test_dos.c	2020-04-09 14:18:54.000000000 +0200
@@ -79,7 +79,7 @@
   { /* Register many conns from this client but not enough to get it blocked */
     unsigned int i;
     for (i = 0; i < max_concurrent_conns; i++) {
-      dos_new_client_conn(&or_conn);
+      dos_new_client_conn(&or_conn, NULL);
     }
   }
 
@@ -88,7 +88,7 @@
             dos_conn_addr_get_defense_type(addr));
 
   /* Register another conn and check that new conns are not allowed anymore */
-  dos_new_client_conn(&or_conn);
+  dos_new_client_conn(&or_conn, NULL);
   tt_int_op(DOS_CONN_DEFENSE_CLOSE, OP_EQ,
             dos_conn_addr_get_defense_type(addr));
 
@@ -98,7 +98,7 @@
             dos_conn_addr_get_defense_type(addr));
 
   /* Register another conn and see that defense measures get reactivated */
-  dos_new_client_conn(&or_conn);
+  dos_new_client_conn(&or_conn, NULL);
   tt_int_op(DOS_CONN_DEFENSE_CLOSE, OP_EQ,
             dos_conn_addr_get_defense_type(addr));
 
@@ -153,7 +153,7 @@
    * circuit counting subsystem */
   geoip_note_client_seen(GEOIP_CLIENT_CONNECT, addr, NULL, now);
   for (i = 0; i < min_conc_conns_for_cc ; i++) {
-    dos_new_client_conn(&or_conn);
+    dos_new_client_conn(&or_conn, NULL);
   }
 
   /* Register new circuits for this client and conn, but not enough to get
@@ -217,7 +217,7 @@
 
   /* Register this client */
   geoip_note_client_seen(GEOIP_CLIENT_CONNECT, addr, NULL, now);
-  dos_new_client_conn(&or_conn);
+  dos_new_client_conn(&or_conn, NULL);
 
   /* Fetch this client from the geoip cache and get its DoS structs */
   clientmap_entry_t *entry = geoip_lookup_client(addr, NULL,
@@ -460,11 +460,11 @@
   geoip_note_client_seen(GEOIP_CLIENT_CONNECT, &or_conn.real_addr, NULL, 0);
   /* Suppose we have 5 connections in rapid succession, the counter should
    * always be 0 because we should ignore this. */
-  dos_new_client_conn(&or_conn);
-  dos_new_client_conn(&or_conn);
-  dos_new_client_conn(&or_conn);
-  dos_new_client_conn(&or_conn);
-  dos_new_client_conn(&or_conn);
+  dos_new_client_conn(&or_conn, NULL);
+  dos_new_client_conn(&or_conn, NULL);
+  dos_new_client_conn(&or_conn, NULL);
+  dos_new_client_conn(&or_conn, NULL);
+  dos_new_client_conn(&or_conn, NULL);
   entry = geoip_lookup_client(&or_conn.real_addr, NULL, GEOIP_CLIENT_CONNECT);
   tt_assert(entry);
   /* We should have a count of 0. */
@@ -474,8 +474,8 @@
    * connection and see if we do get it. */
   tor_addr_parse(&or_conn.real_addr, "42.42.42.43");
   geoip_note_client_seen(GEOIP_CLIENT_CONNECT, &or_conn.real_addr, NULL, 0);
-  dos_new_client_conn(&or_conn);
-  dos_new_client_conn(&or_conn);
+  dos_new_client_conn(&or_conn, NULL);
+  dos_new_client_conn(&or_conn, NULL);
   entry = geoip_lookup_client(&or_conn.real_addr, NULL, GEOIP_CLIENT_CONNECT);
   tt_assert(entry);
   /* We should have a count of 2. */
diff -Nur tor-0.3.5.10/src/test/test_options.c tor-0.3.5.12/src/test/test_options.c
--- tor-0.3.5.10/src/test/test_options.c	2019-10-11 23:48:21.000000000 +0200
+++ tor-0.3.5.12/src/test/test_options.c	2020-06-30 16:27:01.000000000 +0200
@@ -485,7 +485,8 @@
 #endif
 
   options_test_data_t *tdata = get_options_test_data(
-                                      "ORPort 127.0.0.1:5555");
+                                      "ORPort 127.0.0.1:5555\n"
+                                      "ContactInfo nobody@example.com");
   setup_capture_of_logs(LOG_WARN);
 
   MOCK(get_uname, fixed_get_uname);
@@ -633,9 +634,11 @@
   ret = options_validate(tdata->old_opt, tdata->opt, tdata->def_opt, 0, &msg);
   tt_int_op(ret, OP_EQ, -1);
   expect_log_msg(
-            "Your ContactInfo config option is not"
-            " set. Please consider setting it, so we can contact you if your"
-            " server is misconfigured or something else goes wrong.\n");
+           "Your ContactInfo config option is not set. Please strongly "
+           "consider setting it, so we can contact you if your relay is "
+           "misconfigured, end-of-life, or something else goes wrong. It "
+           "is also possible that your relay might get rejected from the "
+           "network due to a missing valid contact address.\n");
   tor_free(msg);
 
   free_options_test_data(tdata);
@@ -645,9 +648,11 @@
   ret = options_validate(tdata->old_opt, tdata->opt, tdata->def_opt, 0, &msg);
   tt_int_op(ret, OP_EQ, -1);
   expect_no_log_msg(
-            "Your ContactInfo config option is not"
-            " set. Please consider setting it, so we can contact you if your"
-            " server is misconfigured or something else goes wrong.\n");
+           "Your ContactInfo config option is not set. Please strongly "
+           "consider setting it, so we can contact you if your relay is "
+           "misconfigured, end-of-life, or something else goes wrong. It "
+           "is also possible that your relay might get rejected from the "
+           "network due to a missing valid contact address.\n");
   tor_free(msg);
 
  done:
diff -Nur tor-0.3.5.10/src/test/test_pem.c tor-0.3.5.12/src/test/test_pem.c
--- tor-0.3.5.10/src/test/test_pem.c	2019-10-11 23:48:21.000000000 +0200
+++ tor-0.3.5.12/src/test/test_pem.c	2020-06-30 16:27:01.000000000 +0200
@@ -115,8 +115,38 @@
   ;
 }
 
+static void
+test_crypto_pem_decode_crlf(void *arg)
+{
+  (void)arg;
+  char crlf_version[4096];
+  uint8_t buf[4096];
+
+  /* Convert 'expected' to a version with CRLF instead of LF. */
+  const char *inp = expected;
+  char *outp = crlf_version;
+  while (*inp) {
+    if (*inp == '\n') {
+      *outp++ = '\r';
+    }
+    *outp++ = *inp++;
+  }
+  *outp = 0;
+
+  /* Decoding should succeed (or else we have bug 33032 again) */
+  int n = pem_decode(buf, sizeof(buf),
+                     crlf_version, strlen(crlf_version),
+                     "WOMBAT QUOTE");
+  tt_int_op(n, OP_EQ, strlen(example_pre));
+  tt_mem_op(buf, OP_EQ, example_pre, n);
+
+ done:
+  ;
+}
+
 struct testcase_t pem_tests[] = {
   { "encode", test_crypto_pem_encode, 0, NULL, NULL },
   { "decode", test_crypto_pem_decode, 0, NULL, NULL },
+  { "decode_crlf", test_crypto_pem_decode_crlf, 0, NULL, NULL },
   END_OF_TESTCASES
 };
diff -Nur tor-0.3.5.10/src/test/test_protover.c tor-0.3.5.12/src/test/test_protover.c
--- tor-0.3.5.10/src/test/test_protover.c	2019-10-11 23:48:21.000000000 +0200
+++ tor-0.3.5.12/src/test/test_protover.c	2020-11-09 14:55:53.000000000 +0100
@@ -25,7 +25,7 @@
 #else
   char *re_encoded = NULL;
 
-  const char *orig = "Foo=1,3 Bar=3 Baz= Quux=9-12,14,15-16,900";
+  const char *orig = "Foo=1,3 Bar=3 Baz= Quux=9-12,14,15-16";
   smartlist_t *elts = parse_protocol_list(orig);
 
   tt_assert(elts);
@@ -61,7 +61,7 @@
 
   e = smartlist_get(elts, 3);
   tt_str_op(e->name, OP_EQ, "Quux");
-  tt_int_op(smartlist_len(e->ranges), OP_EQ, 4);
+  tt_int_op(smartlist_len(e->ranges), OP_EQ, 3);
   {
     r = smartlist_get(e->ranges, 0);
     tt_int_op(r->low, OP_EQ, 9);
@@ -74,10 +74,6 @@
     r = smartlist_get(e->ranges, 2);
     tt_int_op(r->low, OP_EQ, 15);
     tt_int_op(r->high, OP_EQ, 16);
-
-    r = smartlist_get(e->ranges, 3);
-    tt_int_op(r->low, OP_EQ, 900);
-    tt_int_op(r->high, OP_EQ, 900);
   }
 
   re_encoded = encode_protocol_list(elts);
@@ -149,14 +145,14 @@
   tt_str_op(result, OP_EQ, "");
   tor_free(result);
 
-  smartlist_add(lst, (void*) "Foo=1-10,500 Bar=1,3-7,8");
+  smartlist_add(lst, (void*) "Foo=1-10,63 Bar=1,3-7,8");
   result = protover_compute_vote(lst, 1);
-  tt_str_op(result, OP_EQ, "Bar=1,3-8 Foo=1-10,500");
+  tt_str_op(result, OP_EQ, "Bar=1,3-8 Foo=1-10,63");
   tor_free(result);
 
-  smartlist_add(lst, (void*) "Quux=123-456,78 Bar=2-6,8 Foo=9");
+  smartlist_add(lst, (void*) "Quux=12-45 Bar=2-6,8 Foo=9");
   result = protover_compute_vote(lst, 1);
-  tt_str_op(result, OP_EQ, "Bar=1-8 Foo=1-10,500 Quux=78,123-456");
+  tt_str_op(result, OP_EQ, "Bar=1-8 Foo=1-10,63 Quux=12-45");
   tor_free(result);
 
   result = protover_compute_vote(lst, 2);
@@ -194,45 +190,16 @@
 
   /* Just below the threshold: Rust */
   smartlist_clear(lst);
-  smartlist_add(lst, (void*) "Sleen=1-500");
+  smartlist_add(lst, (void*) "Sleen=1-50");
   result = protover_compute_vote(lst, 1);
-  tt_str_op(result, OP_EQ, "Sleen=1-500");
+  tt_str_op(result, OP_EQ, "Sleen=1-50");
   tor_free(result);
 
   /* Just below the threshold: C */
   smartlist_clear(lst);
-  smartlist_add(lst, (void*) "Sleen=1-65536");
-  result = protover_compute_vote(lst, 1);
-  tt_str_op(result, OP_EQ, "Sleen=1-65536");
-  tor_free(result);
-
-  /* Large protover lists that exceed the threshold */
-
-  /* By adding two votes, C allows us to exceed the limit */
-  smartlist_add(lst, (void*) "Sleen=1-65536");
-  smartlist_add(lst, (void*) "Sleen=100000");
-  result = protover_compute_vote(lst, 1);
-  tt_str_op(result, OP_EQ, "Sleen=1-65536,100000");
-  tor_free(result);
-
-  /* Large integers */
-  smartlist_clear(lst);
-  smartlist_add(lst, (void*) "Sleen=4294967294");
+  smartlist_add(lst, (void*) "Sleen=1-63");
   result = protover_compute_vote(lst, 1);
-  tt_str_op(result, OP_EQ, "Sleen=4294967294");
-  tor_free(result);
-
-  /* This parses, but fails at the vote stage */
-  smartlist_clear(lst);
-  smartlist_add(lst, (void*) "Sleen=4294967295");
-  result = protover_compute_vote(lst, 1);
-  tt_str_op(result, OP_EQ, "");
-  tor_free(result);
-
-  smartlist_clear(lst);
-  smartlist_add(lst, (void*) "Sleen=4294967296");
-  result = protover_compute_vote(lst, 1);
-  tt_str_op(result, OP_EQ, "");
+  tt_str_op(result, OP_EQ, "Sleen=1-63");
   tor_free(result);
 
   /* Protocol name too long */
@@ -272,8 +239,8 @@
   tt_assert(! protover_all_supported("Wombat=9", &msg));
   tt_str_op(msg, OP_EQ, "Wombat=9");
   tor_free(msg);
-  tt_assert(! protover_all_supported("Link=999", &msg));
-  tt_str_op(msg, OP_EQ, "Link=999");
+  tt_assert(! protover_all_supported("Link=60", &msg));
+  tt_str_op(msg, OP_EQ, "Link=60");
   tor_free(msg);
 
   // Mix of things we support and things we don't
@@ -283,11 +250,11 @@
 
   /* Mix of things we support and don't support within a single protocol
    * which we do support */
-  tt_assert(! protover_all_supported("Link=3-999", &msg));
-  tt_str_op(msg, OP_EQ, "Link=6-999");
+  tt_assert(! protover_all_supported("Link=3-60", &msg));
+  tt_str_op(msg, OP_EQ, "Link=6-60");
   tor_free(msg);
-  tt_assert(! protover_all_supported("Link=1-3,345-666", &msg));
-  tt_str_op(msg, OP_EQ, "Link=345-666");
+  tt_assert(! protover_all_supported("Link=1-3,50-63", &msg));
+  tt_str_op(msg, OP_EQ, "Link=50-63");
   tor_free(msg);
   tt_assert(! protover_all_supported("Link=1-3,5-12", &msg));
   tt_str_op(msg, OP_EQ, "Link=6-12");
@@ -295,18 +262,8 @@
 
   /* Mix of protocols we do support and some we don't, where the protocols
    * we do support have some versions we don't support. */
-  tt_assert(! protover_all_supported("Link=1-3,5-12 Quokka=9000-9001", &msg));
-  tt_str_op(msg, OP_EQ, "Link=6-12 Quokka=9000-9001");
-  tor_free(msg);
-
-  /* We shouldn't be able to DoS ourselves parsing a large range. */
-  tt_assert(! protover_all_supported("Sleen=1-2147483648", &msg));
-  tt_str_op(msg, OP_EQ, "Sleen=1-2147483648");
-  tor_free(msg);
-
-  /* This case is allowed. */
-  tt_assert(! protover_all_supported("Sleen=1-4294967294", &msg));
-  tt_str_op(msg, OP_EQ, "Sleen=1-4294967294");
+  tt_assert(! protover_all_supported("Link=1-3,5-12 Quokka=40-41", &msg));
+  tt_str_op(msg, OP_EQ, "Link=6-12 Quokka=40-41");
   tor_free(msg);
 
   /* If we get a (barely) valid (but unsupported list, we say "yes, that's
@@ -566,9 +523,9 @@
     /* Will fail because of 4294967295. */
     { "Foo=1,3 Bar=3 Baz= Quux=9-12,14,15-16,900 Zn=1,4294967295",
        NULL },
-    { "Foo=1,3 Bar=3 Baz= Quux=9-12,14,15-16,900 Zn=1,4294967294",
-      "Bar=3 Foo=1,3 Quux=9-12,14-16,900 Zn=1,4294967294" },
-    { "Zu16=1,65536", "Zu16=1,65536" },
+    { "Foo=1,3 Bar=3 Baz= Quux=9-12,14,15-16,50 Zn=1,42",
+      "Bar=3 Foo=1,3 Quux=9-12,14-16,50 Zn=1,42" },
+    { "Zu16=1,63", "Zu16=1,63" },
     { "N-1=1,2", "N-1=1-2" },
     { "-1=4294967295", NULL },
     { "-1=3", "-1=3" },
@@ -602,12 +559,8 @@
     /* Large integers */
     { "Link=4294967296", NULL },
     /* Large range */
-    { "Sleen=1-501", "Sleen=1-501" },
+    { "Sleen=1-63", "Sleen=1-63" },
     { "Sleen=1-65537", NULL },
-    /* Both C/Rust implementations should be able to handle this mild DoS. */
-    { "Sleen=1-2147483648", NULL },
-    /* Rust tests are built in debug mode, so ints are bounds-checked. */
-    { "Sleen=1-4294967295", NULL },
   };
   unsigned u;
   smartlist_t *votes = smartlist_new();
diff -Nur tor-0.3.5.10/src/test/test_rendcache.c tor-0.3.5.12/src/test/test_rendcache.c
--- tor-0.3.5.10/src/test/test_rendcache.c	2019-10-11 23:48:21.000000000 +0200
+++ tor-0.3.5.12/src/test/test_rendcache.c	2020-09-18 16:42:47.000000000 +0200
@@ -954,6 +954,7 @@
   one->parsed = desc_one;
   desc_one->timestamp = time(NULL) + TIME_IN_THE_PAST;
   desc_one->pk = pk_generate(0);
+  rend_cache_increment_allocation(rend_cache_entry_allocation(one));
   strmap_set_lc(rend_cache, "foo1", one);
 
   rend_cache_free_all();
@@ -978,11 +979,13 @@
 
   // Handles NULL descriptor correctly
   e = tor_malloc_zero(sizeof(rend_cache_entry_t));
+  rend_cache_increment_allocation(rend_cache_entry_allocation(e));
   rend_cache_entry_free(e);
 
   // Handles non-NULL descriptor correctly
   e = tor_malloc_zero(sizeof(rend_cache_entry_t));
   e->desc = tor_malloc(10);
+  rend_cache_increment_allocation(rend_cache_entry_allocation(e));
   rend_cache_entry_free(e);
 
  /* done: */
@@ -1101,6 +1104,7 @@
   desc->timestamp = now;
   desc->pk = pk_generate(0);
   e->parsed = desc;
+  rend_cache_increment_allocation(rend_cache_entry_allocation(e));
   digestmap_set(rend_cache_v2_dir, key, e);
 
   /* Set the cutoff to minus 10 seconds. */
@@ -1250,4 +1254,3 @@
     test_rend_cache_validate_intro_point_failure, 0, NULL, NULL },
   END_OF_TESTCASES
 };
-
diff -Nur tor-0.3.5.10/src/test/test_router.c tor-0.3.5.12/src/test/test_router.c
--- tor-0.3.5.10/src/test/test_router.c	2019-10-11 23:48:21.000000000 +0200
+++ tor-0.3.5.12/src/test/test_router.c	2020-10-07 15:29:17.000000000 +0200
@@ -7,9 +7,12 @@
  * \brief Unittests for code in router.c
  **/
 
+#define CONFIG_PRIVATE
+#define CONNECTION_PRIVATE
 #include "core/or/or.h"
 #include "app/config/config.h"
 #include "core/mainloop/mainloop.h"
+#include "core/mainloop/connection.h"
 #include "feature/hibernate/hibernate.h"
 #include "feature/nodelist/routerinfo_st.h"
 #include "feature/nodelist/routerlist.h"
@@ -17,6 +20,9 @@
 #include "feature/stats/rephist.h"
 #include "lib/crypt_ops/crypto_curve25519.h"
 #include "lib/crypt_ops/crypto_ed25519.h"
+#include "lib/encoding/confline.h"
+
+#include "core/or/listener_connection_st.h"
 
 /* Test suite stuff */
 #include "test/test.h"
@@ -231,11 +237,124 @@
   UNMOCK(we_are_hibernating);
 }
 
+static smartlist_t *fake_connection_array = NULL;
+static smartlist_t *
+mock_get_connection_array(void)
+{
+  return fake_connection_array;
+}
+
+static void
+test_router_get_advertised_or_port(void *arg)
+{
+  (void)arg;
+  int r, w=0, n=0;
+  char *msg=NULL;
+  or_options_t *opts = options_new();
+  listener_connection_t *listener = NULL;
+  tor_addr_port_t ipv6;
+
+  // Test one failing case of router_get_advertised_ipv6_or_ap().
+  router_get_advertised_ipv6_or_ap(opts, &ipv6);
+  tt_str_op(fmt_addrport(&ipv6.addr, ipv6.port), OP_EQ, "[::]:0");
+
+  // And one failing case of router_get_advertised_or_port().
+  tt_int_op(0, OP_EQ, router_get_advertised_or_port_by_af(opts, AF_INET));
+  tt_int_op(0, OP_EQ, router_get_advertised_or_port(opts));
+
+  // Set up a couple of configured ports.
+  config_line_append(&opts->ORPort_lines, "ORPort", "[1234::5678]:auto");
+  config_line_append(&opts->ORPort_lines, "ORPort", "5.6.7.8:9999");
+  r = parse_ports(opts, 0, &msg, &n, &w);
+  tt_assert(r == 0);
+
+  // There are no listeners, so the "auto" case will turn up no results.
+  tt_int_op(0, OP_EQ, router_get_advertised_or_port_by_af(opts, AF_INET6));
+  router_get_advertised_ipv6_or_ap(opts, &ipv6);
+  tt_str_op(fmt_addrport(&ipv6.addr, ipv6.port), OP_EQ, "[::]:0");
+
+  // This will return the matching value from the configured port.
+  tt_int_op(9999, OP_EQ, router_get_advertised_or_port_by_af(opts, AF_INET));
+  tt_int_op(9999, OP_EQ, router_get_advertised_or_port(opts));
+
+  // Now set up a dummy listener.
+  MOCK(get_connection_array, mock_get_connection_array);
+  fake_connection_array = smartlist_new();
+  listener = listener_connection_new(CONN_TYPE_OR_LISTENER, AF_INET6);
+  TO_CONN(listener)->port = 54321;
+  smartlist_add(fake_connection_array, TO_CONN(listener));
+
+  // We should get a port this time.
+  tt_int_op(54321, OP_EQ, router_get_advertised_or_port_by_af(opts, AF_INET6));
+
+  // Test one succeeding case of router_get_advertised_ipv6_or_ap().
+  router_get_advertised_ipv6_or_ap(opts, &ipv6);
+  tt_str_op(fmt_addrport(&ipv6.addr, ipv6.port), OP_EQ,
+            "[1234::5678]:54321");
+
+  // This will return the matching value from the configured port.
+  tt_int_op(9999, OP_EQ, router_get_advertised_or_port_by_af(opts, AF_INET));
+  tt_int_op(9999, OP_EQ, router_get_advertised_or_port(opts));
+
+ done:
+  or_options_free(opts);
+  config_free_all();
+  smartlist_free(fake_connection_array);
+  connection_free_minimal(TO_CONN(listener));
+  UNMOCK(get_connection_array);
+}
+
+static void
+test_router_get_advertised_or_port_localhost(void *arg)
+{
+  (void)arg;
+  int r, w=0, n=0;
+  char *msg=NULL;
+  or_options_t *opts = options_new();
+  tor_addr_port_t ipv6;
+
+  // Set up a couple of configured ports on localhost.
+  config_line_append(&opts->ORPort_lines, "ORPort", "[::1]:9999");
+  config_line_append(&opts->ORPort_lines, "ORPort", "127.0.0.1:8888");
+  r = parse_ports(opts, 0, &msg, &n, &w);
+  tt_assert(r == 0);
+
+  // We should refuse to advertise them, since we have default dirauths.
+  router_get_advertised_ipv6_or_ap(opts, &ipv6);
+  tt_str_op(fmt_addrport(&ipv6.addr, ipv6.port), OP_EQ, "[::]:0");
+  // But the lower-level function should still report the correct value
+  tt_int_op(9999, OP_EQ, router_get_advertised_or_port_by_af(opts, AF_INET6));
+
+  // The IPv4 checks are done in resolve_my_address(), which doesn't use
+  // ORPorts so we can't test them here. (See #33681.) Both these lower-level
+  // functions should still report the correct value.
+  tt_int_op(8888, OP_EQ, router_get_advertised_or_port_by_af(opts, AF_INET));
+  tt_int_op(8888, OP_EQ, router_get_advertised_or_port(opts));
+
+  // Now try with a fake authority set up.
+  config_line_append(&opts->DirAuthorities, "DirAuthority",
+                     "127.0.0.1:1066 "
+                     "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA");
+
+  tt_int_op(9999, OP_EQ, router_get_advertised_or_port_by_af(opts, AF_INET6));
+  router_get_advertised_ipv6_or_ap(opts, &ipv6);
+  tt_str_op(fmt_addrport(&ipv6.addr, ipv6.port), OP_EQ, "[::1]:9999");
+
+  tt_int_op(8888, OP_EQ, router_get_advertised_or_port_by_af(opts, AF_INET));
+  tt_int_op(8888, OP_EQ, router_get_advertised_or_port(opts));
+
+ done:
+  or_options_free(opts);
+  config_free_all();
+}
+
 #define ROUTER_TEST(name, flags)                          \
   { #name, test_router_ ## name, flags, NULL, NULL }
 
 struct testcase_t router_tests[] = {
   ROUTER_TEST(check_descriptor_bandwidth_changed, TT_FORK),
   ROUTER_TEST(dump_router_to_string_no_bridge_distribution_method, TT_FORK),
+  ROUTER_TEST(get_advertised_or_port, TT_FORK),
+  ROUTER_TEST(get_advertised_or_port_localhost, TT_FORK),
   END_OF_TESTCASES
 };
diff -Nur tor-0.3.5.10/src/test/test_socks.c tor-0.3.5.12/src/test/test_socks.c
--- tor-0.3.5.10/src/test/test_socks.c	2019-10-11 23:48:21.000000000 +0200
+++ tor-0.3.5.12/src/test/test_socks.c	2020-05-06 22:58:12.000000000 +0200
@@ -778,7 +778,7 @@
   for (i = 0; i < ARRAY_LENGTH(commands); ++i) {
     for (j = 0; j < commands[i].len; ++j) {
       switch (commands[i].setup) {
-        default: /* Falls through */
+        default: FALLTHROUGH;
         case NONE:
           /* This test calls for no setup on the socks state. */
           break;
diff -Nur tor-0.3.5.10/src/test/test_tortls.c tor-0.3.5.12/src/test/test_tortls.c
--- tor-0.3.5.10/src/test/test_tortls.c	2019-10-11 23:48:21.000000000 +0200
+++ tor-0.3.5.12/src/test/test_tortls.c	2020-07-09 15:28:53.000000000 +0200
@@ -105,6 +105,17 @@
   "Yy1RT69d0rwYc5u/vnqODz1IjvT90smsrkBumGt791FAFeg=\n"
   "-----END CERTIFICATE-----\n";
 
+static tor_x509_cert_t *fixed_x509_cert = NULL;
+static tor_x509_cert_t *
+get_peer_cert_mock_return_fixed(tor_tls_t *tls)
+{
+  (void)tls;
+  if (fixed_x509_cert)
+    return tor_x509_cert_dup(fixed_x509_cert);
+  else
+    return NULL;
+}
+
 tor_x509_cert_impl_t *
 read_cert_from(const char *str)
 {
@@ -513,6 +524,67 @@
   crypto_pk_free(k);
 }
 
+static void
+test_tortls_cert_matches_key(void *ignored)
+{
+  (void)ignored;
+
+  tor_x509_cert_impl_t *cert1 = NULL,
+                       *cert2 = NULL,
+                       *cert3 = NULL,
+                       *cert4 = NULL;
+  tor_x509_cert_t *c1 = NULL, *c2 = NULL, *c3 = NULL, *c4 = NULL;
+  crypto_pk_t *k1 = NULL, *k2 = NULL, *k3 = NULL;
+
+  k1 = pk_generate(1);
+  k2 = pk_generate(2);
+  k3 = pk_generate(3);
+
+  cert1 = tor_tls_create_certificate(k1, k2, "A", "B", 1000);
+  cert2 = tor_tls_create_certificate(k1, k3, "C", "D", 1000);
+  cert3 = tor_tls_create_certificate(k2, k3, "C", "D", 1000);
+  cert4 = tor_tls_create_certificate(k3, k2, "E", "F", 1000);
+
+  tt_assert(cert1 && cert2 && cert3 && cert4);
+
+  c1 = tor_x509_cert_new(cert1); cert1 = NULL;
+  c2 = tor_x509_cert_new(cert2); cert2 = NULL;
+  c3 = tor_x509_cert_new(cert3); cert3 = NULL;
+  c4 = tor_x509_cert_new(cert4); cert4 = NULL;
+
+  tt_assert(c1 && c2 && c3 && c4);
+
+  MOCK(tor_tls_get_peer_cert, get_peer_cert_mock_return_fixed);
+
+  fixed_x509_cert = NULL;
+  /* If the peer has no certificate, it shouldn't match anything. */
+  tt_assert(! tor_tls_cert_matches_key(NULL, c1));
+  tt_assert(! tor_tls_cert_matches_key(NULL, c2));
+  tt_assert(! tor_tls_cert_matches_key(NULL, c3));
+  tt_assert(! tor_tls_cert_matches_key(NULL, c4));
+  fixed_x509_cert = c1;
+  /* If the peer has a certificate, it should match every cert with the same
+   * subject key. */
+  tt_assert(tor_tls_cert_matches_key(NULL, c1));
+  tt_assert(tor_tls_cert_matches_key(NULL, c2));
+  tt_assert(! tor_tls_cert_matches_key(NULL, c3));
+  tt_assert(! tor_tls_cert_matches_key(NULL, c4));
+
+ done:
+  tor_x509_cert_free(c1);
+  tor_x509_cert_free(c2);
+  tor_x509_cert_free(c3);
+  tor_x509_cert_free(c4);
+  if (cert1) tor_x509_cert_impl_free(cert1);
+  if (cert2) tor_x509_cert_impl_free(cert2);
+  if (cert3) tor_x509_cert_impl_free(cert3);
+  if (cert4) tor_x509_cert_impl_free(cert4);
+  crypto_pk_free(k1);
+  crypto_pk_free(k2);
+  crypto_pk_free(k3);
+  UNMOCK(tor_tls_get_peer_cert);
+}
+
 #define LOCAL_TEST_CASE(name, flags)                            \
   { #name, test_tortls_##name, (flags|TT_FORK), NULL, NULL }
 
@@ -533,5 +605,6 @@
   LOCAL_TEST_CASE(is_server, 0),
   LOCAL_TEST_CASE(bridge_init, TT_FORK),
   LOCAL_TEST_CASE(verify, TT_FORK),
+  LOCAL_TEST_CASE(cert_matches_key, 0),
   END_OF_TESTCASES
 };
diff -Nur tor-0.3.5.10/src/test/test_tortls_openssl.c tor-0.3.5.12/src/test/test_tortls_openssl.c
--- tor-0.3.5.10/src/test/test_tortls_openssl.c	2019-10-11 23:48:21.000000000 +0200
+++ tor-0.3.5.12/src/test/test_tortls_openssl.c	2020-07-09 15:28:53.000000000 +0200
@@ -479,75 +479,6 @@
 }
 #endif
 
-static tor_x509_cert_t *fixed_x509_cert = NULL;
-static tor_x509_cert_t *
-get_peer_cert_mock_return_fixed(tor_tls_t *tls)
-{
-  (void)tls;
-  if (fixed_x509_cert)
-    return tor_x509_cert_dup(fixed_x509_cert);
-  else
-    return NULL;
-}
-
-static void
-test_tortls_cert_matches_key(void *ignored)
-{
-  (void)ignored;
-
-  X509 *cert1 = NULL, *cert2 = NULL, *cert3 = NULL, *cert4 = NULL;
-  tor_x509_cert_t *c1 = NULL, *c2 = NULL, *c3 = NULL, *c4 = NULL;
-  crypto_pk_t *k1 = NULL, *k2 = NULL, *k3 = NULL;
-
-  k1 = pk_generate(1);
-  k2 = pk_generate(2);
-  k3 = pk_generate(3);
-
-  cert1 = tor_tls_create_certificate(k1, k2, "A", "B", 1000);
-  cert2 = tor_tls_create_certificate(k1, k3, "C", "D", 1000);
-  cert3 = tor_tls_create_certificate(k2, k3, "C", "D", 1000);
-  cert4 = tor_tls_create_certificate(k3, k2, "E", "F", 1000);
-
-  tt_assert(cert1 && cert2 && cert3 && cert4);
-
-  c1 = tor_x509_cert_new(cert1); cert1 = NULL;
-  c2 = tor_x509_cert_new(cert2); cert2 = NULL;
-  c3 = tor_x509_cert_new(cert3); cert3 = NULL;
-  c4 = tor_x509_cert_new(cert4); cert4 = NULL;
-
-  tt_assert(c1 && c2 && c3 && c4);
-
-  MOCK(tor_tls_get_peer_cert, get_peer_cert_mock_return_fixed);
-
-  fixed_x509_cert = NULL;
-  /* If the peer has no certificate, it shouldn't match anything. */
-  tt_assert(! tor_tls_cert_matches_key(NULL, c1));
-  tt_assert(! tor_tls_cert_matches_key(NULL, c2));
-  tt_assert(! tor_tls_cert_matches_key(NULL, c3));
-  tt_assert(! tor_tls_cert_matches_key(NULL, c4));
-  fixed_x509_cert = c1;
-  /* If the peer has a certificate, it should match every cert with the same
-   * subject key. */
-  tt_assert(tor_tls_cert_matches_key(NULL, c1));
-  tt_assert(tor_tls_cert_matches_key(NULL, c2));
-  tt_assert(! tor_tls_cert_matches_key(NULL, c3));
-  tt_assert(! tor_tls_cert_matches_key(NULL, c4));
-
- done:
-  tor_x509_cert_free(c1);
-  tor_x509_cert_free(c2);
-  tor_x509_cert_free(c3);
-  tor_x509_cert_free(c4);
-  if (cert1) X509_free(cert1);
-  if (cert2) X509_free(cert2);
-  if (cert3) X509_free(cert3);
-  if (cert4) X509_free(cert4);
-  crypto_pk_free(k1);
-  crypto_pk_free(k2);
-  crypto_pk_free(k3);
-  UNMOCK(tor_tls_get_peer_cert);
-}
-
 #ifndef OPENSSL_OPAQUE
 static void
 test_tortls_cert_get_key(void *ignored)
@@ -2279,7 +2210,6 @@
   INTRUSIVE_TEST_CASE(get_error, TT_FORK),
   LOCAL_TEST_CASE(always_accept_verify_cb, 0),
   INTRUSIVE_TEST_CASE(x509_cert_free, 0),
-  LOCAL_TEST_CASE(cert_matches_key, 0),
   INTRUSIVE_TEST_CASE(cert_get_key, 0),
   LOCAL_TEST_CASE(get_my_client_auth_key, TT_FORK),
   INTRUSIVE_TEST_CASE(get_ciphersuite_name, 0),
diff -Nur tor-0.3.5.10/src/test/testing_common.c tor-0.3.5.12/src/test/testing_common.c
--- tor-0.3.5.10/src/test/testing_common.c	2019-10-11 23:48:21.000000000 +0200
+++ tor-0.3.5.12/src/test/testing_common.c	2020-10-07 14:03:52.000000000 +0200
@@ -278,6 +278,8 @@
   control_initialize_event_queue();
   configure_backtrace_handler(get_version());
 
+  unsigned num=1, den=1;
+
   for (i_out = i = 1; i < c; ++i) {
     if (!strcmp(v[i], "--warn")) {
       loglevel = LOG_WARN;
@@ -289,6 +291,19 @@
       loglevel = LOG_DEBUG;
     } else if (!strcmp(v[i], "--accel")) {
       accel_crypto = 1;
+    } else if (!strcmp(v[i], "--fraction")) {
+      if (i+1 == c) {
+        printf("--fraction needs an argument.\n");
+        return 1;
+      }
+      const char *fracstr = v[++i];
+      char ch;
+      if (sscanf(fracstr, "%u/%u%c", &num, &den, &ch) != 2) {
+        printf("--fraction expects a fraction as an input.\n");
+      }
+      if (den == 0 || num == 0 || num > den) {
+        printf("--fraction expects a valid fraction as an input.\n");
+      }
     } else {
       v[i_out++] = v[i];
     }
@@ -348,6 +363,48 @@
 
   atexit(remove_directory);
 
+  /* Look for TOR_SKIP_TESTCASES: a space-separated list of tests to skip. */
+  const char *skip_tests = getenv("TOR_SKIP_TESTCASES");
+  if (skip_tests) {
+    smartlist_t *skip = smartlist_new();
+    smartlist_split_string(skip, skip_tests, NULL,
+                           SPLIT_IGNORE_BLANK, -1);
+    int n = 0;
+    SMARTLIST_FOREACH_BEGIN(skip, char *, cp) {
+      n += tinytest_skip(testgroups, cp);
+      tor_free(cp);
+    } SMARTLIST_FOREACH_END(cp);
+    printf("Skipping %d testcases.\n", n);
+    smartlist_free(skip);
+  }
+
+  if (den != 1) {
+    // count the tests. Linear but fast.
+    unsigned n_tests = 0;
+    struct testgroup_t *tg;
+    struct testcase_t *tc;
+    for (tg = testgroups; tg->prefix != NULL; ++tg) {
+      for (tc = tg->cases; tc->name != NULL; ++tc) {
+        ++n_tests;
+      }
+    }
+    // Which tests should we run?  This can give iffy results if den is huge
+    // but it doesn't actually matter in practice.
+    unsigned tests_per_chunk = CEIL_DIV(n_tests, den);
+    unsigned start_at = (num-1) * tests_per_chunk;
+
+    // Skip the tests that are outside of the range.
+    unsigned idx = 0;
+    for (tg = testgroups; tg->prefix != NULL; ++tg) {
+      for (tc = tg->cases; tc->name != NULL; ++tc) {
+        if (idx < start_at || idx >= start_at + tests_per_chunk) {
+          tc->flags |= TT_SKIP;
+        }
+        ++idx;
+      }
+    }
+  }
+
   int have_failed = (tinytest_main(c, v, testgroups) != 0);
 
   free_pregenerated_keys();
diff -Nur tor-0.3.5.10/src/test/unittest_part1.sh tor-0.3.5.12/src/test/unittest_part1.sh
--- tor-0.3.5.10/src/test/unittest_part1.sh	1970-01-01 01:00:00.000000000 +0100
+++ tor-0.3.5.12/src/test/unittest_part1.sh	2020-10-07 14:03:52.000000000 +0200
@@ -0,0 +1,3 @@
+#!/bin/sh
+
+"${abs_top_builddir:-.}/src/test/test" --fraction 1/8
diff -Nur tor-0.3.5.10/src/test/unittest_part2.sh tor-0.3.5.12/src/test/unittest_part2.sh
--- tor-0.3.5.10/src/test/unittest_part2.sh	1970-01-01 01:00:00.000000000 +0100
+++ tor-0.3.5.12/src/test/unittest_part2.sh	2020-10-07 14:03:52.000000000 +0200
@@ -0,0 +1,3 @@
+#!/bin/sh
+
+"${abs_top_builddir:-.}/src/test/test" --fraction 2/8
diff -Nur tor-0.3.5.10/src/test/unittest_part3.sh tor-0.3.5.12/src/test/unittest_part3.sh
--- tor-0.3.5.10/src/test/unittest_part3.sh	1970-01-01 01:00:00.000000000 +0100
+++ tor-0.3.5.12/src/test/unittest_part3.sh	2020-10-07 14:03:52.000000000 +0200
@@ -0,0 +1,3 @@
+#!/bin/sh
+
+"${abs_top_builddir:-.}/src/test/test" --fraction 3/8
diff -Nur tor-0.3.5.10/src/test/unittest_part4.sh tor-0.3.5.12/src/test/unittest_part4.sh
--- tor-0.3.5.10/src/test/unittest_part4.sh	1970-01-01 01:00:00.000000000 +0100
+++ tor-0.3.5.12/src/test/unittest_part4.sh	2020-10-07 14:03:52.000000000 +0200
@@ -0,0 +1,3 @@
+#!/bin/sh
+
+"${abs_top_builddir:-.}/src/test/test" --fraction 4/8
diff -Nur tor-0.3.5.10/src/test/unittest_part5.sh tor-0.3.5.12/src/test/unittest_part5.sh
--- tor-0.3.5.10/src/test/unittest_part5.sh	1970-01-01 01:00:00.000000000 +0100
+++ tor-0.3.5.12/src/test/unittest_part5.sh	2020-10-07 14:03:52.000000000 +0200
@@ -0,0 +1,3 @@
+#!/bin/sh
+
+"${abs_top_builddir:-.}/src/test/test" --fraction 5/8
diff -Nur tor-0.3.5.10/src/test/unittest_part6.sh tor-0.3.5.12/src/test/unittest_part6.sh
--- tor-0.3.5.10/src/test/unittest_part6.sh	1970-01-01 01:00:00.000000000 +0100
+++ tor-0.3.5.12/src/test/unittest_part6.sh	2020-10-07 14:03:52.000000000 +0200
@@ -0,0 +1,3 @@
+#!/bin/sh
+
+"${abs_top_builddir:-.}/src/test/test" --fraction 6/8
diff -Nur tor-0.3.5.10/src/test/unittest_part7.sh tor-0.3.5.12/src/test/unittest_part7.sh
--- tor-0.3.5.10/src/test/unittest_part7.sh	1970-01-01 01:00:00.000000000 +0100
+++ tor-0.3.5.12/src/test/unittest_part7.sh	2020-10-07 14:03:52.000000000 +0200
@@ -0,0 +1,3 @@
+#!/bin/sh
+
+"${abs_top_builddir:-.}/src/test/test" --fraction 7/8
diff -Nur tor-0.3.5.10/src/test/unittest_part8.sh tor-0.3.5.12/src/test/unittest_part8.sh
--- tor-0.3.5.10/src/test/unittest_part8.sh	1970-01-01 01:00:00.000000000 +0100
+++ tor-0.3.5.12/src/test/unittest_part8.sh	2020-10-07 14:03:52.000000000 +0200
@@ -0,0 +1,3 @@
+#!/bin/sh
+
+"${abs_top_builddir:-.}/src/test/test" --fraction 8/8
diff -Nur tor-0.3.5.10/src/win32/orconfig.h tor-0.3.5.12/src/win32/orconfig.h
--- tor-0.3.5.10/src/win32/orconfig.h	2020-03-13 21:57:42.000000000 +0100
+++ tor-0.3.5.12/src/win32/orconfig.h	2020-11-09 23:14:58.000000000 +0100
@@ -218,7 +218,7 @@
 #define USING_TWOS_COMPLEMENT
 
 /* Version number of package */
-#define VERSION "0.3.5.10"
+#define VERSION "0.3.5.12"
 
 
 
