[or-cvs] r12285: Implement lots of proposal 105. None of it is enabled yet. (in tor/trunk: . doc doc/spec/proposals src/or)

nickm at seul.org nickm at seul.org
Tue Oct 30 18:31:31 UTC 2007


Author: nickm
Date: 2007-10-30 14:31:30 -0400 (Tue, 30 Oct 2007)
New Revision: 12285

Modified:
   tor/trunk/
   tor/trunk/doc/TODO
   tor/trunk/doc/spec/proposals/105-handshake-revision.txt
   tor/trunk/src/or/command.c
   tor/trunk/src/or/connection_or.c
   tor/trunk/src/or/or.h
   tor/trunk/src/or/router.c
Log:
 r16282 at catbus:  nickm | 2007-10-30 14:28:58 -0400
 Implement lots of proposal 105.  None of it is enabled yet.



Property changes on: tor/trunk
___________________________________________________________________
 svk:merge ticket from /tor/trunk [r16282] on 8246c3cf-6607-4228-993b-4d95d33730f1

Modified: tor/trunk/doc/TODO
===================================================================
--- tor/trunk/doc/TODO	2007-10-30 16:19:41 UTC (rev 12284)
+++ tor/trunk/doc/TODO	2007-10-30 18:31:30 UTC (rev 12285)
@@ -42,16 +42,21 @@
     - 105+TLS, if possible.
       - 105 only
         - Need to get a finished proposal 105
-        - "Pick a version" function
+        o "Pick a version" function
         - Have a 'waiting_for_version' state.
-        - Store version in or_connection_t.
-        - Generate netinfo cells
-        - Accept netinfo cells
+        o Store version in or_connection_t.
+        o Generate netinfo cells
+        o Accept netinfo cells
+        . Add an is_canonical field to or_connection_t.
+          o Set it when we get a match in the netinfo.
+          o Set it when we get a match for a routerinfo we have.
+          - Don't extend a circuit over a noncanonical connection with
+            mismatched address.
         - Version negotiation: send a version cell and enter
           waiting-for-version; when version cell arrives, pick version
           and send netinfo and be "open".
-        - On netinfo, warn if there's skew from a server.
-        - Handle IP addresses in netinfo properly.
+        o On netinfo, warn if there's skew from a server.
+        - Learn our outgoing IP address from netinfo cells?
       - TLS only
         - Need to get a finished TLS normalization proposal
         - Revised authentication.

Modified: tor/trunk/doc/spec/proposals/105-handshake-revision.txt
===================================================================
--- tor/trunk/doc/spec/proposals/105-handshake-revision.txt	2007-10-30 16:19:41 UTC (rev 12284)
+++ tor/trunk/doc/spec/proposals/105-handshake-revision.txt	2007-10-30 18:31:30 UTC (rev 12285)
@@ -4,7 +4,7 @@
 Last-Modified: $Date$
 Author: Nick Mathewson, Roger Dingledine
 Created:
-Status: Open
+Status: Accepted
 
 Overview:
 
@@ -120,7 +120,7 @@
    When a Tor connection is established, both parties normally send a
    VERSIONS cell before sending any other cells.  (But see below.)
 
-         VersionsLen          [1 byte]
+         VersionsLen          [2 byte]
          Versions             [VersionsLen bytes]
 
    "Versions" is a sequence of VersionsLen bytes.  Each value between 1 and
@@ -157,6 +157,8 @@
    The VERSIONS cell must be sent as a v1 cell (2 bytes of circuitID, 1
    byte of command, 509 bytes of payload).
 
+   [NOTE: The VERSIONS cell is assigned the command number 7.]
+
 2.2. MITM-prevention and time checking
 
    If we negotiate a v2 connection or higher, the second cell we send SHOULD
@@ -195,6 +197,7 @@
    given in the EXTEND cell is not listed in the NETINFO cell, the first
    party SHOULD close the connection as a likely MITM attack.
 
+   [NOTE: The NETINFO cell is assigned the command number 8.]
 
 Discussion: Versions versus feature lists
 

Modified: tor/trunk/src/or/command.c
===================================================================
--- tor/trunk/src/or/command.c	2007-10-30 16:19:41 UTC (rev 12284)
+++ tor/trunk/src/or/command.c	2007-10-30 18:31:30 UTC (rev 12285)
@@ -25,12 +25,16 @@
 uint64_t stats_n_created_cells_processed = 0;
 uint64_t stats_n_relay_cells_processed = 0;
 uint64_t stats_n_destroy_cells_processed = 0;
