Bladeren bron

Merge remote-tracking branch 'public/split_entry_conn'

Conflicts:
	src/or/connection.c
	src/or/connection_edge.c
	src/or/connection_edge.h
	src/or/dnsserv.c

Some of these were a little tricky, since they touched code that
changed because of the prop171 fixes.
Nick Mathewson 12 jaren geleden
bovenliggende
commit
0cb01f5c97
17 gewijzigde bestanden met toevoegingen van 577 en 465 verwijderingen
  1. 10 5
      src/or/circuitbuild.c
  2. 54 45
      src/or/circuituse.c
  3. 3 3
      src/or/circuituse.h
  4. 64 42
      src/or/connection.c
  5. 1 0
      src/or/connection.h
  6. 206 191
      src/or/connection_edge.c
  7. 15 14
      src/or/connection_edge.h
  8. 33 31
      src/or/control.c
  9. 1 1
      src/or/control.h
  10. 5 4
      src/or/directory.c
  11. 32 28
      src/or/dnsserv.c
  12. 2 2
      src/or/dnsserv.h
  13. 1 1
      src/or/hibernate.c
  14. 4 4
      src/or/main.c
  15. 69 35
      src/or/or.h
  16. 59 43
      src/or/relay.c
  17. 18 16
      src/or/rendclient.c

+ 10 - 5
src/or/circuitbuild.c

