Commit 8314fa5e authored by Nick Mathewson's avatar Nick Mathewson 🤹
Browse files

Implement sensible isolation for tunneled directory conns

One-hop dirconn streams all share a session group, and get the
ISO_SESSIONGRP flag: they may share circuits with each other and
nothing else.

Anonymized dirconn streams get a new internal-use-only ISO_STREAM
flag: they may not share circuits with anything, including each other.
parent 424063e3
Loading
Loading
Loading
Loading
+3 −3
Original line number Diff line number Diff line
@@ -4973,7 +4973,7 @@ parse_client_port_config(smartlist_t *out,
       cfg->type = listener_type;
       cfg->port = port ? port : defaultport;
       tor_addr_copy(&cfg->addr, &addr);
       cfg->session_group = -1;
       cfg->session_group = SESSION_GROUP_UNSET;
       cfg->isolation_flags = ISO_DEFAULT;
       smartlist_add(out, cfg);
     }
@@ -4992,7 +4992,7 @@ parse_client_port_config(smartlist_t *out,
       cfg->type = listener_type;
       cfg->port = defaultport;
       tor_addr_from_str(&cfg->addr, defaultaddr);
       cfg->session_group = -1;
       cfg->session_group = SESSION_GROUP_UNSET;
       cfg->isolation_flags = ISO_DEFAULT;
       smartlist_add(out, cfg);
    }
@@ -5006,7 +5006,7 @@ parse_client_port_config(smartlist_t *out,
  for (; ports; ports = ports->next) {
    tor_addr_t addr;
    int port;
    int sessiongroup = -1;
    int sessiongroup = SESSION_GROUP_UNSET;
    unsigned isolation = ISO_DEFAULT;

    char *addrport;
+1 −1
Original line number Diff line number Diff line
@@ -868,7 +868,7 @@ connection_create_listener(const struct sockaddr *listensockaddr,
  tor_socket_t s; /* the socket we're going to make */
  uint16_t usePort = 0, gotPort = 0;
  int start_reading = 0;
  static int global_next_session_group = -2;
  static int global_next_session_group = SESSION_GROUP_FIRST_AUTO;

  if (get_n_open_sockets() >= get_options()->_ConnLimit-1) {
    warn_too_many_conns();
+16 −2
Original line number Diff line number Diff line
@@ -2497,7 +2497,9 @@ connection_ap_handshake_send_resolve(edge_connection_t *ap_conn)
edge_connection_t *
connection_ap_make_link(connection_t *partner,
                        char *address, uint16_t port,
                        const char *digest, int use_begindir, int want_onehop)
                        const char *digest,
                        int session_group, int isolation_flags,
                        int use_begindir, int want_onehop)
{
  edge_connection_t *conn;

@@ -2515,7 +2517,6 @@ connection_ap_make_link(connection_t *partner,
  conn->socks_request->has_finished = 0; /* waiting for 'connected' */
  strlcpy(conn->socks_request->address, address,
          sizeof(conn->socks_request->address));
  conn->original_dest_address = tor_strdup(address);
  conn->socks_request->port = port;
  conn->socks_request->command = SOCKS_COMMAND_CONNECT;
  conn->want_onehop = want_onehop;
@@ -2528,6 +2529,11 @@ connection_ap_make_link(connection_t *partner,
                  digest, DIGEST_LEN);
  }

  /* Populate isolation fields. */
  conn->original_dest_address = tor_strdup(address);
  conn->session_group = session_group;
  conn->isolation_flags = isolation_flags;

  conn->_base.address = tor_strdup("(Tor_internal)");
  tor_addr_make_unspec(&conn->_base.addr);
  conn->_base.port = 0;
@@ -3291,6 +3297,9 @@ connection_edge_streams_are_compatible(const edge_connection_t *a,
      tor_strdup(a->socks_request->address);
  }

  if (iso & ISO_STREAM)
    return 0;

  if ((iso & ISO_DESTPORT) && a->socks_request->port != b->socks_request->port)
    return 0;
  if ((iso & ISO_DESTADDR) &&
@@ -3350,6 +3359,11 @@ connection_edge_compatible_with_circuit(const edge_connection_t *conn,
      tor_strdup(conn->socks_request->address);
  }

  /* If isolation_values_set, then the circuit is not compatible with
   * any new ISO_STREAM stream. */
  if (iso & ISO_STREAM)
    return 0;

  if ((iso & ISO_DESTPORT) && conn->socks_request->port != circ->dest_port)
    return 0;
  if ((iso & ISO_DESTADDR) &&
+2 −0
Original line number Diff line number Diff line
@@ -36,6 +36,8 @@ int connection_ap_handshake_send_resolve(edge_connection_t *ap_conn);
edge_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,
                                         size_t replylen,
+7 −1
Original line number Diff line number Diff line
@@ -973,6 +973,10 @@ directory_initiate_command_rend(const char *address, const tor_addr_t *_addr,
    }
  } else { /* we want to connect via a tor connection */
    edge_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. */
    int iso_flags = anonymized_connection ? ISO_STREAM : ISO_SESSIONGRP;

    /* If it's an anonymized connection, remember the fact that we
     * wanted it for later: maybe we'll want it again soon. */
@@ -988,7 +992,9 @@ directory_initiate_command_rend(const char *address, const tor_addr_t *_addr,
    linked_conn =
      connection_ap_make_link(TO_CONN(conn),
                              conn->_base.address, conn->_base.port,
                              digest, use_begindir, conn->dirconn_direct);
                              digest,
                              SESSION_GROUP_DIRCONN, iso_flags,
                              use_begindir, conn->dirconn_direct);
    if (!linked_conn) {
      log_warn(LD_NET,"Making tunnel to dirserver failed.");
      connection_mark_for_close(TO_CONN(conn));
Loading