[or-cvs] Implemented router twins

Roger Dingledine arma at seul.org
Thu Jul 18 23:44:59 UTC 2002


Update of /home/or/cvsroot/src/or
In directory moria.seul.org:/home/arma/work/onion/cvs/src/or

Modified Files:
	circuit.c command.c connection_ap.c main.c onion.c or.h 
Log Message:
Implemented router twins

I modified new_route so we don't pick twins back-to-back in the path.

I also had to patch my previous uses of connection_twin_get_by_addr_port()
because they assumed that "addr" and "port" would be the same for a twin
as for the original router.



Index: circuit.c
===================================================================
RCS file: /home/or/cvsroot/src/or/circuit.c,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -d -r1.7 -r1.8
--- circuit.c	18 Jul 2002 06:37:58 -0000	1.7
+++ circuit.c	18 Jul 2002 23:44:57 -0000	1.8
@@ -287,14 +287,14 @@
     return -1;
 
   if(crypt_type == 'e') {
-    log(LOG_DEBUG,"circuit_crypt(): Encrypting %d bytes.",inlen);
+//    log(LOG_DEBUG,"circuit_crypt(): Encrypting %d bytes.",inlen);
     if(circ->cpath) { /* we're at the beginning of the circuit. We'll want to do layered crypts. */
       /* 'e' means we're preparing to send it out. */
       for (i=0; i < circ->cpathlen; i++) /* moving from last to first hop 
                                           * Remember : cpath is in reverse order, i.e. last hop first
                                           */
       { 
-        log(LOG_DEBUG,"circuit_crypt() : Encrypting via cpath: Processing hop %u",circ->cpathlen-i);
+//        log(LOG_DEBUG,"circuit_crypt() : Encrypting via cpath: Processing hop %u",circ->cpathlen-i);
         thishop = circ->cpath[i];
     
         /* encrypt */
@@ -317,13 +317,13 @@
       memcpy(in,out,inlen);
     }
   } else if(crypt_type == 'd') {
-    log(LOG_DEBUG,"circuit_crypt(): Decrypting %d bytes.",inlen);
+//    log(LOG_DEBUG,"circuit_crypt(): Decrypting %d bytes.",inlen);
     if(circ->cpath) { /* we're at the beginning of the circuit. We'll want to do layered crypts. */
       for (i=circ->cpathlen-1; i >= 0; i--) /* moving from first to last hop 
                                        * Remember : cpath is in reverse order, i.e. last hop first
                                        */
       { 
-        log(LOG_DEBUG,"circuit_crypt() : Decrypting via cpath: Processing hop %u",circ->cpathlen-i);
+//        log(LOG_DEBUG,"circuit_crypt() : Decrypting via cpath: Processing hop %u",circ->cpathlen-i);
         thishop = circ->cpath[i];
 
         /* encrypt */

Index: command.c
===================================================================
RCS file: /home/or/cvsroot/src/or/command.c,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -d -r1.7 -r1.8
--- command.c	18 Jul 2002 06:37:58 -0000	1.7
+++ command.c	18 Jul 2002 23:44:57 -0000	1.8
@@ -111,6 +111,10 @@
       circuit_close(circ);
       return;
     }
+
+    circ->n_addr = n_conn->addr; /* these are different if we found a twin instead */
+    circ->n_port = n_conn->port;
+
     circ->n_conn = n_conn;
     log(LOG_DEBUG,"command_process_create_cell(): n_conn is %s:%u",n_conn->address,ntohs(n_conn->port));
 

Index: connection_ap.c
===================================================================
RCS file: /home/or/cvsroot/src/or/connection_ap.c,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -d -r1.5 -r1.6
--- connection_ap.c	18 Jul 2002 06:37:58 -0000	1.5
+++ connection_ap.c	18 Jul 2002 23:44:57 -0000	1.6
@@ -195,8 +195,6 @@
   free(route); /* we don't need it anymore */
 
   circ = circuit_new(0, conn); /* sets circ->p_aci and circ->p_conn */
-  circ->n_addr = firsthop->addr;
-  circ->n_port = firsthop->or_port;
   circ->state = CIRCUIT_STATE_OR_WAIT;
   circ->onion = onion;
   circ->onionlen = onionlen;
@@ -207,6 +205,8 @@
       firsthop->address,ntohs(firsthop->or_port));
   n_conn = connection_twin_get_by_addr_port(firsthop->addr,firsthop->or_port);
   if(!n_conn) { /* not currently connected */
+    circ->n_addr = firsthop->addr;
+    circ->n_port = firsthop->or_port;
     if(global_role & ROLE_OR_CONNECT_ALL) { /* we would be connected if he were up. but he's not. */
       log(LOG_DEBUG,"ap_handshake_establish_circuit(): Route's firsthop isn't connected.");
       circuit_close(circ); 
@@ -221,11 +221,13 @@
       return -1;
     }   
     conn->state = AP_CONN_STATE_OR_WAIT;
-    connection_watch_events(conn, 0); /* Stop listening for input from the AP! */
+    connection_stop_reading(conn); /* Stop listening for input from the AP! */
     return 0; /* return success. The onion/circuit/etc will be taken care of automatically
                * (may already have been) whenever n_conn reaches OR_CONN_STATE_OPEN.
                */ 
-  } else { /* it's already open. use it. */
+  } else { /* it (or a twin) is already open. use it. */
+    circ->n_addr = n_conn->addr;
+    circ->n_port = n_conn->port;
     return ap_handshake_send_onion(conn, n_conn, circ);
   }
 }
@@ -237,12 +239,12 @@
   log(LOG_DEBUG,"ap_handshake_n_conn_open(): Starting.");
   circ = circuit_get_by_naddr_nport(or_conn->addr, or_conn->port);
   if(!circ)
-    return 0; /* i'm ok with that */
+    return 0; /* i'm ok with that. no need to close the connection or anything. */
 
   if(circ->p_conn->state != AP_CONN_STATE_OR_WAIT) {
     log(LOG_DEBUG,"Bug: ap_handshake_n_conn_open() got an ap_conn not in OR_WAIT state.");
   }
-  connection_watch_events(or_conn, POLLIN); /* resume listening for reads */
+  connection_start_reading(circ->p_conn); /* resume listening for reads */
   log(LOG_DEBUG,"ap_handshake_n_conn_open(): Found circ, sending onion.");
   return ap_handshake_send_onion(circ->p_conn, or_conn, circ);
 }
