[tor-commits] [tor/master] Merge branch 'maint-0.3.5' into bug31107_035

asn at torproject.org asn at torproject.org
Wed Sep 25 11:19:13 UTC 2019


commit 7589995111b452cf7e92f5e9b5d94df244cbdbb9
Merge: 3c97ab3c2 046183714
Author: Nick Mathewson <nickm at torproject.org>
Date:   Tue Sep 17 09:16:52 2019 -0400

    Merge branch 'maint-0.3.5' into bug31107_035

 .appveyor.yml                                      |  119 +
 .gitignore                                         |  139 +-
 .gitlab-ci.yml                                     |   45 +
 .gitmodules                                        |    3 +
 .travis.yml                                        |   78 +-
 CODE_OF_CONDUCT                                    |    7 +
 CONTRIBUTING                                       |   39 +
 ChangeLog                                          | 9099 +++++++++++++++++++-
 Doxyfile.in                                        | 1184 ++-
 INSTALL                                            |   34 -
 LICENSE                                            |   32 +-
 Makefile.am                                        |  276 +-
 README                                             |    3 +
 ReleaseNotes                                       | 7319 +++++++++++++++-
 acinclude.m4                                       |   25 +-
 autogen.sh                                         |    4 +-
 changes/29241_diagnostic                           |    4 +
 changes/bug13221                                   |    5 +
 changes/bug21394.2                                 |    7 -
 changes/bug22619                                   |    3 +
 changes/bug23512                                   |    6 -
 changes/bug23681                                   |    5 -
 changes/bug23790                                   |    6 -
 changes/bug24104                                   |    4 -
 changes/bug24661                                   |    3 +
 changes/bug24903                                   |    5 -
 changes/bug25113                                   |    5 -
 changes/bug25116                                   |    4 -
 changes/bug25733                                   |    4 -
 changes/bug27073                                   |    4 -
 changes/bug27197                                   |    3 +
 changes/bug27199                                   |    3 +
 changes/bug27316                                   |    3 -
 changes/bug27658                                   |    6 -
 changes/bug27709                                   |    4 -
 changes/bug27740                                   |    4 +
 changes/bug27741                                   |    5 +
 changes/bug27750                                   |    6 +
 changes/bug27800                                   |    4 +
 changes/bug27804                                   |    3 +
 changes/bug27841                                   |    7 +
 changes/bug27963_timeradd                          |    4 +
 changes/bug27968                                   |    3 +
 changes/bug28115                                   |    3 +
 changes/bug28127                                   |    7 +
 changes/bug28183                                   |    4 +
 changes/bug28298                                   |    4 +
 changes/bug28303                                   |    3 +
 changes/bug28348_034                               |    5 +
 changes/bug28399                                   |    4 +
 changes/bug28419                                   |    3 +
 changes/bug28435                                   |    3 +
 changes/bug28441                                   |    4 +
 changes/bug28454                                   |    4 +
 changes/bug28485                                   |    3 +
 changes/bug28524                                   |    4 +
 changes/bug28554                                   |    3 +
 changes/bug28562                                   |    5 +
 changes/bug28568                                   |    4 +
 changes/bug28569                                   |    3 +
 changes/bug28612                                   |    4 +
 changes/bug28619                                   |    6 +
 changes/bug28656                                   |    3 +
 changes/bug28698                                   |    3 +
 changes/bug28895                                   |    5 +
 changes/bug28920                                   |    6 +
 changes/bug28938                                   |    4 +
 changes/bug28974                                   |    3 +
 changes/bug28979                                   |    4 +
 changes/bug28981                                   |    5 +
 changes/bug28995                                   |    5 +
 changes/bug29017                                   |    4 +
 changes/bug29034                                   |    5 +
 changes/bug29040                                   |    4 +
 changes/bug29042                                   |    5 +
 changes/bug29135                                   |    5 +
 changes/bug29144                                   |    5 +
 changes/bug29161                                   |    3 +
 changes/bug29175_035                               |    4 +
 changes/bug29241                                   |    6 +
 changes/bug29244                                   |    4 +
 changes/bug29530_035                               |    5 +
 changes/bug29601                                   |    6 +
 changes/bug29670                                   |    4 +
 changes/bug29875                                   |   11 +
 changes/bug29922                                   |    4 +
 changes/bug30011                                   |    4 +
 changes/bug30040                                   |    9 +
 changes/bug30148                                   |    4 +
 changes/bug30189                                   |    4 +
 changes/bug30190                                   |    3 +
 changes/bug30316                                   |    4 +
 changes/bug30452                                   |    3 +
 changes/bug30475                                   |    4 +
 changes/bug30713                                   |    5 +
 changes/bug30744                                   |    3 +
 changes/bug30894                                   |    4 +
 changes/bug31003                                   |    4 +
 changes/bug31463                                   |    3 +
 changes/cid1444119                                 |    3 +
 changes/geoip-2018-09-06                           |    4 -
 changes/geoip-2018-10-09                           |    4 -
 changes/rust_asan                                  |    8 +
 changes/ticket19566                                |    6 +
 changes/ticket27252                                |    6 -
 changes/ticket27471                                |    5 +
 changes/ticket27738                                |    4 -
 changes/ticket27751                                |    2 +
 changes/ticket27838                                |    4 +
 changes/ticket27913                                |    3 +
 changes/ticket27995                                |    4 +
 changes/ticket28026                                |    3 +
 changes/ticket28113                                |    5 +
 changes/ticket28128                                |    4 +
 changes/ticket28229_diag                           |    3 +
 changes/ticket28275                                |    4 +
 changes/ticket28318                                |    3 +
 changes/ticket28459                                |    4 +
 changes/ticket28574                                |    4 +
 changes/ticket28668                                |    3 +
 changes/ticket28669                                |    6 +
 changes/ticket28838                                |    8 +
 changes/ticket28851                                |    4 +
 changes/ticket28879                                |    5 +
 changes/ticket28881                                |    4 +
 changes/ticket28883                                |    4 +
 changes/ticket28912                                |    6 +
 changes/ticket28924                                |    4 +
 changes/ticket28973                                |    6 +
 changes/ticket29026                                |    4 +
 changes/ticket29160                                |    4 +
 changes/ticket29168                                |    5 +
 changes/ticket29435                                |    3 +
 changes/ticket29617                                |    4 +
 changes/ticket29702                                |    4 +
 changes/ticket29806                                |    7 +
 changes/ticket29962                                |    3 +
 changes/ticket30117                                |    4 +
 changes/ticket30234                                |    2 +
 changes/ticket30454                                |   10 +
 changes/ticket30591                                |    3 +
 changes/ticket30694                                |    3 +
 changes/ticket30871                                |    6 +
 changes/ticket31554                                |    4 +
 config.rust.in                                     |   24 +
 configure.ac                                       |  967 ++-
 contrib/dist/tor.service.in                        |    2 +-
 contrib/include.am                                 |    1 -
 contrib/operator-tools/linux-tor-prio.sh           |    2 +-
 contrib/win32build/package_nsis-mingw.sh           |   95 -
 contrib/win32build/tor-mingw.nsi.in                |    2 +-
 doc/HACKING/CodeStructure.md                       |  129 +
 doc/HACKING/CodingStandards.md                     |  237 +-
 doc/HACKING/CodingStandardsRust.md                 |  523 ++
 doc/HACKING/Fuzzing.md                             |  123 +
 doc/HACKING/GettingStarted.md                      |    5 +-
 doc/HACKING/GettingStartedRust.md                  |  183 +
 doc/HACKING/HelpfulTools.md                        |  132 +-
 doc/HACKING/HowToReview.md                         |    3 +
 doc/HACKING/Module.md                              |  111 +
 doc/HACKING/ReleasingTor.md                        |  135 +-
 doc/HACKING/Tracing.md                             |   91 +
 doc/HACKING/WritingTests.md                        |   12 +-
 doc/HACKING/android/Simpleperf.md                  |   98 +
 doc/include.am                                     |   28 +-
 doc/tor-print-ed-signing-cert.1.txt                |   32 +
 doc/tor-resolve.1.txt                              |    2 +-
 doc/tor.1.txt                                      | 1706 ++--
 doc/torify.1.txt                                   |   20 +-
 doc/torrc_format.txt                               |   15 +-
 m4/ax_check_sign.m4                                |    4 +-
 m4/pc_from_ucontext.m4                             |   20 +-
 scripts/README                                     |    6 +
 scripts/coccinelle/ceil_div.cocci                  |    6 +
 scripts/coccinelle/test-operator-cleanup           |   11 +
 scripts/coccinelle/test_assert_int.cocci           |   49 +
 scripts/coccinelle/test_assert_null.cocci          |   11 +
 scripts/coccinelle/test_assert_zero.cocci          |    5 +
 scripts/codegen/fuzzing_include_am.py              |  154 +
 scripts/codegen/gen_server_ciphers.py              |   64 +-
 scripts/codegen/get_mozilla_ciphers.py             |   15 +-
 scripts/codegen/makedesc.py                        |    2 +-
 scripts/codegen/run_trunnel.sh                     |   10 +-
 scripts/maint/analyze_callgraph.py                 |  259 -
 scripts/maint/annotate_ifdef_directives            |   74 +
 scripts/maint/checkIncludes.py                     |  115 +
 scripts/maint/checkOptionDocs.pl.in                |    2 +-
 scripts/maint/checkSpace.pl                        |  148 +-
 scripts/maint/display_callgraph.py                 |   41 -
 scripts/maint/fallback.blacklist                   |  229 -
 scripts/maint/fallback.whitelist                   |  525 +-
 scripts/maint/format_changelog.py                  |    4 +-
 scripts/maint/generateFallbackDirLine.py           |   38 +
 scripts/maint/generate_callgraph.sh                |   14 -
 scripts/maint/lintChanges.py                       |   72 +-
 scripts/maint/lookupFallbackDirContact.py          |   28 +
 scripts/maint/rectify_include_paths.py             |   60 +
 scripts/maint/redox.py                             |    4 +-
 scripts/maint/run_calltool.sh                      |   29 +
 scripts/maint/sortChanges.py                       |    2 +-
 scripts/maint/updateCopyright.pl                   |    4 +-
 scripts/maint/updateFallbackDirs.py                |  815 +-
 scripts/maint/updateRustDependencies.sh            |   45 +
 scripts/test/appveyor-irc-notify.py                |  219 +
 scripts/test/chutney-git-bisect.sh                 |   62 +
 scripts/test/cov-diff                              |   14 +-
 scripts/test/cov-exclude                           |    6 +
 scripts/test/coverage                              |    8 +-
 scripts/test/scan-build.sh                         |   61 +-
 src/{or => app/config}/auth_dirs.inc               |    0
 src/app/config/config.c                            | 8521 ++++++++++++++++++
 src/app/config/config.h                            |  300 +
 src/app/config/confparse.c                         | 1207 +++
 src/app/config/confparse.h                         |  233 +
 src/{or => app/config}/fallback_dirs.inc           |    0
 src/app/config/or_options_st.h                     | 1077 +++
 src/app/config/or_state_st.h                       |   92 +
 src/app/config/statefile.c                         |  728 ++
 src/app/config/statefile.h                         |   36 +
 src/app/include.am                                 |   35 +
 src/app/main/main.c                                | 1519 ++++
 src/app/main/main.h                                |   31 +
 src/app/main/ntmain.c                              |  785 ++
 src/app/main/ntmain.h                              |   28 +
 src/app/main/tor_main.c                            |   42 +
 src/common/Makefile.nmake                          |   28 -
 src/common/address.c                               | 2162 -----
 src/common/address.h                               |  379 -
 src/common/address_set.c                           |  129 -
 src/common/address_set.h                           |   35 -
 src/common/aes.c                                   |  404 -
 src/common/aes.h                                   |   27 -
 src/common/backtrace.c                             |  248 -
 src/common/backtrace.h                             |   21 -
 src/common/ciphers.inc                             |  140 -
 src/common/compat.c                                | 3555 --------
 src/common/compat.h                                |  747 --
 src/common/compat_libevent.c                       |  285 -
 src/common/compat_libevent.h                       |   75 -
 src/common/compat_openssl.h                        |   47 -
 src/common/compat_pthreads.c                       |  349 -
 src/common/compat_threads.c                        |  332 -
 src/common/compat_threads.h                        |  151 -
 src/common/compat_time.c                           |  656 --
 src/common/compat_time.h                           |  162 -
 src/common/compat_winthreads.c                     |  250 -
 src/common/container.c                             | 1517 ----
 src/common/container.h                             |  725 --
 src/common/crypto.c                                | 3432 --------
 src/common/crypto.h                                |  340 -
 src/common/crypto_curve25519.c                     |  354 -
 src/common/crypto_curve25519.h                     |   87 -
 src/common/crypto_ed25519.c                        |  736 --
 src/common/crypto_ed25519.h                        |  131 -
 src/common/crypto_format.c                         |  277 -
 src/common/crypto_format.h                         |   46 -
 src/common/crypto_pwbox.c                          |  212 -
 src/common/crypto_pwbox.h                          |   20 -
 src/common/crypto_s2k.c                            |  468 -
 src/common/crypto_s2k.h                            |   73 -
 src/common/di_ops.c                                |  274 -
 src/common/di_ops.h                                |   50 -
 src/common/handles.h                               |  153 -
 src/common/include.am                              |  175 -
 src/common/log.c                                   | 1395 ---
 src/common/memarea.c                               |  306 -
 src/common/memarea.h                               |   24 -
 src/common/procmon.c                               |  343 -
 src/common/procmon.h                               |   33 -
 src/common/pubsub.c                                |  129 -
 src/common/pubsub.h                                |  179 -
 src/common/sandbox.c                               | 2016 -----
 src/common/sandbox.h                               |  182 -
 src/common/testsupport.h                           |   90 -
 src/common/timers.c                                |  293 -
 src/common/timers.h                                |   24 -
 src/common/torgzip.c                               |  586 --
 src/common/torgzip.h                               |   72 -
 src/common/torint.h                                |  367 -
 src/common/torlog.h                                |  251 -
 src/common/tortls.c                                | 2579 ------
 src/common/tortls.h                                |  265 -
 src/common/util.c                                  | 5774 -------------
 src/common/util.h                                  |  561 --
 src/common/util_bug.c                              |  115 -
 src/common/util_bug.h                              |  204 -
 src/common/util_format.c                           |  562 --
 src/common/util_format.h                           |   34 -
 src/common/util_process.c                          |  158 -
 src/common/util_process.h                          |   26 -
 src/common/workqueue.c                             |  538 --
 src/common/workqueue.h                             |   49 -
 src/config/torrc.minimal.in-staging                |   18 +-
 src/config/torrc.sample.in                         |   49 +-
 src/core/crypto/hs_ntor.c                          |  620 ++
 src/core/crypto/hs_ntor.h                          |   69 +
 src/core/crypto/onion_crypto.c                     |  311 +
 src/core/crypto/onion_crypto.h                     |   47 +
 src/core/crypto/onion_fast.c                       |  144 +
 src/core/crypto/onion_fast.h                       |   41 +
 src/core/crypto/onion_ntor.c                       |  341 +
 src/core/crypto/onion_ntor.h                       |   65 +
 src/core/crypto/onion_tap.c                        |  246 +
 src/core/crypto/onion_tap.h                        |   40 +
 src/core/crypto/relay_crypto.c                     |  332 +
 src/core/crypto/relay_crypto.h                     |   31 +
 src/core/include.am                                |  404 +
 src/core/mainloop/connection.c                     | 5504 ++++++++++++
 src/core/mainloop/connection.h                     |  353 +
 src/core/mainloop/cpuworker.c                      |  600 ++
 src/core/mainloop/cpuworker.h                      |   37 +
 src/core/mainloop/mainloop.c                       | 2942 +++++++
 src/core/mainloop/mainloop.h                       |  114 +
 src/core/mainloop/netstatus.c                      |   28 +
 src/core/mainloop/netstatus.h                      |   13 +
 src/core/mainloop/periodic.c                       |  174 +
 src/core/mainloop/periodic.h                       |   88 +
 src/core/or/addr_policy_st.h                       |   46 +
 src/core/or/address_set.c                          |   71 +
 src/core/or/address_set.h                          |   31 +
 src/core/or/cell_queue_st.h                        |   29 +
 src/core/or/cell_st.h                              |   20 +
 src/core/or/channel.c                              | 3476 ++++++++
 src/core/or/channel.h                              |  780 ++
 src/core/or/channelpadding.c                       |  794 ++
 src/core/or/channelpadding.h                       |   43 +
 src/core/or/channeltls.c                           | 2485 ++++++
 src/core/or/channeltls.h                           |   79 +
 src/core/or/circuit_st.h                           |  182 +
 src/core/or/circuitbuild.c                         | 3012 +++++++
 src/core/or/circuitbuild.h                         |  102 +
 src/core/or/circuitlist.c                          | 2853 ++++++
 src/core/or/circuitlist.h                          |  250 +
 src/core/or/circuitmux.c                           | 1364 +++
 src/core/or/circuitmux.h                           |  162 +
 src/core/or/circuitmux_ewma.c                      |  829 ++
 src/core/or/circuitmux_ewma.h                      |   30 +
 src/core/or/circuitstats.c                         | 1951 +++++
 src/core/or/circuitstats.h                         |  213 +
 src/core/or/circuituse.c                           | 3142 +++++++
 src/core/or/circuituse.h                           |   93 +
 src/core/or/command.c                              |  703 ++
 src/core/or/command.h                              |   31 +
 src/core/or/connection_edge.c                      | 4534 ++++++++++
 src/core/or/connection_edge.h                      |  279 +
 src/core/or/connection_or.c                        | 3026 +++++++
 src/core/or/connection_or.h                        |  166 +
 src/core/or/connection_st.h                        |  149 +
 src/core/or/cpath_build_state_st.h                 |   38 +
 src/core/or/crypt_path_reference_st.h              |   23 +
 src/core/or/crypt_path_st.h                        |   70 +
 src/core/or/destroy_cell_queue_st.h                |   27 +
 src/core/or/dos.c                                  |  801 ++
 src/core/or/dos.h                                  |  140 +
 src/core/or/edge_connection_st.h                   |   77 +
 src/core/or/entry_connection_st.h                  |  100 +
 src/core/or/entry_port_cfg_st.h                    |   54 +
 src/core/or/extend_info_st.h                       |   30 +
 src/core/or/half_edge_st.h                         |   34 +
 src/core/or/listener_connection_st.h               |   25 +
 src/core/or/onion.c                                |  720 ++
 src/core/or/onion.h                                |   90 +
 src/core/or/or.h                                   | 1094 +++
 src/core/or/or_circuit_st.h                        |   80 +
 src/core/or/or_connection_st.h                     |   92 +
 src/core/or/or_handshake_certs_st.h                |   40 +
 src/core/or/or_handshake_state_st.h                |   78 +
 src/core/or/origin_circuit_st.h                    |  294 +
 src/core/or/policies.c                             | 3145 +++++++
 src/core/or/policies.h                             |  187 +
 src/core/or/port_cfg_st.h                          |   35 +
 src/core/or/protover.c                             |  942 ++
 src/core/or/protover.h                             |   97 +
 src/core/or/protover_rust.c                        |   34 +
 src/core/or/reasons.c                              |  497 ++
 src/core/or/reasons.h                              |   34 +
 src/core/or/relay.c                                | 3169 +++++++
 src/core/or/relay.h                                |  124 +
 src/core/or/relay_crypto_st.h                      |   31 +
 src/core/or/scheduler.c                            |  768 ++
 src/core/or/scheduler.h                            |  218 +
 src/core/or/scheduler_kist.c                       |  844 ++
 src/core/or/scheduler_vanilla.c                    |  175 +
 src/core/or/server_port_cfg_st.h                   |   20 +
 src/core/or/socks_request_st.h                     |   77 +
 src/core/or/status.c                               |  252 +
 src/core/or/status.h                               |   18 +
 src/core/or/tor_version_st.h                       |   32 +
 src/core/or/var_cell_st.h                          |   23 +
 src/core/or/versions.c                             |  422 +
 src/core/or/versions.h                             |   44 +
 src/core/proto/proto_cell.c                        |   86 +
 src/core/proto/proto_cell.h                        |   17 +
 src/core/proto/proto_control0.c                    |   26 +
 src/core/proto/proto_control0.h                    |   14 +
 src/core/proto/proto_ext_or.c                      |   40 +
 src/core/proto/proto_ext_or.h                      |   22 +
 src/core/proto/proto_http.c                        |  171 +
 src/core/proto/proto_http.h                        |   24 +
 src/core/proto/proto_socks.c                       | 1133 +++
 src/core/proto/proto_socks.h                       |   21 +
 src/ext/OpenBSD_malloc_Linux.c                     |    2 +-
 src/ext/byteorder.h                                |   71 +
 src/ext/csiphash.c                                 |   50 +-
 src/ext/curve25519_donna/curve25519-donna-c64.c    |    2 +-
 src/ext/curve25519_donna/curve25519-donna.c        |    2 +-
 src/ext/ed25519/donna/ed25519-donna-impl-base.h    |   12 +-
 .../donna/ed25519-donna-portable-identify.h        |    2 +-
 src/ext/ed25519/donna/ed25519-hash-custom.h        |   31 +
 src/ext/ed25519/donna/ed25519-randombytes-custom.h |    2 +-
 src/ext/ed25519/donna/ed25519_donna_tor.h          |    7 +-
 src/ext/ed25519/donna/ed25519_tor.c                |   43 +-
 src/ext/ed25519/ref10/blinding.c                   |   51 +-
 src/ext/ed25519/ref10/crypto_hash_sha512.h         |   30 +-
 src/ext/ed25519/ref10/crypto_int32.h               |    2 +-
 src/ext/ed25519/ref10/crypto_int64.h               |    2 +-
 src/ext/ed25519/ref10/crypto_uint32.h              |    2 +-
 src/ext/ed25519/ref10/crypto_uint64.h              |    2 +-
 src/ext/ed25519/ref10/crypto_verify_32.h           |    3 +-
 src/ext/ed25519/ref10/ed25519_ref10.h              |    6 +-
 src/ext/ed25519/ref10/keypair.c                    |    4 +-
 src/ext/ed25519/ref10/randombytes.h                |    2 +-
 src/ext/getdelim.c                                 |   79 +
 src/ext/ht.h                                       |    4 +-
 src/ext/include.am                                 |    4 +-
 src/ext/keccak-tiny/keccak-tiny-unrolled.c         |   21 +-
 src/ext/keccak-tiny/keccak-tiny.h                  |    2 +-
 src/ext/mulodi/mulodi4.c                           |    2 +-
 src/ext/rust                                       |    1 +
 src/ext/siphash.h                                  |    1 +
 src/ext/timeouts/timeout-bitops.c                  |    3 +-
 src/ext/timeouts/timeout.c                         |    4 +-
 src/ext/tinytest.c                                 |   13 +-
 src/ext/trunnel/trunnel-impl.h                     |    5 +-
 src/ext/trunnel/trunnel.c                          |   10 +-
 src/ext/trunnel/trunnel.h                          |    4 +-
 src/feature/api/tor_api.c                          |  167 +
 src/feature/api/tor_api.h                          |  129 +
 src/feature/api/tor_api_internal.h                 |   29 +
 src/feature/client/addressmap.c                    | 1156 +++
 src/feature/client/addressmap.h                    |   65 +
 src/feature/client/bridges.c                       | 1029 +++
 src/feature/client/bridges.h                       |   80 +
 src/feature/client/circpathbias.c                  | 1641 ++++
 src/feature/client/circpathbias.h                  |   29 +
 src/feature/client/dnsserv.c                       |  415 +
 src/feature/client/dnsserv.h                       |   27 +
 src/feature/client/entrynodes.c                    | 3824 ++++++++
 src/feature/client/entrynodes.h                    |  639 ++
 src/feature/client/transports.c                    | 1738 ++++
 src/feature/client/transports.h                    |  147 +
 src/feature/control/control.c                      | 7902 +++++++++++++++++
 src/feature/control/control.h                      |  417 +
 src/feature/control/control_connection_st.h        |   46 +
 src/feature/control/fmt_serverstatus.c             |  104 +
 src/feature/control/fmt_serverstatus.h             |   18 +
 src/feature/control/getinfo_geoip.c                |   45 +
 src/feature/control/getinfo_geoip.h                |   14 +
 src/feature/dirauth/authmode.c                     |   70 +
 src/feature/dirauth/authmode.h                     |   46 +
 src/feature/dirauth/bwauth.c                       |  459 +
 src/feature/dirauth/bwauth.h                       |   58 +
 src/feature/dirauth/dircollate.c                   |  327 +
 src/feature/dirauth/dircollate.h                   |   70 +
 src/feature/dirauth/dirvote.c                      | 4658 ++++++++++
 src/feature/dirauth/dirvote.h                      |  250 +
 src/feature/dirauth/dsigs_parse.c                  |  282 +
 src/feature/dirauth/dsigs_parse.h                  |   22 +
 src/feature/dirauth/guardfraction.c                |  333 +
 src/feature/dirauth/guardfraction.h                |   24 +
 src/feature/dirauth/keypin.c                       |  515 ++
 src/feature/dirauth/keypin.h                       |   47 +
 src/feature/dirauth/ns_detached_signatures_st.h    |   22 +
 src/feature/dirauth/process_descs.c                |  839 ++
 src/feature/dirauth/process_descs.h                |   38 +
 src/feature/dirauth/reachability.c                 |  207 +
 src/feature/dirauth/reachability.h                 |   36 +
 src/feature/dirauth/recommend_pkg.c                |   90 +
 src/feature/dirauth/recommend_pkg.h                |   17 +
 src/feature/dirauth/shared_random.c                | 1291 +++
 src/feature/dirauth/shared_random.h                |  194 +
 src/feature/dirauth/shared_random_state.c          | 1340 +++
 src/feature/dirauth/shared_random_state.h          |  148 +
 src/feature/dirauth/vote_microdesc_hash_st.h       |   22 +
 src/feature/dirauth/voteflags.c                    |  644 ++
 src/feature/dirauth/voteflags.h                    |   31 +
 src/feature/dircache/cached_dir_st.h               |   25 +
 src/feature/dircache/conscache.c                   |  627 ++
 src/feature/dircache/conscache.h                   |   66 +
 src/feature/dircache/consdiffmgr.c                 | 1945 +++++
 src/feature/dircache/consdiffmgr.h                 |   75 +
 src/feature/dircache/dircache.c                    | 1740 ++++
 src/feature/dircache/dircache.h                    |   43 +
 src/feature/dircache/dirserv.c                     |  918 ++
 src/feature/dircache/dirserv.h                     |  119 +
 src/feature/dirclient/dir_server_st.h              |   54 +
 src/feature/dirclient/dirclient.c                  | 3206 +++++++
 src/feature/dirclient/dirclient.h                  |  172 +
 src/feature/dirclient/dlstatus.c                   |  422 +
 src/feature/dirclient/dlstatus.h                   |   58 +
 src/feature/dirclient/download_status_st.h         |   65 +
 src/feature/dircommon/consdiff.c                   | 1414 +++
 src/feature/dircommon/consdiff.h                   |   99 +
 src/feature/dircommon/dir_connection_st.h          |   67 +
 src/feature/dircommon/directory.c                  |  651 ++
 src/feature/dircommon/directory.h                  |  129 +
 src/feature/dircommon/fp_pair.c                    |  315 +
 src/feature/dircommon/fp_pair.h                    |   56 +
 src/feature/dircommon/vote_timing_st.h             |   24 +
 src/feature/dircommon/voting_schedule.c            |  194 +
 src/feature/dircommon/voting_schedule.h            |   65 +
 src/feature/dirparse/authcert_members.i            |   13 +
 src/feature/dirparse/authcert_parse.c              |  207 +
 src/feature/dirparse/authcert_parse.h              |   18 +
 src/feature/dirparse/microdesc_parse.c             |  267 +
 src/feature/dirparse/microdesc_parse.h             |   20 +
 src/feature/dirparse/ns_parse.c                    | 1685 ++++
 src/feature/dirparse/ns_parse.h                    |   45 +
 src/feature/dirparse/parsecommon.c                 |  458 +
 src/feature/dirparse/parsecommon.h                 |  324 +
 src/feature/dirparse/policy_parse.c                |  224 +
 src/feature/dirparse/policy_parse.h                |   25 +
 src/feature/dirparse/routerparse.c                 | 1245 +++
 src/feature/dirparse/routerparse.h                 |   49 +
 src/feature/dirparse/sigcommon.c                   |  185 +
 src/feature/dirparse/sigcommon.h                   |   48 +
 src/feature/dirparse/signing.c                     |   98 +
 src/feature/dirparse/signing.h                     |   23 +
 src/feature/dirparse/unparseable.c                 |  591 ++
 src/feature/dirparse/unparseable.h                 |   56 +
 src/feature/hibernate/hibernate.c                  | 1267 +++
 src/feature/hibernate/hibernate.h                  |   61 +
 src/feature/hs/hs_cache.c                          |  986 +++
 src/feature/hs/hs_cache.h                          |  130 +
 src/feature/hs/hs_cell.c                           |  952 ++
 src/feature/hs/hs_cell.h                           |  109 +
 src/feature/hs/hs_circuit.c                        | 1271 +++
 src/feature/hs/hs_circuit.h                        |   75 +
 src/feature/hs/hs_circuitmap.c                     |  585 ++
 src/feature/hs/hs_circuitmap.h                     |  112 +
 src/feature/hs/hs_client.c                         | 1945 +++++
 src/feature/hs/hs_client.h                         |  119 +
 src/feature/hs/hs_common.c                         | 1829 ++++
 src/feature/hs/hs_common.h                         |  288 +
 src/feature/hs/hs_config.c                         |  696 ++
 src/feature/hs/hs_config.h                         |   25 +
 src/feature/hs/hs_control.c                        |  261 +
 src/feature/hs/hs_control.h                        |   52 +
 src/feature/hs/hs_descriptor.c                     | 3073 +++++++
 src/feature/hs/hs_descriptor.h                     |  346 +
 src/feature/hs/hs_ident.c                          |  127 +
 src/feature/hs/hs_ident.h                          |  150 +
 src/feature/hs/hs_intropoint.c                     |  609 ++
 src/feature/hs/hs_intropoint.h                     |   64 +
 src/feature/hs/hs_service.c                        | 4170 +++++++++
 src/feature/hs/hs_service.h                        |  444 +
 src/feature/hs/hs_stats.c                          |   58 +
 src/feature/hs/hs_stats.h                          |   14 +
 src/feature/hs/hsdir_index_st.h                    |   24 +
 src/feature/hs_common/replaycache.c                |  209 +
 src/feature/hs_common/replaycache.h                |   67 +
 src/feature/hs_common/shared_random_client.c       |  293 +
 src/feature/hs_common/shared_random_client.h       |   48 +
 src/feature/keymgt/loadkey.c                       |  755 ++
 src/feature/keymgt/loadkey.h                       |   55 +
 src/feature/nodelist/authcert.c                    | 1208 +++
 src/feature/nodelist/authcert.h                    |   60 +
 src/feature/nodelist/authority_cert_st.h           |   32 +
 src/feature/nodelist/desc_store_st.h               |   39 +
 src/feature/nodelist/describe.c                    |  183 +
 src/feature/nodelist/describe.h                    |   25 +
 src/feature/nodelist/dirlist.c                     |  422 +
 src/feature/nodelist/dirlist.h                     |   47 +
 src/feature/nodelist/document_signature_st.h       |   29 +
 src/feature/nodelist/extrainfo_st.h                |   30 +
 src/feature/nodelist/fmt_routerstatus.c            |  253 +
 src/feature/nodelist/fmt_routerstatus.h            |   41 +
 src/feature/nodelist/microdesc.c                   | 1063 +++
 src/feature/nodelist/microdesc.h                   |   60 +
 src/feature/nodelist/microdesc_st.h                |   80 +
 src/feature/nodelist/networkstatus.c               | 2723 ++++++
 src/feature/nodelist/networkstatus.h               |  160 +
 src/feature/nodelist/networkstatus_sr_info_st.h    |   23 +
 src/feature/nodelist/networkstatus_st.h            |  104 +
 src/feature/nodelist/networkstatus_voter_info_st.h |   30 +
 src/feature/nodelist/nickname.c                    |   62 +
 src/feature/nodelist/nickname.h                    |   19 +
 src/feature/nodelist/node_select.c                 | 1111 +++
 src/feature/nodelist/node_select.h                 |  102 +
 src/feature/nodelist/node_st.h                     |  102 +
 src/feature/nodelist/nodelist.c                    | 2620 ++++++
 src/feature/nodelist/nodelist.h                    |  169 +
 src/feature/nodelist/routerinfo.c                  |   79 +
 src/feature/nodelist/routerinfo.h                  |   27 +
 src/feature/nodelist/routerinfo_st.h               |  115 +
 src/feature/nodelist/routerlist.c                  | 3234 +++++++
 src/feature/nodelist/routerlist.h                  |  207 +
 src/feature/nodelist/routerlist_st.h               |   40 +
 src/feature/nodelist/routerset.c                   |  463 +
 src/feature/nodelist/routerset.h                   |   89 +
 src/feature/nodelist/routerstatus_st.h             |   80 +
 src/feature/nodelist/signed_descriptor_st.h        |   61 +
 src/feature/nodelist/torcert.c                     |  764 ++
 src/feature/nodelist/torcert.h                     |  116 +
 src/feature/nodelist/vote_routerstatus_st.h        |   41 +
 src/feature/relay/dns.c                            | 2187 +++++
 src/feature/relay/dns.h                            |   72 +
 src/feature/relay/dns_structs.h                    |  102 +
 src/feature/relay/ext_orport.c                     |  662 ++
 src/feature/relay/ext_orport.h                     |   64 +
 src/feature/relay/onion_queue.c                    |  361 +
 src/feature/relay/onion_queue.h                    |   23 +
 src/feature/relay/router.c                         | 3128 +++++++
 src/feature/relay/router.h                         |  122 +
 src/feature/relay/routerkeys.c                     |  740 ++
 src/feature/relay/routerkeys.h                     |   45 +
 src/feature/relay/routermode.c                     |   80 +
 src/feature/relay/routermode.h                     |   24 +
 src/feature/relay/selftest.c                       |  301 +
 src/feature/relay/selftest.h                       |   24 +
 src/feature/rend/rend_authorized_client_st.h       |   18 +
 .../rend/rend_encoded_v2_service_descriptor_st.h   |   17 +
 src/feature/rend/rend_intro_point_st.h             |   76 +
 src/feature/rend/rend_service_descriptor_st.h      |   34 +
 src/feature/rend/rendcache.c                       | 1008 +++
 src/feature/rend/rendcache.h                       |  130 +
 src/feature/rend/rendclient.c                      | 1228 +++
 src/feature/rend/rendclient.h                      |   51 +
 src/feature/rend/rendcommon.c                      | 1047 +++
 src/feature/rend/rendcommon.h                      |   82 +
 src/feature/rend/rendmid.c                         |  370 +
 src/feature/rend/rendmid.h                         |   25 +
 src/feature/rend/rendparse.c                       |  600 ++
 src/feature/rend/rendparse.h                       |   32 +
 src/feature/rend/rendservice.c                     | 4487 ++++++++++
 src/feature/rend/rendservice.h                     |  222 +
 src/feature/stats/geoip_stats.c                    | 1425 +++
 src/feature/stats/geoip_stats.h                    |  139 +
 src/feature/stats/predict_ports.c                  |  313 +
 src/feature/stats/predict_ports.h                  |   30 +
 src/feature/stats/rephist.c                        | 2933 +++++++
 src/feature/stats/rephist.h                        |  133 +
 src/include.am                                     |   43 +-
 src/lib/arch/.may_include                          |    2 +
 src/lib/arch/bytes.h                               |  182 +
 src/lib/arch/include.am                            |    3 +
 src/lib/cc/.may_include                            |    1 +
 src/lib/cc/compat_compiler.h                       |  220 +
 src/lib/cc/include.am                              |    4 +
 src/lib/cc/torint.h                                |  128 +
 src/lib/compress/.may_include                      |   12 +
 src/lib/compress/compress.c                        |  681 ++
 src/lib/compress/compress.h                        |   99 +
 src/lib/compress/compress_buf.c                    |   83 +
 src/lib/compress/compress_lzma.c                   |  362 +
 src/lib/compress/compress_lzma.h                   |   46 +
 src/lib/compress/compress_none.c                   |   54 +
 src/lib/compress/compress_none.h                   |   20 +
 src/lib/compress/compress_zlib.c                   |  304 +
 src/lib/compress/compress_zlib.h                   |   46 +
 src/lib/compress/compress_zstd.c                   |  541 ++
 src/lib/compress/compress_zstd.h                   |   53 +
 src/lib/compress/include.am                        |   26 +
 src/lib/container/.may_include                     |   18 +
 src/lib/container/bitarray.h                       |   86 +
 src/lib/container/bloomfilt.c                      |  113 +
 src/lib/container/bloomfilt.h                      |   41 +
 src/lib/container/buffers.c                        |  932 ++
 src/lib/container/buffers.h                        |  122 +
 src/lib/container/handles.h                        |  153 +
 src/lib/container/include.am                       |   27 +
 src/lib/container/map.c                            |  413 +
 src/lib/container/map.h                            |  261 +
 src/lib/container/order.c                          |   48 +
 src/lib/container/order.h                          |   60 +
 src/lib/container/smartlist.c                      |  866 ++
 src/lib/container/smartlist.h                      |  168 +
 src/lib/crypt_ops/.may_include                     |   24 +
 src/lib/crypt_ops/aes.h                            |   31 +
 src/lib/crypt_ops/aes_nss.c                        |  106 +
 src/lib/crypt_ops/aes_openssl.c                    |  410 +
 src/lib/crypt_ops/compat_openssl.h                 |   57 +
 src/lib/crypt_ops/crypto_cipher.c                  |  190 +
 src/lib/crypt_ops/crypto_cipher.h                  |   57 +
 src/lib/crypt_ops/crypto_curve25519.c              |  366 +
 src/lib/crypt_ops/crypto_curve25519.h              |   85 +
 src/lib/crypt_ops/crypto_dh.c                      |  113 +
 src/lib/crypt_ops/crypto_dh.h                      |   64 +
 src/lib/crypt_ops/crypto_dh_nss.c                  |  209 +
 src/lib/crypt_ops/crypto_dh_openssl.c              |  477 +
 src/lib/crypt_ops/crypto_digest.c                  |  828 ++
 src/lib/crypt_ops/crypto_digest.h                  |  132 +
 src/lib/crypt_ops/crypto_ed25519.c                 |  821 ++
 src/lib/crypt_ops/crypto_ed25519.h                 |  144 +
 src/lib/crypt_ops/crypto_format.c                  |  305 +
 src/lib/crypt_ops/crypto_format.h                  |   50 +
 src/lib/crypt_ops/crypto_hkdf.c                    |  201 +
 src/lib/crypt_ops/crypto_hkdf.h                    |   27 +
 src/lib/crypt_ops/crypto_init.c                    |  204 +
 src/lib/crypt_ops/crypto_init.h                    |   36 +
 src/lib/crypt_ops/crypto_nss_mgt.c                 |  132 +
 src/lib/crypt_ops/crypto_nss_mgt.h                 |   34 +
 src/lib/crypt_ops/crypto_ope.c                     |  185 +
 src/lib/crypt_ops/crypto_ope.h                     |   46 +
 src/lib/crypt_ops/crypto_openssl_mgt.c             |  398 +
 src/lib/crypt_ops/crypto_openssl_mgt.h             |   89 +
 src/lib/crypt_ops/crypto_pwbox.c                   |  219 +
 src/lib/crypt_ops/crypto_pwbox.h                   |   28 +
 src/lib/crypt_ops/crypto_rand.c                    |  731 ++
 src/lib/crypt_ops/crypto_rand.h                    |   53 +
 src/lib/crypt_ops/crypto_rsa.c                     |  672 ++
 src/lib/crypt_ops/crypto_rsa.h                     |  145 +
 src/lib/crypt_ops/crypto_rsa_nss.c                 |  738 ++
 src/lib/crypt_ops/crypto_rsa_openssl.c             |  590 ++
 src/lib/crypt_ops/crypto_s2k.c                     |  525 ++
 src/lib/crypt_ops/crypto_s2k.h                     |   78 +
 src/lib/crypt_ops/crypto_util.c                    |  111 +
 src/lib/crypt_ops/crypto_util.h                    |   21 +
 src/lib/crypt_ops/digestset.c                      |   58 +
 src/lib/crypt_ops/digestset.h                      |   29 +
 src/lib/crypt_ops/include.am                       |   70 +
 src/lib/ctime/.may_include                         |    5 +
 src/lib/ctime/di_ops.c                             |  278 +
 src/lib/ctime/di_ops.h                             |   55 +
 src/lib/ctime/include.am                           |   25 +
 src/lib/defs/.may_include                          |    1 +
 src/lib/defs/dh_sizes.h                            |   22 +
 src/lib/defs/digest_sizes.h                        |   27 +
 src/lib/defs/include.am                            |    5 +
 src/lib/defs/x25519_sizes.h                        |   36 +
 src/lib/encoding/.may_include                      |   10 +
 src/lib/encoding/binascii.c                        |  520 ++
 src/lib/encoding/binascii.h                        |   60 +
 src/lib/encoding/confline.c                        |  402 +
 src/lib/encoding/confline.h                        |   78 +
 src/lib/encoding/cstring.c                         |  138 +
 src/lib/encoding/cstring.h                         |   19 +
 src/lib/encoding/include.am                        |   26 +
 src/lib/encoding/keyval.c                          |   52 +
 src/lib/encoding/keyval.h                          |   17 +
 src/lib/encoding/pem.c                             |  106 +
 src/lib/encoding/pem.h                             |   26 +
 src/lib/encoding/time_fmt.c                        |  516 ++
 src/lib/encoding/time_fmt.h                        |   44 +
 src/lib/err/.may_include                           |    3 +
 src/lib/err/backtrace.c                            |  286 +
 src/lib/err/backtrace.h                            |   35 +
 src/lib/err/include.am                             |   19 +
 src/lib/err/torerr.c                               |  238 +
 src/lib/err/torerr.h                               |   47 +
 src/lib/evloop/.may_include                        |   16 +
 src/lib/evloop/compat_libevent.c                   |  535 ++
 src/lib/evloop/compat_libevent.h                   |  104 +
 src/lib/evloop/include.am                          |   26 +
 src/lib/evloop/procmon.c                           |  339 +
 src/lib/evloop/procmon.h                           |   34 +
 src/lib/evloop/timers.c                            |  328 +
 src/lib/evloop/timers.h                            |   35 +
 src/lib/evloop/token_bucket.c                      |  258 +
 src/lib/evloop/token_bucket.h                      |  117 +
 src/lib/evloop/workqueue.c                         |  682 ++
 src/lib/evloop/workqueue.h                         |   70 +
 src/lib/fdio/.may_include                          |    4 +
 src/lib/fdio/fdio.c                                |  115 +
 src/lib/fdio/fdio.h                                |   23 +
 src/lib/fdio/include.am                            |   17 +
 src/lib/fs/.may_include                            |   16 +
 src/lib/fs/conffile.c                              |  174 +
 src/lib/fs/conffile.h                              |   23 +
 src/lib/fs/dir.c                                   |  367 +
 src/lib/fs/dir.h                                   |   33 +
 src/lib/fs/files.c                                 |  721 ++
 src/lib/fs/files.h                                 |  145 +
 src/lib/fs/freespace.c                             |   63 +
 src/lib/fs/include.am                              |   37 +
 src/lib/fs/lockfile.c                              |  145 +
 src/lib/fs/lockfile.h                              |   20 +
 src/lib/fs/mmap.c                                  |  240 +
 src/lib/fs/mmap.h                                  |   41 +
 src/lib/fs/path.c                                  |  295 +
 src/lib/fs/path.h                                  |   30 +
 src/lib/fs/storagedir.c                            |  606 ++
 src/lib/fs/storagedir.h                            |   64 +
 src/lib/fs/userdb.c                                |  138 +
 src/lib/fs/userdb.h                                |   26 +
 src/lib/fs/winlib.c                                |   30 +
 src/lib/fs/winlib.h                                |   22 +
 src/lib/geoip/.may_include                         |   13 +
 src/lib/geoip/country.h                            |   16 +
 src/lib/geoip/geoip.c                              |  510 ++
 src/lib/geoip/geoip.h                              |   50 +
 src/lib/geoip/include.am                           |   17 +
 src/lib/include.libdonna.am                        |   24 +
 src/lib/intmath/.may_include                       |    4 +
 src/lib/intmath/addsub.c                           |   28 +
 src/lib/intmath/addsub.h                           |   19 +
 src/lib/intmath/bits.c                             |   94 +
 src/lib/intmath/bits.h                             |   22 +
 src/lib/intmath/cmp.h                              |   39 +
 src/lib/intmath/include.am                         |   25 +
 src/lib/intmath/logic.h                            |   20 +
 src/lib/intmath/muldiv.c                           |   81 +
 src/lib/intmath/muldiv.h                           |   28 +
 src/lib/intmath/weakrng.c                          |   60 +
 src/lib/intmath/weakrng.h                          |   31 +
 src/lib/lock/.may_include                          |    5 +
 src/lib/lock/compat_mutex.c                        |   40 +
 src/lib/lock/compat_mutex.h                        |   66 +
 src/lib/lock/compat_mutex_pthreads.c               |  103 +
 src/lib/lock/compat_mutex_winthreads.c             |   46 +
 src/lib/lock/include.am                            |   24 +
 src/lib/log/.may_include                           |   15 +
 src/lib/log/escape.c                               |  137 +
 src/lib/log/escape.h                               |   23 +
 src/lib/log/git_revision.c                         |   24 +
 src/lib/log/git_revision.h                         |   12 +
 src/lib/log/include.am                             |   36 +
 src/lib/log/log.c                                  | 1483 ++++
 src/lib/log/log.h                                  |  276 +
 src/lib/log/ratelim.c                              |   60 +
 src/lib/log/ratelim.h                              |   53 +
 src/lib/log/util_bug.c                             |  161 +
 src/lib/log/util_bug.h                             |  246 +
 src/lib/log/win32err.c                             |   61 +
 src/lib/log/win32err.h                             |   22 +
 src/lib/malloc/.may_include                        |    6 +
 src/lib/malloc/include.am                          |   21 +
 src/lib/malloc/malloc.c                            |  230 +
 src/lib/malloc/malloc.h                            |   92 +
 src/lib/math/.may_include                          |    5 +
 src/lib/math/fp.c                                  |  119 +
 src/lib/math/fp.h                                  |   23 +
 src/lib/math/include.am                            |   20 +
 src/lib/math/laplace.c                             |   73 +
 src/lib/math/laplace.h                             |   22 +
 src/lib/memarea/.may_include                       |    7 +
 src/lib/memarea/include.am                         |   17 +
 src/lib/memarea/memarea.c                          |  403 +
 src/lib/memarea/memarea.h                          |   35 +
 src/lib/meminfo/.may_include                       |    8 +
 src/lib/meminfo/include.am                         |   17 +
 src/lib/meminfo/meminfo.c                          |  180 +
 src/lib/meminfo/meminfo.h                          |   21 +
 src/lib/net/.may_include                           |   15 +
 src/lib/net/address.c                              | 2057 +++++
 src/lib/net/address.h                              |  388 +
 src/lib/net/alertsock.c                            |  295 +
 src/lib/net/alertsock.h                            |   45 +
 src/lib/net/buffers_net.c                          |  202 +
 src/lib/net/buffers_net.h                          |   27 +
 src/lib/net/gethostname.c                          |   30 +
 src/lib/net/gethostname.h                          |   19 +
 src/lib/net/inaddr.c                               |  267 +
 src/lib/net/inaddr.h                               |   27 +
 src/lib/net/inaddr_st.h                            |  107 +
 src/lib/net/include.am                             |   34 +
 src/lib/net/nettypes.h                             |   44 +
 src/lib/net/resolve.c                              |  424 +
 src/lib/net/resolve.h                              |   58 +
 src/lib/net/socket.c                               |  697 ++
 src/lib/net/socket.h                               |  118 +
 src/lib/net/socketpair.c                           |  214 +
 src/lib/net/socketpair.h                           |   19 +
 src/lib/net/socks5_status.h                        |   32 +
 src/lib/osinfo/.may_include                        |    5 +
 src/lib/osinfo/include.am                          |   17 +
 src/lib/osinfo/uname.c                             |  149 +
 src/lib/osinfo/uname.h                             |   18 +
 src/lib/process/.may_include                       |   17 +
 src/lib/process/daemon.c                           |  187 +
 src/lib/process/daemon.h                           |   21 +
 src/lib/process/env.c                              |  224 +
 src/lib/process/env.h                              |   41 +
 src/lib/process/include.am                         |   29 +
 src/lib/process/pidfile.c                          |   52 +
 src/lib/process/pidfile.h                          |   16 +
 src/lib/process/restrict.c                         |  285 +
 src/lib/process/restrict.h                         |   27 +
 src/lib/process/setuid.c                           |  386 +
 src/lib/process/setuid.h                           |   22 +
 src/lib/process/subprocess.c                       | 1236 +++
 src/lib/process/subprocess.h                       |  134 +
 src/lib/process/waitpid.c                          |  154 +
 src/lib/process/waitpid.h                          |   29 +
 src/lib/sandbox/.may_include                       |   15 +
 src/lib/sandbox/include.am                         |   18 +
 src/{common => lib/sandbox}/linux_syscalls.inc     |    0
 src/lib/sandbox/sandbox.c                          | 1808 ++++
 src/lib/sandbox/sandbox.h                          |  150 +
 src/lib/smartlist_core/.may_include                |    7 +
 src/lib/smartlist_core/include.am                  |   21 +
 src/lib/smartlist_core/smartlist_core.c            |  234 +
 src/lib/smartlist_core/smartlist_core.h            |  100 +
 src/lib/smartlist_core/smartlist_foreach.h         |  133 +
 src/lib/smartlist_core/smartlist_split.c           |   92 +
 src/lib/smartlist_core/smartlist_split.h           |   20 +
 src/lib/string/.may_include                        |   10 +
 src/lib/string/compat_ctype.c                      |   72 +
 src/lib/string/compat_ctype.h                      |   67 +
 src/lib/string/compat_string.c                     |   74 +
 src/lib/string/compat_string.h                     |   62 +
 src/lib/string/include.am                          |   27 +
 src/lib/string/parse_int.c                         |  131 +
 src/lib/string/parse_int.h                         |   25 +
 src/lib/string/printf.c                            |  167 +
 src/lib/string/printf.h                            |   30 +
 src/lib/string/scanf.c                             |  317 +
 src/lib/string/scanf.h                             |   24 +
 src/lib/string/util_string.c                       |  543 ++
 src/lib/string/util_string.h                       |   57 +
 src/lib/term/.may_include                          |    9 +
 src/lib/term/getpass.c                             |  120 +
 src/lib/term/getpass.h                             |   18 +
 src/lib/term/include.am                            |   24 +
 src/lib/testsupport/.may_include                   |    0
 src/lib/testsupport/include.am                     |    3 +
 src/lib/testsupport/testsupport.h                  |  103 +
 src/lib/thread/.may_include                        |    7 +
 src/lib/thread/compat_pthreads.c                   |  270 +
 src/lib/thread/compat_threads.c                    |  111 +
 src/lib/thread/compat_winthreads.c                 |  223 +
 src/lib/thread/include.am                          |   27 +
 src/lib/thread/numcpus.c                           |   98 +
 src/lib/thread/numcpus.h                           |   16 +
 src/lib/thread/threads.h                           |  168 +
 src/lib/time/.may_include                          |   11 +
 src/lib/time/compat_time.c                         |  869 ++
 src/lib/time/compat_time.h                         |  235 +
 src/lib/time/include.am                            |   19 +
 src/lib/time/tvdiff.c                              |  189 +
 src/lib/time/tvdiff.h                              |   23 +
 src/lib/tls/.may_include                           |   17 +
 src/lib/tls/buffers_tls.c                          |  182 +
 src/lib/tls/buffers_tls.h                          |   23 +
 src/lib/tls/ciphers.inc                            |  100 +
 src/lib/tls/include.am                             |   40 +
 src/lib/tls/nss_countbytes.c                       |  244 +
 src/lib/tls/nss_countbytes.h                       |   25 +
 src/lib/tls/tortls.c                               |  442 +
 src/lib/tls/tortls.h                               |  160 +
 src/lib/tls/tortls_internal.h                      |   76 +
 src/lib/tls/tortls_nss.c                           |  833 ++
 src/lib/tls/tortls_openssl.c                       | 1795 ++++
 src/lib/tls/tortls_st.h                            |   75 +
 src/lib/tls/x509.c                                 |  143 +
 src/lib/tls/x509.h                                 |   75 +
 src/lib/tls/x509_internal.h                        |   53 +
 src/lib/tls/x509_nss.c                             |  458 +
 src/lib/tls/x509_openssl.c                         |  464 +
 src/lib/trace/.may_include                         |    3 +
 src/lib/trace/debug.h                              |   30 +
 src/lib/trace/events.h                             |   45 +
 src/lib/trace/include.am                           |   18 +
 src/lib/trace/trace.c                              |   17 +
 src/lib/trace/trace.h                              |   14 +
 src/lib/wallclock/.may_include                     |    6 +
 src/lib/wallclock/approx_time.c                    |   43 +
 src/lib/wallclock/approx_time.h                    |   25 +
 src/lib/wallclock/include.am                       |   22 +
 src/lib/wallclock/time_to_tm.c                     |  200 +
 src/lib/wallclock/time_to_tm.h                     |   22 +
 src/lib/wallclock/timeval.h                        |   65 +
 src/lib/wallclock/tor_gettimeofday.c               |   82 +
 src/lib/wallclock/tor_gettimeofday.h               |   20 +
 src/or/Makefile.nmake                              |   78 -
 src/or/addressmap.c                                | 1125 ---
 src/or/addressmap.h                                |   65 -
 src/or/buffers.c                                   | 2065 -----
 src/or/buffers.h                                   |  101 -
 src/or/channel.c                                   | 4617 ----------
 src/or/channel.h                                   |  609 --
 src/or/channeltls.c                                | 2208 -----
 src/or/channeltls.h                                |   76 -
 src/or/circpathbias.c                              | 1546 ----
 src/or/circpathbias.h                              |   29 -
 src/or/circuitbuild.c                              | 2553 ------
 src/or/circuitbuild.h                              |   78 -
 src/or/circuitlist.c                               | 2435 ------
 src/or/circuitlist.h                               |   91 -
 src/or/circuitmux.c                                | 1990 -----
 src/or/circuitmux.h                                |  160 -
 src/or/circuitmux_ewma.c                           |  765 --
 src/or/circuitmux_ewma.h                           |   24 -
 src/or/circuitstats.c                              | 1734 ----
 src/or/circuitstats.h                              |   98 -
 src/or/circuituse.c                                | 2624 ------
 src/or/circuituse.h                                |   63 -
 src/or/command.c                                   |  642 --
 src/or/command.h                                   |   31 -
 src/or/config.c                                    | 8013 -----------------
 src/or/config.h                                    |  205 -
 src/or/confparse.c                                 | 1364 ---
 src/or/confparse.h                                 |  143 -
 src/or/connection.c                                | 5177 -----------
 src/or/connection.h                                |  290 -
 src/or/connection_edge.c                           | 3825 --------
 src/or/connection_edge.h                           |  192 -
 src/or/connection_or.c                             | 2454 ------
 src/or/connection_or.h                             |  107 -
 src/or/control.c                                   | 7190 ----------------
 src/or/control.h                                   |  292 -
 src/or/cpuworker.c                                 |  572 --
 src/or/cpuworker.h                                 |   29 -
 src/or/dircollate.c                                |  353 -
 src/or/dircollate.h                                |   68 -
 src/or/directory.c                                 | 4316 ----------
 src/or/directory.h                                 |  175 -
 src/or/dirserv.c                                   | 3913 ---------
 src/or/dirserv.h                                   |  143 -
 src/or/dirvote.c                                   | 4012 ---------
 src/or/dirvote.h                                   |  240 -
 src/or/dns.c                                       | 2120 -----
 src/or/dns.h                                       |   70 -
 src/or/dns_structs.h                               |  102 -
 src/or/dnsserv.c                                   |  396 -
 src/or/dnsserv.h                                   |   27 -
 src/or/dos.c                                       |  794 --
 src/or/dos.h                                       |  140 -
 src/or/entrynodes.c                                | 2561 ------
 src/or/entrynodes.h                                |  187 -
 src/or/ext_orport.c                                |  653 --
 src/or/ext_orport.h                                |   42 -
 src/or/fp_pair.c                                   |  315 -
 src/or/fp_pair.h                                   |   45 -
 src/or/geoip.c                                     | 1875 ----
 src/or/geoip.h                                     |  100 -
 src/or/hibernate.c                                 | 1125 ---
 src/or/hibernate.h                                 |   59 -
 src/or/include.am                                  |  222 -
 src/or/keypin.c                                    |  498 --
 src/or/keypin.h                                    |   47 -
 src/or/main.c                                      | 3533 --------
 src/or/main.h                                      |   98 -
 src/or/microdesc.c                                 |  968 ---
 src/or/microdesc.h                                 |   56 -
 src/or/networkstatus.c                             | 2535 ------
 src/or/networkstatus.h                             |  135 -
 src/or/nodelist.c                                  | 2026 -----
 src/or/nodelist.h                                  |  131 -
 src/or/ntmain.c                                    |  781 --
 src/or/ntmain.h                                    |   28 -
 src/or/onion.c                                     | 1247 ---
 src/or/onion.h                                     |  121 -
 src/or/onion_fast.c                                |  142 -
 src/or/onion_fast.h                                |   39 -
 src/or/onion_ntor.c                                |  335 -
 src/or/onion_ntor.h                                |   61 -
 src/or/onion_tap.c                                 |  247 -
 src/or/onion_tap.h                                 |   38 -
 src/or/or.h                                        | 5392 ------------
 src/or/periodic.c                                  |  126 -
 src/or/periodic.h                                  |   37 -
 src/or/policies.c                                  | 3040 -------
 src/or/policies.h                                  |  147 -
 src/or/protover.c                                  |  793 --
 src/or/protover.h                                  |   74 -
 src/or/reasons.c                                   |  444 -
 src/or/reasons.h                                   |   31 -
 src/or/relay.c                                     | 3068 -------
 src/or/relay.h                                     |  115 -
 src/or/rendcache.c                                 | 1013 ---
 src/or/rendcache.h                                 |  115 -
 src/or/rendclient.c                                | 1567 ----
 src/or/rendclient.h                                |   58 -
 src/or/rendcommon.c                                | 1118 ---
 src/or/rendcommon.h                                |   87 -
 src/or/rendmid.c                                   |  382 -
 src/or/rendmid.h                                   |   25 -
 src/or/rendservice.c                               | 4438 ----------
 src/or/rendservice.h                               |  205 -
 src/or/rephist.c                                   | 3299 -------
 src/or/rephist.h                                   |  123 -
 src/or/replaycache.c                               |  216 -
 src/or/replaycache.h                               |   66 -
 src/or/router.c                                    | 3658 --------
 src/or/router.h                                    |  163 -
 src/or/routerkeys.c                                | 1147 ---
 src/or/routerkeys.h                                |   77 -
 src/or/routerlist.c                                | 5820 -------------
 src/or/routerlist.h                                |  258 -
 src/or/routerparse.c                               | 6364 --------------
 src/or/routerparse.h                               |  131 -
 src/or/routerset.c                                 |  445 -
 src/or/routerset.h                                 |   84 -
 src/or/scheduler.c                                 |  707 --
 src/or/scheduler.h                                 |   57 -
 src/or/shared_random.c                             | 1363 ---
 src/or/shared_random.h                             |  168 -
 src/or/shared_random_state.c                       | 1360 ---
 src/or/shared_random_state.h                       |  149 -
 src/or/statefile.c                                 |  684 --
 src/or/statefile.h                                 |   28 -
 src/or/status.c                                    |  210 -
 src/or/status.h                                    |   18 -
 src/or/tor_main.c                                  |   40 -
 src/or/torcert.c                                   |  297 -
 src/or/torcert.h                                   |   76 -
 src/or/transports.c                                | 1744 ----
 src/or/transports.h                                |  139 -
 src/rust/.cargo/config.in                          |   12 +
 src/rust/.rustfmt.toml                             |   12 +
 src/rust/Cargo.lock                                |  122 +
 src/rust/Cargo.toml                                |   26 +
 src/rust/build.rs                                  |  190 +
 src/rust/crypto/Cargo.toml                         |   37 +
 src/rust/crypto/digests/mod.rs                     |    7 +
 src/rust/crypto/digests/sha2.rs                    |  234 +
 src/rust/crypto/lib.rs                             |   46 +
 src/rust/crypto/rand/mod.rs                        |    6 +
 src/rust/crypto/rand/rng.rs                        |  145 +
 src/rust/external/Cargo.toml                       |   20 +
 src/rust/external/crypto_digest.rs                 |  454 +
 src/rust/external/crypto_rand.rs                   |   84 +
 src/rust/external/external.rs                      |   37 +
 src/rust/external/lib.rs                           |   19 +
 src/rust/include.am                                |   41 +
 src/rust/protover/Cargo.toml                       |   33 +
 src/rust/protover/errors.rs                        |   57 +
 src/rust/protover/ffi.rs                           |  245 +
 src/rust/protover/lib.rs                           |   40 +
 src/rust/protover/protoset.rs                      |  689 ++
 src/rust/protover/protover.rs                      |  971 +++
 src/rust/protover/tests/protover.rs                |  404 +
 src/rust/smartlist/Cargo.toml                      |   18 +
 src/rust/smartlist/lib.rs                          |   17 +
 src/rust/smartlist/smartlist.rs                    |  115 +
 src/rust/tor_allocate/Cargo.toml                   |   18 +
 src/rust/tor_allocate/lib.rs                       |   20 +
 src/rust/tor_allocate/tor_allocate.rs              |  104 +
 src/rust/tor_log/Cargo.toml                        |   21 +
 src/rust/tor_log/lib.rs                            |   16 +
 src/rust/tor_log/tor_log.rs                        |  265 +
 src/rust/tor_rust/Cargo.toml                       |   22 +
 src/rust/tor_rust/include.am                       |   28 +
 src/rust/tor_rust/lib.rs                           |    5 +
 src/rust/tor_util/Cargo.toml                       |   24 +
 src/rust/tor_util/ffi.rs                           |   27 +
 src/rust/tor_util/lib.rs                           |   14 +
 src/rust/tor_util/strings.rs                       |  140 +
 src/test/Makefile.nmake                            |    4 +-
 src/test/bench.c                                   |  125 +-
 src/test/bt_test.py                                |    2 +-
 src/test/ed25519_exts_ref.py                       |   38 +-
 src/test/ed25519_vectors.inc                       |   32 +-
 src/test/fakechans.h                               |    3 +-
 src/test/fuzz/dict/consensus                       |   52 +
 src/test/fuzz/dict/descriptor                      |   41 +
 src/test/fuzz/dict/extrainfo                       |   32 +
 src/test/fuzz/dict/hsdescv2                        |    8 +
 src/test/fuzz/dict/hsdescv3                        |    6 +
 src/test/fuzz/dict/http                            |   24 +
 src/test/fuzz/dict/iptsv2                          |    6 +
 src/test/fuzz/dict/microdesc                       |    7 +
 src/test/fuzz/fixup_filenames.sh                   |   19 +
 src/test/fuzz/fuzz_consensus.c                     |   81 +
 src/test/fuzz/fuzz_descriptor.c                    |   81 +
 src/test/fuzz/fuzz_diff.c                          |   69 +
 src/test/fuzz/fuzz_diff_apply.c                    |   65 +
 src/test/fuzz/fuzz_extrainfo.c                     |   67 +
 src/test/fuzz/fuzz_hsdescv2.c                      |   52 +
 src/test/fuzz/fuzz_hsdescv3.c                      |   99 +
 src/test/fuzz/fuzz_http.c                          |  134 +
 src/test/fuzz/fuzz_http_connect.c                  |  109 +
 src/test/fuzz/fuzz_iptsv2.c                        |   50 +
 src/test/fuzz/fuzz_microdesc.c                     |   49 +
 src/test/fuzz/fuzz_multi.sh                        |   34 +
 src/test/fuzz/fuzz_socks.c                         |   50 +
 src/test/fuzz/fuzz_vrs.c                           |   87 +
 src/test/fuzz/fuzzing.h                            |   13 +
 src/test/fuzz/fuzzing_common.c                     |  197 +
 src/test/fuzz/include.am                           |  440 +
 src/test/fuzz/minimize.sh                          |   14 +
 src/test/fuzz_static_testcases.sh                  |   27 +
 src/test/hs_build_address.py                       |   38 +
 src/test/hs_indexes.py                             |   70 +
 src/test/hs_ntor_ref.py                            |  428 +
 src/test/hs_test_helpers.c                         |  325 +
 src/test/hs_test_helpers.h                         |   25 +
 src/test/include.am                                |  224 +-
 src/test/log_test_helpers.c                        |    6 +-
 src/test/log_test_helpers.h                        |   45 +-
 src/test/ntor_ref.py                               |    2 +-
 src/test/ope_ref.py                                |   40 +
 src/test/rend_test_helpers.c                       |   31 +-
 src/test/rend_test_helpers.h                       |    7 +-
 src/test/rust_supp.txt                             |    1 +
 src/test/test-child.c                              |    4 +-
 src/test/test-memwipe.c                            |   17 +-
 src/test/test-network.sh                           |    4 +-
 src/test/test-timers.c                             |   31 +-
 src/test/test.c                                    |  568 +-
 src/test/test.h                                    |   79 +-
 src/test/test_accounting.c                         |   16 +-
 src/test/test_addr.c                               |  248 +-
 src/test/test_address.c                            |  147 +-
 src/test/test_address_set.c                        |   26 +-
 src/test/test_bridges.c                            |  704 ++
 src/test/test_bt_cl.c                              |   27 +-
 src/test/test_buffers.c                            |  548 +-
 src/test/test_bwmgt.c                              |  233 +
 src/test/test_cell_formats.c                       |   66 +-
 src/test/test_cell_queue.c                         |   19 +-
 src/test/test_channel.c                            | 1931 ++---
 src/test/test_channelpadding.c                     | 1104 +++
 src/test/test_channeltls.c                         |   67 +-
 src/test/test_checkdir.c                           |   16 +-
 src/test/test_circuitbuild.c                       |  182 +
 src/test/test_circuitlist.c                        |  192 +-
 src/test/test_circuitmux.c                         |   69 +-
 src/test/test_circuitstats.c                       |  206 +
 src/test/test_circuituse.c                         |  310 +
 src/test/test_compat_libevent.c                    |   71 +-
 src/test/test_config.c                             | 1983 +++--
 src/test/test_connection.c                         |  558 +-
 src/test/test_connection.h                         |   13 +
 src/test/test_conscache.c                          |  340 +
 src/test/test_consdiff.c                           | 1185 +++
 src/test/test_consdiffmgr.c                        |  900 ++
 src/test/test_containers.c                         |  150 +-
 src/test/test_controller.c                         |  667 +-
 src/test/test_controller_events.c                  |  160 +-
 src/test/test_crypto.c                             |  538 +-
 src/test/test_crypto_ope.c                         |  154 +
 src/test/test_crypto_openssl.c                     |  106 +
 src/test/test_crypto_slow.c                        |   50 +-
 src/test/test_data.c                               |    4 +-
 src/test/test_dir.c                                | 2531 ++++--
 src/test/test_dir_common.c                         |   28 +-
 src/test/test_dir_common.h                         |    7 +-
 src/test/test_dir_handle_get.c                     |  376 +-
 src/test/test_dns.c                                |   88 +-
 src/test/test_dos.c                                |   31 +-
 src/test/test_entryconn.c                          |  202 +-
 src/test/test_entrynodes.c                         | 3519 ++++++--
 src/test/test_extorport.c                          |   86 +-
 src/test/test_geoip.c                              |  580 ++
 src/test/test_guardfraction.c                      |   81 +-
 src/test/test_handles.c                            |   13 +-
 src/test/test_helpers.c                            |  229 +-
 src/test/test_helpers.h                            |   22 +-
 src/test/test_hs.c                                 |  613 +-
 src/test/test_hs_cache.c                           |  566 ++
 src/test/test_hs_cell.c                            |  131 +
 src/test/test_hs_client.c                          | 1010 +++
 src/test/test_hs_common.c                          | 1839 ++++
 src/test/test_hs_config.c                          |  517 ++
 src/test/test_hs_control.c                         |  194 +
 src/test/test_hs_descriptor.c                      |  965 +++
 src/test/test_hs_descriptor.inc                    |  224 +
 src/test/test_hs_intropoint.c                      |  930 ++
 src/test/test_hs_ntor.c                            |  115 +
 src/test/test_hs_ntor.sh                           |   11 +
 src/test/test_hs_ntor_cl.c                         |  259 +
 src/test/test_hs_service.c                         | 2145 +++++
 src/test/test_introduce.c                          |   20 +-
 src/test/test_key_expiration.sh                    |  138 +
 src/test/test_keygen.sh                            |  112 +-
 src/test/test_keypin.c                             |  112 +-
 src/test/test_link_handshake.c                     |  941 +-
 src/test/test_logging.c                            |   28 +-
 src/test/test_mainloop.c                           |  142 +
 src/test/test_microdesc.c                          |  135 +-
 src/test/test_nodelist.c                           |  140 +-
 src/test/test_ntor_cl.c                            |   18 +-
 src/test/test_oom.c                                |   83 +-
 src/test/test_oos.c                                |   37 +-
 src/test/test_options.c                            |  981 +--
 src/test/test_pem.c                                |  122 +
 src/test/test_periodic_event.c                     |  333 +
 src/test/test_policy.c                             |  492 +-
 src/test/test_procmon.c                            |   10 +-
 src/test/test_proto_http.c                         |  213 +
 src/test/test_proto_misc.c                         |  265 +
 src/test/test_protover.c                           |  363 +-
 src/test/test_pt.c                                 |   74 +-
 src/test/test_pubsub.c                             |   85 -
 src/test/test_rebind.py                            |  145 +
 src/test/test_rebind.sh                            |   32 +
 src/test/test_relay.c                              |   59 +-
 src/test/test_relaycell.c                          |  837 +-
 src/test/test_relaycrypt.c                         |  190 +
 src/test/test_rendcache.c                          |  114 +-
 src/test/test_replay.c                             |   34 +-
 src/test/test_router.c                             |  119 +-
 src/test/test_routerkeys.c                         |  334 +-
 src/test/test_routerlist.c                         |  432 +-
 src/test/test_routerset.c                          |  130 +-
 src/test/test_rust.sh                              |   27 +
 src/test/test_scheduler.c                          | 1115 ++-
 src/test/test_shared_random.c                      |  508 +-
 src/test/test_slow.c                               |    6 +-
 src/test/test_socks.c                              |  671 +-
 src/test/test_status.c                             |   57 +-
 src/test/test_storagedir.c                         |  376 +
 src/test/test_switch_id.c                          |   17 +-
 src/test/test_threads.c                            |   20 +-
 src/test/test_tortls.c                             | 2860 +-----
 src/test/test_tortls.h                             |   13 +
 src/test/test_tortls_openssl.c                     | 2316 +++++
 src/test/test_util.c                               | 1553 +++-
 src/test/test_util_format.c                        |   99 +-
 src/test/test_util_process.c                       |   12 +-
 src/test/test_util_slow.c                          |   45 +-
 src/test/test_voting_schedule.c                    |   64 +
 src/test/test_workqueue.c                          |   79 +-
 src/test/test_x509.c                               |  205 +
 src/test/test_zero_length_keys.sh                  |    6 +-
 src/test/testing_common.c                          |  181 +-
 src/test/testing_rsakeys.c                         |  546 ++
 src/test/zero_length_keys.sh                       |    3 +-
 src/tools/Makefile.nmake                           |    5 +-
 src/tools/include.am                               |   80 +-
 src/tools/tor-checkkey.c                           |   89 -
 src/tools/tor-fw-helper/README                     |   10 -
 src/tools/tor-gencert.c                            |  110 +-
 src/tools/tor-print-ed-signing-cert.c              |   65 +
 src/tools/tor-resolve.c                            |   72 +-
 src/tools/tor_runner.c                             |  112 +
 src/trunnel/channelpadding_negotiation.c           |  281 +
 src/trunnel/channelpadding_negotiation.h           |   98 +
 src/trunnel/channelpadding_negotiation.trunnel     |   17 +
 src/trunnel/ed25519_cert.c                         | 2312 ++++-
 src/trunnel/ed25519_cert.h                         |  678 +-
 src/trunnel/ed25519_cert.trunnel                   |   64 +-
 src/trunnel/hs/cell_common.c                       |  595 ++
 src/trunnel/hs/cell_common.h                       |  203 +
 src/trunnel/hs/cell_common.trunnel                 |   12 +
 src/trunnel/hs/cell_establish_intro.c              |  735 ++
 src/trunnel/hs/cell_establish_intro.h              |  276 +
 src/trunnel/hs/cell_establish_intro.trunnel        |   41 +
 src/trunnel/hs/cell_introduce1.c                   | 1347 +++
 src/trunnel/hs/cell_introduce1.h                   |  500 ++
 src/trunnel/hs/cell_introduce1.trunnel             |   75 +
 src/trunnel/hs/cell_rendezvous.c                   |  470 +
 src/trunnel/hs/cell_rendezvous.h                   |  187 +
 src/trunnel/hs/cell_rendezvous.trunnel             |   29 +
 src/trunnel/include.am                             |   36 +-
 src/trunnel/link_handshake.c                       |  212 +-
 src/trunnel/link_handshake.h                       |  148 +-
 src/trunnel/pwbox.c                                |   54 +-
 src/trunnel/pwbox.h                                |   38 +-
 src/trunnel/socks5.c                               | 3978 +++++++++
 src/trunnel/socks5.h                               |  995 +++
 src/trunnel/socks5.trunnel                         |   94 +
 src/trunnel/trunnel-local.h                        |    6 +-
 src/win32/orconfig.h                               |    2 +-
 warning_flags.in                                   |    1 +
 1347 files changed, 319206 insertions(+), 195287 deletions(-)