+uint64_t stats_n_versions_cells_processed = 0;
+uint64_t stats_n_netinfo_cells_processed = 0;
 
-/* These are the main four functions for processing cells */
+/* These are the main functions for processing cells */
 static void command_process_create_cell(cell_t *cell, or_connection_t *conn);
 static void command_process_created_cell(cell_t *cell, or_connection_t *conn);
 static void command_process_relay_cell(cell_t *cell, or_connection_t *conn);
 static void command_process_destroy_cell(cell_t *cell, or_connection_t *conn);
+static void command_process_versions_cell(cell_t *cell, or_connection_t *conn);
+static void command_process_netinfo_cell(cell_t *cell, or_connection_t *conn);
 
 #ifdef KEEP_TIMING_STATS
 /** This is a wrapper function around the actual function that processes the
@@ -99,6 +103,16 @@
   }
 #endif
 
+#ifdef KEEP_TIMING_STATS
+#define PROCESS_CELL(tp, cl, cn) STMT_BEGIN {                   \
+    ++num ## tp;                                                \
+    command_time_process_cell(cl, cn, & tp ## time ,            \
+                              command_process_ ## tp ## _cell);  \
+  } STMT_END
+#else
+#define PROCESS_CELL(tp, cl, cn) command_process_ ## tp ## _cell(cl, cn)
+#endif
+
   switch (cell->command) {
     case CELL_PADDING:
       ++stats_n_padding_cells_processed;
@@ -107,47 +121,31 @@
     case CELL_CREATE:
     case CELL_CREATE_FAST:
       ++stats_n_create_cells_processed;
-#ifdef KEEP_TIMING_STATS
-      ++num_create;
-      command_time_process_cell(cell, conn, &create_time,
-                                command_process_create_cell);
-#else
-      command_process_create_cell(cell, conn);
-#endif
+      PROCESS_CELL(create, cell, conn);
       break;
     case CELL_CREATED:
     case CELL_CREATED_FAST:
       ++stats_n_created_cells_processed;
-#ifdef KEEP_TIMING_STATS
-      ++num_created;
-      command_time_process_cell(cell, conn, &created_time,
-                                command_process_created_cell);
-#else
-      command_process_created_cell(cell, conn);
-#endif
+      PROCESS_CELL(created, cell, conn);
       break;
     case CELL_RELAY:
       ++stats_n_relay_cells_processed;
-#ifdef KEEP_TIMING_STATS
-      ++num_relay;
-      command_time_process_cell(cell, conn, &relay_time,
-                                command_process_relay_cell);
-#else
-      command_process_relay_cell(cell, conn);
-#endif
+      PROCESS_CELL(relay, cell, conn);
       break;
     case CELL_DESTROY:
       ++stats_n_destroy_cells_processed;
-#ifdef KEEP_TIMING_STATS
-      ++num_destroy;
-      command_time_process_cell(cell, conn, &destroy_time,
-                                command_process_destroy_cell);
-#else
-      command_process_destroy_cell(cell, conn);
-#endif
+      PROCESS_CELL(destroy, cell, conn);
       break;
+    case CELL_VERSIONS:
+      ++stats_n_versions_cells_processed;
+      PROCESS_CELL(versions, cell, conn);
+      break;
+    case CELL_NETINFO:
+      ++stats_n_netinfo_cells_processed;
+      PROCESS_CELL(netinfo, cell, conn);
+      break;
     default:
-      log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL,
+      log_fn(LOG_INFO, LD_PROTOCOL,
              "Cell of unknown type (%d) received. Dropping.", cell->command);
       break;
   }
@@ -389,3 +387,110 @@
   }
 }
 
+/** Process a 'versions' cell.  The current link protocol version must be 0
+ * to indicate that no version has yet been negotiated. DOCDOC say more. */
+static void
+command_process_versions_cell(cell_t *cell, or_connection_t *conn)
+{
+  uint16_t versionslen;
+  int highest_supported_version = 0;
+  const char *cp, *end;
+  if (conn->link_proto != 0) {
+    log_fn(LOG_PROTOCOL_WARN, LD_OR,
+           "Received a VERSIONS cell on a connection with its version "
+           "already set to %d; dropping", (int) conn->link_proto);
+    return;
+  }
+  versionslen = ntohs(get_uint16(cell->payload));
+  end = cell->payload + 2 + versionslen;
+  if (end > cell->payload + CELL_PAYLOAD_SIZE)
+    end = cell->payload + CELL_PAYLOAD_SIZE; /*XXXX020 warn?*/
+  for (cp = cell->payload + 2; cp < end; ++cp) {
+    uint8_t v = *cp;
+    if (v == 1) {
+      if (v > highest_supported_version)
+        highest_supported_version = v;
+    }
+  }
+  if (!versionslen) {
+    log_fn(LOG_PROTOCOL_WARN, LD_OR,
+           "Couldn't find a version in common; defaulting to v1.");
+    /*XXXX020 or just break the connection?*/
+    conn->link_proto = 1;
+    return;
+  }
+}
+
+/** Process a 'netinfo' cell. DOCDOC say more. */
+static void
+command_process_netinfo_cell(cell_t *cell, or_connection_t *conn)
+{
+  time_t timestamp;
+  uint8_t my_addr_type;
+  uint8_t my_addr_len;
+  const char *my_addr_ptr;
+  const char *cp, *end;
+  uint8_t n_other_addrs;
+  time_t now = time(NULL);
+
+  /*XXXX020 reject duplicat netinfos. */
+
+  if (conn->link_proto < 2) {
+    log_fn(LOG_PROTOCOL_WARN, LD_OR,
+           "Received a NETINFO cell on %s connection; dropping.",
+           conn->link_proto == 0 ? "non-versioned" : "a v1");
+    return;
+  }
+  /* Decode the cell. */
+  timestamp = ntohl(get_uint32(cell->payload));
+  my_addr_type = (uint8_t) cell->payload[4];
+  my_addr_len = (uint8_t) cell->payload[5];
+  my_addr_ptr = cell->payload + 6;
+  /* Possibly learn my address. XXXX020 */
+  end = cell->payload + CELL_PAYLOAD_SIZE;
+  cp = cell->payload + 6 + my_addr_len;
+  if (cp >= end) {
+    log_fn(LOG_PROTOCOL_WARN, LD_OR,
+           "Address too long in netinfo cell; dropping.");
+    return;
+  }
+
+  /*XXXX020 magic number 3600 */
+  if (abs(timestamp - now) > 3600 &&
+      router_get_by_digest(conn->identity_digest)) {
+    long delta = now - timestamp;
+    char dbuf[64];
+    /*XXXX020 not always warn!*/
+    format_time_interval(dbuf, sizeof(dbuf), delta);
+    log_fn(LOG_WARN, LD_HTTP, "Received NETINFO cell with skewed time from "
+           "server at %s:%d.  It seems that our clock is %s by %s, or "
+           "that theirs is %s. Tor requires an accurate clock to work: "
+           "please check your time and date settings.",
+           conn->_base.address, (int)conn->_base.port,
+           delta>0 ? "ahead" : "behind", dbuf,
+           delta>0 ? "behind" : "ahead");
+    control_event_general_status(LOG_WARN,
+                                 "CLOCK_SKEW SKEW=%ld SOURCE=OR:%s:%d",
+                                 delta, conn->_base.address, conn->_base.port);
+  }
+
+  n_other_addrs = (uint8_t) *cp++;
+  while (n_other_addrs && cp < end-2) {
+    /* Consider all the other addresses; if any matches, this connection is
+     * "canonical." */
+    uint8_t other_addr_type = (uint8_t) *cp++;
+    uint8_t other_addr_len = (uint8_t) *cp++;
+    if (cp + other_addr_len >= end)
+      break; /*XXXX020 protocol warn. */
+    if (other_addr_type == RESOLVED_TYPE_IPV4 && other_addr_len == 4) {
+      uint32_t addr = ntohl(get_uint32(cp));
+      if (addr == conn->real_addr) {
+        conn->is_canonical = 1;
+        break;
+      }
+    }
+    cp += other_addr_len;
+    --n_other_addrs;
+  }
+}
+