@@ -2648,14 +2648,19 @@ node_handles_some_port(const node_t *node, smartlist_t *needed_ports)
 static int
 ap_stream_wants_exit_attention(connection_t *conn)
 {
+  entry_connection_t *entry;
+  if (conn->type != CONN_TYPE_AP)
+    return 0;
+  entry = TO_ENTRY_CONN(conn);
+
   if (conn->type == CONN_TYPE_AP &&
       conn->state == AP_CONN_STATE_CIRCUIT_WAIT &&
       !conn->marked_for_close &&
-      !(TO_EDGE_CONN(conn)->want_onehop) && /* ignore one-hop streams */
-      !(TO_EDGE_CONN(conn)->use_begindir) && /* ignore targeted dir fetches */
-      !(TO_EDGE_CONN(conn)->chosen_exit_name) && /* ignore defined streams */
+      !(entry->want_onehop) && /* ignore one-hop streams */
+      !(entry->use_begindir) && /* ignore targeted dir fetches */
+      !(entry->chosen_exit_name) && /* ignore defined streams */
       !connection_edge_is_rendezvous_stream(TO_EDGE_CONN(conn)) &&
-      !circuit_stream_is_being_handled(TO_EDGE_CONN(conn), 0,
+      !circuit_stream_is_being_handled(TO_ENTRY_CONN(conn), 0,
                                        MIN_CIRCUITS_HANDLING_STREAM))
     return 1;
   return 0;
@@ -2760,7 +2765,7 @@ choose_good_exit_server_general(int need_uptime, int need_capacity)
     SMARTLIST_FOREACH_BEGIN(connections, connection_t *, conn) {
       if (!ap_stream_wants_exit_attention(conn))
         continue; /* Skip everything but APs in CIRCUIT_WAIT */
-      if (connection_ap_can_use_exit(TO_EDGE_CONN(conn), node)) {
+      if (connection_ap_can_use_exit(TO_ENTRY_CONN(conn), node)) {
         ++n_supported[i];
 //        log_fn(LOG_DEBUG,"%s is supported. n_supported[%d] now %d.",
 //               router->nickname, i, n_supported[i]);

+ 54 - 45
src/or/circuituse.c

@@ -41,7 +41,7 @@ static void circuit_increment_failure_count(void);
  */
 static int
 circuit_is_acceptable(const origin_circuit_t *origin_circ,
-                      const edge_connection_t *conn,
+                      const entry_connection_t *conn,
                       int must_be_open, uint8_t purpose,
                       int need_uptime, int need_internal,
                       time_t now)
@@ -135,10 +135,11 @@ circuit_is_acceptable(const origin_circuit_t *origin_circ,
       return 0;
     }
   } else { /* not general */
-    if ((conn->rend_data && !origin_circ->rend_data) ||
-        (!conn->rend_data && origin_circ->rend_data) ||
-        (conn->rend_data && origin_circ->rend_data &&
-         rend_cmp_service_ids(conn->rend_data->onion_address,
+    const edge_connection_t *edge_conn = ENTRY_TO_EDGE_CONN(conn);
+    if ((edge_conn->rend_data && !origin_circ->rend_data) ||
+        (!edge_conn->rend_data && origin_circ->rend_data) ||
+        (edge_conn->rend_data && origin_circ->rend_data &&
+         rend_cmp_service_ids(edge_conn->rend_data->onion_address,
                               origin_circ->rend_data->onion_address))) {
       /* this circ is not for this conn */
       return 0;
@@ -159,11 +160,11 @@ circuit_is_acceptable(const origin_circuit_t *origin_circ,
  */
 static int
 circuit_is_better(const origin_circuit_t *oa, const origin_circuit_t *ob,
-                  const edge_connection_t *conn)
+                  const entry_connection_t *conn)
 {
   const circuit_t *a = TO_CIRCUIT(oa);
   const circuit_t *b = TO_CIRCUIT(ob);
-  const uint8_t purpose = conn->_base.purpose;
+  const uint8_t purpose = ENTRY_TO_CONN(conn)->purpose;
   int a_bits, b_bits;
 
   switch (purpose) {
@@ -241,7 +242,7 @@ circuit_is_better(const origin_circuit_t *oa, const origin_circuit_t *ob,
  * closest introduce-purposed circuit that you can find.
  */
 static origin_circuit_t *
-circuit_get_best(const edge_connection_t *conn,
+circuit_get_best(const entry_connection_t *conn,
                  int must_be_open, uint8_t purpose,
                  int need_uptime, int need_internal)
 {
@@ -544,7 +545,7 @@ circuit_remove_handled_ports(smartlist_t *needed_ports)
  * Else return 0.
  */
 int
-circuit_stream_is_being_handled(edge_connection_t *conn,
+circuit_stream_is_being_handled(entry_connection_t *conn,
                                 uint16_t port, int min)
 {
   circuit_t *circ;
@@ -738,8 +739,11 @@ circuit_detach_stream(circuit_t *circ, edge_connection_t *conn)
   tor_assert(circ);
   tor_assert(conn);
 
-  conn->cpath_layer = NULL; /* make sure we don't keep a stale pointer */
-  conn->may_use_optimistic_data = 0;
+  if (conn->_base.type == CONN_TYPE_AP) {
+    entry_connection_t *entry_conn = EDGE_TO_ENTRY_CONN(conn);
+    entry_conn->may_use_optimistic_data = 0;
+  }
+  conn->cpath_layer = NULL; /* don't keep a stale pointer */
   conn->on_circuit = NULL;
 
   if (CIRCUIT_IS_ORIGIN(circ)) {
@@ -1286,7 +1290,7 @@ circuit_reset_failure_count(int timeout)
  * Write the found or in-progress or launched circ into *circp.
  */
 static int
-circuit_get_open_circ_or_launch(edge_connection_t *conn,
+circuit_get_open_circ_or_launch(entry_connection_t *conn,
                                 uint8_t desired_circuit_purpose,
                                 origin_circuit_t **circp)
 {
@@ -1298,11 +1302,11 @@ circuit_get_open_circ_or_launch(edge_connection_t *conn,
 
   tor_assert(conn);
   tor_assert(circp);
-  tor_assert(conn->_base.state == AP_CONN_STATE_CIRCUIT_WAIT);
+  tor_assert(ENTRY_TO_CONN(conn)->state == AP_CONN_STATE_CIRCUIT_WAIT);
   check_exit_policy =
       conn->socks_request->command == SOCKS_COMMAND_CONNECT &&
       !conn->use_begindir &&
-      !connection_edge_is_rendezvous_stream(conn);
+      !connection_edge_is_rendezvous_stream(ENTRY_TO_EDGE_CONN(conn));
   want_onehop = conn->want_onehop;
 
   need_uptime = !conn->want_onehop && !conn->use_begindir &&
@@ -1410,19 +1414,20 @@ circuit_get_open_circ_or_launch(edge_connection_t *conn,
 
     if (desired_circuit_purpose == CIRCUIT_PURPOSE_C_INTRODUCE_ACK_WAIT) {
       /* need to pick an intro point */
-      tor_assert(conn->rend_data);
-      extend_info = rend_client_get_random_intro(conn->rend_data);
+      rend_data_t *rend_data = ENTRY_TO_EDGE_CONN(conn)->rend_data;
+      tor_assert(rend_data);
+      extend_info = rend_client_get_random_intro(rend_data);
       if (!extend_info) {
         log_info(LD_REND,
                  "No intro points for '%s': re-fetching service descriptor.",
-                 safe_str_client(conn->rend_data->onion_address));
-        rend_client_refetch_v2_renddesc(conn->rend_data);
-        conn->_base.state = AP_CONN_STATE_RENDDESC_WAIT;
+                 safe_str_client(rend_data->onion_address));
+        rend_client_refetch_v2_renddesc(rend_data);
+        ENTRY_TO_CONN(conn)->state = AP_CONN_STATE_RENDDESC_WAIT;
         return 0;
       }
       log_info(LD_REND,"Chose %s as intro point for '%s'.",
                extend_info_describe(extend_info),
-               safe_str_client(conn->rend_data->onion_address));
+               safe_str_client(rend_data->onion_address));
     }
 
     /* If we have specified a particular exit node for our
@@ -1511,7 +1516,7 @@ circuit_get_open_circ_or_launch(edge_connection_t *conn,
       rep_hist_note_used_internal(time(NULL), need_uptime, 1);
       if (circ) {
         /* write the service_id into circ */
-        circ->rend_data = rend_data_dup(conn->rend_data);
+        circ->rend_data = rend_data_dup(ENTRY_TO_EDGE_CONN(conn)->rend_data);
         if (circ->_base.purpose == CIRCUIT_PURPOSE_C_ESTABLISH_REND &&
             circ->_base.state == CIRCUIT_STATE_OPEN)
           rend_client_rendcirc_has_opened(circ);
@@ -1569,7 +1574,7 @@ optimistic_data_enabled(void)
  * hop in circ's cpath if <b>cpath</b> is NULL.
  */
 static void
-link_apconn_to_circ(edge_connection_t *apconn, origin_circuit_t *circ,
+link_apconn_to_circ(entry_connection_t *apconn, origin_circuit_t *circ,
                     crypt_path_t *cpath)
 {
   const node_t *exitnode;
@@ -1578,29 +1583,29 @@ link_apconn_to_circ(edge_connection_t *apconn, origin_circuit_t *circ,
   log_debug(LD_APP|LD_CIRC, "attaching new conn to circ. n_circ_id %d.",
             circ->_base.n_circ_id);
   /* reset it, so we can measure circ timeouts */
-  apconn->_base.timestamp_lastread = time(NULL);
-  apconn->next_stream = circ->p_streams;
-  apconn->on_circuit = TO_CIRCUIT(circ);
+  ENTRY_TO_CONN(apconn)->timestamp_lastread = time(NULL);
+  ENTRY_TO_EDGE_CONN(apconn)->next_stream = circ->p_streams;
+  ENTRY_TO_EDGE_CONN(apconn)->on_circuit = TO_CIRCUIT(circ);
   /* assert_connection_ok(conn, time(NULL)); */
-  circ->p_streams = apconn;
+  circ->p_streams = ENTRY_TO_EDGE_CONN(apconn);
 
   if (cpath) { /* we were given one; use it */
     tor_assert(cpath_is_on_circuit(circ, cpath));
-    apconn->cpath_layer = cpath;
-  } else { /* use the last hop in the circuit */
+  } else {
+    /* use the last hop in the circuit */
     tor_assert(circ->cpath);
     tor_assert(circ->cpath->prev);
     tor_assert(circ->cpath->prev->state == CPATH_STATE_OPEN);
-    apconn->cpath_layer = circ->cpath->prev;
+    cpath = circ->cpath->prev;
   }
+  ENTRY_TO_EDGE_CONN(apconn)->cpath_layer = cpath;
 
   circ->isolation_any_streams_attached = 1;
   connection_edge_update_circuit_isolation(apconn, circ, 0);
 
   /* See if we can use optimistic data on this circuit */
-  if (apconn->cpath_layer->extend_info &&
-      (exitnode = node_get_by_id(
-                     apconn->cpath_layer->extend_info->identity_digest)) &&
+  if (cpath->extend_info &&
+      (exitnode = node_get_by_id(cpath->extend_info->identity_digest)) &&
       exitnode->rs) {
     /* Okay; we know what exit node this is. */
     if (optimistic_data_enabled() &&
@@ -1642,7 +1647,7 @@ hostname_in_track_host_exits(const or_options_t *options, const char *address)
  * <b>conn</b>'s destination.
  */
 static void
-consider_recording_trackhost(const edge_connection_t *conn,
+consider_recording_trackhost(const entry_connection_t *conn,
                              const origin_circuit_t *circ)
 {
   const or_options_t *options = get_options();
@@ -1680,18 +1685,19 @@ consider_recording_trackhost(const edge_connection_t *conn,
  * indicated by <b>cpath</b>, or from the last hop in circ's cpath if
  * <b>cpath</b> is NULL. */
 int
-connection_ap_handshake_attach_chosen_circuit(edge_connection_t *conn,
+connection_ap_handshake_attach_chosen_circuit(entry_connection_t *conn,
                                               origin_circuit_t *circ,
                                               crypt_path_t *cpath)
 {
+  connection_t *base_conn = ENTRY_TO_CONN(conn);
   tor_assert(conn);
-  tor_assert(conn->_base.state == AP_CONN_STATE_CIRCUIT_WAIT ||
-             conn->_base.state == AP_CONN_STATE_CONTROLLER_WAIT);
+  tor_assert(base_conn->state == AP_CONN_STATE_CIRCUIT_WAIT ||
+             base_conn->state == AP_CONN_STATE_CONTROLLER_WAIT);
   tor_assert(conn->socks_request);
   tor_assert(circ);
   tor_assert(circ->_base.state == CIRCUIT_STATE_OPEN);
 
-  conn->_base.state = AP_CONN_STATE_CIRCUIT_WAIT;
+  base_conn->state = AP_CONN_STATE_CIRCUIT_WAIT;
 
   if (!circ->_base.timestamp_dirty)
     circ->_base.timestamp_dirty = time(NULL);
@@ -1721,21 +1727,22 @@ connection_ap_handshake_attach_chosen_circuit(edge_connection_t *conn,
 /* XXXX this function should mark for close whenever it returns -1;
  * its callers shouldn't have to worry about that. */
 int
-connection_ap_handshake_attach_circuit(edge_connection_t *conn)
+connection_ap_handshake_attach_circuit(entry_connection_t *conn)
 {
+  connection_t *base_conn = ENTRY_TO_CONN(conn);
   int retval;
   int conn_age;
   int want_onehop;
 
   tor_assert(conn);
-  tor_assert(conn->_base.state == AP_CONN_STATE_CIRCUIT_WAIT);
+  tor_assert(base_conn->state == AP_CONN_STATE_CIRCUIT_WAIT);
   tor_assert(conn->socks_request);
   want_onehop = conn->want_onehop;
 
-  conn_age = (int)(time(NULL) - conn->_base.timestamp_created);
+  conn_age = (int)(time(NULL) - base_conn->timestamp_created);
 
   if (conn_age >= get_options()->SocksTimeout) {
-    int severity = (tor_addr_is_null(&conn->_base.addr) && !conn->_base.port) ?
+    int severity = (tor_addr_is_null(&base_conn->addr) && !base_conn->port) ?
       LOG_INFO : LOG_NOTICE;
     log_fn(severity, LD_APP,
            "Tried for %d seconds to get a connection to %s:%d. Giving up.",
@@ -1744,7 +1751,8 @@ connection_ap_handshake_attach_circuit(edge_connection_t *conn)
     return -1;
   }
 
-  if (!connection_edge_is_rendezvous_stream(conn)) { /* we're a general conn */
+  if (!connection_edge_is_rendezvous_stream(ENTRY_TO_EDGE_CONN(conn))) {
+    /* we're a general conn */
     origin_circuit_t *circ=NULL;
 
     if (conn->chosen_exit_name) {
@@ -1799,7 +1807,7 @@ connection_ap_handshake_attach_circuit(edge_connection_t *conn)
   } else { /* we're a rendezvous conn */
     origin_circuit_t *rendcirc=NULL, *introcirc=NULL;
 
-    tor_assert(!conn->cpath_layer);
+    tor_assert(!ENTRY_TO_EDGE_CONN(conn)->cpath_layer);
 
     /* start by finding a rendezvous circuit for us */
 
@@ -1855,8 +1863,9 @@ connection_ap_handshake_attach_circuit(edge_connection_t *conn)
             !c->marked_for_close && CIRCUIT_IS_ORIGIN(c)) {
           origin_circuit_t *oc = TO_ORIGIN_CIRCUIT(c);
           if (oc->rend_data &&
-              !rend_cmp_service_ids(conn->rend_data->onion_address,
-                                    oc->rend_data->onion_address)) {
+              !rend_cmp_service_ids(
+                            ENTRY_TO_EDGE_CONN(conn)->rend_data->onion_address,
+                            oc->rend_data->onion_address)) {
             log_info(LD_REND|LD_CIRC, "Closing introduction circuit that we "
                      "built in parallel.");
             circuit_mark_for_close(c, END_CIRC_REASON_TIMEOUT);

+ 3 - 3
src/or/circuituse.h

@@ -14,7 +14,7 @@
 
 void circuit_expire_building(void);
 void circuit_remove_handled_ports(smartlist_t *needed_ports);
-int circuit_stream_is_being_handled(edge_connection_t *conn, uint16_t port,
+int circuit_stream_is_being_handled(entry_connection_t *conn, uint16_t port,
                                     int min);
 #if 0
 int circuit_conforms_to_options(const origin_circuit_t *circ,
@@ -45,10 +45,10 @@ origin_circuit_t *circuit_launch_by_extend_info(uint8_t purpose,
                                                 int flags);
 origin_circuit_t *circuit_launch(uint8_t purpose, int flags);
 void circuit_reset_failure_count(int timeout);
-int connection_ap_handshake_attach_chosen_circuit(edge_connection_t *conn,
+int connection_ap_handshake_attach_chosen_circuit(entry_connection_t *conn,
                                                   origin_circuit_t *circ,
                                                   crypt_path_t *cpath);
-int connection_ap_handshake_attach_circuit(edge_connection_t *conn);
+int connection_ap_handshake_attach_circuit(entry_connection_t *conn);
 
 int hostname_in_track_host_exits(const or_options_t *options,
                                  const char *address);

+ 64 - 42
src/or/connection.c

@@ -243,16 +243,26 @@ or_connection_new(int socket_family)
   return or_conn;
 }
 
+/** Allocate and return a new entry_connection_t, initialized as by
+ * connection_init(). */
+entry_connection_t *
+entry_connection_new(int type, int socket_family)
+{
+  entry_connection_t *entry_conn = tor_malloc_zero(sizeof(entry_connection_t));
+  tor_assert(type == CONN_TYPE_AP);
+  connection_init(time(NULL), ENTRY_TO_CONN(entry_conn), type, socket_family);
+  entry_conn->socks_request = socks_request_new();
+  return entry_conn;
+}
+
 /** Allocate and return a new edge_connection_t, initialized as by
  * connection_init(). */
 edge_connection_t *
 edge_connection_new(int type, int socket_family)
 {
   edge_connection_t *edge_conn = tor_malloc_zero(sizeof(edge_connection_t));
-  tor_assert(type == CONN_TYPE_EXIT || type == CONN_TYPE_AP);
+  tor_assert(type == CONN_TYPE_EXIT);
   connection_init(time(NULL), TO_CONN(edge_conn), type, socket_family);
-  if (type == CONN_TYPE_AP)
-    edge_conn->socks_request = socks_request_new();
   return edge_conn;
 }
 
@@ -291,9 +301,11 @@ connection_new(int type, int socket_family)
       return TO_CONN(or_connection_new(socket_family));
 
     case CONN_TYPE_EXIT:
-    case CONN_TYPE_AP:
       return TO_CONN(edge_connection_new(type, socket_family));
 
+    case CONN_TYPE_AP:
+      return ENTRY_TO_CONN(entry_connection_new(type, socket_family));
+
     case CONN_TYPE_DIR:
       return TO_CONN(dir_connection_new(socket_family));
 
@@ -334,9 +346,11 @@ connection_init(time_t now, connection_t *conn, int type, int socket_family)
       conn->magic = OR_CONNECTION_MAGIC;
       break;
     case CONN_TYPE_EXIT:
-    case CONN_TYPE_AP:
       conn->magic = EDGE_CONNECTION_MAGIC;
       break;
+    case CONN_TYPE_AP:
+      conn->magic = ENTRY_CONNECTION_MAGIC;
+      break;
     case CONN_TYPE_DIR:
       conn->magic = DIR_CONNECTION_MAGIC;
       break;
@@ -402,6 +416,10 @@ _connection_free(connection_t *conn)
       memlen = sizeof(or_connection_t);
       break;
     case CONN_TYPE_AP:
+      tor_assert(conn->magic == ENTRY_CONNECTION_MAGIC);
+      mem = TO_ENTRY_CONN(conn);
+      memlen = sizeof(entry_connection_t);
+      break;
     case CONN_TYPE_EXIT:
       tor_assert(conn->magic == EDGE_CONNECTION_MAGIC);
       mem = TO_EDGE_CONN(conn);
@@ -465,19 +483,21 @@ _connection_free(connection_t *conn)
     smartlist_free(or_conn->active_circuit_pqueue);
     tor_free(or_conn->nickname);
   }
-  if (CONN_IS_EDGE(conn)) {
-    edge_connection_t *edge_conn = TO_EDGE_CONN(conn);
-    tor_free(edge_conn->chosen_exit_name);
-    tor_free(edge_conn->original_dest_address);
-    if (edge_conn->socks_request)
-      socks_request_free(edge_conn->socks_request);
-    if (edge_conn->pending_optimistic_data) {
-      generic_buffer_free(edge_conn->pending_optimistic_data);
+  if (conn->type == CONN_TYPE_AP) {
+    entry_connection_t *entry_conn = TO_ENTRY_CONN(conn);
+    tor_free(entry_conn->chosen_exit_name);
+    tor_free(entry_conn->original_dest_address);
+    if (entry_conn->socks_request)
+      socks_request_free(entry_conn->socks_request);
+    if (entry_conn->pending_optimistic_data) {
+      generic_buffer_free(entry_conn->pending_optimistic_data);
     }
-    if (edge_conn->sending_optimistic_data) {
-      generic_buffer_free(edge_conn->sending_optimistic_data);
+    if (entry_conn->sending_optimistic_data) {
+      generic_buffer_free(entry_conn->sending_optimistic_data);
     }
-    rend_data_free(edge_conn->rend_data);
+  }
+  if (CONN_IS_EDGE(conn)) {
+    rend_data_free(TO_EDGE_CONN(conn)->rend_data);
   }
   if (conn->type == CONN_TYPE_CONTROL) {
     control_connection_t *control_conn = TO_CONTROL_CONN(conn);
@@ -587,7 +607,7 @@ connection_about_to_close_connection(connection_t *conn)
       connection_or_about_to_close(TO_OR_CONN(conn));
       break;
     case CONN_TYPE_AP:
-      connection_ap_about_to_close(TO_EDGE_CONN(conn));
+      connection_ap_about_to_close(TO_ENTRY_CONN(conn));
       break;
     case CONN_TYPE_EXIT:
       connection_exit_about_to_close(TO_EDGE_CONN(conn));
@@ -1211,20 +1231,20 @@ connection_init_accepted_conn(connection_t *conn,
       control_event_or_conn_status(TO_OR_CONN(conn), OR_CONN_EVENT_NEW, 0);
       return connection_tls_start_handshake(TO_OR_CONN(conn), 1);
     case CONN_TYPE_AP:
-      TO_EDGE_CONN(conn)->isolation_flags = listener->isolation_flags;
-      TO_EDGE_CONN(conn)->session_group = listener->session_group;
-      TO_EDGE_CONN(conn)->nym_epoch = get_signewnym_epoch();
-      TO_EDGE_CONN(conn)->socks_request->listener_type = listener->_base.type;
+      TO_ENTRY_CONN(conn)->isolation_flags = listener->isolation_flags;
+      TO_ENTRY_CONN(conn)->session_group = listener->session_group;
+      TO_ENTRY_CONN(conn)->nym_epoch = get_signewnym_epoch();
+      TO_ENTRY_CONN(conn)->socks_request->listener_type = listener->_base.type;
       switch (TO_CONN(listener)->type) {
         case CONN_TYPE_AP_LISTENER:
           conn->state = AP_CONN_STATE_SOCKS_WAIT;
           break;
         case CONN_TYPE_AP_TRANS_LISTENER:
-          TO_EDGE_CONN(conn)->is_transparent_ap = 1;
+          TO_ENTRY_CONN(conn)->is_transparent_ap = 1;
           conn->state = AP_CONN_STATE_CIRCUIT_WAIT;
-          return connection_ap_process_transparent(TO_EDGE_CONN(conn));
+          return connection_ap_process_transparent(TO_ENTRY_CONN(conn));
         case CONN_TYPE_AP_NATD_LISTENER:
-          TO_EDGE_CONN(conn)->is_transparent_ap = 1;
+          TO_ENTRY_CONN(conn)->is_transparent_ap = 1;
           conn->state = AP_CONN_STATE_NATD_WAIT;
           break;
       }
@@ -2616,8 +2636,10 @@ connection_handle_read_impl(connection_t *conn)
     if (CONN_IS_EDGE(conn)) {
       edge_connection_t *edge_conn = TO_EDGE_CONN(conn);
       connection_edge_end_errno(edge_conn);
-      if (edge_conn->socks_request) /* broken, don't send a socks reply back */
-        edge_conn->socks_request->has_finished = 1;
+      if (conn->type == CONN_TYPE_AP && TO_ENTRY_CONN(conn)->socks_request) {
+        /* broken, don't send a socks reply back */
+        TO_ENTRY_CONN(conn)->socks_request->has_finished = 1;
+      }
     }
     connection_close_immediate(conn); /* Don't flush; connection is dead. */
     connection_mark_for_close(conn);
@@ -2959,8 +2981,10 @@ connection_handle_event_cb(struct bufferevent *bufev, short event, void *arg)
       edge_connection_t *edge_conn = TO_EDGE_CONN(conn);
       if (!edge_conn->edge_has_sent_end)
         connection_edge_end_errno(edge_conn);
-      if (edge_conn->socks_request) /* broken, don't send a socks reply back */
-        edge_conn->socks_request->has_finished = 1;
+      if (conn->type == CONN_TYPE_AP && TO_ENTRY_CONN(conn)->socks_request) {
+        /* broken, don't send a socks reply back */
+        TO_ENTRY_CONN(conn)->socks_request->has_finished = 1;
+      }
     }
     connection_close_immediate(conn); /* Connection is dead. */
     if (!conn->marked_for_close)
@@ -3495,8 +3519,7 @@ connection_get_by_type_state_rendquery(int type, int state,
              type == CONN_TYPE_AP || type == CONN_TYPE_EXIT);
   tor_assert(rendquery);
 
-  SMARTLIST_FOREACH(conns, connection_t *, conn,
-  {
+  SMARTLIST_FOREACH_BEGIN(conns, connection_t *, conn) {
     if (conn->type == type &&
         !conn->marked_for_close &&
         (!state || state == conn->state)) {
@@ -3511,7 +3534,7 @@ connection_get_by_type_state_rendquery(int type, int state,
                             TO_EDGE_CONN(conn)->rend_data->onion_address))
         return conn;
     }
-  });
+  } SMARTLIST_FOREACH_END(conn);
   return NULL;
 }
 
@@ -3934,6 +3957,8 @@ assert_connection_ok(connection_t *conn, time_t now)
       tor_assert(conn->magic == OR_CONNECTION_MAGIC);
       break;
     case CONN_TYPE_AP:
+      tor_assert(conn->magic == ENTRY_CONNECTION_MAGIC);
+      break;
     case CONN_TYPE_EXIT:
       tor_assert(conn->magic == EDGE_CONNECTION_MAGIC);
       break;
@@ -4000,21 +4025,18 @@ assert_connection_ok(connection_t *conn, time_t now)
   }
 
   if (CONN_IS_EDGE(conn)) {
-    edge_connection_t *edge_conn = TO_EDGE_CONN(conn);
-    if (edge_conn->chosen_exit_optional || edge_conn->chosen_exit_retries) {
-      tor_assert(conn->type == CONN_TYPE_AP);
-      tor_assert(edge_conn->chosen_exit_name);
-    }
-
     /* XXX unchecked: package window, deliver window. */
     if (conn->type == CONN_TYPE_AP) {
+      entry_connection_t *entry_conn = TO_ENTRY_CONN(conn);
+      if (entry_conn->chosen_exit_optional || entry_conn->chosen_exit_retries)
+        tor_assert(entry_conn->chosen_exit_name);
 
-      tor_assert(edge_conn->socks_request);
+      tor_assert(entry_conn->socks_request);
       if (conn->state == AP_CONN_STATE_OPEN) {
-        tor_assert(edge_conn->socks_request->has_finished);
+        tor_assert(entry_conn->socks_request->has_finished);
         if (!conn->marked_for_close) {
-          tor_assert(edge_conn->cpath_layer);
-          assert_cpath_layer_ok(edge_conn->cpath_layer);
+          tor_assert(ENTRY_TO_EDGE_CONN(entry_conn)->cpath_layer);
+          assert_cpath_layer_ok(ENTRY_TO_EDGE_CONN(entry_conn)->cpath_layer);
         }
       }
     }
@@ -4047,7 +4069,7 @@ assert_connection_ok(connection_t *conn, time_t now)
     case CONN_TYPE_AP:
       tor_assert(conn->state >= _AP_CONN_STATE_MIN);
       tor_assert(conn->state <= _AP_CONN_STATE_MAX);
-      tor_assert(TO_EDGE_CONN(conn)->socks_request);
+      tor_assert(TO_ENTRY_CONN(conn)->socks_request);
       break;
     case CONN_TYPE_DIR:
       tor_assert(conn->state >= _DIR_CONN_STATE_MIN);

+ 1 - 0
src/or/connection.h

@@ -21,6 +21,7 @@ const char *conn_state_to_string(int type, int state);
 dir_connection_t *dir_connection_new(int socket_family);
 or_connection_t *or_connection_new(int socket_family);
 edge_connection_t *edge_connection_new(int type, int socket_family);
+entry_connection_t *entry_connection_new(int type, int socket_family);
 control_connection_t *control_connection_new(int socket_family);
 listener_connection_t *listener_connection_new(int type, int socket_family);
 connection_t *connection_new(int type, int socket_family);

File diff suppressed because it is too large
+ 206 - 191
src/or/connection_edge.c


+ 15 - 14
src/or/connection_edge.h

@@ -15,7 +15,7 @@
 #define connection_mark_unattached_ap(conn, endreason) \
   _connection_mark_unattached_ap((conn), (endreason), __LINE__, _SHORT_FILE_)
 
-void _connection_mark_unattached_ap(edge_connection_t *conn, int endreason,
+void _connection_mark_unattached_ap(entry_connection_t *conn, int endreason,
                                     int line, const char *file);
 int connection_edge_reached_eof(edge_connection_t *conn);
 int connection_edge_process_inbuf(edge_connection_t *conn,
@@ -27,22 +27,22 @@ int connection_edge_flushed_some(edge_connection_t *conn);
 int connection_edge_finished_flushing(edge_connection_t *conn);
 int connection_edge_finished_connecting(edge_connection_t *conn);
 
-void connection_ap_about_to_close(edge_connection_t *edge_conn);
+void connection_ap_about_to_close(entry_connection_t *edge_conn);
 void connection_exit_about_to_close(edge_connection_t *edge_conn);
 
-int connection_ap_handshake_send_begin(edge_connection_t *ap_conn);
-int connection_ap_handshake_send_resolve(edge_connection_t *ap_conn);
+int connection_ap_handshake_send_begin(entry_connection_t *ap_conn);
+int connection_ap_handshake_send_resolve(entry_connection_t *ap_conn);
 
-edge_connection_t  *connection_ap_make_link(connection_t *partner,
+entry_connection_t  *connection_ap_make_link(connection_t *partner,
                                             char *address, uint16_t port,
                                             const char *digest,
                                             int session_group,
                                             int isolation_flags,
                                             int use_begindir, int want_onehop);
-void connection_ap_handshake_socks_reply(edge_connection_t *conn, char *reply,
+void connection_ap_handshake_socks_reply(entry_connection_t *conn, char *reply,
                                          size_t replylen,
                                          int endreason);
-void connection_ap_handshake_socks_resolved(edge_connection_t *conn,
+void connection_ap_handshake_socks_resolved(entry_connection_t *conn,
                                             int answer_type,
                                             size_t answer_len,
                                             const uint8_t *answer,
@@ -53,17 +53,17 @@ int connection_exit_begin_conn(cell_t *cell, circuit_t *circ);
 int connection_exit_begin_resolve(cell_t *cell, or_circuit_t *circ);
 void connection_exit_connect(edge_connection_t *conn);
 int connection_edge_is_rendezvous_stream(edge_connection_t *conn);
-int connection_ap_can_use_exit(const edge_connection_t *conn,
+int connection_ap_can_use_exit(const entry_connection_t *conn,
                                const node_t *exit);
 void connection_ap_expire_beginning(void);
 void connection_ap_attach_pending(void);
 void connection_ap_fail_onehop(const char *failed_digest,
                                cpath_build_state_t *build_state);
 void circuit_discard_optional_exit_enclaves(extend_info_t *info);
-int connection_ap_detach_retriable(edge_connection_t *conn,
+int connection_ap_detach_retriable(entry_connection_t *conn,
                                    origin_circuit_t *circ,
                                    int reason);
-int connection_ap_process_transparent(edge_connection_t *conn);
+int connection_ap_process_transparent(entry_connection_t *conn);
 
 int address_is_invalid_destination(const char *address, int client);
 
@@ -88,10 +88,10 @@ void client_dns_set_addressmap(const char *address, uint32_t val,
 const char *addressmap_register_virtual_address(int type, char *new_address);
 void addressmap_get_mappings(smartlist_t *sl, time_t min_expires,
                              time_t max_expires, int want_expiry);
-int connection_ap_rewrite_and_attach_if_allowed(edge_connection_t *conn,
+int connection_ap_rewrite_and_attach_if_allowed(entry_connection_t *conn,
                                                 origin_circuit_t *circ,
                                                 crypt_path_t *cpath);
-int connection_ap_handshake_rewrite_and_attach(edge_connection_t *conn,
+int connection_ap_handshake_rewrite_and_attach(entry_connection_t *conn,
                                                origin_circuit_t *circ,
                                                crypt_path_t *cpath);
 
@@ -105,9 +105,10 @@ hostname_type_t parse_extended_hostname(char *address, int allowdotexit);
 int get_pf_socket(void);
 #endif
 
-int connection_edge_compatible_with_circuit(const edge_connection_t *conn,
+
+int connection_edge_compatible_with_circuit(const entry_connection_t *conn,
                                             const origin_circuit_t *circ);
-int connection_edge_update_circuit_isolation(const edge_connection_t *conn,
+int connection_edge_update_circuit_isolation(const entry_connection_t *conn,
                                              origin_circuit_t *circ,
                                              int dry_run);
 void circuit_clear_isolation(origin_circuit_t *circ);

+ 33 - 31
src/or/control.c

@@ -177,7 +177,7 @@ static int handle_control_resolve(control_connection_t *conn, uint32_t len,
 static int handle_control_usefeature(control_connection_t *conn,
                                      uint32_t len,
                                      const char *body);
-static int write_stream_target_to_buf(edge_connection_t *conn, char *buf,
+static int write_stream_target_to_buf(entry_connection_t *conn, char *buf,
                                       size_t len);
 static void orconn_target_get_name(char *buf, size_t len,
                                    or_connection_t *conn);
@@ -656,7 +656,7 @@ get_circ(const char *id)
 }
 
 /** Given a text stream <b>id</b>, return the corresponding AP connection. */
-static edge_connection_t *
+static entry_connection_t *
 get_stream(const char *id)
 {
   uint64_t n_id;
@@ -668,7 +668,7 @@ get_stream(const char *id)
   conn = connection_get_by_global_id(n_id);
   if (!conn || conn->type != CONN_TYPE_AP || conn->marked_for_close)
     return NULL;
-  return TO_EDGE_CONN(conn);
+  return TO_ENTRY_CONN(conn);
 }
 
 /** Helper for setconf and resetconf. Acts like setconf, except
@@ -1802,7 +1802,7 @@ getinfo_helper_events(control_connection_t *control_conn,
     char buf[256];
     SMARTLIST_FOREACH_BEGIN(conns, connection_t *, base_conn) {
       const char *state;
-      edge_connection_t *conn;
+      entry_connection_t *conn;
       char *s;
       size_t slen;
       circuit_t *circ;
@@ -1812,8 +1812,8 @@ getinfo_helper_events(control_connection_t *control_conn,
           base_conn->state == AP_CONN_STATE_SOCKS_WAIT ||
           base_conn->state == AP_CONN_STATE_NATD_WAIT)
         continue;
-      conn = TO_EDGE_CONN(base_conn);
-      switch (conn->_base.state)
+      conn = TO_ENTRY_CONN(base_conn);
+      switch (base_conn->state)
         {
         case AP_CONN_STATE_CONTROLLER_WAIT:
         case AP_CONN_STATE_CIRCUIT_WAIT:
@@ -1832,17 +1832,17 @@ getinfo_helper_events(control_connection_t *control_conn,
           state = "SUCCEEDED"; break;
         default:
           log_warn(LD_BUG, "Asked for stream in unknown state %d",
-                   conn->_base.state);
+                   base_conn->state);
           continue;
         }
-      circ = circuit_get_by_edge_conn(conn);
+      circ = circuit_get_by_edge_conn(ENTRY_TO_EDGE_CONN(conn));
       if (circ && CIRCUIT_IS_ORIGIN(circ))
         origin_circ = TO_ORIGIN_CIRCUIT(circ);
       write_stream_target_to_buf(conn, buf, sizeof(buf));
       slen = strlen(buf)+strlen(state)+32;
       s = tor_malloc(slen+1);
       tor_snprintf(s, slen, "%lu %s %lu %s",
-                   (unsigned long) conn->_base.global_identifier,state,
+                   (unsigned long) base_conn->global_identifier,state,
                    origin_circ?
                          (unsigned long)origin_circ->global_identifier : 0ul,
                    buf);
@@ -2462,7 +2462,7 @@ static int
 handle_control_attachstream(control_connection_t *conn, uint32_t len,
                             const char *body)
 {
-  edge_connection_t *ap_conn = NULL;
+  entry_connection_t *ap_conn = NULL;
   origin_circuit_t *circ = NULL;
   int zero_circ;
   smartlist_t *args;
@@ -2498,9 +2498,9 @@ handle_control_attachstream(control_connection_t *conn, uint32_t len,
   if (!ap_conn || (!zero_circ && !circ) || !hop_line_ok)
     return 0;
 
-  if (ap_conn->_base.state != AP_CONN_STATE_CONTROLLER_WAIT &&
-      ap_conn->_base.state != AP_CONN_STATE_CONNECT_WAIT &&
-      ap_conn->_base.state != AP_CONN_STATE_RESOLVE_WAIT) {
+  if (ENTRY_TO_CONN(ap_conn)->state != AP_CONN_STATE_CONTROLLER_WAIT &&
+      ENTRY_TO_CONN(ap_conn)->state != AP_CONN_STATE_CONNECT_WAIT &&
+      ENTRY_TO_CONN(ap_conn)->state != AP_CONN_STATE_RESOLVE_WAIT) {
     connection_write_str_to_buf(
                     "555 Connection is not managed by controller.\r\n",
                     conn);
@@ -2508,15 +2508,16 @@ handle_control_attachstream(control_connection_t *conn, uint32_t len,
   }
 
   /* Do we need to detach it first? */
-  if (ap_conn->_base.state != AP_CONN_STATE_CONTROLLER_WAIT) {
-    circuit_t *tmpcirc = circuit_get_by_edge_conn(ap_conn);
-    connection_edge_end(ap_conn, END_STREAM_REASON_TIMEOUT);
+  if (ENTRY_TO_CONN(ap_conn)->state != AP_CONN_STATE_CONTROLLER_WAIT) {
+    edge_connection_t *edge_conn = ENTRY_TO_EDGE_CONN(ap_conn);
+    circuit_t *tmpcirc = circuit_get_by_edge_conn(edge_conn);
+    connection_edge_end(edge_conn, END_STREAM_REASON_TIMEOUT);
     /* Un-mark it as ending, since we're going to reuse it. */
-    ap_conn->edge_has_sent_end = 0;
-    ap_conn->end_reason = 0;
+    edge_conn->edge_has_sent_end = 0;
+    edge_conn->end_reason = 0;
     if (tmpcirc)
-      circuit_detach_stream(tmpcirc,ap_conn);
-    ap_conn->_base.state = AP_CONN_STATE_CONTROLLER_WAIT;
+      circuit_detach_stream(tmpcirc, edge_conn);
+    TO_CONN(edge_conn)->state = AP_CONN_STATE_CONTROLLER_WAIT;
   }
 
   if (circ && (circ->_base.state != CIRCUIT_STATE_OPEN)) {
@@ -2638,7 +2639,7 @@ static int
 handle_control_redirectstream(control_connection_t *conn, uint32_t len,
                               const char *body)
 {
-  edge_connection_t *ap_conn = NULL;
+  entry_connection_t *ap_conn = NULL;
   char *new_addr = NULL;
   uint16_t new_port = 0;
   smartlist_t *args;
@@ -2686,7 +2687,7 @@ static int
 handle_control_closestream(control_connection_t *conn, uint32_t len,
                            const char *body)
 {
-  edge_connection_t *ap_conn=NULL;
+  entry_connection_t *ap_conn=NULL;
   uint8_t reason=0;
   smartlist_t *args;
   int ok;
@@ -3266,7 +3267,7 @@ control_event_circuit_status(origin_circuit_t *circ, circuit_status_event_t tp,
  * <b>conn</b>, and write it to <b>buf</b>.  Return 0 on success, -1 on
  * failure. */
 static int
-write_stream_target_to_buf(edge_connection_t *conn, char *buf, size_t len)
+write_stream_target_to_buf(entry_connection_t *conn, char *buf, size_t len)
 {
   char buf2[256];
   if (conn->chosen_exit_name)
@@ -3277,8 +3278,8 @@ write_stream_target_to_buf(edge_connection_t *conn, char *buf, size_t len)
   if (tor_snprintf(buf, len, "%s%s%s:%d",
                conn->socks_request->address,
                conn->chosen_exit_name ? buf2 : "",
-               !conn->chosen_exit_name &&
-                 connection_edge_is_rendezvous_stream(conn) ? ".onion" : "",
+               !conn->chosen_exit_name && connection_edge_is_rendezvous_stream(
+                                     ENTRY_TO_EDGE_CONN(conn)) ? ".onion" : "",
                conn->socks_request->port)<0)
     return -1;
   return 0;
@@ -3287,7 +3288,7 @@ write_stream_target_to_buf(edge_connection_t *conn, char *buf, size_t len)
 /** Something has happened to the stream associated with AP connection
  * <b>conn</b>: tell any interested control connections. */
 int
-control_event_stream_status(edge_connection_t *conn, stream_status_event_t tp,
+control_event_stream_status(entry_connection_t *conn, stream_status_event_t tp,
                             int reason_code)
 {
   char reason_buf[64];
@@ -3359,7 +3360,7 @@ control_event_stream_status(edge_connection_t *conn, stream_status_event_t tp,
 
   if (tp == STREAM_EVENT_NEW) {
     tor_snprintf(addrport_buf,sizeof(addrport_buf), " SOURCE_ADDR=%s:%d",
-                 TO_CONN(conn)->address, TO_CONN(conn)->port );
+                 ENTRY_TO_CONN(conn)->address, ENTRY_TO_CONN(conn)->port);
   } else {
     addrport_buf[0] = '\0';
   }
@@ -3367,12 +3368,12 @@ control_event_stream_status(edge_connection_t *conn, stream_status_event_t tp,
   if (tp == STREAM_EVENT_NEW_RESOLVE) {
     purpose = " PURPOSE=DNS_REQUEST";
   } else if (tp == STREAM_EVENT_NEW) {
-    if (conn->is_dns_request ||
+    if (ENTRY_TO_EDGE_CONN(conn)->is_dns_request ||
         (conn->socks_request &&
          SOCKS_COMMAND_IS_RESOLVE(conn->socks_request->command)))
       purpose = " PURPOSE=DNS_REQUEST";
     else if (conn->use_begindir) {
-      connection_t *linked = TO_CONN(conn)->linked_conn;
+      connection_t *linked = ENTRY_TO_CONN(conn)->linked_conn;
       int linked_dir_purpose = -1;
       if (linked && linked->type == CONN_TYPE_DIR)
         linked_dir_purpose = linked->purpose;
@@ -3384,12 +3385,13 @@ control_event_stream_status(edge_connection_t *conn, stream_status_event_t tp,
       purpose = " PURPOSE=USER";
   }
 
-  circ = circuit_get_by_edge_conn(conn);
+  circ = circuit_get_by_edge_conn(ENTRY_TO_EDGE_CONN(conn));
   if (circ && CIRCUIT_IS_ORIGIN(circ))
     origin_circ = TO_ORIGIN_CIRCUIT(circ);
   send_control_event(EVENT_STREAM_STATUS, ALL_FORMATS,
                         "650 STREAM "U64_FORMAT" %s %lu %s%s%s%s\r\n",
-                        U64_PRINTF_ARG(conn->_base.global_identifier), status,
+                     U64_PRINTF_ARG(ENTRY_TO_CONN(conn)->global_identifier),
+                     status,
                         origin_circ?
                            (unsigned long)origin_circ->global_identifier : 0ul,
                         buf, reason_buf, addrport_buf, purpose);

+ 1 - 1
src/or/control.h

@@ -37,7 +37,7 @@ int control_event_is_interesting(int event);
 
 int control_event_circuit_status(origin_circuit_t *circ,
                                  circuit_status_event_t e, int reason);
-int control_event_stream_status(edge_connection_t *conn,
+int control_event_stream_status(entry_connection_t *conn,
                                 stream_status_event_t e,
                                 int reason);
 int control_event_or_conn_status(or_connection_t *conn,

+ 5 - 4
src/or/directory.c

@@ -972,7 +972,7 @@ directory_initiate_command_rend(const char *address, const tor_addr_t *_addr,
            error indicates broken link in windowsland. */
     }
   } else { /* we want to connect via a tor connection */
-    edge_connection_t *linked_conn;
+    entry_connection_t *linked_conn;
     /* Anonymized tunneled connections can never share a circuit.
      * One-hop directory connections can share circuits with each other
      * but nothing else. */
@@ -1014,10 +1014,11 @@ directory_initiate_command_rend(const char *address, const tor_addr_t *_addr,
                            if_modified_since);
 
     connection_watch_events(TO_CONN(conn), READ_EVENT|WRITE_EVENT);
-    IF_HAS_BUFFEREVENT(TO_CONN(linked_conn), {
-      connection_watch_events(TO_CONN(linked_conn), READ_EVENT|WRITE_EVENT);
+    IF_HAS_BUFFEREVENT(ENTRY_TO_CONN(linked_conn), {
+      connection_watch_events(ENTRY_TO_CONN(linked_conn),
+                              READ_EVENT|WRITE_EVENT);
     }) ELSE_IF_NO_BUFFEREVENT
-      connection_start_reading(TO_CONN(linked_conn));
+      connection_start_reading(ENTRY_TO_CONN(linked_conn));
   }
 }
 

+ 32 - 28
src/or/dnsserv.c

@@ -32,6 +32,7 @@ static void
 evdns_server_callback(struct evdns_server_request *req, void *data_)
 {
   const listener_connection_t *listener = data_;
+  entry_connection_t *entry_conn;
   edge_connection_t *conn;
   int i = 0;
   struct evdns_server_question *q = NULL;
@@ -115,8 +116,9 @@ evdns_server_callback(struct evdns_server_request *req, void *data_)
   }
 
   /* Make a new dummy AP connection, and attach the request to it. */
-  conn = edge_connection_new(CONN_TYPE_AP, AF_INET);
-  conn->_base.state = AP_CONN_STATE_RESOLVE_WAIT;
+  entry_conn = entry_connection_new(CONN_TYPE_AP, AF_INET);
+  conn = ENTRY_TO_EDGE_CONN(entry_conn);
+  TO_CONN(conn)->state = AP_CONN_STATE_RESOLVE_WAIT;
   conn->is_dns_request = 1;
 
   tor_addr_copy(&TO_CONN(conn)->addr, &tor_addr);
@@ -124,27 +126,27 @@ evdns_server_callback(struct evdns_server_request *req, void *data_)
   TO_CONN(conn)->address = tor_dup_addr(&tor_addr);
 
   if (q->type == EVDNS_TYPE_A)
-    conn->socks_request->command = SOCKS_COMMAND_RESOLVE;
+    entry_conn->socks_request->command = SOCKS_COMMAND_RESOLVE;
   else
-    conn->socks_request->command = SOCKS_COMMAND_RESOLVE_PTR;
+    entry_conn->socks_request->command = SOCKS_COMMAND_RESOLVE_PTR;
 
-  strlcpy(conn->socks_request->address, q->name,
-          sizeof(conn->socks_request->address));
+  strlcpy(entry_conn->socks_request->address, q->name,
+          sizeof(entry_conn->socks_request->address));
 
-  conn->socks_request->listener_type = listener->_base.type;
-  conn->dns_server_request = req;
-  conn->isolation_flags = listener->isolation_flags;
-  conn->session_group = listener->session_group;
-  conn->nym_epoch = get_signewnym_epoch();
+  entry_conn->socks_request->listener_type = listener->_base.type;
+  entry_conn->dns_server_request = req;
+  entry_conn->isolation_flags = listener->isolation_flags;
+  entry_conn->session_group = listener->session_group;
+  entry_conn->nym_epoch = get_signewnym_epoch();
 
-  if (connection_add(TO_CONN(conn)) < 0) {
+  if (connection_add(ENTRY_TO_CONN(entry_conn)) < 0) {
     log_warn(LD_APP, "Couldn't register dummy connection for DNS request");
     evdns_server_request_respond(req, DNS_ERR_SERVERFAILED);
-    connection_free(TO_CONN(conn));
+    connection_free(ENTRY_TO_CONN(entry_conn));
     return;
   }
 
-  control_event_stream_status(conn, STREAM_EVENT_NEW, 0);
+  control_event_stream_status(entry_conn, STREAM_EVENT_NEW, 0);
 
   /* Now, unless a controller asked us to leave streams unattached,
   * throw the connection over to get rewritten (which will
@@ -153,7 +155,7 @@ evdns_server_callback(struct evdns_server_request *req, void *data_)
   log_info(LD_APP, "Passing request for %s to rewrite_and_attach.",
            escaped_safe_str_client(q->name));
   q_name = tor_strdup(q->name); /* q could be freed in rewrite_and_attach */
-  connection_ap_rewrite_and_attach_if_allowed(conn, NULL, NULL);
+  connection_ap_rewrite_and_attach_if_allowed(entry_conn, NULL, NULL);
   /* Now, the connection is marked if it was bad. */
 
   log_info(LD_APP, "Passed request for %s to rewrite_and_attach_if_allowed.",
@@ -169,28 +171,30 @@ evdns_server_callback(struct evdns_server_request *req, void *data_)
 int
 dnsserv_launch_request(const char *name, int reverse)
 {
+  entry_connection_t *entry_conn;
   edge_connection_t *conn;
   char *q_name;
 
   /* Make a new dummy AP connection, and attach the request to it. */
-  conn = edge_connection_new(CONN_TYPE_AP, AF_INET);
+  entry_conn = entry_connection_new(CONN_TYPE_AP, AF_INET);
+  conn = ENTRY_TO_EDGE_CONN(entry_conn);
   conn->_base.state = AP_CONN_STATE_RESOLVE_WAIT;
 
   if (reverse)
-    conn->socks_request->command = SOCKS_COMMAND_RESOLVE_PTR;
+    entry_conn->socks_request->command = SOCKS_COMMAND_RESOLVE_PTR;
   else
-    conn->socks_request->command = SOCKS_COMMAND_RESOLVE;
+    entry_conn->socks_request->command = SOCKS_COMMAND_RESOLVE;
 
   conn->is_dns_request = 1;
 
-  strlcpy(conn->socks_request->address, name,
-          sizeof(conn->socks_request->address));
+  strlcpy(entry_conn->socks_request->address, name,
+          sizeof(entry_conn->socks_request->address));
 
-  conn->socks_request->listener_type = CONN_TYPE_CONTROL_LISTENER;
-  conn->original_dest_address = tor_strdup(name);
-  conn->session_group = SESSION_GROUP_CONTROL_RESOLVE;
-  conn->nym_epoch = get_signewnym_epoch();
-  conn->isolation_flags = ISO_DEFAULT;
+  entry_conn->socks_request->listener_type = CONN_TYPE_CONTROL_LISTENER;
+  entry_conn->original_dest_address = tor_strdup(name);
+  entry_conn->session_group = SESSION_GROUP_CONTROL_RESOLVE;
+  entry_conn->nym_epoch = get_signewnym_epoch();
+  entry_conn->isolation_flags = ISO_DEFAULT;
 
   if (connection_add(TO_CONN(conn))<0) {
     log_warn(LD_APP, "Couldn't register dummy connection for RESOLVE request");
@@ -205,7 +209,7 @@ dnsserv_launch_request(const char *name, int reverse)
   log_info(LD_APP, "Passing request for %s to rewrite_and_attach.",
            escaped_safe_str_client(name));
   q_name = tor_strdup(name); /* q could be freed in rewrite_and_attach */
-  connection_ap_rewrite_and_attach_if_allowed(conn, NULL, NULL);
+  connection_ap_rewrite_and_attach_if_allowed(entry_conn, NULL, NULL);
   /* Now, the connection is marked if it was bad. */
 
   log_info(LD_APP, "Passed request for %s to rewrite_and_attach_if_allowed.",
@@ -217,7 +221,7 @@ dnsserv_launch_request(const char *name, int reverse)
 /** If there is a pending request on <b>conn</b> that's waiting for an answer,
  * send back an error and free the request. */
 void
-dnsserv_reject_request(edge_connection_t *conn)
+dnsserv_reject_request(entry_connection_t *conn)
 {
   if (conn->dns_server_request) {
     evdns_server_request_respond(conn->dns_server_request,
@@ -263,7 +267,7 @@ evdns_get_orig_address(const struct evdns_server_request *req,
  * <b>answer_len</b>, in <b>answer</b>, with TTL <b>ttl</b>.  Doesn't do
  * any caching; that's handled elsewhere. */
 void
-dnsserv_resolved(edge_connection_t *conn,
+dnsserv_resolved(entry_connection_t *conn,
                  int answer_type,
                  size_t answer_len,
                  const char *answer,

+ 2 - 2
src/or/dnsserv.h

@@ -14,12 +14,12 @@
 
 void dnsserv_configure_listener(connection_t *conn);
 void dnsserv_close_listener(connection_t *conn);
-void dnsserv_resolved(edge_connection_t *conn,
+void dnsserv_resolved(entry_connection_t *conn,
                       int answer_type,
                       size_t answer_len,
                       const char *answer,
                       int ttl);
-void dnsserv_reject_request(edge_connection_t *conn);
+void dnsserv_reject_request(entry_connection_t *conn);
 int dnsserv_launch_request(const char *name, int is_reverse);
 
 #endif

+ 1 - 1
src/or/hibernate.c

@@ -856,7 +856,7 @@ hibernate_go_dormant(time_t now)
       connection_edge_end(TO_EDGE_CONN(conn), END_STREAM_REASON_HIBERNATING);
     log_info(LD_NET,"Closing conn type %d", conn->type);
     if (conn->type == CONN_TYPE_AP) /* send socks failure if needed */
-      connection_mark_unattached_ap(TO_EDGE_CONN(conn),
+      connection_mark_unattached_ap(TO_ENTRY_CONN(conn),
                                     END_STREAM_REASON_HIBERNATING);
     else
       connection_mark_for_close(conn);

+ 4 - 4
src/or/main.c

@@ -865,13 +865,13 @@ directory_all_unreachable(time_t now)
 
   while ((conn = connection_get_by_type_state(CONN_TYPE_AP,
                                               AP_CONN_STATE_CIRCUIT_WAIT))) {
-    edge_connection_t *edge_conn = TO_EDGE_CONN(conn);
+    entry_connection_t *entry_conn = TO_ENTRY_CONN(conn);
     log_notice(LD_NET,
                "Is your network connection down? "
                "Failing connection to '%s:%d'.",
-               safe_str_client(edge_conn->socks_request->address),
-               edge_conn->socks_request->port);
-    connection_mark_unattached_ap(edge_conn,
+               safe_str_client(entry_conn->socks_request->address),
+               entry_conn->socks_request->port);
+    connection_mark_unattached_ap(entry_conn,
                                   END_STREAM_REASON_NET_UNREACHABLE);
   }
   control_event_general_status(LOG_ERR, "DIR_ALL_UNREACHABLE");

+ 69 - 35
src/or/or.h

@@ -941,6 +941,7 @@ typedef struct socks_request_t socks_request_t;
 #define BASE_CONNECTION_MAGIC 0x7C3C304Eu
 #define OR_CONNECTION_MAGIC 0x7D31FF03u
 #define EDGE_CONNECTION_MAGIC 0xF0374013u
+#define ENTRY_CONNECTION_MAGIC 0xbb4a5703
 #define DIR_CONNECTION_MAGIC 0x9988ffeeu
 #define CONTROL_CONNECTION_MAGIC 0x8abc765du
 #define LISTENER_CONNECTION_MAGIC 0x1a1ac741u
@@ -1173,27 +1174,27 @@ typedef struct or_connection_t {
                                               * identity digest as this one. */
 } or_connection_t;
 
-/** Subtype of connection_t for an "edge connection" -- that is, a socks (ap)
+/** Subtype of connection_t for an "edge connection" -- that is, an entry (ap)
  * connection, or an exit. */
 typedef struct edge_connection_t {
   connection_t _base;
 
   struct edge_connection_t *next_stream; /**< Points to the next stream at this
                                           * edge, if any */
-  struct crypt_path_t *cpath_layer; /**< A pointer to which node in the circ
-                                     * this conn exits at. */
   int package_window; /**< How many more relay cells can I send into the
                        * circuit? */
   int deliver_window; /**< How many more relay cells can end at me? */
 
-  /** Nickname of planned exit node -- used with .exit support. */
-  char *chosen_exit_name;
-
-  socks_request_t *socks_request; /**< SOCKS structure describing request (AP
-                                   * only.) */
   struct circuit_t *on_circuit; /**< The circuit (if any) that this edge
                                  * connection is using. */
 
+  /** A pointer to which node in the circ this conn exits at.  Set for AP
+   * connections and for hidden service exit connections. */
+  struct crypt_path_t *cpath_layer;
+  /** What rendezvous service are we querying for (if an AP) or providing (if
+   * an exit)? */
+  rend_data_t *rend_data;
+
   uint32_t address_ttl; /**< TTL for address-to-addr mapping on exit
                          * connection.  Exit connections only. */
 
@@ -1209,8 +1210,29 @@ typedef struct edge_connection_t {
   /** Bytes written since last call to control_event_stream_bandwidth_used() */
   uint32_t n_written;
 
-  /** What rendezvous service are we querying for? (AP only) */
-  rend_data_t *rend_data;
+  /** True iff this connection is for a DNS request only. */
+  unsigned int is_dns_request:1;
+
+  unsigned int edge_has_sent_end:1; /**< For debugging; only used on edge
+                         * connections.  Set once we've set the stream end,
+                         * and check in connection_about_to_close_connection().
+                         */
+  /** True iff we've blocked reading until the circuit has fewer queued
+   * cells. */
+  unsigned int edge_blocked_on_circ:1;
+
+} edge_connection_t;
+
+/** Subtype of edge_connection_t for an "entry connection" -- that is, a SOCKS
+ * connection, a DNS request, a TransPort connection or a NATD connection */
+typedef struct entry_connection_t {
+  edge_connection_t _edge;
+
+  /** Nickname of planned exit node -- used with .exit support. */
+  char *chosen_exit_name;
+
+  socks_request_t *socks_request; /**< SOCKS structure describing request (AP
+                                   * only.) */
 
   /* === Isolation related, AP only. === */
   /** AP only: based on which factors do we isolate this stream? */
@@ -1231,6 +1253,19 @@ typedef struct edge_connection_t {
    * already retried several times. */
   uint8_t num_socks_retries;
 
+  /** For AP connections only: buffer for data that we have sent
+   * optimistically, which we might need to re-send if we have to
+   * retry this connection. */
+  generic_buffer_t *pending_optimistic_data;
+  /* For AP connections only: buffer for data that we previously sent
+  * optimistically which we are currently re-sending as we retry this
+  * connection. */
+  generic_buffer_t *sending_optimistic_data;
+
+  /** If this is a DNSPort connection, this field holds the pending DNS
+   * request that we're going to try to answer.  */
+  struct evdns_server_request *dns_server_request;
+
 #define NUM_CIRCUITS_LAUNCHED_THRESHOLD 10
   /** Number of times we've launched a circuit to handle this stream. If
     * it gets too high, that could indicate an inconsistency between our
@@ -1238,9 +1273,6 @@ typedef struct edge_connection_t {
     * stream to one of the available circuits" logic. */
   unsigned int num_circuits_launched:4;
 
-  /** True iff this connection is for a DNS request only. */
-  unsigned int is_dns_request:1;
-
   /** True iff this stream must attach to a one-hop circuit (e.g. for
    * begin_dir). */
   unsigned int want_onehop:1;
@@ -1248,13 +1280,6 @@ typedef struct edge_connection_t {
    * itself rather than BEGIN (either via onehop or via a whole circuit). */
   unsigned int use_begindir:1;
 
-  unsigned int edge_has_sent_end:1; /**< For debugging; only used on edge
-                         * connections.  Set once we've set the stream end,
-                         * and check in connection_about_to_close_connection().
-                         */
-  /** True iff we've blocked reading until the circuit has fewer queued
-   * cells. */
-  unsigned int edge_blocked_on_circ:1;
   /** For AP connections only. If 1, and we fail to reach the chosen exit,
    * stop requiring it. */
   unsigned int chosen_exit_optional:1;
@@ -1274,20 +1299,7 @@ typedef struct edge_connection_t {
    */
   unsigned int may_use_optimistic_data : 1;
 
-  /** For AP connections only: buffer for data that we have sent
-   * optimistically, which we might need to re-send if we have to
-   * retry this connection. */
-  generic_buffer_t *pending_optimistic_data;
-  /* For AP connections only: buffer for data that we previously sent
-  * optimistically which we are currently re-sending as we retry this
-  * connection. */
-  generic_buffer_t *sending_optimistic_data;
-
-  /** If this is a DNSPort connection, this field holds the pending DNS
-   * request that we're going to try to answer.  */
-  struct evdns_server_request *dns_server_request;
-
-} edge_connection_t;
+} entry_connection_t;
 
 /** Subtype of connection_t for an "directory connection" -- that is, an HTTP
  * connection to retrieve or serve directory material. */
@@ -1360,6 +1372,11 @@ typedef struct control_connection_t {
 /** Helper macro: Given a pointer to to._base, of type from*, return &to. */
 #define DOWNCAST(to, ptr) ((to*)SUBTYPE_P(ptr, to, _base))
 
+/** Cast a entry_connection_t subtype pointer to a edge_connection_t **/
+#define ENTRY_TO_EDGE_CONN(c) (&(((c))->_edge))
+/** Cast a entry_connection_t subtype pointer to a connection_t **/
+#define ENTRY_TO_CONN(c) (TO_CONN(ENTRY_TO_EDGE_CONN(c)))
+
 /** Convert a connection_t* to an or_connection_t*; assert if the cast is
  * invalid. */
 static or_connection_t *TO_OR_CONN(connection_t *);
@@ -1369,6 +1386,12 @@ static dir_connection_t *TO_DIR_CONN(connection_t *);
 /** Convert a connection_t* to an edge_connection_t*; assert if the cast is
  * invalid. */
 static edge_connection_t *TO_EDGE_CONN(connection_t *);
+/** Convert a connection_t* to an entry_connection_t*; assert if the cast is
+ * invalid. */
+static entry_connection_t *TO_ENTRY_CONN(connection_t *);
+/** Convert a edge_connection_t* to an entry_connection_t*; assert if the cast is
+ * invalid. */
+static entry_connection_t *EDGE_TO_ENTRY_CONN(edge_connection_t *);
 /** Convert a connection_t* to an control_connection_t*; assert if the cast is
  * invalid. */
 static control_connection_t *TO_CONTROL_CONN(connection_t *);
@@ -1388,9 +1411,20 @@ static INLINE dir_connection_t *TO_DIR_CONN(connection_t *c)
 }
 static INLINE edge_connection_t *TO_EDGE_CONN(connection_t *c)
 {
-  tor_assert(c->magic == EDGE_CONNECTION_MAGIC);
+  tor_assert(c->magic == EDGE_CONNECTION_MAGIC ||
+             c->magic == ENTRY_CONNECTION_MAGIC);
   return DOWNCAST(edge_connection_t, c);
 }
+static INLINE entry_connection_t *TO_ENTRY_CONN(connection_t *c)
+{
+  tor_assert(c->magic == ENTRY_CONNECTION_MAGIC);
+  return (entry_connection_t*) SUBTYPE_P(c, entry_connection_t, _edge._base);
+}
+static INLINE entry_connection_t *EDGE_TO_ENTRY_CONN(edge_connection_t *c)
+{
+  tor_assert(c->_base.magic == ENTRY_CONNECTION_MAGIC);
+  return (entry_connection_t*) SUBTYPE_P(c, entry_connection_t, _edge);
+}
 static INLINE control_connection_t *TO_CONTROL_CONN(connection_t *c)
 {
   tor_assert(c->magic == CONTROL_CONNECTION_MAGIC);

+ 59 - 43
src/or/relay.c

@@ -649,6 +649,7 @@ connection_edge_send_command(edge_connection_t *fromconn,
 {
   /* XXXX NM Split this function into a separate versions per circuit type? */
   circuit_t *circ;
+  crypt_path_t *cpath_layer = fromconn->cpath_layer;
   tor_assert(fromconn);
   circ = fromconn->on_circuit;
 
@@ -663,7 +664,8 @@ connection_edge_send_command(edge_connection_t *fromconn,
   if (!circ) {
     if (fromconn->_base.type == CONN_TYPE_AP) {
       log_info(LD_APP,"no circ. Closing conn.");
-      connection_mark_unattached_ap(fromconn, END_STREAM_REASON_INTERNAL);
+      connection_mark_unattached_ap(EDGE_TO_ENTRY_CONN(fromconn),
+                                    END_STREAM_REASON_INTERNAL);
     } else {
       log_info(LD_EXIT,"no circ. Closing conn.");
       fromconn->edge_has_sent_end = 1; /* no circ to send to */
@@ -675,7 +677,7 @@ connection_edge_send_command(edge_connection_t *fromconn,
 
   return relay_send_command_from_edge(fromconn->stream_id, circ,
                                       relay_command, payload,
-                                      payload_len, fromconn->cpath_layer);
+                                      payload_len, cpath_layer);
 }
 
 /** How many times will I retry a stream that fails due to DNS
@@ -703,16 +705,17 @@ edge_reason_is_retriable(int reason)
 static int
 connection_ap_process_end_not_open(
     relay_header_t *rh, cell_t *cell, origin_circuit_t *circ,
-    edge_connection_t *conn, crypt_path_t *layer_hint)
+    entry_connection_t *conn, crypt_path_t *layer_hint)
 {
   struct in_addr in;
   node_t *exitrouter;
   int reason = *(cell->payload+RELAY_HEADER_SIZE);
   int control_reason = reason | END_STREAM_REASON_FLAG_REMOTE;
+  edge_connection_t *edge_conn = ENTRY_TO_EDGE_CONN(conn);
   (void) layer_hint; /* unused */
 
   if (rh->length > 0 && edge_reason_is_retriable(reason) &&
-      !connection_edge_is_rendezvous_stream(conn)  /* avoid retry if rend */
+      !connection_edge_is_rendezvous_stream(edge_conn) /* avoid retry if rend */
       ) {
     const char *chosen_exit_digest =
       circ->build_state->chosen_exit->identity_digest;
@@ -840,7 +843,7 @@ connection_ap_process_end_not_open(
        stream_end_reason_to_string(rh->length > 0 ? reason : -1));
   circuit_log_path(LOG_INFO,LD_APP,circ);
   /* need to test because of detach_retriable */
-  if (!conn->_base.marked_for_close)
+  if (!ENTRY_TO_CONN(conn)->marked_for_close)
     connection_mark_unattached_ap(conn, control_reason);
   return 0;
 }
@@ -849,7 +852,7 @@ connection_ap_process_end_not_open(
  * dotted-quad representation of <b>new_addr</b> (given in host order),
  * and send an appropriate REMAP event. */
 static void
-remap_event_helper(edge_connection_t *conn, uint32_t new_addr)
+remap_event_helper(entry_connection_t *conn, uint32_t new_addr)
 {
   struct in_addr in;
 
@@ -875,7 +878,8 @@ connection_edge_process_relay_cell_not_open(
   if (rh->command == RELAY_COMMAND_END) {
     if (CIRCUIT_IS_ORIGIN(circ) && conn->_base.type == CONN_TYPE_AP) {
       return connection_ap_process_end_not_open(rh, cell,
-                                                TO_ORIGIN_CIRCUIT(circ), conn,
+                                                TO_ORIGIN_CIRCUIT(circ),
+                                                EDGE_TO_ENTRY_CONN(conn),
                                                 layer_hint);
     } else {
       /* we just got an 'end', don't need to send one */
@@ -889,6 +893,7 @@ connection_edge_process_relay_cell_not_open(
 
   if (conn->_base.type == CONN_TYPE_AP &&
       rh->command == RELAY_COMMAND_CONNECTED) {
+    entry_connection_t *entry_conn = EDGE_TO_ENTRY_CONN(conn);
     tor_assert(CIRCUIT_IS_ORIGIN(circ));
     if (conn->_base.state != AP_CONN_STATE_CONNECT_WAIT) {
       log_fn(LOG_PROTOCOL_WARN, LD_APP,
@@ -906,22 +911,23 @@ connection_edge_process_relay_cell_not_open(
         log_info(LD_APP, "...but it claims the IP address was %s. Closing.",
                  fmt_addr32(addr));
         connection_edge_end(conn, END_STREAM_REASON_TORPROTOCOL);
-        connection_mark_unattached_ap(conn, END_STREAM_REASON_TORPROTOCOL);
+        connection_mark_unattached_ap(entry_conn,
+                                      END_STREAM_REASON_TORPROTOCOL);
         return 0;
       }
       if (rh->length >= 8)
         ttl = (int)ntohl(get_uint32(cell->payload+RELAY_HEADER_SIZE+4));
       else
         ttl = -1;
-      client_dns_set_addressmap(conn->socks_request->address, addr,
-                                conn->chosen_exit_name, ttl);
+      client_dns_set_addressmap(entry_conn->socks_request->address, addr,
+                                entry_conn->chosen_exit_name, ttl);
 
-      remap_event_helper(conn, addr);
+      remap_event_helper(entry_conn, addr);
     }
     circuit_log_path(LOG_INFO,LD_APP,TO_ORIGIN_CIRCUIT(circ));
     /* don't send a socks reply to transparent conns */
-    if (!conn->socks_request->has_finished)
-      connection_ap_handshake_socks_reply(conn, NULL, 0, 0);
+    if (!entry_conn->socks_request->has_finished)
+      connection_ap_handshake_socks_reply(entry_conn, NULL, 0, 0);
 
     /* Was it a linked dir conn? If so, a dir request just started to
      * fetch something; this could be a bootstrap status milestone. */
@@ -946,9 +952,9 @@ connection_edge_process_relay_cell_not_open(
     }
     /* This is definitely a success, so forget about any pending data we
      * had sent. */
-    if (conn->pending_optimistic_data) {
-      generic_buffer_free(conn->pending_optimistic_data);
-      conn->pending_optimistic_data = NULL;
+    if (entry_conn->pending_optimistic_data) {
+      generic_buffer_free(entry_conn->pending_optimistic_data);
+      entry_conn->pending_optimistic_data = NULL;
     }
 
     /* handle anything that might have queued */
@@ -964,17 +970,18 @@ connection_edge_process_relay_cell_not_open(
     int ttl;
     int answer_len;
     uint8_t answer_type;
+    entry_connection_t *entry_conn = EDGE_TO_ENTRY_CONN(conn);
     if (conn->_base.state != AP_CONN_STATE_RESOLVE_WAIT) {
       log_fn(LOG_PROTOCOL_WARN, LD_APP, "Got a 'resolved' cell while "
              "not in state resolve_wait. Dropping.");
       return 0;
     }
-    tor_assert(SOCKS_COMMAND_IS_RESOLVE(conn->socks_request->command));
+    tor_assert(SOCKS_COMMAND_IS_RESOLVE(entry_conn->socks_request->command));
     answer_len = cell->payload[RELAY_HEADER_SIZE+1];
     if (rh->length < 2 || answer_len+2>rh->length) {
       log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL,
              "Dropping malformed 'resolved' cell");
-      connection_mark_unattached_ap(conn, END_STREAM_REASON_TORPROTOCOL);
+      connection_mark_unattached_ap(entry_conn, END_STREAM_REASON_TORPROTOCOL);
       return 0;
     }
     answer_type = cell->payload[RELAY_HEADER_SIZE];
@@ -989,14 +996,14 @@ connection_edge_process_relay_cell_not_open(
           is_internal_IP(addr, 0)) {
         log_info(LD_APP,"Got a resolve with answer %s. Rejecting.",
                  fmt_addr32(addr));
-        connection_ap_handshake_socks_resolved(conn,
+        connection_ap_handshake_socks_resolved(entry_conn,
                                                RESOLVED_TYPE_ERROR_TRANSIENT,
                                                0, NULL, 0, TIME_MAX);
-        connection_mark_unattached_ap(conn, END_STREAM_REASON_TORPROTOCOL);
+        connection_mark_unattached_ap(entry_conn,END_STREAM_REASON_TORPROTOCOL);
         return 0;
       }
     }
-    connection_ap_handshake_socks_resolved(conn,
+    connection_ap_handshake_socks_resolved(entry_conn,
                    answer_type,
                    cell->payload[RELAY_HEADER_SIZE+1], /*answer_len*/
                    cell->payload+RELAY_HEADER_SIZE+2, /*answer*/
@@ -1004,9 +1011,9 @@ connection_edge_process_relay_cell_not_open(
                    -1);
     if (answer_type == RESOLVED_TYPE_IPV4 && answer_len == 4) {
       uint32_t addr = ntohl(get_uint32(cell->payload+RELAY_HEADER_SIZE+2));
-      remap_event_helper(conn, addr);
+      remap_event_helper(entry_conn, addr);
     }
-    connection_mark_unattached_ap(conn,
+    connection_mark_unattached_ap(entry_conn,
                               END_STREAM_REASON_DONE |
                               END_STREAM_REASON_FLAG_ALREADY_SOCKS_REPLIED);
     return 0;
@@ -1164,9 +1171,13 @@ connection_edge_process_relay_cell(cell_t *cell, circuit_t *circ,
                conn->_base.s,
                stream_end_reason_to_string(reason),
                conn->stream_id);
-      if (conn->socks_request && !conn->socks_request->has_finished)
-        log_warn(LD_BUG,
-                 "open stream hasn't sent socks answer yet? Closing.");
+      if (conn->_base.type == CONN_TYPE_AP) {
+        entry_connection_t *entry_conn = EDGE_TO_ENTRY_CONN(conn);
+        if (entry_conn->socks_request &&
+            !entry_conn->socks_request->has_finished)
+          log_warn(LD_BUG,
+                   "open stream hasn't sent socks answer yet? Closing.");
+      }
       /* We just *got* an end; no reason to send one. */
       conn->edge_has_sent_end = 1;
       if (!conn->end_reason)
@@ -1348,11 +1359,14 @@ connection_edge_package_raw_inbuf(edge_connection_t *conn, int package_partial,
   size_t amount_to_process, length;
   char payload[CELL_PAYLOAD_SIZE];
   circuit_t *circ;
-  unsigned domain = conn->cpath_layer ? LD_APP : LD_EXIT;
+  const unsigned domain = conn->_base.type == CONN_TYPE_AP ? LD_APP : LD_EXIT;
   int sending_from_optimistic = 0;
   const int sending_optimistically =
     conn->_base.type == CONN_TYPE_AP &&
     conn->_base.state != AP_CONN_STATE_OPEN;
+  entry_connection_t *entry_conn =
+    conn->_base.type == CONN_TYPE_AP ? EDGE_TO_ENTRY_CONN(conn) : NULL;
+  crypt_path_t *cpath_layer = conn->cpath_layer;
 
   tor_assert(conn);
 
@@ -1375,7 +1389,7 @@ connection_edge_package_raw_inbuf(edge_connection_t *conn, int package_partial,
     return -1;
   }
 
-  if (circuit_consider_stop_edge_reading(circ, conn->cpath_layer))
+  if (circuit_consider_stop_edge_reading(circ, cpath_layer))
     return 0;
 
   if (conn->package_window <= 0) {
@@ -1385,10 +1399,11 @@ connection_edge_package_raw_inbuf(edge_connection_t *conn, int package_partial,
     return 0;
   }
 
-  sending_from_optimistic = conn->sending_optimistic_data != NULL;
+  sending_from_optimistic = entry_conn &&
+    entry_conn->sending_optimistic_data != NULL;
 
   if (PREDICT_UNLIKELY(sending_from_optimistic)) {
-    amount_to_process = generic_buffer_len(conn->sending_optimistic_data);
+    amount_to_process = generic_buffer_len(entry_conn->sending_optimistic_data);
     if (PREDICT_UNLIKELY(!amount_to_process)) {
       log_warn(LD_BUG, "sending_optimistic_data was non-NULL but empty");
       amount_to_process = connection_get_inbuf_len(TO_CONN(conn));
@@ -1416,10 +1431,10 @@ connection_edge_package_raw_inbuf(edge_connection_t *conn, int package_partial,
     /* XXX023 We could be more efficient here by sometimes packing
      * previously-sent optimistic data in the same cell with data
      * from the inbuf. */
-    generic_buffer_get(conn->sending_optimistic_data, payload, length);
-    if (!generic_buffer_len(conn->sending_optimistic_data)) {
-        generic_buffer_free(conn->sending_optimistic_data);
-        conn->sending_optimistic_data = NULL;
+    generic_buffer_get(entry_conn->sending_optimistic_data, payload, length);
+    if (!generic_buffer_len(entry_conn->sending_optimistic_data)) {
+        generic_buffer_free(entry_conn->sending_optimistic_data);
+        entry_conn->sending_optimistic_data = NULL;
     }
   } else {
     connection_fetch_from_buf(payload, length, TO_CONN(conn));
@@ -1431,9 +1446,9 @@ connection_edge_package_raw_inbuf(edge_connection_t *conn, int package_partial,
   if (sending_optimistically && !sending_from_optimistic) {
     /* This is new optimistic data; remember it in case we need to detach and
        retry */
-    if (!conn->pending_optimistic_data)
-      conn->pending_optimistic_data = generic_buffer_new();
-    generic_buffer_add(conn->pending_optimistic_data, payload, length);
+    if (!entry_conn->pending_optimistic_data)
+      entry_conn->pending_optimistic_data = generic_buffer_new();
+    generic_buffer_add(entry_conn->pending_optimistic_data, payload, length);
   }
 
   if (connection_edge_send_command(conn, RELAY_COMMAND_DATA,
@@ -1441,18 +1456,18 @@ connection_edge_package_raw_inbuf(edge_connection_t *conn, int package_partial,
     /* circuit got marked for close, don't continue, don't need to mark conn */
     return 0;
 
-  if (!conn->cpath_layer) { /* non-rendezvous exit */
+  if (!cpath_layer) { /* non-rendezvous exit */
     tor_assert(circ->package_window > 0);
     circ->package_window--;
   } else { /* we're an AP, or an exit on a rendezvous circ */
-    tor_assert(conn->cpath_layer->package_window > 0);
-    conn->cpath_layer->package_window--;
+    tor_assert(cpath_layer->package_window > 0);
+    cpath_layer->package_window--;
   }
 
   if (--conn->package_window <= 0) { /* is it 0 after decrement? */
     connection_stop_reading(TO_CONN(conn));
     log_debug(domain,"conn->package_window reached 0.");
-    circuit_consider_stop_edge_reading(circ, conn->cpath_layer);
+    circuit_consider_stop_edge_reading(circ, cpath_layer);
     return 0; /* don't process the inbuf any more */
   }
   log_debug(domain,"conn->package_window is now %d",conn->package_window);
@@ -1491,7 +1506,7 @@ connection_edge_consider_sending_sendme(edge_connection_t *conn)
   }
 
   while (conn->deliver_window <= STREAMWINDOW_START - STREAMWINDOW_INCREMENT) {
-    log_debug(conn->cpath_layer?LD_APP:LD_EXIT,
+    log_debug(conn->_base.type == CONN_TYPE_AP ?LD_APP:LD_EXIT,
               "Outbuf %d, Queuing stream sendme.",
               (int)conn->_base.outbuf_flushlen);
     conn->deliver_window += STREAMWINDOW_INCREMENT;
@@ -1693,9 +1708,10 @@ circuit_consider_stop_edge_reading(circuit_t *circ, crypt_path_t *layer_hint)
   if (layer_hint->package_window <= 0) {
     log_debug(domain,"yes, at-origin. stopped.");
     for (conn = TO_ORIGIN_CIRCUIT(circ)->p_streams; conn;
-         conn=conn->next_stream)
+         conn=conn->next_stream) {
       if (conn->cpath_layer == layer_hint)
         connection_stop_reading(TO_CONN(conn));
+    }
     return 1;
   }
   return 0;

+ 18 - 16
src/or/rendclient.c

@@ -824,40 +824,42 @@ rend_client_receive_rendezvous(origin_circuit_t *circ, const uint8_t *request,
 void
 rend_client_desc_trynow(const char *query)
 {
-  edge_connection_t *conn;
+  entry_connection_t *conn;
   rend_cache_entry_t *entry;
+  const rend_data_t *rend_data;
   time_t now = time(NULL);
 
   smartlist_t *conns = get_connection_array();
-  SMARTLIST_FOREACH_BEGIN(conns, connection_t *, _conn) {
-    if (_conn->type != CONN_TYPE_AP ||
-        _conn->state != AP_CONN_STATE_RENDDESC_WAIT ||
-        _conn->marked_for_close)
+  SMARTLIST_FOREACH_BEGIN(conns, connection_t *, base_conn) {
+    if (base_conn->type != CONN_TYPE_AP ||
+        base_conn->state != AP_CONN_STATE_RENDDESC_WAIT ||
+        base_conn->marked_for_close)
       continue;
-    conn = TO_EDGE_CONN(_conn);
-    if (!conn->rend_data)
+    conn = TO_ENTRY_CONN(base_conn);
+    rend_data = ENTRY_TO_EDGE_CONN(conn)->rend_data;
+    if (!rend_data)
       continue;
-    if (rend_cmp_service_ids(query, conn->rend_data->onion_address))
+    if (rend_cmp_service_ids(query, rend_data->onion_address))
       continue;
-    assert_connection_ok(TO_CONN(conn), now);
-    if (rend_cache_lookup_entry(conn->rend_data->onion_address, -1,
+    assert_connection_ok(base_conn, now);
+    if (rend_cache_lookup_entry(rend_data->onion_address, -1,
                                 &entry) == 1 &&
         rend_client_any_intro_points_usable(entry)) {
       /* either this fetch worked, or it failed but there was a
        * valid entry from before which we should reuse */
       log_info(LD_REND,"Rend desc is usable. Launching circuits.");
-      conn->_base.state = AP_CONN_STATE_CIRCUIT_WAIT;
+      base_conn->state = AP_CONN_STATE_CIRCUIT_WAIT;
 
       /* restart their timeout values, so they get a fair shake at
        * connecting to the hidden service. */
-      conn->_base.timestamp_created = now;
-      conn->_base.timestamp_lastread = now;
-      conn->_base.timestamp_lastwritten = now;
+      base_conn->timestamp_created = now;
+      base_conn->timestamp_lastread = now;
+      base_conn->timestamp_lastwritten = now;
 
       if (connection_ap_handshake_attach_circuit(conn) < 0) {
         /* it will never work */
         log_warn(LD_REND,"Rendezvous attempt failed. Closing.");
-        if (!conn->_base.marked_for_close)
+        if (!base_conn->marked_for_close)
           connection_mark_unattached_ap(conn, END_STREAM_REASON_CANT_ATTACH);
       }
     } else { /* 404, or fetch didn't get that far */
@@ -866,7 +868,7 @@ rend_client_desc_trynow(const char *query)
                  safe_str_client(query));
       connection_mark_unattached_ap(conn, END_STREAM_REASON_RESOLVEFAILED);
     }
-  } SMARTLIST_FOREACH_END(_conn);
+  } SMARTLIST_FOREACH_END(base_conn);
 }
 
 /** Return a newly allocated extend_info_t* for a randomly chosen introduction

Some files were not shown because too many files changed in this diff