[or-cvs] make a relay_header_t struct and pack/unpack funcs

Roger Dingledine arma at seul.org
Fri Dec 19 05:09:53 UTC 2003


Update of /home/or/cvsroot/src/or
In directory moria.mit.edu:/home2/arma/work/onion/cvs/src/or

Modified Files:
	buffers.c circuit.c connection.c connection_edge.c or.h 
Log Message:
make a relay_header_t struct and pack/unpack funcs
split 7-byte stream_id string into 2-byte recognized and 2-byte stream_id
fix two seg faults in fetch_from_buf_http
fix several lurking seg faults in handling unexpected relay cells

still need to
 * clean up relay_crypt
 * use relay dummies if there's going to be a conflict with rh.recognized
 * check for a conflict when generating stream_ids


Index: buffers.c
===================================================================
RCS file: /home/or/cvsroot/src/or/buffers.c,v
retrieving revision 1.58
retrieving revision 1.59
diff -u -d -r1.58 -r1.59
--- buffers.c	17 Dec 2003 21:09:31 -0000	1.58
+++ buffers.c	19 Dec 2003 05:09:50 -0000	1.59
@@ -375,12 +375,12 @@
   if(headers_out) {
     *headers_out = tor_malloc(headerlen+1);
     memcpy(*headers_out,buf->mem,headerlen);
-    *headers_out[headerlen] = 0; /* null terminate it */
+    (*headers_out)[headerlen] = 0; /* null terminate it */
   }
   if(body_out) {
     *body_out = tor_malloc(bodylen+1);
     memcpy(*body_out,buf->mem+headerlen,bodylen);
-    *body_out[bodylen] = 0; /* null terminate it */
+    (*body_out)[bodylen] = 0; /* null terminate it */
   }
   buf_remove_from_front(buf, headerlen+bodylen);
   return 1;

Index: circuit.c
===================================================================
RCS file: /home/or/cvsroot/src/or/circuit.c,v
retrieving revision 1.124
retrieving revision 1.125
diff -u -d -r1.124 -r1.125
--- circuit.c	17 Dec 2003 21:09:31 -0000	1.124
+++ circuit.c	19 Dec 2003 05:09:51 -0000	1.125
@@ -6,6 +6,9 @@
 
 extern or_options_t options; /* command-line and config-file options */
 
+static int relay_crypt(circuit_t *circ, char *in, char cell_direction,
+                crypt_path_t **layer_hint, char *recognized);
+static connection_t *relay_lookup_conn(circuit_t *circ, cell_t *cell, int cell_direction);
 static void circuit_free_cpath_node(crypt_path_t *victim);
 static circ_id_t get_unique_circ_id_by_conn(connection_t *conn, int circ_id_type);
 