Modified: tor/trunk/src/or/connection_or.c
===================================================================
--- tor/trunk/src/or/connection_or.c	2007-10-30 16:19:41 UTC (rev 12284)
+++ tor/trunk/src/or/connection_or.c	2007-10-30 18:31:30 UTC (rev 12285)
@@ -356,11 +356,16 @@
   connection_or_set_identity_digest(conn, id_digest);
   conn->_base.addr = addr;
   conn->_base.port = port;
+  conn->real_addr = addr;
   if (r) {
+    if (conn->_base.addr == r->addr)
+      conn->is_canonical = 1;
     if (!started_here) {
       /* Override the addr/port, so our log messages will make sense.
        * This is dangerous, since if we ever try looking up a conn by
        * its actual addr/port, we won't remember. Careful! */
+      /* XXXX020 this is stupid, and it's the reason we need real_addr to
+       * track is_canonical properly. */
       conn->_base.addr = r->addr;
       conn->_base.port = r->or_port;
     }
@@ -740,6 +745,8 @@
   }
   connection_watch_events(TO_CONN(conn), EV_READ);
   circuit_n_conn_done(conn, 1); /* send the pending creates, if any. */
+
+  conn->link_proto = 1; /* Version negotiation not yet enabled.XXX020 */
   return 0;
 }
 