@@ -332,7 +334,7 @@
 
   /* now we want to give the AP a "0" byte, because it wants to hear
    * back from us */
-  connection_write_to_buf(&zero, 1, ap_conn);
+  connection_write_to_buf(&zero, 1, ap_conn); /* this does connection_start_writing() too */
 
   return 0;
 }

Index: main.c
===================================================================
RCS file: /home/or/cvsroot/src/or/main.c,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -d -r1.13 -r1.14
--- main.c	18 Jul 2002 06:37:58 -0000	1.13
+++ main.c	18 Jul 2002 23:44:57 -0000	1.14
@@ -91,6 +91,22 @@
   return 0;  
 }
 
+int pkey_cmp(RSA *a, RSA *b) {
+  /* return 0 if a and b are "the same key". Return non-0 otherwise. */
+
+  int result;
+
+  if(!a || !b)
+    return -1;
+
+  assert(a->n && a->e && b->n && b->e);
+
+  result = BN_cmp(a->n, b->n);
+  if(result)
+    return result;
+  return BN_cmp(a->e, b->e);
+}
+
 connection_t *connection_twin_get_by_addr_port(uint32_t addr, uint16_t port) {
   /* Find a connection to the router described by addr and port,
    *   or alternately any router which knows its key.
@@ -99,16 +115,29 @@
    */
   int i;
   connection_t *conn;
+  routerinfo_t *router;
 
   /* first check if it's there exactly */
   conn = connection_exact_get_by_addr_port(addr,port);
   if(conn && connection_state_is_open(conn)) {
+    log(LOG_DEBUG,"connection_twin_get_by_addr_port(): Found exact match.");
     return conn;
   }
 
   /* now check if any of the other open connections are a twin for this one */
 
-  /* XXX */
+  router = router_get_by_addr_port(addr,port);
+  if(!router)
+    return NULL;
+
+  for(i=0;i<nfds;i++) {
+    conn = connection_array[i];
+    assert(conn);
+    if(connection_state_is_open(conn) && !pkey_cmp(conn->pkey, router->pkey)) {
+      log(LOG_DEBUG,"connection_twin_get_by_addr_port(): Found twin (%s).",conn->address);
+      return conn;
+    }
+  }
 
   /* guess not */
   return NULL;

Index: onion.c
===================================================================
RCS file: /home/or/cvsroot/src/or/onion.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -d -r1.3 -r1.4
--- onion.c	16 Jul 2002 01:12:15 -0000	1.3
+++ onion.c	18 Jul 2002 23:44:57 -0000	1.4
@@ -131,9 +131,9 @@
 
       choice = choice % (rarray_len);
       log(LOG_DEBUG,"new_route() : Chosen router %u.",choice);
-      if (choice == oldchoice) /* same router */
-      {
-	/* try again  */
+      if (choice == oldchoice ||
+        (oldchoice < rarray_len && !pkey_cmp(rarray[choice]->pkey, rarray[oldchoice]->pkey))) {
+        /* same router, or router twin. try again. */
 	i--;
 	continue;
       }

Index: or.h
===================================================================
RCS file: /home/or/cvsroot/src/or/or.h,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -d -r1.11 -r1.12
--- or.h	18 Jul 2002 06:37:58 -0000	1.11
+++ or.h	18 Jul 2002 23:44:57 -0000	1.12
@@ -509,6 +509,7 @@
 int connection_remove(connection_t *conn);
 void connection_set_poll_socket(connection_t *conn);
 
+int pkey_cmp(RSA *a, RSA *b);
 connection_t *connection_twin_get_by_addr_port(uint32_t addr, uint16_t port);
 connection_t *connection_exact_get_by_addr_port(uint32_t addr, uint16_t port);
 



More information about the tor-commits mailing list