[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

[or-cvs] add circuit-level sendme relay cells



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

Modified Files:
	buffers.c circuit.c command.c config.c connection.c 
	connection_ap.c connection_edge.c connection_exit.c 
	directory.c dns.c main.c onion.c or.h routers.c test.c 
Log Message:
add circuit-level sendme relay cells
remove sendme cells
replace malloc with tor_malloc
patch (but not track down) bug in onion pending list
streamline connection_ap handshake



Index: buffers.c
===================================================================
RCS file: /home/or/cvsroot/src/or/buffers.c,v
retrieving revision 1.21
retrieving revision 1.22
diff -u -d -r1.21 -r1.22
--- buffers.c	1 May 2003 06:42:28 -0000	1.21
+++ buffers.c	20 May 2003 06:41:22 -0000	1.22
@@ -10,15 +10,13 @@
 
 /* Create a new buf of size MAX_BUF_SIZE. Write a pointer to it
  * into *buf, write MAX_BUF_SIZE into *buflen, and initialize
- * *buf_datalen to 0. Return 0 if success, or -1 if malloc fails.
+ * *buf_datalen to 0. Return 0.
  */
 int buf_new(char **buf, int *buflen, int *buf_datalen) {
 
   assert(buf && buflen && buf_datalen);
 
-  *buf = (char *)malloc(MAX_BUF_SIZE);
-  if(!*buf)
-    return -1;
+  *buf = (char *)tor_malloc(MAX_BUF_SIZE);
 //  memset(*buf,0,MAX_BUF_SIZE);
   *buflen = MAX_BUF_SIZE;
   *buf_datalen = 0;
@@ -139,9 +137,7 @@
 z_stream *zstream_new(int compression)
 {
   z_stream* stream;
-  stream = malloc(sizeof(z_stream));
-  if (!stream)
-    return NULL;
+  stream = tor_malloc(sizeof(z_stream));
   memset(stream, 0, sizeof(z_stream));
   if (compression) {
     if (deflateInit(stream, Z_DEFAULT_COMPRESSION) != Z_OK) {

Index: circuit.c
===================================================================
RCS file: /home/or/cvsroot/src/or/circuit.c,v
retrieving revision 1.43
retrieving revision 1.44
diff -u -d -r1.43 -r1.44
--- circuit.c	6 May 2003 05:54:42 -0000	1.43
+++ circuit.c	20 May 2003 06:41:22 -0000	1.44
@@ -55,9 +55,7 @@
 
   my_gettimeofday(&now);
 
-  circ = (circuit_t *)malloc(sizeof(circuit_t));
-  if(!circ)
-    return NULL;
+  circ = (circuit_t *)tor_malloc(sizeof(circuit_t));
   memset(circ,0,sizeof(circuit_t)); /* zero it out */
 
   circ->timestamp_created = now.tv_sec;
@@ -71,8 +69,8 @@
   circ->p_aci = p_aci;
   /* circ->n_aci remains 0 because we haven't identified the next hop yet */
 
-  circ->n_receive_circwindow = CIRCWINDOW_START;
-  circ->p_receive_circwindow = CIRCWINDOW_START;
+  circ->package_window = CIRCWINDOW_START;
+  circ->deliver_window = CIRCWINDOW_START;
 
   circuit_add(circ);
 
@@ -230,30 +228,36 @@
     cell_direction = CELL_DIRECTION_OUT;
     numsent_ap++;
     log(LOG_DEBUG,"circuit_deliver_relay_cell_from_edge(): now sent %d relay cells from ap", numsent_ap);
-    if(circ->p_receive_circwindow <= 0) {
-      log(LOG_DEBUG,"circuit_deliver_relay_cell_from_edge(): pwindow 0, queueing for later.");
+#if 0
+    if(layer_hint->package_window <= 0) {
+      log(LOG_DEBUG,"circuit_deliver_relay_cell_from_edge(): package_window 0, queueing for later.");
       circ->relay_queue = relay_queue_add(circ->relay_queue, cell, layer_hint);
       return 0;
     }
-    circ->p_receive_circwindow--;
-//    log(LOG_INFO,"circuit_deliver_relay_cell_from_edge(): p_receive_circwindow now %d.",circ->p_receive_circwindow);
+    layer_hint->package_window--;
+//    log(LOG_INFO,"circuit_deliver_relay_cell_from_edge(): package_window now %d.",layer_hint->package_window);
+#endif
   } else { /* i'm the exit */
     cell_direction = CELL_DIRECTION_IN;
+//    assert(layer_hint == NULL);
+//    assert(circ->cpath == NULL);
     numsent_exit++;
     log(LOG_DEBUG,"circuit_deliver_relay_cell_from_edge(): now sent %d relay cells from exit", numsent_exit);
-    if(circ->n_receive_circwindow <= 0) {
-      log(LOG_DEBUG,"circuit_deliver_relay_cell_from_edge(): nwindow 0, queueing for later.");
+#if 0
+    if(circ->package_window <= 0) {
+      log(LOG_DEBUG,"circuit_deliver_relay_cell_from_edge(): package_window 0, queueing for later.");
       circ->relay_queue = relay_queue_add(circ->relay_queue, cell, layer_hint);
       return 0;
     }
-    circ->n_receive_circwindow--;
+    circ->package_window--;
+#endif
   }
 
   if(circuit_deliver_relay_cell(cell, circ, cell_direction, layer_hint) < 0) {
     return -1;
   }
 
-  circuit_consider_stop_edge_reading(circ, edge_type); /* has window reached 0? */
+//  circuit_consider_stop_edge_reading(circ, edge_type, layer_hint); /* has window reached 0? */
   return 0;
 }
 
@@ -271,7 +275,7 @@
 
   log(LOG_DEBUG,"circuit_deliver_relay_cell(): direction %d, streamid %d before crypt.", cell_direction, *(int*)(cell->payload+1));
 
-  if(relay_crypt(circ, buf, 1+CELL_PAYLOAD_SIZE, cell_direction, layer_hint, &recognized, &conn) < 0) {
+  if(relay_crypt(circ, buf, 1+CELL_PAYLOAD_SIZE, cell_direction, &layer_hint, &recognized, &conn) < 0) {
     log(LOG_DEBUG,"circuit_deliver_relay_cell(): relay crypt failed. Dropping connection.");
     return -1;
   }
@@ -282,11 +286,11 @@
   if(recognized) {
     if(cell_direction == CELL_DIRECTION_OUT) {
       log(LOG_DEBUG,"circuit_deliver_relay_cell(): Sending to exit.");
-      return connection_edge_process_relay_cell(cell, circ, conn, EDGE_EXIT);
+      return connection_edge_process_relay_cell(cell, circ, conn, EDGE_EXIT, NULL);
     }
     if(cell_direction == CELL_DIRECTION_IN) {
       log(LOG_DEBUG,"circuit_deliver_relay_cell(): Sending to AP.");
-      return connection_edge_process_relay_cell(cell, circ, conn, EDGE_AP);
+      return connection_edge_process_relay_cell(cell, circ, conn, EDGE_AP, layer_hint);
     }
   }
 
@@ -306,7 +310,7 @@
 }
 
 int relay_crypt(circuit_t *circ, char *in, int inlen, char cell_direction,
-                crypt_path_t *layer_hint, char *recognized, connection_t **conn) {
+                crypt_path_t **layer_hint, char *recognized, connection_t **conn) {
   crypt_path_t *thishop;
   char out[256];
 
@@ -333,8 +337,10 @@
         memcpy(in,out,inlen);
         log(LOG_DEBUG,"relay_crypt(): after decrypt: %d",*(int*)(in+2));
 
-        if( (*recognized = relay_check_recognized(circ, cell_direction, in+2, conn)))
+        if( (*recognized = relay_check_recognized(circ, cell_direction, in+2, conn))) {
+          *layer_hint = thishop;
           return 0;
+        }
 
         thishop = thishop->next;
       } while(thishop != circ->cpath && thishop->state == CPATH_STATE_OPEN);
@@ -359,7 +365,7 @@
   } else if(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 */
+      thishop = *layer_hint; /* we already know which layer, from when we package_raw_inbuf'ed */
       /* moving from last to first hop */
       do {
         assert(thishop);
@@ -435,40 +441,53 @@
 
 }
 
-void circuit_resume_edge_reading(circuit_t *circ, int edge_type) {
+void circuit_resume_edge_reading(circuit_t *circ, int edge_type, crypt_path_t *layer_hint) {
   connection_t *conn;
-  struct relay_queue_t *tmpd;
+  struct relay_queue_t *relay, *victim;
 
   assert(edge_type == EDGE_EXIT || edge_type == EDGE_AP);
 
+  log(LOG_DEBUG,"circuit_resume_edge_reading(): resuming");
+#if 0
   /* first, send the queue waiting at circ onto the circuit */
-  while(circ->relay_queue) {
-    assert(circ->relay_queue->cell);
+  relay = circ->relay_queue;
+  while(relay) {
+    assert(relay->cell);
     if(edge_type == EDGE_EXIT) {
-      circ->n_receive_circwindow--;
-      assert(circ->n_receive_circwindow >= 0);
+      assert(relay->layer_hint == NULL);
+      circ->package_window--;
+      assert(circ->package_window >= 0);
 
-      if(circuit_deliver_relay_cell(circ->relay_queue->cell, circ, CELL_DIRECTION_IN, circ->relay_queue->layer_hint) < 0) {
+      if(circuit_deliver_relay_cell(relay->cell, circ, CELL_DIRECTION_IN, relay->layer_hint) < 0) {
         circuit_close(circ);
         return;
       }
     } else { /* ap */
-      circ->p_receive_circwindow--;
-      assert(circ->p_receive_circwindow >= 0);
+      assert(relay->layer_hint);
+      if(relay->layer_hint != layer_hint) {
+        relay=relay->next; /* this cell isn't destined for this layer. don't send it. */
+        continue;
+      }
+      relay->layer_hint->package_window--;
+      assert(relay->layer_hint->package_window >= 0);
 
-      if(circuit_deliver_relay_cell(circ->relay_queue->cell, circ, CELL_DIRECTION_OUT, circ->relay_queue->layer_hint) < 0) {
+      if(circuit_deliver_relay_cell(relay->cell, circ, CELL_DIRECTION_OUT, relay->layer_hint) < 0) {
         circuit_close(circ);
         return;
       }
     }
-    tmpd = circ->relay_queue;
-    circ->relay_queue = tmpd->next;
-    free(tmpd->cell);
-    free(tmpd);
+    victim = relay;
+    relay=relay->next;
+    if(circ->relay_queue == victim) {
+      circ->relay_queue = relay;
+    }
+    free(victim->cell);
+    free(victim);
 
-    if(circuit_consider_stop_edge_reading(circ, edge_type))
+    if(circuit_consider_stop_edge_reading(circ, edge_type, layer_hint))
       return;
   }
+#endif
 
   if(edge_type == EDGE_EXIT)
     conn = circ->n_conn;
@@ -476,58 +495,64 @@
     conn = circ->p_conn;
 
   for( ; conn; conn=conn->next_stream) {
-    if((edge_type == EDGE_EXIT && conn->n_receive_streamwindow > 0) ||
-       (edge_type == EDGE_AP   && conn->p_receive_streamwindow > 0)) {
+    if((edge_type == EDGE_EXIT && conn->package_window > 0) ||
+       (edge_type == EDGE_AP   && conn->package_window > 0 && conn->cpath_layer == layer_hint)) {
       connection_start_reading(conn);
       connection_package_raw_inbuf(conn); /* handle whatever might still be on the inbuf */
     }
   }
-  circuit_consider_stop_edge_reading(circ, edge_type);
+  circuit_consider_stop_edge_reading(circ, edge_type, layer_hint);
 }
 
 /* returns 1 if the window is empty, else 0. If it's empty, tell edge conns to stop reading. */
-int circuit_consider_stop_edge_reading(circuit_t *circ, int edge_type) {
+int circuit_consider_stop_edge_reading(circuit_t *circ, int edge_type, crypt_path_t *layer_hint) {
   connection_t *conn = NULL;
 
   assert(edge_type == EDGE_EXIT || edge_type == EDGE_AP);
+  assert(edge_type == EDGE_EXIT || layer_hint);
 
-  if(edge_type == EDGE_EXIT && circ->n_receive_circwindow <= 0)
+  log(LOG_DEBUG,"circuit_consider_stop_edge_reading(): considering");
+  if(edge_type == EDGE_EXIT && circ->package_window <= 0)
     conn = circ->n_conn;
-  else if(edge_type == EDGE_AP && circ->p_receive_circwindow <= 0)
+  else if(edge_type == EDGE_AP && layer_hint->package_window <= 0)
     conn = circ->p_conn;
   else
     return 0;
 
   for( ; conn; conn=conn->next_stream)
-    connection_stop_reading(conn);
+    if(!layer_hint || conn->cpath_layer == layer_hint)
+      connection_stop_reading(conn);
 
+  log(LOG_DEBUG,"circuit_consider_stop_edge_reading(): yes. stopped.");
   return 1;
 }
 
-int circuit_consider_sending_sendme(circuit_t *circ, int edge_type) {
-  cell_t sendme;
+int circuit_consider_sending_sendme(circuit_t *circ, int edge_type, crypt_path_t *layer_hint) {
+  cell_t cell;
 
   assert(circ);
 
-  memset(&sendme, 0, sizeof(cell_t));
-  sendme.command = CELL_SENDME;
-  sendme.length = CIRCWINDOW_INCREMENT;
+  memset(&cell, 0, sizeof(cell_t));
+  cell.command = CELL_RELAY;
+  SET_CELL_RELAY_COMMAND(cell, RELAY_COMMAND_SENDME);
+  SET_CELL_STREAM_ID(cell, ZERO_STREAM);
 
+  cell.length = RELAY_HEADER_SIZE;
   if(edge_type == EDGE_AP) { /* i'm the AP */
-    while(circ->n_receive_circwindow < CIRCWINDOW_START-CIRCWINDOW_INCREMENT) {
-      log(LOG_DEBUG,"circuit_consider_sending_sendme(): n_receive_circwindow %d, Queueing sendme forward.", circ->n_receive_circwindow);
-      circ->n_receive_circwindow += CIRCWINDOW_INCREMENT;
-      sendme.aci = circ->n_aci;
-      if(connection_write_cell_to_buf(&sendme, circ->n_conn) < 0) {
+    cell.aci = circ->n_aci;
+    while(layer_hint->deliver_window < CIRCWINDOW_START-CIRCWINDOW_INCREMENT) {
+      log(LOG_DEBUG,"circuit_consider_sending_sendme(): deliver_window %d, Queueing sendme forward.", layer_hint->deliver_window);
+      layer_hint->deliver_window += CIRCWINDOW_INCREMENT;
+      if(circuit_deliver_relay_cell_from_edge(&cell, circ, edge_type, layer_hint) < 0) {
         return -1;
       }
     }
   } else if(edge_type == EDGE_EXIT) { /* i'm the exit */
-    while(circ->p_receive_circwindow < CIRCWINDOW_START-CIRCWINDOW_INCREMENT) {
-      log(LOG_DEBUG,"circuit_consider_sending_sendme(): p_receive_circwindow %d, Queueing sendme back.", circ->p_receive_circwindow);
-      circ->p_receive_circwindow += CIRCWINDOW_INCREMENT;
-      sendme.aci = circ->p_aci;
-      if(connection_write_cell_to_buf(&sendme, circ->p_conn) < 0) {
+    cell.aci = circ->p_aci;
+    while(circ->deliver_window < CIRCWINDOW_START-CIRCWINDOW_INCREMENT) {
+      log(LOG_DEBUG,"circuit_consider_sending_sendme(): deliver_window %d, Queueing sendme back.", circ->deliver_window);
+      circ->deliver_window += CIRCWINDOW_INCREMENT;
+      if(circuit_deliver_relay_cell_from_edge(&cell, circ, edge_type, layer_hint) < 0) {
         return -1;
       }
     }

Index: command.c
===================================================================
RCS file: /home/or/cvsroot/src/or/command.c,v
retrieving revision 1.29
retrieving revision 1.30
diff -u -d -r1.29 -r1.30
--- command.c	7 May 2003 22:40:03 -0000	1.29
+++ command.c	20 May 2003 06:41:22 -0000	1.30
@@ -28,8 +28,8 @@
 }
 
 void command_process_cell(cell_t *cell, connection_t *conn) {
-  static int num_create=0, num_created=0, num_relay=0, num_destroy=0, num_sendme=0;
-  static int create_time=0, created_time=0, relay_time=0, destroy_time=0, sendme_time=0;
+  static int num_create=0, num_created=0, num_relay=0, num_destroy=0;
+  static int create_time=0, created_time=0, relay_time=0, destroy_time=0;
   static long current_second = 0; /* from previous calls to gettimeofday */
   struct timeval now;
 
@@ -42,11 +42,10 @@
     log(LOG_INFO,"Created:   %d (%d ms)", num_created, created_time/1000);
     log(LOG_INFO,"Relay:     %d (%d ms)", num_relay, relay_time/1000);
     log(LOG_INFO,"Destroy:   %d (%d ms)", num_destroy, destroy_time/1000);
-    log(LOG_INFO,"Sendme:    %d (%d ms)", num_sendme, sendme_time/1000);
 
     /* zero out stats */
-    num_create = num_created = num_relay = num_destroy = num_sendme = 0;
-    create_time = created_time = relay_time = destroy_time = sendme_time = 0;
+    num_create = num_created = num_relay = num_destroy = 0;
+    create_time = created_time = relay_time = destroy_time = 0;
 
     /* remember which second it is, for next time */
     current_second = now.tv_sec; 
@@ -72,10 +71,6 @@
       command_time_process_cell(cell, conn, &num_destroy, &destroy_time,
                                 command_process_destroy_cell);
       break;
-    case CELL_SENDME:
-      command_time_process_cell(cell, conn, &num_sendme, &sendme_time,
-                                command_process_sendme_cell);
-      break;
     default:
       log(LOG_DEBUG,"Cell of unknown type (%d) received. Dropping.", cell->command);
       break;
@@ -161,63 +156,6 @@
   return;
 }
 
-void command_process_sendme_cell(cell_t *cell, connection_t *conn) {
-  circuit_t *circ;
-
-  circ = circuit_get_by_aci_conn(cell->aci, conn);
-
-  if(!circ) {
-    log(LOG_DEBUG,"command_process_sendme_cell(): unknown circuit %d. Dropping.", cell->aci);
-    return;
-  }
-
-#if 0
-  if(circ->state == CIRCUIT_STATE_ONION_WAIT) {
-    log(LOG_DEBUG,"command_process_sendme_cell(): circuit in onion_wait. Dropping.");
-    return;
-  }
-  if(circ->state == CIRCUIT_STATE_OR_WAIT) {
-    log(LOG_DEBUG,"command_process_sendme_cell(): circuit in or_wait. Dropping.");
-    return;
-  }
-#endif
-
-  /* at this point both circ->n_conn and circ->p_conn are guaranteed to be set */
-
-  if(cell->length != CIRCWINDOW_INCREMENT) {
-    log(LOG_WARNING,"command_process_sendme_cell(): non-standard sendme value %d.",cell->length);
-  }
-
-  if(cell->aci == circ->p_aci) { /* it's an outgoing cell */
-    circ->n_receive_circwindow += cell->length;
-    assert(circ->n_receive_circwindow <= CIRCWINDOW_START);
-    log(LOG_DEBUG,"command_process_sendme_cell(): n_receive_circwindow for aci %d is %d.",circ->n_aci,circ->n_receive_circwindow);
-    if(!circ->n_conn || circ->n_conn->type == CONN_TYPE_EXIT) {
-      circuit_resume_edge_reading(circ, EDGE_EXIT);
-    } else {
-      cell->aci = circ->n_aci; /* switch it */
-      if(connection_write_cell_to_buf(cell, circ->n_conn) < 0) {
-        circuit_close(circ);
-        return;
-      }
-    }
-  } else { /* it's an ingoing cell */
-    assert(cell->aci == circ->n_aci);
-    circ->p_receive_circwindow += cell->length;
-    log(LOG_DEBUG,"command_process_sendme_cell(): p_receive_circwindow for aci %d is %d.",circ->p_aci,circ->p_receive_circwindow);
-    assert(circ->p_receive_circwindow <= CIRCWINDOW_START);
-    if(!circ->p_conn || circ->p_conn->type == CONN_TYPE_AP) {
-      circuit_resume_edge_reading(circ, EDGE_AP);
-    } else {
-      cell->aci = circ->p_aci; /* switch it */
-      if(connection_write_cell_to_buf(cell, circ->p_conn) < 0) {
-        circuit_close(circ);
-        return;
-      }
-    }
-  } 
-}
-
 void command_process_relay_cell(cell_t *cell, connection_t *conn) {
   circuit_t *circ;
 
@@ -234,6 +172,7 @@
     return;
   }
 
+#if 0
   if(cell->aci == circ->p_aci) { /* it's an outgoing cell */
     if(--circ->p_receive_circwindow < 0) { /* is it less than 0 after decrement? */
       log(LOG_INFO,"command_process_relay_cell(): Too many relay cells for out circuit (aci %d). Closing.", circ->p_aci);
@@ -251,6 +190,7 @@
     }
     log(LOG_DEBUG,"command_process_relay_cell(): n_receive_circwindow for aci %d is %d.",circ->n_aci,circ->n_receive_circwindow);
   }
+#endif
 
 #if 0
   if(circ->state == CIRCUIT_STATE_ONION_WAIT) {

Index: config.c
===================================================================
RCS file: /home/or/cvsroot/src/or/config.c,v
retrieving revision 1.32
retrieving revision 1.33
diff -u -d -r1.32 -r1.33
--- config.c	7 May 2003 22:40:03 -0000	1.32
+++ config.c	20 May 2003 06:41:22 -0000	1.33
@@ -43,7 +43,7 @@
       continue;
     }
 
-    new = malloc(sizeof(struct config_line));
+    new = tor_malloc(sizeof(struct config_line));
     s = argv[i];
     while(*s == '-')
       s++;
@@ -107,7 +107,7 @@
     *end = 0; /* null it out */
 
     /* prepare to parse the string into key / value */
-    new = malloc(sizeof(struct config_line));
+    new = tor_malloc(sizeof(struct config_line));
     new->key = strdup(start);
     new->value = strdup(s);
 

Index: connection.c
===================================================================
RCS file: /home/or/cvsroot/src/or/connection.c,v
retrieving revision 1.60
retrieving revision 1.61
diff -u -d -r1.60 -r1.61
--- connection.c	5 May 2003 23:24:45 -0000	1.60
+++ connection.c	20 May 2003 06:41:22 -0000	1.61
@@ -70,9 +70,7 @@
 
   my_gettimeofday(&now);
 
-  conn = (connection_t *)malloc(sizeof(connection_t));
-  if(!conn)
-    return NULL;
+  conn = (connection_t *)tor_malloc(sizeof(connection_t));
   memset(conn,0,sizeof(connection_t)); /* zero it out to start */
 
   conn->type = type;
@@ -655,7 +653,7 @@
 
   assert(conn);
   assert(!connection_speaks_cells(conn));
-  /* this function should never get called if the receive_streamwindow is 0 */
+  /* this function should never get called if either package_window is 0 */
  
 repeat_connection_package_raw_inbuf:
 
@@ -713,13 +711,8 @@
       circuit_close(circ);
       return 0;
     }
-    assert(conn->n_receive_streamwindow > 0);
-    if(--conn->n_receive_streamwindow <= 0) { /* is it 0 after decrement? */
-      connection_stop_reading(conn);
-      log(LOG_DEBUG,"connection_package_raw_inbuf(): receive_streamwindow at exit reached 0.");
-      return 0; /* don't process the inbuf any more */
-    }
-    log(LOG_DEBUG,"connection_package_raw_inbuf(): receive_streamwindow at exit is %d",conn->n_receive_streamwindow);
+    assert(circ->package_window > 0);
+    circ->package_window--;
   } else { /* send it forward. we're an AP */
     assert(conn->type == CONN_TYPE_AP);
     cell.aci = circ->n_aci;
@@ -728,14 +721,23 @@
       circuit_close(circ);
       return 0;
     }
-    assert(conn->p_receive_streamwindow > 0);
-    if(--conn->p_receive_streamwindow <= 0) { /* is it 0 after decrement? */
-      connection_stop_reading(conn);
-      log(LOG_DEBUG,"connection_package_raw_inbuf(): receive_streamwindow at AP reached 0.");
-      return 0; /* don't process the inbuf any more */
-    }
-    log(LOG_DEBUG,"connection_package_raw_inbuf(): receive_streamwindow at AP is %d",conn->p_receive_streamwindow);
+    assert(conn->cpath_layer->package_window > 0);
+    conn->cpath_layer->package_window--;
   }
+
+  if(circuit_consider_stop_edge_reading(circ,
+     conn->type == CONN_TYPE_EXIT ? EDGE_EXIT : EDGE_AP, conn->cpath_layer))
+    return 0;
+
+  assert(conn->package_window > 0);
+  if(--conn->package_window <= 0) { /* is it 0 after decrement? */
+    connection_stop_reading(conn);
+    log(LOG_DEBUG,"connection_package_raw_inbuf(): conn->package_window reached 0.");
+    return 0; /* don't process the inbuf any more */
+  }
+  log(LOG_DEBUG,"connection_package_raw_inbuf(): conn->package_window is %d",conn->package_window);
+
+
   /* handle more if there's more, or return 0 if there isn't */
   goto repeat_connection_package_raw_inbuf;
 }
@@ -760,32 +762,23 @@
   SET_CELL_STREAM_ID(cell, conn->stream_id);
   cell.length += RELAY_HEADER_SIZE;
 
-  if(edge_type == EDGE_EXIT) { /* we're at an exit */
-    if(conn->p_receive_streamwindow < STREAMWINDOW_START - STREAMWINDOW_INCREMENT) {
-      log(LOG_DEBUG,"connection_consider_sending_sendme(): Outbuf %d, Queueing stream sendme back.", conn->outbuf_flushlen);
-      conn->p_receive_streamwindow += STREAMWINDOW_INCREMENT;
-      cell.aci = circ->p_aci;
-      if(circuit_deliver_relay_cell_from_edge(&cell, circ, edge_type, NULL) < 0) {
-        log(LOG_DEBUG,"connection_consider_sending_sendme(): circuit_deliver_relay_cell_from_edge (backward) failed. Closing.");
-        circuit_close(circ);
-        return 0;
-      }
-    }
-  } else { /* we're at an AP */
-    assert(edge_type == EDGE_AP);
-    if(conn->n_receive_streamwindow < STREAMWINDOW_START-STREAMWINDOW_INCREMENT) {
-      log(LOG_DEBUG,"connection_consider_sending_sendme(): Outbuf %d, Queueing stream sendme forward.", conn->outbuf_flushlen);
-      conn->n_receive_streamwindow += STREAMWINDOW_INCREMENT;
-      cell.aci = circ->n_aci;
-      if(circuit_deliver_relay_cell_from_edge(&cell, circ, edge_type, conn->cpath_layer) < 0) {
-        log(LOG_DEBUG,"connection_consider_sending_sendme(): circuit_deliver_relay_cell_from_edge (forward) failed. Closing.");
-        circuit_close(circ);
-        return 0;
-      }
+  if(edge_type == EDGE_EXIT)
+    cell.aci = circ->p_aci;
+  else
+    cell.aci = circ->n_aci;
+
+  while(conn->deliver_window < STREAMWINDOW_START - STREAMWINDOW_INCREMENT) {
+    log(LOG_DEBUG,"connection_consider_sending_sendme(): Outbuf %d, Queueing stream sendme.", conn->outbuf_flushlen);
+    conn->deliver_window += STREAMWINDOW_INCREMENT;
+    if(circuit_deliver_relay_cell_from_edge(&cell, circ, edge_type, conn->cpath_layer) < 0) {
+      log(LOG_DEBUG,"connection_consider_sending_sendme(): circuit_deliver_relay_cell_from_edge failed. Closing.");
+      circuit_close(circ);
+      return 0;
     }
   }
+
   return 0;
-} 
+}
 
 int connection_finished_flushing(connection_t *conn) {
 

Index: connection_ap.c
===================================================================
RCS file: /home/or/cvsroot/src/or/connection_ap.c,v
retrieving revision 1.41
retrieving revision 1.42
diff -u -d -r1.41 -r1.42
--- connection_ap.c	2 May 2003 21:29:25 -0000	1.41
+++ connection_ap.c	20 May 2003 06:41:22 -0000	1.42
@@ -5,9 +5,10 @@
 #include "or.h"
 
 int ap_handshake_process_socks(connection_t *conn) {
-  char c;
   socks4_t socks4_info; 
   circuit_t *circ;
+  char tmpbuf[512];
+  int amt;
 
   assert(conn);
 
@@ -49,48 +50,44 @@
        socks4_info.destip[2] ||
        !socks4_info.destip[3]) { /* not 0.0.0.x */
       log(LOG_NOTICE,"ap_handshake_process_socks(): destip not in form 0.0.0.x.");
-      sprintf(conn->dest_tmp, "%d.%d.%d.%d", socks4_info.destip[0],
+      sprintf(tmpbuf, "%d.%d.%d.%d", socks4_info.destip[0],
         socks4_info.destip[1], socks4_info.destip[2], socks4_info.destip[3]);
-      conn->dest_addr = strdup(conn->dest_tmp);
+      conn->dest_addr = strdup(tmpbuf);
       log(LOG_DEBUG,"ap_handshake_process_socks(): Successfully read destip (%s)", conn->dest_addr);
     }
 
   }
 
   if(!conn->read_username) { /* the socks spec says we've got to read stuff until we get a null */
-    for(;;) {
-      if(!conn->inbuf_datalen)
-        return 0; /* maybe next time */
-      if(connection_fetch_from_buf((char *)&c,1,conn) < 0)
-        return -1;
-      if(!c) {
-        conn->read_username = 1;
-        log(LOG_DEBUG,"ap_handshake_process_socks(): Successfully read username.");
-        break;
-      }
+    amt = connection_find_on_inbuf("\0", 1, conn);
+    if(amt < 0) /* not there yet */
+      return 0;
+    if(amt > 500) {
+      log(LOG_NOTICE,"ap_handshake_process_socks(): username too long.");    
+      ap_handshake_socks_reply(conn, SOCKS4_REQUEST_REJECT);
+      return -1;
     }
+    if(connection_fetch_from_buf(tmpbuf,amt,conn) < 0)
+      return -1;
+    conn->read_username = 1;
+    log(LOG_DEBUG,"ap_handshake_process_socks(): Successfully read username.");
   }
 
   if(!conn->dest_addr) { /* no dest_addr found yet */
-
-    for(;;) {
-      if(!conn->inbuf_datalen)
-        return 0; /* maybe next time */
-      if(connection_fetch_from_buf((char *)&c,1,conn) < 0)
-        return -1;
-      conn->dest_tmp[conn->dest_tmplen++] = c;
-      if(conn->dest_tmplen > 500) {
-        log(LOG_NOTICE,"ap_handshake_process_socks(): dest_addr too long!");
-        ap_handshake_socks_reply(conn, SOCKS4_REQUEST_REJECT);
-        return -1;
-      }
-      if(!c) { /* we found the null; we're done */
-        conn->dest_addr = strdup(conn->dest_tmp);
-        log(LOG_NOTICE,"ap_handshake_process_socks(): successfully read dest addr '%s'",
-          conn->dest_addr);
-        break;
-      }
+    amt = connection_find_on_inbuf("\0", 1, conn);
+    if(amt < 0) /* not there yet */
+      return 0;
+    if(amt > 500) {
+      log(LOG_NOTICE,"ap_handshake_process_socks(): dest_addr too long.");    
+      ap_handshake_socks_reply(conn, SOCKS4_REQUEST_REJECT);
+      return -1;
     }
+    if(connection_fetch_from_buf(tmpbuf,amt,conn) < 0)
+      return -1;
+
+    conn->dest_addr = strdup(tmpbuf);
+    log(LOG_NOTICE,"ap_handshake_process_socks(): successfully read dest addr '%s'",
+      conn->dest_addr);
   }
 
   /* find the circuit that we should use, if there is one. */
@@ -143,8 +140,8 @@
     log(LOG_DEBUG,"ap_handshake_send_begin(): failed to deliver begin cell. Closing.");
     return -1;
   }
-  ap_conn->n_receive_streamwindow = STREAMWINDOW_START;
-  ap_conn->p_receive_streamwindow = STREAMWINDOW_START;
+  ap_conn->package_window = STREAMWINDOW_START;
+  ap_conn->deliver_window = STREAMWINDOW_START;
   ap_conn->state = AP_CONN_STATE_OPEN;
   log(LOG_INFO,"ap_handshake_send_begin(): Address/port sent, ap socket %d, n_aci %d",ap_conn->s,circ->n_aci);
   return 0;

Index: connection_edge.c
===================================================================
RCS file: /home/or/cvsroot/src/or/connection_edge.c,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -d -r1.8 -r1.9
--- connection_edge.c	5 May 2003 23:24:45 -0000	1.8
+++ connection_edge.c	20 May 2003 06:41:22 -0000	1.9
@@ -50,7 +50,7 @@
     case EXIT_CONN_STATE_OPEN:
       if(connection_package_raw_inbuf(conn) < 0)
         return -1;
-      circuit_consider_stop_edge_reading(circuit_get_by_conn(conn), EDGE_AP);
+      circuit_consider_stop_edge_reading(circuit_get_by_conn(conn), conn->type == CONN_TYPE_AP ? EDGE_AP : EDGE_EXIT, conn->cpath_layer);
       return 0;
     case EXIT_CONN_STATE_CONNECTING:
       log(LOG_DEBUG,"connection_edge_process_inbuf(): text from server while in 'connecting' state at exit. Leaving it on buffer.");
@@ -90,7 +90,8 @@
   return 0;
 }
 
-int connection_edge_process_relay_cell(cell_t *cell, circuit_t *circ, connection_t *conn, int edge_type) {
+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;
 
@@ -103,8 +104,6 @@
   num_seen++;
   log(LOG_DEBUG,"connection_edge_process_relay_cell(): Now seen %d relay cells here.", num_seen);
 
-  circuit_consider_sending_sendme(circ, edge_type);
-
   /* either conn is NULL, in which case we've got a control cell, or else
    * conn points to the recognized stream. */
 
@@ -130,13 +129,23 @@
       }
       return connection_exit_begin_conn(cell, circ);
     case RELAY_COMMAND_DATA:
+      if((edge_type == EDGE_AP && --layer_hint->deliver_window < 0) ||
+         (edge_type == EDGE_EXIT && --circ->deliver_window < 0)) {
+        log(LOG_DEBUG,"connection_edge_process_relay_cell(): circ deliver_window below 0. Killing.");
+        return -1; /* XXX kill the whole circ? */
+      }
+      log(LOG_DEBUG,"connection_edge_process_relay_cell(): circ deliver_window now %d.", edge_type == EDGE_AP ? layer_hint->deliver_window : circ->deliver_window);
+
+      if(circuit_consider_sending_sendme(circ, edge_type, layer_hint) < 0)
+        return -1;
+
       if(!conn) {
         log(LOG_DEBUG,"connection_edge_process_relay_cell(): relay cell dropped, unknown stream %d.",*(int*)conn->stream_id);
         return 0;
       }
-      if((edge_type == EDGE_AP && --conn->n_receive_streamwindow < 0) ||
-         (edge_type == EDGE_EXIT && --conn->p_receive_streamwindow < 0)) { /* is it below 0 after decrement? */
-        log(LOG_DEBUG,"connection_edge_process_relay_cell(): receive_streamwindow below 0. Killing.");
+
+      if(--conn->deliver_window < 0) { /* is it below 0 after decrement? */
+        log(LOG_DEBUG,"connection_edge_process_relay_cell(): conn deliver_window below 0. Killing.");
         return -1; /* somebody's breaking protocol. kill the whole circuit. */
       }
 
@@ -206,16 +215,23 @@
       break;
     case RELAY_COMMAND_SENDME:
       if(!conn) {
-        log(LOG_DEBUG,"connection_edge_process_relay_cell(): sendme cell dropped, unknown stream %d.",*(int*)conn->stream_id);
+        if(edge_type == EDGE_AP) {
+          assert(layer_hint);
+          layer_hint->package_window += CIRCWINDOW_INCREMENT;
+          log(LOG_DEBUG,"connection_edge_process_relay_cell(): 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(LOG_DEBUG,"connection_edge_process_relay_cell(): circ-level sendme at exit, packagewindow %d.", circ->package_window);
+          circuit_resume_edge_reading(circ, EDGE_EXIT, layer_hint);
+        }
         return 0;
       }
-      if(edge_type == EDGE_AP)
-        conn->p_receive_streamwindow += STREAMWINDOW_INCREMENT;
-      else
-        conn->n_receive_streamwindow += STREAMWINDOW_INCREMENT;
+      conn->package_window += STREAMWINDOW_INCREMENT;
       connection_start_reading(conn);
       connection_package_raw_inbuf(conn); /* handle whatever might still be on the inbuf */
-      circuit_consider_stop_edge_reading(circ, edge_type);
+      circuit_consider_stop_edge_reading(circ, edge_type, layer_hint);
       break;
     default:
       log(LOG_DEBUG,"connection_edge_process_relay_cell(): unknown relay command %d.",relay_command);

Index: connection_exit.c
===================================================================
RCS file: /home/or/cvsroot/src/or/connection_exit.c,v
retrieving revision 1.33
retrieving revision 1.34
diff -u -d -r1.33 -r1.34
--- connection_exit.c	2 May 2003 21:29:25 -0000	1.33
+++ connection_exit.c	20 May 2003 06:41:22 -0000	1.34
@@ -38,8 +38,8 @@
   n_conn->receiver_bucket = -1; /* edge connections don't do receiver buckets */
   n_conn->bandwidth = -1;
   n_conn->s = -1; /* not yet valid */
-  n_conn->n_receive_streamwindow = STREAMWINDOW_START;
-  n_conn->p_receive_streamwindow = STREAMWINDOW_START;
+  n_conn->package_window = STREAMWINDOW_START;
+  n_conn->deliver_window = STREAMWINDOW_START;
   if(connection_add(n_conn) < 0) { /* no space, forget it */
     log(LOG_DEBUG,"connection_exit_begin_conn(): connection_add failed. Dropping.");
     connection_free(n_conn);

Index: directory.c
===================================================================
RCS file: /home/or/cvsroot/src/or/directory.c,v
retrieving revision 1.14
retrieving revision 1.15
diff -u -d -r1.14 -r1.15
--- directory.c	9 May 2003 02:25:37 -0000	1.14
+++ directory.c	20 May 2003 06:41:22 -0000	1.15
@@ -224,7 +224,7 @@
     amt = connection_find_on_inbuf("\r\n\r\n", 4, conn);
     if(amt < 0) /* not there yet */
       return 0;
-    headers = malloc(amt+1);
+    headers = tor_malloc(amt+1);
     if(connection_fetch_from_buf(headers,amt,conn) < 0) {
       log(LOG_DEBUG,"directory_handle_reading(): fetch_from_buf failed (reading headers).");
       return -1;

Index: dns.c
===================================================================
RCS file: /home/or/cvsroot/src/or/dns.c,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -d -r1.9 -r1.10
--- dns.c	7 Apr 2003 02:12:02 -0000	1.9
+++ dns.c	20 May 2003 06:41:22 -0000	1.10
@@ -460,7 +460,7 @@
     switch(resolve->state) {
       case CACHE_STATE_PENDING:
         /* add us to the pending list */
-        pending_connection = malloc(sizeof(struct pending_connection_t));
+        pending_connection = tor_malloc(sizeof(struct pending_connection_t));
         pending_connection->conn = exitconn;
         pending_connection->next = resolve->pending_connections;
         resolve->pending_connections = pending_connection;
@@ -472,13 +472,13 @@
         return -1;
     }
   } else { /* need to add it */
-    resolve = malloc(sizeof(struct cached_resolve));
+    resolve = tor_malloc(sizeof(struct cached_resolve));
     memset(resolve, 0, sizeof(struct cached_resolve));
     resolve->state = CACHE_STATE_PENDING;
     strncpy(resolve->question, exitconn->address, MAX_ADDRESSLEN);
 
     /* add us to the pending list */
-    pending_connection = malloc(sizeof(struct pending_connection_t));
+    pending_connection = tor_malloc(sizeof(struct pending_connection_t));
     pending_connection->conn = exitconn;
     pending_connection->next = resolve->pending_connections;
     resolve->pending_connections = pending_connection;

Index: main.c
===================================================================
RCS file: /home/or/cvsroot/src/or/main.c,v
retrieving revision 1.64
retrieving revision 1.65
diff -u -d -r1.64 -r1.65
--- main.c	9 May 2003 02:25:37 -0000	1.64
+++ main.c	20 May 2003 06:41:22 -0000	1.65
@@ -652,11 +652,7 @@
   routerinfo_t *router;
   int i, n = 0;
 
-  routers = (routerinfo_t**) malloc(sizeof(routerinfo_t*) * (nfds+1));
-  if (!routers) {
-    log(LOG_ERR, "build_directory(): couldn't allocate space for routerinfo");
-    return -1;
-  }
+  routers = (routerinfo_t **)tor_malloc(sizeof(routerinfo_t*) * (nfds+1));
   if (my_routerinfo) {
     log(LOG_INFO, "build_directory(): adding self (%s:%d)", 
         my_routerinfo->address, my_routerinfo->or_port);

Index: onion.c
===================================================================
RCS file: /home/or/cvsroot/src/or/onion.c,v
retrieving revision 1.47
retrieving revision 1.48
diff -u -d -r1.47 -r1.48
--- onion.c	7 May 2003 22:40:03 -0000	1.47
+++ onion.c	20 May 2003 06:41:22 -0000	1.48
@@ -30,7 +30,7 @@
 int onion_pending_add(circuit_t *circ) {
   struct onion_queue_t *tmp;
 
-  tmp = malloc(sizeof(struct onion_queue_t));
+  tmp = tor_malloc(sizeof(struct onion_queue_t));
   memset(tmp, 0, sizeof(struct onion_queue_t));
   tmp->circ = circ;
 
@@ -74,6 +74,12 @@
     return; /* no onions pending, we're done */
 
   assert(ol_list->circ);
+  if(!ol_list->circ->p_conn) {
+    log(LOG_INFO,"onion_pending_process_one(): ol_list->circ->p_conn null, must have died?");
+    onion_pending_remove(ol_list->circ);
+    return; /* it died on us */
+  }
+
   assert(ol_list->circ->p_conn);
   assert(ol_length > 0);
   circ = ol_list->circ;
@@ -143,9 +149,9 @@
 struct relay_queue_t *relay_queue_add(struct relay_queue_t *list, cell_t *cell, crypt_path_t *layer_hint) {
   struct relay_queue_t *tmpd, *newd;
 
-  newd = malloc(sizeof(struct relay_queue_t));
+  newd = tor_malloc(sizeof(struct relay_queue_t));
   memset(newd, 0, sizeof(struct relay_queue_t));
-  newd->cell = malloc(sizeof(cell_t));
+  newd->cell = tor_malloc(sizeof(cell_t));
   memcpy(newd->cell, cell, sizeof(cell_t));
   newd->layer_hint = layer_hint;
 
@@ -279,11 +285,7 @@
   }
 
   /* allocate memory for the new route */
-  route = (unsigned int *)malloc(*routelen * sizeof(unsigned int));
-  if (!route) {
-    log(LOG_ERR,"Memory allocation failed.");
-    return NULL;
-  }
+  route = (unsigned int *)tor_malloc(*routelen * sizeof(unsigned int));
  
   oldchoice = rarray_len;
   for(i=0;i<*routelen;i++) {
@@ -385,13 +387,7 @@
     router = rarray[route[i]];
 
     /* build up the crypt_path */
-    hop = (crypt_path_t *)malloc(sizeof(crypt_path_t));
-    if(!hop) {
-      log(LOG_ERR,"Error allocating crypt path hop memory.");
-      circuit_free_cpath(cpath);
-      free(route);
-      return NULL;
-    }
+    hop = (crypt_path_t *)tor_malloc(sizeof(crypt_path_t));
     memset(hop, 0, sizeof(crypt_path_t));
 
     /* link hop into the cpath, at the front */
@@ -412,6 +408,9 @@
     hop->port = rarray[route[i]]->or_port;
     hop->addr = rarray[route[i]]->addr;
 
+    hop->package_window = CIRCWINDOW_START;
+    hop->deliver_window = CIRCWINDOW_START;
+
     log(LOG_DEBUG,"onion_generate_cpath() : Building hop %u of crypt path.",i+1);
   }
 
@@ -457,8 +456,7 @@
   dhbytes = crypto_dh_get_bytes(dh);
   pkbytes = crypto_pk_keysize(dest_router_key);
   assert(dhbytes+16 == DH_ONIONSKIN_LEN);
-  if (!(pubkey = malloc(dhbytes+16)))
-    goto err;
+  pubkey = (char *)tor_malloc(dhbytes+16);
 
   if (crypto_rand(16, pubkey))
     goto err;

Index: or.h
===================================================================
RCS file: /home/or/cvsroot/src/or/or.h,v
retrieving revision 1.84
retrieving revision 1.85
diff -u -d -r1.84 -r1.85
--- or.h	9 May 2003 02:25:37 -0000	1.84
+++ or.h	20 May 2003 06:41:23 -0000	1.85
@@ -153,7 +153,6 @@
 #define CELL_CREATED 2
 #define CELL_RELAY 3
 #define CELL_DESTROY 4
-#define CELL_SENDME 5
 
 #define CELL_PAYLOAD_SIZE 248
 #define CELL_NETWORK_SIZE 256
@@ -259,8 +258,12 @@
   char stream_id[STREAM_ID_SIZE];
   struct connection_t *next_stream;
   struct crypt_path_t *cpath_layer; /* a pointer to which node in the circ this conn exits at */
+  int package_window;
+  int deliver_window;
+#if 0
   int n_receive_streamwindow;
   int p_receive_streamwindow;
+#endif
   int done_sending;
   int done_receiving;
 #ifdef USE_ZLIB
@@ -280,10 +283,6 @@
   char *dest_addr;
   uint16_t dest_port; /* host order */
 
-/* Used by ap: */
-  char dest_tmp[512];
-  int dest_tmplen;
-  
 /* Used by everyone */
   char *address; /* strdup into this, because free_connection frees it */
 /* Used for cell connections */
@@ -351,6 +350,8 @@
   struct crypt_path_t *next;
   struct crypt_path_t *prev; /* doubly linked list */
 
+  int package_window;
+  int deliver_window;
 };
 
 #define DH_KEY_LEN CRYPTO_DH_SIZE
@@ -370,8 +371,8 @@
   uint16_t n_port;
   connection_t *p_conn;
   connection_t *n_conn; /* convention: first conn is the OR conn, if there is one */
-  int n_receive_circwindow;
-  int p_receive_circwindow;
+  int package_window;
+  int deliver_window;
 
   aci_t p_aci; /* connection identifiers */
   aci_t n_aci;
@@ -504,12 +505,12 @@
 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);
+                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);
-int circuit_consider_stop_edge_reading(circuit_t *circ, int edge_type);
-int circuit_consider_sending_sendme(circuit_t *circ, int edge_type);
+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);
+int circuit_consider_sending_sendme(circuit_t *circ, int edge_type, crypt_path_t *layer_hint);
 
 void circuit_free(circuit_t *circ);
 void circuit_free_cpath(crypt_path_t *cpath);
@@ -642,7 +643,7 @@
 
 int connection_edge_process_inbuf(connection_t *conn);
 int connection_edge_send_command(connection_t *conn, circuit_t *circ, int relay_command);
-int connection_edge_process_relay_cell(cell_t *cell, circuit_t *circ, connection_t *conn, int edge_type);
+int connection_edge_process_relay_cell(cell_t *cell, circuit_t *circ, connection_t *conn, int edge_type, crypt_path_t *layer_hint);
 int connection_edge_finished_flushing(connection_t *conn);
 
 /********************************* connection_exit.c ***************************/

Index: routers.c
===================================================================
RCS file: /home/or/cvsroot/src/or/routers.c,v
retrieving revision 1.32
retrieving revision 1.33
diff -u -d -r1.32 -r1.33
--- routers.c	9 May 2003 02:25:37 -0000	1.32
+++ routers.c	20 May 2003 06:41:23 -0000	1.33
@@ -215,11 +215,7 @@
     return -1;
   }
 
-  string = malloc(statbuf.st_size+1);
-  if(!string) {
-    log(LOG_ERR,"router_get_list_from_file(): Out of memory.");
-    return -1;
-  }
+  string = tor_malloc(statbuf.st_size+1);
 
   if(read(fd,string,statbuf.st_size) != statbuf.st_size) {
     log(LOG_ERR,"router_get_list_from_file(): Couldn't read all %d bytes of file '%s'.",statbuf.st_size,routerfile);
@@ -325,7 +321,7 @@
       next = strstr(*s, OR_SIGNATURE_END_TAG);
       if (!next) { tok->val.error = "No signature end tag found"; return -1; }
       
-      signature = malloc(256);
+      signature = tor_malloc(256);
       i = base64_decode(signature, 256, *s, next-*s);
       if (i<0) {
         free(signature);
@@ -604,10 +600,7 @@
 
   assert(s);
 
-  if (!(rarray = malloc((sizeof(routerinfo_t *))*MAX_ROUTERS_IN_DIR))) {
-    log(LOG_ERR, "router_get_list_from_string_tok(): malloc failed");
-    return -1;
-  }
+  rarray = (routerinfo_t **)tor_malloc((sizeof(routerinfo_t *))*MAX_ROUTERS_IN_DIR);
 
   while (tok->tp == K_ROUTER) {
     router = router_get_entry_from_string_tok(s, tok);
@@ -625,10 +618,7 @@
  
   if (*dest) 
     directory_free(*dest);
-  if (!(*dest = (directory_t*) malloc(sizeof(directory_t)))) {
-    log(LOG_ERR, "router_get_list_from_string_tok(): malloc failed");
-    return -1;
-  }
+  *dest = (directory_t *)tor_malloc(sizeof(directory_t));
   (*dest)->routers = rarray;
   (*dest)->n_routers = rarray_len;
   return 0;
@@ -710,10 +700,8 @@
     log(LOG_ERR,"router_get_entry_from_string(): Entry does not start with \"router\"");
     return NULL;
   }
-  if (!(router = malloc(sizeof(routerinfo_t)))) {
-    log(LOG_ERR,"router_get_entry_from_string(): Could not allocate memory.");
-    return NULL;
-  }
+
+  router = tor_malloc(sizeof(routerinfo_t));
   memset(router,0,sizeof(routerinfo_t)); /* zero it out first */
   /* C doesn't guarantee that NULL is represented by 0 bytes.  You'll
      thank me for this someday. */
@@ -828,10 +816,10 @@
     return -1;
   arg = tok->val.cmd.args[0];
 
-  newe = malloc(sizeof(struct exit_policy_t));
+  newe = tor_malloc(sizeof(struct exit_policy_t));
   memset(newe,0,sizeof(struct exit_policy_t));
   
-  newe->string = malloc(8+strlen(arg));
+  newe->string = tor_malloc(8+strlen(arg));
   if (tok->tp == K_REJECT) {
     strcpy(newe->string, "reject ");
     newe->policy_type = EXIT_POLICY_REJECT;

Index: test.c
===================================================================
RCS file: /home/or/cvsroot/src/or/test.c,v
retrieving revision 1.18
retrieving revision 1.19
diff -u -d -r1.18 -r1.19
--- test.c	9 May 2003 02:00:33 -0000	1.18
+++ test.c	20 May 2003 06:41:23 -0000	1.19
@@ -275,9 +275,9 @@
                         CRYPTO_CIPHER_3DES,
                         -1 };
 
-  data1 = malloc(1024);
-  data2 = malloc(1024);
-  data3 = malloc(1024);
+  data1 = tor_malloc(1024);
+  data2 = tor_malloc(1024);
+  data3 = tor_malloc(1024);
   test_assert(data1 && data2 && data3);
 
   /* Try out identity ciphers. */
@@ -623,9 +623,9 @@
   test_assert(rp2->exit_policy->next->next == NULL);
 
   /* Okay, now for the directories. */
-  dir1 = (directory_t*) malloc(sizeof(directory_t));
+  dir1 = (directory_t*) tor_malloc(sizeof(directory_t));
   dir1->n_routers = 2;
-  dir1->routers = (routerinfo_t**) malloc(sizeof(routerinfo_t*)*2);
+  dir1->routers = (routerinfo_t**) tor_malloc(sizeof(routerinfo_t*)*2);
   dir1->routers[0] = &r1;
   dir1->routers[1] = &r2;
   test_assert(! dump_signed_directory_to_string_impl(buf, 2048, dir1, pk1));