@@ -773,7 +780,7 @@
   char buf[CELL_NETWORK_SIZE];
   cell_t cell;
 
-loop:
+ loop:
   log_debug(LD_OR,
             "%d: starting, inbuf_datalen %d (%d pending in tls object).",
             conn->_base.s,(int)buf_datalen(conn->_base.inbuf),
@@ -825,3 +832,56 @@
   return 0;
 }
 
+/** DOCDOC */
+static int
+connection_or_send_versions(or_connection_t *conn)
+{
+  cell_t cell;
+  uint8_t versions[] = { 1 };
+  int n_versions = sizeof(versions) / sizeof(uint8_t);
+  int i;
+  memset(&cell, 0, sizeof(cell_t));
+  cell.command = CELL_VERSIONS;
+  set_uint16(cell.payload, htons(n_versions));
+  for (i = 0; i < n_versions; ++i) {
+    uint8_t v = versions[i];
+    tor_assert(v > 0 && v < 128);
+    cell.payload[2+i] = v;
+  }
+
+  connection_or_write_cell_to_buf(&cell, conn);
+}
+
+/** DOCDOC */
+static int
+connection_or_send_netinfo(or_connection_t *conn)
+{
+  cell_t cell;
+  time_t now = time(NULL);
+  routerinfo_t *me;
+
+  memset(&cell, 0, sizeof(cell_t));
+  cell.command = CELL_NETINFO;
+
+  /* Their address. */
+  set_uint32(cell.payload, htonl(now));
+  cell.payload[4] = RESOLVED_TYPE_IPV4;
+  cell.payload[5] = 4;
+  set_uint32(cell.payload+6, htonl(conn->_base.addr));
+
+  /* My address. */
+  if ((me = router_get_my_routerinfo())) {
+    cell.payload[10] = 1; /* only one address is supported. */
+    cell.payload[11] = RESOLVED_TYPE_IPV4;
+    cell.payload[12] = 4;
+    set_uint32(cell.payload+13, htonl(me->addr));
+  } else {
+    cell.payload[10] = 0;
+  }
+
+  connection_or_write_cell_to_buf(&cell, conn);
+
+  /*XXXX020 remove these once we send netinfo and versions cells. */
+  (void) connection_or_send_netinfo;
+  (void) connection_or_send_versions;
+}

Modified: tor/trunk/src/or/or.h
===================================================================
--- tor/trunk/src/or/or.h	2007-10-30 16:19:41 UTC (rev 12284)
+++ tor/trunk/src/or/or.h	2007-10-30 18:31:30 UTC (rev 12285)
@@ -651,6 +651,8 @@
 #define CELL_DESTROY 4
 #define CELL_CREATE_FAST 5
 #define CELL_CREATED_FAST 6
+#define CELL_VERSIONS 7
+#define CELL_NETINFO 8
 
 /** How long to test reachability before complaining to the user. */
 #define TIMEOUT_UNTIL_UNREACHABILITY_COMPLAINT (20*60)
@@ -868,9 +870,14 @@
    * recent, we can rate limit it further. */
   time_t client_used;
 
+  uint32_t real_addr; /**DOCDOC */
+
   circ_id_type_t circ_id_type:2; /**< When we send CREATE cells along this
                                   * connection, which half of the space should
                                   * we use? */
+  unsigned int is_canonical; /**< DOCDOC */
+  uint8_t link_proto; /**< What protocol version are we using? 0 for
+                       * "none negotiated yet." */
   uint16_t next_circ_id; /**< Which circ_id do we try to use next on
                           * this connection?  This is always in the
                           * range 0..1<<15-1. */

Modified: tor/trunk/src/or/router.c
===================================================================
--- tor/trunk/src/or/router.c	2007-10-30 16:19:41 UTC (rev 12284)
+++ tor/trunk/src/or/router.c	2007-10-30 18:31:30 UTC (rev 12285)
@@ -1570,6 +1570,7 @@
   result = tor_snprintf(s, maxlen,
                     "router %s %s %d 0 %d\n"
                     "platform %s\n"
+                    "opt protocols Link 1 Circuit 1\n"
                     "published %s\n"
                     "opt fingerprint %s\n"
                     "uptime %ld\n"



More information about the tor-commits mailing list