@@ -310,11 +313,14 @@
 /* update digest from the payload of cell. assign integrity part to cell. */
 void relay_set_digest(crypto_digest_env_t *digest, cell_t *cell) {
   uint32_t integrity;
+  relay_header_t rh;
 
   crypto_digest_add_bytes(digest, cell->payload, CELL_PAYLOAD_SIZE);
   crypto_digest_get_digest(digest, (char *)&integrity, 4);
   log_fn(LOG_DEBUG,"Putting digest of %u into relay cell.",integrity);
-  SET_CELL_RELAY_INTEGRITY(*cell, integrity);
+  relay_header_unpack(&rh, cell->payload);
+  rh.integrity = integrity;
+  relay_header_pack(cell->payload, &rh);
 }
 
 /* update digest from the payload of cell (with the integrity part set
@@ -322,10 +328,14 @@
  */
 int relay_check_digest(crypto_digest_env_t *digest, cell_t *cell) {
   uint32_t received_integrity, calculated_integrity;
+  relay_header_t rh;
+
+  relay_header_unpack(&rh, cell->payload);
+  received_integrity = rh.integrity;
+  rh.integrity = 0;
+  relay_header_pack(cell->payload, &rh);
 
-  received_integrity = CELL_RELAY_INTEGRITY(*cell);
   log_fn(LOG_DEBUG,"Reading digest of %u from relay cell.",received_integrity);
-  SET_CELL_RELAY_INTEGRITY(*cell, 0);
 
   crypto_digest_add_bytes(digest, cell->payload, CELL_PAYLOAD_SIZE);
   crypto_digest_get_digest(digest, (char *)&calculated_integrity, 4);
@@ -346,15 +356,16 @@
   assert(cell && circ);
   assert(cell_direction == CELL_DIRECTION_OUT || cell_direction == CELL_DIRECTION_IN);
 
-  log_fn(LOG_DEBUG,"direction %d, streamid %d before crypt.", cell_direction, *(int*)(cell->payload+1));
+  log_fn(LOG_DEBUG,"direction %d, stream_id %d before crypt.", cell_direction, *(uint16_t*)(cell->payload+1));/*XXX*/
 
-  if(relay_crypt(circ, cell->payload, CELL_PAYLOAD_SIZE, cell_direction,
-                 &layer_hint, &recognized, &conn) < 0) {
+  if(relay_crypt(circ, cell->payload, cell_direction,
+                 &layer_hint, &recognized) < 0) {
     log_fn(LOG_WARN,"relay crypt failed. Dropping connection.");
     return -1;
   }
 
   if(recognized) {
+    conn = relay_lookup_conn(circ, cell, cell_direction);
     if(cell_direction == CELL_DIRECTION_OUT) {
        if(relay_check_digest(circ->n_digest, cell) < 0) {
         log_fn(LOG_WARN,"outgoing cell failed integrity check. Closing circ.");
@@ -400,14 +411,14 @@
   return 0;
 }
 
-int relay_crypt(circuit_t *circ, char *in, int inlen, char cell_direction,
-                crypt_path_t **layer_hint, char *recognized, connection_t **conn) {
+static int relay_crypt(circuit_t *circ, char *in, char cell_direction,
+                       crypt_path_t **layer_hint, char *recognized) {
   crypt_path_t *thishop;
-  char out[CELL_NETWORK_SIZE];
-
-  assert(circ && in && recognized && conn);
+  char out[CELL_PAYLOAD_SIZE]; /* 'in' must be this size too */
+  relay_header_t rh;
 
-  assert(inlen < CELL_NETWORK_SIZE);
+  assert(circ && in && recognized);
+  assert(cell_direction == CELL_DIRECTION_IN || cell_direction == CELL_DIRECTION_OUT);
 
   if(cell_direction == CELL_DIRECTION_IN) {
     if(circ->cpath) { /* we're at the beginning of the circuit.
@@ -420,16 +431,17 @@
       do { /* Remember: cpath is in forward order, that is, first hop first. */
         assert(thishop);
 
-        log_fn(LOG_DEBUG,"before decrypt: %d",*(int*)(in+1));
+        log_fn(LOG_DEBUG,"before decrypt: %d",*(uint16_t*)(in+1));
         /* decrypt */
-        if(crypto_cipher_decrypt(thishop->b_crypto, in, inlen, out)) {
+        if(crypto_cipher_decrypt(thishop->b_crypto, in, CELL_PAYLOAD_SIZE, out)) {
           log_fn(LOG_WARN,"Error performing onion decryption: %s", crypto_perror());
           return -1;
         }
-        memcpy(in,out,inlen);
-        log_fn(LOG_DEBUG,"after decrypt: %d",*(int*)(in+1));
+        memcpy(in,out,CELL_PAYLOAD_SIZE);
+        log_fn(LOG_DEBUG,"after decrypt: %d",*(uint16_t*)(in+1));
 
-        if( (*recognized = relay_check_recognized(circ, cell_direction, in+1, conn))) {
+        if(*(uint16_t*)(in+1) == 0) { /* XXX */
+          *recognized = 1;
           *layer_hint = thishop;
           return 0;
         }
@@ -440,20 +452,19 @@
       return 0;
     } else { /* we're in the middle. Just one crypt. */
 
-      log_fn(LOG_DEBUG,"before encrypt: %d",*(int*)(in+1));
-      if(crypto_cipher_encrypt(circ->p_crypto, in, inlen, out)) {
+      log_fn(LOG_DEBUG,"before encrypt: %d",*(uint16_t*)(in+1));
+      if(crypto_cipher_encrypt(circ->p_crypto, in, CELL_PAYLOAD_SIZE, out)) {
         log_fn(LOG_WARN,"Onion encryption failed for circID %u: %s",
                circ->p_circ_id, crypto_perror());
         return -1;
       }
-      memcpy(in,out,inlen);
-      log_fn(LOG_DEBUG,"after encrypt: %d",*(int*)(in+1));
+      memcpy(in,out,CELL_PAYLOAD_SIZE);
+      log_fn(LOG_DEBUG,"after encrypt: %d",*(uint16_t*)(in+1));
 
       log_fn(LOG_DEBUG,"Skipping recognized check, because we're not the OP.");
       /* don't check for recognized. only the OP can recognize a stream on the way back. */
-
     }
-  } else if(cell_direction == CELL_DIRECTION_OUT) {
+  } else /* cell_direction == CELL_DIRECTION_OUT */ {
     if(circ->cpath) { /* we're at the beginning of the circuit. We'll want to do layered crypts. */
 
       thishop = *layer_hint; /* we already know which layer, from when we package_raw_inbuf'ed */
@@ -461,69 +472,56 @@
       do {
         assert(thishop);
 
-        log_fn(LOG_DEBUG,"before encrypt: %d",*(int*)(in+1));
-        if(crypto_cipher_encrypt(thishop->f_crypto, in, inlen, out)) {
+        log_fn(LOG_DEBUG,"before encrypt: %d",*(uint16_t*)(in+1));
+        if(crypto_cipher_encrypt(thishop->f_crypto, in, CELL_PAYLOAD_SIZE, out)) {
           log_fn(LOG_WARN,"Error performing encryption: %s", crypto_perror());
           return -1;
         }
-        memcpy(in,out,inlen);
-        log_fn(LOG_DEBUG,"after encrypt: %d",*(int*)(in+1));
+        memcpy(in,out,CELL_PAYLOAD_SIZE);
+        log_fn(LOG_DEBUG,"after encrypt: %d",*(uint16_t*)(in+1));
 
         thishop = thishop->prev;
       } while(thishop != circ->cpath->prev);
     } else { /* we're in the middle. Just one crypt. */
 
-      if(crypto_cipher_decrypt(circ->n_crypto,in, inlen, out)) {
+      if(crypto_cipher_decrypt(circ->n_crypto,in, CELL_PAYLOAD_SIZE, out)) {
         log_fn(LOG_WARN,"Decryption failed for circID %u: %s",
                circ->n_circ_id, crypto_perror());
         return -1;
       }
-      memcpy(in,out,inlen);
+      memcpy(in,out,CELL_PAYLOAD_SIZE);
 
-      if( (*recognized = relay_check_recognized(circ, cell_direction, in+1, conn)))
+      if(*(uint16_t*)(in+1) == 0) { /* XXX */
+        *recognized = 1;
         return 0;
-
+      }
     }
-  } else {
-    log_fn(LOG_ERR,"unknown cell direction %d.", cell_direction);
-    assert(0);
   }
-
   return 0;
 }
 
-int relay_check_recognized(circuit_t *circ, int cell_direction, char *stream, connection_t **conn) {
-/* FIXME can optimize by passing thishop in */
+static connection_t *relay_lookup_conn(circuit_t *circ, cell_t *cell, int cell_direction) {
   connection_t *tmpconn;
+  relay_header_t rh;
 
-  if(!memcmp(stream,ZERO_STREAM,STREAM_ID_SIZE)) {
-    log_fn(LOG_DEBUG,"It's the zero stream. Recognized.");
-    return 1; /* the zero stream is always recognized */
-  }
-  log_fn(LOG_DEBUG,"not the zero stream.");
+  relay_header_unpack(&rh, cell->payload);
+
+  if(!rh.stream_id)
+    return NULL;
 
   if(cell_direction == CELL_DIRECTION_OUT)
     tmpconn = circ->n_streams;
   else
     tmpconn = circ->p_streams;
 
-  if(!tmpconn) {
-    log_fn(LOG_DEBUG,"No conns. Not recognized.");
-    return 0;
-  }
-
   for( ; tmpconn; tmpconn=tmpconn->next_stream) {
-    if(!memcmp(stream,tmpconn->stream_id, STREAM_ID_SIZE)) {
-      log_fn(LOG_DEBUG,"recognized stream %d.", *(int*)stream);
-      *conn = tmpconn;
-      return 1;
+    if(rh.stream_id == tmpconn->stream_id) {
+      log_fn(LOG_DEBUG,"found conn for stream %d.", rh.stream_id);
+      return tmpconn;
     }
-    log_fn(LOG_DEBUG,"considered stream %d, not it.",*(int*)tmpconn->stream_id);
+    log_fn(LOG_DEBUG,"considered stream %d, not it.",tmpconn->stream_id);
   }
-
-  log_fn(LOG_DEBUG,"Didn't recognize on this iteration of decryption.");
-  return 0;
-
+  return NULL; /* probably a begin relay cell */
 }
 
 void circuit_resume_edge_reading(circuit_t *circ, int edge_type, crypt_path_t *layer_hint) {
@@ -1060,7 +1058,7 @@
 
     for(stream = circ->p_streams; stream; stream=stream->next_stream) {
       if(stream->cpath_layer == victim) {
-        log_fn(LOG_INFO, "Marking stream %d for close.", *(int*)stream->stream_id);
+        log_fn(LOG_INFO, "Marking stream %d for close.", stream->stream_id);
         /* no need to send 'end' relay cells,
          * because the other side's already dead
          */

Index: connection.c
===================================================================
RCS file: /home/or/cvsroot/src/or/connection.c,v
retrieving revision 1.142
retrieving revision 1.143
diff -u -d -r1.142 -r1.143
--- connection.c	17 Dec 2003 21:09:31 -0000	1.142
+++ connection.c	19 Dec 2003 05:09:51 -0000	1.143
@@ -760,7 +760,7 @@
   }
 
   if (conn->type != CONN_TYPE_EXIT && conn->type != CONN_TYPE_AP) {
-    assert(!conn->stream_id[0]);
+    assert(!conn->stream_id);
     assert(!conn->next_stream);
     assert(!conn->cpath_layer);
     assert(!conn->package_window);

Index: connection_edge.c
===================================================================
RCS file: /home/or/cvsroot/src/or/connection_edge.c,v
retrieving revision 1.80
retrieving revision 1.81
diff -u -d -r1.80 -r1.81
--- connection_edge.c	17 Dec 2003 21:09:31 -0000	1.80
+++ connection_edge.c	19 Dec 2003 05:09:51 -0000	1.81
@@ -20,6 +20,22 @@
 static uint32_t client_dns_lookup_entry(const char *address);
 static void client_dns_set_entry(const char *address, uint32_t val);
 
+void relay_header_pack(char *dest, const relay_header_t *src) {
+  *(uint8_t*)(dest)    = src->command;
+  *(uint16_t*)(dest+1) = htons(src->recognized);
+  *(uint16_t*)(dest+3) = htons(src->stream_id);
+  *(uint32_t*)(dest+5) = htonl(src->integrity);
+  *(uint16_t*)(dest+9) = htons(src->length);
+}
+
+void relay_header_unpack(relay_header_t *dest, const char *src) {
+  dest->command    = *(uint8_t*)(src);
+  dest->recognized = ntohs(*(uint16_t*)(src+1));
+  dest->stream_id  = ntohs(*(uint16_t*)(src+3));
+  dest->integrity  = ntohl(*(uint32_t*)(src+5));
+  dest->length     = ntohs(*(uint16_t*)(src+9));
+}
+
 int connection_edge_process_inbuf(connection_t *conn) {
 
   assert(conn);
@@ -127,18 +143,16 @@
 int connection_edge_send_command(connection_t *fromconn, circuit_t *circ, int relay_command,
                                  void *payload, int payload_len, crypt_path_t *cpath_layer) {
   cell_t cell;
+  relay_header_t rh;
   int cell_direction;
-  int is_control_cell=0;
 
   if(!circ) {
     log_fn(LOG_WARN,"no circ. Closing.");
     return -1;
   }
 
-  if(!fromconn || relay_command == RELAY_COMMAND_BEGIN) /* XXX more */
-    is_control_cell = 1;
-
   memset(&cell, 0, sizeof(cell_t));
+  cell.command = CELL_RELAY;
 //  if(fromconn && fromconn->type == CONN_TYPE_AP) {
   if(cpath_layer) {
     cell.circ_id = circ->n_circ_id;
@@ -148,17 +162,14 @@
     cell_direction = CELL_DIRECTION_IN;
   }
 
-  cell.command = CELL_RELAY;
-  SET_CELL_RELAY_COMMAND(cell, relay_command);
-  if(is_control_cell)
-    SET_CELL_STREAM_ID(cell, ZERO_STREAM);
-  else
-    SET_CELL_STREAM_ID(cell, fromconn->stream_id);
-
-  SET_CELL_RELAY_LENGTH(cell, payload_len);
-  if(payload_len) {
-    memcpy(cell.payload+RELAY_HEADER_SIZE,payload,payload_len);
-  }
+  memset(&rh, 0, sizeof(rh));
+  rh.command = relay_command;
+  if(fromconn)
+    rh.stream_id = fromconn->stream_id; /* else it's 0 */
+  rh.length = payload_len;
+  relay_header_pack(cell.payload, &rh);
+  if(payload_len)
+    memcpy(cell.payload+RELAY_HEADER_SIZE, payload, payload_len);
 
   if(cell_direction == CELL_DIRECTION_OUT) /* AP */
     relay_set_digest(cpath_layer->f_digest, &cell);
@@ -180,14 +191,14 @@
  * circuit, else 0. */
 int connection_edge_process_relay_cell(cell_t *cell, circuit_t *circ, connection_t *conn,
                                        int edge_type, crypt_path_t *layer_hint) {
-  int relay_command;
   static int num_seen=0;
   uint32_t addr;
+  relay_header_t rh;
 
   assert(cell && circ);
 
-  relay_command = CELL_RELAY_COMMAND(*cell);
-//  log_fn(LOG_DEBUG,"command %d stream %d", relay_command, stream_id);
+  relay_header_unpack(&rh, cell->payload);
+//  log_fn(LOG_DEBUG,"command %d stream %d", rh.command, rh.stream_id);
   num_seen++;
   log_fn(LOG_DEBUG,"Now seen %d relay cells here.", num_seen);
 
@@ -195,9 +206,9 @@
    * conn points to the recognized stream. */
 
   if(conn && conn->state != AP_CONN_STATE_OPEN && conn->state != EXIT_CONN_STATE_OPEN) {
-    if(conn->type == CONN_TYPE_EXIT && relay_command == RELAY_COMMAND_END) {
+    if(conn->type == CONN_TYPE_EXIT && rh.command == RELAY_COMMAND_END) {
       log_fn(LOG_INFO,"Exit got end (%s) before we're connected. Marking for close.",
-        connection_edge_end_reason(cell->payload+RELAY_HEADER_SIZE, CELL_RELAY_LENGTH(*cell)));
+        connection_edge_end_reason(cell->payload+RELAY_HEADER_SIZE, rh.length));
       if(conn->state == EXIT_CONN_STATE_RESOLVING) {
         log_fn(LOG_INFO,"...and informing resolver we don't want the answer anymore.");
         dns_cancel_pending_resolve(conn->address, conn);
@@ -207,14 +218,14 @@
       return 0;
     } else {
       log_fn(LOG_WARN,"Got an unexpected relay command %d, in state %d (%s). Closing.",
-             relay_command, conn->state, conn_state_to_string[conn->type][conn->state]);
+             rh.command, conn->state, conn_state_to_string[conn->type][conn->state]);
       if(connection_edge_end(conn, END_STREAM_REASON_MISC, conn->cpath_layer) < 0)
         log_fn(LOG_WARN,"1: I called connection_edge_end redundantly.");
       return -1;
     }
   }
 
-  switch(relay_command) {
+  switch(rh.command) {
     case RELAY_COMMAND_BEGIN:
       if(edge_type == EDGE_AP) {
         log_fn(LOG_WARN,"relay begin request unsupported at AP. Dropping.");
@@ -235,12 +246,13 @@
           log_fn(LOG_WARN,"2: I called connection_edge_end redundantly.");
         return -1;
       }
-      log_fn(LOG_DEBUG,"circ deliver_window now %d.", edge_type == EDGE_AP ? layer_hint->deliver_window : circ->deliver_window);
+      log_fn(LOG_DEBUG,"circ deliver_window now %d.", edge_type == EDGE_AP ?
+             layer_hint->deliver_window : circ->deliver_window);
 
       circuit_consider_sending_sendme(circ, edge_type, layer_hint);
 
       if(!conn) {
-        log_fn(LOG_INFO,"relay cell dropped, unknown stream %d.",*(int*)conn->stream_id);
+        log_fn(LOG_INFO,"data cell dropped, unknown stream.");
         return 0;
       }
 
@@ -249,19 +261,18 @@
         return -1; /* somebody's breaking protocol. kill the whole circuit. */
       }
 
-      stats_n_data_bytes_received += CELL_RELAY_LENGTH(*cell);
+      stats_n_data_bytes_received += rh.length;
       connection_write_to_buf(cell->payload + RELAY_HEADER_SIZE,
-                              CELL_RELAY_LENGTH(*cell), conn);
+                              rh.length, conn);
       connection_edge_consider_sending_sendme(conn);
       return 0;
     case RELAY_COMMAND_END:
       if(!conn) {
-        log_fn(LOG_INFO,"end cell (%s) dropped, unknown stream %d.",
-          connection_edge_end_reason(cell->payload+RELAY_HEADER_SIZE, CELL_RELAY_LENGTH(*cell)),
-          *(int*)conn->stream_id);
+        log_fn(LOG_INFO,"end cell (%s) dropped, unknown stream.",
+          connection_edge_end_reason(cell->payload+RELAY_HEADER_SIZE, rh.length));
         return 0;
       }
-      if(CELL_RELAY_LENGTH(*cell) >= 5 &&
+      if(rh.length >= 5 &&
          *(cell->payload+RELAY_HEADER_SIZE) == END_STREAM_REASON_EXITPOLICY) {
         /* No need to close the connection. We'll hold it open while
          * we try a new exit node.
@@ -282,8 +293,8 @@
         }
       }
       log_fn(LOG_INFO,"end cell (%s) for stream %d. Removing stream.",
-        connection_edge_end_reason(cell->payload+RELAY_HEADER_SIZE, CELL_RELAY_LENGTH(*cell)),
-        *(int*)conn->stream_id);
+        connection_edge_end_reason(cell->payload+RELAY_HEADER_SIZE, rh.length),
+        conn->stream_id);
 
 #ifdef HALF_OPEN
       conn->done_sending = 1;
@@ -344,11 +355,11 @@
         return 0;
       }
       if(!conn) {
-        log_fn(LOG_INFO,"connected cell dropped, unknown stream %d.",*(int*)conn->stream_id);
+        log_fn(LOG_INFO,"connected cell dropped, unknown stream.");
         return 0;
       }
       log_fn(LOG_INFO,"Connected! Notifying application.");
-      if (CELL_RELAY_LENGTH(*cell) >= 4) {
+      if (rh.length >= 4) {
         addr = ntohl(*(uint32_t*)(cell->payload + RELAY_HEADER_SIZE));
         client_dns_set_entry(conn->socks_request->address, addr);
       }
@@ -363,12 +374,14 @@
         if(edge_type == EDGE_AP) {
           assert(layer_hint);
           layer_hint->package_window += CIRCWINDOW_INCREMENT;
-          log_fn(LOG_DEBUG,"circ-level sendme at AP, packagewindow %d.", layer_hint->package_window);
+          log_fn(LOG_DEBUG,"circ-level sendme at AP, packagewindow %d.",
+                 layer_hint->package_window);
           circuit_resume_edge_reading(circ, EDGE_AP, layer_hint);
         } else {
           assert(!layer_hint);
           circ->package_window += CIRCWINDOW_INCREMENT;
-          log_fn(LOG_DEBUG,"circ-level sendme at exit, packagewindow %d.", circ->package_window);
+          log_fn(LOG_DEBUG,"circ-level sendme at exit, packagewindow %d.",
+                 circ->package_window);
           circuit_resume_edge_reading(circ, EDGE_EXIT, layer_hint);
         }
         return 0;
@@ -378,11 +391,8 @@
       connection_start_reading(conn);
       connection_edge_package_raw_inbuf(conn); /* handle whatever might still be on the inbuf */
       return 0;
-    default:
-      log_fn(LOG_WARN,"unknown relay command %d.",relay_command);
-      return -1;
   }
-  assert(0);
+  log_fn(LOG_WARN,"unknown relay command %d.",rh.command);
   return -1;
 }
 
@@ -667,20 +677,19 @@
   assert(ap_conn->state == AP_CONN_STATE_CIRCUIT_WAIT);
   assert(ap_conn->socks_request);
 
-  crypto_pseudo_rand(STREAM_ID_SIZE, ap_conn->stream_id);
-  /* FIXME check for collisions */
+  crypto_pseudo_rand(sizeof(ap_conn->stream_id), (unsigned char*) &ap_conn->stream_id);
+  /* XXX check for collisions */
 
   in.s_addr = htonl(client_dns_lookup_entry(ap_conn->socks_request->address));
   string_addr = in.s_addr ? inet_ntoa(in) : NULL;
 
-  memcpy(payload, ap_conn->stream_id, STREAM_ID_SIZE);
-  payload_len = STREAM_ID_SIZE + 1 +
-    snprintf(payload+STREAM_ID_SIZE,CELL_PAYLOAD_SIZE-RELAY_HEADER_SIZE-STREAM_ID_SIZE,
-             "%s:%d",
-             string_addr ? string_addr : ap_conn->socks_request->address,
-             ap_conn->socks_request->port);
+  snprintf(payload,RELAY_PAYLOAD_SIZE,
+           "%s:%d",
+           string_addr ? string_addr : ap_conn->socks_request->address,
+           ap_conn->socks_request->port);
+  payload_len = strlen(payload)+1;
 
-  log_fn(LOG_DEBUG,"Sending relay cell to begin stream %d.",*(int *)ap_conn->stream_id);
+  log_fn(LOG_DEBUG,"Sending relay cell to begin stream %d.",ap_conn->stream_id);
 
   if(connection_edge_send_command(ap_conn, circ, RELAY_COMMAND_BEGIN,
                                payload, payload_len, ap_conn->cpath_layer) < 0)
@@ -734,18 +743,20 @@
 
 static int connection_exit_begin_conn(cell_t *cell, circuit_t *circ) {
   connection_t *n_stream;
+  relay_header_t rh;
   char *colon;
 
+  relay_header_unpack(&rh, cell->payload);
+
   /* XXX currently we don't send an end cell back if we drop the
    * begin because it's malformed.
    */
 
-  if(!memchr(cell->payload+RELAY_HEADER_SIZE+STREAM_ID_SIZE,0,
-             CELL_RELAY_LENGTH(*cell)-STREAM_ID_SIZE)) {
+  if(!memchr(cell->payload+RELAY_HEADER_SIZE, 0, rh.length)) {
     log_fn(LOG_WARN,"relay begin cell has no \\0. Dropping.");
     return 0;
   }
-  colon = strchr(cell->payload+RELAY_HEADER_SIZE+STREAM_ID_SIZE, ':');
+  colon = strchr(cell->payload+RELAY_HEADER_SIZE, ':');
   if(!colon) {
     log_fn(LOG_WARN,"relay begin cell has no colon. Dropping.");
     return 0;
@@ -760,8 +771,8 @@
   log_fn(LOG_DEBUG,"Creating new exit connection.");
   n_stream = connection_new(CONN_TYPE_EXIT);
 
-  memcpy(n_stream->stream_id, cell->payload + RELAY_HEADER_SIZE, STREAM_ID_SIZE);
-  n_stream->address = tor_strdup(cell->payload + RELAY_HEADER_SIZE + STREAM_ID_SIZE);
+  n_stream->stream_id = rh.stream_id;
+  n_stream->address = tor_strdup(cell->payload + RELAY_HEADER_SIZE);
   n_stream->port = atoi(colon+1);
   n_stream->state = EXIT_CONN_STATE_RESOLVING;
   /* leave n_stream->s at -1, because it's not yet valid */

Index: or.h
===================================================================
RCS file: /home/or/cvsroot/src/or/or.h,v
retrieving revision 1.211
retrieving revision 1.212
diff -u -d -r1.211 -r1.212
--- or.h	17 Dec 2003 21:09:31 -0000	1.211
+++ or.h	19 Dec 2003 05:09:51 -0000	1.212
@@ -235,36 +235,45 @@
 /*
  * Relay payload:
  *         Relay command           [1 byte]
- *         Stream ID               [7 bytes]
+ *         Recognized              [2 bytes]
+ *         Stream ID               [2 bytes]
  *         Partial SHA-1           [4 bytes]
  *         Length                  [2 bytes]
- *         Relay payload           [495 bytes]
+ *         Relay payload           [498 bytes]
  */
 
+#if 0
 #define CELL_RELAY_COMMAND(c)         (*(uint8_t*)((c).payload))
 #define SET_CELL_RELAY_COMMAND(c,cmd) (*(uint8_t*)((c).payload) = (cmd))
 
-#define STREAM_ID_SIZE 7
-#define SET_CELL_STREAM_ID(c,id)      memcpy((c).payload+1,(id),STREAM_ID_SIZE)
-#define ZERO_STREAM "\0\0\0\0\0\0\0"
+#define CELL_RELAY_RECOGNIZED(c)       (ntohs(*(uint16_t*)((c).payload+1)))
+#define SET_CELL_RELAY_RECOGNIZED(c,r) (*(uint16_t*)((c).payload+1) = htons(r))
 
-#define CELL_RELAY_COMMAND_END_REASON(c) (*(uint8_t)((c).payload+1))
+#define STREAM_ID_SIZE 2
+//#define SET_CELL_STREAM_ID(c,id)      memcpy((c).payload+1,(id),STREAM_ID_SIZE)
+#define CELL_RELAY_STREAM_ID(c)        (ntohs(*(uint16_t*)((c).payload+3)))
+#define SET_CELL_RELAY_STREAM_ID(c,id) (*(uint16_t*)((c).payload+3) = htons(id))
+#define ZERO_STREAM 0
 
 /* integrity is the first 32 bits (in network order) of a sha-1 of all
  * cell payloads that are relay cells that have been sent / delivered
  * to the hop on the * circuit (the integrity is zeroed while doing
  * each calculation)
  */
-#define CELL_RELAY_INTEGRITY(c)       (ntohl(*(uint32_t*)((c).payload+1+STREAM_ID_SIZE)))
-#define SET_CELL_RELAY_INTEGRITY(c,i) (*(uint32_t*)((c).payload+1+STREAM_ID_SIZE) = htonl(i))
+#define CELL_RELAY_INTEGRITY(c)       (ntohl(*(uint32_t*)((c).payload+5)))
+#define SET_CELL_RELAY_INTEGRITY(c,i) (*(uint32_t*)((c).payload+5) = htonl(i))
 
 /* relay length is how many bytes are used in the cell payload past relay_header_size */
-#define CELL_RELAY_LENGTH(c)         (ntohs(*(uint16_t*)((c).payload+1+STREAM_ID_SIZE+4)))
-#define SET_CELL_RELAY_LENGTH(c,len) (*(uint16_t*)((c).payload+1+STREAM_ID_SIZE+4) = htons(len))
+#define CELL_RELAY_LENGTH(c)         (ntohs(*(uint16_t*)((c).payload+9)))
+#define SET_CELL_RELAY_LENGTH(c,len) (*(uint16_t*)((c).payload+9) = htons(len))
+#endif
 
 #define CELL_PAYLOAD_SIZE 509
 #define CELL_NETWORK_SIZE 512
 
+#define RELAY_HEADER_SIZE (1+2+2+4+2)
+#define RELAY_PAYLOAD_SIZE (CELL_PAYLOAD_SIZE-RELAY_HEADER_SIZE)
+
 /* cell definition */
 typedef struct {
   circ_id_t circ_id;
@@ -272,8 +281,13 @@
   unsigned char payload[CELL_PAYLOAD_SIZE];
 } cell_t;
 
-#define RELAY_HEADER_SIZE (1+STREAM_ID_SIZE+4+2)
-#define RELAY_PAYLOAD_SIZE (CELL_PAYLOAD_SIZE-RELAY_HEADER_SIZE)
+typedef struct {
+  uint8_t command;
+  uint16_t recognized;
+  uint16_t stream_id;
+  uint32_t integrity;
+  uint16_t length;
+} relay_header_t;
 
 typedef struct buf_t buf_t;
 typedef struct socks_request_t socks_request_t;
@@ -327,7 +341,7 @@
                         */
 
 /* Used only by edge connections: */
-  char stream_id[STREAM_ID_SIZE];
+  uint16_t stream_id;
   struct 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? */
@@ -556,9 +570,6 @@
 int relay_check_digest(crypto_digest_env_t *digest, cell_t *cell);
 int circuit_deliver_relay_cell(cell_t *cell, circuit_t *circ,
                                int cell_direction, crypt_path_t *layer_hint);
-int relay_crypt(circuit_t *circ, char *in, int inlen, char cell_direction,
-                crypt_path_t **layer_hint, char *recognized, connection_t **conn);
-int relay_check_recognized(circuit_t *circ, int cell_direction, char *stream, connection_t **conn);
 
 void circuit_resume_edge_reading(circuit_t *circ, int edge_type, crypt_path_t *layer_hint);
 int circuit_consider_stop_edge_reading(circuit_t *circ, int edge_type, crypt_path_t *layer_hint);
@@ -648,6 +659,8 @@
 
 /********************************* connection_edge.c ***************************/
 
+void relay_header_pack(char *dest, const relay_header_t *src);
+void relay_header_unpack(relay_header_t *dest, const char *src);
 int connection_edge_process_inbuf(connection_t *conn);
 int connection_edge_end(connection_t *conn, char reason, crypt_path_t *cpath_layer);
 



More information about the tor-commits mailing list