LCOV - code coverage report
Current view: top level - core/or - connection_edge.c (source / functions) Hit Total Coverage
Test: lcov.info Lines: 492 1905 25.8 %
Date: 2021-11-24 03:28:48 Functions: 40 85 47.1 %

          Line data    Source code
       1             : /* Copyright (c) 2001 Matej Pfajfar.
       2             :  * Copyright (c) 2001-2004, Roger Dingledine.
       3             :  * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
       4             :  * Copyright (c) 2007-2021, The Tor Project, Inc. */
       5             : /* See LICENSE for licensing information */
       6             : 
       7             : /**
       8             :  * \file connection_edge.c
       9             :  * \brief Handle edge streams.
      10             :  *
      11             :  * An edge_connection_t is a subtype of a connection_t, and represents two
      12             :  * critical concepts in Tor: a stream, and an edge connection.  From the Tor
      13             :  * protocol's point of view, a stream is a bi-directional channel that is
      14             :  * multiplexed on a single circuit.  Each stream on a circuit is identified
      15             :  * with a separate 16-bit stream ID, local to the (circuit,exit) pair.
      16             :  * Streams are created in response to client requests.
      17             :  *
      18             :  * An edge connection is one thing that can implement a stream: it is either a
      19             :  * TCP application socket that has arrived via (e.g.) a SOCKS request, or an
      20             :  * exit connection.
      21             :  *
      22             :  * Not every instance of edge_connection_t truly represents an edge connection,
      23             :  * however. (Sorry!) We also create edge_connection_t objects for streams that
      24             :  * we will not be handling with TCP.  The types of these streams are:
      25             :  *   <ul>
      26             :  *   <li>DNS lookup streams, created on the client side in response to
      27             :  *     a UDP DNS request received on a DNSPort, or a RESOLVE command
      28             :  *     on a controller.
      29             :  *   <li>DNS lookup streams, created on the exit side in response to
      30             :  *     a RELAY_RESOLVE cell from a client.
      31             :  *   <li>Tunneled directory streams, created on the directory cache side
      32             :  *     in response to a RELAY_BEGIN_DIR cell.  These streams attach directly
      33             :  *     to a dir_connection_t object without ever using TCP.
      34             :  *   </ul>
      35             :  *
      36             :  * This module handles general-purpose functionality having to do with
      37             :  * edge_connection_t.  On the client side, it accepts various types of
      38             :  * application requests on SocksPorts, TransPorts, and NATDPorts, and
      39             :  * creates streams appropriately.
      40             :  *
      41             :  * This module is also responsible for implementing stream isolation:
      42             :  * ensuring that streams that should not be linkable to one another are
      43             :  * kept to different circuits.
      44             :  *
      45             :  * On the exit side, this module handles the various stream-creating
      46             :  * type of RELAY cells by launching appropriate outgoing connections,
      47             :  * DNS requests, or directory connection objects.
      48             :  *
      49             :  * And for all edge connections, this module is responsible for handling
      50             :  * incoming and outdoing data as it arrives or leaves in the relay.c
      51             :  * module.  (Outgoing data will be packaged in
      52             :  * connection_edge_process_inbuf() as it calls
      53             :  * connection_edge_package_raw_inbuf(); incoming data from RELAY_DATA
      54             :  * cells is applied in connection_edge_process_relay_cell().)
      55             :  **/
      56             : #define CONNECTION_EDGE_PRIVATE
      57             : 
      58             : #include "core/or/or.h"
      59             : 
      60             : #include "lib/err/backtrace.h"
      61             : 
      62             : #include "app/config/config.h"
      63             : #include "core/mainloop/connection.h"
      64             : #include "core/mainloop/mainloop.h"
      65             : #include "core/mainloop/netstatus.h"
      66             : #include "core/or/channel.h"
      67             : #include "core/or/circuitbuild.h"
      68             : #include "core/or/circuitlist.h"
      69             : #include "core/or/circuituse.h"
      70             : #include "core/or/circuitpadding.h"
      71             : #include "core/or/connection_edge.h"
      72             : #include "core/or/connection_or.h"
      73             : #include "core/or/extendinfo.h"
      74             : #include "core/or/policies.h"
      75             : #include "core/or/reasons.h"
      76             : #include "core/or/relay.h"
      77             : #include "core/or/sendme.h"
      78             : #include "core/proto/proto_http.h"
      79             : #include "core/proto/proto_socks.h"
      80             : #include "feature/client/addressmap.h"
      81             : #include "feature/client/circpathbias.h"
      82             : #include "feature/client/dnsserv.h"
      83             : #include "feature/control/control_events.h"
      84             : #include "feature/dircache/dirserv.h"
      85             : #include "feature/dircommon/directory.h"
      86             : #include "feature/hibernate/hibernate.h"
      87             : #include "feature/hs/hs_cache.h"
      88             : #include "feature/hs/hs_circuit.h"
      89             : #include "feature/hs/hs_client.h"
      90             : #include "feature/hs/hs_common.h"
      91             : #include "feature/nodelist/describe.h"
      92             : #include "feature/nodelist/networkstatus.h"
      93             : #include "feature/nodelist/nodelist.h"
      94             : #include "feature/nodelist/routerlist.h"
      95             : #include "feature/nodelist/routerset.h"
      96             : #include "feature/relay/dns.h"
      97             : #include "feature/relay/router.h"
      98             : #include "feature/relay/routermode.h"
      99             : #include "feature/rend/rendcommon.h"
     100             : #include "feature/stats/predict_ports.h"
     101             : #include "feature/stats/rephist.h"
     102             : #include "lib/buf/buffers.h"
     103             : #include "lib/crypt_ops/crypto_util.h"
     104             : 
     105             : #include "core/or/cell_st.h"
     106             : #include "core/or/cpath_build_state_st.h"
     107             : #include "feature/dircommon/dir_connection_st.h"
     108             : #include "core/or/entry_connection_st.h"
     109             : #include "core/or/extend_info_st.h"
     110             : #include "feature/nodelist/node_st.h"
     111             : #include "core/or/or_circuit_st.h"
     112             : #include "core/or/origin_circuit_st.h"
     113             : #include "core/or/half_edge_st.h"
     114             : #include "core/or/socks_request_st.h"
     115             : #include "lib/evloop/compat_libevent.h"
     116             : 
     117             : #ifdef HAVE_LINUX_TYPES_H
     118             : #include <linux/types.h>
     119             : #endif
     120             : #ifdef HAVE_LINUX_NETFILTER_IPV4_H
     121             : #include <linux/netfilter_ipv4.h>
     122             : #define TRANS_NETFILTER
     123             : #define TRANS_NETFILTER_IPV4
     124             : #endif
     125             : 
     126             : #ifdef HAVE_LINUX_IF_H
     127             : #include <linux/if.h>
     128             : #endif
     129             : 
     130             : #ifdef HAVE_LINUX_NETFILTER_IPV6_IP6_TABLES_H
     131             : #include <linux/netfilter_ipv6/ip6_tables.h>
     132             : #if defined(IP6T_SO_ORIGINAL_DST)
     133             : #define TRANS_NETFILTER
     134             : #define TRANS_NETFILTER_IPV6
     135             : #endif
     136             : #endif /* defined(HAVE_LINUX_NETFILTER_IPV6_IP6_TABLES_H) */
     137             : 
     138             : #ifdef HAVE_FCNTL_H
     139             : #include <fcntl.h>
     140             : #endif
     141             : #ifdef HAVE_SYS_IOCTL_H
     142             : #include <sys/ioctl.h>
     143             : #endif
     144             : #ifdef HAVE_SYS_PARAM_H
     145             : #include <sys/param.h>
     146             : #endif
     147             : 
     148             : #if defined(HAVE_NET_IF_H) && defined(HAVE_NET_PFVAR_H)
     149             : #include <net/if.h>
     150             : #include <net/pfvar.h>
     151             : #define TRANS_PF
     152             : #endif
     153             : 
     154             : #ifdef IP_TRANSPARENT
     155             : #define TRANS_TPROXY
     156             : #endif
     157             : 
     158             : #define SOCKS4_GRANTED          90
     159             : #define SOCKS4_REJECT           91
     160             : 
     161             : static int connection_ap_handshake_process_socks(entry_connection_t *conn);
     162             : static int connection_ap_process_natd(entry_connection_t *conn);
     163             : static int connection_exit_connect_dir(edge_connection_t *exitconn);
     164             : static int consider_plaintext_ports(entry_connection_t *conn, uint16_t port);
     165             : static int connection_ap_supports_optimistic_data(const entry_connection_t *);
     166             : static bool network_reentry_is_allowed(void);
     167             : 
     168             : /**
     169             :  * Cast a `connection_t *` to an `edge_connection_t *`.
     170             :  *
     171             :  * Exit with an assertion failure if the input is not an
     172             :  * `edge_connection_t`.
     173             :  **/
     174             : edge_connection_t *
     175         122 : TO_EDGE_CONN(connection_t *c)
     176             : {
     177         122 :   tor_assert(c->magic == EDGE_CONNECTION_MAGIC ||
     178             :              c->magic == ENTRY_CONNECTION_MAGIC);
     179         122 :   return DOWNCAST(edge_connection_t, c);
     180             : }
     181             : 
     182             : /**
     183             :  * Cast a `const connection_t *` to a `const edge_connection_t *`.
     184             :  *
     185             :  * Exit with an assertion failure if the input is not an
     186             :  * `edge_connection_t`.
     187             :  **/
     188             : const edge_connection_t *
     189           5 : CONST_TO_EDGE_CONN(const connection_t *c)
     190             : {
     191           5 :   return TO_EDGE_CONN((connection_t *)c);
     192             : }
     193             : 
     194             : /**
     195             :  * Cast a `connection_t *` to an `entry_connection_t *`.
     196             :  *
     197             :  * Exit with an assertion failure if the input is not an
     198             :  * `entry_connection_t`.
     199             :  **/
     200             : entry_connection_t *
     201         302 : TO_ENTRY_CONN(connection_t *c)
     202             : {
     203         302 :   tor_assert(c->magic == ENTRY_CONNECTION_MAGIC);
     204         302 :   return (entry_connection_t*) SUBTYPE_P(c, entry_connection_t, edge_.base_);
     205             : }
     206             : 
     207             : /**
     208             :  * Cast a `const connection_t *` to a `const entry_connection_t *`.
     209             :  *
     210             :  * Exit with an assertion failure if the input is not an
     211             :  * `entry_connection_t`.
     212             :  **/
     213             : const entry_connection_t *
     214           0 : CONST_TO_ENTRY_CONN(const connection_t *c)
     215             : {
     216           0 :   return TO_ENTRY_CONN((connection_t*) c);
     217             : }
     218             : 
     219             : /**
     220             :  * Cast an `edge_connection_t *` to an `entry_connection_t *`.
     221             :  *
     222             :  * Exit with an assertion failure if the input is not an
     223             :  * `entry_connection_t`.
     224             :  **/
     225             : entry_connection_t *
     226          32 : EDGE_TO_ENTRY_CONN(edge_connection_t *c)
     227             : {
     228          32 :   tor_assert(c->base_.magic == ENTRY_CONNECTION_MAGIC);
     229          32 :   return (entry_connection_t*) SUBTYPE_P(c, entry_connection_t, edge_);
     230             : }
     231             : 
     232             : /**
     233             :  * Cast a `const edge_connection_t *` to a `const entry_connection_t *`.
     234             :  *
     235             :  * Exit with an assertion failure if the input is not an
     236             :  * `entry_connection_t`.
     237             :  **/
     238             : const entry_connection_t *
     239           0 : CONST_EDGE_TO_ENTRY_CONN(const edge_connection_t *c)
     240             : {
     241           0 :   return EDGE_TO_ENTRY_CONN((edge_connection_t*)c);
     242             : }
     243             : 
     244             : /** An AP stream has failed/finished. If it hasn't already sent back
     245             :  * a socks reply, send one now (based on endreason). Also set
     246             :  * has_sent_end to 1, and mark the conn.
     247             :  */
     248           0 : MOCK_IMPL(void,
     249             : connection_mark_unattached_ap_,(entry_connection_t *conn, int endreason,
     250             :                                 int line, const char *file))
     251             : {
     252           0 :   connection_t *base_conn = ENTRY_TO_CONN(conn);
     253           0 :   tor_assert(base_conn->type == CONN_TYPE_AP);
     254           0 :   ENTRY_TO_EDGE_CONN(conn)->edge_has_sent_end = 1; /* no circ yet */
     255             : 
     256           0 :   if (base_conn->marked_for_close) {
     257             :     /* This call will warn as appropriate. */
     258           0 :     connection_mark_for_close_(base_conn, line, file);
     259           0 :     return;
     260             :   }
     261             : 
     262           0 :   if (!conn->socks_request->has_finished) {
     263           0 :     if (endreason & END_STREAM_REASON_FLAG_ALREADY_SOCKS_REPLIED)
     264           0 :       log_warn(LD_BUG,
     265             :                "stream (marked at %s:%d) sending two socks replies?",
     266             :                file, line);
     267             : 
     268           0 :     if (SOCKS_COMMAND_IS_CONNECT(conn->socks_request->command))
     269           0 :       connection_ap_handshake_socks_reply(conn, NULL, 0, endreason);
     270           0 :     else if (SOCKS_COMMAND_IS_RESOLVE(conn->socks_request->command))
     271           0 :       connection_ap_handshake_socks_resolved(conn,
     272             :                                              RESOLVED_TYPE_ERROR_TRANSIENT,
     273             :                                              0, NULL, -1, -1);
     274             :     else /* unknown or no handshake at all. send no response. */
     275           0 :       conn->socks_request->has_finished = 1;
     276             :   }
     277             : 
     278           0 :   connection_mark_and_flush_(base_conn, line, file);
     279             : 
     280           0 :   ENTRY_TO_EDGE_CONN(conn)->end_reason = endreason;
     281             : }
     282             : 
     283             : /** There was an EOF. Send an end and mark the connection for close.
     284             :  */
     285             : int
     286           7 : connection_edge_reached_eof(edge_connection_t *conn)
     287             : {
     288           7 :   if (connection_get_inbuf_len(TO_CONN(conn)) &&
     289           0 :       connection_state_is_open(TO_CONN(conn))) {
     290             :     /* it still has stuff to process. don't let it die yet. */
     291             :     return 0;
     292             :   }
     293           7 :   log_info(LD_EDGE,"conn (fd "TOR_SOCKET_T_FORMAT") reached eof. Closing.",
     294             :            conn->base_.s);
     295           7 :   if (!conn->base_.marked_for_close) {
     296             :     /* only mark it if not already marked. it's possible to
     297             :      * get the 'end' right around when the client hangs up on us. */
     298           7 :     connection_edge_end(conn, END_STREAM_REASON_DONE);
     299           7 :     if (conn->base_.type == CONN_TYPE_AP) {
     300             :       /* eof, so don't send a socks reply back */
     301           7 :       if (EDGE_TO_ENTRY_CONN(conn)->socks_request)
     302           7 :         EDGE_TO_ENTRY_CONN(conn)->socks_request->has_finished = 1;
     303             :     }
     304           7 :     connection_mark_for_close(TO_CONN(conn));
     305             :   }
     306             :   return 0;
     307             : }
     308             : 
     309             : /** Handle new bytes on conn->inbuf based on state:
     310             :  *   - If it's waiting for socks info, try to read another step of the
     311             :  *     socks handshake out of conn->inbuf.
     312             :  *   - If it's waiting for the original destination, fetch it.
     313             :  *   - If it's open, then package more relay cells from the stream.
     314             :  *   - Else, leave the bytes on inbuf alone for now.
     315             :  *
     316             :  * Mark and return -1 if there was an unexpected error with the conn,
     317             :  * else return 0.
     318             :  */
     319             : int
     320           0 : connection_edge_process_inbuf(edge_connection_t *conn, int package_partial)
     321             : {
     322           0 :   tor_assert(conn);
     323             : 
     324           0 :   switch (conn->base_.state) {
     325           0 :     case AP_CONN_STATE_SOCKS_WAIT:
     326           0 :       if (connection_ap_handshake_process_socks(EDGE_TO_ENTRY_CONN(conn)) <0) {
     327             :         /* already marked */
     328           0 :         return -1;
     329             :       }
     330             :       return 0;
     331           0 :     case AP_CONN_STATE_NATD_WAIT:
     332           0 :       if (connection_ap_process_natd(EDGE_TO_ENTRY_CONN(conn)) < 0) {
     333             :         /* already marked */
     334           0 :         return -1;
     335             :       }
     336             :       return 0;
     337           0 :     case AP_CONN_STATE_HTTP_CONNECT_WAIT:
     338           0 :       if (connection_ap_process_http_connect(EDGE_TO_ENTRY_CONN(conn)) < 0) {
     339           0 :         return -1;
     340             :       }
     341             :       return 0;
     342           0 :     case AP_CONN_STATE_OPEN:
     343           0 :       if (! conn->base_.linked) {
     344           0 :         note_user_activity(approx_time());
     345             :       }
     346             : 
     347           0 :       FALLTHROUGH;
     348             :     case EXIT_CONN_STATE_OPEN:
     349           0 :       if (connection_edge_package_raw_inbuf(conn, package_partial, NULL) < 0) {
     350             :         /* (We already sent an end cell if possible) */
     351           0 :         connection_mark_for_close(TO_CONN(conn));
     352           0 :         return -1;
     353             :       }
     354             :       return 0;
     355           0 :     case AP_CONN_STATE_CONNECT_WAIT:
     356           0 :       if (connection_ap_supports_optimistic_data(EDGE_TO_ENTRY_CONN(conn))) {
     357           0 :         log_info(LD_EDGE,
     358             :                  "data from edge while in '%s' state. Sending it anyway. "
     359             :                  "package_partial=%d, buflen=%ld",
     360             :                  conn_state_to_string(conn->base_.type, conn->base_.state),
     361             :                  package_partial,
     362             :                  (long)connection_get_inbuf_len(TO_CONN(conn)));
     363           0 :         if (connection_edge_package_raw_inbuf(conn, package_partial, NULL)<0) {
     364             :           /* (We already sent an end cell if possible) */
     365           0 :           connection_mark_for_close(TO_CONN(conn));
     366           0 :           return -1;
     367             :         }
     368             :         return 0;
     369             :       }
     370             :       /* Fall through if the connection is on a circuit without optimistic
     371             :        * data support. */
     372           0 :       FALLTHROUGH;
     373             :     case EXIT_CONN_STATE_CONNECTING:
     374             :     case AP_CONN_STATE_RENDDESC_WAIT:
     375             :     case AP_CONN_STATE_CIRCUIT_WAIT:
     376             :     case AP_CONN_STATE_RESOLVE_WAIT:
     377             :     case AP_CONN_STATE_CONTROLLER_WAIT:
     378           0 :       log_info(LD_EDGE,
     379             :                "data from edge while in '%s' state. Leaving it on buffer.",
     380             :                conn_state_to_string(conn->base_.type, conn->base_.state));
     381           0 :       return 0;
     382             :   }
     383           0 :   log_warn(LD_BUG,"Got unexpected state %d. Closing.",conn->base_.state);
     384           0 :   tor_fragile_assert();
     385           0 :   connection_edge_end(conn, END_STREAM_REASON_INTERNAL);
     386           0 :   connection_mark_for_close(TO_CONN(conn));
     387           0 :   return -1;
     388             : }
     389             : 
     390             : /** This edge needs to be closed, because its circuit has closed.
     391             :  * Mark it for close and return 0.
     392             :  */
     393             : int
     394           0 : connection_edge_destroy(circid_t circ_id, edge_connection_t *conn)
     395             : {
     396           0 :   if (!conn->base_.marked_for_close) {
     397           0 :     log_info(LD_EDGE, "CircID %u: At an edge. Marking connection for close.",
     398             :              (unsigned) circ_id);
     399           0 :     if (conn->base_.type == CONN_TYPE_AP) {
     400           0 :       entry_connection_t *entry_conn = EDGE_TO_ENTRY_CONN(conn);
     401           0 :       connection_mark_unattached_ap(entry_conn, END_STREAM_REASON_DESTROY);
     402           0 :       control_event_stream_bandwidth(conn);
     403           0 :       control_event_stream_status(entry_conn, STREAM_EVENT_CLOSED,
     404             :                                   END_STREAM_REASON_DESTROY);
     405           0 :       conn->end_reason |= END_STREAM_REASON_FLAG_ALREADY_SENT_CLOSED;
     406             :     } else {
     407             :       /* closing the circuit, nothing to send an END to */
     408           0 :       conn->edge_has_sent_end = 1;
     409           0 :       conn->end_reason = END_STREAM_REASON_DESTROY;
     410           0 :       conn->end_reason |= END_STREAM_REASON_FLAG_ALREADY_SENT_CLOSED;
     411           0 :       connection_mark_and_flush(TO_CONN(conn));
     412             :     }
     413             :   }
     414           0 :   conn->cpath_layer = NULL;
     415           0 :   conn->on_circuit = NULL;
     416           0 :   return 0;
     417             : }
     418             : 
     419             : /** Send a raw end cell to the stream with ID <b>stream_id</b> out over the
     420             :  * <b>circ</b> towards the hop identified with <b>cpath_layer</b>. If this
     421             :  * is not a client connection, set the relay end cell's reason for closing
     422             :  * as <b>reason</b> */
     423             : static int
     424           0 : relay_send_end_cell_from_edge(streamid_t stream_id, circuit_t *circ,
     425             :                               uint8_t reason, crypt_path_t *cpath_layer)
     426             : {
     427           0 :   char payload[1];
     428             : 
     429           0 :   if (CIRCUIT_PURPOSE_IS_CLIENT(circ->purpose)) {
     430             :     /* Never send the server an informative reason code; it doesn't need to
     431             :      * know why the client stream is failing. */
     432           0 :     reason = END_STREAM_REASON_MISC;
     433             :   }
     434             : 
     435           0 :   payload[0] = (char) reason;
     436             : 
     437             :   /* Note: we have to use relay_send_command_from_edge here, not
     438             :    * connection_edge_end or connection_edge_send_command, since those require
     439             :    * that we have a stream connected to a circuit, and we don't connect to a
     440             :    * circuit until we have a pending/successful resolve. */
     441           0 :   return relay_send_command_from_edge(stream_id, circ, RELAY_COMMAND_END,
     442             :                                       payload, 1, cpath_layer);
     443             : }
     444             : 
     445             : /* If the connection <b>conn</b> is attempting to connect to an external
     446             :  * destination that is an hidden service and the reason is a connection
     447             :  * refused or timeout, log it so the operator can take appropriate actions.
     448             :  * The log statement is a rate limited warning. */
     449             : static void
     450           7 : warn_if_hs_unreachable(const edge_connection_t *conn, uint8_t reason)
     451             : {
     452           7 :   tor_assert(conn);
     453             : 
     454           7 :   if (conn->base_.type == CONN_TYPE_EXIT &&
     455           0 :       connection_edge_is_rendezvous_stream(conn) &&
     456           0 :       (reason == END_STREAM_REASON_CONNECTREFUSED ||
     457           0 :        reason == END_STREAM_REASON_TIMEOUT)) {
     458             : #define WARN_FAILED_HS_CONNECTION 300
     459           0 :     static ratelim_t warn_limit = RATELIM_INIT(WARN_FAILED_HS_CONNECTION);
     460           0 :     char *m;
     461           0 :     if ((m = rate_limit_log(&warn_limit, approx_time()))) {
     462           0 :       log_warn(LD_EDGE, "Onion service connection to %s failed (%s)",
     463             :                connection_describe_peer(TO_CONN(conn)),
     464             :                stream_end_reason_to_string(reason));
     465           0 :       tor_free(m);
     466             :     }
     467             :   }
     468           7 : }
     469             : 
     470             : /** Given a TTL (in seconds) from a DNS response or from a relay, determine
     471             :  * what TTL clients and relays should actually use for caching it. */
     472             : uint32_t
     473           6 : clip_dns_ttl(uint32_t ttl)
     474             : {
     475             :   /* This logic is a defense against "DefectTor" DNS-based traffic
     476             :    * confirmation attacks, as in https://nymity.ch/tor-dns/tor-dns.pdf .
     477             :    * We only give two values: a "low" value and a "high" value.
     478             :    */
     479           6 :   if (ttl < MIN_DNS_TTL)
     480             :     return MIN_DNS_TTL;
     481             :   else
     482           5 :     return MAX_DNS_TTL;
     483             : }
     484             : 
     485             : /** Send a relay end cell from stream <b>conn</b> down conn's circuit, and
     486             :  * remember that we've done so.  If this is not a client connection, set the
     487             :  * relay end cell's reason for closing as <b>reason</b>.
     488             :  *
     489             :  * Return -1 if this function has already been called on this conn,
     490             :  * else return 0.
     491             :  */
     492             : int
     493           7 : connection_edge_end(edge_connection_t *conn, uint8_t reason)
     494             : {
     495           7 :   char payload[RELAY_PAYLOAD_SIZE];
     496           7 :   size_t payload_len=1;
     497           7 :   circuit_t *circ;
     498           7 :   uint8_t control_reason = reason;
     499             : 
     500           7 :   if (conn->edge_has_sent_end) {
     501           0 :     log_warn(LD_BUG,"(Harmless.) Calling connection_edge_end (reason %d) "
     502             :              "on an already ended stream?", reason);
     503           0 :     tor_fragile_assert();
     504           0 :     return -1;
     505             :   }
     506             : 
     507           7 :   if (conn->base_.marked_for_close) {
     508           0 :     log_warn(LD_BUG,
     509             :              "called on conn that's already marked for close at %s:%d.",
     510             :              conn->base_.marked_for_close_file, conn->base_.marked_for_close);
     511           0 :     return 0;
     512             :   }
     513             : 
     514           7 :   circ = circuit_get_by_edge_conn(conn);
     515           7 :   if (circ && CIRCUIT_PURPOSE_IS_CLIENT(circ->purpose)) {
     516             :     /* If this is a client circuit, don't send the server an informative
     517             :      * reason code; it doesn't need to know why the client stream is
     518             :      * failing. */
     519           4 :     reason = END_STREAM_REASON_MISC;
     520             :   }
     521             : 
     522           7 :   payload[0] = (char)reason;
     523           7 :   if (reason == END_STREAM_REASON_EXITPOLICY &&
     524           0 :       !connection_edge_is_rendezvous_stream(conn)) {
     525           0 :     int addrlen;
     526           0 :     if (tor_addr_family(&conn->base_.addr) == AF_INET) {
     527           0 :       set_uint32(payload+1, tor_addr_to_ipv4n(&conn->base_.addr));
     528           0 :       addrlen = 4;
     529             :     } else {
     530           0 :       memcpy(payload+1, tor_addr_to_in6_addr8(&conn->base_.addr), 16);
     531           0 :       addrlen = 16;
     532             :     }
     533           0 :     set_uint32(payload+1+addrlen, htonl(clip_dns_ttl(conn->address_ttl)));
     534           0 :     payload_len += 4+addrlen;
     535             :   }
     536             : 
     537           7 :   if (circ && !circ->marked_for_close) {
     538           7 :     log_debug(LD_EDGE,"Sending end on conn (fd "TOR_SOCKET_T_FORMAT").",
     539             :               conn->base_.s);
     540             : 
     541           7 :     if (CIRCUIT_IS_ORIGIN(circ)) {
     542           7 :       origin_circuit_t *origin_circ = TO_ORIGIN_CIRCUIT(circ);
     543           7 :       connection_half_edge_add(conn, origin_circ);
     544             :     }
     545             : 
     546           7 :     connection_edge_send_command(conn, RELAY_COMMAND_END,
     547             :                                  payload, payload_len);
     548             :     /* We'll log warn if the connection was an hidden service and couldn't be
     549             :      * made because the service wasn't available. */
     550           7 :     warn_if_hs_unreachable(conn, control_reason);
     551             :   } else {
     552           0 :     log_debug(LD_EDGE,"No circ to send end on conn "
     553             :               "(fd "TOR_SOCKET_T_FORMAT").",
     554             :               conn->base_.s);
     555             :   }
     556             : 
     557           7 :   conn->edge_has_sent_end = 1;
     558           7 :   conn->end_reason = control_reason;
     559           7 :   return 0;
     560             : }
     561             : 
     562             : /**
     563             :  * Helper function for bsearch.
     564             :  *
     565             :  * As per smartlist_bsearch, return < 0 if key precedes member,
     566             :  * > 0 if member precedes key, and 0 if they are equal.
     567             :  *
     568             :  * This is equivalent to subtraction of the values of key - member
     569             :  * (why does no one ever say that explicitly?).
     570             :  */
     571             : static int
     572     6111899 : connection_half_edge_compare_bsearch(const void *key, const void **member)
     573             : {
     574     6111899 :   const half_edge_t *e2;
     575     6111899 :   tor_assert(key);
     576     6111899 :   tor_assert(member && *(half_edge_t**)member);
     577     6111899 :   e2 = *(const half_edge_t **)member;
     578             : 
     579     6111899 :   return *(const streamid_t*)key - e2->stream_id;
     580             : }
     581             : 
     582             : /** Total number of half_edge_t objects allocated */
     583             : static size_t n_half_conns_allocated = 0;
     584             : 
     585             : /**
     586             :  * Add a half-closed connection to the list, to watch for activity.
     587             :  *
     588             :  * These connections are removed from the list upon receiving an end
     589             :  * cell.
     590             :  */
     591             : STATIC void
     592       66690 : connection_half_edge_add(const edge_connection_t *conn,
     593             :                          origin_circuit_t *circ)
     594             : {
     595       66690 :   half_edge_t *half_conn = NULL;
     596       66690 :   int insert_at = 0;
     597       66690 :   int ignored;
     598             : 
     599             :   /* Double-check for re-insertion. This should not happen,
     600             :    * but this check is cheap compared to the sort anyway */
     601       66690 :   if (connection_half_edge_find_stream_id(circ->half_streams,
     602       66690 :                                           conn->stream_id)) {
     603           6 :     log_warn(LD_BUG, "Duplicate stream close for stream %d on circuit %d",
     604             :              conn->stream_id, circ->global_identifier);
     605           6 :     return;
     606             :   }
     607             : 
     608       66684 :   half_conn = tor_malloc_zero(sizeof(half_edge_t));
     609       66684 :   ++n_half_conns_allocated;
     610             : 
     611       66684 :   if (!circ->half_streams) {
     612           5 :     circ->half_streams = smartlist_new();
     613             :   }
     614             : 
     615       66684 :   half_conn->stream_id = conn->stream_id;
     616             : 
     617             :   // How many sendme's should I expect?
     618       66684 :   half_conn->sendmes_pending =
     619       66684 :    (STREAMWINDOW_START-conn->package_window)/STREAMWINDOW_INCREMENT;
     620             : 
     621             :    // Is there a connected cell pending?
     622       66684 :   half_conn->connected_pending = conn->base_.state ==
     623             :       AP_CONN_STATE_CONNECT_WAIT;
     624             : 
     625             :   /* Data should only arrive if we're not waiting on a resolved cell.
     626             :    * It can arrive after waiting on connected, because of optimistic
     627             :    * data. */
     628       66684 :   if (conn->base_.state != AP_CONN_STATE_RESOLVE_WAIT) {
     629             :     // How many more data cells can arrive on this id?
     630       66682 :     half_conn->data_pending = conn->deliver_window;
     631             :   }
     632             : 
     633       66684 :   insert_at = smartlist_bsearch_idx(circ->half_streams, &half_conn->stream_id,
     634             :                                     connection_half_edge_compare_bsearch,
     635             :                                     &ignored);
     636       66684 :   smartlist_insert(circ->half_streams, insert_at, half_conn);
     637             : }
     638             : 
     639             : /** Release space held by <b>he</b> */
     640             : void
     641       66684 : half_edge_free_(half_edge_t *he)
     642             : {
     643       66684 :   if (!he)
     644             :     return;
     645       66684 :   --n_half_conns_allocated;
     646       66684 :   tor_free(he);
     647             : }
     648             : 
     649             : /** Return the number of bytes devoted to storing info on half-open streams. */
     650             : size_t
     651          12 : half_streams_get_total_allocation(void)
     652             : {
     653          12 :   return n_half_conns_allocated * sizeof(half_edge_t);
     654             : }
     655             : 
     656             : /**
     657             :  * Find a stream_id_t in the list in O(lg(n)).
     658             :  *
     659             :  * Returns NULL if the list is empty or element is not found.
     660             :  * Returns a pointer to the element if found.
     661             :  */
     662             : STATIC half_edge_t *
     663      332191 : connection_half_edge_find_stream_id(const smartlist_t *half_conns,
     664             :                                     streamid_t stream_id)
     665             : {
     666      332191 :   if (!half_conns)
     667             :     return NULL;
     668             : 
     669      332174 :   return smartlist_bsearch(half_conns, &stream_id,
     670             :                            connection_half_edge_compare_bsearch);
     671             : }
     672             : 
     673             : /**
     674             :  * Check if this stream_id is in a half-closed state. If so,
     675             :  * check if it still has data cells pending, and decrement that
     676             :  * window if so.
     677             :  *
     678             :  * Return 1 if the data window was not empty.
     679             :  * Return 0 otherwise.
     680             :  */
     681             : int
     682        1020 : connection_half_edge_is_valid_data(const smartlist_t *half_conns,
     683             :                                    streamid_t stream_id)
     684             : {
     685        1020 :   half_edge_t *half = connection_half_edge_find_stream_id(half_conns,
     686             :                                                           stream_id);
     687             : 
     688        1020 :   if (!half)
     689             :     return 0;
     690             : 
     691        1002 :   if (half->data_pending > 0) {
     692        1000 :     half->data_pending--;
     693        1000 :     return 1;
     694             :   }
     695             : 
     696             :   return 0;
     697             : }
     698             : 
     699             : /**
     700             :  * Check if this stream_id is in a half-closed state. If so,
     701             :  * check if it still has a connected cell pending, and decrement
     702             :  * that window if so.
     703             :  *
     704             :  * Return 1 if the connected window was not empty.
     705             :  * Return 0 otherwise.
     706             :  */
     707             : int
     708          20 : connection_half_edge_is_valid_connected(const smartlist_t *half_conns,
     709             :                                         streamid_t stream_id)
     710             : {
     711          20 :   half_edge_t *half = connection_half_edge_find_stream_id(half_conns,
     712             :                                                           stream_id);
     713             : 
     714          20 :   if (!half)
     715             :     return 0;
     716             : 
     717           6 :   if (half->connected_pending) {
     718           2 :     half->connected_pending = 0;
     719           2 :     return 1;
     720             :   }
     721             : 
     722             :   return 0;
     723             : }
     724             : 
     725             : /**
     726             :  * Check if this stream_id is in a half-closed state. If so,
     727             :  * check if it still has sendme cells pending, and decrement that
     728             :  * window if so.
     729             :  *
     730             :  * Return 1 if the sendme window was not empty.
     731             :  * Return 0 otherwise.
     732             :  */
     733             : int
     734          37 : connection_half_edge_is_valid_sendme(const smartlist_t *half_conns,
     735             :                                      streamid_t stream_id)
     736             : {
     737          37 :   half_edge_t *half = connection_half_edge_find_stream_id(half_conns,
     738             :                                                           stream_id);
     739             : 
     740          37 :   if (!half)
     741             :     return 0;
     742             : 
     743          20 :   if (half->sendmes_pending > 0) {
     744          18 :     half->sendmes_pending--;
     745          18 :     return 1;
     746             :   }
     747             : 
     748             :   return 0;
     749             : }
     750             : 
     751             : /**
     752             :  * Check if this stream_id is in a half-closed state. If so, remove
     753             :  * it from the list. No other data should come after the END cell.
     754             :  *
     755             :  * Return 1 if stream_id was in half-closed state.
     756             :  * Return 0 otherwise.
     757             :  */
     758             : int
     759        1155 : connection_half_edge_is_valid_end(smartlist_t *half_conns,
     760             :                                   streamid_t stream_id)
     761             : {
     762        1155 :   half_edge_t *half;
     763        1155 :   int found, remove_idx;
     764             : 
     765        1155 :   if (!half_conns)
     766             :     return 0;
     767             : 
     768        1148 :   remove_idx = smartlist_bsearch_idx(half_conns, &stream_id,
     769             :                                     connection_half_edge_compare_bsearch,
     770             :                                     &found);
     771        1148 :   if (!found)
     772             :     return 0;
     773             : 
     774        1119 :   half = smartlist_get(half_conns, remove_idx);
     775        1119 :   smartlist_del_keeporder(half_conns, remove_idx);
     776        1119 :   half_edge_free(half);
     777        1119 :   return 1;
     778             : }
     779             : 
     780             : /**
     781             :  * Streams that were used to send a RESOLVE cell are closed
     782             :  * when they get the RESOLVED, without an end. So treat
     783             :  * a RESOLVED just like an end, and remove from the list.
     784             :  */
     785             : int
     786          18 : connection_half_edge_is_valid_resolved(smartlist_t *half_conns,
     787             :                                        streamid_t stream_id)
     788             : {
     789          18 :   return connection_half_edge_is_valid_end(half_conns, stream_id);
     790             : }
     791             : 
     792             : /** An error has just occurred on an operation on an edge connection
     793             :  * <b>conn</b>.  Extract the errno; convert it to an end reason, and send an
     794             :  * appropriate relay end cell to the other end of the connection's circuit.
     795             :  **/
     796             : int
     797           0 : connection_edge_end_errno(edge_connection_t *conn)
     798             : {
     799           0 :   uint8_t reason;
     800           0 :   tor_assert(conn);
     801           0 :   reason = errno_to_stream_end_reason(tor_socket_errno(conn->base_.s));
     802           0 :   return connection_edge_end(conn, reason);
     803             : }
     804             : 
     805             : /** We just wrote some data to <b>conn</b>; act appropriately.
     806             :  *
     807             :  * (That is, if it's open, consider sending a stream-level sendme cell if we
     808             :  * have just flushed enough.)
     809             :  */
     810             : int
     811           0 : connection_edge_flushed_some(edge_connection_t *conn)
     812             : {
     813           0 :   switch (conn->base_.state) {
     814           0 :     case AP_CONN_STATE_OPEN:
     815           0 :       if (! conn->base_.linked) {
     816           0 :         note_user_activity(approx_time());
     817             :       }
     818             : 
     819           0 :       FALLTHROUGH;
     820             :     case EXIT_CONN_STATE_OPEN:
     821           0 :       sendme_connection_edge_consider_sending(conn);
     822           0 :       break;
     823             :   }
     824           0 :   return 0;
     825             : }
     826             : 
     827             : /** Connection <b>conn</b> has finished writing and has no bytes left on
     828             :  * its outbuf.
     829             :  *
     830             :  * If it's in state 'open', stop writing, consider responding with a
     831             :  * sendme, and return.
     832             :  * Otherwise, stop writing and return.
     833             :  *
     834             :  * If <b>conn</b> is broken, mark it for close and return -1, else
     835             :  * return 0.
     836             :  */
     837             : int
     838           0 : connection_edge_finished_flushing(edge_connection_t *conn)
     839             : {
     840           0 :   tor_assert(conn);
     841             : 
     842           0 :   switch (conn->base_.state) {
     843           0 :     case AP_CONN_STATE_OPEN:
     844             :     case EXIT_CONN_STATE_OPEN:
     845           0 :       sendme_connection_edge_consider_sending(conn);
     846           0 :       return 0;
     847             :     case AP_CONN_STATE_SOCKS_WAIT:
     848             :     case AP_CONN_STATE_NATD_WAIT:
     849             :     case AP_CONN_STATE_RENDDESC_WAIT:
     850             :     case AP_CONN_STATE_CIRCUIT_WAIT:
     851             :     case AP_CONN_STATE_CONNECT_WAIT:
     852             :     case AP_CONN_STATE_CONTROLLER_WAIT:
     853             :     case AP_CONN_STATE_RESOLVE_WAIT:
     854             :     case AP_CONN_STATE_HTTP_CONNECT_WAIT:
     855             :       return 0;
     856           0 :     default:
     857           0 :       log_warn(LD_BUG, "Called in unexpected state %d.",conn->base_.state);
     858           0 :       tor_fragile_assert();
     859             :       return -1;
     860             :   }
     861             :   return 0;
     862             : }
     863             : 
     864             : /** Longest size for the relay payload of a RELAY_CONNECTED cell that we're
     865             :  * able to generate. */
     866             : /* 4 zero bytes; 1 type byte; 16 byte IPv6 address; 4 byte TTL. */
     867             : #define MAX_CONNECTED_CELL_PAYLOAD_LEN 25
     868             : 
     869             : /** Set the buffer at <b>payload_out</b> -- which must have at least
     870             :  * MAX_CONNECTED_CELL_PAYLOAD_LEN bytes available -- to the body of a
     871             :  * RELAY_CONNECTED cell indicating that we have connected to <b>addr</b>, and
     872             :  * that the name resolution that led us to <b>addr</b> will be valid for
     873             :  * <b>ttl</b> seconds. Return -1 on error, or the number of bytes used on
     874             :  * success. */
     875             : STATIC int
     876           3 : connected_cell_format_payload(uint8_t *payload_out,
     877             :                               const tor_addr_t *addr,
     878             :                               uint32_t ttl)
     879             : {
     880           3 :   const sa_family_t family = tor_addr_family(addr);
     881           3 :   int connected_payload_len;
     882             : 
     883             :   /* should be needless */
     884           3 :   memset(payload_out, 0, MAX_CONNECTED_CELL_PAYLOAD_LEN);
     885             : 
     886           3 :   if (family == AF_INET) {
     887           2 :     set_uint32(payload_out, tor_addr_to_ipv4n(addr));
     888           2 :     connected_payload_len = 4;
     889           1 :   } else if (family == AF_INET6) {
     890           1 :     set_uint32(payload_out, 0);
     891           1 :     set_uint8(payload_out + 4, 6);
     892           1 :     memcpy(payload_out + 5, tor_addr_to_in6_addr8(addr), 16);
     893           1 :     connected_payload_len = 21;
     894             :   } else {
     895             :     return -1;
     896             :   }
     897             : 
     898           3 :   set_uint32(payload_out + connected_payload_len, htonl(clip_dns_ttl(ttl)));
     899           3 :   connected_payload_len += 4;
     900             : 
     901           3 :   tor_assert(connected_payload_len <= MAX_CONNECTED_CELL_PAYLOAD_LEN);
     902             : 
     903             :   return connected_payload_len;
     904             : }
     905             : 
     906             : /* This is an onion service client connection: Export the client circuit ID
     907             :  * according to the HAProxy proxy protocol. */
     908             : STATIC void
     909           5 : export_hs_client_circuit_id(edge_connection_t *edge_conn,
     910             :                             hs_circuit_id_protocol_t protocol)
     911             : {
     912             :   /* We only support HAProxy right now. */
     913           5 :   if (protocol != HS_CIRCUIT_ID_PROTOCOL_HAPROXY)
     914           0 :     return;
     915             : 
     916           5 :   char *buf = NULL;
     917           5 :   const char dst_ipv6[] = "::1";
     918             :   /* See RFC4193 regarding fc00::/7 */
     919           5 :   const char src_ipv6_prefix[] = "fc00:dead:beef:4dad:";
     920           5 :   uint16_t dst_port = 0;
     921           5 :   uint16_t src_port = 1; /* default value */
     922           5 :   uint32_t gid = 0; /* default value */
     923             : 
     924             :   /* Generate a GID and source port for this client */
     925           5 :   if (edge_conn->on_circuit != NULL) {
     926           5 :     gid = TO_ORIGIN_CIRCUIT(edge_conn->on_circuit)->global_identifier;
     927           5 :     src_port = gid & 0x0000ffff;
     928             :   }
     929             : 
     930             :   /* Grab the original dest port from the hs ident */
     931           5 :   if (edge_conn->hs_ident) {
     932           5 :     dst_port = edge_conn->hs_ident->orig_virtual_port;
     933             :   }
     934             : 
     935             :   /* Build the string */
     936           5 :   tor_asprintf(&buf, "PROXY TCP6 %s:%x:%x %s %d %d\r\n",
     937             :                src_ipv6_prefix,
     938             :                gid >> 16, gid & 0x0000ffff,
     939             :                dst_ipv6, src_port, dst_port);
     940             : 
     941           5 :   connection_buf_add(buf, strlen(buf), TO_CONN(edge_conn));
     942             : 
     943           5 :   tor_free(buf);
     944             : }
     945             : 
     946             : /** Connected handler for exit connections: start writing pending
     947             :  * data, deliver 'CONNECTED' relay cells as appropriate, and check
     948             :  * any pending data that may have been received. */
     949             : int
     950           0 : connection_edge_finished_connecting(edge_connection_t *edge_conn)
     951             : {
     952           0 :   connection_t *conn;
     953             : 
     954           0 :   tor_assert(edge_conn);
     955           0 :   tor_assert(edge_conn->base_.type == CONN_TYPE_EXIT);
     956           0 :   conn = TO_CONN(edge_conn);
     957           0 :   tor_assert(conn->state == EXIT_CONN_STATE_CONNECTING);
     958             : 
     959           0 :   log_info(LD_EXIT,"%s established.",
     960             :            connection_describe(conn));
     961             : 
     962           0 :   rep_hist_note_exit_stream_opened(conn->port);
     963             : 
     964           0 :   conn->state = EXIT_CONN_STATE_OPEN;
     965             : 
     966           0 :   connection_watch_events(conn, READ_EVENT); /* stop writing, keep reading */
     967           0 :   if (connection_get_outbuf_len(conn)) /* in case there are any queued relay
     968             :                                         * cells */
     969           0 :     connection_start_writing(conn);
     970             :   /* deliver a 'connected' relay cell back through the circuit. */
     971           0 :   if (connection_edge_is_rendezvous_stream(edge_conn)) {
     972           0 :     if (connection_edge_send_command(edge_conn,
     973             :                                      RELAY_COMMAND_CONNECTED, NULL, 0) < 0)
     974             :       return 0; /* circuit is closed, don't continue */
     975             :   } else {
     976           0 :     uint8_t connected_payload[MAX_CONNECTED_CELL_PAYLOAD_LEN];
     977           0 :     int connected_payload_len =
     978           0 :       connected_cell_format_payload(connected_payload, &conn->addr,
     979             :                                     edge_conn->address_ttl);
     980           0 :     if (connected_payload_len < 0)
     981           0 :       return -1;
     982             : 
     983           0 :     if (connection_edge_send_command(edge_conn,
     984             :                         RELAY_COMMAND_CONNECTED,
     985             :                         (char*)connected_payload, connected_payload_len) < 0)
     986             :       return 0; /* circuit is closed, don't continue */
     987             :   }
     988           0 :   tor_assert(edge_conn->package_window > 0);
     989             :   /* in case the server has written anything */
     990           0 :   return connection_edge_process_inbuf(edge_conn, 1);
     991             : }
     992             : 
     993             : /** A list of all the entry_connection_t * objects that are not marked
     994             :  * for close, and are in AP_CONN_STATE_CIRCUIT_WAIT.
     995             :  *
     996             :  * (Right now, we check in several places to make sure that this list is
     997             :  * correct.  When it's incorrect, we'll fix it, and log a BUG message.)
     998             :  */
     999             : static smartlist_t *pending_entry_connections = NULL;
    1000             : 
    1001             : static int untried_pending_connections = 0;
    1002             : 
    1003             : /**
    1004             :  * Mainloop event to tell us to scan for pending connections that can
    1005             :  * be attached.
    1006             :  */
    1007             : static mainloop_event_t *attach_pending_entry_connections_ev = NULL;
    1008             : 
    1009             : /** Common code to connection_(ap|exit)_about_to_close. */
    1010             : static void
    1011           6 : connection_edge_about_to_close(edge_connection_t *edge_conn)
    1012             : {
    1013           6 :   if (!edge_conn->edge_has_sent_end) {
    1014           0 :     connection_t *conn = TO_CONN(edge_conn);
    1015           0 :     log_warn(LD_BUG, "(Harmless.) Edge connection (marked at %s:%d) "
    1016             :              "hasn't sent end yet?",
    1017             :              conn->marked_for_close_file, conn->marked_for_close);
    1018           0 :     tor_fragile_assert();
    1019             :   }
    1020           6 : }
    1021             : 
    1022             : /** Called when we're about to finally unlink and free an AP (client)
    1023             :  * connection: perform necessary accounting and cleanup */
    1024             : void
    1025           6 : connection_ap_about_to_close(entry_connection_t *entry_conn)
    1026             : {
    1027           6 :   circuit_t *circ;
    1028           6 :   edge_connection_t *edge_conn = ENTRY_TO_EDGE_CONN(entry_conn);
    1029           6 :   connection_t *conn = ENTRY_TO_CONN(entry_conn);
    1030             : 
    1031           6 :   connection_edge_about_to_close(edge_conn);
    1032             : 
    1033           6 :   if (entry_conn->socks_request->has_finished == 0) {
    1034             :     /* since conn gets removed right after this function finishes,
    1035             :      * there's no point trying to send back a reply at this point. */
    1036           0 :     log_warn(LD_BUG,"Closing stream (marked at %s:%d) without sending"
    1037             :              " back a socks reply.",
    1038             :              conn->marked_for_close_file, conn->marked_for_close);
    1039             :   }
    1040           6 :   if (!edge_conn->end_reason) {
    1041           0 :     log_warn(LD_BUG,"Closing stream (marked at %s:%d) without having"
    1042             :              " set end_reason.",
    1043             :              conn->marked_for_close_file, conn->marked_for_close);
    1044             :   }
    1045           6 :   if (entry_conn->dns_server_request) {
    1046           0 :     log_warn(LD_BUG,"Closing stream (marked at %s:%d) without having"
    1047             :              " replied to DNS request.",
    1048             :              conn->marked_for_close_file, conn->marked_for_close);
    1049           0 :     dnsserv_reject_request(entry_conn);
    1050             :   }
    1051             : 
    1052           6 :   if (TO_CONN(edge_conn)->state == AP_CONN_STATE_CIRCUIT_WAIT) {
    1053           0 :     smartlist_remove(pending_entry_connections, entry_conn);
    1054             :   }
    1055             : 
    1056             : #if 1
    1057             :   /* Check to make sure that this isn't in pending_entry_connections if it
    1058             :    * didn't actually belong there. */
    1059           6 :   if (TO_CONN(edge_conn)->type == CONN_TYPE_AP) {
    1060           6 :     connection_ap_warn_and_unmark_if_pending_circ(entry_conn,
    1061             :                                                   "about_to_close");
    1062             :   }
    1063             : #endif /* 1 */
    1064             : 
    1065           6 :   control_event_stream_bandwidth(edge_conn);
    1066           6 :   control_event_stream_status(entry_conn, STREAM_EVENT_CLOSED,
    1067           6 :                               edge_conn->end_reason);
    1068           6 :   circ = circuit_get_by_edge_conn(edge_conn);
    1069           6 :   if (circ)
    1070           0 :     circuit_detach_stream(circ, edge_conn);
    1071           6 : }
    1072             : 
    1073             : /** Called when we're about to finally unlink and free an exit
    1074             :  * connection: perform necessary accounting and cleanup */
    1075             : void
    1076           0 : connection_exit_about_to_close(edge_connection_t *edge_conn)
    1077             : {
    1078           0 :   circuit_t *circ;
    1079           0 :   connection_t *conn = TO_CONN(edge_conn);
    1080             : 
    1081           0 :   connection_edge_about_to_close(edge_conn);
    1082             : 
    1083           0 :   circ = circuit_get_by_edge_conn(edge_conn);
    1084           0 :   if (circ)
    1085           0 :     circuit_detach_stream(circ, edge_conn);
    1086           0 :   if (conn->state == EXIT_CONN_STATE_RESOLVING) {
    1087           0 :     connection_dns_remove(edge_conn);
    1088             :   }
    1089           0 : }
    1090             : 
    1091             : /** Define a schedule for how long to wait between retrying
    1092             :  * application connections. Rather than waiting a fixed amount of
    1093             :  * time between each retry, we wait 10 seconds each for the first
    1094             :  * two tries, and 15 seconds for each retry after
    1095             :  * that. Hopefully this will improve the expected user experience. */
    1096             : static int
    1097           0 : compute_retry_timeout(entry_connection_t *conn)
    1098             : {
    1099           0 :   int timeout = get_options()->CircuitStreamTimeout;
    1100           0 :   if (timeout) /* if our config options override the default, use them */
    1101             :     return timeout;
    1102           0 :   if (conn->num_socks_retries < 2) /* try 0 and try 1 */
    1103           0 :     return 10;
    1104             :   return 15;
    1105             : }
    1106             : 
    1107             : /** Find all general-purpose AP streams waiting for a response that sent their
    1108             :  * begin/resolve cell too long ago. Detach from their current circuit, and
    1109             :  * mark their current circuit as unsuitable for new streams. Then call
    1110             :  * connection_ap_handshake_attach_circuit() to attach to a new circuit (if
    1111             :  * available) or launch a new one.
    1112             :  *
    1113             :  * For rendezvous streams, simply give up after SocksTimeout seconds (with no
    1114             :  * retry attempt).
    1115             :  */
    1116             : void
    1117           0 : connection_ap_expire_beginning(void)
    1118             : {
    1119           0 :   edge_connection_t *conn;
    1120           0 :   entry_connection_t *entry_conn;
    1121           0 :   circuit_t *circ;
    1122           0 :   time_t now = time(NULL);
    1123           0 :   const or_options_t *options = get_options();
    1124           0 :   int severity;
    1125           0 :   int cutoff;
    1126           0 :   int seconds_idle, seconds_since_born;
    1127           0 :   smartlist_t *conns = get_connection_array();
    1128             : 
    1129           0 :   SMARTLIST_FOREACH_BEGIN(conns, connection_t *, base_conn) {
    1130           0 :     if (base_conn->type != CONN_TYPE_AP || base_conn->marked_for_close)
    1131           0 :       continue;
    1132           0 :     entry_conn = TO_ENTRY_CONN(base_conn);
    1133           0 :     conn = ENTRY_TO_EDGE_CONN(entry_conn);
    1134             :     /* if it's an internal linked connection, don't yell its status. */
    1135           0 :     severity = (tor_addr_is_null(&base_conn->addr) && !base_conn->port)
    1136           0 :       ? LOG_INFO : LOG_NOTICE;
    1137           0 :     seconds_idle = (int)( now - base_conn->timestamp_last_read_allowed );
    1138           0 :     seconds_since_born = (int)( now - base_conn->timestamp_created );
    1139             : 
    1140           0 :     if (base_conn->state == AP_CONN_STATE_OPEN)
    1141           0 :       continue;
    1142             : 
    1143             :     /* We already consider SocksTimeout in
    1144             :      * connection_ap_handshake_attach_circuit(), but we need to consider
    1145             :      * it here too because controllers that put streams in controller_wait
    1146             :      * state never ask Tor to attach the circuit. */
    1147           0 :     if (AP_CONN_STATE_IS_UNATTACHED(base_conn->state)) {
    1148           0 :       if (seconds_since_born >= options->SocksTimeout) {
    1149           0 :         log_fn(severity, LD_APP,
    1150             :             "Tried for %d seconds to get a connection to %s:%d. "
    1151             :             "Giving up. (%s)",
    1152             :             seconds_since_born,
    1153             :             safe_str_client(entry_conn->socks_request->address),
    1154             :             entry_conn->socks_request->port,
    1155             :             conn_state_to_string(CONN_TYPE_AP, base_conn->state));
    1156           0 :         connection_mark_unattached_ap(entry_conn, END_STREAM_REASON_TIMEOUT);
    1157             :       }
    1158           0 :       continue;
    1159             :     }
    1160             : 
    1161             :     /* We're in state connect_wait or resolve_wait now -- waiting for a
    1162             :      * reply to our relay cell. See if we want to retry/give up. */
    1163             : 
    1164           0 :     cutoff = compute_retry_timeout(entry_conn);
    1165           0 :     if (seconds_idle < cutoff)
    1166           0 :       continue;
    1167           0 :     circ = circuit_get_by_edge_conn(conn);
    1168           0 :     if (!circ) { /* it's vanished? */
    1169           0 :       log_info(LD_APP,"Conn is waiting (address %s), but lost its circ.",
    1170             :                safe_str_client(entry_conn->socks_request->address));
    1171           0 :       connection_mark_unattached_ap(entry_conn, END_STREAM_REASON_TIMEOUT);
    1172           0 :       continue;
    1173             :     }
    1174           0 :     if (circ->purpose == CIRCUIT_PURPOSE_C_REND_JOINED) {
    1175           0 :       if (seconds_idle >= options->SocksTimeout) {
    1176           0 :         log_fn(severity, LD_REND,
    1177             :                "Rend stream is %d seconds late. Giving up on address"
    1178             :                " '%s.onion'.",
    1179             :                seconds_idle,
    1180             :                safe_str_client(entry_conn->socks_request->address));
    1181             :         /* Roll back path bias use state so that we probe the circuit
    1182             :          * if nothing else succeeds on it */
    1183           0 :         pathbias_mark_use_rollback(TO_ORIGIN_CIRCUIT(circ));
    1184             : 
    1185           0 :         connection_edge_end(conn, END_STREAM_REASON_TIMEOUT);
    1186           0 :         connection_mark_unattached_ap(entry_conn, END_STREAM_REASON_TIMEOUT);
    1187             :       }
    1188           0 :       continue;
    1189             :     }
    1190             : 
    1191           0 :     if (circ->purpose != CIRCUIT_PURPOSE_C_GENERAL &&
    1192             :         circ->purpose != CIRCUIT_PURPOSE_CONTROLLER &&
    1193             :         circ->purpose != CIRCUIT_PURPOSE_C_HSDIR_GET &&
    1194             :         circ->purpose != CIRCUIT_PURPOSE_S_HSDIR_POST &&
    1195             :         circ->purpose != CIRCUIT_PURPOSE_C_MEASURE_TIMEOUT &&
    1196             :         circ->purpose != CIRCUIT_PURPOSE_PATH_BIAS_TESTING) {
    1197           0 :       log_warn(LD_BUG, "circuit->purpose == CIRCUIT_PURPOSE_C_GENERAL failed. "
    1198             :                "The purpose on the circuit was %s; it was in state %s, "
    1199             :                "path_state %s.",
    1200             :                circuit_purpose_to_string(circ->purpose),
    1201             :                circuit_state_to_string(circ->state),
    1202             :                CIRCUIT_IS_ORIGIN(circ) ?
    1203             :                 pathbias_state_to_string(TO_ORIGIN_CIRCUIT(circ)->path_state) :
    1204             :                 "none");
    1205             :     }
    1206           0 :     log_fn(cutoff < 15 ? LOG_INFO : severity, LD_APP,
    1207             :            "We tried for %d seconds to connect to '%s' using exit %s."
    1208             :            " Retrying on a new circuit.",
    1209             :            seconds_idle,
    1210             :            safe_str_client(entry_conn->socks_request->address),
    1211             :            conn->cpath_layer ?
    1212             :              extend_info_describe(conn->cpath_layer->extend_info):
    1213             :              "*unnamed*");
    1214             :     /* send an end down the circuit */
    1215           0 :     connection_edge_end(conn, END_STREAM_REASON_TIMEOUT);
    1216             :     /* un-mark it as ending, since we're going to reuse it */
    1217           0 :     conn->edge_has_sent_end = 0;
    1218           0 :     conn->end_reason = 0;
    1219             :     /* make us not try this circuit again, but allow
    1220             :      * current streams on it to survive if they can */
    1221           0 :     mark_circuit_unusable_for_new_conns(TO_ORIGIN_CIRCUIT(circ));
    1222             : 
    1223             :     /* give our stream another 'cutoff' seconds to try */
    1224           0 :     conn->base_.timestamp_last_read_allowed += cutoff;
    1225           0 :     if (entry_conn->num_socks_retries < 250) /* avoid overflow */
    1226           0 :       entry_conn->num_socks_retries++;
    1227             :     /* move it back into 'pending' state, and try to attach. */
    1228           0 :     if (connection_ap_detach_retriable(entry_conn, TO_ORIGIN_CIRCUIT(circ),
    1229             :                                        END_STREAM_REASON_TIMEOUT)<0) {
    1230           0 :       if (!base_conn->marked_for_close)
    1231           0 :         connection_mark_unattached_ap(entry_conn,
    1232             :                                       END_STREAM_REASON_CANT_ATTACH);
    1233             :     }
    1234           0 :   } SMARTLIST_FOREACH_END(base_conn);
    1235           0 : }
    1236             : 
    1237             : /**
    1238             :  * As connection_ap_attach_pending, but first scans the entire connection
    1239             :  * array to see if any elements are missing.
    1240             :  */
    1241             : void
    1242           0 : connection_ap_rescan_and_attach_pending(void)
    1243             : {
    1244           0 :   entry_connection_t *entry_conn;
    1245           0 :   smartlist_t *conns = get_connection_array();
    1246             : 
    1247           0 :   if (PREDICT_UNLIKELY(NULL == pending_entry_connections))
    1248           0 :     pending_entry_connections = smartlist_new();
    1249             : 
    1250           0 :   SMARTLIST_FOREACH_BEGIN(conns, connection_t *, conn) {
    1251           0 :     if (conn->marked_for_close ||
    1252           0 :         conn->type != CONN_TYPE_AP ||
    1253             :         conn->state != AP_CONN_STATE_CIRCUIT_WAIT)
    1254           0 :       continue;
    1255             : 
    1256           0 :     entry_conn = TO_ENTRY_CONN(conn);
    1257           0 :     tor_assert(entry_conn);
    1258           0 :     if (! smartlist_contains(pending_entry_connections, entry_conn)) {
    1259           0 :       log_warn(LD_BUG, "Found a connection %p that was supposed to be "
    1260             :                "in pending_entry_connections, but wasn't. No worries; "
    1261             :                "adding it.",
    1262             :                pending_entry_connections);
    1263           0 :       untried_pending_connections = 1;
    1264           0 :       connection_ap_mark_as_pending_circuit(entry_conn);
    1265             :     }
    1266             : 
    1267           0 :   } SMARTLIST_FOREACH_END(conn);
    1268             : 
    1269           0 :   connection_ap_attach_pending(1);
    1270           0 : }
    1271             : 
    1272             : #ifdef DEBUGGING_17659
    1273             : #define UNMARK() do {                           \
    1274             :     entry_conn->marked_pending_circ_line = 0;   \
    1275             :     entry_conn->marked_pending_circ_file = 0;   \
    1276             :   } while (0)
    1277             : #else /* !defined(DEBUGGING_17659) */
    1278             : #define UNMARK() do { } while (0)
    1279             : #endif /* defined(DEBUGGING_17659) */
    1280             : 
    1281             : /** Tell any AP streams that are listed as waiting for a new circuit to try
    1282             :  * again.  If there is an available circuit for a stream, attach it. Otherwise,
    1283             :  * launch a new circuit.
    1284             :  *
    1285             :  * If <b>retry</b> is false, only check the list if it contains at least one
    1286             :  * streams that we have not yet tried to attach to a circuit.
    1287             :  */
    1288             : void
    1289           3 : connection_ap_attach_pending(int retry)
    1290             : {
    1291           3 :   if (PREDICT_UNLIKELY(!pending_entry_connections)) {
    1292           3 :     return;
    1293             :   }
    1294             : 
    1295           1 :   if (untried_pending_connections == 0 && !retry)
    1296             :     return;
    1297             : 
    1298             :   /* Don't allow any modifications to list while we are iterating over
    1299             :    * it.  We'll put streams back on this list if we can't attach them
    1300             :    * immediately. */
    1301           1 :   smartlist_t *pending = pending_entry_connections;
    1302           1 :   pending_entry_connections = smartlist_new();
    1303             : 
    1304           2 :   SMARTLIST_FOREACH_BEGIN(pending,
    1305             :                           entry_connection_t *, entry_conn) {
    1306           1 :     connection_t *conn = ENTRY_TO_CONN(entry_conn);
    1307           1 :     tor_assert(conn && entry_conn);
    1308           1 :     if (conn->marked_for_close) {
    1309           0 :       UNMARK();
    1310           0 :       continue;
    1311             :     }
    1312           1 :     if (conn->magic != ENTRY_CONNECTION_MAGIC) {
    1313           0 :       log_warn(LD_BUG, "%p has impossible magic value %u.",
    1314             :                entry_conn, (unsigned)conn->magic);
    1315           0 :       UNMARK();
    1316           0 :       continue;
    1317             :     }
    1318           1 :     if (conn->state != AP_CONN_STATE_CIRCUIT_WAIT) {
    1319           0 :       log_warn(LD_BUG, "%p is no longer in circuit_wait. Its current state "
    1320             :                "is %s. Why is it on pending_entry_connections?",
    1321             :                entry_conn,
    1322             :                conn_state_to_string(conn->type, conn->state));
    1323           0 :       UNMARK();
    1324           0 :       continue;
    1325             :     }
    1326             : 
    1327             :     /* Okay, we're through the sanity checks. Try to handle this stream. */
    1328           1 :     if (connection_ap_handshake_attach_circuit(entry_conn) < 0) {
    1329           0 :       if (!conn->marked_for_close)
    1330           0 :         connection_mark_unattached_ap(entry_conn,
    1331             :                                       END_STREAM_REASON_CANT_ATTACH);
    1332             :     }
    1333             : 
    1334           1 :     if (! conn->marked_for_close &&
    1335           1 :         conn->type == CONN_TYPE_AP &&
    1336             :         conn->state == AP_CONN_STATE_CIRCUIT_WAIT) {
    1337             :       /* Is it still waiting for a circuit? If so, we didn't attach it,
    1338             :        * so it's still pending.  Put it back on the list.
    1339             :        */
    1340           1 :       if (!smartlist_contains(pending_entry_connections, entry_conn)) {
    1341           1 :         smartlist_add(pending_entry_connections, entry_conn);
    1342           1 :         continue;
    1343             :       }
    1344             :     }
    1345             : 
    1346             :     /* If we got here, then we either closed the connection, or
    1347             :      * we attached it. */
    1348           0 :     UNMARK();
    1349           1 :   } SMARTLIST_FOREACH_END(entry_conn);
    1350             : 
    1351           1 :   smartlist_free(pending);
    1352           1 :   untried_pending_connections = 0;
    1353             : }
    1354             : 
    1355             : static void
    1356           0 : attach_pending_entry_connections_cb(mainloop_event_t *ev, void *arg)
    1357             : {
    1358           0 :   (void)ev;
    1359           0 :   (void)arg;
    1360           0 :   connection_ap_attach_pending(0);
    1361           0 : }
    1362             : 
    1363             : /** Mark <b>entry_conn</b> as needing to get attached to a circuit.
    1364             :  *
    1365             :  * And <b>entry_conn</b> must be in AP_CONN_STATE_CIRCUIT_WAIT,
    1366             :  * should not already be pending a circuit.  The circuit will get
    1367             :  * launched or the connection will get attached the next time we
    1368             :  * call connection_ap_attach_pending().
    1369             :  */
    1370             : void
    1371           1 : connection_ap_mark_as_pending_circuit_(entry_connection_t *entry_conn,
    1372             :                                        const char *fname, int lineno)
    1373             : {
    1374           1 :   connection_t *conn = ENTRY_TO_CONN(entry_conn);
    1375           1 :   tor_assert(conn->state == AP_CONN_STATE_CIRCUIT_WAIT);
    1376           1 :   tor_assert(conn->magic == ENTRY_CONNECTION_MAGIC);
    1377           1 :   if (conn->marked_for_close)
    1378             :     return;
    1379             : 
    1380           1 :   if (PREDICT_UNLIKELY(NULL == pending_entry_connections)) {
    1381           1 :     pending_entry_connections = smartlist_new();
    1382             :   }
    1383           1 :   if (PREDICT_UNLIKELY(NULL == attach_pending_entry_connections_ev)) {
    1384           1 :     attach_pending_entry_connections_ev = mainloop_event_postloop_new(
    1385             :                                   attach_pending_entry_connections_cb, NULL);
    1386             :   }
    1387           1 :   if (PREDICT_UNLIKELY(smartlist_contains(pending_entry_connections,
    1388             :                                           entry_conn))) {
    1389           0 :     log_warn(LD_BUG, "What?? pending_entry_connections already contains %p! "
    1390             :              "(Called from %s:%d.)",
    1391             :              entry_conn, fname, lineno);
    1392             : #ifdef DEBUGGING_17659
    1393           0 :     const char *f2 = entry_conn->marked_pending_circ_file;
    1394           0 :     log_warn(LD_BUG, "(Previously called from %s:%d.)\n",
    1395             :              f2 ? f2 : "<NULL>",
    1396             :              entry_conn->marked_pending_circ_line);
    1397             : #endif /* defined(DEBUGGING_17659) */
    1398           0 :     log_backtrace(LOG_WARN, LD_BUG, "To debug, this may help");
    1399           0 :     return;
    1400             :   }
    1401             : 
    1402             : #ifdef DEBUGGING_17659
    1403           1 :   entry_conn->marked_pending_circ_line = (uint16_t) lineno;
    1404           1 :   entry_conn->marked_pending_circ_file = fname;
    1405             : #endif
    1406             : 
    1407           1 :   untried_pending_connections = 1;
    1408           1 :   smartlist_add(pending_entry_connections, entry_conn);
    1409             : 
    1410           1 :   mainloop_event_activate(attach_pending_entry_connections_ev);
    1411             : }
    1412             : 
    1413             : /** Mark <b>entry_conn</b> as no longer waiting for a circuit. */
    1414             : void
    1415           1 : connection_ap_mark_as_non_pending_circuit(entry_connection_t *entry_conn)
    1416             : {
    1417           1 :   if (PREDICT_UNLIKELY(NULL == pending_entry_connections))
    1418             :     return;
    1419           0 :   UNMARK();
    1420           0 :   smartlist_remove(pending_entry_connections, entry_conn);
    1421             : }
    1422             : 
    1423             : /** Mark <b>entry_conn</b> as waiting for a rendezvous descriptor. This
    1424             :  * function will remove the entry connection from the waiting for a circuit
    1425             :  * list (pending_entry_connections).
    1426             :  *
    1427             :  * This pattern is used across the code base because a connection in state
    1428             :  * AP_CONN_STATE_RENDDESC_WAIT must not be in the pending list. */
    1429             : void
    1430           0 : connection_ap_mark_as_waiting_for_renddesc(entry_connection_t *entry_conn)
    1431             : {
    1432           0 :   tor_assert(entry_conn);
    1433             : 
    1434           0 :   connection_ap_mark_as_non_pending_circuit(entry_conn);
    1435           0 :   ENTRY_TO_CONN(entry_conn)->state = AP_CONN_STATE_RENDDESC_WAIT;
    1436           0 : }
    1437             : 
    1438             : /* DOCDOC */
    1439             : void
    1440          12 : connection_ap_warn_and_unmark_if_pending_circ(entry_connection_t *entry_conn,
    1441             :                                               const char *where)
    1442             : {
    1443          12 :   if (pending_entry_connections &&
    1444           0 :       smartlist_contains(pending_entry_connections, entry_conn)) {
    1445           0 :     log_warn(LD_BUG, "What was %p doing in pending_entry_connections in %s?",
    1446             :              entry_conn, where);
    1447           0 :     connection_ap_mark_as_non_pending_circuit(entry_conn);
    1448             :   }
    1449          12 : }
    1450             : 
    1451             : /** Tell any AP streams that are waiting for a one-hop tunnel to
    1452             :  * <b>failed_digest</b> that they are going to fail. */
    1453             : /* XXXX We should get rid of this function, and instead attach
    1454             :  * one-hop streams to circ->p_streams so they get marked in
    1455             :  * circuit_mark_for_close like normal p_streams. */
    1456             : void
    1457           0 : connection_ap_fail_onehop(const char *failed_digest,
    1458             :                           cpath_build_state_t *build_state)
    1459             : {
    1460           0 :   entry_connection_t *entry_conn;
    1461           0 :   char digest[DIGEST_LEN];
    1462           0 :   smartlist_t *conns = get_connection_array();
    1463           0 :   SMARTLIST_FOREACH_BEGIN(conns, connection_t *, conn) {
    1464           0 :     if (conn->marked_for_close ||
    1465           0 :         conn->type != CONN_TYPE_AP ||
    1466             :         conn->state != AP_CONN_STATE_CIRCUIT_WAIT)
    1467           0 :       continue;
    1468           0 :     entry_conn = TO_ENTRY_CONN(conn);
    1469           0 :     if (!entry_conn->want_onehop)
    1470           0 :       continue;
    1471           0 :     if (hexdigest_to_digest(entry_conn->chosen_exit_name, digest) < 0 ||
    1472           0 :         tor_memneq(digest, failed_digest, DIGEST_LEN))
    1473           0 :       continue;
    1474           0 :     if (tor_digest_is_zero(digest)) {
    1475             :       /* we don't know the digest; have to compare addr:port */
    1476           0 :       tor_addr_t addr;
    1477           0 :       if (!build_state || !build_state->chosen_exit ||
    1478           0 :           !entry_conn->socks_request) {
    1479           0 :         continue;
    1480             :       }
    1481           0 :       if (tor_addr_parse(&addr, entry_conn->socks_request->address)<0 ||
    1482           0 :           !extend_info_has_orport(build_state->chosen_exit, &addr,
    1483           0 :                                   entry_conn->socks_request->port))
    1484           0 :         continue;
    1485             :     }
    1486           0 :     log_info(LD_APP, "Closing one-hop stream to '%s/%s' because the OR conn "
    1487             :                      "just failed.", entry_conn->chosen_exit_name,
    1488             :                      entry_conn->socks_request->address);
    1489           0 :     connection_mark_unattached_ap(entry_conn, END_STREAM_REASON_TIMEOUT);
    1490           0 :   } SMARTLIST_FOREACH_END(conn);
    1491           0 : }
    1492             : 
    1493             : /** A circuit failed to finish on its last hop <b>info</b>. If there
    1494             :  * are any streams waiting with this exit node in mind, but they
    1495             :  * don't absolutely require it, make them give up on it.
    1496             :  */
    1497             : void
    1498           0 : circuit_discard_optional_exit_enclaves(extend_info_t *info)
    1499             : {
    1500           0 :   entry_connection_t *entry_conn;
    1501           0 :   const node_t *r1, *r2;
    1502             : 
    1503           0 :   smartlist_t *conns = get_connection_array();
    1504           0 :   SMARTLIST_FOREACH_BEGIN(conns, connection_t *, conn) {
    1505           0 :     if (conn->marked_for_close ||
    1506           0 :         conn->type != CONN_TYPE_AP ||
    1507             :         conn->state != AP_CONN_STATE_CIRCUIT_WAIT)
    1508           0 :       continue;
    1509           0 :     entry_conn = TO_ENTRY_CONN(conn);
    1510           0 :     if (!entry_conn->chosen_exit_optional &&
    1511             :         !entry_conn->chosen_exit_retries)
    1512           0 :       continue;
    1513           0 :     r1 = node_get_by_nickname(entry_conn->chosen_exit_name,
    1514             :                               NNF_NO_WARN_UNNAMED);
    1515           0 :     r2 = node_get_by_id(info->identity_digest);
    1516           0 :     if (!r1 || !r2 || r1 != r2)
    1517           0 :       continue;
    1518           0 :     tor_assert(entry_conn->socks_request);
    1519           0 :     if (entry_conn->chosen_exit_optional) {
    1520           0 :       log_info(LD_APP, "Giving up on enclave exit '%s' for destination %s.",
    1521             :                safe_str_client(entry_conn->chosen_exit_name),
    1522             :                escaped_safe_str_client(entry_conn->socks_request->address));
    1523           0 :       entry_conn->chosen_exit_optional = 0;
    1524           0 :       tor_free(entry_conn->chosen_exit_name); /* clears it */
    1525             :       /* if this port is dangerous, warn or reject it now that we don't
    1526             :        * think it'll be using an enclave. */
    1527           0 :       consider_plaintext_ports(entry_conn, entry_conn->socks_request->port);
    1528             :     }
    1529           0 :     if (entry_conn->chosen_exit_retries) {
    1530           0 :       if (--entry_conn->chosen_exit_retries == 0) { /* give up! */
    1531           0 :         clear_trackexithost_mappings(entry_conn->chosen_exit_name);
    1532           0 :         tor_free(entry_conn->chosen_exit_name); /* clears it */
    1533             :         /* if this port is dangerous, warn or reject it now that we don't
    1534             :          * think it'll be using an enclave. */
    1535           0 :         consider_plaintext_ports(entry_conn, entry_conn->socks_request->port);
    1536             :       }
    1537             :     }
    1538           0 :   } SMARTLIST_FOREACH_END(conn);
    1539           0 : }
    1540             : 
    1541             : /** Set the connection state to CONTROLLER_WAIT and send an control port event.
    1542             :  */
    1543             : void
    1544           0 : connection_entry_set_controller_wait(entry_connection_t *conn)
    1545             : {
    1546           0 :   CONNECTION_AP_EXPECT_NONPENDING(conn);
    1547           0 :   ENTRY_TO_CONN(conn)->state = AP_CONN_STATE_CONTROLLER_WAIT;
    1548           0 :   control_event_stream_status(conn, STREAM_EVENT_CONTROLLER_WAIT, 0);
    1549           0 : }
    1550             : 
    1551             : /** The AP connection <b>conn</b> has just failed while attaching or
    1552             :  * sending a BEGIN or resolving on <b>circ</b>, but another circuit
    1553             :  * might work. Detach the circuit, and either reattach it, launch a
    1554             :  * new circuit, tell the controller, or give up as appropriate.
    1555             :  *
    1556             :  * Returns -1 on err, 1 on success, 0 on not-yet-sure.
    1557             :  */
    1558             : int
    1559           0 : connection_ap_detach_retriable(entry_connection_t *conn,
    1560             :                                origin_circuit_t *circ,
    1561             :                                int reason)
    1562             : {
    1563           0 :   control_event_stream_status(conn, STREAM_EVENT_FAILED_RETRIABLE, reason);
    1564           0 :   ENTRY_TO_CONN(conn)->timestamp_last_read_allowed = time(NULL);
    1565             : 
    1566             :   /* Roll back path bias use state so that we probe the circuit
    1567             :    * if nothing else succeeds on it */
    1568           0 :   pathbias_mark_use_rollback(circ);
    1569             : 
    1570           0 :   if (conn->pending_optimistic_data) {
    1571           0 :     buf_set_to_copy(&conn->sending_optimistic_data,
    1572             :                     conn->pending_optimistic_data);
    1573             :   }
    1574             : 
    1575           0 :   if (!get_options()->LeaveStreamsUnattached || conn->use_begindir) {
    1576             :     /* If we're attaching streams ourself, or if this connection is
    1577             :      * a tunneled directory connection, then just attach it. */
    1578           0 :     ENTRY_TO_CONN(conn)->state = AP_CONN_STATE_CIRCUIT_WAIT;
    1579           0 :     circuit_detach_stream(TO_CIRCUIT(circ),ENTRY_TO_EDGE_CONN(conn));
    1580           0 :     connection_ap_mark_as_pending_circuit(conn);
    1581             :   } else {
    1582           0 :     connection_entry_set_controller_wait(conn);
    1583           0 :     circuit_detach_stream(TO_CIRCUIT(circ),ENTRY_TO_EDGE_CONN(conn));
    1584             :   }
    1585           0 :   return 0;
    1586             : }
    1587             : 
    1588             : /** Check if <b>conn</b> is using a dangerous port. Then warn and/or
    1589             :  * reject depending on our config options. */
    1590             : static int
    1591           0 : consider_plaintext_ports(entry_connection_t *conn, uint16_t port)
    1592             : {
    1593           0 :   const or_options_t *options = get_options();
    1594           0 :   int reject = smartlist_contains_int_as_string(
    1595           0 :                                      options->RejectPlaintextPorts, port);
    1596             : 
    1597           0 :   if (smartlist_contains_int_as_string(options->WarnPlaintextPorts, port)) {
    1598           0 :     log_warn(LD_APP, "Application request to port %d: this port is "
    1599             :              "commonly used for unencrypted protocols. Please make sure "
    1600             :              "you don't send anything you would mind the rest of the "
    1601             :              "Internet reading!%s", port, reject ? " Closing." : "");
    1602           0 :     control_event_client_status(LOG_WARN, "DANGEROUS_PORT PORT=%d RESULT=%s",
    1603             :                                 port, reject ? "REJECT" : "WARN");
    1604             :   }
    1605             : 
    1606           0 :   if (reject) {
    1607           0 :     log_info(LD_APP, "Port %d listed in RejectPlaintextPorts. Closing.", port);
    1608           0 :     connection_mark_unattached_ap(conn, END_STREAM_REASON_ENTRYPOLICY);
    1609           0 :     return -1;
    1610             :   }
    1611             : 
    1612             :   return 0;
    1613             : }
    1614             : 
    1615             : /** Return true iff <b>query</b> is a syntactically valid service ID (as
    1616             :  * generated by rend_get_service_id).  */
    1617             : static int
    1618           2 : rend_valid_v2_service_id(const char *query)
    1619             : {
    1620             :   /** Length of 'y' portion of 'y.onion' URL. */
    1621             : #define REND_SERVICE_ID_LEN_BASE32 16
    1622             : 
    1623           2 :   if (strlen(query) != REND_SERVICE_ID_LEN_BASE32)
    1624             :     return 0;
    1625             : 
    1626           2 :   if (strspn(query, BASE32_CHARS) != REND_SERVICE_ID_LEN_BASE32)
    1627           0 :     return 0;
    1628             : 
    1629             :   return 1;
    1630             : }
    1631             : 
    1632             : /** Parse the given hostname in address. Returns true if the parsing was
    1633             :  * successful and type_out contains the type of the hostname. Else, false is
    1634             :  * returned which means it was not recognized and type_out is set to
    1635             :  * BAD_HOSTNAME.
    1636             :  *
    1637             :  * The possible recognized forms are (where true is returned):
    1638             :  *
    1639             :  *  If address is of the form "y.onion" with a well-formed handle y:
    1640             :  *     Put a NUL after y, lower-case it, and return ONION_V3_HOSTNAME
    1641             :  *     depending on the HS version.
    1642             :  *
    1643             :  *  If address is of the form "x.y.onion" with a well-formed handle x:
    1644             :  *     Drop "x.", put a NUL after y, lower-case it, and return
    1645             :  *     ONION_V3_HOSTNAME depending on the HS version.
    1646             :  *
    1647             :  * If address is of the form "y.onion" with a badly-formed handle y:
    1648             :  *     Return BAD_HOSTNAME and log a message.
    1649             :  *
    1650             :  * If address is of the form "y.exit":
    1651             :  *     Put a NUL after y and return EXIT_HOSTNAME.
    1652             :  *
    1653             :  * Otherwise:
    1654             :  *     Return NORMAL_HOSTNAME and change nothing.
    1655             :  */
    1656             : STATIC bool
    1657          10 : parse_extended_hostname(char *address, hostname_type_t *type_out)
    1658             : {
    1659          10 :   char *s;
    1660          10 :   char *q;
    1661          10 :   char query[HS_SERVICE_ADDR_LEN_BASE32+1];
    1662             : 
    1663          10 :   s = strrchr(address,'.');
    1664          10 :   if (!s) {
    1665           0 :     *type_out = NORMAL_HOSTNAME; /* no dot, thus normal */
    1666           0 :     goto success;
    1667             :   }
    1668          10 :   if (!strcmp(s+1,"exit")) {
    1669           1 :     *s = 0; /* NUL-terminate it */
    1670           1 :     *type_out = EXIT_HOSTNAME; /* .exit */
    1671           1 :     goto success;
    1672             :   }
    1673           9 :   if (strcmp(s+1,"onion")) {
    1674           1 :     *type_out = NORMAL_HOSTNAME; /* neither .exit nor .onion, thus normal */
    1675           1 :     goto success;
    1676             :   }
    1677             : 
    1678             :   /* so it is .onion */
    1679           8 :   *s = 0; /* NUL-terminate it */
    1680             :   /* locate a 'sub-domain' component, in order to remove it */
    1681           8 :   q = strrchr(address, '.');
    1682           8 :   if (q == address) {
    1683           1 :     *type_out = BAD_HOSTNAME;
    1684           1 :     goto failed; /* reject sub-domain, as DNS does */
    1685             :   }
    1686           7 :   q = (NULL == q) ? address : q + 1;
    1687           7 :   if (strlcpy(query, q, HS_SERVICE_ADDR_LEN_BASE32+1) >=
    1688             :       HS_SERVICE_ADDR_LEN_BASE32+1) {
    1689           1 :     *type_out = BAD_HOSTNAME;
    1690           1 :     goto failed;
    1691             :   }
    1692           6 :   if (q != address) {
    1693           5 :     memmove(address, q, strlen(q) + 1 /* also get \0 */);
    1694             :   }
    1695             :   /* v2 onion address check. */
    1696           6 :   if (strlen(query) == REND_SERVICE_ID_LEN_BASE32) {
    1697           2 :     *type_out = ONION_V2_HOSTNAME;
    1698           2 :     if (rend_valid_v2_service_id(query)) {
    1699           2 :       goto success;
    1700             :     }
    1701           0 :     goto failed;
    1702             :   }
    1703             : 
    1704             :   /* v3 onion address check. */
    1705           4 :   if (strlen(query) == HS_SERVICE_ADDR_LEN_BASE32) {
    1706           3 :     *type_out = ONION_V3_HOSTNAME;
    1707           3 :     if (hs_address_is_valid(query)) {
    1708           2 :       goto success;
    1709             :     }
    1710           1 :     goto failed;
    1711             :   }
    1712             : 
    1713             :   /* Reaching this point, nothing was recognized. */
    1714           1 :   *type_out = BAD_HOSTNAME;
    1715           1 :   goto failed;
    1716             : 
    1717             :  success:
    1718             :   return true;
    1719           4 :  failed:
    1720             :   /* otherwise, return to previous state and return 0 */
    1721           4 :   *s = '.';
    1722           4 :   const bool is_onion = (*type_out == ONION_V2_HOSTNAME) ||
    1723             :     (*type_out == ONION_V3_HOSTNAME);
    1724           7 :   log_warn(LD_APP, "Invalid %shostname %s; rejecting",
    1725             :            is_onion ? "onion " : "",
    1726             :            safe_str_client(address));
    1727           4 :   if (*type_out == ONION_V3_HOSTNAME) {
    1728           1 :       *type_out = BAD_HOSTNAME;
    1729             :   }
    1730             :   return false;
    1731             : }
    1732             : 
    1733             : /** How many times do we try connecting with an exit configured via
    1734             :  * TrackHostExits before concluding that it won't work any more and trying a
    1735             :  * different one? */
    1736             : #define TRACKHOSTEXITS_RETRIES 5
    1737             : 
    1738             : /** Call connection_ap_handshake_rewrite_and_attach() unless a controller
    1739             :  *  asked us to leave streams unattached. Return 0 in that case.
    1740             :  *
    1741             :  *  See connection_ap_handshake_rewrite_and_attach()'s
    1742             :  *  documentation for arguments and return value.
    1743             :  */
    1744           0 : MOCK_IMPL(int,
    1745             : connection_ap_rewrite_and_attach_if_allowed,(entry_connection_t *conn,
    1746             :                                              origin_circuit_t *circ,
    1747             :                                              crypt_path_t *cpath))
    1748             : {
    1749           0 :   const or_options_t *options = get_options();
    1750             : 
    1751           0 :   if (options->LeaveStreamsUnattached) {
    1752           0 :     connection_entry_set_controller_wait(conn);
    1753           0 :     return 0;
    1754             :   }
    1755           0 :   return connection_ap_handshake_rewrite_and_attach(conn, circ, cpath);
    1756             : }
    1757             : 
    1758             : /* Try to perform any map-based rewriting of the target address in
    1759             :  * <b>conn</b>, filling in the fields of <b>out</b> as we go, and modifying
    1760             :  * conn->socks_request.address as appropriate.
    1761             :  */
    1762             : STATIC void
    1763          32 : connection_ap_handshake_rewrite(entry_connection_t *conn,
    1764             :                                 rewrite_result_t *out)
    1765             : {
    1766          32 :   socks_request_t *socks = conn->socks_request;
    1767          32 :   const or_options_t *options = get_options();
    1768          32 :   tor_addr_t addr_tmp;
    1769             : 
    1770             :   /* Initialize all the fields of 'out' to reasonable defaults */
    1771          32 :   out->automap = 0;
    1772          32 :   out->exit_source = ADDRMAPSRC_NONE;
    1773          32 :   out->map_expires = TIME_MAX;
    1774          32 :   out->end_reason = 0;
    1775          32 :   out->should_close = 0;
    1776          32 :   out->orig_address[0] = 0;
    1777             : 
    1778             :   /* We convert all incoming addresses to lowercase. */
    1779          32 :   tor_strlower(socks->address);
    1780             :   /* Remember the original address. */
    1781          32 :   strlcpy(out->orig_address, socks->address, sizeof(out->orig_address));
    1782          32 :   log_debug(LD_APP,"Client asked for %s:%d",
    1783             :             safe_str_client(socks->address),
    1784             :             socks->port);
    1785             : 
    1786             :   /* Check for whether this is a .exit address.  By default, those are
    1787             :    * disallowed when they're coming straight from the client, but you're
    1788             :    * allowed to have them in MapAddress commands and so forth. */
    1789          32 :   if (!strcmpend(socks->address, ".exit")) {
    1790           2 :     static ratelim_t exit_warning_limit = RATELIM_INIT(60*15);
    1791           2 :     log_fn_ratelim(&exit_warning_limit, LOG_WARN, LD_APP,
    1792             :                    "The  \".exit\" notation is disabled in Tor due to "
    1793             :                    "security risks.");
    1794           2 :     control_event_client_status(LOG_WARN, "SOCKS_BAD_HOSTNAME HOSTNAME=%s",
    1795             :                                 escaped(socks->address));
    1796           2 :     out->end_reason = END_STREAM_REASON_TORPROTOCOL;
    1797           2 :     out->should_close = 1;
    1798           5 :     return;
    1799             :   }
    1800             : 
    1801             :   /* Remember the original address so we can tell the user about what
    1802             :    * they actually said, not just what it turned into. */
    1803             :   /* XXX yes, this is the same as out->orig_address above. One is
    1804             :    * in the output, and one is in the connection. */
    1805          30 :   if (! conn->original_dest_address) {
    1806             :     /* Is the 'if' necessary here? XXXX */
    1807          30 :     conn->original_dest_address = tor_strdup(conn->socks_request->address);
    1808             :   }
    1809             : 
    1810             :   /* First, apply MapAddress and MAPADDRESS mappings. We need to do
    1811             :    * these only for non-reverse lookups, since they don't exist for those.
    1812             :    * We also need to do this before we consider automapping, since we might
    1813             :    * e.g. resolve irc.oftc.net into irconionaddress.onion, at which point
    1814             :    * we'd need to automap it. */
    1815          30 :   if (socks->command != SOCKS_COMMAND_RESOLVE_PTR) {
    1816          29 :     const unsigned rewrite_flags = AMR_FLAG_USE_MAPADDRESS;
    1817          29 :     if (addressmap_rewrite(socks->address, sizeof(socks->address),
    1818             :                        rewrite_flags, &out->map_expires, &out->exit_source)) {
    1819           8 :       control_event_stream_status(conn, STREAM_EVENT_REMAP,
    1820             :                                   REMAP_STREAM_SOURCE_CACHE);
    1821             :     }
    1822             :   }
    1823             : 
    1824             :   /* Now see if we need to create or return an existing Hostname->IP
    1825             :    * automapping.  Automapping happens when we're asked to resolve a
    1826             :    * hostname, and AutomapHostsOnResolve is set, and the hostname has a
    1827             :    * suffix listed in AutomapHostsSuffixes.  It's a handy feature
    1828             :    * that lets you have Tor assign e.g. IPv6 addresses for .onion
    1829             :    * names, and return them safely from DNSPort.
    1830             :    */
    1831          39 :   if (socks->command == SOCKS_COMMAND_RESOLVE &&
    1832           9 :       tor_addr_parse(&addr_tmp, socks->address)<0 &&
    1833           9 :       options->AutomapHostsOnResolve) {
    1834             :     /* Check the suffix... */
    1835           8 :     out->automap = addressmap_address_should_automap(socks->address, options);
    1836           8 :     if (out->automap) {
    1837             :       /* If we get here, then we should apply an automapping for this. */
    1838           7 :       const char *new_addr;
    1839             :       /* We return an IPv4 address by default, or an IPv6 address if we
    1840             :        * are allowed to do so. */
    1841           7 :       int addr_type = RESOLVED_TYPE_IPV4;
    1842           7 :       if (conn->socks_request->socks_version != 4) {
    1843           7 :         if (!conn->entry_cfg.ipv4_traffic ||
    1844           5 :             (conn->entry_cfg.ipv6_traffic && conn->entry_cfg.prefer_ipv6) ||
    1845             :             conn->entry_cfg.prefer_ipv6_virtaddr)
    1846           2 :           addr_type = RESOLVED_TYPE_IPV6;
    1847             :       }
    1848             :       /* Okay, register the target address as automapped, and find the new
    1849             :        * address we're supposed to give as a resolve answer.  (Return a cached
    1850             :        * value if we've looked up this address before.
    1851             :        */
    1852           7 :       new_addr = addressmap_register_virtual_address(
    1853             :                                     addr_type, tor_strdup(socks->address));
    1854           7 :       if (! new_addr) {
    1855           0 :         log_warn(LD_APP, "Unable to automap address %s",
    1856             :                  escaped_safe_str(socks->address));
    1857           0 :         out->end_reason = END_STREAM_REASON_INTERNAL;
    1858           0 :         out->should_close = 1;
    1859           0 :         return;
    1860             :       }
    1861           7 :       log_info(LD_APP, "Automapping %s to %s",
    1862             :                escaped_safe_str_client(socks->address),
    1863             :                safe_str_client(new_addr));
    1864           7 :       strlcpy(socks->address, new_addr, sizeof(socks->address));
    1865             :     }
    1866             :   }
    1867             : 
    1868             :   /* Now handle reverse lookups, if they're in the cache.  This doesn't
    1869             :    * happen too often, since client-side DNS caching is off by default,
    1870             :    * and very deprecated. */
    1871          30 :   if (socks->command == SOCKS_COMMAND_RESOLVE_PTR) {
    1872           1 :     unsigned rewrite_flags = 0;
    1873           1 :     if (conn->entry_cfg.use_cached_ipv4_answers)
    1874           0 :       rewrite_flags |= AMR_FLAG_USE_IPV4_DNS;
    1875           1 :     if (conn->entry_cfg.use_cached_ipv6_answers)
    1876           0 :       rewrite_flags |= AMR_FLAG_USE_IPV6_DNS;
    1877             : 
    1878           1 :     if (addressmap_rewrite_reverse(socks->address, sizeof(socks->address),
    1879             :                                    rewrite_flags, &out->map_expires)) {
    1880           0 :       char *result = tor_strdup(socks->address);
    1881             :       /* remember _what_ is supposed to have been resolved. */
    1882           0 :       tor_snprintf(socks->address, sizeof(socks->address), "REVERSE[%s]",
    1883             :                    out->orig_address);
    1884           0 :       connection_ap_handshake_socks_resolved(conn, RESOLVED_TYPE_HOSTNAME,
    1885             :                                              strlen(result), (uint8_t*)result,
    1886             :                                              -1,
    1887             :                                              out->map_expires);
    1888           0 :       tor_free(result);
    1889           0 :       out->end_reason = END_STREAM_REASON_DONE |
    1890             :                         END_STREAM_REASON_FLAG_ALREADY_SOCKS_REPLIED;
    1891           0 :       out->should_close = 1;
    1892           0 :       return;
    1893             :     }
    1894             : 
    1895             :     /* Hang on, did we find an answer saying that this is a reverse lookup for
    1896             :      * an internal address?  If so, we should reject it if we're configured to
    1897             :      * do so. */
    1898           1 :     if (options->ClientDNSRejectInternalAddresses) {
    1899             :       /* Don't let clients try to do a reverse lookup on 10.0.0.1. */
    1900           1 :       tor_addr_t addr;
    1901           1 :       int ok;
    1902           1 :       ok = tor_addr_parse_PTR_name(
    1903             :                                &addr, socks->address, AF_UNSPEC, 1);
    1904           1 :       if (ok == 1 && tor_addr_is_internal(&addr, 0)) {
    1905           1 :         connection_ap_handshake_socks_resolved(conn, RESOLVED_TYPE_ERROR,
    1906             :                                                0, NULL, -1, TIME_MAX);
    1907           1 :         out->end_reason = END_STREAM_REASON_SOCKSPROTOCOL |
    1908             :                           END_STREAM_REASON_FLAG_ALREADY_SOCKS_REPLIED;
    1909           1 :         out->should_close = 1;
    1910           1 :         return;
    1911             :       }
    1912             :     }
    1913             :   }
    1914             : 
    1915             :   /* If we didn't automap it before, then this is still the address that
    1916             :    * came straight from the user, mapped according to any
    1917             :    * MapAddress/MAPADDRESS commands.  Now apply other mappings,
    1918             :    * including previously registered Automap entries (IP back to
    1919             :    * hostname), TrackHostExits entries, and client-side DNS cache
    1920             :    * entries (if they're turned on).
    1921             :    */
    1922          29 :   if (socks->command != SOCKS_COMMAND_RESOLVE_PTR &&
    1923          29 :       !out->automap) {
    1924          22 :     unsigned rewrite_flags = AMR_FLAG_USE_AUTOMAP | AMR_FLAG_USE_TRACKEXIT;
    1925          22 :     addressmap_entry_source_t exit_source2;
    1926          22 :     if (conn->entry_cfg.use_cached_ipv4_answers)
    1927           1 :       rewrite_flags |= AMR_FLAG_USE_IPV4_DNS;
    1928          22 :     if (conn->entry_cfg.use_cached_ipv6_answers)
    1929           1 :       rewrite_flags |= AMR_FLAG_USE_IPV6_DNS;
    1930          22 :     if (addressmap_rewrite(socks->address, sizeof(socks->address),
    1931             :                         rewrite_flags, &out->map_expires, &exit_source2)) {
    1932           6 :       control_event_stream_status(conn, STREAM_EVENT_REMAP,
    1933             :                                   REMAP_STREAM_SOURCE_CACHE);
    1934             :     }
    1935          22 :     if (out->exit_source == ADDRMAPSRC_NONE) {
    1936             :       /* If it wasn't a .exit before, maybe it turned into a .exit. Remember
    1937             :        * the original source of a .exit. */
    1938          21 :       out->exit_source = exit_source2;
    1939             :     }
    1940             :   }
    1941             : 
    1942             :   /* Check to see whether we're about to use an address in the virtual
    1943             :    * range without actually having gotten it from an Automap. */
    1944          29 :   if (!out->automap && address_is_in_virtual_range(socks->address)) {
    1945             :     /* This address was probably handed out by
    1946             :      * client_dns_get_unmapped_address, but the mapping was discarded for some
    1947             :      * reason.  Or the user typed in a virtual address range manually.  We
    1948             :      * *don't* want to send the address through Tor; that's likely to fail,
    1949             :      * and may leak information.
    1950             :      */
    1951           2 :     log_warn(LD_APP,"Missing mapping for virtual address '%s'. Refusing.",
    1952             :              safe_str_client(socks->address));
    1953           2 :     out->end_reason = END_STREAM_REASON_INTERNAL;
    1954           2 :     out->should_close = 1;
    1955           2 :     return;
    1956             :   }
    1957             : }
    1958             : 
    1959             : /** We just received a SOCKS request in <b>conn</b> to a v3 onion. Start
    1960             :  *  connecting to the onion service. */
    1961             : static int
    1962           1 : connection_ap_handle_onion(entry_connection_t *conn,
    1963             :                            socks_request_t *socks,
    1964             :                            origin_circuit_t *circ)
    1965             : {
    1966           1 :   int retval;
    1967           1 :   time_t now = approx_time();
    1968           1 :   connection_t *base_conn = ENTRY_TO_CONN(conn);
    1969             : 
    1970             :   /* If .onion address requests are disabled, refuse the request */
    1971           1 :   if (!conn->entry_cfg.onion_traffic) {
    1972           0 :     log_warn(LD_APP, "Onion address %s requested from a port with .onion "
    1973             :              "disabled", safe_str_client(socks->address));
    1974           0 :     connection_mark_unattached_ap(conn, END_STREAM_REASON_ENTRYPOLICY);
    1975           0 :     return -1;
    1976             :   }
    1977             : 
    1978             :   /* Check whether it's RESOLVE or RESOLVE_PTR.  We don't handle those
    1979             :    * for hidden service addresses. */
    1980           1 :   if (SOCKS_COMMAND_IS_RESOLVE(socks->command)) {
    1981             :     /* if it's a resolve request, fail it right now, rather than
    1982             :      * building all the circuits and then realizing it won't work. */
    1983           0 :     log_warn(LD_APP,
    1984             :              "Resolve requests to hidden services not allowed. Failing.");
    1985           0 :     connection_ap_handshake_socks_resolved(conn,RESOLVED_TYPE_ERROR,
    1986             :                                            0,NULL,-1,TIME_MAX);
    1987           0 :     connection_mark_unattached_ap(conn,
    1988             :                                END_STREAM_REASON_SOCKSPROTOCOL |
    1989             :                                END_STREAM_REASON_FLAG_ALREADY_SOCKS_REPLIED);
    1990           0 :     return -1;
    1991             :   }
    1992             : 
    1993             :   /* If we were passed a circuit, then we need to fail.  .onion addresses
    1994             :    * only work when we launch our own circuits for now. */
    1995           1 :   if (circ) {
    1996           0 :     log_warn(LD_CONTROL, "Attachstream to a circuit is not "
    1997             :              "supported for .onion addresses currently. Failing.");
    1998           0 :     connection_mark_unattached_ap(conn, END_STREAM_REASON_TORPROTOCOL);
    1999           0 :     return -1;
    2000             :   }
    2001             : 
    2002           1 :   int descriptor_is_usable = 0;
    2003             : 
    2004             :   /* Create HS conn identifier with HS pubkey */
    2005           2 :   hs_ident_edge_conn_t *hs_conn_ident =
    2006           1 :     tor_malloc_zero(sizeof(hs_ident_edge_conn_t));
    2007             : 
    2008           1 :   retval = hs_parse_address(socks->address, &hs_conn_ident->identity_pk,
    2009             :                             NULL, NULL);
    2010           1 :   if (retval < 0) {
    2011           0 :     log_warn(LD_GENERAL, "failed to parse hs address");
    2012           0 :     tor_free(hs_conn_ident);
    2013           0 :     return -1;
    2014             :   }
    2015           1 :   ENTRY_TO_EDGE_CONN(conn)->hs_ident = hs_conn_ident;
    2016             : 
    2017             :   /* Check the v3 desc cache */
    2018           1 :   const hs_descriptor_t *cached_desc = NULL;
    2019           1 :   unsigned int refetch_desc = 0;
    2020           1 :   cached_desc = hs_cache_lookup_as_client(&hs_conn_ident->identity_pk);
    2021           1 :   if (cached_desc) {
    2022           0 :     descriptor_is_usable =
    2023           0 :       hs_client_any_intro_points_usable(&hs_conn_ident->identity_pk,
    2024             :                                         cached_desc);
    2025           0 :     log_info(LD_GENERAL, "Found %s descriptor in cache for %s. %s.",
    2026             :              (descriptor_is_usable) ? "usable" : "unusable",
    2027             :              safe_str_client(socks->address),
    2028             :              (descriptor_is_usable) ? "Not fetching." : "Refetching.");
    2029             :   } else {
    2030             :     /* We couldn't find this descriptor; we should look it up. */
    2031           1 :     log_info(LD_REND, "No descriptor found in our cache for %s. Fetching.",
    2032             :              safe_str_client(socks->address));
    2033           1 :     refetch_desc = 1;
    2034             :   }
    2035             : 
    2036             :   /* Help predict that we'll want to do hidden service circuits in the
    2037             :    * future. We're not sure if it will need a stable circuit yet, but
    2038             :    * we know we'll need *something*. */
    2039           1 :   rep_hist_note_used_internal(now, 0, 1);
    2040             : 
    2041             :   /* Now we have a descriptor but is it usable or not? If not, refetch.
    2042             :    * Also, a fetch could have been requested if the onion address was not
    2043             :    * found in the cache previously. */
    2044           1 :   if (refetch_desc || !descriptor_is_usable) {
    2045           1 :     edge_connection_t *edge_conn = ENTRY_TO_EDGE_CONN(conn);
    2046           1 :     connection_ap_mark_as_non_pending_circuit(conn);
    2047           1 :     base_conn->state = AP_CONN_STATE_RENDDESC_WAIT;
    2048           1 :     tor_assert(edge_conn->hs_ident);
    2049             :     /* Attempt to fetch the hsv3 descriptor. Check the retval to see how it
    2050             :      * went and act accordingly. */
    2051           1 :     int ret = hs_client_refetch_hsdesc(&edge_conn->hs_ident->identity_pk);
    2052           1 :     switch (ret) {
    2053             :     case HS_CLIENT_FETCH_MISSING_INFO:
    2054             :       /* Keeping the connection in descriptor wait state is fine because
    2055             :        * once we get enough dirinfo or a new live consensus, the HS client
    2056             :        * subsystem is notified and every connection in that state will
    2057             :        * trigger a fetch for the service key. */
    2058             :     case HS_CLIENT_FETCH_LAUNCHED:
    2059             :     case HS_CLIENT_FETCH_PENDING:
    2060             :     case HS_CLIENT_FETCH_HAVE_DESC:
    2061             :       return 0;
    2062           0 :     case HS_CLIENT_FETCH_ERROR:
    2063             :     case HS_CLIENT_FETCH_NO_HSDIRS:
    2064             :     case HS_CLIENT_FETCH_NOT_ALLOWED:
    2065             :       /* Can't proceed further and better close the SOCKS request. */
    2066           0 :       return -1;
    2067             :     }
    2068             :   }
    2069             : 
    2070             :   /* We have the descriptor!  So launch a connection to the HS. */
    2071           0 :   log_info(LD_REND, "Descriptor is here. Great.");
    2072             : 
    2073           0 :   base_conn->state = AP_CONN_STATE_CIRCUIT_WAIT;
    2074             :   /* We'll try to attach it at the next event loop, or whenever
    2075             :    * we call connection_ap_attach_pending() */
    2076           0 :   connection_ap_mark_as_pending_circuit(conn);
    2077           0 :   return 0;
    2078             : }
    2079             : 
    2080             : /** Connection <b>conn</b> just finished its socks handshake, or the
    2081             :  * controller asked us to take care of it. If <b>circ</b> is defined,
    2082             :  * then that's where we'll want to attach it. Otherwise we have to
    2083             :  * figure it out ourselves.
    2084             :  *
    2085             :  * First, parse whether it's a .exit address, remap it, and so on. Then
    2086             :  * if it's for a general circuit, try to attach it to a circuit (or launch
    2087             :  * one as needed), else if it's for a rendezvous circuit, fetch a
    2088             :  * rendezvous descriptor first (or attach/launch a circuit if the
    2089             :  * rendezvous descriptor is already here and fresh enough).
    2090             :  *
    2091             :  * The stream will exit from the hop
    2092             :  * indicated by <b>cpath</b>, or from the last hop in circ's cpath if
    2093             :  * <b>cpath</b> is NULL.
    2094             :  */
    2095             : int
    2096           1 : connection_ap_handshake_rewrite_and_attach(entry_connection_t *conn,
    2097             :                                            origin_circuit_t *circ,
    2098             :                                            crypt_path_t *cpath)
    2099             : {
    2100           1 :   socks_request_t *socks = conn->socks_request;
    2101           1 :   const or_options_t *options = get_options();
    2102           1 :   connection_t *base_conn = ENTRY_TO_CONN(conn);
    2103           1 :   time_t now = time(NULL);
    2104           1 :   rewrite_result_t rr;
    2105             : 
    2106             :   /* First we'll do the rewrite part.  Let's see if we get a reasonable
    2107             :    * answer.
    2108             :    */
    2109           1 :   memset(&rr, 0, sizeof(rr));
    2110           1 :   connection_ap_handshake_rewrite(conn,&rr);
    2111             : 
    2112           1 :   if (rr.should_close) {
    2113             :     /* connection_ap_handshake_rewrite told us to close the connection:
    2114             :      * either because it sent back an answer, or because it sent back an
    2115             :      * error */
    2116           0 :     connection_mark_unattached_ap(conn, rr.end_reason);
    2117           0 :     if (END_STREAM_REASON_DONE == (rr.end_reason & END_STREAM_REASON_MASK))
    2118             :       return 0;
    2119             :     else
    2120           0 :       return -1;
    2121             :   }
    2122             : 
    2123           1 :   const time_t map_expires = rr.map_expires;
    2124           1 :   const int automap = rr.automap;
    2125           1 :   const addressmap_entry_source_t exit_source = rr.exit_source;
    2126             : 
    2127             :   /* Now see whether the hostname is bogus.  This could happen because of an
    2128             :    * onion hostname whose format we don't recognize. */
    2129           1 :   hostname_type_t addresstype;
    2130           1 :   if (!parse_extended_hostname(socks->address, &addresstype)) {
    2131           0 :     control_event_client_status(LOG_WARN, "SOCKS_BAD_HOSTNAME HOSTNAME=%s",
    2132             :                                 escaped(socks->address));
    2133           0 :     if (addresstype == BAD_HOSTNAME) {
    2134           0 :       conn->socks_request->socks_extended_error_code = SOCKS5_HS_BAD_ADDRESS;
    2135             :     }
    2136           0 :     connection_mark_unattached_ap(conn, END_STREAM_REASON_TORPROTOCOL);
    2137           0 :     return -1;
    2138             :   }
    2139             : 
    2140             :   /* If this is a .exit hostname, strip off the .name.exit part, and
    2141             :    * see whether we're willing to connect there, and otherwise handle the
    2142             :    * .exit address.
    2143             :    *
    2144             :    * We'll set chosen_exit_name and/or close the connection as appropriate.
    2145             :    */
    2146           1 :   if (addresstype == EXIT_HOSTNAME) {
    2147             :     /* If StrictNodes is not set, then .exit overrides ExcludeNodes but
    2148             :      * not ExcludeExitNodes. */
    2149           0 :     routerset_t *excludeset = options->StrictNodes ?
    2150             :       options->ExcludeExitNodesUnion_ : options->ExcludeExitNodes;
    2151           0 :     const node_t *node = NULL;
    2152             : 
    2153             :     /* If this .exit was added by an AUTOMAP, then it came straight from
    2154             :      * a user.  That's not safe. */
    2155           0 :     if (exit_source == ADDRMAPSRC_AUTOMAP) {
    2156             :       /* Whoops; this one is stale.  It must have gotten added earlier?
    2157             :        * (Probably this is not possible, since AllowDotExit no longer
    2158             :        * exists.) */
    2159           0 :       log_warn(LD_APP,"Stale automapped address for '%s.exit'. Refusing.",
    2160             :                safe_str_client(socks->address));
    2161           0 :       control_event_client_status(LOG_WARN, "SOCKS_BAD_HOSTNAME HOSTNAME=%s",
    2162             :                                   escaped(socks->address));
    2163           0 :       connection_mark_unattached_ap(conn, END_STREAM_REASON_TORPROTOCOL);
    2164           0 :       tor_assert_nonfatal_unreached();
    2165           0 :       return -1;
    2166             :     }
    2167             : 
    2168             :     /* Double-check to make sure there are no .exits coming from
    2169             :      * impossible/weird sources. */
    2170           0 :     if (exit_source == ADDRMAPSRC_DNS || exit_source == ADDRMAPSRC_NONE) {
    2171             :       /* It shouldn't be possible to get a .exit address from any of these
    2172             :        * sources. */
    2173           0 :       log_warn(LD_BUG,"Address '%s.exit', with impossible source for the "
    2174             :                ".exit part. Refusing.",
    2175             :                safe_str_client(socks->address));
    2176           0 :       control_event_client_status(LOG_WARN, "SOCKS_BAD_HOSTNAME HOSTNAME=%s",
    2177             :                                   escaped(socks->address));
    2178           0 :       connection_mark_unattached_ap(conn, END_STREAM_REASON_TORPROTOCOL);
    2179           0 :       return -1;
    2180             :     }
    2181             : 
    2182           0 :     tor_assert(!automap);
    2183             : 
    2184             :     /* Now, find the character before the .(name) part.
    2185             :      * (The ".exit" part got stripped off by "parse_extended_hostname").
    2186             :      *
    2187             :      * We're going to put the exit name into conn->chosen_exit_name, and
    2188             :      * look up a node correspondingly. */
    2189           0 :     char *s = strrchr(socks->address,'.');
    2190           0 :     if (s) {
    2191             :       /* The address was of the form "(stuff).(name).exit */
    2192           0 :       if (s[1] != '\0') {
    2193             :         /* Looks like a real .exit one. */
    2194           0 :         conn->chosen_exit_name = tor_strdup(s+1);
    2195           0 :         node = node_get_by_nickname(conn->chosen_exit_name, 0);
    2196             : 
    2197           0 :         if (exit_source == ADDRMAPSRC_TRACKEXIT) {
    2198             :           /* We 5 tries before it expires the addressmap */
    2199           0 :           conn->chosen_exit_retries = TRACKHOSTEXITS_RETRIES;
    2200             :         }
    2201           0 :         *s = 0;
    2202             :       } else {
    2203             :         /* Oops, the address was (stuff)..exit.  That's not okay. */
    2204           0 :         log_warn(LD_APP,"Malformed exit address '%s.exit'. Refusing.",
    2205             :                  safe_str_client(socks->address));
    2206           0 :         control_event_client_status(LOG_WARN, "SOCKS_BAD_HOSTNAME HOSTNAME=%s",
    2207             :                                     escaped(socks->address));
    2208           0 :         connection_mark_unattached_ap(conn, END_STREAM_REASON_TORPROTOCOL);
    2209           0 :         return -1;
    2210             :       }
    2211             :     } else {
    2212             :       /* It looks like they just asked for "foo.exit".  That's a special
    2213             :        * form that means (foo's address).foo.exit. */
    2214             : 
    2215           0 :       conn->chosen_exit_name = tor_strdup(socks->address);
    2216           0 :       node = node_get_by_nickname(conn->chosen_exit_name, 0);
    2217           0 :       if (node) {
    2218           0 :         *socks->address = 0;
    2219           0 :         node_get_address_string(node, socks->address, sizeof(socks->address));
    2220             :       }
    2221             :     }
    2222             : 
    2223             :     /* Now make sure that the chosen exit exists... */
    2224           0 :     if (!node) {
    2225           0 :       log_warn(LD_APP,
    2226             :                "Unrecognized relay in exit address '%s.exit'. Refusing.",
    2227             :                safe_str_client(socks->address));
    2228           0 :       connection_mark_unattached_ap(conn, END_STREAM_REASON_TORPROTOCOL);
    2229           0 :       return -1;
    2230             :     }
    2231             :     /* ...and make sure that it isn't excluded. */
    2232           0 :     if (routerset_contains_node(excludeset, node)) {
    2233           0 :       log_warn(LD_APP,
    2234             :                "Excluded relay in exit address '%s.exit'. Refusing.",
    2235             :                safe_str_client(socks->address));
    2236           0 :       connection_mark_unattached_ap(conn, END_STREAM_REASON_TORPROTOCOL);
    2237           0 :       return -1;
    2238             :     }
    2239             :     /* XXXX-1090 Should we also allow foo.bar.exit if ExitNodes is set and
    2240             :        Bar is not listed in it?  I say yes, but our revised manpage branch
    2241             :        implies no. */
    2242             :   }
    2243             : 
    2244             :   /* Now, we handle everything that isn't a .onion address. */
    2245           1 :   if (addresstype != ONION_V3_HOSTNAME && addresstype != ONION_V2_HOSTNAME) {
    2246             :     /* Not a hidden-service request.  It's either a hostname or an IP,
    2247             :      * possibly with a .exit that we stripped off.  We're going to check
    2248             :      * if we're allowed to connect/resolve there, and then launch the
    2249             :      * appropriate request. */
    2250             : 
    2251             :     /* Check for funny characters in the address. */
    2252           0 :     if (address_is_invalid_destination(socks->address, 1)) {
    2253           0 :       control_event_client_status(LOG_WARN, "SOCKS_BAD_HOSTNAME HOSTNAME=%s",
    2254             :                                   escaped(socks->address));
    2255           0 :       log_warn(LD_APP,
    2256             :                "Destination '%s' seems to be an invalid hostname. Failing.",
    2257             :                safe_str_client(socks->address));
    2258           0 :       connection_mark_unattached_ap(conn, END_STREAM_REASON_TORPROTOCOL);
    2259           0 :       return -1;
    2260             :     }
    2261             : 
    2262             :     /* socks->address is a non-onion hostname or IP address.
    2263             :      * If we can't do any non-onion requests, refuse the connection.
    2264             :      * If we have a hostname but can't do DNS, refuse the connection.
    2265             :      * If we have an IP address, but we can't use that address family,
    2266             :      * refuse the connection.
    2267             :      *
    2268             :      * If we can do DNS requests, and we can use at least one address family,
    2269             :      * then we have to resolve the address first. Then we'll know if it
    2270             :      * resolves to a usable address family. */
    2271             : 
    2272             :     /* First, check if all non-onion traffic is disabled */
    2273           0 :     if (!conn->entry_cfg.dns_request && !conn->entry_cfg.ipv4_traffic
    2274           0 :         && !conn->entry_cfg.ipv6_traffic) {
    2275           0 :         log_warn(LD_APP, "Refusing to connect to non-hidden-service hostname "
    2276             :                  "or IP address %s because Port has OnionTrafficOnly set (or "
    2277             :                  "NoDNSRequest, NoIPv4Traffic, and NoIPv6Traffic).",
    2278             :                  safe_str_client(socks->address));
    2279           0 :         connection_mark_unattached_ap(conn, END_STREAM_REASON_ENTRYPOLICY);
    2280           0 :         return -1;
    2281             :     }
    2282             : 
    2283             :     /* Then check if we have a hostname or IP address, and whether DNS or
    2284             :      * the IP address family are permitted.  Reject if not. */
    2285           0 :     tor_addr_t dummy_addr;
    2286           0 :     int socks_family = tor_addr_parse(&dummy_addr, socks->address);
    2287             :     /* family will be -1 for a non-onion hostname that's not an IP */
    2288           0 :     if (socks_family == -1) {
    2289           0 :       if (!conn->entry_cfg.dns_request) {
    2290           0 :         log_warn(LD_APP, "Refusing to connect to hostname %s "
    2291             :                  "because Port has NoDNSRequest set.",
    2292             :                  safe_str_client(socks->address));
    2293           0 :         connection_mark_unattached_ap(conn, END_STREAM_REASON_ENTRYPOLICY);
    2294           0 :         return -1;
    2295             :       }
    2296           0 :     } else if (socks_family == AF_INET) {
    2297           0 :       if (!conn->entry_cfg.ipv4_traffic) {
    2298           0 :         log_warn(LD_APP, "Refusing to connect to IPv4 address %s because "
    2299             :                  "Port has NoIPv4Traffic set.",
    2300             :                  safe_str_client(socks->address));
    2301           0 :         connection_mark_unattached_ap(conn, END_STREAM_REASON_ENTRYPOLICY);
    2302           0 :         return -1;
    2303             :       }
    2304           0 :     } else if (socks_family == AF_INET6) {
    2305           0 :       if (!conn->entry_cfg.ipv6_traffic) {
    2306           0 :         log_warn(LD_APP, "Refusing to connect to IPv6 address %s because "
    2307             :                  "Port has NoIPv6Traffic set.",
    2308             :                  safe_str_client(socks->address));
    2309           0 :         connection_mark_unattached_ap(conn, END_STREAM_REASON_ENTRYPOLICY);
    2310           0 :         return -1;
    2311             :       }
    2312             :     } else {
    2313           0 :       tor_assert_nonfatal_unreached_once();
    2314             :     }
    2315             : 
    2316             :     /* See if this is a hostname lookup that we can answer immediately.
    2317             :      * (For example, an attempt to look up the IP address for an IP address.)
    2318             :      */
    2319           0 :     if (socks->command == SOCKS_COMMAND_RESOLVE) {
    2320           0 :       tor_addr_t answer;
    2321             :       /* Reply to resolves immediately if we can. */
    2322           0 :       if (tor_addr_parse(&answer, socks->address) >= 0) {/* is it an IP? */
    2323             :         /* remember _what_ is supposed to have been resolved. */
    2324           0 :         strlcpy(socks->address, rr.orig_address, sizeof(socks->address));
    2325           0 :         connection_ap_handshake_socks_resolved_addr(conn, &answer, -1,
    2326             :                                                     map_expires);
    2327           0 :         connection_mark_unattached_ap(conn,
    2328             :                                 END_STREAM_REASON_DONE |
    2329             :                                 END_STREAM_REASON_FLAG_ALREADY_SOCKS_REPLIED);
    2330           0 :         return 0;
    2331             :       }
    2332           0 :       tor_assert(!automap);
    2333           0 :       rep_hist_note_used_resolve(now); /* help predict this next time */
    2334           0 :     } else if (socks->command == SOCKS_COMMAND_CONNECT) {
    2335             :       /* Now see if this is a connect request that we can reject immediately */
    2336             : 
    2337           0 :       tor_assert(!automap);
    2338             :       /* Don't allow connections to port 0. */
    2339           0 :       if (socks->port == 0) {
    2340           0 :         log_notice(LD_APP,"Application asked to connect to port 0. Refusing.");
    2341           0 :         connection_mark_unattached_ap(conn, END_STREAM_REASON_TORPROTOCOL);
    2342           0 :         return -1;
    2343             :       }
    2344             :       /* You can't make connections to internal addresses, by default.
    2345             :        * Exceptions are begindir requests (where the address is meaningless),
    2346             :        * or cases where you've hand-configured a particular exit, thereby
    2347             :        * making the local address meaningful. */
    2348           0 :       if (options->ClientRejectInternalAddresses &&
    2349           0 :           !conn->use_begindir && !conn->chosen_exit_name && !circ) {
    2350             :         /* If we reach this point then we don't want to allow internal
    2351             :          * addresses.  Check if we got one. */
    2352           0 :         tor_addr_t addr;
    2353           0 :         if (tor_addr_hostname_is_local(socks->address) ||
    2354           0 :             (tor_addr_parse(&addr, socks->address) >= 0 &&
    2355           0 :              tor_addr_is_internal(&addr, 0))) {
    2356             :           /* If this is an explicit private address with no chosen exit node,
    2357             :            * then we really don't want to try to connect to it.  That's
    2358             :            * probably an error. */
    2359           0 :           if (conn->is_transparent_ap) {
    2360             : #define WARN_INTRVL_LOOP 300
    2361           0 :             static ratelim_t loop_warn_limit = RATELIM_INIT(WARN_INTRVL_LOOP);
    2362           0 :             char *m;
    2363           0 :             if ((m = rate_limit_log(&loop_warn_limit, approx_time()))) {
    2364           0 :               log_warn(LD_NET,
    2365             :                        "Rejecting request for anonymous connection to private "
    2366             :                        "address %s on a TransPort or NATDPort.  Possible loop "
    2367             :                        "in your NAT rules?%s", safe_str_client(socks->address),
    2368             :                        m);
    2369           0 :               tor_free(m);
    2370             :             }
    2371             :           } else {
    2372             : #define WARN_INTRVL_PRIV 300
    2373           0 :             static ratelim_t priv_warn_limit = RATELIM_INIT(WARN_INTRVL_PRIV);
    2374           0 :             char *m;
    2375           0 :             if ((m = rate_limit_log(&priv_warn_limit, approx_time()))) {
    2376           0 :               log_warn(LD_NET,
    2377             :                        "Rejecting SOCKS request for anonymous connection to "
    2378             :                        "private address %s.%s",
    2379             :                        safe_str_client(socks->address),m);
    2380           0 :               tor_free(m);
    2381             :             }
    2382             :           }
    2383           0 :           connection_mark_unattached_ap(conn, END_STREAM_REASON_PRIVATE_ADDR);
    2384           0 :           return -1;
    2385             :         }
    2386             :       } /* end "if we should check for internal addresses" */
    2387             : 
    2388             :       /* Okay.  We're still doing a CONNECT, and it wasn't a private
    2389             :        * address.  Here we do special handling for literal IP addresses,
    2390             :        * to see if we should reject this preemptively, and to set up
    2391             :        * fields in conn->entry_cfg to tell the exit what AF we want. */
    2392             :       {
    2393           0 :         tor_addr_t addr;
    2394             :         /* XXX Duplicate call to tor_addr_parse. */
    2395           0 :         if (tor_addr_parse(&addr, socks->address) >= 0) {
    2396             :           /* If we reach this point, it's an IPv4 or an IPv6 address. */
    2397           0 :           sa_family_t family = tor_addr_family(&addr);
    2398             : 
    2399           0 :           if ((family == AF_INET && ! conn->entry_cfg.ipv4_traffic) ||
    2400           0 :               (family == AF_INET6 && ! conn->entry_cfg.ipv6_traffic)) {
    2401             :             /* You can't do an IPv4 address on a v6-only socks listener,
    2402             :              * or vice versa. */
    2403           0 :             log_warn(LD_NET, "Rejecting SOCKS request for an IP address "
    2404             :                      "family that this listener does not support.");
    2405           0 :             connection_mark_unattached_ap(conn, END_STREAM_REASON_ENTRYPOLICY);
    2406           0 :             return -1;
    2407           0 :           } else if (family == AF_INET6 && socks->socks_version == 4) {
    2408             :             /* You can't make a socks4 request to an IPv6 address. Socks4
    2409             :              * doesn't support that. */
    2410           0 :             log_warn(LD_NET, "Rejecting SOCKS4 request for an IPv6 address.");
    2411           0 :             connection_mark_unattached_ap(conn, END_STREAM_REASON_ENTRYPOLICY);
    2412           0 :             return -1;
    2413           0 :           } else if (socks->socks_version == 4 &&
    2414           0 :                      !conn->entry_cfg.ipv4_traffic) {
    2415             :             /* You can't do any kind of Socks4 request when IPv4 is forbidden.
    2416             :              *
    2417             :              * XXX raise this check outside the enclosing block? */
    2418           0 :             log_warn(LD_NET, "Rejecting SOCKS4 request on a listener with "
    2419             :                      "no IPv4 traffic supported.");
    2420           0 :             connection_mark_unattached_ap(conn, END_STREAM_REASON_ENTRYPOLICY);
    2421           0 :             return -1;
    2422           0 :           } else if (family == AF_INET6) {
    2423             :             /* Tell the exit: we won't accept any ipv4 connection to an IPv6
    2424             :              * address. */
    2425           0 :             conn->entry_cfg.ipv4_traffic = 0;
    2426           0 :           } else if (family == AF_INET) {
    2427             :             /* Tell the exit: we won't accept any ipv6 connection to an IPv4
    2428             :              * address. */
    2429           0 :             conn->entry_cfg.ipv6_traffic = 0;
    2430             :           }
    2431             : 
    2432             :           /* Next, yet another check: we know it's a direct IP address. Is it
    2433             :            * the IP address of a known relay and its ORPort, or of a directory
    2434             :            * authority and its OR or Dir Port? If so, and if a consensus param
    2435             :            * says to, then exit relays will refuse this request (see ticket
    2436             :            * 2667 for details). Let's just refuse it locally right now, to
    2437             :            * save time and network load but also to give the user a more
    2438             :            * useful log message. */
    2439           0 :           if (!network_reentry_is_allowed() &&
    2440           0 :               nodelist_reentry_contains(&addr, socks->port)) {
    2441           0 :             log_warn(LD_APP, "Not attempting connection to %s:%d because "
    2442             :                      "the network would reject it. Are you trying to send "
    2443             :                      "Tor traffic over Tor? This traffic can be harmful to "
    2444             :                      "the Tor network. If you really need it, try using "
    2445             :                      "a bridge as a workaround.",
    2446             :                      safe_str_client(socks->address), socks->port);
    2447           0 :             connection_mark_unattached_ap(conn, END_STREAM_REASON_TORPROTOCOL);
    2448           0 :             return -1;
    2449             :           }
    2450             :         }
    2451             :       }
    2452             : 
    2453             :       /* we never allow IPv6 answers on socks4. (TODO: Is this smart?) */
    2454           0 :       if (socks->socks_version == 4)
    2455           0 :         conn->entry_cfg.ipv6_traffic = 0;
    2456             : 
    2457             :       /* Still handling CONNECT. Now, check for exit enclaves.  (Which we
    2458             :        * don't do on BEGIN_DIR, or when there is a chosen exit.)
    2459             :        *
    2460             :        * TODO: Should we remove this?  Exit enclaves are nutty and don't
    2461             :        * work very well
    2462             :        */
    2463           0 :       if (!conn->use_begindir && !conn->chosen_exit_name && !circ) {
    2464             :         /* see if we can find a suitable enclave exit */
    2465           0 :         const node_t *r =
    2466           0 :           router_find_exact_exit_enclave(socks->address, socks->port);
    2467           0 :         if (r) {
    2468           0 :           log_info(LD_APP,
    2469             :                    "Redirecting address %s to exit at enclave router %s",
    2470             :                    safe_str_client(socks->address), node_describe(r));
    2471             :           /* use the hex digest, not nickname, in case there are two
    2472             :              routers with this nickname */
    2473           0 :           conn->chosen_exit_name =
    2474           0 :             tor_strdup(hex_str(r->identity, DIGEST_LEN));
    2475           0 :           conn->chosen_exit_optional = 1;
    2476             :         }
    2477             :       }
    2478             : 
    2479             :       /* Still handling CONNECT: warn or reject if it's using a dangerous
    2480             :        * port. */
    2481           0 :       if (!conn->use_begindir && !conn->chosen_exit_name && !circ)
    2482           0 :         if (consider_plaintext_ports(conn, socks->port) < 0)
    2483             :           return -1;
    2484             : 
    2485             :       /* Remember the port so that we will predict that more requests
    2486             :          there will happen in the future. */
    2487           0 :       if (!conn->use_begindir) {
    2488             :         /* help predict this next time */
    2489           0 :         rep_hist_note_used_port(now, socks->port);
    2490             :       }
    2491           0 :     } else if (socks->command == SOCKS_COMMAND_RESOLVE_PTR) {
    2492           0 :       rep_hist_note_used_resolve(now); /* help predict this next time */
    2493             :       /* no extra processing needed */
    2494             :     } else {
    2495             :       /* We should only be doing CONNECT, RESOLVE, or RESOLVE_PTR! */
    2496           0 :       tor_fragile_assert();
    2497             :     }
    2498             : 
    2499             :     /* Okay. At this point we've set chosen_exit_name if needed, rewritten the
    2500             :      * address, and decided not to reject it for any number of reasons. Now
    2501             :      * mark the connection as waiting for a circuit, and try to attach it!
    2502             :      */
    2503           0 :     base_conn->state = AP_CONN_STATE_CIRCUIT_WAIT;
    2504             : 
    2505             :     /* If we were given a circuit to attach to, try to attach. Otherwise,
    2506             :      * try to find a good one and attach to that. */
    2507           0 :     int rv;
    2508           0 :     if (circ) {
    2509           0 :       rv = connection_ap_handshake_attach_chosen_circuit(conn, circ, cpath);
    2510             :     } else {
    2511             :       /* We'll try to attach it at the next event loop, or whenever
    2512             :        * we call connection_ap_attach_pending() */
    2513           0 :       connection_ap_mark_as_pending_circuit(conn);
    2514           0 :       rv = 0;
    2515             :     }
    2516             : 
    2517             :     /* If the above function returned 0 then we're waiting for a circuit.
    2518             :      * if it returned 1, we're attached.  Both are okay.  But if it returned
    2519             :      * -1, there was an error, so make sure the connection is marked, and
    2520             :      * return -1. */
    2521           0 :     if (rv < 0) {
    2522           0 :       if (!base_conn->marked_for_close)
    2523           0 :         connection_mark_unattached_ap(conn, END_STREAM_REASON_CANT_ATTACH);
    2524           0 :       return -1;
    2525             :     }
    2526             : 
    2527           0 :     return 0;
    2528             :   } else {
    2529             :     /* If we get here, it's a request for a .onion address! */
    2530             : 
    2531             :     /* We don't support v2 onions anymore. Log a warning and bail. */
    2532           1 :     if (addresstype == ONION_V2_HOSTNAME) {
    2533           0 :       log_warn(LD_PROTOCOL, "Tried to connect to a v2 onion address, but this "
    2534             :                "version of Tor no longer supports them. Please encourage the "
    2535             :                "site operator to upgrade. For more information see "
    2536             :                "https://blog.torproject.org/v2-deprecation-timeline.");
    2537           0 :       control_event_client_status(LOG_WARN, "SOCKS_BAD_HOSTNAME HOSTNAME=%s",
    2538             :                                   escaped(socks->address));
    2539           0 :       connection_mark_unattached_ap(conn, END_STREAM_REASON_TORPROTOCOL);
    2540           0 :       return -1;
    2541             :     }
    2542             : 
    2543           1 :     tor_assert(addresstype == ONION_V3_HOSTNAME);
    2544           1 :     tor_assert(!automap);
    2545           1 :     return connection_ap_handle_onion(conn, socks, circ);
    2546             :   }
    2547             : 
    2548             :   return 0; /* unreached but keeps the compiler happy */
    2549             : }
    2550             : 
    2551             : #ifdef TRANS_PF
    2552             : static int pf_socket = -1;
    2553             : int
    2554             : get_pf_socket(void)
    2555             : {
    2556             :   int pf;
    2557             :   /*  This should be opened before dropping privileges. */
    2558             :   if (pf_socket >= 0)
    2559             :     return pf_socket;
    2560             : 
    2561             : #if defined(OpenBSD)
    2562             :   /* only works on OpenBSD */
    2563             :   pf = tor_open_cloexec("/dev/pf", O_RDONLY, 0);
    2564             : #else
    2565             :   /* works on NetBSD and FreeBSD */
    2566             :   pf = tor_open_cloexec("/dev/pf", O_RDWR, 0);
    2567             : #endif /* defined(OpenBSD) */
    2568             : 
    2569             :   if (pf < 0) {
    2570             :     log_warn(LD_NET, "open(\"/dev/pf\") failed: %s", strerror(errno));
    2571             :     return -1;
    2572             :   }
    2573             : 
    2574             :   pf_socket = pf;
    2575             :   return pf_socket;
    2576             : }
    2577             : #endif /* defined(TRANS_PF) */
    2578             : 
    2579             : #if defined(TRANS_NETFILTER) || defined(TRANS_PF) || \
    2580             :   defined(TRANS_TPROXY)
    2581             : /** Try fill in the address of <b>req</b> from the socket configured
    2582             :  * with <b>conn</b>. */
    2583             : static int
    2584           0 : destination_from_socket(entry_connection_t *conn, socks_request_t *req)
    2585             : {
    2586           0 :   struct sockaddr_storage orig_dst;
    2587           0 :   socklen_t orig_dst_len = sizeof(orig_dst);
    2588           0 :   tor_addr_t addr;
    2589             : 
    2590             : #ifdef TRANS_TPROXY
    2591           0 :   if (get_options()->TransProxyType_parsed == TPT_TPROXY) {
    2592           0 :     if (getsockname(ENTRY_TO_CONN(conn)->s, (struct sockaddr*)&orig_dst,
    2593             :                     &orig_dst_len) < 0) {
    2594           0 :       int e = tor_socket_errno(ENTRY_TO_CONN(conn)->s);
    2595           0 :       log_warn(LD_NET, "getsockname() failed: %s", tor_socket_strerror(e));
    2596           0 :       return -1;
    2597             :     }
    2598           0 :     goto done;
    2599             :   }
    2600             : #endif /* defined(TRANS_TPROXY) */
    2601             : 
    2602             : #ifdef TRANS_NETFILTER
    2603           0 :   int rv = -1;
    2604           0 :   switch (ENTRY_TO_CONN(conn)->socket_family) {
    2605             : #ifdef TRANS_NETFILTER_IPV4
    2606           0 :     case AF_INET:
    2607           0 :       rv = getsockopt(ENTRY_TO_CONN(conn)->s, SOL_IP, SO_ORIGINAL_DST,
    2608             :                   (struct sockaddr*)&orig_dst, &orig_dst_len);
    2609           0 :       break;
    2610             : #endif /* defined(TRANS_NETFILTER_IPV4) */
    2611             : #ifdef TRANS_NETFILTER_IPV6
    2612           0 :     case AF_INET6:
    2613           0 :       rv = getsockopt(ENTRY_TO_CONN(conn)->s, SOL_IPV6, IP6T_SO_ORIGINAL_DST,
    2614             :                   (struct sockaddr*)&orig_dst, &orig_dst_len);
    2615           0 :       break;
    2616             : #endif /* defined(TRANS_NETFILTER_IPV6) */
    2617           0 :     default:
    2618           0 :       log_warn(LD_BUG, "Received transparent data from an unsupported "
    2619             :                        "socket family %d",
    2620             :                ENTRY_TO_CONN(conn)->socket_family);
    2621           0 :       return -1;
    2622             :   }
    2623           0 :   if (rv < 0) {
    2624           0 :     int e = tor_socket_errno(ENTRY_TO_CONN(conn)->s);
    2625           0 :     log_warn(LD_NET, "getsockopt() failed: %s", tor_socket_strerror(e));
    2626           0 :     return -1;
    2627             :   }
    2628           0 :   goto done;
    2629             : #elif defined(TRANS_PF)
    2630             :   if (getsockname(ENTRY_TO_CONN(conn)->s, (struct sockaddr*)&orig_dst,
    2631             :                   &orig_dst_len) < 0) {
    2632             :     int e = tor_socket_errno(ENTRY_TO_CONN(conn)->s);
    2633             :     log_warn(LD_NET, "getsockname() failed: %s", tor_socket_strerror(e));
    2634             :     return -1;
    2635             :   }
    2636             :   goto done;
    2637             : #else
    2638             :   (void)conn;
    2639             :   (void)req;
    2640             :   log_warn(LD_BUG, "Unable to determine destination from socket.");
    2641             :   return -1;
    2642             : #endif /* defined(TRANS_NETFILTER) || ... */
    2643             : 
    2644           0 :  done:
    2645           0 :   tor_addr_from_sockaddr(&addr, (struct sockaddr*)&orig_dst, &req->port);
    2646           0 :   tor_addr_to_str(req->address, &addr, sizeof(req->address), 1);
    2647             : 
    2648           0 :   return 0;
    2649             : }
    2650             : #endif /* defined(TRANS_NETFILTER) || defined(TRANS_PF) || ... */
    2651             : 
    2652             : #ifdef TRANS_PF
    2653             : static int
    2654             : destination_from_pf(entry_connection_t *conn, socks_request_t *req)
    2655             : {
    2656             :   struct sockaddr_storage proxy_addr;
    2657             :   socklen_t proxy_addr_len = sizeof(proxy_addr);
    2658             :   struct sockaddr *proxy_sa = (struct sockaddr*) &proxy_addr;
    2659             :   struct pfioc_natlook pnl;
    2660             :   tor_addr_t addr;
    2661             :   int pf = -1;
    2662             : 
    2663             :   if (getsockname(ENTRY_TO_CONN(conn)->s, (struct sockaddr*)&proxy_addr,
    2664             :                   &proxy_addr_len) < 0) {
    2665             :     int e = tor_socket_errno(ENTRY_TO_CONN(conn)->s);
    2666             :     log_warn(LD_NET, "getsockname() to determine transocks destination "
    2667             :              "failed: %s", tor_socket_strerror(e));
    2668             :     return -1;
    2669             :   }
    2670             : 
    2671             : #ifdef __FreeBSD__
    2672             :   if (get_options()->TransProxyType_parsed == TPT_IPFW) {
    2673             :     /* ipfw(8) is used and in this case getsockname returned the original
    2674             :        destination */
    2675             :     if (tor_addr_from_sockaddr(&addr, proxy_sa, &req->port) < 0) {
    2676             :       tor_fragile_assert();
    2677             :       return -1;
    2678             :     }
    2679             : 
    2680             :     tor_addr_to_str(req->address, &addr, sizeof(req->address), 0);
    2681             : 
    2682             :     return 0;
    2683             :   }
    2684             : #endif /* defined(__FreeBSD__) */
    2685             : 
    2686             :   memset(&pnl, 0, sizeof(pnl));
    2687             :   pnl.proto           = IPPROTO_TCP;
    2688             :   pnl.direction       = PF_OUT;
    2689             :   if (proxy_sa->sa_family == AF_INET) {
    2690             :     struct sockaddr_in *sin = (struct sockaddr_in *)proxy_sa;
    2691             :     pnl.af              = AF_INET;
    2692             :     pnl.saddr.v4.s_addr = tor_addr_to_ipv4n(&ENTRY_TO_CONN(conn)->addr);
    2693             :     pnl.sport           = htons(ENTRY_TO_CONN(conn)->port);
    2694             :     pnl.daddr.v4.s_addr = sin->sin_addr.s_addr;
    2695             :     pnl.dport           = sin->sin_port;
    2696             :   } else if (proxy_sa->sa_family == AF_INET6) {
    2697             :     struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)proxy_sa;
    2698             :     pnl.af = AF_INET6;
    2699             :     const struct in6_addr *dest_in6 =
    2700             :       tor_addr_to_in6(&ENTRY_TO_CONN(conn)->addr);
    2701             :     if (BUG(!dest_in6))
    2702             :       return -1;
    2703             :     memcpy(&pnl.saddr.v6, dest_in6, sizeof(struct in6_addr));
    2704             :     pnl.sport = htons(ENTRY_TO_CONN(conn)->port);
    2705             :     memcpy(&pnl.daddr.v6, &sin6->sin6_addr, sizeof(struct in6_addr));
    2706             :     pnl.dport = sin6->sin6_port;
    2707             :   } else {
    2708             :     log_warn(LD_NET, "getsockname() gave an unexpected address family (%d)",
    2709             :              (int)proxy_sa->sa_family);
    2710             :     return -1;
    2711             :   }
    2712             : 
    2713             :   pf = get_pf_socket();
    2714             :   if (pf<0)
    2715             :     return -1;
    2716             : 
    2717             :   if (ioctl(pf, DIOCNATLOOK, &pnl) < 0) {
    2718             :     log_warn(LD_NET, "ioctl(DIOCNATLOOK) failed: %s", strerror(errno));
    2719             :     return -1;
    2720             :   }
    2721             : 
    2722             :   if (pnl.af == AF_INET) {
    2723             :     tor_addr_from_ipv4n(&addr, pnl.rdaddr.v4.s_addr);
    2724             :   } else if (pnl.af == AF_INET6) {
    2725             :     tor_addr_from_in6(&addr, &pnl.rdaddr.v6);
    2726             :   } else {
    2727             :     tor_fragile_assert();
    2728             :     return -1;
    2729             :   }
    2730             : 
    2731             :   tor_addr_to_str(req->address, &addr, sizeof(req->address), 1);
    2732             :   req->port = ntohs(pnl.rdport);
    2733             : 
    2734             :   return 0;
    2735             : }
    2736             : #endif /* defined(TRANS_PF) */
    2737             : 
    2738             : /** Fetch the original destination address and port from a
    2739             :  * system-specific interface and put them into a
    2740             :  * socks_request_t as if they came from a socks request.
    2741             :  *
    2742             :  * Return -1 if an error prevents fetching the destination,
    2743             :  * else return 0.
    2744             :  */
    2745             : static int
    2746           0 : connection_ap_get_original_destination(entry_connection_t *conn,
    2747             :                                        socks_request_t *req)
    2748             : {
    2749             : #ifdef TRANS_NETFILTER
    2750           0 :   return destination_from_socket(conn, req);
    2751             : #elif defined(TRANS_PF)
    2752             :   const or_options_t *options = get_options();
    2753             : 
    2754             :   if (options->TransProxyType_parsed == TPT_PF_DIVERT)
    2755             :     return destination_from_socket(conn, req);
    2756             : 
    2757             :   if (options->TransProxyType_parsed == TPT_DEFAULT ||
    2758             :       options->TransProxyType_parsed == TPT_IPFW)
    2759             :     return destination_from_pf(conn, req);
    2760             : 
    2761             :   (void)conn;
    2762             :   (void)req;
    2763             :   log_warn(LD_BUG, "Proxy destination determination mechanism %s unknown.",
    2764             :            options->TransProxyType);
    2765             :   return -1;
    2766             : #else
    2767             :   (void)conn;
    2768             :   (void)req;
    2769             :   log_warn(LD_BUG, "Called connection_ap_get_original_destination, but no "
    2770             :            "transparent proxy method was configured.");
    2771             :   return -1;
    2772             : #endif /* defined(TRANS_NETFILTER) || ... */
    2773             : }
    2774             : 
    2775             : /** connection_edge_process_inbuf() found a conn in state
    2776             :  * socks_wait. See if conn->inbuf has the right bytes to proceed with
    2777             :  * the socks handshake.
    2778             :  *
    2779             :  * If the handshake is complete, send it to
    2780             :  * connection_ap_handshake_rewrite_and_attach().
    2781             :  *
    2782             :  * Return -1 if an unexpected error with conn occurs (and mark it for close),
    2783             :  * else return 0.
    2784             :  */
    2785             : static int
    2786           0 : connection_ap_handshake_process_socks(entry_connection_t *conn)
    2787             : {
    2788           0 :   socks_request_t *socks;
    2789           0 :   int sockshere;
    2790           0 :   const or_options_t *options = get_options();
    2791           0 :   int had_reply = 0;
    2792           0 :   connection_t *base_conn = ENTRY_TO_CONN(conn);
    2793             : 
    2794           0 :   tor_assert(conn);
    2795           0 :   tor_assert(base_conn->type == CONN_TYPE_AP);
    2796           0 :   tor_assert(base_conn->state == AP_CONN_STATE_SOCKS_WAIT);
    2797           0 :   tor_assert(conn->socks_request);
    2798           0 :   socks = conn->socks_request;
    2799             : 
    2800           0 :   log_debug(LD_APP,"entered.");
    2801             : 
    2802           0 :   sockshere = fetch_from_buf_socks(base_conn->inbuf, socks,
    2803           0 :                                    options->TestSocks, options->SafeSocks);
    2804             : 
    2805           0 :   if (socks->replylen) {
    2806           0 :     had_reply = 1;
    2807           0 :     connection_buf_add((const char*)socks->reply, socks->replylen,
    2808             :                             base_conn);
    2809           0 :     socks->replylen = 0;
    2810           0 :     if (sockshere == -1) {
    2811             :       /* An invalid request just got a reply, no additional
    2812             :        * one is necessary. */
    2813           0 :       socks->has_finished = 1;
    2814             :     }
    2815             :   }
    2816             : 
    2817           0 :   if (sockshere == 0) {
    2818           0 :     log_debug(LD_APP,"socks handshake not all here yet.");
    2819           0 :     return 0;
    2820           0 :   } else if (sockshere == -1) {
    2821           0 :     if (!had_reply) {
    2822           0 :       log_warn(LD_APP,"Fetching socks handshake failed. Closing.");
    2823           0 :       connection_ap_handshake_socks_reply(conn, NULL, 0,
    2824             :                                           END_STREAM_REASON_SOCKSPROTOCOL);
    2825             :     }
    2826           0 :     connection_mark_unattached_ap(conn,
    2827             :                               END_STREAM_REASON_SOCKSPROTOCOL |
    2828             :                               END_STREAM_REASON_FLAG_ALREADY_SOCKS_REPLIED);
    2829           0 :     return -1;
    2830             :   } /* else socks handshake is done, continue processing */
    2831             : 
    2832           0 :   if (SOCKS_COMMAND_IS_CONNECT(socks->command))
    2833           0 :     control_event_stream_status(conn, STREAM_EVENT_NEW, 0);
    2834             :   else
    2835           0 :     control_event_stream_status(conn, STREAM_EVENT_NEW_RESOLVE, 0);
    2836             : 
    2837           0 :   return connection_ap_rewrite_and_attach_if_allowed(conn, NULL, NULL);
    2838             : }
    2839             : 
    2840             : /** connection_init_accepted_conn() found a new trans AP conn.
    2841             :  * Get the original destination and send it to
    2842             :  * connection_ap_handshake_rewrite_and_attach().
    2843             :  *
    2844             :  * Return -1 if an unexpected error with conn (and it should be marked
    2845             :  * for close), else return 0.
    2846             :  */
    2847             : int
    2848           0 : connection_ap_process_transparent(entry_connection_t *conn)
    2849             : {
    2850           0 :   socks_request_t *socks;
    2851             : 
    2852           0 :   tor_assert(conn);
    2853           0 :   tor_assert(conn->socks_request);
    2854           0 :   socks = conn->socks_request;
    2855             : 
    2856             :   /* pretend that a socks handshake completed so we don't try to
    2857             :    * send a socks reply down a transparent conn */
    2858           0 :   socks->command = SOCKS_COMMAND_CONNECT;
    2859           0 :   socks->has_finished = 1;
    2860             : 
    2861           0 :   log_debug(LD_APP,"entered.");
    2862             : 
    2863           0 :   if (connection_ap_get_original_destination(conn, socks) < 0) {
    2864           0 :     log_warn(LD_APP,"Fetching original destination failed. Closing.");
    2865           0 :     connection_mark_unattached_ap(conn,
    2866             :                                END_STREAM_REASON_CANT_FETCH_ORIG_DEST);
    2867           0 :     return -1;
    2868             :   }
    2869             :   /* we have the original destination */
    2870             : 
    2871           0 :   control_event_stream_status(conn, STREAM_EVENT_NEW, 0);
    2872             : 
    2873           0 :   return connection_ap_rewrite_and_attach_if_allowed(conn, NULL, NULL);
    2874             : }
    2875             : 
    2876             : /** connection_edge_process_inbuf() found a conn in state natd_wait. See if
    2877             :  * conn-\>inbuf has the right bytes to proceed.  See FreeBSD's libalias(3) and
    2878             :  * ProxyEncodeTcpStream() in src/lib/libalias/alias_proxy.c for the encoding
    2879             :  * form of the original destination.
    2880             :  *
    2881             :  * If the original destination is complete, send it to
    2882             :  * connection_ap_handshake_rewrite_and_attach().
    2883             :  *
    2884             :  * Return -1 if an unexpected error with conn (and it should be marked
    2885             :  * for close), else return 0.
    2886             :  */
    2887             : static int
    2888           0 : connection_ap_process_natd(entry_connection_t *conn)
    2889             : {
    2890           0 :   char tmp_buf[36], *tbuf, *daddr;
    2891           0 :   size_t tlen = 30;
    2892           0 :   int err, port_ok;
    2893           0 :   socks_request_t *socks;
    2894             : 
    2895           0 :   tor_assert(conn);
    2896           0 :   tor_assert(ENTRY_TO_CONN(conn)->state == AP_CONN_STATE_NATD_WAIT);
    2897           0 :   tor_assert(conn->socks_request);
    2898           0 :   socks = conn->socks_request;
    2899             : 
    2900           0 :   log_debug(LD_APP,"entered.");
    2901             : 
    2902             :   /* look for LF-terminated "[DEST ip_addr port]"
    2903             :    * where ip_addr is a dotted-quad and port is in string form */
    2904           0 :   err = connection_buf_get_line(ENTRY_TO_CONN(conn), tmp_buf, &tlen);
    2905           0 :   if (err == 0)
    2906             :     return 0;
    2907           0 :   if (err < 0) {
    2908           0 :     log_warn(LD_APP,"NATD handshake failed (DEST too long). Closing");
    2909           0 :     connection_mark_unattached_ap(conn, END_STREAM_REASON_INVALID_NATD_DEST);
    2910           0 :     return -1;
    2911             :   }
    2912             : 
    2913           0 :   if (strcmpstart(tmp_buf, "[DEST ")) {
    2914           0 :     log_warn(LD_APP,"NATD handshake was ill-formed; closing. The client "
    2915             :              "said: %s",
    2916             :              escaped(tmp_buf));
    2917           0 :     connection_mark_unattached_ap(conn, END_STREAM_REASON_INVALID_NATD_DEST);
    2918           0 :     return -1;
    2919             :   }
    2920             : 
    2921           0 :   daddr = tbuf = &tmp_buf[0] + 6; /* after end of "[DEST " */
    2922           0 :   if (!(tbuf = strchr(tbuf, ' '))) {
    2923           0 :     log_warn(LD_APP,"NATD handshake was ill-formed; closing. The client "
    2924             :              "said: %s",
    2925             :              escaped(tmp_buf));
    2926           0 :     connection_mark_unattached_ap(conn, END_STREAM_REASON_INVALID_NATD_DEST);
    2927           0 :     return -1;
    2928             :   }
    2929           0 :   *tbuf++ = '\0';
    2930             : 
    2931             :   /* pretend that a socks handshake completed so we don't try to
    2932             :    * send a socks reply down a natd conn */
    2933           0 :   strlcpy(socks->address, daddr, sizeof(socks->address));
    2934           0 :   socks->port = (uint16_t)
    2935           0 :     tor_parse_long(tbuf, 10, 1, 65535, &port_ok, &daddr);
    2936           0 :   if (!port_ok) {
    2937           0 :     log_warn(LD_APP,"NATD handshake failed; port %s is ill-formed or out "
    2938             :              "of range.", escaped(tbuf));
    2939           0 :     connection_mark_unattached_ap(conn, END_STREAM_REASON_INVALID_NATD_DEST);
    2940           0 :     return -1;
    2941             :   }
    2942             : 
    2943           0 :   socks->command = SOCKS_COMMAND_CONNECT;
    2944           0 :   socks->has_finished = 1;
    2945             : 
    2946           0 :   control_event_stream_status(conn, STREAM_EVENT_NEW, 0);
    2947             : 
    2948           0 :   ENTRY_TO_CONN(conn)->state = AP_CONN_STATE_CIRCUIT_WAIT;
    2949             : 
    2950           0 :   return connection_ap_rewrite_and_attach_if_allowed(conn, NULL, NULL);
    2951             : }
    2952             : 
    2953             : static const char HTTP_CONNECT_IS_NOT_AN_HTTP_PROXY_MSG[] =
    2954             :   "HTTP/1.0 405 Method Not Allowed\r\n"
    2955             :   "Content-Type: text/html; charset=iso-8859-1\r\n\r\n"
    2956             :   "<html>\n"
    2957             :   "<head>\n"
    2958             :   "<title>This is an HTTP CONNECT tunnel, not a full HTTP Proxy</title>\n"
    2959             :   "</head>\n"
    2960             :   "<body>\n"
    2961             :   "<h1>This is an HTTP CONNECT tunnel, not an HTTP proxy.</h1>\n"
    2962             :   "<p>\n"
    2963             :   "It appears you have configured your web browser to use this Tor port as\n"
    2964             :   "an HTTP proxy.\n"
    2965             :   "</p><p>\n"
    2966             :   "This is not correct: This port is configured as a CONNECT tunnel, not\n"
    2967             :   "an HTTP proxy. Please configure your client accordingly.  You can also\n"
    2968             :   "use HTTPS; then the client should automatically use HTTP CONNECT."
    2969             :   "</p>\n"
    2970             :   "<p>\n"
    2971             :   "See <a href=\"https://www.torproject.org/documentation.html\">"
    2972             :   "https://www.torproject.org/documentation.html</a> for more "
    2973             :   "information.\n"
    2974             :   "</p>\n"
    2975             :   "</body>\n"
    2976             :   "</html>\n";
    2977             : 
    2978             : /** Called on an HTTP CONNECT entry connection when some bytes have arrived,
    2979             :  * but we have not yet received a full HTTP CONNECT request.  Try to parse an
    2980             :  * HTTP CONNECT request from the connection's inbuf.  On success, set up the
    2981             :  * connection's socks_request field and try to attach the connection.  On
    2982             :  * failure, send an HTTP reply, and mark the connection.
    2983             :  */
    2984             : STATIC int
    2985           0 : connection_ap_process_http_connect(entry_connection_t *conn)
    2986             : {
    2987           0 :   if (BUG(ENTRY_TO_CONN(conn)->state != AP_CONN_STATE_HTTP_CONNECT_WAIT))
    2988           0 :     return -1;
    2989             : 
    2990           0 :   char *headers = NULL, *body = NULL;
    2991           0 :   char *command = NULL, *addrport = NULL;
    2992           0 :   char *addr = NULL;
    2993           0 :   size_t bodylen = 0;
    2994             : 
    2995           0 :   const char *errmsg = NULL;
    2996           0 :   int rv = 0;
    2997             : 
    2998           0 :   const int http_status =
    2999           0 :     fetch_from_buf_http(ENTRY_TO_CONN(conn)->inbuf, &headers, 8192,
    3000             :                         &body, &bodylen, 1024, 0);
    3001           0 :   if (http_status < 0) {
    3002             :     /* Bad http status */
    3003           0 :     errmsg = "HTTP/1.0 400 Bad Request\r\n\r\n";
    3004           0 :     goto err;
    3005           0 :   } else if (http_status == 0) {
    3006             :     /* no HTTP request yet. */
    3007           0 :     goto done;
    3008             :   }
    3009             : 
    3010           0 :   const int cmd_status = parse_http_command(headers, &command, &addrport);
    3011           0 :   if (cmd_status < 0) {
    3012           0 :     errmsg = "HTTP/1.0 400 Bad Request\r\n\r\n";
    3013           0 :     goto err;
    3014             :   }
    3015           0 :   tor_assert(command);
    3016           0 :   tor_assert(addrport);
    3017           0 :   if (strcasecmp(command, "connect")) {
    3018           0 :     errmsg = HTTP_CONNECT_IS_NOT_AN_HTTP_PROXY_MSG;
    3019           0 :     goto err;
    3020             :   }
    3021             : 
    3022           0 :   tor_assert(conn->socks_request);
    3023           0 :   socks_request_t *socks = conn->socks_request;
    3024           0 :   uint16_t port;
    3025           0 :   if (tor_addr_port_split(LOG_WARN, addrport, &addr, &port) < 0) {
    3026           0 :     errmsg = "HTTP/1.0 400 Bad Request\r\n\r\n";
    3027           0 :     goto err;
    3028             :   }
    3029           0 :   if (strlen(addr) >= MAX_SOCKS_ADDR_LEN) {
    3030           0 :     errmsg = "HTTP/1.0 414 Request-URI Too Long\r\n\r\n";
    3031           0 :     goto err;
    3032             :   }
    3033             : 
    3034             :   /* Abuse the 'username' and 'password' fields here. They are already an
    3035             :   * abuse. */
    3036             :   {
    3037           0 :     char *authorization = http_get_header(headers, "Proxy-Authorization: ");
    3038           0 :     if (authorization) {
    3039           0 :       socks->username = authorization; // steal reference
    3040           0 :       socks->usernamelen = strlen(authorization);
    3041             :     }
    3042           0 :     char *isolation = http_get_header(headers, "X-Tor-Stream-Isolation: ");
    3043           0 :     if (isolation) {
    3044           0 :       socks->password = isolation; // steal reference
    3045           0 :       socks->passwordlen = strlen(isolation);
    3046             :     }
    3047             :   }
    3048             : 
    3049           0 :   socks->command = SOCKS_COMMAND_CONNECT;
    3050           0 :   socks->listener_type = CONN_TYPE_AP_HTTP_CONNECT_LISTENER;
    3051           0 :   strlcpy(socks->address, addr, sizeof(socks->address));
    3052           0 :   socks->port = port;
    3053             : 
    3054           0 :   control_event_stream_status(conn, STREAM_EVENT_NEW, 0);
    3055             : 
    3056           0 :   rv = connection_ap_rewrite_and_attach_if_allowed(conn, NULL, NULL);
    3057             : 
    3058             :   // XXXX send a "100 Continue" message?
    3059             : 
    3060           0 :   goto done;
    3061             : 
    3062           0 :  err:
    3063           0 :   if (BUG(errmsg == NULL))
    3064             :     errmsg = "HTTP/1.0 400 Bad Request\r\n\r\n";
    3065           0 :   log_info(LD_EDGE, "HTTP tunnel error: saying %s", escaped(errmsg));
    3066           0 :   connection_buf_add(errmsg, strlen(errmsg), ENTRY_TO_CONN(conn));
    3067             :   /* Mark it as "has_finished" so that we don't try to send an extra socks
    3068             :    * reply. */
    3069           0 :   conn->socks_request->has_finished = 1;
    3070           0 :   connection_mark_unattached_ap(conn,
    3071             :                                 END_STREAM_REASON_HTTPPROTOCOL|
    3072             :                                 END_STREAM_REASON_FLAG_ALREADY_SOCKS_REPLIED);
    3073             : 
    3074           0 :  done:
    3075           0 :   tor_free(headers);
    3076           0 :   tor_free(body);
    3077           0 :   tor_free(command);
    3078           0 :   tor_free(addrport);
    3079           0 :   tor_free(addr);
    3080           0 :   return rv;
    3081             : }
    3082             : 
    3083             : /** Iterate over the two bytes of stream_id until we get one that is not
    3084             :  * already in use; return it. Return 0 if can't get a unique stream_id.
    3085             :  */
    3086             : streamid_t
    3087       65567 : get_unique_stream_id_by_circ(origin_circuit_t *circ)
    3088             : {
    3089       65567 :   edge_connection_t *tmpconn;
    3090       65567 :   streamid_t test_stream_id;
    3091       65567 :   uint32_t attempts=0;
    3092             : 
    3093             :  again:
    3094      196640 :   test_stream_id = circ->next_stream_id++;
    3095      196640 :   if (++attempts > 1<<16) {
    3096             :     /* Make sure we don't loop forever if all stream_id's are used. */
    3097           2 :     log_warn(LD_APP,"No unused stream IDs. Failing.");
    3098           2 :     return 0;
    3099             :   }
    3100      196638 :   if (test_stream_id == 0)
    3101           3 :     goto again;
    3102      262169 :   for (tmpconn = circ->p_streams; tmpconn; tmpconn=tmpconn->next_stream)
    3103       65535 :     if (tmpconn->stream_id == test_stream_id)
    3104           1 :       goto again;
    3105             : 
    3106      196634 :   if (connection_half_edge_find_stream_id(circ->half_streams,
    3107             :                                            test_stream_id))
    3108      131069 :     goto again;
    3109             : 
    3110             :   return test_stream_id;
    3111             : }
    3112             : 
    3113             : /** Return true iff <b>conn</b> is linked to a circuit and configured to use
    3114             :  * an exit that supports optimistic data. */
    3115             : static int
    3116           0 : connection_ap_supports_optimistic_data(const entry_connection_t *conn)
    3117             : {
    3118           0 :   const edge_connection_t *edge_conn = ENTRY_TO_EDGE_CONN(conn);
    3119             :   /* We can only send optimistic data if we're connected to an open
    3120             :      general circuit. */
    3121           0 :   if (edge_conn->on_circuit == NULL ||
    3122           0 :       edge_conn->on_circuit->state != CIRCUIT_STATE_OPEN ||
    3123           0 :       (edge_conn->on_circuit->purpose != CIRCUIT_PURPOSE_C_GENERAL &&
    3124           0 :        edge_conn->on_circuit->purpose != CIRCUIT_PURPOSE_C_HSDIR_GET &&
    3125           0 :        edge_conn->on_circuit->purpose != CIRCUIT_PURPOSE_S_HSDIR_POST &&
    3126             :        edge_conn->on_circuit->purpose != CIRCUIT_PURPOSE_C_REND_JOINED))
    3127             :     return 0;
    3128             : 
    3129           0 :   return conn->may_use_optimistic_data;
    3130             : }
    3131             : 
    3132             : /** Return a bitmask of BEGIN_FLAG_* flags that we should transmit in the
    3133             :  * RELAY_BEGIN cell for <b>ap_conn</b>. */
    3134             : static uint32_t
    3135           0 : connection_ap_get_begincell_flags(entry_connection_t *ap_conn)
    3136             : {
    3137           0 :   edge_connection_t *edge_conn = ENTRY_TO_EDGE_CONN(ap_conn);
    3138           0 :   const node_t *exitnode = NULL;
    3139           0 :   const crypt_path_t *cpath_layer = edge_conn->cpath_layer;
    3140           0 :   uint32_t flags = 0;
    3141             : 
    3142             :   /* No flags for begindir */
    3143           0 :   if (ap_conn->use_begindir)
    3144             :     return 0;
    3145             : 
    3146             :   /* No flags for hidden services. */
    3147           0 :   if (edge_conn->on_circuit->purpose != CIRCUIT_PURPOSE_C_GENERAL)
    3148             :     return 0;
    3149             : 
    3150             :   /* If only IPv4 is supported, no flags */
    3151           0 :   if (ap_conn->entry_cfg.ipv4_traffic && !ap_conn->entry_cfg.ipv6_traffic)
    3152             :     return 0;
    3153             : 
    3154           0 :   if (! cpath_layer ||
    3155           0 :       ! cpath_layer->extend_info)
    3156             :     return 0;
    3157             : 
    3158           0 :   if (!ap_conn->entry_cfg.ipv4_traffic)
    3159           0 :     flags |= BEGIN_FLAG_IPV4_NOT_OK;
    3160             : 
    3161           0 :   exitnode = node_get_by_id(cpath_layer->extend_info->identity_digest);
    3162             : 
    3163           0 :   if (ap_conn->entry_cfg.ipv6_traffic && exitnode) {
    3164           0 :     tor_addr_t a;
    3165           0 :     tor_addr_make_null(&a, AF_INET6);
    3166           0 :     if (compare_tor_addr_to_node_policy(&a, ap_conn->socks_request->port,
    3167             :                                         exitnode)
    3168             :         != ADDR_POLICY_REJECTED) {
    3169             :       /* Only say "IPv6 OK" if the exit node supports IPv6. Otherwise there's
    3170             :        * no point. */
    3171           0 :       flags |= BEGIN_FLAG_IPV6_OK;
    3172             :     }
    3173             :   }
    3174             : 
    3175           0 :   if (flags == BEGIN_FLAG_IPV6_OK) {
    3176             :     /* When IPv4 and IPv6 are both allowed, consider whether to say we
    3177             :      * prefer IPv6.  Otherwise there's no point in declaring a preference */
    3178           0 :     if (ap_conn->entry_cfg.prefer_ipv6)
    3179           0 :       flags |= BEGIN_FLAG_IPV6_PREFERRED;
    3180             :   }
    3181             : 
    3182           0 :   if (flags == BEGIN_FLAG_IPV4_NOT_OK) {
    3183           0 :     log_warn(LD_EDGE, "I'm about to ask a node for a connection that I "
    3184             :              "am telling it to fulfil with neither IPv4 nor IPv6. That's "
    3185             :              "not going to work. Did you perhaps ask for an IPv6 address "
    3186             :              "on an IPv4Only port, or vice versa?");
    3187             :   }
    3188             : 
    3189             :   return flags;
    3190             : }
    3191             : 
    3192             : /** Write a relay begin cell, using destaddr and destport from ap_conn's
    3193             :  * socks_request field, and send it down circ.
    3194             :  *
    3195             :  * If ap_conn is broken, mark it for close and return -1. Else return 0.
    3196             :  */
    3197           0 : MOCK_IMPL(int,
    3198             : connection_ap_handshake_send_begin,(entry_connection_t *ap_conn))
    3199             : {
    3200           0 :   char payload[CELL_PAYLOAD_SIZE];
    3201           0 :   int payload_len;
    3202           0 :   int begin_type;
    3203           0 :   const or_options_t *options = get_options();
    3204           0 :   origin_circuit_t *circ;
    3205           0 :   edge_connection_t *edge_conn = ENTRY_TO_EDGE_CONN(ap_conn);
    3206           0 :   connection_t *base_conn = TO_CONN(edge_conn);
    3207           0 :   tor_assert(edge_conn->on_circuit);
    3208           0 :   circ = TO_ORIGIN_CIRCUIT(edge_conn->on_circuit);
    3209             : 
    3210           0 :   tor_assert(base_conn->type == CONN_TYPE_AP);
    3211           0 :   tor_assert(base_conn->state == AP_CONN_STATE_CIRCUIT_WAIT);
    3212           0 :   tor_assert(ap_conn->socks_request);
    3213           0 :   tor_assert(SOCKS_COMMAND_IS_CONNECT(ap_conn->socks_request->command));
    3214             : 
    3215           0 :   edge_conn->stream_id = get_unique_stream_id_by_circ(circ);
    3216           0 :   if (edge_conn->stream_id==0) {
    3217             :     /* XXXX+ Instead of closing this stream, we should make it get
    3218             :      * retried on another circuit. */
    3219           0 :     connection_mark_unattached_ap(ap_conn, END_STREAM_REASON_INTERNAL);
    3220             : 
    3221             :     /* Mark this circuit "unusable for new streams". */
    3222           0 :     mark_circuit_unusable_for_new_conns(circ);
    3223           0 :     return -1;
    3224             :   }
    3225             : 
    3226             :   /* Set up begin cell flags. */
    3227           0 :   edge_conn->begincell_flags = connection_ap_get_begincell_flags(ap_conn);
    3228             : 
    3229           0 :   tor_snprintf(payload,RELAY_PAYLOAD_SIZE, "%s:%d",
    3230           0 :                (circ->base_.purpose == CIRCUIT_PURPOSE_C_GENERAL ||
    3231             :                 circ->base_.purpose == CIRCUIT_PURPOSE_CONTROLLER) ?
    3232             :                  ap_conn->socks_request->address : "",
    3233           0 :                ap_conn->socks_request->port);
    3234           0 :   payload_len = (int)strlen(payload)+1;
    3235           0 :   if (payload_len <= RELAY_PAYLOAD_SIZE - 4 && edge_conn->begincell_flags) {
    3236           0 :     set_uint32(payload + payload_len, htonl(edge_conn->begincell_flags));
    3237           0 :     payload_len += 4;
    3238             :   }
    3239             : 
    3240           0 :   log_info(LD_APP,
    3241             :            "Sending relay cell %d on circ %u to begin stream %d.",
    3242             :            (int)ap_conn->use_begindir,
    3243             :            (unsigned)circ->base_.n_circ_id,
    3244             :            edge_conn->stream_id);
    3245             : 
    3246           0 :   begin_type = ap_conn->use_begindir ?
    3247           0 :                  RELAY_COMMAND_BEGIN_DIR : RELAY_COMMAND_BEGIN;
    3248             : 
    3249             :   /* Check that circuits are anonymised, based on their type. */
    3250           0 :   if (begin_type == RELAY_COMMAND_BEGIN) {
    3251             :     /* This connection is a standard OR connection.
    3252             :      * Make sure its path length is anonymous, or that we're in a
    3253             :      * non-anonymous mode. */
    3254           0 :     assert_circ_anonymity_ok(circ, options);
    3255           0 :   } else if (begin_type == RELAY_COMMAND_BEGIN_DIR) {
    3256             :     /* This connection is a begindir directory connection.
    3257             :      * Look at the linked directory connection to access the directory purpose.
    3258             :      * If a BEGINDIR connection is ever not linked, that's a bug. */
    3259           0 :     if (BUG(!base_conn->linked)) {
    3260           0 :       return -1;
    3261             :     }
    3262           0 :     connection_t *linked_dir_conn_base = base_conn->linked_conn;
    3263             :     /* If the linked connection has been unlinked by other code, we can't send
    3264             :      * a begin cell on it. */
    3265           0 :     if (!linked_dir_conn_base) {
    3266             :       return -1;
    3267             :     }
    3268             :     /* Sensitive directory connections must have an anonymous path length.
    3269             :      * Otherwise, directory connections are typically one-hop.
    3270             :      * This matches the earlier check for directory connection path anonymity
    3271             :      * in directory_initiate_request(). */
    3272           0 :     if (purpose_needs_anonymity(linked_dir_conn_base->purpose,
    3273           0 :                     TO_DIR_CONN(linked_dir_conn_base)->router_purpose,
    3274           0 :                     TO_DIR_CONN(linked_dir_conn_base)->requested_resource)) {
    3275           0 :       assert_circ_anonymity_ok(circ, options);
    3276             :     }
    3277             :   } else {
    3278             :     /* This code was written for the two connection types BEGIN and BEGIN_DIR
    3279             :      */
    3280             :     tor_assert_unreached();
    3281             :   }
    3282             : 
    3283           0 :   if (connection_edge_send_command(edge_conn, begin_type,
    3284             :                   begin_type == RELAY_COMMAND_BEGIN ? payload : NULL,
    3285             :                   begin_type == RELAY_COMMAND_BEGIN ? payload_len : 0) < 0)
    3286             :     return -1; /* circuit is closed, don't continue */
    3287             : 
    3288           0 :   edge_conn->package_window = STREAMWINDOW_START;
    3289           0 :   edge_conn->deliver_window = STREAMWINDOW_START;
    3290           0 :   base_conn->state = AP_CONN_STATE_CONNECT_WAIT;
    3291           0 :   log_info(LD_APP,"Address/port sent, ap socket "TOR_SOCKET_T_FORMAT
    3292             :            ", n_circ_id %u",
    3293             :            base_conn->s, (unsigned)circ->base_.n_circ_id);
    3294           0 :   control_event_stream_status(ap_conn, STREAM_EVENT_SENT_CONNECT, 0);
    3295             : 
    3296             :   /* If there's queued-up data, send it now */
    3297           0 :   if ((connection_get_inbuf_len(base_conn) ||
    3298           0 :        ap_conn->sending_optimistic_data) &&
    3299           0 :       connection_ap_supports_optimistic_data(ap_conn)) {
    3300           0 :     log_info(LD_APP, "Sending up to %ld + %ld bytes of queued-up data",
    3301             :              (long)connection_get_inbuf_len(base_conn),
    3302             :              ap_conn->sending_optimistic_data ?
    3303             :              (long)buf_datalen(ap_conn->sending_optimistic_data) : 0);
    3304           0 :     if (connection_edge_package_raw_inbuf(edge_conn, 1, NULL) < 0) {
    3305           0 :       connection_mark_for_close(base_conn);
    3306             :     }
    3307             :   }
    3308             : 
    3309             :   return 0;
    3310             : }
    3311             : 
    3312             : /** Write a relay resolve cell, using destaddr and destport from ap_conn's
    3313             :  * socks_request field, and send it down circ.
    3314             :  *
    3315             :  * If ap_conn is broken, mark it for close and return -1. Else return 0.
    3316             :  */
    3317             : int
    3318           0 : connection_ap_handshake_send_resolve(entry_connection_t *ap_conn)
    3319             : {
    3320           0 :   int payload_len, command;
    3321           0 :   const char *string_addr;
    3322           0 :   char inaddr_buf[REVERSE_LOOKUP_NAME_BUF_LEN];
    3323           0 :   origin_circuit_t *circ;
    3324           0 :   edge_connection_t *edge_conn = ENTRY_TO_EDGE_CONN(ap_conn);
    3325           0 :   connection_t *base_conn = TO_CONN(edge_conn);
    3326           0 :   tor_assert(edge_conn->on_circuit);
    3327           0 :   circ = TO_ORIGIN_CIRCUIT(edge_conn->on_circuit);
    3328             : 
    3329           0 :   tor_assert(base_conn->type == CONN_TYPE_AP);
    3330           0 :   tor_assert(base_conn->state == AP_CONN_STATE_CIRCUIT_WAIT);
    3331           0 :   tor_assert(ap_conn->socks_request);
    3332           0 :   tor_assert(circ->base_.purpose == CIRCUIT_PURPOSE_C_GENERAL);
    3333             : 
    3334           0 :   command = ap_conn->socks_request->command;
    3335           0 :   tor_assert(SOCKS_COMMAND_IS_RESOLVE(command));
    3336             : 
    3337           0 :   edge_conn->stream_id = get_unique_stream_id_by_circ(circ);
    3338           0 :   if (edge_conn->stream_id==0) {
    3339             :     /* XXXX+ Instead of closing this stream, we should make it get
    3340             :      * retried on another circuit. */
    3341           0 :     connection_mark_unattached_ap(ap_conn, END_STREAM_REASON_INTERNAL);
    3342             : 
    3343             :     /* Mark this circuit "unusable for new streams". */
    3344           0 :     mark_circuit_unusable_for_new_conns(circ);
    3345           0 :     return -1;
    3346             :   }
    3347             : 
    3348           0 :   if (command == SOCKS_COMMAND_RESOLVE) {
    3349           0 :     string_addr = ap_conn->socks_request->address;
    3350           0 :     payload_len = (int)strlen(string_addr)+1;
    3351             :   } else {
    3352             :     /* command == SOCKS_COMMAND_RESOLVE_PTR */
    3353           0 :     const char *a = ap_conn->socks_request->address;
    3354           0 :     tor_addr_t addr;
    3355           0 :     int r;
    3356             : 
    3357             :     /* We're doing a reverse lookup.  The input could be an IP address, or
    3358             :      * could be an .in-addr.arpa or .ip6.arpa address */
    3359           0 :     r = tor_addr_parse_PTR_name(&addr, a, AF_UNSPEC, 1);
    3360           0 :     if (r <= 0) {
    3361           0 :       log_warn(LD_APP, "Rejecting ill-formed reverse lookup of %s",
    3362             :                safe_str_client(a));
    3363           0 :       connection_mark_unattached_ap(ap_conn, END_STREAM_REASON_INTERNAL);
    3364           0 :       return -1;
    3365             :     }
    3366             : 
    3367           0 :     r = tor_addr_to_PTR_name(inaddr_buf, sizeof(inaddr_buf), &addr);
    3368           0 :     if (r < 0) {
    3369           0 :       log_warn(LD_BUG, "Couldn't generate reverse lookup hostname of %s",
    3370             :                safe_str_client(a));
    3371           0 :       connection_mark_unattached_ap(ap_conn, END_STREAM_REASON_INTERNAL);
    3372           0 :       return -1;
    3373             :     }
    3374             : 
    3375           0 :     string_addr = inaddr_buf;
    3376           0 :     payload_len = (int)strlen(inaddr_buf)+1;
    3377           0 :     tor_assert(payload_len <= (int)sizeof(inaddr_buf));
    3378             :   }
    3379             : 
    3380           0 :   log_debug(LD_APP,
    3381             :             "Sending relay cell to begin stream %d.", edge_conn->stream_id);
    3382             : 
    3383           0 :   if (connection_edge_send_command(edge_conn,
    3384             :                            RELAY_COMMAND_RESOLVE,
    3385             :                            string_addr, payload_len) < 0)
    3386             :     return -1; /* circuit is closed, don't continue */
    3387             : 
    3388           0 :   if (!base_conn->address) {
    3389             :     /* This might be unnecessary. XXXX */
    3390           0 :     base_conn->address = tor_addr_to_str_dup(&base_conn->addr);
    3391             :   }
    3392           0 :   base_conn->state = AP_CONN_STATE_RESOLVE_WAIT;
    3393           0 :   log_info(LD_APP,"Address sent for resolve, ap socket "TOR_SOCKET_T_FORMAT
    3394             :            ", n_circ_id %u",
    3395             :            base_conn->s, (unsigned)circ->base_.n_circ_id);
    3396           0 :   control_event_stream_status(ap_conn, STREAM_EVENT_SENT_RESOLVE, 0);
    3397           0 :   return 0;
    3398             : }
    3399             : 
    3400             : /** Make an AP connection_t linked to the connection_t <b>partner</b>. make a
    3401             :  * new linked connection pair, and attach one side to the conn, connection_add
    3402             :  * it, initialize it to circuit_wait, and call
    3403             :  * connection_ap_handshake_attach_circuit(conn) on it.
    3404             :  *
    3405             :  * Return the newly created end of the linked connection pair, or -1 if error.
    3406             :  */
    3407             : entry_connection_t *
    3408           0 : connection_ap_make_link(connection_t *partner,
    3409             :                         char *address, uint16_t port,
    3410             :                         const char *digest,
    3411             :                         int session_group, int isolation_flags,
    3412             :                         int use_begindir, int want_onehop)
    3413             : {
    3414           0 :   entry_connection_t *conn;
    3415           0 :   connection_t *base_conn;
    3416             : 
    3417           0 :   log_info(LD_APP,"Making internal %s tunnel to %s:%d ...",
    3418             :            want_onehop ? "direct" : "anonymized",
    3419             :            safe_str_client(address), port);
    3420             : 
    3421           0 :   conn = entry_connection_new(CONN_TYPE_AP, tor_addr_family(&partner->addr));
    3422           0 :   base_conn = ENTRY_TO_CONN(conn);
    3423           0 :   base_conn->linked = 1; /* so that we can add it safely below. */
    3424             : 
    3425             :   /* populate conn->socks_request */
    3426             : 
    3427             :   /* leave version at zero, so the socks_reply is empty */
    3428           0 :   conn->socks_request->socks_version = 0;
    3429           0 :   conn->socks_request->has_finished = 0; /* waiting for 'connected' */
    3430           0 :   strlcpy(conn->socks_request->address, address,
    3431             :           sizeof(conn->socks_request->address));
    3432           0 :   conn->socks_request->port = port;
    3433           0 :   conn->socks_request->command = SOCKS_COMMAND_CONNECT;
    3434           0 :   conn->want_onehop = want_onehop;
    3435           0 :   conn->use_begindir = use_begindir;
    3436           0 :   if (use_begindir) {
    3437           0 :     conn->chosen_exit_name = tor_malloc(HEX_DIGEST_LEN+2);
    3438           0 :     conn->chosen_exit_name[0] = '$';
    3439           0 :     tor_assert(digest);
    3440           0 :     base16_encode(conn->chosen_exit_name+1,HEX_DIGEST_LEN+1,
    3441             :                   digest, DIGEST_LEN);
    3442             :   }
    3443             : 
    3444             :   /* Populate isolation fields. */
    3445           0 :   conn->socks_request->listener_type = CONN_TYPE_DIR_LISTENER;
    3446           0 :   conn->original_dest_address = tor_strdup(address);
    3447           0 :   conn->entry_cfg.session_group = session_group;
    3448           0 :   conn->entry_cfg.isolation_flags = isolation_flags;
    3449             : 
    3450           0 :   base_conn->address = tor_strdup("(Tor_internal)");
    3451           0 :   tor_addr_make_unspec(&base_conn->addr);
    3452           0 :   base_conn->port = 0;
    3453             : 
    3454           0 :   connection_link_connections(partner, base_conn);
    3455             : 
    3456           0 :   if (connection_add(base_conn) < 0) { /* no space, forget it */
    3457           0 :     connection_free(base_conn);
    3458           0 :     return NULL;
    3459             :   }
    3460             : 
    3461           0 :   base_conn->state = AP_CONN_STATE_CIRCUIT_WAIT;
    3462             : 
    3463           0 :   control_event_stream_status(conn, STREAM_EVENT_NEW, 0);
    3464             : 
    3465             :   /* attaching to a dirty circuit is fine */
    3466           0 :   connection_ap_mark_as_pending_circuit(conn);
    3467           0 :   log_info(LD_APP,"... application connection created and linked.");
    3468           0 :   return conn;
    3469             : }
    3470             : 
    3471             : /** Notify any interested controller connections about a new hostname resolve
    3472             :  * or resolve error.  Takes the same arguments as does
    3473             :  * connection_ap_handshake_socks_resolved(). */
    3474             : static void
    3475           0 : tell_controller_about_resolved_result(entry_connection_t *conn,
    3476             :                                       int answer_type,
    3477             :                                       size_t answer_len,
    3478             :                                       const char *answer,
    3479             :                                       int ttl,
    3480             :                                       time_t expires)
    3481             : {
    3482           0 :   uint64_t stream_id = 0;
    3483             : 
    3484           0 :   if (BUG(!conn)) {
    3485           0 :     return;
    3486             :   }
    3487             : 
    3488           0 :   stream_id = ENTRY_TO_CONN(conn)->global_identifier;
    3489             : 
    3490           0 :   expires = time(NULL) + ttl;
    3491           0 :   if (answer_type == RESOLVED_TYPE_IPV4 && answer_len >= 4) {
    3492           0 :     char *cp = tor_dup_ip(ntohl(get_uint32(answer)));
    3493           0 :     if (cp)
    3494           0 :       control_event_address_mapped(conn->socks_request->address,
    3495             :                                    cp, expires, NULL, 0, stream_id);
    3496           0 :     tor_free(cp);
    3497           0 :   } else if (answer_type == RESOLVED_TYPE_HOSTNAME && answer_len < 256) {
    3498           0 :     char *cp = tor_strndup(answer, answer_len);
    3499           0 :     control_event_address_mapped(conn->socks_request->address,
    3500             :                                  cp, expires, NULL, 0, stream_id);
    3501           0 :     tor_free(cp);
    3502             :   } else {
    3503           0 :     control_event_address_mapped(conn->socks_request->address,
    3504           0 :                                  "<error>", time(NULL)+ttl,
    3505             :                                  "error=yes", 0, stream_id);
    3506             :   }
    3507             : }
    3508             : 
    3509             : /**
    3510             :  * As connection_ap_handshake_socks_resolved, but take a tor_addr_t to send
    3511             :  * as the answer.
    3512             :  */
    3513             : void
    3514           5 : connection_ap_handshake_socks_resolved_addr(entry_connection_t *conn,
    3515             :                                             const tor_addr_t *answer,
    3516             :                                             int ttl,
    3517             :                                             time_t expires)
    3518             : {
    3519           5 :   if (tor_addr_family(answer) == AF_INET) {
    3520           4 :     uint32_t a = tor_addr_to_ipv4n(answer); /* network order */
    3521           4 :     connection_ap_handshake_socks_resolved(conn,RESOLVED_TYPE_IPV4,4,
    3522             :                                            (uint8_t*)&a,
    3523             :                                            ttl, expires);
    3524           1 :   } else if (tor_addr_family(answer) == AF_INET6) {
    3525           1 :     const uint8_t *a = tor_addr_to_in6_addr8(answer);
    3526           1 :     connection_ap_handshake_socks_resolved(conn,RESOLVED_TYPE_IPV6,16,
    3527             :                                            a,
    3528             :                                            ttl, expires);
    3529             :   } else {
    3530           0 :     log_warn(LD_BUG, "Got called with address of unexpected family %d",
    3531             :              tor_addr_family(answer));
    3532           0 :     connection_ap_handshake_socks_resolved(conn,
    3533             :                                            RESOLVED_TYPE_ERROR,0,NULL,-1,-1);
    3534             :   }
    3535           5 : }
    3536             : 
    3537             : /** Send an answer to an AP connection that has requested a DNS lookup via
    3538             :  * SOCKS.  The type should be one of RESOLVED_TYPE_(IPV4|IPV6|HOSTNAME) or -1
    3539             :  * for unreachable; the answer should be in the format specified in the socks
    3540             :  * extensions document.  <b>ttl</b> is the ttl for the answer, or -1 on
    3541             :  * certain errors or for values that didn't come via DNS.  <b>expires</b> is
    3542             :  * a time when the answer expires, or -1 or TIME_MAX if there's a good TTL.
    3543             :  **/
    3544             : /* XXXX the use of the ttl and expires fields is nutty.  Let's make this
    3545             :  * interface and those that use it less ugly. */
    3546           2 : MOCK_IMPL(void,
    3547             : connection_ap_handshake_socks_resolved,(entry_connection_t *conn,
    3548             :                                        int answer_type,
    3549             :                                        size_t answer_len,
    3550             :                                        const uint8_t *answer,
    3551             :                                        int ttl,
    3552             :                                        time_t expires))
    3553             : {
    3554           2 :   char buf[384];
    3555           2 :   size_t replylen;
    3556             : 
    3557           2 :   if (ttl >= 0) {
    3558           1 :     if (answer_type == RESOLVED_TYPE_IPV4 && answer_len == 4) {
    3559           1 :       tor_addr_t a;
    3560           1 :       tor_addr_from_ipv4n(&a, get_uint32(answer));
    3561           1 :       if (! tor_addr_is_null(&a)) {
    3562           1 :         client_dns_set_addressmap(conn,
    3563           1 :                                   conn->socks_request->address, &a,
    3564           1 :                                   conn->chosen_exit_name, ttl);
    3565             :       }
    3566           0 :     } else if (answer_type == RESOLVED_TYPE_IPV6 && answer_len == 16) {
    3567           0 :       tor_addr_t a;
    3568           0 :       tor_addr_from_ipv6_bytes(&a, answer);
    3569           0 :       if (! tor_addr_is_null(&a)) {
    3570           0 :         client_dns_set_addressmap(conn,
    3571           0 :                                   conn->socks_request->address, &a,
    3572           0 :                                   conn->chosen_exit_name, ttl);
    3573             :       }
    3574           0 :     } else if (answer_type == RESOLVED_TYPE_HOSTNAME && answer_len < 256) {
    3575           0 :       char *cp = tor_strndup((char*)answer, answer_len);
    3576           0 :       client_dns_set_reverse_addressmap(conn,
    3577           0 :                                         conn->socks_request->address,
    3578             :                                         cp,
    3579           0 :                                         conn->chosen_exit_name, ttl);
    3580           0 :       tor_free(cp);
    3581             :     }
    3582             :   }
    3583             : 
    3584           2 :   if (ENTRY_TO_EDGE_CONN(conn)->is_dns_request) {
    3585           0 :     if (conn->dns_server_request) {
    3586             :       /* We had a request on our DNS port: answer it. */
    3587           0 :       dnsserv_resolved(conn, answer_type, answer_len, (char*)answer, ttl);
    3588           0 :       conn->socks_request->has_finished = 1;
    3589           2 :       return;
    3590             :     } else {
    3591             :       /* This must be a request from the controller. Since answers to those
    3592             :        * requests are not cached, they do not generate an ADDRMAP event on
    3593             :        * their own. */
    3594           0 :       tell_controller_about_resolved_result(conn, answer_type, answer_len,
    3595             :                                             (char*)answer, ttl, expires);
    3596           0 :       conn->socks_request->has_finished = 1;
    3597           0 :       return;
    3598             :     }
    3599             :     /* We shouldn't need to free conn here; it gets marked by the caller. */
    3600             :   }
    3601             : 
    3602           2 :   if (conn->socks_request->socks_version == 4) {
    3603           0 :     buf[0] = 0x00; /* version */
    3604           0 :     if (answer_type == RESOLVED_TYPE_IPV4 && answer_len == 4) {
    3605           0 :       buf[1] = SOCKS4_GRANTED;
    3606           0 :       set_uint16(buf+2, 0);
    3607           0 :       memcpy(buf+4, answer, 4); /* address */
    3608           0 :       replylen = SOCKS4_NETWORK_LEN;
    3609             :     } else { /* "error" */
    3610           0 :       buf[1] = SOCKS4_REJECT;
    3611           0 :       memset(buf+2, 0, 6);
    3612           0 :       replylen = SOCKS4_NETWORK_LEN;
    3613             :     }
    3614           2 :   } else if (conn->socks_request->socks_version == 5) {
    3615             :     /* SOCKS5 */
    3616           0 :     buf[0] = 0x05; /* version */
    3617           0 :     if (answer_type == RESOLVED_TYPE_IPV4 && answer_len == 4) {
    3618           0 :       buf[1] = SOCKS5_SUCCEEDED;
    3619           0 :       buf[2] = 0; /* reserved */
    3620           0 :       buf[3] = 0x01; /* IPv4 address type */
    3621           0 :       memcpy(buf+4, answer, 4); /* address */
    3622           0 :       set_uint16(buf+8, 0); /* port == 0. */
    3623           0 :       replylen = 10;
    3624           0 :     } else if (answer_type == RESOLVED_TYPE_IPV6 && answer_len == 16) {
    3625           0 :       buf[1] = SOCKS5_SUCCEEDED;
    3626           0 :       buf[2] = 0; /* reserved */
    3627           0 :       buf[3] = 0x04; /* IPv6 address type */
    3628           0 :       memcpy(buf+4, answer, 16); /* address */
    3629           0 :       set_uint16(buf+20, 0); /* port == 0. */
    3630           0 :       replylen = 22;
    3631           0 :     } else if (answer_type == RESOLVED_TYPE_HOSTNAME && answer_len < 256) {
    3632           0 :       buf[1] = SOCKS5_SUCCEEDED;
    3633           0 :       buf[2] = 0; /* reserved */
    3634           0 :       buf[3] = 0x03; /* Domainname address type */
    3635           0 :       buf[4] = (char)answer_len;
    3636           0 :       memcpy(buf+5, answer, answer_len); /* address */
    3637           0 :       set_uint16(buf+5+answer_len, 0); /* port == 0. */
    3638           0 :       replylen = 5+answer_len+2;
    3639             :     } else {
    3640           0 :       buf[1] = SOCKS5_HOST_UNREACHABLE;
    3641           0 :       memset(buf+2, 0, 8);
    3642           0 :       replylen = 10;
    3643             :     }
    3644             :   } else {
    3645             :     /* no socks version info; don't send anything back */
    3646             :     return;
    3647             :   }
    3648           0 :   connection_ap_handshake_socks_reply(conn, buf, replylen,
    3649           0 :           (answer_type == RESOLVED_TYPE_IPV4 ||
    3650           0 :            answer_type == RESOLVED_TYPE_IPV6 ||
    3651             :            answer_type == RESOLVED_TYPE_HOSTNAME) ?
    3652             :                                       0 : END_STREAM_REASON_RESOLVEFAILED);
    3653             : }
    3654             : 
    3655             : /** Send a socks reply to stream <b>conn</b>, using the appropriate
    3656             :  * socks version, etc, and mark <b>conn</b> as completed with SOCKS
    3657             :  * handshaking.
    3658             :  *
    3659             :  * If <b>reply</b> is defined, then write <b>replylen</b> bytes of it to conn
    3660             :  * and return, else reply based on <b>endreason</b> (one of
    3661             :  * END_STREAM_REASON_*). If <b>reply</b> is undefined, <b>endreason</b> can't
    3662             :  * be 0 or REASON_DONE.  Send endreason to the controller, if appropriate.
    3663             :  */
    3664             : void
    3665           1 : connection_ap_handshake_socks_reply(entry_connection_t *conn, char *reply,
    3666             :                                     size_t replylen, int endreason)
    3667             : {
    3668           1 :   char buf[256];
    3669           1 :   socks5_reply_status_t status;
    3670             : 
    3671           1 :   tor_assert(conn->socks_request); /* make sure it's an AP stream */
    3672             : 
    3673           1 :   if (conn->socks_request->socks_use_extended_errors &&
    3674           0 :       conn->socks_request->socks_extended_error_code != 0) {
    3675             :     status = conn->socks_request->socks_extended_error_code;
    3676             :   } else {
    3677           1 :     status = stream_end_reason_to_socks5_response(endreason);
    3678             :   }
    3679             : 
    3680           1 :   if (!SOCKS_COMMAND_IS_RESOLVE(conn->socks_request->command)) {
    3681           1 :     control_event_stream_status(conn, status==SOCKS5_SUCCEEDED ?
    3682             :                                 STREAM_EVENT_SUCCEEDED : STREAM_EVENT_FAILED,
    3683             :                                 endreason);
    3684             :   }
    3685             : 
    3686             :   /* Flag this stream's circuit as having completed a stream successfully
    3687             :    * (for path bias) */
    3688           1 :   if (status == SOCKS5_SUCCEEDED ||
    3689           1 :       endreason == END_STREAM_REASON_RESOLVEFAILED ||
    3690           0 :       endreason == END_STREAM_REASON_CONNECTREFUSED ||
    3691           0 :       endreason == END_STREAM_REASON_CONNRESET ||
    3692             :       endreason == END_STREAM_REASON_NOROUTE ||
    3693             :       endreason == END_STREAM_REASON_RESOURCELIMIT) {
    3694           1 :     if (!conn->edge_.on_circuit ||
    3695           1 :        !CIRCUIT_IS_ORIGIN(conn->edge_.on_circuit)) {
    3696           0 :       if (endreason != END_STREAM_REASON_RESOLVEFAILED) {
    3697           0 :         log_info(LD_BUG,
    3698             :                  "No origin circuit for successful SOCKS stream %"PRIu64
    3699             :                  ". Reason: %d",
    3700             :                  (ENTRY_TO_CONN(conn)->global_identifier),
    3701             :                  endreason);
    3702             :       }
    3703             :       /*
    3704             :        * Else DNS remaps and failed hidden service lookups can send us
    3705             :        * here with END_STREAM_REASON_RESOLVEFAILED; ignore it
    3706             :        *
    3707             :        * Perhaps we could make the test more precise; we can tell hidden
    3708             :        * services by conn->edge_.renddata != NULL; anything analogous for
    3709             :        * the DNS remap case?
    3710             :        */
    3711             :     } else {
    3712             :       // XXX: Hrmm. It looks like optimistic data can't go through this
    3713             :       // codepath, but someone should probably test it and make sure.
    3714             :       // We don't want to mark optimistically opened streams as successful.
    3715           1 :       pathbias_mark_use_success(TO_ORIGIN_CIRCUIT(conn->edge_.on_circuit));
    3716             :     }
    3717             :   }
    3718             : 
    3719           1 :   if (conn->socks_request->has_finished) {
    3720           0 :     log_warn(LD_BUG, "(Harmless.) duplicate calls to "
    3721             :              "connection_ap_handshake_socks_reply.");
    3722           0 :     return;
    3723             :   }
    3724           1 :   if (replylen) { /* we already have a reply in mind */
    3725           0 :     connection_buf_add(reply, replylen, ENTRY_TO_CONN(conn));
    3726           0 :     conn->socks_request->has_finished = 1;
    3727           0 :     return;
    3728             :   }
    3729           1 :   if (conn->socks_request->listener_type ==
    3730             :        CONN_TYPE_AP_HTTP_CONNECT_LISTENER) {
    3731           0 :     const char *response = end_reason_to_http_connect_response_line(endreason);
    3732           0 :     if (!response) {
    3733           0 :       response = "HTTP/1.0 400 Bad Request\r\n\r\n";
    3734             :     }
    3735           0 :     connection_buf_add(response, strlen(response), ENTRY_TO_CONN(conn));
    3736           1 :   } else if (conn->socks_request->socks_version == 4) {
    3737           0 :     memset(buf,0,SOCKS4_NETWORK_LEN);
    3738           0 :     buf[1] = (status==SOCKS5_SUCCEEDED ? SOCKS4_GRANTED : SOCKS4_REJECT);
    3739             :     /* leave version, destport, destip zero */
    3740           0 :     connection_buf_add(buf, SOCKS4_NETWORK_LEN, ENTRY_TO_CONN(conn));
    3741           1 :   } else if (conn->socks_request->socks_version == 5) {
    3742           0 :     size_t buf_len;
    3743           0 :     memset(buf,0,sizeof(buf));
    3744           0 :     if (tor_addr_family(&conn->edge_.base_.addr) == AF_INET) {
    3745           0 :       buf[0] = 5; /* version 5 */
    3746           0 :       buf[1] = (char)status;
    3747           0 :       buf[2] = 0;
    3748           0 :       buf[3] = 1; /* ipv4 addr */
    3749             :       /* 4 bytes for the header, 2 bytes for the port, 4 for the address. */
    3750           0 :       buf_len = 10;
    3751             :     } else { /* AF_INET6. */
    3752           0 :       buf[0] = 5; /* version 5 */
    3753           0 :       buf[1] = (char)status;
    3754           0 :       buf[2] = 0;
    3755           0 :       buf[3] = 4; /* ipv6 addr */
    3756             :       /* 4 bytes for the header, 2 bytes for the port, 16 for the address. */
    3757           0 :       buf_len = 22;
    3758             :     }
    3759           0 :     connection_buf_add(buf,buf_len,ENTRY_TO_CONN(conn));
    3760             :   }
    3761             :   /* If socks_version isn't 4 or 5, don't send anything.
    3762             :    * This can happen in the case of AP bridges. */
    3763           1 :   conn->socks_request->has_finished = 1;
    3764           1 :   return;
    3765             : }
    3766             : 
    3767             : /** Read a RELAY_BEGIN or RELAY_BEGIN_DIR cell from <b>cell</b>, decode it, and
    3768             :  * place the result in <b>bcell</b>.  On success return 0; on failure return
    3769             :  * <0 and set *<b>end_reason_out</b> to the end reason we should send back to
    3770             :  * the client.
    3771             :  *
    3772             :  * Return -1 in the case where we want to send a RELAY_END cell, and < -1 when
    3773             :  * we don't.
    3774             :  **/
    3775             : STATIC int
    3776          17 : begin_cell_parse(const cell_t *cell, begin_cell_t *bcell,
    3777             :                  uint8_t *end_reason_out)
    3778             : {
    3779          17 :   relay_header_t rh;
    3780          17 :   const uint8_t *body, *nul;
    3781             : 
    3782          17 :   memset(bcell, 0, sizeof(*bcell));
    3783          17 :   *end_reason_out = END_STREAM_REASON_MISC;
    3784             : 
    3785          17 :   relay_header_unpack(&rh, cell->payload);
    3786          17 :   if (rh.length > RELAY_PAYLOAD_SIZE) {
    3787             :     return -2; /*XXXX why not TORPROTOCOL? */
    3788             :   }
    3789             : 
    3790          16 :   bcell->stream_id = rh.stream_id;
    3791             : 
    3792          16 :   if (rh.command == RELAY_COMMAND_BEGIN_DIR) {
    3793           2 :     bcell->is_begindir = 1;
    3794           2 :     return 0;
    3795          14 :   } else if (rh.command != RELAY_COMMAND_BEGIN) {
    3796           0 :     log_warn(LD_BUG, "Got an unexpected command %d", (int)rh.command);
    3797           0 :     *end_reason_out = END_STREAM_REASON_INTERNAL;
    3798           0 :     return -1;
    3799             :   }
    3800             : 
    3801          14 :   body = cell->payload + RELAY_HEADER_SIZE;
    3802          14 :   nul = memchr(body, 0, rh.length);
    3803          14 :   if (! nul) {
    3804           3 :     log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL,
    3805             :            "Relay begin cell has no \\0. Closing.");
    3806           3 :     *end_reason_out = END_STREAM_REASON_TORPROTOCOL;
    3807           3 :     return -1;
    3808             :   }
    3809             : 
    3810          11 :   if (tor_addr_port_split(LOG_PROTOCOL_WARN,
    3811             :                           (char*)(body),
    3812             :                           &bcell->address,&bcell->port)<0) {
    3813           3 :     log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL,
    3814             :            "Unable to parse addr:port in relay begin cell. Closing.");
    3815           3 :     *end_reason_out = END_STREAM_REASON_TORPROTOCOL;
    3816           3 :     return -1;
    3817             :   }
    3818           8 :   if (bcell->port == 0) {
    3819           1 :     log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL,
    3820             :            "Missing port in relay begin cell. Closing.");
    3821           1 :     tor_free(bcell->address);
    3822           1 :     *end_reason_out = END_STREAM_REASON_TORPROTOCOL;
    3823           1 :     return -1;
    3824             :   }
    3825           7 :   if (body + rh.length >= nul + 4)
    3826           2 :     bcell->flags = ntohl(get_uint32(nul+1));
    3827             : 
    3828             :   return 0;
    3829             : }
    3830             : 
    3831             : /** For the given <b>circ</b> and the edge connection <b>conn</b>, setup the
    3832             :  * connection, attach it to the circ and connect it. Return 0 on success
    3833             :  * or END_CIRC_AT_ORIGIN if we can't find the requested hidden service port
    3834             :  * where the caller should close the circuit. */
    3835             : static int
    3836           0 : handle_hs_exit_conn(circuit_t *circ, edge_connection_t *conn)
    3837             : {
    3838           0 :   int ret;
    3839           0 :   origin_circuit_t *origin_circ;
    3840             : 
    3841           0 :   assert_circuit_ok(circ);
    3842           0 :   tor_assert(circ->purpose == CIRCUIT_PURPOSE_S_REND_JOINED);
    3843           0 :   tor_assert(conn);
    3844             : 
    3845           0 :   log_debug(LD_REND, "Connecting the hidden service rendezvous circuit "
    3846             :                      "to the service destination.");
    3847             : 
    3848           0 :   origin_circ = TO_ORIGIN_CIRCUIT(circ);
    3849           0 :   conn->base_.address = tor_strdup("(rendezvous)");
    3850           0 :   conn->base_.state = EXIT_CONN_STATE_CONNECTING;
    3851             : 
    3852           0 :   if (origin_circ->hs_ident) {
    3853             :     /* Setup the identifier to be the one for the circuit service. */
    3854           0 :     conn->hs_ident =
    3855           0 :       hs_ident_edge_conn_new(&origin_circ->hs_ident->identity_pk);
    3856           0 :     tor_assert(connection_edge_is_rendezvous_stream(conn));
    3857           0 :     ret = hs_service_set_conn_addr_port(origin_circ, conn);
    3858             :   } else {
    3859             :     /* We should never get here if the circuit's purpose is rendezvous. */
    3860           0 :     tor_assert_nonfatal_unreached();
    3861           0 :     return -1;
    3862             :   }
    3863           0 :   if (ret < 0) {
    3864           0 :     log_info(LD_REND, "Didn't find rendezvous service at %s",
    3865             :              connection_describe_peer(TO_CONN(conn)));
    3866             :     /* Send back reason DONE because we want to make hidden service port
    3867             :      * scanning harder thus instead of returning that the exit policy
    3868             :      * didn't match, which makes it obvious that the port is closed,
    3869             :      * return DONE and kill the circuit. That way, a user (malicious or
    3870             :      * not) needs one circuit per bad port unless it matches the policy of
    3871             :      * the hidden service. */
    3872           0 :     relay_send_end_cell_from_edge(conn->stream_id, circ,
    3873             :                                   END_STREAM_REASON_DONE,
    3874           0 :                                   origin_circ->cpath->prev);
    3875           0 :     connection_free_(TO_CONN(conn));
    3876             : 
    3877             :     /* Drop the circuit here since it might be someone deliberately
    3878             :      * scanning the hidden service ports. Note that this mitigates port
    3879             :      * scanning by adding more work on the attacker side to successfully
    3880             :      * scan but does not fully solve it. */
    3881           0 :     if (ret < -1) {
    3882             :       return END_CIRC_AT_ORIGIN;
    3883             :     } else {
    3884           0 :       return 0;
    3885             :     }
    3886             :   }
    3887             : 
    3888             :   /* Link the circuit and the connection crypt path. */
    3889           0 :   conn->cpath_layer = origin_circ->cpath->prev;
    3890             : 
    3891             :   /* If this is the first stream on this circuit, tell circpad */
    3892           0 :   if (!origin_circ->p_streams)
    3893           0 :     circpad_machine_event_circ_has_streams(origin_circ);
    3894             : 
    3895             :   /* Add it into the linked list of p_streams on this circuit */
    3896           0 :   conn->next_stream = origin_circ->p_streams;
    3897           0 :   origin_circ->p_streams = conn;
    3898           0 :   conn->on_circuit = circ;
    3899           0 :   assert_circuit_ok(circ);
    3900             : 
    3901           0 :   hs_inc_rdv_stream_counter(origin_circ);
    3902             : 
    3903             :   /* If it's an onion service connection, we might want to include the proxy
    3904             :    * protocol header: */
    3905           0 :   if (conn->hs_ident) {
    3906           0 :     hs_circuit_id_protocol_t circuit_id_protocol =
    3907           0 :       hs_service_exports_circuit_id(&conn->hs_ident->identity_pk);
    3908           0 :     export_hs_client_circuit_id(conn, circuit_id_protocol);
    3909             :   }
    3910             : 
    3911             :   /* Connect tor to the hidden service destination. */
    3912           0 :   connection_exit_connect(conn);
    3913             : 
    3914             :   /* For path bias: This circuit was used successfully */
    3915           0 :   pathbias_mark_use_success(origin_circ);
    3916           0 :   return 0;
    3917             : }
    3918             : 
    3919             : /** A relay 'begin' or 'begin_dir' cell has arrived, and either we are
    3920             :  * an exit hop for the circuit, or we are the origin and it is a
    3921             :  * rendezvous begin.
    3922             :  *
    3923             :  * Launch a new exit connection and initialize things appropriately.
    3924             :  *
    3925             :  * If it's a rendezvous stream, call connection_exit_connect() on
    3926             :  * it.
    3927             :  *
    3928             :  * For general streams, call dns_resolve() on it first, and only call
    3929             :  * connection_exit_connect() if the dns answer is already known.
    3930             :  *
    3931             :  * Note that we don't call connection_add() on the new stream! We wait
    3932             :  * for connection_exit_connect() to do that.
    3933             :  *
    3934             :  * Return -(some circuit end reason) if we want to tear down <b>circ</b>.
    3935             :  * Else return 0.
    3936             :  */
    3937             : int
    3938           0 : connection_exit_begin_conn(cell_t *cell, circuit_t *circ)
    3939             : {
    3940           0 :   edge_connection_t *n_stream;
    3941           0 :   relay_header_t rh;
    3942           0 :   char *address = NULL;
    3943           0 :   uint16_t port = 0;
    3944           0 :   or_circuit_t *or_circ = NULL;
    3945           0 :   origin_circuit_t *origin_circ = NULL;
    3946           0 :   crypt_path_t *layer_hint = NULL;
    3947           0 :   const or_options_t *options = get_options();
    3948           0 :   begin_cell_t bcell;
    3949           0 :   int rv;
    3950           0 :   uint8_t end_reason=0;
    3951             : 
    3952           0 :   assert_circuit_ok(circ);
    3953           0 :   if (!CIRCUIT_IS_ORIGIN(circ)) {
    3954           0 :     or_circ = TO_OR_CIRCUIT(circ);
    3955             :   } else {
    3956           0 :     tor_assert(circ->purpose == CIRCUIT_PURPOSE_S_REND_JOINED);
    3957           0 :     origin_circ = TO_ORIGIN_CIRCUIT(circ);
    3958           0 :     layer_hint = origin_circ->cpath->prev;
    3959             :   }
    3960             : 
    3961           0 :   relay_header_unpack(&rh, cell->payload);
    3962           0 :   if (rh.length > RELAY_PAYLOAD_SIZE)
    3963             :     return -END_CIRC_REASON_TORPROTOCOL;
    3964             : 
    3965           0 :   if (!server_mode(options) &&
    3966           0 :       circ->purpose != CIRCUIT_PURPOSE_S_REND_JOINED) {
    3967           0 :     log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL,
    3968             :            "Relay begin cell at non-server. Closing.");
    3969           0 :     relay_send_end_cell_from_edge(rh.stream_id, circ,
    3970             :                                   END_STREAM_REASON_EXITPOLICY, NULL);
    3971           0 :     return 0;
    3972             :   }
    3973             : 
    3974           0 :   rv = begin_cell_parse(cell, &bcell, &end_reason);
    3975           0 :   if (rv < -1) {
    3976             :     return -END_CIRC_REASON_TORPROTOCOL;
    3977           0 :   } else if (rv == -1) {
    3978           0 :     tor_free(bcell.address);
    3979           0 :     relay_send_end_cell_from_edge(rh.stream_id, circ, end_reason, layer_hint);
    3980           0 :     return 0;
    3981             :   }
    3982             : 
    3983           0 :   if (! bcell.is_begindir) {
    3984             :     /* Steal reference */
    3985           0 :     tor_assert(bcell.address);
    3986           0 :     address = bcell.address;
    3987           0 :     port = bcell.port;
    3988             : 
    3989           0 :     if (or_circ && or_circ->p_chan) {
    3990           0 :       const int client_chan = channel_is_client(or_circ->p_chan);
    3991           0 :       if ((client_chan ||
    3992           0 :            (!connection_or_digest_is_known_relay(
    3993           0 :                 or_circ->p_chan->identity_digest) &&
    3994           0 :           should_refuse_unknown_exits(options)))) {
    3995             :         /* Don't let clients use us as a single-hop proxy. It attracts
    3996             :          * attackers and users who'd be better off with, well, single-hop
    3997             :          * proxies. */
    3998           0 :         log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL,
    3999             :                "Attempt by %s to open a stream %s. Closing.",
    4000             :                safe_str(channel_describe_peer(or_circ->p_chan)),
    4001             :                client_chan ? "on first hop of circuit" :
    4002             :                              "from unknown relay");
    4003           0 :         relay_send_end_cell_from_edge(rh.stream_id, circ,
    4004             :                                       client_chan ?
    4005             :                                         END_STREAM_REASON_TORPROTOCOL :
    4006             :                                         END_STREAM_REASON_MISC,
    4007             :                                       NULL);
    4008           0 :         tor_free(address);
    4009           0 :         return 0;
    4010             :       }
    4011             :     }
    4012           0 :   } else if (rh.command == RELAY_COMMAND_BEGIN_DIR) {
    4013           0 :     if (!directory_permits_begindir_requests(options) ||
    4014           0 :         circ->purpose != CIRCUIT_PURPOSE_OR) {
    4015           0 :       relay_send_end_cell_from_edge(rh.stream_id, circ,
    4016             :                                   END_STREAM_REASON_NOTDIRECTORY, layer_hint);
    4017           0 :       return 0;
    4018             :     }
    4019             :     /* Make sure to get the 'real' address of the previous hop: the
    4020             :      * caller might want to know whether the remote IP address has changed,
    4021             :      * and we might already have corrected base_.addr[ess] for the relay's
    4022             :      * canonical IP address. */
    4023           0 :     tor_addr_t chan_addr;
    4024           0 :     if (or_circ && or_circ->p_chan &&
    4025           0 :         channel_get_addr_if_possible(or_circ->p_chan, &chan_addr)) {
    4026           0 :       address = tor_addr_to_str_dup(&chan_addr);
    4027             :     } else {
    4028           0 :       address = tor_strdup("127.0.0.1");
    4029             :     }
    4030           0 :     port = 1; /* XXXX This value is never actually used anywhere, and there
    4031             :                * isn't "really" a connection here.  But we
    4032             :                * need to set it to something nonzero. */
    4033             :   } else {
    4034           0 :     log_warn(LD_BUG, "Got an unexpected command %d", (int)rh.command);
    4035           0 :     relay_send_end_cell_from_edge(rh.stream_id, circ,
    4036             :                                   END_STREAM_REASON_INTERNAL, layer_hint);
    4037           0 :     return 0;
    4038             :   }
    4039             : 
    4040           0 :   if (! options->IPv6Exit) {
    4041             :     /* I don't care if you prefer IPv6; I can't give you any. */
    4042           0 :     bcell.flags &= ~BEGIN_FLAG_IPV6_PREFERRED;
    4043             :     /* If you don't want IPv4, I can't help. */
    4044           0 :     if (bcell.flags & BEGIN_FLAG_IPV4_NOT_OK) {
    4045           0 :       tor_free(address);
    4046           0 :       relay_send_end_cell_from_edge(rh.stream_id, circ,
    4047             :                                     END_STREAM_REASON_EXITPOLICY, layer_hint);
    4048           0 :       return 0;
    4049             :     }
    4050             :   }
    4051             : 
    4052           0 :   log_debug(LD_EXIT,"Creating new exit connection.");
    4053             :   /* The 'AF_INET' here is temporary; we might need to change it later in
    4054             :    * connection_exit_connect(). */
    4055           0 :   n_stream = edge_connection_new(CONN_TYPE_EXIT, AF_INET);
    4056             : 
    4057             :   /* Remember the tunneled request ID in the new edge connection, so that
    4058             :    * we can measure download times. */
    4059           0 :   n_stream->dirreq_id = circ->dirreq_id;
    4060             : 
    4061           0 :   n_stream->base_.purpose = EXIT_PURPOSE_CONNECT;
    4062           0 :   n_stream->begincell_flags = bcell.flags;
    4063           0 :   n_stream->stream_id = rh.stream_id;
    4064           0 :   n_stream->base_.port = port;
    4065             :   /* leave n_stream->s at -1, because it's not yet valid */
    4066           0 :   n_stream->package_window = STREAMWINDOW_START;
    4067           0 :   n_stream->deliver_window = STREAMWINDOW_START;
    4068             : 
    4069           0 :   if (circ->purpose == CIRCUIT_PURPOSE_S_REND_JOINED) {
    4070           0 :     int ret;
    4071           0 :     tor_free(address);
    4072             :     /* We handle this circuit and stream in this function for all supported
    4073             :      * hidden service version. */
    4074           0 :     ret = handle_hs_exit_conn(circ, n_stream);
    4075             : 
    4076           0 :     if (ret == 0) {
    4077             :       /* This was a valid cell. Count it as delivered + overhead. */
    4078           0 :       circuit_read_valid_data(origin_circ, rh.length);
    4079             :     }
    4080           0 :     return ret;
    4081             :   }
    4082           0 :   tor_strlower(address);
    4083           0 :   n_stream->base_.address = address;
    4084           0 :   n_stream->base_.state = EXIT_CONN_STATE_RESOLVEFAILED;
    4085             :   /* default to failed, change in dns_resolve if it turns out not to fail */
    4086             : 
    4087             :   /* If we're hibernating or shutting down, we refuse to open new streams. */
    4088           0 :   if (we_are_hibernating()) {
    4089           0 :     relay_send_end_cell_from_edge(rh.stream_id, circ,
    4090             :                                   END_STREAM_REASON_HIBERNATING, NULL);
    4091           0 :     connection_free_(TO_CONN(n_stream));
    4092           0 :     return 0;
    4093             :   }
    4094             : 
    4095           0 :   n_stream->on_circuit = circ;
    4096             : 
    4097           0 :   if (rh.command == RELAY_COMMAND_BEGIN_DIR) {
    4098           0 :     tor_addr_t tmp_addr;
    4099           0 :     tor_assert(or_circ);
    4100           0 :     if (or_circ->p_chan &&
    4101           0 :         channel_get_addr_if_possible(or_circ->p_chan, &tmp_addr)) {
    4102           0 :       tor_addr_copy(&n_stream->base_.addr, &tmp_addr);
    4103             :     }
    4104           0 :     return connection_exit_connect_dir(n_stream);
    4105             :   }
    4106             : 
    4107           0 :   log_debug(LD_EXIT,"about to start the dns_resolve().");
    4108             : 
    4109             :   /* send it off to the gethostbyname farm */
    4110           0 :   switch (dns_resolve(n_stream)) {
    4111           0 :     case 1: /* resolve worked; now n_stream is attached to circ. */
    4112           0 :       assert_circuit_ok(circ);
    4113           0 :       log_debug(LD_EXIT,"about to call connection_exit_connect().");
    4114           0 :       connection_exit_connect(n_stream);
    4115           0 :       return 0;
    4116           0 :     case -1: /* resolve failed */
    4117           0 :       relay_send_end_cell_from_edge(rh.stream_id, circ,
    4118             :                                     END_STREAM_REASON_RESOLVEFAILED, NULL);
    4119             :       /* n_stream got freed. don't touch it. */
    4120           0 :       break;
    4121           0 :     case 0: /* resolve added to pending list */
    4122           0 :       assert_circuit_ok(circ);
    4123           0 :       break;
    4124             :   }
    4125             :   return 0;
    4126             : }
    4127             : 
    4128             : /**
    4129             :  * Called when we receive a RELAY_COMMAND_RESOLVE cell 'cell' along the
    4130             :  * circuit <b>circ</b>;
    4131             :  * begin resolving the hostname, and (eventually) reply with a RESOLVED cell.
    4132             :  */
    4133             : int
    4134           0 : connection_exit_begin_resolve(cell_t *cell, or_circuit_t *circ)
    4135             : {
    4136           0 :   edge_connection_t *dummy_conn;
    4137           0 :   relay_header_t rh;
    4138             : 
    4139           0 :   assert_circuit_ok(TO_CIRCUIT(circ));
    4140           0 :   relay_header_unpack(&rh, cell->payload);
    4141           0 :   if (rh.length > RELAY_PAYLOAD_SIZE)
    4142             :     return -1;
    4143             : 
    4144             :   /* This 'dummy_conn' only exists to remember the stream ID
    4145             :    * associated with the resolve request; and to make the
    4146             :    * implementation of dns.c more uniform.  (We really only need to
    4147             :    * remember the circuit, the stream ID, and the hostname to be
    4148             :    * resolved; but if we didn't store them in a connection like this,
    4149             :    * the housekeeping in dns.c would get way more complicated.)
    4150             :    */
    4151           0 :   dummy_conn = edge_connection_new(CONN_TYPE_EXIT, AF_INET);
    4152           0 :   dummy_conn->stream_id = rh.stream_id;
    4153           0 :   dummy_conn->base_.address = tor_strndup(
    4154             :                                        (char*)cell->payload+RELAY_HEADER_SIZE,
    4155             :                                        rh.length);
    4156           0 :   dummy_conn->base_.port = 0;
    4157           0 :   dummy_conn->base_.state = EXIT_CONN_STATE_RESOLVEFAILED;
    4158           0 :   dummy_conn->base_.purpose = EXIT_PURPOSE_RESOLVE;
    4159             : 
    4160           0 :   dummy_conn->on_circuit = TO_CIRCUIT(circ);
    4161             : 
    4162             :   /* send it off to the gethostbyname farm */
    4163           0 :   switch (dns_resolve(dummy_conn)) {
    4164             :     case -1: /* Impossible to resolve; a resolved cell was sent. */
    4165             :       /* Connection freed; don't touch it. */
    4166             :       return 0;
    4167           0 :     case 1: /* The result was cached; a resolved cell was sent. */
    4168           0 :       if (!dummy_conn->base_.marked_for_close)
    4169           0 :         connection_free_(TO_CONN(dummy_conn));
    4170             :       return 0;
    4171           0 :     case 0: /* resolve added to pending list */
    4172           0 :       assert_circuit_ok(TO_CIRCUIT(circ));
    4173           0 :       break;
    4174             :   }
    4175             :   return 0;
    4176             : }
    4177             : 
    4178             : /** Helper: Return true and set *<b>why_rejected</b> to an optional clarifying
    4179             :  * message message iff we do not allow connections to <b>addr</b>:<b>port</b>.
    4180             :  */
    4181             : static int
    4182           0 : my_exit_policy_rejects(const tor_addr_t *addr,
    4183             :                        uint16_t port,
    4184             :                        const char **why_rejected)
    4185             : {
    4186           0 :   if (router_compare_to_my_exit_policy(addr, port)) {
    4187           0 :     *why_rejected = "";
    4188           0 :     return 1;
    4189           0 :   } else if (tor_addr_family(addr) == AF_INET6 && !get_options()->IPv6Exit) {
    4190           0 :     *why_rejected = " (IPv6 address without IPv6Exit configured)";
    4191           0 :     return 1;
    4192             :   }
    4193             :   return 0;
    4194             : }
    4195             : 
    4196             : /** Return true iff the consensus allows network reentry. The default value is
    4197             :  * false if the parameter is not found. */
    4198             : static bool
    4199           0 : network_reentry_is_allowed(void)
    4200             : {
    4201             :   /* Default is false, re-entry is not allowed. */
    4202           0 :   return !!networkstatus_get_param(NULL, "allow-network-reentry", 0, 0, 1);
    4203             : }
    4204             : 
    4205             : /** Connect to conn's specified addr and port. If it worked, conn
    4206             :  * has now been added to the connection_array.
    4207             :  *
    4208             :  * Send back a connected cell. Include the resolved IP of the destination
    4209             :  * address, but <em>only</em> if it's a general exit stream. (Rendezvous
    4210             :  * streams must not reveal what IP they connected to.)
    4211             :  */
    4212             : void
    4213           0 : connection_exit_connect(edge_connection_t *edge_conn)
    4214             : {
    4215           0 :   const tor_addr_t *addr;
    4216           0 :   uint16_t port;
    4217           0 :   connection_t *conn = TO_CONN(edge_conn);
    4218           0 :   int socket_error = 0, result;
    4219           0 :   const char *why_failed_exit_policy = NULL;
    4220             : 
    4221             :   /* Apply exit policy to non-rendezvous connections. */
    4222           0 :   if (! connection_edge_is_rendezvous_stream(edge_conn) &&
    4223           0 :       my_exit_policy_rejects(&edge_conn->base_.addr,
    4224           0 :                              edge_conn->base_.port,
    4225             :                              &why_failed_exit_policy)) {
    4226           0 :     if (BUG(!why_failed_exit_policy))
    4227           0 :       why_failed_exit_policy = "";
    4228           0 :     log_info(LD_EXIT,"%s failed exit policy%s. Closing.",
    4229             :              connection_describe(conn),
    4230             :              why_failed_exit_policy);
    4231           0 :     connection_edge_end(edge_conn, END_STREAM_REASON_EXITPOLICY);
    4232           0 :     circuit_detach_stream(circuit_get_by_edge_conn(edge_conn), edge_conn);
    4233           0 :     connection_free(conn);
    4234           0 :     return;
    4235             :   }
    4236             : 
    4237             :   /* Next, check for attempts to connect back into the Tor network. We don't
    4238             :    * want to allow these for the same reason we don't want to allow
    4239             :    * infinite-length circuits (see "A Practical Congestion Attack on Tor Using
    4240             :    * Long Paths", Usenix Security 2009). See also ticket 2667.
    4241             :    *
    4242             :    * Skip this if the network reentry is allowed (known from the consensus).
    4243             :    *
    4244             :    * The TORPROTOCOL reason is used instead of EXITPOLICY so client do NOT
    4245             :    * attempt to retry connecting onto another circuit that will also fail
    4246             :    * bringing considerable more load on the network if so.
    4247             :    *
    4248             :    * Since the address+port set here is a bloomfilter, in very rare cases, the
    4249             :    * check will create a false positive meaning that the destination could
    4250             :    * actually be legit and thus being denied exit. However, sending back a
    4251             :    * reason that makes the client retry results in much worst consequences in
    4252             :    * case of an attack so this is a small price to pay. */
    4253           0 :   if (!connection_edge_is_rendezvous_stream(edge_conn) &&
    4254           0 :       !network_reentry_is_allowed() &&
    4255           0 :       nodelist_reentry_contains(&conn->addr, conn->port)) {
    4256           0 :     log_info(LD_EXIT, "%s tried to connect back to a known relay address. "
    4257             :                       "Closing.", connection_describe(conn));
    4258           0 :     connection_edge_end(edge_conn, END_STREAM_REASON_CONNECTREFUSED);
    4259           0 :     circuit_detach_stream(circuit_get_by_edge_conn(edge_conn), edge_conn);
    4260           0 :     connection_free(conn);
    4261           0 :     return;
    4262             :   }
    4263             : 
    4264             : #ifdef HAVE_SYS_UN_H
    4265           0 :   if (conn->socket_family != AF_UNIX) {
    4266             : #else
    4267             :   {
    4268             : #endif /* defined(HAVE_SYS_UN_H) */
    4269           0 :     addr = &conn->addr;
    4270           0 :     port = conn->port;
    4271             : 
    4272           0 :     if (tor_addr_family(addr) == AF_INET6)
    4273           0 :       conn->socket_family = AF_INET6;
    4274             : 
    4275           0 :     log_debug(LD_EXIT, "about to try connecting");
    4276           0 :     result = connection_connect(conn, conn->address,
    4277             :                                 addr, port, &socket_error);
    4278             : #ifdef HAVE_SYS_UN_H
    4279             :   } else {
    4280             :     /*
    4281             :      * In the AF_UNIX case, we expect to have already had conn->port = 1,
    4282             :      * tor_addr_make_unspec(conn->addr) (cf. the way we mark in the incoming
    4283             :      * case in connection_handle_listener_read()), and conn->address should
    4284             :      * have the socket path to connect to.
    4285             :      */
    4286           0 :     tor_assert(conn->address && strlen(conn->address) > 0);
    4287             : 
    4288           0 :     log_debug(LD_EXIT, "about to try connecting");
    4289           0 :     result = connection_connect_unix(conn, conn->address, &socket_error);
    4290             : #endif /* defined(HAVE_SYS_UN_H) */
    4291             :   }
    4292             : 
    4293           0 :   switch (result) {
    4294           0 :     case -1: {
    4295           0 :       int reason = errno_to_stream_end_reason(socket_error);
    4296           0 :       connection_edge_end(edge_conn, reason);
    4297           0 :       circuit_detach_stream(circuit_get_by_edge_conn(edge_conn), edge_conn);
    4298           0 :       connection_free(conn);
    4299           0 :       return;
    4300             :     }
    4301           0 :     case 0:
    4302           0 :       conn->state = EXIT_CONN_STATE_CONNECTING;
    4303             : 
    4304           0 :       connection_watch_events(conn, READ_EVENT | WRITE_EVENT);
    4305             :       /* writable indicates finish;
    4306             :        * readable/error indicates broken link in windows-land. */
    4307           0 :       return;
    4308             :     /* case 1: fall through */
    4309             :   }
    4310             : 
    4311           0 :   conn->state = EXIT_CONN_STATE_OPEN;
    4312           0 :   if (connection_get_outbuf_len(conn)) {
    4313             :     /* in case there are any queued data cells, from e.g. optimistic data */
    4314           0 :     connection_watch_events(conn, READ_EVENT|WRITE_EVENT);
    4315             :   } else {
    4316           0 :     connection_watch_events(conn, READ_EVENT);
    4317             :   }
    4318             : 
    4319             :   /* also, deliver a 'connected' cell back through the circuit. */
    4320           0 :   if (connection_edge_is_rendezvous_stream(edge_conn)) {
    4321             :     /* don't send an address back! */
    4322           0 :     connection_edge_send_command(edge_conn,
    4323             :                                  RELAY_COMMAND_CONNECTED,
    4324             :                                  NULL, 0);
    4325             :   } else { /* normal stream */
    4326           0 :     uint8_t connected_payload[MAX_CONNECTED_CELL_PAYLOAD_LEN];
    4327           0 :     int connected_payload_len =
    4328           0 :       connected_cell_format_payload(connected_payload, &conn->addr,
    4329             :                                     edge_conn->address_ttl);
    4330           0 :     if (connected_payload_len < 0) {
    4331           0 :       connection_edge_end(edge_conn, END_STREAM_REASON_INTERNAL);
    4332           0 :       circuit_detach_stream(circuit_get_by_edge_conn(edge_conn), edge_conn);
    4333           0 :       connection_free(conn);
    4334           0 :       return;
    4335             :     }
    4336             : 
    4337           0 :     connection_edge_send_command(edge_conn,
    4338             :                                  RELAY_COMMAND_CONNECTED,
    4339             :                                  (char*)connected_payload,
    4340             :                                  connected_payload_len);
    4341             :   }
    4342             : }
    4343             : 
    4344             : /** Given an exit conn that should attach to us as a directory server, open a
    4345             :  * bridge connection with a linked connection pair, create a new directory
    4346             :  * conn, and join them together.  Return 0 on success (or if there was an
    4347             :  * error we could send back an end cell for).  Return -(some circuit end
    4348             :  * reason) if the circuit needs to be torn down.  Either connects
    4349             :  * <b>exitconn</b>, frees it, or marks it, as appropriate.
    4350             :  */
    4351             : static int
    4352           0 : connection_exit_connect_dir(edge_connection_t *exitconn)
    4353             : {
    4354           0 :   dir_connection_t *dirconn = NULL;
    4355           0 :   or_circuit_t *circ = TO_OR_CIRCUIT(exitconn->on_circuit);
    4356             : 
    4357           0 :   log_info(LD_EXIT, "Opening local connection for anonymized directory exit");
    4358             : 
    4359           0 :   exitconn->base_.state = EXIT_CONN_STATE_OPEN;
    4360             : 
    4361           0 :   dirconn = dir_connection_new(tor_addr_family(&exitconn->base_.addr));
    4362             : 
    4363           0 :   tor_addr_copy(&dirconn->base_.addr, &exitconn->base_.addr);
    4364           0 :   dirconn->base_.port = 0;
    4365           0 :   dirconn->base_.address = tor_strdup(exitconn->base_.address);
    4366           0 :   dirconn->base_.type = CONN_TYPE_DIR;
    4367           0 :   dirconn->base_.purpose = DIR_PURPOSE_SERVER;
    4368           0 :   dirconn->base_.state = DIR_CONN_STATE_SERVER_COMMAND_WAIT;
    4369             : 
    4370             :   /* Note that the new dir conn belongs to the same tunneled request as
    4371             :    * the edge conn, so that we can measure download times. */
    4372           0 :   dirconn->dirreq_id = exitconn->dirreq_id;
    4373             : 
    4374           0 :   connection_link_connections(TO_CONN(dirconn), TO_CONN(exitconn));
    4375             : 
    4376           0 :   if (connection_add(TO_CONN(exitconn))<0) {
    4377           0 :     connection_edge_end(exitconn, END_STREAM_REASON_RESOURCELIMIT);
    4378           0 :     connection_free_(TO_CONN(exitconn));
    4379           0 :     connection_free_(TO_CONN(dirconn));
    4380           0 :     return 0;
    4381             :   }
    4382             : 
    4383             :   /* link exitconn to circ, now that we know we can use it. */
    4384           0 :   exitconn->next_stream = circ->n_streams;
    4385           0 :   circ->n_streams = exitconn;
    4386             : 
    4387           0 :   if (connection_add(TO_CONN(dirconn))<0) {
    4388           0 :     connection_edge_end(exitconn, END_STREAM_REASON_RESOURCELIMIT);
    4389           0 :     connection_close_immediate(TO_CONN(exitconn));
    4390           0 :     connection_mark_for_close(TO_CONN(exitconn));
    4391           0 :     connection_free_(TO_CONN(dirconn));
    4392           0 :     return 0;
    4393             :   }
    4394             : 
    4395           0 :   connection_start_reading(TO_CONN(dirconn));
    4396           0 :   connection_start_reading(TO_CONN(exitconn));
    4397             : 
    4398           0 :   if (connection_edge_send_command(exitconn,
    4399             :                                    RELAY_COMMAND_CONNECTED, NULL, 0) < 0) {
    4400           0 :     connection_mark_for_close(TO_CONN(exitconn));
    4401           0 :     connection_mark_for_close(TO_CONN(dirconn));
    4402           0 :     return 0;
    4403             :   }
    4404             : 
    4405             :   return 0;
    4406             : }
    4407             : 
    4408             : /** Return 1 if <b>conn</b> is a rendezvous stream, or 0 if
    4409             :  * it is a general stream.
    4410             :  */
    4411             : int
    4412           3 : connection_edge_is_rendezvous_stream(const edge_connection_t *conn)
    4413             : {
    4414           3 :   tor_assert(conn);
    4415             : 
    4416           3 :   if (conn->hs_ident) {
    4417           3 :     return 1;
    4418             :   }
    4419             :   return 0;
    4420             : }
    4421             : 
    4422             : /** Return 1 if router <b>exit_node</b> is likely to allow stream <b>conn</b>
    4423             :  * to exit from it, or 0 if it probably will not allow it.
    4424             :  * (We might be uncertain if conn's destination address has not yet been
    4425             :  * resolved.)
    4426             :  */
    4427             : int
    4428           0 : connection_ap_can_use_exit(const entry_connection_t *conn,
    4429             :                            const node_t *exit_node)
    4430             : {
    4431           0 :   const or_options_t *options = get_options();
    4432             : 
    4433           0 :   tor_assert(conn);
    4434           0 :   tor_assert(conn->socks_request);
    4435           0 :   tor_assert(exit_node);
    4436             : 
    4437             :   /* If a particular exit node has been requested for the new connection,
    4438             :    * make sure the exit node of the existing circuit matches exactly.
    4439             :    */
    4440           0 :   if (conn->chosen_exit_name) {
    4441           0 :     const node_t *chosen_exit =
    4442           0 :       node_get_by_nickname(conn->chosen_exit_name, 0);
    4443           0 :     if (!chosen_exit || tor_memneq(chosen_exit->identity,
    4444             :                                exit_node->identity, DIGEST_LEN)) {
    4445             :       /* doesn't match */
    4446             : //      log_debug(LD_APP,"Requested node '%s', considering node '%s'. No.",
    4447             : //                conn->chosen_exit_name, exit->nickname);
    4448           0 :       return 0;
    4449             :     }
    4450             :   }
    4451             : 
    4452           0 :   if (conn->use_begindir) {
    4453             :     /* Internal directory fetches do not count as exiting. */
    4454             :     return 1;
    4455             :   }
    4456             : 
    4457           0 :   if (conn->socks_request->command == SOCKS_COMMAND_CONNECT) {
    4458           0 :     tor_addr_t addr, *addrp = NULL;
    4459           0 :     addr_policy_result_t r;
    4460           0 :     if (0 == tor_addr_parse(&addr, conn->socks_request->address)) {
    4461             :       addrp = &addr;
    4462           0 :     } else if (!conn->entry_cfg.ipv4_traffic && conn->entry_cfg.ipv6_traffic) {
    4463           0 :       tor_addr_make_null(&addr, AF_INET6);
    4464           0 :       addrp = &addr;
    4465           0 :     } else if (conn->entry_cfg.ipv4_traffic && !conn->entry_cfg.ipv6_traffic) {
    4466           0 :       tor_addr_make_null(&addr, AF_INET);
    4467           0 :       addrp = &addr;
    4468             :     }
    4469           0 :     r = compare_tor_addr_to_node_policy(addrp, conn->socks_request->port,
    4470             :                                         exit_node);
    4471           0 :     if (r == ADDR_POLICY_REJECTED)
    4472           0 :       return 0; /* We know the address, and the exit policy rejects it. */
    4473           0 :     if (r == ADDR_POLICY_PROBABLY_REJECTED && !conn->chosen_exit_name)
    4474             :       return 0; /* We don't know the addr, but the exit policy rejects most
    4475             :                  * addresses with this port. Since the user didn't ask for
    4476             :                  * this node, err on the side of caution. */
    4477           0 :   } else if (SOCKS_COMMAND_IS_RESOLVE(conn->socks_request->command)) {
    4478             :     /* Don't send DNS requests to non-exit servers by default. */
    4479           0 :     if (!conn->chosen_exit_name && node_exit_policy_rejects_all(exit_node))
    4480             :       return 0;
    4481             :   }
    4482           0 :   if (routerset_contains_node(options->ExcludeExitNodesUnion_, exit_node)) {
    4483             :     /* Not a suitable exit. Refuse it. */
    4484           0 :     return 0;
    4485             :   }
    4486             : 
    4487             :   return 1;
    4488             : }
    4489             : 
    4490             : /** Return true iff the (possibly NULL) <b>alen</b>-byte chunk of memory at
    4491             :  * <b>a</b> is equal to the (possibly NULL) <b>blen</b>-byte chunk of memory
    4492             :  * at <b>b</b>. */
    4493             : static int
    4494           0 : memeq_opt(const char *a, size_t alen, const char *b, size_t blen)
    4495             : {
    4496           0 :   if (a == NULL) {
    4497           0 :     return (b == NULL);
    4498           0 :   } else if (b == NULL) {
    4499             :     return 0;
    4500           0 :   } else if (alen != blen) {
    4501             :     return 0;
    4502             :   } else {
    4503           0 :     return tor_memeq(a, b, alen);
    4504             :   }
    4505             : }
    4506             : 
    4507             : /**
    4508             :  * Return true iff none of the isolation flags and fields in <b>conn</b>
    4509             :  * should prevent it from being attached to <b>circ</b>.
    4510             :  */
    4511             : int
    4512           1 : connection_edge_compatible_with_circuit(const entry_connection_t *conn,
    4513             :                                         const origin_circuit_t *circ)
    4514             : {
    4515           1 :   const uint8_t iso = conn->entry_cfg.isolation_flags;
    4516           1 :   const socks_request_t *sr = conn->socks_request;
    4517             : 
    4518             :   /* If circ has never been used for an isolated connection, we can
    4519             :    * totally use it for this one. */
    4520           1 :   if (!circ->isolation_values_set)
    4521             :     return 1;
    4522             : 
    4523             :   /* If circ has been used for connections having more than one value
    4524             :    * for some field f, it will have the corresponding bit set in
    4525             :    * isolation_flags_mixed.  If isolation_flags_mixed has any bits
    4526             :    * in common with iso, then conn must be isolated from at least
    4527             :    * one stream that has been attached to circ. */
    4528           0 :   if ((iso & circ->isolation_flags_mixed) != 0) {
    4529             :     /* For at least one field where conn is isolated, the circuit
    4530             :      * already has mixed streams. */
    4531             :     return 0;
    4532             :   }
    4533             : 
    4534           0 :   if (! conn->original_dest_address) {
    4535           0 :     log_warn(LD_BUG, "Reached connection_edge_compatible_with_circuit without "
    4536             :              "having set conn->original_dest_address");
    4537           0 :     ((entry_connection_t*)conn)->original_dest_address =
    4538           0 :       tor_strdup(conn->socks_request->address);
    4539             :   }
    4540             : 
    4541           0 :   if ((iso & ISO_STREAM) &&
    4542           0 :       (circ->associated_isolated_stream_global_id !=
    4543           0 :        ENTRY_TO_CONN(conn)->global_identifier))
    4544             :     return 0;
    4545             : 
    4546           0 :   if ((iso & ISO_DESTPORT) && conn->socks_request->port != circ->dest_port)
    4547             :     return 0;
    4548           0 :   if ((iso & ISO_DESTADDR) &&
    4549           0 :       strcasecmp(conn->original_dest_address, circ->dest_address))
    4550             :     return 0;
    4551           0 :   if ((iso & ISO_SOCKSAUTH) &&
    4552           0 :       (! memeq_opt(sr->username, sr->usernamelen,
    4553           0 :                    circ->socks_username, circ->socks_username_len) ||
    4554           0 :        ! memeq_opt(sr->password, sr->passwordlen,
    4555           0 :                    circ->socks_password, circ->socks_password_len)))
    4556           0 :     return 0;
    4557           0 :   if ((iso & ISO_CLIENTPROTO) &&
    4558           0 :       (conn->socks_request->listener_type != circ->client_proto_type ||
    4559           0 :        conn->socks_request->socks_version != circ->client_proto_socksver))
    4560             :     return 0;
    4561           0 :   if ((iso & ISO_CLIENTADDR) &&
    4562           0 :       !tor_addr_eq(&ENTRY_TO_CONN(conn)->addr, &circ->client_addr))
    4563             :     return 0;
    4564           0 :   if ((iso & ISO_SESSIONGRP) &&
    4565           0 :       conn->entry_cfg.session_group != circ->session_group)
    4566             :     return 0;
    4567           0 :   if ((iso & ISO_NYM_EPOCH) && conn->nym_epoch != circ->nym_epoch)
    4568           0 :     return 0;
    4569             : 
    4570             :   return 1;
    4571             : }
    4572             : 
    4573             : /**
    4574             :  * If <b>dry_run</b> is false, update <b>circ</b>'s isolation flags and fields
    4575             :  * to reflect having had <b>conn</b> attached to it, and return 0.  Otherwise,
    4576             :  * if <b>dry_run</b> is true, then make no changes to <b>circ</b>, and return
    4577             :  * a bitfield of isolation flags that we would have to set in
    4578             :  * isolation_flags_mixed to add <b>conn</b> to <b>circ</b>, or -1 if
    4579             :  * <b>circ</b> has had no streams attached to it.
    4580             :  */
    4581             : int
    4582           1 : connection_edge_update_circuit_isolation(const entry_connection_t *conn,
    4583             :                                          origin_circuit_t *circ,
    4584             :                                          int dry_run)
    4585             : {
    4586           1 :   const socks_request_t *sr = conn->socks_request;
    4587           1 :   if (! conn->original_dest_address) {
    4588           0 :     log_warn(LD_BUG, "Reached connection_update_circuit_isolation without "
    4589             :              "having set conn->original_dest_address");
    4590           0 :     ((entry_connection_t*)conn)->original_dest_address =
    4591           0 :       tor_strdup(conn->socks_request->address);
    4592             :   }
    4593             : 
    4594           1 :   if (!circ->isolation_values_set) {
    4595           1 :     if (dry_run)
    4596             :       return -1;
    4597           1 :     circ->associated_isolated_stream_global_id =
    4598           1 :       ENTRY_TO_CONN(conn)->global_identifier;
    4599           1 :     circ->dest_port = conn->socks_request->port;
    4600           1 :     circ->dest_address = tor_strdup(conn->original_dest_address);
    4601           1 :     circ->client_proto_type = conn->socks_request->listener_type;
    4602           1 :     circ->client_proto_socksver = conn->socks_request->socks_version;
    4603           1 :     tor_addr_copy(&circ->client_addr, &ENTRY_TO_CONN(conn)->addr);
    4604           1 :     circ->session_group = conn->entry_cfg.session_group;
    4605           1 :     circ->nym_epoch = conn->nym_epoch;
    4606           2 :     circ->socks_username = sr->username ?
    4607           1 :       tor_memdup(sr->username, sr->usernamelen) : NULL;
    4608           2 :     circ->socks_password = sr->password ?
    4609           1 :       tor_memdup(sr->password, sr->passwordlen) : NULL;
    4610           1 :     circ->socks_username_len = sr->usernamelen;
    4611           1 :     circ->socks_password_len = sr->passwordlen;
    4612             : 
    4613           1 :     circ->isolation_values_set = 1;
    4614           1 :     return 0;
    4615             :   } else {
    4616           0 :     uint8_t mixed = 0;
    4617           0 :     if (conn->socks_request->port != circ->dest_port)
    4618           0 :       mixed |= ISO_DESTPORT;
    4619           0 :     if (strcasecmp(conn->original_dest_address, circ->dest_address))
    4620           0 :       mixed |= ISO_DESTADDR;
    4621           0 :     if (!memeq_opt(sr->username, sr->usernamelen,
    4622           0 :                    circ->socks_username, circ->socks_username_len) ||
    4623           0 :         !memeq_opt(sr->password, sr->passwordlen,
    4624           0 :                    circ->socks_password, circ->socks_password_len))
    4625           0 :       mixed |= ISO_SOCKSAUTH;
    4626           0 :     if ((conn->socks_request->listener_type != circ->client_proto_type ||
    4627           0 :          conn->socks_request->socks_version != circ->client_proto_socksver))
    4628           0 :       mixed |= ISO_CLIENTPROTO;
    4629           0 :     if (!tor_addr_eq(&ENTRY_TO_CONN(conn)->addr, &circ->client_addr))
    4630           0 :       mixed |= ISO_CLIENTADDR;
    4631           0 :     if (conn->entry_cfg.session_group != circ->session_group)
    4632           0 :       mixed |= ISO_SESSIONGRP;
    4633           0 :     if (conn->nym_epoch != circ->nym_epoch)
    4634           0 :       mixed |= ISO_NYM_EPOCH;
    4635             : 
    4636           0 :     if (dry_run)
    4637           0 :       return mixed;
    4638             : 
    4639           0 :     if ((mixed & conn->entry_cfg.isolation_flags) != 0) {
    4640           0 :       log_warn(LD_BUG, "Updating a circuit with seemingly incompatible "
    4641             :                "isolation flags.");
    4642             :     }
    4643           0 :     circ->isolation_flags_mixed |= mixed;
    4644           0 :     return 0;
    4645             :   }
    4646             : }
    4647             : 
    4648             : /**
    4649             :  * Clear the isolation settings on <b>circ</b>.
    4650             :  *
    4651             :  * This only works on an open circuit that has never had a stream attached to
    4652             :  * it, and whose isolation settings are hypothetical.  (We set hypothetical
    4653             :  * isolation settings on circuits as we're launching them, so that we
    4654             :  * know whether they can handle more streams or whether we need to launch
    4655             :  * even more circuits.  Once the circuit is open, if it turns out that
    4656             :  * we no longer have any streams to attach to it, we clear the isolation flags
    4657             :  * and data so that other streams can have a chance.)
    4658             :  */
    4659             : void
    4660           0 : circuit_clear_isolation(origin_circuit_t *circ)
    4661             : {
    4662           0 :   if (circ->isolation_any_streams_attached) {
    4663           0 :     log_warn(LD_BUG, "Tried to clear the isolation status of a dirty circuit");
    4664           0 :     return;
    4665             :   }
    4666           0 :   if (TO_CIRCUIT(circ)->state != CIRCUIT_STATE_OPEN) {
    4667           0 :     log_warn(LD_BUG, "Tried to clear the isolation status of a non-open "
    4668             :              "circuit");
    4669           0 :     return;
    4670             :   }
    4671             : 
    4672           0 :   circ->isolation_values_set = 0;
    4673           0 :   circ->isolation_flags_mixed = 0;
    4674           0 :   circ->associated_isolated_stream_global_id = 0;
    4675           0 :   circ->client_proto_type = 0;
    4676           0 :   circ->client_proto_socksver = 0;
    4677           0 :   circ->dest_port = 0;
    4678           0 :   tor_addr_make_unspec(&circ->client_addr);
    4679           0 :   tor_free(circ->dest_address);
    4680           0 :   circ->session_group = -1;
    4681           0 :   circ->nym_epoch = 0;
    4682           0 :   if (circ->socks_username) {
    4683           0 :     memwipe(circ->socks_username, 0x11, circ->socks_username_len);
    4684           0 :     tor_free(circ->socks_username);
    4685             :   }
    4686           0 :   if (circ->socks_password) {
    4687           0 :     memwipe(circ->socks_password, 0x05, circ->socks_password_len);
    4688           0 :     tor_free(circ->socks_password);
    4689             :   }
    4690           0 :   circ->socks_username_len = circ->socks_password_len = 0;
    4691             : }
    4692             : 
    4693             : /** Send an END and mark for close the given edge connection conn using the
    4694             :  * given reason that has to be a stream reason.
    4695             :  *
    4696             :  * Note: We don't unattached the AP connection (if applicable) because we
    4697             :  * don't want to flush the remaining data. This function aims at ending
    4698             :  * everything quickly regardless of the connection state.
    4699             :  *
    4700             :  * This function can't fail and does nothing if conn is NULL. */
    4701             : void
    4702           0 : connection_edge_end_close(edge_connection_t *conn, uint8_t reason)
    4703             : {
    4704           0 :   if (!conn) {
    4705             :     return;
    4706             :   }
    4707             : 
    4708           0 :   connection_edge_end(conn, reason);
    4709           0 :   connection_mark_for_close(TO_CONN(conn));
    4710             : }
    4711             : 
    4712             : /** Free all storage held in module-scoped variables for connection_edge.c */
    4713             : void
    4714         235 : connection_edge_free_all(void)
    4715             : {
    4716         235 :   untried_pending_connections = 0;
    4717         235 :   smartlist_free(pending_entry_connections);
    4718         235 :   pending_entry_connections = NULL;
    4719         235 :   mainloop_event_free(attach_pending_entry_connections_ev);
    4720         235 : }

Generated by: LCOV version 1.14