diff --cc src/core/or/channeltls.c
index 000000000,91a424728..4db283d20
mode 000000,100644..100644
--- a/src/core/or/channeltls.c
+++ b/src/core/or/channeltls.c
@@@ -1,0 -1,2477 +1,2485 @@@
+ /* * Copyright (c) 2012-2019, The Tor Project, Inc. */
+ /* See LICENSE for licensing information */
+ 
+ /**
+  * \file channeltls.c
+  *
+  * \brief A concrete subclass of channel_t using or_connection_t to transfer
+  * cells between Tor instances.
+  *
+  * This module fills in the various function pointers in channel_t, to
+  * implement the channel_tls_t channels as used in Tor today.  These channels
+  * are created from channel_tls_connect() and
+  * channel_tls_handle_incoming(). Each corresponds 1:1 to or_connection_t
+  * object, as implemented in connection_or.c.  These channels transmit cells
+  * to the underlying or_connection_t by calling
+  * connection_or_write_*_cell_to_buf(), and receive cells from the underlying
+  * or_connection_t when connection_or_process_cells_from_inbuf() calls
+  * channel_tls_handle_*_cell().
+  *
+  * Here we also implement the server (responder) side of the v3+ Tor link
+  * handshake, which uses CERTS and AUTHENTICATE cell to negotiate versions,
+  * exchange expected and observed IP and time information, and bootstrap a
+  * level of authentication higher than we have gotten on the raw TLS
+  * handshake.
+  *
+  * NOTE: Since there is currently only one type of channel, there are probably
+  * more than a few cases where functionality that is currently in
+  * channeltls.c, connection_or.c, and channel.c ought to be divided up
+  * differently.  The right time to do this is probably whenever we introduce
+  * our next channel type.
+  **/
+ 
+ /*
+  * Define this so channel.h gives us things only channel_t subclasses
+  * should touch.
+  */
+ #define TOR_CHANNEL_INTERNAL_
+ 
+ #define CHANNELTLS_PRIVATE
+ 
+ #include "core/or/or.h"
+ #include "core/or/channel.h"
+ #include "core/or/channeltls.h"
+ #include "core/or/circuitmux.h"
+ #include "core/or/circuitmux_ewma.h"
+ #include "core/or/command.h"
+ #include "app/config/config.h"
+ #include "core/mainloop/connection.h"
+ #include "core/or/connection_or.h"
+ #include "feature/control/control.h"
+ #include "feature/client/entrynodes.h"
+ #include "trunnel/link_handshake.h"
+ #include "core/or/relay.h"
+ #include "feature/stats/rephist.h"
+ #include "feature/relay/router.h"
+ #include "feature/relay/routermode.h"
+ #include "feature/nodelist/dirlist.h"
+ #include "core/or/scheduler.h"
+ #include "feature/nodelist/torcert.h"
+ #include "feature/nodelist/networkstatus.h"
+ #include "trunnel/channelpadding_negotiation.h"
+ #include "core/or/channelpadding.h"
+ 
+ #include "core/or/cell_st.h"
+ #include "core/or/cell_queue_st.h"
+ #include "core/or/extend_info_st.h"
+ #include "core/or/or_connection_st.h"
+ #include "core/or/or_handshake_certs_st.h"
+ #include "core/or/or_handshake_state_st.h"
+ #include "feature/nodelist/routerinfo_st.h"
+ #include "core/or/var_cell_st.h"
+ 
+ #include "lib/tls/tortls.h"
+ #include "lib/tls/x509.h"
+ 
+ /** How many CELL_PADDING cells have we received, ever? */
+ uint64_t stats_n_padding_cells_processed = 0;
+ /** How many CELL_VERSIONS cells have we received, ever? */
+ uint64_t stats_n_versions_cells_processed = 0;
+ /** How many CELL_NETINFO cells have we received, ever? */
+ uint64_t stats_n_netinfo_cells_processed = 0;
+ /** How many CELL_VPADDING cells have we received, ever? */
+ uint64_t stats_n_vpadding_cells_processed = 0;
+ /** How many CELL_CERTS cells have we received, ever? */
+ uint64_t stats_n_certs_cells_processed = 0;
+ /** How many CELL_AUTH_CHALLENGE cells have we received, ever? */
+ uint64_t stats_n_auth_challenge_cells_processed = 0;
+ /** How many CELL_AUTHENTICATE cells have we received, ever? */
+ uint64_t stats_n_authenticate_cells_processed = 0;
+ /** How many CELL_AUTHORIZE cells have we received, ever? */
+ uint64_t stats_n_authorize_cells_processed = 0;
+ 
+ /** Active listener, if any */
+ static channel_listener_t *channel_tls_listener = NULL;
+ 
+ /* channel_tls_t method declarations */
+ 
+ static void channel_tls_close_method(channel_t *chan);
+ static const char * channel_tls_describe_transport_method(channel_t *chan);
+ static void channel_tls_free_method(channel_t *chan);
+ static double channel_tls_get_overhead_estimate_method(channel_t *chan);
+ static int
+ channel_tls_get_remote_addr_method(channel_t *chan, tor_addr_t *addr_out);
+ static int
+ channel_tls_get_transport_name_method(channel_t *chan, char **transport_out);
+ 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_matches_extend_info_method(channel_t *chan,
+                                        extend_info_t *extend_info);
+ static int channel_tls_matches_target_method(channel_t *chan,
+                                              const tor_addr_t *target);
+ static int channel_tls_num_cells_writeable_method(channel_t *chan);
+ static size_t channel_tls_num_bytes_queued_method(channel_t *chan);
+ static int channel_tls_write_cell_method(channel_t *chan,
+                                          cell_t *cell);
+ static int channel_tls_write_packed_cell_method(channel_t *chan,
+                                                 packed_cell_t *packed_cell);
+ static int channel_tls_write_var_cell_method(channel_t *chan,
+                                              var_cell_t *var_cell);
+ 
+ /* channel_listener_tls_t method declarations */
+ 
+ static void channel_tls_listener_close_method(channel_listener_t *chan_l);
+ static const char *
+ channel_tls_listener_describe_transport_method(channel_listener_t *chan_l);
+ 
+ /** Handle incoming cells for the handshake stuff here rather than
+  * passing them on up. */
+ 
+ static void channel_tls_process_versions_cell(var_cell_t *cell,
+                                               channel_tls_t *tlschan);
+ static void channel_tls_process_netinfo_cell(cell_t *cell,
+                                              channel_tls_t *tlschan);
+ static int command_allowed_before_handshake(uint8_t command);
+ static int enter_v3_handshake_with_cell(var_cell_t *cell,
+                                         channel_tls_t *tlschan);
+ static void channel_tls_process_padding_negotiate_cell(cell_t *cell,
+                                                        channel_tls_t *chan);
+ 
+ /**
+  * Do parts of channel_tls_t initialization common to channel_tls_connect()
+  * and channel_tls_handle_incoming().
+  */
+ STATIC void
+ channel_tls_common_init(channel_tls_t *tlschan)
+ {
+   channel_t *chan;
+ 
+   tor_assert(tlschan);
+ 
+   chan = &(tlschan->base_);
+   channel_init(chan);
+   chan->magic = TLS_CHAN_MAGIC;
+   chan->state = CHANNEL_STATE_OPENING;
+   chan->close = channel_tls_close_method;
+   chan->describe_transport = channel_tls_describe_transport_method;
+   chan->free_fn = channel_tls_free_method;
+   chan->get_overhead_estimate = channel_tls_get_overhead_estimate_method;
+   chan->get_remote_addr = channel_tls_get_remote_addr_method;
+   chan->get_remote_descr = channel_tls_get_remote_descr_method;
+   chan->get_transport_name = channel_tls_get_transport_name_method;
+   chan->has_queued_writes = channel_tls_has_queued_writes_method;
+   chan->is_canonical = channel_tls_is_canonical_method;
+   chan->matches_extend_info = channel_tls_matches_extend_info_method;
+   chan->matches_target = channel_tls_matches_target_method;
+   chan->num_bytes_queued = channel_tls_num_bytes_queued_method;
+   chan->num_cells_writeable = channel_tls_num_cells_writeable_method;
+   chan->write_cell = channel_tls_write_cell_method;
+   chan->write_packed_cell = channel_tls_write_packed_cell_method;
+   chan->write_var_cell = channel_tls_write_var_cell_method;
+ 
+   chan->cmux = circuitmux_alloc();
+   /* We only have one policy for now so always set it to EWMA. */
+   circuitmux_set_policy(chan->cmux, &ewma_policy);
+ }
+ 
+ /**
+  * Start a new TLS channel.
+  *
+  * Launch a new OR connection to <b>addr</b>:<b>port</b> and expect to
+  * handshake with an OR with identity digest <b>id_digest</b>, and wrap
+  * it in a channel_tls_t.
+  */
+ channel_t *
+ channel_tls_connect(const tor_addr_t *addr, uint16_t port,
+                     const char *id_digest,
+                     const ed25519_public_key_t *ed_id)
+ {
+   channel_tls_t *tlschan = tor_malloc_zero(sizeof(*tlschan));
+   channel_t *chan = &(tlschan->base_);
+ 
+   channel_tls_common_init(tlschan);
+ 
+   log_debug(LD_CHANNEL,
+             "In channel_tls_connect() for channel %p "
+             "(global id %"PRIu64 ")",
+             tlschan,
+             (chan->global_identifier));
+ 
+   if (is_local_addr(addr)) {
+     log_debug(LD_CHANNEL,
+               "Marking new outgoing channel %"PRIu64 " at %p as local",
+               (chan->global_identifier), chan);
+     channel_mark_local(chan);
+   } else {
+     log_debug(LD_CHANNEL,
+               "Marking new outgoing channel %"PRIu64 " at %p as remote",
+               (chan->global_identifier), chan);
+     channel_mark_remote(chan);
+   }
+ 
+   channel_mark_outgoing(chan);
+ 
+   /* Set up or_connection stuff */
+   tlschan->conn = connection_or_connect(addr, port, id_digest, ed_id, tlschan);
+   /* connection_or_connect() will fill in tlschan->conn */
+   if (!(tlschan->conn)) {
+     chan->reason_for_closing = CHANNEL_CLOSE_FOR_ERROR;
+     channel_change_state(chan, CHANNEL_STATE_ERROR);
+     goto err;
+   }
+ 
+   log_debug(LD_CHANNEL,
+             "Got orconn %p for channel with global id %"PRIu64,
+             tlschan->conn, (chan->global_identifier));
+ 
+   goto done;
+ 
+  err:
+   circuitmux_free(chan->cmux);
+   tor_free(tlschan);
+   chan = NULL;
+ 
+  done:
+   /* If we got one, we should register it */
+   if (chan) channel_register(chan);
+ 
+   return chan;
+ }
+ 
+ /**
+  * Return the current channel_tls_t listener.
+  *
+  * Returns the current channel listener for incoming TLS connections, or
+  * NULL if none has been established
+  */
+ channel_listener_t *
+ channel_tls_get_listener(void)
+ {
+   return channel_tls_listener;
+ }
+ 
+ /**
+  * Start a channel_tls_t listener if necessary.
+  *
+  * Return the current channel_tls_t listener, or start one if we haven't yet,
+  * and return that.
+  */
+ channel_listener_t *
+ channel_tls_start_listener(void)
+ {
+   channel_listener_t *listener;
+ 
+   if (!channel_tls_listener) {
+     listener = tor_malloc_zero(sizeof(*listener));
+     channel_init_listener(listener);
+     listener->state = CHANNEL_LISTENER_STATE_LISTENING;
+     listener->close = channel_tls_listener_close_method;
+     listener->describe_transport =
+       channel_tls_listener_describe_transport_method;
+ 
+     channel_tls_listener = listener;
+ 
+     log_debug(LD_CHANNEL,
+               "Starting TLS channel listener %p with global id %"PRIu64,
+               listener, (listener->global_identifier));
+ 
+     channel_listener_register(listener);
+   } else listener = channel_tls_listener;
+ 
+   return listener;
+ }
+ 
+ /**
+  * Free everything on shutdown.
+  *
+  * Not much to do here, since channel_free_all() takes care of a lot, but let's
+  * get rid of the listener.
+  */
+ void
+ channel_tls_free_all(void)
+ {
+   channel_listener_t *old_listener = NULL;
+ 
+   log_debug(LD_CHANNEL,
+             "Shutting down TLS channels...");
+ 
+   if (channel_tls_listener) {
+     /*
+      * When we close it, channel_tls_listener will get nulled out, so save
+      * a pointer so we can free it.
+      */
+     old_listener = channel_tls_listener;
+     log_debug(LD_CHANNEL,
+               "Closing channel_tls_listener with ID %"PRIu64
+               " at %p.",
+               (old_listener->global_identifier),
+               old_listener);
+     channel_listener_unregister(old_listener);
+     channel_listener_mark_for_close(old_listener);
+     channel_listener_free(old_listener);
+     tor_assert(channel_tls_listener == NULL);
+   }
+ 
+   log_debug(LD_CHANNEL,
+             "Done shutting down TLS channels");
+ }
+ 
+ /**
+  * Create a new channel around an incoming or_connection_t.
+  */
+ channel_t *
+ channel_tls_handle_incoming(or_connection_t *orconn)
+ {
+   channel_tls_t *tlschan = tor_malloc_zero(sizeof(*tlschan));
+   channel_t *chan = &(tlschan->base_);
+ 
+   tor_assert(orconn);
+   tor_assert(!(orconn->chan));
+ 
+   channel_tls_common_init(tlschan);
+ 
+   /* Link the channel and orconn to each other */
+   tlschan->conn = orconn;
+   orconn->chan = tlschan;
+ 
+   if (is_local_addr(&(TO_CONN(orconn)->addr))) {
+     log_debug(LD_CHANNEL,
+               "Marking new incoming channel %"PRIu64 " at %p as local",
+               (chan->global_identifier), chan);
+     channel_mark_local(chan);
+   } else {
+     log_debug(LD_CHANNEL,
+               "Marking new incoming channel %"PRIu64 " at %p as remote",
+               (chan->global_identifier), chan);
+     channel_mark_remote(chan);
+   }
+ 
+   channel_mark_incoming(chan);
+ 
+   /* Register it */
+   channel_register(chan);
+ 
+   return chan;
+ }
+ 
+ /*********
+  * Casts *
+  ********/
+ 
+ /**
+  * Cast a channel_tls_t to a channel_t.
+  */
+ channel_t *
+ channel_tls_to_base(channel_tls_t *tlschan)
+ {
+   if (!tlschan) return NULL;
+ 
+   return &(tlschan->base_);
+ }
+ 
+ /**
+  * Cast a channel_t to a channel_tls_t, with appropriate type-checking
+  * asserts.
+  */
+ channel_tls_t *
+ channel_tls_from_base(channel_t *chan)
+ {
+   if (!chan) return NULL;
+ 
+   tor_assert(chan->magic == TLS_CHAN_MAGIC);
+ 
+   return (channel_tls_t *)(chan);
+ }
+ 
+ /********************************************
+  * Method implementations for channel_tls_t *
+  *******************************************/
+ 
+ /**
+  * Close a channel_tls_t.
+  *
+  * This implements the close method for channel_tls_t.
+  */
+ static void
+ channel_tls_close_method(channel_t *chan)
+ {
+   channel_tls_t *tlschan = BASE_CHAN_TO_TLS(chan);
+ 
+   tor_assert(tlschan);
+ 
+   if (tlschan->conn) connection_or_close_normally(tlschan->conn, 1);
+   else {
+     /* Weird - we'll have to change the state ourselves, I guess */
+     log_info(LD_CHANNEL,
+              "Tried to close channel_tls_t %p with NULL conn",
+              tlschan);
+     channel_change_state(chan, CHANNEL_STATE_ERROR);
+   }
+ }
+ 
+ /**
+  * Describe the transport for a channel_tls_t.
+  *
+  * This returns the string "TLS channel on connection <id>" to the upper
+  * layer.
+  */
+ static const char *
+ channel_tls_describe_transport_method(channel_t *chan)
+ {
+   static char *buf = NULL;
+   uint64_t id;
+   channel_tls_t *tlschan;
+   const char *rv = NULL;
+ 
+   tor_assert(chan);
+ 
+   tlschan = BASE_CHAN_TO_TLS(chan);
+ 
+   if (tlschan->conn) {
+     id = TO_CONN(tlschan->conn)->global_identifier;
+ 
+     if (buf) tor_free(buf);
+     tor_asprintf(&buf,
+                  "TLS channel (connection %"PRIu64 ")",
+                  (id));
+ 
+     rv = buf;
+   } else {
+     rv = "TLS channel (no connection)";
+   }
+ 
+   return rv;
+ }
+ 
+ /**
+  * Free a channel_tls_t.
+  *
+  * This is called by the generic channel layer when freeing a channel_tls_t;
+  * this happens either on a channel which has already reached
+  * CHANNEL_STATE_CLOSED or CHANNEL_STATE_ERROR from channel_run_cleanup() or
+  * on shutdown from channel_free_all().  In the latter case we might still
+  * have an orconn active (which connection_free_all() will get to later),
+  * so we should null out its channel pointer now.
+  */
+ static void
+ channel_tls_free_method(channel_t *chan)
+ {
+   channel_tls_t *tlschan = BASE_CHAN_TO_TLS(chan);
+ 
+   tor_assert(tlschan);
+ 
+   if (tlschan->conn) {
+     tlschan->conn->chan = NULL;
+     tlschan->conn = NULL;
+   }
+ }
+ 
+ /**
+  * Get an estimate of the average TLS overhead for the upper layer.
+  */
+ static double
+ channel_tls_get_overhead_estimate_method(channel_t *chan)
+ {
+   double overhead = 1.0;
+   channel_tls_t *tlschan = BASE_CHAN_TO_TLS(chan);
+ 
+   tor_assert(tlschan);
+   tor_assert(tlschan->conn);
+ 
+   /* Just return 1.0f if we don't have sensible data */
+   if (tlschan->conn->bytes_xmitted > 0 &&
+       tlschan->conn->bytes_xmitted_by_tls >=
+       tlschan->conn->bytes_xmitted) {
+     overhead = ((double)(tlschan->conn->bytes_xmitted_by_tls)) /
+       ((double)(tlschan->conn->bytes_xmitted));
+ 
+     /*
+      * Never estimate more than 2.0; otherwise we get silly large estimates
+      * at the very start of a new TLS connection.
+      */
+     if (overhead > 2.0)
+       overhead = 2.0;
+   }
+ 
+   log_debug(LD_CHANNEL,
+             "Estimated overhead ratio for TLS chan %"PRIu64 " is %f",
+             (chan->global_identifier), overhead);
+ 
+   return overhead;
+ }
+ 
+ /**
+  * Get the remote address of a channel_tls_t.
+  *
+  * This implements the get_remote_addr method for channel_tls_t; copy the
+  * remote endpoint of the channel to addr_out and return 1 (always
+  * succeeds for this transport).
+  */
+ static int
+ channel_tls_get_remote_addr_method(channel_t *chan, tor_addr_t *addr_out)
+ {
+   int rv = 0;
+   channel_tls_t *tlschan = BASE_CHAN_TO_TLS(chan);
+ 
+   tor_assert(tlschan);
+   tor_assert(addr_out);
+ 
+   if (tlschan->conn) {
+     tor_addr_copy(addr_out, &(tlschan->conn->real_addr));
+     rv = 1;
+   } else tor_addr_make_unspec(addr_out);
+ 
+   return rv;
+ }
+ 
+ /**
+  * Get the name of the pluggable transport used by a channel_tls_t.
+  *
+  * This implements the get_transport_name for channel_tls_t. If the
+  * channel uses a pluggable transport, copy its name to
+  * <b>transport_out</b> and return 0. If the channel did not use a
+  * pluggable transport, return -1.
+  */
+ static int
+ channel_tls_get_transport_name_method(channel_t *chan, char **transport_out)
+ {
+   channel_tls_t *tlschan = BASE_CHAN_TO_TLS(chan);
+ 
+   tor_assert(tlschan);
+   tor_assert(transport_out);
+   tor_assert(tlschan->conn);
+ 
+   if (!tlschan->conn->ext_or_transport)
+     return -1;
+ 
+   *transport_out = tor_strdup(tlschan->conn->ext_or_transport);
+   return 0;
+ }
+ 
+ /**
+  * Get endpoint description of a channel_tls_t.
+  *
+  * This implements the get_remote_descr method for channel_tls_t; it returns
+  * a text description of the remote endpoint of the channel suitable for use
+  * in log messages. The req parameter is 0 for the canonical address or 1 for
+  * the actual address seen.
+  */
+ static const char *
+ channel_tls_get_remote_descr_method(channel_t *chan, int flags)
+ {
+ #define MAX_DESCR_LEN 32
+ 
+   static char buf[MAX_DESCR_LEN + 1];
+   channel_tls_t *tlschan = BASE_CHAN_TO_TLS(chan);
+   connection_t *conn;
+   const char *answer = NULL;
+   char *addr_str;
+ 
+   tor_assert(tlschan);
+ 
+   if (tlschan->conn) {
+     conn = TO_CONN(tlschan->conn);
+     switch (flags) {
+       case 0:
+         /* Canonical address with port*/
+         tor_snprintf(buf, MAX_DESCR_LEN + 1,
+                      "%s:%u", conn->address, conn->port);
+         answer = buf;
+         break;
+       case GRD_FLAG_ORIGINAL:
+         /* Actual address with port */
+         addr_str = tor_addr_to_str_dup(&(tlschan->conn->real_addr));
+         tor_snprintf(buf, MAX_DESCR_LEN + 1,
+                      "%s:%u", addr_str, conn->port);
+         tor_free(addr_str);
+         answer = buf;
+         break;
+       case GRD_FLAG_ADDR_ONLY:
+         /* Canonical address, no port */
+         strlcpy(buf, conn->address, sizeof(buf));
+         answer = buf;
+         break;
+       case GRD_FLAG_ORIGINAL|GRD_FLAG_ADDR_ONLY:
+         /* Actual address, no port */
+         addr_str = tor_addr_to_str_dup(&(tlschan->conn->real_addr));
+         strlcpy(buf, addr_str, sizeof(buf));
+         tor_free(addr_str);
+         answer = buf;
+         break;
+       default:
+         /* Something's broken in channel.c */
+         tor_assert_nonfatal_unreached_once();
+     }
+   } else {
+     strlcpy(buf, "(No connection)", sizeof(buf));
+     answer = buf;
+   }
+ 
+   return answer;
+ }
+ 
+ /**
+  * Tell the upper layer if we have queued writes.
+  *
+  * This implements the has_queued_writes method for channel_tls t_; it returns
+  * 1 iff we have queued writes on the outbuf of the underlying or_connection_t.
+  */
+ static int
+ channel_tls_has_queued_writes_method(channel_t *chan)
+ {
+   size_t outbuf_len;
+   channel_tls_t *tlschan = BASE_CHAN_TO_TLS(chan);
+ 
+   tor_assert(tlschan);
+   if (!(tlschan->conn)) {
+     log_info(LD_CHANNEL,
+              "something called has_queued_writes on a tlschan "
+              "(%p with ID %"PRIu64 " but no conn",
+              chan, (chan->global_identifier));
+   }
+ 
+   outbuf_len = (tlschan->conn != NULL) ?
+     connection_get_outbuf_len(TO_CONN(tlschan->conn)) :
+     0;
+ 
+   return (outbuf_len > 0);
+ }
+ 
+ /**
+  * 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.
+  */
+ static int
+ channel_tls_is_canonical_method(channel_t *chan, int req)
+ {
+   int answer = 0;
+   channel_tls_t *tlschan = BASE_CHAN_TO_TLS(chan);
+ 
+   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();
+     }
+   }
+   /* else return 0 for tlschan->conn == NULL */
+ 
+   return answer;
+ }
+ 
+ /**
+  * Check if we match an extend_info_t.
+  *
+  * This implements the matches_extend_info method for channel_tls_t; the upper
+  * layer wants to know if this channel matches an extend_info_t.
+  */
+ static int
+ channel_tls_matches_extend_info_method(channel_t *chan,
+                                        extend_info_t *extend_info)
+ {
+   channel_tls_t *tlschan = BASE_CHAN_TO_TLS(chan);
+ 
+   tor_assert(tlschan);
+   tor_assert(extend_info);
+ 
+   /* Never match if we have no conn */
+   if (!(tlschan->conn)) {
+     log_info(LD_CHANNEL,
+              "something called matches_extend_info on a tlschan "
+              "(%p with ID %"PRIu64 " but no conn",
+              chan, (chan->global_identifier));
+     return 0;
+   }
+ 
+   return (tor_addr_eq(&(extend_info->addr),
+                       &(TO_CONN(tlschan->conn)->addr)) &&
+          (extend_info->port == TO_CONN(tlschan->conn)->port));
+ }
+ 
+ /**
+  * Check if we match a target address; return true iff we do.
+  *
+  * This implements the matches_target method for channel_tls t_; the upper
+  * layer wants to know if this channel matches a target address when extending
+  * a circuit.
+  */
+ static int
+ channel_tls_matches_target_method(channel_t *chan,
+                                   const tor_addr_t *target)
+ {
+   channel_tls_t *tlschan = BASE_CHAN_TO_TLS(chan);
+ 
+   tor_assert(tlschan);
+   tor_assert(target);
+ 
+   /* Never match if we have no conn */
+   if (!(tlschan->conn)) {
+     log_info(LD_CHANNEL,
+              "something called matches_target on a tlschan "
+              "(%p with ID %"PRIu64 " but no conn",
+              chan, (chan->global_identifier));
+     return 0;
+   }
+ 
+   /* real_addr is the address this connection came from.
+    * base_.addr is updated by connection_or_init_conn_from_address()
+    * to be the address in the descriptor. It may be tempting to
+    * allow either address to be allowed, but if we did so, it would
+    * enable someone who steals a relay's keys to impersonate/MITM it
+    * from anywhere on the Internet! (Because they could make long-lived
+    * TLS connections from anywhere to all relays, and wait for them to
+    * be used for extends).
+    */
+   return tor_addr_eq(&(tlschan->conn->real_addr), target);
+ }
+ 
+ /**
+  * Tell the upper layer how many bytes we have queued and not yet
+  * sent.
+  */
+ static size_t
+ channel_tls_num_bytes_queued_method(channel_t *chan)
+ {
+   channel_tls_t *tlschan = BASE_CHAN_TO_TLS(chan);
+ 
+   tor_assert(tlschan);
+   tor_assert(tlschan->conn);
+ 
+   return connection_get_outbuf_len(TO_CONN(tlschan->conn));
+ }
+ 
+ /**
+  * Tell the upper layer how many cells we can accept to write.
+  *
+  * This implements the num_cells_writeable method for channel_tls_t; it
+  * returns an estimate of the number of cells we can accept with
+  * channel_tls_write_*_cell().
+  */
+ static int
+ channel_tls_num_cells_writeable_method(channel_t *chan)
+ {
+   size_t outbuf_len;
+   ssize_t n;
+   channel_tls_t *tlschan = BASE_CHAN_TO_TLS(chan);
+   size_t cell_network_size;
+ 
+   tor_assert(tlschan);
+   tor_assert(tlschan->conn);
+ 
+   cell_network_size = get_cell_network_size(tlschan->conn->wide_circ_ids);
+   outbuf_len = connection_get_outbuf_len(TO_CONN(tlschan->conn));
+   /* Get the number of cells */
+   n = CEIL_DIV(OR_CONN_HIGHWATER - outbuf_len, cell_network_size);
+   if (n < 0) n = 0;
+ #if SIZEOF_SIZE_T > SIZEOF_INT
+   if (n > INT_MAX) n = INT_MAX;
+ #endif
+ 
+   return (int)n;
+ }
+ 
+ /**
+  * Write a cell to a channel_tls_t.
+  *
+  * This implements the write_cell method for channel_tls_t; given a
+  * channel_tls_t and a cell_t, transmit the cell_t.
+  */
+ static int
+ channel_tls_write_cell_method(channel_t *chan, cell_t *cell)
+ {
+   channel_tls_t *tlschan = BASE_CHAN_TO_TLS(chan);
+   int written = 0;
+ 
+   tor_assert(tlschan);
+   tor_assert(cell);
+ 
+   if (tlschan->conn) {
+     connection_or_write_cell_to_buf(cell, tlschan->conn);
+     ++written;
+   } else {
+     log_info(LD_CHANNEL,
+              "something called write_cell on a tlschan "
+              "(%p with ID %"PRIu64 " but no conn",
+              chan, (chan->global_identifier));
+   }
+ 
+   return written;
+ }
+ 
+ /**
+  * Write a packed cell to a channel_tls_t.
+  *
+  * This implements the write_packed_cell method for channel_tls_t; given a
+  * channel_tls_t and a packed_cell_t, transmit the packed_cell_t.
+  *
+  * Return 0 on success or negative value on error. The caller must free the
+  * packed cell.
+  */
+ static int
+ channel_tls_write_packed_cell_method(channel_t *chan,
+                                      packed_cell_t *packed_cell)
+ {
+   tor_assert(chan);
+   channel_tls_t *tlschan = BASE_CHAN_TO_TLS(chan);
+   size_t cell_network_size = get_cell_network_size(chan->wide_circ_ids);
+ 
+   tor_assert(tlschan);
+   tor_assert(packed_cell);
+ 
+   if (tlschan->conn) {
+     connection_buf_add(packed_cell->body, cell_network_size,
+                             TO_CONN(tlschan->conn));
+   } else {
+     log_info(LD_CHANNEL,
+              "something called write_packed_cell on a tlschan "
+              "(%p with ID %"PRIu64 " but no conn",
+              chan, (chan->global_identifier));
+     return -1;
+   }
+ 
+   return 0;
+ }
+ 
+ /**
+  * Write a variable-length cell to a channel_tls_t.
+  *
+  * This implements the write_var_cell method for channel_tls_t; given a
+  * channel_tls_t and a var_cell_t, transmit the var_cell_t.
+  */
+ static int
+ channel_tls_write_var_cell_method(channel_t *chan, var_cell_t *var_cell)
+ {
+   channel_tls_t *tlschan = BASE_CHAN_TO_TLS(chan);
+   int written = 0;
+ 
+   tor_assert(tlschan);
+   tor_assert(var_cell);
+ 
+   if (tlschan->conn) {
+     connection_or_write_var_cell_to_buf(var_cell, tlschan->conn);
+     ++written;
+   } else {
+     log_info(LD_CHANNEL,
+              "something called write_var_cell on a tlschan "
+              "(%p with ID %"PRIu64 " but no conn",
+              chan, (chan->global_identifier));
+   }
+ 
+   return written;
+ }
+ 
+ /*************************************************
+  * Method implementations for channel_listener_t *
+  ************************************************/
+ 
+ /**
+  * Close a channel_listener_t.
+  *
+  * This implements the close method for channel_listener_t.
+  */
+ static void
+ channel_tls_listener_close_method(channel_listener_t *chan_l)
+ {
+   tor_assert(chan_l);
+ 
+   /*
+    * Listeners we just go ahead and change state through to CLOSED, but
+    * make sure to check if they're channel_tls_listener to NULL it out.
+    */
+   if (chan_l == channel_tls_listener)
+     channel_tls_listener = NULL;
+ 
+   if (!(chan_l->state == CHANNEL_LISTENER_STATE_CLOSING ||
+         chan_l->state == CHANNEL_LISTENER_STATE_CLOSED ||
+         chan_l->state == CHANNEL_LISTENER_STATE_ERROR)) {
+     channel_listener_change_state(chan_l, CHANNEL_LISTENER_STATE_CLOSING);
+   }
+ 
+   if (chan_l->incoming_list) {
+     SMARTLIST_FOREACH_BEGIN(chan_l->incoming_list,
+                             channel_t *, ichan) {
+       channel_mark_for_close(ichan);
+     } SMARTLIST_FOREACH_END(ichan);
+ 
+     smartlist_free(chan_l->incoming_list);
+     chan_l->incoming_list = NULL;
+   }
+ 
+   if (!(chan_l->state == CHANNEL_LISTENER_STATE_CLOSED ||
+         chan_l->state == CHANNEL_LISTENER_STATE_ERROR)) {
+     channel_listener_change_state(chan_l, CHANNEL_LISTENER_STATE_CLOSED);
+   }
+ }
+ 
+ /**
+  * Describe the transport for a channel_listener_t.
+  *
+  * This returns the string "TLS channel (listening)" to the upper
+  * layer.
+  */
+ static const char *
+ channel_tls_listener_describe_transport_method(channel_listener_t *chan_l)
+ {
+   tor_assert(chan_l);
+ 
+   return "TLS channel (listening)";
+ }
+ 
+ /*******************************************************
+  * Functions for handling events on an or_connection_t *
+  ******************************************************/
+ 
+ /**
+  * Handle an orconn state change.
+  *
+  * This function will be called by connection_or.c when the or_connection_t
+  * associated with this channel_tls_t changes state.
+  */
+ void
+ channel_tls_handle_state_change_on_orconn(channel_tls_t *chan,
+                                           or_connection_t *conn,
+                                           uint8_t old_state,
+                                           uint8_t state)
+ {
+   channel_t *base_chan;
+ 
+   tor_assert(chan);
+   tor_assert(conn);
+   tor_assert(conn->chan == chan);
+   tor_assert(chan->conn == conn);
+   /* Shut the compiler up without triggering -Wtautological-compare */
+   (void)old_state;
+ 
+   base_chan = TLS_CHAN_TO_BASE(chan);
+ 
+   /* Make sure the base connection state makes sense - shouldn't be error
+    * or closed. */
+ 
+   tor_assert(CHANNEL_IS_OPENING(base_chan) ||
+              CHANNEL_IS_OPEN(base_chan) ||
+              CHANNEL_IS_MAINT(base_chan) ||
+              CHANNEL_IS_CLOSING(base_chan));
+ 
+   /* Did we just go to state open? */
+   if (state == OR_CONN_STATE_OPEN) {
+     /*
+      * We can go to CHANNEL_STATE_OPEN from CHANNEL_STATE_OPENING or
+      * CHANNEL_STATE_MAINT on this.
+      */
+     channel_change_state_open(base_chan);
+     /* We might have just become writeable; check and tell the scheduler */
+     if (connection_or_num_cells_writeable(conn) > 0) {
+       scheduler_channel_wants_writes(base_chan);
+     }
+   } else {
+     /*
+      * Not open, so from CHANNEL_STATE_OPEN we go to CHANNEL_STATE_MAINT,
+      * otherwise no change.
+      */
+     if (CHANNEL_IS_OPEN(base_chan)) {
+       channel_change_state(base_chan, CHANNEL_STATE_MAINT);
+     }
+   }
+ }
+ 
+ #ifdef KEEP_TIMING_STATS
+ 
+ /**
+  * Timing states wrapper.
+  *
+  * This is a wrapper function around the actual function that processes the
+  * <b>cell</b> that just arrived on <b>chan</b>. Increment <b>*time</b>
+  * by the number of microseconds used by the call to <b>*func(cell, chan)</b>.
+  */
+ static void
+ channel_tls_time_process_cell(cell_t *cell, channel_tls_t *chan, int *time,
+                               void (*func)(cell_t *, channel_tls_t *))
+ {
+   struct timeval start, end;
+   long time_passed;
+ 
+   tor_gettimeofday(&start);
+ 
+   (*func)(cell, chan);
+ 
+   tor_gettimeofday(&end);
+   time_passed = tv_udiff(&start, &end) ;
+ 
+   if (time_passed > 10000) { /* more than 10ms */
+     log_debug(LD_OR,"That call just took %ld ms.",time_passed/1000);
+   }
+ 
+   if (time_passed < 0) {
+     log_info(LD_GENERAL,"That call took us back in time!");
+     time_passed = 0;
+   }
+ 
+   *time += time_passed;
+ }
+ #endif /* defined(KEEP_TIMING_STATS) */
+ 
+ /**
+  * Handle an incoming cell on a channel_tls_t.
+  *
+  * This is called from connection_or.c to handle an arriving cell; it checks
+  * for cell types specific to the handshake for this transport protocol and
+  * handles them, and queues all other cells to the channel_t layer, which
+  * eventually will hand them off to command.c.
+  *
+  * The channel layer itself decides whether the cell should be queued or
+  * can be handed off immediately to the upper-layer code.  It is responsible
+  * for copying in the case that it queues; we merely pass pointers through
+  * which we get from connection_or_process_cells_from_inbuf().
+  */
+ void
+ channel_tls_handle_cell(cell_t *cell, or_connection_t *conn)
+ {
+   channel_tls_t *chan;
+   int handshaking;
+ 
+ #ifdef KEEP_TIMING_STATS
+ #define PROCESS_CELL(tp, cl, cn) STMT_BEGIN {                   \
+     ++num ## tp;                                                \
+     channel_tls_time_process_cell(cl, cn, & tp ## time ,            \
+                              channel_tls_process_ ## tp ## _cell);  \
+     } STMT_END
+ #else /* !(defined(KEEP_TIMING_STATS)) */
+ #define PROCESS_CELL(tp, cl, cn) channel_tls_process_ ## tp ## _cell(cl, cn)
+ #endif /* defined(KEEP_TIMING_STATS) */
+ 
+   tor_assert(cell);
+   tor_assert(conn);
+ 
+   chan = conn->chan;
+ 
+  if (!chan) {
+    log_warn(LD_CHANNEL,
+             "Got a cell_t on an OR connection with no channel");
+    return;
+   }
+ 
+   handshaking = (TO_CONN(conn)->state != OR_CONN_STATE_OPEN);
+ 
+   if (conn->base_.marked_for_close)
+     return;
+ 
+   /* Reject all but VERSIONS and NETINFO when handshaking. */
+   /* (VERSIONS should actually be impossible; it's variable-length.) */
+   if (handshaking && cell->command != CELL_VERSIONS &&
+       cell->command != CELL_NETINFO) {
+     log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL,
+            "Received unexpected cell command %d in chan state %s / "
+            "conn state %s; closing the connection.",
+            (int)cell->command,
+            channel_state_to_string(TLS_CHAN_TO_BASE(chan)->state),
+            conn_state_to_string(CONN_TYPE_OR, TO_CONN(conn)->state));
+     connection_or_close_for_error(conn, 0);
+     return;
+   }
+ 
+   if (conn->base_.state == OR_CONN_STATE_OR_HANDSHAKING_V3)
+     or_handshake_state_record_cell(conn, conn->handshake_state, cell, 1);
+ 
+   /* We note that we're on the internet whenever we read a cell. This is
+    * a fast operation. */
+   entry_guards_note_internet_connectivity(get_guard_selection_info());
+   rep_hist_padding_count_read(PADDING_TYPE_TOTAL);
+ 
+   if (TLS_CHAN_TO_BASE(chan)->currently_padding)
+     rep_hist_padding_count_read(PADDING_TYPE_ENABLED_TOTAL);
+ 
+   switch (cell->command) {
+     case CELL_PADDING:
+       rep_hist_padding_count_read(PADDING_TYPE_CELL);
+       if (TLS_CHAN_TO_BASE(chan)->currently_padding)
+         rep_hist_padding_count_read(PADDING_TYPE_ENABLED_CELL);
+       ++stats_n_padding_cells_processed;
+       /* do nothing */
+       break;
+     case CELL_VERSIONS:
 -      tor_fragile_assert();
++      /* A VERSIONS cell should always be a variable-length cell, and
++       * so should never reach this function (which handles constant-sized
++       * cells). But if the connection is using the (obsolete) v1 link
++       * protocol, all cells will be treated as constant-sized, and so
++       * it's possible we'll reach this code.
++       */
++      log_fn(LOG_PROTOCOL_WARN, LD_CHANNEL,
++             "Received unexpected VERSIONS cell on a channel using link "
++             "protocol %d; ignoring.", conn->link_proto);
+       break;
+     case CELL_NETINFO:
+       ++stats_n_netinfo_cells_processed;
+       PROCESS_CELL(netinfo, cell, chan);
+       break;
+     case CELL_PADDING_NEGOTIATE:
+       ++stats_n_netinfo_cells_processed;
+       PROCESS_CELL(padding_negotiate, cell, chan);
+       break;
+     case CELL_CREATE:
+     case CELL_CREATE_FAST:
+     case CELL_CREATED:
+     case CELL_CREATED_FAST:
+     case CELL_RELAY:
+     case CELL_RELAY_EARLY:
+     case CELL_DESTROY:
+     case CELL_CREATE2:
+     case CELL_CREATED2:
+       /*
+        * These are all transport independent and we pass them up through the
+        * channel_t mechanism.  They are ultimately handled in command.c.
+        */
+       channel_process_cell(TLS_CHAN_TO_BASE(chan), cell);
+       break;
+     default:
+       log_fn(LOG_INFO, LD_PROTOCOL,
+              "Cell of unknown type (%d) received in channeltls.c.  "
+              "Dropping.",
+              cell->command);
+              break;
+   }
+ }
+ 
+ /**
+  * Handle an incoming variable-length cell on a channel_tls_t.
+  *
+  * Process a <b>var_cell</b> that was just received on <b>conn</b>. Keep
+  * internal statistics about how many of each cell we've processed so far
+  * this second, and the total number of microseconds it took to
+  * process each type of cell.  All the var_cell commands are handshake-
+  * related and live below the channel_t layer, so no variable-length
+  * cells ever get delivered in the current implementation, but I've left
+  * the mechanism in place for future use.
+  *
+  * If we were handing them off to the upper layer, the channel_t queueing
+  * code would be responsible for memory management, and we'd just be passing
+  * pointers through from connection_or_process_cells_from_inbuf().  That
+  * caller always frees them after this function returns, so this function
+  * should never free var_cell.
+  */
+ void
+ channel_tls_handle_var_cell(var_cell_t *var_cell, or_connection_t *conn)
+ {
+   channel_tls_t *chan;
+ 
+ #ifdef KEEP_TIMING_STATS
+   /* how many of each cell have we seen so far this second? needs better
+    * name. */
+   static int num_versions = 0, num_certs = 0;
+   static time_t current_second = 0; /* from previous calls to time */
+   time_t now = time(NULL);
+ 
+   if (current_second == 0) current_second = now;
+   if (now > current_second) { /* the second has rolled over */
+     /* print stats */
+     log_info(LD_OR,
+              "At end of second: %d versions (%d ms), %d certs (%d ms)",
+              num_versions, versions_time / ((now - current_second) * 1000),
+              num_certs, certs_time / ((now - current_second) * 1000));
+ 
+     num_versions = num_certs = 0;
+     versions_time = certs_time = 0;
+ 
+     /* remember which second it is, for next time */
+     current_second = now;
+   }
+ #endif /* defined(KEEP_TIMING_STATS) */
+ 
+   tor_assert(var_cell);
+   tor_assert(conn);
+ 
+   chan = conn->chan;
+ 
+   if (!chan) {
+     log_warn(LD_CHANNEL,
+              "Got a var_cell_t on an OR connection with no channel");
+     return;
+   }
+ 
+   if (TO_CONN(conn)->marked_for_close)
+     return;
+ 
+   switch (TO_CONN(conn)->state) {
+     case OR_CONN_STATE_OR_HANDSHAKING_V2:
+       if (var_cell->command != CELL_VERSIONS) {
+         log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL,
+                "Received a cell with command %d in unexpected "
+                "orconn state \"%s\" [%d], channel state \"%s\" [%d]; "
+                "closing the connection.",
+                (int)(var_cell->command),
+                conn_state_to_string(CONN_TYPE_OR, TO_CONN(conn)->state),
+                TO_CONN(conn)->state,
+                channel_state_to_string(TLS_CHAN_TO_BASE(chan)->state),
+                (int)(TLS_CHAN_TO_BASE(chan)->state));
+         /*
+          * The code in connection_or.c will tell channel_t to close for
+          * error; it will go to CHANNEL_STATE_CLOSING, and then to
+          * CHANNEL_STATE_ERROR when conn is closed.
+          */
+         connection_or_close_for_error(conn, 0);
+         return;
+       }
+       break;
+     case OR_CONN_STATE_TLS_HANDSHAKING:
+       /* If we're using bufferevents, it's entirely possible for us to
+        * notice "hey, data arrived!" before we notice "hey, the handshake
+        * finished!" And we need to be accepting both at once to handle both
+        * the v2 and v3 handshakes. */
+       /* But that should be happening any longer've disabled bufferevents. */
+       tor_assert_nonfatal_unreached_once();
+ 
+       /* fall through */
+     case OR_CONN_STATE_TLS_SERVER_RENEGOTIATING:
+       if (!(command_allowed_before_handshake(var_cell->command))) {
+         log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL,
+                "Received a cell with command %d in unexpected "
+                "orconn state \"%s\" [%d], channel state \"%s\" [%d]; "
+                "closing the connection.",
+                (int)(var_cell->command),
+                conn_state_to_string(CONN_TYPE_OR, TO_CONN(conn)->state),
+                (int)(TO_CONN(conn)->state),
+                channel_state_to_string(TLS_CHAN_TO_BASE(chan)->state),
+                (int)(TLS_CHAN_TO_BASE(chan)->state));
+         /* see above comment about CHANNEL_STATE_ERROR */
+         connection_or_close_for_error(conn, 0);
+         return;
+       } else {
+         if (enter_v3_handshake_with_cell(var_cell, chan) < 0)
+           return;
+       }
+       break;
+     case OR_CONN_STATE_OR_HANDSHAKING_V3:
+       if (var_cell->command != CELL_AUTHENTICATE)
+         or_handshake_state_record_var_cell(conn, conn->handshake_state,
+                                            var_cell, 1);
+       break; /* Everything is allowed */
+     case OR_CONN_STATE_OPEN:
+       if (conn->link_proto < 3) {
+         log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL,
+                "Received a variable-length cell with command %d in orconn "
+                "state %s [%d], channel state %s [%d] with link protocol %d; "
+                "ignoring it.",
+                (int)(var_cell->command),
+                conn_state_to_string(CONN_TYPE_OR, TO_CONN(conn)->state),
+                (int)(TO_CONN(conn)->state),
+                channel_state_to_string(TLS_CHAN_TO_BASE(chan)->state),
+                (int)(TLS_CHAN_TO_BASE(chan)->state),
+                (int)(conn->link_proto));
+         return;
+       }
+       break;
+     default:
+       log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL,
+              "Received var-length cell with command %d in unexpected "
+              "orconn state \"%s\" [%d], channel state \"%s\" [%d]; "
+              "ignoring it.",
+              (int)(var_cell->command),
+              conn_state_to_string(CONN_TYPE_OR, TO_CONN(conn)->state),
+              (int)(TO_CONN(conn)->state),
+              channel_state_to_string(TLS_CHAN_TO_BASE(chan)->state),
+              (int)(TLS_CHAN_TO_BASE(chan)->state));
+       return;
+   }
+ 
+   /* We note that we're on the internet whenever we read a cell. This is
+    * a fast operation. */
+   entry_guards_note_internet_connectivity(get_guard_selection_info());
+ 
+   /* Now handle the cell */
+ 
+   switch (var_cell->command) {
+     case CELL_VERSIONS:
+       ++stats_n_versions_cells_processed;
+       PROCESS_CELL(versions, var_cell, chan);
+       break;
+     case CELL_VPADDING:
+       ++stats_n_vpadding_cells_processed;
+       /* Do nothing */
+       break;
+     case CELL_CERTS:
+       ++stats_n_certs_cells_processed;
+       PROCESS_CELL(certs, var_cell, chan);
+       break;
+     case CELL_AUTH_CHALLENGE:
+       ++stats_n_auth_challenge_cells_processed;
+       PROCESS_CELL(auth_challenge, var_cell, chan);
+       break;
+     case CELL_AUTHENTICATE:
+       ++stats_n_authenticate_cells_processed;
+       PROCESS_CELL(authenticate, var_cell, chan);
+       break;
+     case CELL_AUTHORIZE:
+       ++stats_n_authorize_cells_processed;
+       /* Ignored so far. */
+       break;
+     default:
+       log_fn(LOG_INFO, LD_PROTOCOL,
+              "Variable-length cell of unknown type (%d) received.",
+              (int)(var_cell->command));
+       break;
+   }
+ }
+ 
+ /**
+  * Update channel marks after connection_or.c has changed an address.
+  *
+  * This is called from connection_or_init_conn_from_address() after the
+  * connection's _base.addr or real_addr fields have potentially been changed
+  * so we can recalculate the local mark.  Notably, this happens when incoming
+  * connections are reverse-proxied and we only learn the real address of the
+  * remote router by looking it up in the consensus after we finish the
+  * handshake and know an authenticated identity digest.
+  */
+ void
+ channel_tls_update_marks(or_connection_t *conn)
+ {
+   channel_t *chan = NULL;
+ 
+   tor_assert(conn);
+   tor_assert(conn->chan);
+ 
+   chan = TLS_CHAN_TO_BASE(conn->chan);
+ 
+   if (is_local_addr(&(TO_CONN(conn)->addr))) {
+     if (!channel_is_local(chan)) {
+       log_debug(LD_CHANNEL,
+                 "Marking channel %"PRIu64 " at %p as local",
+                 (chan->global_identifier), chan);
+       channel_mark_local(chan);
+     }
+   } else {
+     if (channel_is_local(chan)) {
+       log_debug(LD_CHANNEL,
+                 "Marking channel %"PRIu64 " at %p as remote",
+                 (chan->global_identifier), chan);
+       channel_mark_remote(chan);
+     }
+   }
+ }
+ 
+ /**
+  * Check if this cell type is allowed before the handshake is finished.
+  *
+  * Return true if <b>command</b> is a cell command that's allowed to start a
+  * V3 handshake.
+  */
+ static int
+ command_allowed_before_handshake(uint8_t command)
+ {
+   switch (command) {
+     case CELL_VERSIONS:
+     case CELL_VPADDING:
+     case CELL_AUTHORIZE:
+       return 1;
+     default:
+       return 0;
+   }
+ }
+ 
+ /**
+  * Start a V3 handshake on an incoming connection.
+  *
+  * Called when we as a server receive an appropriate cell while waiting
+  * either for a cell or a TLS handshake.  Set the connection's state to
+  * "handshaking_v3', initializes the or_handshake_state field as needed,
+  * and add the cell to the hash of incoming cells.)
+  */
+ static int
+ enter_v3_handshake_with_cell(var_cell_t *cell, channel_tls_t *chan)
+ {
+   int started_here = 0;
+ 
+   tor_assert(cell);
+   tor_assert(chan);
+   tor_assert(chan->conn);
+ 
+   started_here = connection_or_nonopen_was_started_here(chan->conn);
+ 
+   tor_assert(TO_CONN(chan->conn)->state == OR_CONN_STATE_TLS_HANDSHAKING ||
+              TO_CONN(chan->conn)->state ==
+                OR_CONN_STATE_TLS_SERVER_RENEGOTIATING);
+ 
+   if (started_here) {
+     log_fn(LOG_PROTOCOL_WARN, LD_OR,
+            "Received a cell while TLS-handshaking, not in "
+            "OR_HANDSHAKING_V3, on a connection we originated.");
+   }
+   connection_or_block_renegotiation(chan->conn);
+   chan->conn->base_.state = OR_CONN_STATE_OR_HANDSHAKING_V3;
+   if (connection_init_or_handshake_state(chan->conn, started_here) < 0) {
+     connection_or_close_for_error(chan->conn, 0);
+     return -1;
+   }
+   or_handshake_state_record_var_cell(chan->conn,
+                                      chan->conn->handshake_state, cell, 1);
+   return 0;
+ }
+ 
+ /**
+  * Process a 'versions' cell.
+  *
+  * This function is called to handle an incoming VERSIONS cell; the current
+  * link protocol version must be 0 to indicate that no version has yet been
+  * negotiated.  We compare the versions in the cell to the list of versions
+  * we support, pick the highest version we have in common, and continue the
+  * negotiation from there.
+  */
+ static void
+ channel_tls_process_versions_cell(var_cell_t *cell, channel_tls_t *chan)
+ {
+   int highest_supported_version = 0;
+   int started_here = 0;
+ 
+   tor_assert(cell);
+   tor_assert(chan);
+   tor_assert(chan->conn);
+ 
+   if ((cell->payload_len % 2) == 1) {
+     log_fn(LOG_PROTOCOL_WARN, LD_OR,
+            "Received a VERSION cell with odd payload length %d; "
+            "closing connection.",cell->payload_len);
+     connection_or_close_for_error(chan->conn, 0);
+     return;
+   }
+ 
+   started_here = connection_or_nonopen_was_started_here(chan->conn);
+ 
+   if (chan->conn->link_proto != 0 ||
+       (chan->conn->handshake_state &&
+        chan->conn->handshake_state->received_versions)) {
+     log_fn(LOG_PROTOCOL_WARN, LD_OR,
+            "Received a VERSIONS cell on a connection with its version "
+            "already set to %d; dropping",
+            (int)(chan->conn->link_proto));
+     return;
+   }
+   switch (chan->conn->base_.state)
+     {
+     case OR_CONN_STATE_OR_HANDSHAKING_V2:
+     case OR_CONN_STATE_OR_HANDSHAKING_V3:
+       break;
+     case OR_CONN_STATE_TLS_HANDSHAKING:
+     case OR_CONN_STATE_TLS_SERVER_RENEGOTIATING:
+     default:
+       log_fn(LOG_PROTOCOL_WARN, LD_OR,
+              "VERSIONS cell while in unexpected state");
+       return;
+   }
+ 
+   tor_assert(chan->conn->handshake_state);
+ 
+   {
+     int i;
+     const uint8_t *cp = cell->payload;
+     for (i = 0; i < cell->payload_len / 2; ++i, cp += 2) {
+       uint16_t v = ntohs(get_uint16(cp));
+       if (is_or_protocol_version_known(v) && v > highest_supported_version)
+         highest_supported_version = v;
+     }
+   }
+   if (!highest_supported_version) {
+     log_fn(LOG_PROTOCOL_WARN, LD_OR,
+            "Couldn't find a version in common between my version list and the "
+            "list in the VERSIONS cell; closing connection.");
+     connection_or_close_for_error(chan->conn, 0);
+     return;
+   } else if (highest_supported_version == 1) {
+     /* Negotiating version 1 makes no sense, since version 1 has no VERSIONS
+      * cells. */
+     log_fn(LOG_PROTOCOL_WARN, LD_OR,
+            "Used version negotiation protocol to negotiate a v1 connection. "
+            "That's crazily non-compliant. Closing connection.");
+     connection_or_close_for_error(chan->conn, 0);
+     return;
+   } else if (highest_supported_version < 3 &&
+              chan->conn->base_.state == OR_CONN_STATE_OR_HANDSHAKING_V3) {
+     log_fn(LOG_PROTOCOL_WARN, LD_OR,
+            "Negotiated link protocol 2 or lower after doing a v3 TLS "
+            "handshake. Closing connection.");
+     connection_or_close_for_error(chan->conn, 0);
+     return;
+   } else if (highest_supported_version != 2 &&
+              chan->conn->base_.state == OR_CONN_STATE_OR_HANDSHAKING_V2) {
+     /* XXXX This should eventually be a log_protocol_warn */
+     log_fn(LOG_WARN, LD_OR,
+            "Negotiated link with non-2 protocol after doing a v2 TLS "
+            "handshake with %s. Closing connection.",
+            fmt_addr(&chan->conn->base_.addr));
+     connection_or_close_for_error(chan->conn, 0);
+     return;
+   }
+ 
+   rep_hist_note_negotiated_link_proto(highest_supported_version, started_here);
+ 
+   chan->conn->link_proto = highest_supported_version;
+   chan->conn->handshake_state->received_versions = 1;
+ 
+   if (chan->conn->link_proto == 2) {
+     log_info(LD_OR,
+              "Negotiated version %d with %s:%d; sending NETINFO.",
+              highest_supported_version,
+              safe_str_client(chan->conn->base_.address),
+              chan->conn->base_.port);
+ 
+     if (connection_or_send_netinfo(chan->conn) < 0) {
+       connection_or_close_for_error(chan->conn, 0);
+       return;
+     }
+   } else {
+     const int send_versions = !started_here;
+     /* If we want to authenticate, send a CERTS cell */
+     const int send_certs = !started_here || public_server_mode(get_options());
+     /* If we're a host that got a connection, ask for authentication. */
+     const int send_chall = !started_here;
+     /* If our certs cell will authenticate us, we can send a netinfo cell
+      * right now. */
+     const int send_netinfo = !started_here;
+     const int send_any =
+       send_versions || send_certs || send_chall || send_netinfo;
+     tor_assert(chan->conn->link_proto >= 3);
+ 
+     log_info(LD_OR,
+              "Negotiated version %d with %s:%d; %s%s%s%s%s",
+              highest_supported_version,
+              safe_str_client(chan->conn->base_.address),
+              chan->conn->base_.port,
+              send_any ? "Sending cells:" : "Waiting for CERTS cell",
+              send_versions ? " VERSIONS" : "",
+              send_certs ? " CERTS" : "",
+              send_chall ? " AUTH_CHALLENGE" : "",
+              send_netinfo ? " NETINFO" : "");
+ 
+ #ifdef DISABLE_V3_LINKPROTO_SERVERSIDE
+     if (1) {
+       connection_or_close_normally(chan->conn, 1);
+       return;
+     }
+ #endif /* defined(DISABLE_V3_LINKPROTO_SERVERSIDE) */
+ 
+     if (send_versions) {
+       if (connection_or_send_versions(chan->conn, 1) < 0) {
+         log_warn(LD_OR, "Couldn't send versions cell");
+         connection_or_close_for_error(chan->conn, 0);
+         return;
+       }
+     }
+ 
+     /* We set this after sending the versions cell. */
+     /*XXXXX symbolic const.*/
+     TLS_CHAN_TO_BASE(chan)->wide_circ_ids =
+       chan->conn->link_proto >= MIN_LINK_PROTO_FOR_WIDE_CIRC_IDS;
+     chan->conn->wide_circ_ids = TLS_CHAN_TO_BASE(chan)->wide_circ_ids;
+ 
+     TLS_CHAN_TO_BASE(chan)->padding_enabled =
+       chan->conn->link_proto >= MIN_LINK_PROTO_FOR_CHANNEL_PADDING;
+ 
+     if (send_certs) {
+       if (connection_or_send_certs_cell(chan->conn) < 0) {
+         log_warn(LD_OR, "Couldn't send certs cell");
+         connection_or_close_for_error(chan->conn, 0);
+         return;
+       }
+     }
+     if (send_chall) {
+       if (connection_or_send_auth_challenge_cell(chan->conn) < 0) {
+         log_warn(LD_OR, "Couldn't send auth_challenge cell");
+         connection_or_close_for_error(chan->conn, 0);
+         return;
+       }
+     }
+     if (send_netinfo) {
+       if (connection_or_send_netinfo(chan->conn) < 0) {
+         log_warn(LD_OR, "Couldn't send netinfo cell");
+         connection_or_close_for_error(chan->conn, 0);
+         return;
+       }
+     }
+   }
+ }
+ 
+ /**
+  * Process a 'padding_negotiate' cell.
+  *
+  * This function is called to handle an incoming PADDING_NEGOTIATE cell;
+  * enable or disable padding accordingly, and read and act on its timeout
+  * value contents.
+  */
+ static void
+ channel_tls_process_padding_negotiate_cell(cell_t *cell, channel_tls_t *chan)
+ {
+   channelpadding_negotiate_t *negotiation;
+   tor_assert(cell);
+   tor_assert(chan);
+   tor_assert(chan->conn);
+ 
+   if (chan->conn->link_proto < MIN_LINK_PROTO_FOR_CHANNEL_PADDING) {
+     log_fn(LOG_PROTOCOL_WARN, LD_OR,
+            "Received a PADDING_NEGOTIATE cell on v%d connection; dropping.",
+            chan->conn->link_proto);
+     return;
+   }
+ 
+   if (channelpadding_negotiate_parse(&negotiation, cell->payload,
+                                      CELL_PAYLOAD_SIZE) < 0) {
+     log_fn(LOG_PROTOCOL_WARN, LD_OR,
+           "Received malformed PADDING_NEGOTIATE cell on v%d connection; "
+           "dropping.", chan->conn->link_proto);
+ 
+     return;
+   }
+ 
+   channelpadding_update_padding_for_channel(TLS_CHAN_TO_BASE(chan),
+                                             negotiation);
+ 
+   channelpadding_negotiate_free(negotiation);
+ }
+ 
+ /**
+  * Helper: compute the absolute value of a time_t.
+  *
+  * (we need this because labs() doesn't always work for time_t, since
+  * long can be shorter than time_t.)
+  */
+ static inline time_t
+ time_abs(time_t val)
+ {
+   return (val < 0) ? -val : val;
+ }
+ 
+ /**
+  * Process a 'netinfo' cell
+  *
+  * This function is called to handle an incoming NETINFO cell; read and act
+  * on its contents, and set the connection state to "open".
+  */
+ static void
+ channel_tls_process_netinfo_cell(cell_t *cell, channel_tls_t *chan)
+ {
+   time_t timestamp;
+   uint8_t my_addr_type;
+   uint8_t my_addr_len;
+   const uint8_t *my_addr_ptr;
+   const uint8_t *cp, *end;
+   uint8_t n_other_addrs;
+   time_t now = time(NULL);
+   const routerinfo_t *me = router_get_my_routerinfo();
+ 
+   time_t apparent_skew = 0;
+   tor_addr_t my_apparent_addr = TOR_ADDR_NULL;
+   int started_here = 0;
+   const char *identity_digest = NULL;
+ 
+   tor_assert(cell);
+   tor_assert(chan);
+   tor_assert(chan->conn);
+ 
+   if (chan->conn->link_proto < 2) {
+     log_fn(LOG_PROTOCOL_WARN, LD_OR,
+            "Received a NETINFO cell on %s connection; dropping.",
+            chan->conn->link_proto == 0 ? "non-versioned" : "a v1");
+     return;
+   }
+   if (chan->conn->base_.state != OR_CONN_STATE_OR_HANDSHAKING_V2 &&
+       chan->conn->base_.state != OR_CONN_STATE_OR_HANDSHAKING_V3) {
+     log_fn(LOG_PROTOCOL_WARN, LD_OR,
+            "Received a NETINFO cell on non-handshaking connection; dropping.");
+     return;
+   }
+   tor_assert(chan->conn->handshake_state &&
+              chan->conn->handshake_state->received_versions);
+   started_here = connection_or_nonopen_was_started_here(chan->conn);
+   identity_digest = chan->conn->identity_digest;
+ 
+   if (chan->conn->base_.state == OR_CONN_STATE_OR_HANDSHAKING_V3) {
+     tor_assert(chan->conn->link_proto >= 3);
+     if (started_here) {
+       if (!(chan->conn->handshake_state->authenticated)) {
+         log_fn(LOG_PROTOCOL_WARN, LD_OR,
+                "Got a NETINFO cell from server, "
+                "but no authentication.  Closing the connection.");
+         connection_or_close_for_error(chan->conn, 0);
+         return;
+       }
+     } else {
+       /* we're the server.  If the client never authenticated, we have
+          some housekeeping to do.*/
+       if (!(chan->conn->handshake_state->authenticated)) {
+         tor_assert(tor_digest_is_zero(
+                   (const char*)(chan->conn->handshake_state->
+                       authenticated_rsa_peer_id)));
+         tor_assert(tor_mem_is_zero(
+                   (const char*)(chan->conn->handshake_state->
+                                 authenticated_ed25519_peer_id.pubkey), 32));
+         /* If the client never authenticated, it's a tor client or bridge
+          * relay, and we must not use it for EXTEND requests (nor could we, as
+          * there are no authenticated peer IDs) */
+         channel_mark_client(TLS_CHAN_TO_BASE(chan));
+         channel_set_circid_type(TLS_CHAN_TO_BASE(chan), NULL,
+                chan->conn->link_proto < MIN_LINK_PROTO_FOR_WIDE_CIRC_IDS);
+ 
+         connection_or_init_conn_from_address(chan->conn,
+                   &(chan->conn->base_.addr),
+                   chan->conn->base_.port,
+                   /* zero, checked above */
+                   (const char*)(chan->conn->handshake_state->
+                                 authenticated_rsa_peer_id),
+                   NULL, /* Ed25519 ID: Also checked as zero */
+                   0);
+       }
+     }
+   }
+ 
+   /* Decode the cell. */
+   timestamp = ntohl(get_uint32(cell->payload));
+   const time_t sent_versions_at =
+     chan->conn->handshake_state->sent_versions_at;
+   if (now > sent_versions_at && (now - sent_versions_at) < 180) {
+     /* If we have gotten the NETINFO cell reasonably soon after having
+      * sent our VERSIONS cell, maybe we can learn skew information from it. */
+     apparent_skew = now - timestamp;
+   }
+ 
+   my_addr_type = (uint8_t) cell->payload[4];
+   my_addr_len = (uint8_t) cell->payload[5];
+   my_addr_ptr = (uint8_t*) cell->payload + 6;
+   end = cell->payload + CELL_PAYLOAD_SIZE;
+   cp = cell->payload + 6 + my_addr_len;
+ 
+   /* We used to check:
+    *    if (my_addr_len >= CELL_PAYLOAD_SIZE - 6) {
+    *
+    * This is actually never going to happen, since my_addr_len is at most 255,
+    * and CELL_PAYLOAD_LEN - 6 is 503.  So we know that cp is < end. */
+ 
+   if (my_addr_type == RESOLVED_TYPE_IPV4 && my_addr_len == 4) {
+     tor_addr_from_ipv4n(&my_apparent_addr, get_uint32(my_addr_ptr));
+ 
+     if (!get_options()->BridgeRelay && me &&
+         get_uint32(my_addr_ptr) == htonl(me->addr)) {
+       TLS_CHAN_TO_BASE(chan)->is_canonical_to_peer = 1;
+     }
+ 
+   } else if (my_addr_type == RESOLVED_TYPE_IPV6 && my_addr_len == 16) {
+     tor_addr_from_ipv6_bytes(&my_apparent_addr, (const char *) my_addr_ptr);
+ 
+     if (!get_options()->BridgeRelay && me &&
+         !tor_addr_is_null(&me->ipv6_addr) &&
+         tor_addr_eq(&my_apparent_addr, &me->ipv6_addr)) {
+       TLS_CHAN_TO_BASE(chan)->is_canonical_to_peer = 1;
+     }
+   }
+ 
+   n_other_addrs = (uint8_t) *cp++;
+   while (n_other_addrs && cp < end-2) {
+     /* Consider all the other addresses; if any matches, this connection is
+      * "canonical." */
+     tor_addr_t addr;
+     const uint8_t *next =
+       decode_address_from_payload(&addr, cp, (int)(end-cp));
+     if (next == NULL) {
+       log_fn(LOG_PROTOCOL_WARN,  LD_OR,
+              "Bad address in netinfo cell; closing connection.");
+       connection_or_close_for_error(chan->conn, 0);
+       return;
+     }
+     /* A relay can connect from anywhere and be canonical, so
+      * long as it tells you from where it came. This may sound a bit
+      * concerning... but that's what "canonical" means: that the
+      * address is one that the relay itself has claimed.  The relay
+      * might be doing something funny, but nobody else is doing a MITM
+      * on the relay's TCP.
+      */
+     if (tor_addr_eq(&addr, &(chan->conn->real_addr))) {
+       connection_or_set_canonical(chan->conn, 1);
+       break;
+     }
+     cp = next;
+     --n_other_addrs;
+   }
+ 
+   if (me && !TLS_CHAN_TO_BASE(chan)->is_canonical_to_peer &&
+       channel_is_canonical(TLS_CHAN_TO_BASE(chan))) {
+     const char *descr =
+       TLS_CHAN_TO_BASE(chan)->get_remote_descr(TLS_CHAN_TO_BASE(chan), 0);
+     log_info(LD_OR,
+              "We made a connection to a relay at %s (fp=%s) but we think "
+              "they will not consider this connection canonical. They "
+              "think we are at %s, but we think its %s.",
+              safe_str(descr),
+              safe_str(hex_str(identity_digest, DIGEST_LEN)),
+              safe_str(tor_addr_is_null(&my_apparent_addr) ?
+              "<none>" : fmt_and_decorate_addr(&my_apparent_addr)),
+              safe_str(fmt_addr32(me->addr)));
+   }
+ 
+   /* Act on apparent skew. */
+   /** Warn when we get a netinfo skew with at least this value. */
+ #define NETINFO_NOTICE_SKEW 3600
+   if (time_abs(apparent_skew) > NETINFO_NOTICE_SKEW &&
+       (started_here ||
+        connection_or_digest_is_known_relay(chan->conn->identity_digest))) {
+     int trusted = router_digest_is_trusted_dir(chan->conn->identity_digest);
+     clock_skew_warning(TO_CONN(chan->conn), apparent_skew, trusted, LD_GENERAL,
+                        "NETINFO cell", "OR");
+   }
+ 
+   /* XXX maybe act on my_apparent_addr, if the source is sufficiently
+    * trustworthy. */
+ 
+   if (! chan->conn->handshake_state->sent_netinfo) {
+     /* If we were prepared to authenticate, but we never got an AUTH_CHALLENGE
+      * cell, then we would not previously have sent a NETINFO cell. Do so
+      * now. */
+     if (connection_or_send_netinfo(chan->conn) < 0) {
+       connection_or_close_for_error(chan->conn, 0);
+       return;
+     }
+   }
+ 
+   if (connection_or_set_state_open(chan->conn) < 0) {
+     log_fn(LOG_PROTOCOL_WARN, LD_OR,
+            "Got good NETINFO cell from %s:%d; but "
+            "was unable to make the OR connection become open.",
+            safe_str_client(chan->conn->base_.address),
+            chan->conn->base_.port);
+     connection_or_close_for_error(chan->conn, 0);
+   } else {
+     log_info(LD_OR,
+              "Got good NETINFO cell from %s:%d; OR connection is now "
+              "open, using protocol version %d. Its ID digest is %s. "
+              "Our address is apparently %s.",
+              safe_str_client(chan->conn->base_.address),
+              chan->conn->base_.port,
+              (int)(chan->conn->link_proto),
+              hex_str(identity_digest, DIGEST_LEN),
+              tor_addr_is_null(&my_apparent_addr) ?
+                "<none>" :
+                safe_str_client(fmt_and_decorate_addr(&my_apparent_addr)));
+   }
+   assert_connection_ok(TO_CONN(chan->conn),time(NULL));
+ }
+ 
+ /** Types of certificates that we know how to parse from CERTS cells.  Each
+  * type corresponds to a different encoding format. */
+ typedef enum cert_encoding_t {
+   CERT_ENCODING_UNKNOWN, /**< We don't recognize this. */
+   CERT_ENCODING_X509, /**< It's an RSA key, signed with RSA, encoded in x509.
+                    * (Actually, it might not be RSA. We test that later.) */
+   CERT_ENCODING_ED25519, /**< It's something signed with an Ed25519 key,
+                       * encoded asa a tor_cert_t.*/
+   CERT_ENCODING_RSA_CROSSCERT, /**< It's an Ed key signed with an RSA key. */
+ } cert_encoding_t;
+ 
+ /**
+  * Given one of the certificate type codes used in a CERTS cell,
+  * return the corresponding cert_encoding_t that we should use to parse
+  * the certificate.
+  */
+ static cert_encoding_t
+ certs_cell_typenum_to_cert_type(int typenum)
+ {
+   switch (typenum) {
+   case CERTTYPE_RSA1024_ID_LINK:
+   case CERTTYPE_RSA1024_ID_ID:
+   case CERTTYPE_RSA1024_ID_AUTH:
+     return CERT_ENCODING_X509;
+   case CERTTYPE_ED_ID_SIGN:
+   case CERTTYPE_ED_SIGN_LINK:
+   case CERTTYPE_ED_SIGN_AUTH:
+     return CERT_ENCODING_ED25519;
+   case CERTTYPE_RSA1024_ID_EDID:
+     return CERT_ENCODING_RSA_CROSSCERT;
+   default:
+     return CERT_ENCODING_UNKNOWN;
+   }
+ }
+ 
+ /**
+  * Process a CERTS cell from a channel.
+  *
+  * This function is called to process an incoming CERTS cell on a
+  * channel_tls_t:
+  *
+  * If the other side should not have sent us a CERTS cell, or the cell is
+  * malformed, or it is supposed to authenticate the TLS key but it doesn't,
+  * then mark the connection.
+  *
+  * If the cell has a good cert chain and we're doing a v3 handshake, then
+  * store the certificates in or_handshake_state.  If this is the client side
+  * of the connection, we then authenticate the server or mark the connection.
+  * If it's the server side, wait for an AUTHENTICATE cell.
+  */
+ STATIC void
+ channel_tls_process_certs_cell(var_cell_t *cell, channel_tls_t *chan)
+ {
+ #define MAX_CERT_TYPE_WANTED CERTTYPE_RSA1024_ID_EDID
+   /* These arrays will be sparse, since a cert type can be at most one
+    * of ed/x509 */
+   tor_x509_cert_t *x509_certs[MAX_CERT_TYPE_WANTED + 1];
+   tor_cert_t *ed_certs[MAX_CERT_TYPE_WANTED + 1];
+   uint8_t *rsa_ed_cc_cert = NULL;
+   size_t rsa_ed_cc_cert_len = 0;
+ 
+   int n_certs, i;
+   certs_cell_t *cc = NULL;
+ 
+   int send_netinfo = 0, started_here = 0;
+ 
+   memset(x509_certs, 0, sizeof(x509_certs));
+   memset(ed_certs, 0, sizeof(ed_certs));
+   tor_assert(cell);
+   tor_assert(chan);
+   tor_assert(chan->conn);
+ 
+ #define ERR(s)                                                  \
+   do {                                                          \
+     log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL,                      \
+            "Received a bad CERTS cell from %s:%d: %s",          \
+            safe_str(chan->conn->base_.address),                 \
+            chan->conn->base_.port, (s));                        \
+     connection_or_close_for_error(chan->conn, 0);               \
+     goto err;                                                   \
+   } while (0)
+ 
+   /* Can't use connection_or_nonopen_was_started_here(); its conn->tls
+    * check looks like it breaks
+    * test_link_handshake_recv_certs_ok_server().  */
+   started_here = chan->conn->handshake_state->started_here;
+ 
+   if (chan->conn->base_.state != OR_CONN_STATE_OR_HANDSHAKING_V3)
+     ERR("We're not doing a v3 handshake!");
+   if (chan->conn->link_proto < 3)
+     ERR("We're not using link protocol >= 3");
+   if (chan->conn->handshake_state->received_certs_cell)
+     ERR("We already got one");
+   if (chan->conn->handshake_state->authenticated) {
+     /* Should be unreachable, but let's make sure. */
+     ERR("We're already authenticated!");
+   }
+   if (cell->payload_len < 1)
+     ERR("It had no body");
+   if (cell->circ_id)
+     ERR("It had a nonzero circuit ID");
+ 
+   if (certs_cell_parse(&cc, cell->payload, cell->payload_len) < 0)
+     ERR("It couldn't be parsed.");
+ 
+   n_certs = cc->n_certs;
+ 
+   for (i = 0; i < n_certs; ++i) {
+     certs_cell_cert_t *c = certs_cell_get_certs(cc, i);
+ 
+     uint16_t cert_type = c->cert_type;
+     uint16_t cert_len = c->cert_len;
+     uint8_t *cert_body = certs_cell_cert_getarray_body(c);
+ 
+     if (cert_type > MAX_CERT_TYPE_WANTED)
+       continue;
+     const cert_encoding_t ct = certs_cell_typenum_to_cert_type(cert_type);
+     switch (ct) {
+       default:
+       case CERT_ENCODING_UNKNOWN:
+         break;
+       case CERT_ENCODING_X509: {
+         tor_x509_cert_t *x509_cert = tor_x509_cert_decode(cert_body, cert_len);
+         if (!x509_cert) {
+           log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL,
+                  "Received undecodable certificate in CERTS cell from %s:%d",
+                  safe_str(chan->conn->base_.address),
+                chan->conn->base_.port);
+         } else {
+           if (x509_certs[cert_type]) {
+             tor_x509_cert_free(x509_cert);
+             ERR("Duplicate x509 certificate");
+           } else {
+             x509_certs[cert_type] = x509_cert;
+           }
+         }
+         break;
+       }
+       case CERT_ENCODING_ED25519: {
+         tor_cert_t *ed_cert = tor_cert_parse(cert_body, cert_len);
+         if (!ed_cert) {
+           log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL,
+                  "Received undecodable Ed certificate "
+                  "in CERTS cell from %s:%d",
+                  safe_str(chan->conn->base_.address),
+                chan->conn->base_.port);
+         } else {
+           if (ed_certs[cert_type]) {
+             tor_cert_free(ed_cert);
+             ERR("Duplicate Ed25519 certificate");
+           } else {
+             ed_certs[cert_type] = ed_cert;
+           }
+         }
+         break;
+       }
+ 
+      case CERT_ENCODING_RSA_CROSSCERT: {
+         if (rsa_ed_cc_cert) {
+           ERR("Duplicate RSA->Ed25519 crosscert");
+         } else {
+           rsa_ed_cc_cert = tor_memdup(cert_body, cert_len);
+           rsa_ed_cc_cert_len = cert_len;
+         }
+         break;
+       }
+     }
+   }
+ 
+   /* Move the certificates we (might) want into the handshake_state->certs
+    * structure. */
+   tor_x509_cert_t *id_cert = x509_certs[CERTTYPE_RSA1024_ID_ID];
+   tor_x509_cert_t *auth_cert = x509_certs[CERTTYPE_RSA1024_ID_AUTH];
+   tor_x509_cert_t *link_cert = x509_certs[CERTTYPE_RSA1024_ID_LINK];
+   chan->conn->handshake_state->certs->auth_cert = auth_cert;
+   chan->conn->handshake_state->certs->link_cert = link_cert;
+   chan->conn->handshake_state->certs->id_cert = id_cert;
+   x509_certs[CERTTYPE_RSA1024_ID_ID] =
+     x509_certs[CERTTYPE_RSA1024_ID_AUTH] =
+     x509_certs[CERTTYPE_RSA1024_ID_LINK] = NULL;
+ 
+   tor_cert_t *ed_id_sign = ed_certs[CERTTYPE_ED_ID_SIGN];
+   tor_cert_t *ed_sign_link = ed_certs[CERTTYPE_ED_SIGN_LINK];
+   tor_cert_t *ed_sign_auth = ed_certs[CERTTYPE_ED_SIGN_AUTH];
+   chan->conn->handshake_state->certs->ed_id_sign = ed_id_sign;
+   chan->conn->handshake_state->certs->ed_sign_link = ed_sign_link;
+   chan->conn->handshake_state->certs->ed_sign_auth = ed_sign_auth;
+   ed_certs[CERTTYPE_ED_ID_SIGN] =
+     ed_certs[CERTTYPE_ED_SIGN_LINK] =
+     ed_certs[CERTTYPE_ED_SIGN_AUTH] = NULL;
+ 
+   chan->conn->handshake_state->certs->ed_rsa_crosscert = rsa_ed_cc_cert;
+   chan->conn->handshake_state->certs->ed_rsa_crosscert_len =
+     rsa_ed_cc_cert_len;
+   rsa_ed_cc_cert = NULL;
+ 
+   int severity;
+   /* Note that this warns more loudly about time and validity if we were
+    * _trying_ to connect to an authority, not necessarily if we _did_ connect
+    * to one. */
+   if (started_here &&
+       router_digest_is_trusted_dir(TLS_CHAN_TO_BASE(chan)->identity_digest))
+     severity = LOG_WARN;
+   else
+     severity = LOG_PROTOCOL_WARN;
+ 
+   const ed25519_public_key_t *checked_ed_id = NULL;
+   const common_digests_t *checked_rsa_id = NULL;
+   or_handshake_certs_check_both(severity,
+                                 chan->conn->handshake_state->certs,
+                                 chan->conn->tls,
+                                 time(NULL),
+                                 &checked_ed_id,
+                                 &checked_rsa_id);
+ 
+   if (!checked_rsa_id)
+     ERR("Invalid certificate chain!");
+ 
+   if (started_here) {
+     /* No more information is needed. */
+ 
+     chan->conn->handshake_state->authenticated = 1;
+     chan->conn->handshake_state->authenticated_rsa = 1;
+     {
+       const common_digests_t *id_digests = checked_rsa_id;
+       crypto_pk_t *identity_rcvd;
+       if (!id_digests)
+         ERR("Couldn't compute digests for key in ID cert");
+ 
+       identity_rcvd = tor_tls_cert_get_key(id_cert);
+       if (!identity_rcvd) {
+         ERR("Couldn't get RSA key from ID cert.");
+       }
+       memcpy(chan->conn->handshake_state->authenticated_rsa_peer_id,
+              id_digests->d[DIGEST_SHA1], DIGEST_LEN);
+       channel_set_circid_type(TLS_CHAN_TO_BASE(chan), identity_rcvd,
+                 chan->conn->link_proto < MIN_LINK_PROTO_FOR_WIDE_CIRC_IDS);
+       crypto_pk_free(identity_rcvd);
+     }
+ 
+     if (checked_ed_id) {
+       chan->conn->handshake_state->authenticated_ed25519 = 1;
+       memcpy(&chan->conn->handshake_state->authenticated_ed25519_peer_id,
+              checked_ed_id, sizeof(ed25519_public_key_t));
+     }
+ 
+     log_debug(LD_HANDSHAKE, "calling client_learned_peer_id from "
+               "process_certs_cell");
+ 
+     if (connection_or_client_learned_peer_id(chan->conn,
+                   chan->conn->handshake_state->authenticated_rsa_peer_id,
+                   checked_ed_id) < 0)
+       ERR("Problem setting or checking peer id");
+ 
+     log_info(LD_HANDSHAKE,
+              "Got some good certificates from %s:%d: Authenticated it with "
+              "RSA%s",
+              safe_str(chan->conn->base_.address), chan->conn->base_.port,
+              checked_ed_id ? " and Ed25519" : "");
+ 
+     if (!public_server_mode(get_options())) {
+       /* If we initiated the connection and we are not a public server, we
+        * aren't planning to authenticate at all.  At this point we know who we
+        * are talking to, so we can just send a netinfo now. */
+       send_netinfo = 1;
+     }
+   } else {
+     /* We can't call it authenticated till we see an AUTHENTICATE cell. */
+     log_info(LD_OR,
+              "Got some good RSA%s certificates from %s:%d. "
+              "Waiting for AUTHENTICATE.",
+              checked_ed_id ? " and Ed25519" : "",
+              safe_str(chan->conn->base_.address),
+              chan->conn->base_.port);
+     /* XXXX check more stuff? */
+   }
+ 
+   chan->conn->handshake_state->received_certs_cell = 1;
+ 
+   if (send_netinfo) {
+     if (connection_or_send_netinfo(chan->conn) < 0) {
+       log_warn(LD_OR, "Couldn't send netinfo cell");
+       connection_or_close_for_error(chan->conn, 0);
+       goto err;
+     }
+   }
+ 
+  err:
+   for (unsigned u = 0; u < ARRAY_LENGTH(x509_certs); ++u) {
+     tor_x509_cert_free(x509_certs[u]);
+   }
+   for (unsigned u = 0; u < ARRAY_LENGTH(ed_certs); ++u) {
+     tor_cert_free(ed_certs[u]);
+   }
+   tor_free(rsa_ed_cc_cert);
+   certs_cell_free(cc);
+ #undef ERR
+ }
+ 
+ /**
+  * Process an AUTH_CHALLENGE cell from a channel_tls_t.
+  *
+  * This function is called to handle an incoming AUTH_CHALLENGE cell on a
+  * channel_tls_t; if we weren't supposed to get one (for example, because we're
+  * not the originator of the channel), or it's ill-formed, or we aren't doing
+  * a v3 handshake, mark the channel.  If the cell is well-formed but we don't
+  * want to authenticate, just drop it.  If the cell is well-formed *and* we
+  * want to authenticate, send an AUTHENTICATE cell and then a NETINFO cell.
+  */
+ STATIC void
+ channel_tls_process_auth_challenge_cell(var_cell_t *cell, channel_tls_t *chan)
+ {
+   int n_types, i, use_type = -1;
+   auth_challenge_cell_t *ac = NULL;
+ 
+   tor_assert(cell);
+   tor_assert(chan);
+   tor_assert(chan->conn);
+ 
+ #define ERR(s)                                                  \
+   do {                                                          \
+     log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL,                      \
+            "Received a bad AUTH_CHALLENGE cell from %s:%d: %s", \
+            safe_str(chan->conn->base_.address),                 \
+            chan->conn->base_.port, (s));                        \
+     connection_or_close_for_error(chan->conn, 0);               \
+     goto done;                                                  \
+   } while (0)
+ 
+   if (chan->conn->base_.state != OR_CONN_STATE_OR_HANDSHAKING_V3)
+     ERR("We're not currently doing a v3 handshake");
+   if (chan->conn->link_proto < 3)
+     ERR("We're not using link protocol >= 3");
+   if (!(chan->conn->handshake_state->started_here))
+     ERR("We didn't originate this connection");
+   if (chan->conn->handshake_state->received_auth_challenge)
+     ERR("We already received one");
+   if (!(chan->conn->handshake_state->received_certs_cell))
+     ERR("We haven't gotten a CERTS cell yet");
+   if (cell->circ_id)
+     ERR("It had a nonzero circuit ID");
+ 
+   if (auth_challenge_cell_parse(&ac, cell->payload, cell->payload_len) < 0)
+     ERR("It was not well-formed.");
+ 
+   n_types = ac->n_methods;
+ 
+   /* Now see if there is an authentication type we can use */
+   for (i = 0; i < n_types; ++i) {
+     uint16_t authtype = auth_challenge_cell_get_methods(ac, i);
+     if (authchallenge_type_is_supported(authtype)) {
+       if (use_type == -1 ||
+           authchallenge_type_is_better(authtype, use_type)) {
+         use_type = authtype;
+       }
+     }
+   }
+ 
+   chan->conn->handshake_state->received_auth_challenge = 1;
+ 
+   if (! public_server_mode(get_options())) {
+     /* If we're not a public server then we don't want to authenticate on a
+        connection we originated, and we already sent a NETINFO cell when we
+        got the CERTS cell. We have nothing more to do. */
+     goto done;
+   }
+ 
+   if (use_type >= 0) {
+     log_info(LD_OR,
+              "Got an AUTH_CHALLENGE cell from %s:%d: Sending "
+              "authentication type %d",
+              safe_str(chan->conn->base_.address),
+              chan->conn->base_.port,
+              use_type);
+ 
+     if (connection_or_send_authenticate_cell(chan->conn, use_type) < 0) {
+       log_warn(LD_OR,
+                "Couldn't send authenticate cell");
+       connection_or_close_for_error(chan->conn, 0);
+       goto done;
+     }
+   } else {
+     log_info(LD_OR,
+              "Got an AUTH_CHALLENGE cell from %s:%d, but we don't "
+              "know any of its authentication types. Not authenticating.",
+              safe_str(chan->conn->base_.address),
+              chan->conn->base_.port);
+   }
+ 
+   if (connection_or_send_netinfo(chan->conn) < 0) {
+     log_warn(LD_OR, "Couldn't send netinfo cell");
+     connection_or_close_for_error(chan->conn, 0);
+     goto done;
+   }
+ 
+  done:
+   auth_challenge_cell_free(ac);
+ 
+ #undef ERR
+ }
+ 
+ /**
+  * Process an AUTHENTICATE cell from a channel_tls_t.
+  *
+  * If it's ill-formed or we weren't supposed to get one or we're not doing a
+  * v3 handshake, then mark the connection.  If it does not authenticate the
+  * other side of the connection successfully (because it isn't signed right,
+  * we didn't get a CERTS cell, etc) mark the connection.  Otherwise, accept
+  * the identity of the router on the other side of the connection.
+  */
+ STATIC void
+ channel_tls_process_authenticate_cell(var_cell_t *cell, channel_tls_t *chan)
+ {
+   var_cell_t *expected_cell = NULL;
+   const uint8_t *auth;
+   int authlen;
+   int authtype;
+   int bodylen;
+ 
+   tor_assert(cell);
+   tor_assert(chan);
+   tor_assert(chan->conn);
+ 
+ #define ERR(s)                                                  \
+   do {                                                          \
+     log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL,                      \
+            "Received a bad AUTHENTICATE cell from %s:%d: %s",   \
+            safe_str(chan->conn->base_.address),                 \
+            chan->conn->base_.port, (s));                        \
+     connection_or_close_for_error(chan->conn, 0);               \
+     var_cell_free(expected_cell);                               \
+     return;                                                     \
+   } while (0)
+ 
+   if (chan->conn->base_.state != OR_CONN_STATE_OR_HANDSHAKING_V3)
+     ERR("We're not doing a v3 handshake");
+   if (chan->conn->link_proto < 3)
+     ERR("We're not using link protocol >= 3");
+   if (chan->conn->handshake_state->started_here)
+     ERR("We originated this connection");
+   if (chan->conn->handshake_state->received_authenticate)
+     ERR("We already got one!");
+   if (chan->conn->handshake_state->authenticated) {
+     /* Should be impossible given other checks */
+     ERR("The peer is already authenticated");
+   }
+   if (!(chan->conn->handshake_state->received_certs_cell))
+     ERR("We never got a certs cell");
+   if (chan->conn->handshake_state->certs->id_cert == NULL)
+     ERR("We never got an identity certificate");
+   if (cell->payload_len < 4)
+     ERR("Cell was way too short");
+ 
+   auth = cell->payload;
+   {
+     uint16_t type = ntohs(get_uint16(auth));
+     uint16_t len = ntohs(get_uint16(auth+2));
+     if (4 + len > cell->payload_len)
+       ERR("Authenticator was truncated");
+ 
+     if (! authchallenge_type_is_supported(type))
+       ERR("Authenticator type was not recognized");
+     authtype = type;
+ 
+     auth += 4;
+     authlen = len;
+   }
+ 
+   if (authlen < V3_AUTH_BODY_LEN + 1)
+     ERR("Authenticator was too short");
+ 
+   expected_cell = connection_or_compute_authenticate_cell_body(
+                 chan->conn, authtype, NULL, NULL, 1);
+   if (! expected_cell)
+     ERR("Couldn't compute expected AUTHENTICATE cell body");
+ 
+   int sig_is_rsa;
+   if (authtype == AUTHTYPE_RSA_SHA256_TLSSECRET ||
+       authtype == AUTHTYPE_RSA_SHA256_RFC5705) {
+     bodylen = V3_AUTH_BODY_LEN;
+     sig_is_rsa = 1;
+   } else {
+     tor_assert(authtype == AUTHTYPE_ED25519_SHA256_RFC5705);
+     /* Our earlier check had better have made sure we had room
+      * for an ed25519 sig (inadvertently) */
+     tor_assert(V3_AUTH_BODY_LEN > ED25519_SIG_LEN);
+     bodylen = authlen - ED25519_SIG_LEN;
+     sig_is_rsa = 0;
+   }
+   if (expected_cell->payload_len != bodylen+4) {
+     ERR("Expected AUTHENTICATE cell body len not as expected.");
+   }
+ 
+   /* Length of random part. */
+   if (BUG(bodylen < 24)) {
+     // LCOV_EXCL_START
+     ERR("Bodylen is somehow less than 24, which should really be impossible");
+     // LCOV_EXCL_STOP
+   }
+ 
+   if (tor_memneq(expected_cell->payload+4, auth, bodylen-24))
+     ERR("Some field in the AUTHENTICATE cell body was not as expected");
+ 
+   if (sig_is_rsa) {
+     if (chan->conn->handshake_state->certs->ed_id_sign != NULL)
+       ERR("RSA-signed AUTHENTICATE response provided with an ED25519 cert");
+ 
+     if (chan->conn->handshake_state->certs->auth_cert == NULL)
+       ERR("We never got an RSA authentication certificate");
+ 
+     crypto_pk_t *pk = tor_tls_cert_get_key(
+                              chan->conn->handshake_state->certs->auth_cert);
+     char d[DIGEST256_LEN];
+     char *signed_data;
+     size_t keysize;
+     int signed_len;
+ 
+     if (! pk) {
+       ERR("Couldn't get RSA key from AUTH cert.");
+     }
+     crypto_digest256(d, (char*)auth, V3_AUTH_BODY_LEN, DIGEST_SHA256);
+ 
+     keysize = crypto_pk_keysize(pk);
+     signed_data = tor_malloc(keysize);
+     signed_len = crypto_pk_public_checksig(pk, signed_data, keysize,
+                                            (char*)auth + V3_AUTH_BODY_LEN,
+                                            authlen - V3_AUTH_BODY_LEN);
+     crypto_pk_free(pk);
+     if (signed_len < 0) {
+       tor_free(signed_data);
+       ERR("RSA signature wasn't valid");
+     }
+     if (signed_len < DIGEST256_LEN) {
+       tor_free(signed_data);
+       ERR("Not enough data was signed");
+     }
+     /* Note that we deliberately allow *more* than DIGEST256_LEN bytes here,
+      * in case they're later used to hold a SHA3 digest or something. */
+     if (tor_memneq(signed_data, d, DIGEST256_LEN)) {
+       tor_free(signed_data);
+       ERR("Signature did not match data to be signed.");
+     }
+     tor_free(signed_data);
+   } else {
+     if (chan->conn->handshake_state->certs->ed_id_sign == NULL)
+       ERR("We never got an Ed25519 identity certificate.");
+     if (chan->conn->handshake_state->certs->ed_sign_auth == NULL)
+       ERR("We never got an Ed25519 authentication certificate.");
+ 
+     const ed25519_public_key_t *authkey =
+       &chan->conn->handshake_state->certs->ed_sign_auth->signed_key;
+     ed25519_signature_t sig;
+     tor_assert(authlen > ED25519_SIG_LEN);
+     memcpy(&sig.sig, auth + authlen - ED25519_SIG_LEN, ED25519_SIG_LEN);
+     if (ed25519_checksig(&sig, auth, authlen - ED25519_SIG_LEN, authkey)<0) {
+       ERR("Ed25519 signature wasn't valid.");
+     }
+   }
+ 
+   /* Okay, we are authenticated. */
+   chan->conn->handshake_state->received_authenticate = 1;
+   chan->conn->handshake_state->authenticated = 1;
+   chan->conn->handshake_state->authenticated_rsa = 1;
+   chan->conn->handshake_state->digest_received_data = 0;
+   {
+     tor_x509_cert_t *id_cert = chan->conn->handshake_state->certs->id_cert;
+     crypto_pk_t *identity_rcvd = tor_tls_cert_get_key(id_cert);
+     const common_digests_t *id_digests = tor_x509_cert_get_id_digests(id_cert);
+     const ed25519_public_key_t *ed_identity_received = NULL;
+ 
+     if (! sig_is_rsa) {
+       chan->conn->handshake_state->authenticated_ed25519 = 1;
+       ed_identity_received =
+         &chan->conn->handshake_state->certs->ed_id_sign->signing_key;
+       memcpy(&chan->conn->handshake_state->authenticated_ed25519_peer_id,
+              ed_identity_received, sizeof(ed25519_public_key_t));
+     }
+ 
+     /* This must exist; we checked key type when reading the cert. */
+     tor_assert(id_digests);
+ 
+     memcpy(chan->conn->handshake_state->authenticated_rsa_peer_id,
+            id_digests->d[DIGEST_SHA1], DIGEST_LEN);
+ 
+     channel_set_circid_type(TLS_CHAN_TO_BASE(chan), identity_rcvd,
+                chan->conn->link_proto < MIN_LINK_PROTO_FOR_WIDE_CIRC_IDS);
+     crypto_pk_free(identity_rcvd);
+ 
+     log_debug(LD_HANDSHAKE,
+               "Calling connection_or_init_conn_from_address for %s "
+               " from %s, with%s ed25519 id.",
+               safe_str(chan->conn->base_.address),
+               __func__,
+               ed_identity_received ? "" : "out");
+ 
+     connection_or_init_conn_from_address(chan->conn,
+                   &(chan->conn->base_.addr),
+                   chan->conn->base_.port,
+                   (const char*)(chan->conn->handshake_state->
+                     authenticated_rsa_peer_id),
+                   ed_identity_received,
+                   0);
+ 
+     log_debug(LD_HANDSHAKE,
+              "Got an AUTHENTICATE cell from %s:%d, type %d: Looks good.",
+              safe_str(chan->conn->base_.address),
+              chan->conn->base_.port,
+              authtype);
+   }
+ 
+   var_cell_free(expected_cell);
+ 
+ #undef ERR
+ }





More information about the tor-commits mailing list