[or-cvs] Factor out cell packing and unpacking

Nick Mathewson nickm at seul.org
Wed Apr 16 17:44:35 UTC 2003


Update of /home/or/cvsroot/src/or
In directory moria.mit.edu:/tmp/cvs-serv5455/src/or

Modified Files:
	connection.c connection_edge.c or.h 
Log Message:
Factor out cell packing and unpacking

Index: connection.c
===================================================================
RCS file: /home/or/cvsroot/src/or/connection.c,v
retrieving revision 1.54
retrieving revision 1.55
diff -u -d -r1.54 -r1.55
--- connection.c	16 Apr 2003 17:04:57 -0000	1.54
+++ connection.c	16 Apr 2003 17:44:33 -0000	1.55
@@ -543,7 +543,6 @@
    */
   conn->outbuf_flushlen += sizeof(cell_t); /* instruct it to send a cell */
   connection_start_writing(conn);
-
 }
 
 void connection_increment_send_timeval(connection_t *conn) {
@@ -584,12 +583,7 @@
   char networkcell[CELL_NETWORK_SIZE];
   char *n = networkcell;
  
-  memset(n,0,CELL_NETWORK_SIZE); /* zero it out to start */
-  *(aci_t *)n = htons(cellp->aci);
-  *(n+2) = cellp->command;
-  *(n+3) = cellp->length;
-  /* seq is reserved, leave zero */
-  memcpy(n+8,cellp->payload,CELL_PAYLOAD_SIZE);
+  cell_pack(n, cellp);
 
   if(connection_encrypt_cell(n,conn)<0) {
     return -1;
@@ -676,7 +670,7 @@
    *       compressing.
    *    2) 
    */
-  len = connection_compress_from_buf(cell.payload + TOPIC_HEADER_SIZE,
+  len = connection_compress_from_buf(cell.payload,
                                      CELL_PAYLOAD_SIZE - TOPIC_HEADER_SIZE,
                                      conn, Z_SYNC_FLUSH);
   if (len < 0)
@@ -690,7 +684,7 @@
     cell.length = amount_to_process;
   }
 
-  if(connection_fetch_from_buf(cell.payload+TOPIC_HEADER_SIZE, cell.length, conn) < 0)
+  if(connection_fetch_from_buf(cell.payload, cell.length, conn) < 0)
     return -1;
 #endif
 
@@ -702,10 +696,11 @@
 
   log(LOG_DEBUG,"connection_package_raw_inbuf(): (%d) Packaging %d bytes (%d waiting).",conn->s,cell.length, conn->inbuf_datalen);
 
-  *(uint16_t *)(cell.payload+2) = htons(conn->topic_id);
-  *cell.payload = TOPIC_COMMAND_DATA;
-  cell.length += TOPIC_HEADER_SIZE;
+
   cell.command = CELL_DATA;
+  cell.topic_command = TOPIC_COMMAND_DATA;
+  cell.topic_id = conn->topic_id;
+  cell.length += TOPIC_HEADER_SIZE;
 
   if(conn->type == CONN_TYPE_EXIT) {
     cell.aci = circ->p_aci;
@@ -756,10 +751,10 @@
   }
 
   memset(&cell, 0, sizeof(cell_t));
-  *(uint16_t *)(cell.payload+2) = htons(conn->topic_id);
-  *cell.payload = TOPIC_COMMAND_SENDME;
-  cell.length += TOPIC_HEADER_SIZE;
   cell.command = CELL_DATA;
+  cell.topic_command = TOPIC_COMMAND_SENDME;
+  cell.topic_id = conn->topic_id;
+  cell.length += TOPIC_HEADER_SIZE;
 
   if(edge_type == EDGE_EXIT) { /* we're at an exit */
     if(conn->p_receive_topicwindow < TOPICWINDOW_START - TOPICWINDOW_INCREMENT) {
@@ -850,16 +845,46 @@
 #endif
 
   /* retrieve cell info from outbuf (create the host-order struct from the network-order string) */
-  memset(&cell,0,sizeof(cell_t)); /* zero it out to start */
-  cell.aci = ntohs(*(aci_t *)outbuf);
-  cell.command = *(outbuf+2);
-  cell.length = *(outbuf+3);
-  memcpy(cell.payload, outbuf+8, CELL_PAYLOAD_SIZE);
+  cell_unpack(&cell, outbuf);
 
 //  log(LOG_DEBUG,"connection_process_cell_from_inbuf(): Decrypted cell is of type %u (ACI %u).",cellp->command,cellp->aci);
   command_process_cell(&cell, conn);
 
   return connection_process_inbuf(conn); /* process the remainder of the buffer */
+}
+
+void
+cell_pack(char *dest, const cell_t *src)
+{
+  *(uint16_t*)dest     = htons(src->aci);
+  *(uint8_t*)(dest+2)  = src->command;
+  *(uint8_t*)(dest+3)  = src->length;
+  *(uint32_t*)(dest+4) = 0; /* Reserved */
+  if (src->command != CELL_DATA) {
+    memcpy(dest+8, src->payload, CELL_PAYLOAD_SIZE);
+  } else {
+    *(uint8_t*)(dest+8)  = src->topic_command;
+    *(uint8_t*)(dest+9)  = 0;
+    *(uint16_t*)(dest+10) = htons(src->topic_id);
+    memcpy(dest+12, src->payload, CELL_PAYLOAD_SIZE - TOPIC_HEADER_SIZE);
+  }
+}
+
+void
+cell_unpack(cell_t *dest, const char *src)
+{
+  dest->aci     = ntohs(*(uint16_t*)(src));
+  dest->command = *(uint8_t*)(src+2);
+  dest->length  = *(uint8_t*)(src+3);
+  dest->seq     = ntohl(*(uint32_t*)(src+4));
+  if (dest->command != CELL_DATA) {
+    memcpy(dest->payload, src+8, CELL_PAYLOAD_SIZE);
+  } else {
+    dest->topic_command = *(uint8_t*)(src+8);
+    /* zero  = *(uint8_t*)(src+9); */
+    dest->topic_id = ntohs(*(uint16_t*)(src+10));
+    memcpy(dest->payload, src+12, CELL_PAYLOAD_SIZE - TOPIC_HEADER_SIZE);
+  }
 }
 
 /*

Index: connection_edge.c
===================================================================
RCS file: /home/or/cvsroot/src/or/connection_edge.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- connection_edge.c	11 Apr 2003 22:28:51 -0000	1.2
+++ connection_edge.c	16 Apr 2003 17:44:33 -0000	1.3
@@ -27,9 +27,10 @@
     memset(&cell, 0, sizeof(cell_t));
     cell.command = CELL_DATA;
     cell.length = TOPIC_HEADER_SIZE;
-    *(uint16_t *)(cell.payload+2) = htons(conn->topic_id);
-    *cell.payload = TOPIC_COMMAND_END;
+    cell.topic_command = TOPIC_COMMAND_END;
+    cell.topic_id = conn->topic_id;
     cell.aci = circ->n_aci;
+
     if (circuit_deliver_data_cell_from_edge(&cell, circ, conn->type) < 0) {
       log(LOG_DEBUG,"connection_edge_process_inbuf: circuit_deliver_data_cell_from_edge failed.  Closing");
       circuit_close(circ);
@@ -75,8 +76,9 @@
   else
     cell.aci = circ->p_aci;
   cell.command = CELL_DATA;
-  *(uint16_t *)(cell.payload+2) = htons(conn->topic_id);
-  *cell.payload = topic_command;
+  cell.topic_command = topic_command;
+  cell.topic_id = conn->topic_id;
+
   cell.length = TOPIC_HEADER_SIZE;
   log(LOG_INFO,"connection_edge_send_command(): delivering %d cell %s.", topic_command, conn->type == CONN_TYPE_AP ? "forward" : "backward");
 
@@ -98,8 +100,8 @@
 
   assert(cell && circ);
 
-  topic_command = *cell->payload;
-  topic_id = ntohs(*(uint16_t *)(cell->payload+2));
+  topic_command = cell->topic_command;
+  topic_id = cell->topic_id;
   log(LOG_DEBUG,"connection_edge_process_data_cell(): command %d topic %d", topic_command, topic_id);
   num_seen++;
   log(LOG_DEBUG,"connection_edge_process_data_cell(): Now seen %d data cells here.", num_seen);
@@ -151,7 +153,7 @@
       }
 
 #ifdef USE_ZLIB
-      if(connection_decompress_to_buf(cell->payload + TOPIC_HEADER_SIZE,
+      if(connection_decompress_to_buf(cell->payload,
                                       cell->length - TOPIC_HEADER_SIZE, 
                                       conn, Z_SYNC_FLUSH) < 0) {
         log(LOG_INFO,"connection_edge_process_data_cell(): write to buf failed. Marking for close.");
@@ -159,7 +161,7 @@
         return 0;
       }
 #else
-      if(connection_write_to_buf(cell->payload + TOPIC_HEADER_SIZE,
+      if(connection_write_to_buf(cell->payload,
                                  cell->length - TOPIC_HEADER_SIZE, conn) < 0) {
         conn->marked_for_close = 1;
         return 0;

Index: or.h
===================================================================
RCS file: /home/or/cvsroot/src/or/or.h,v
retrieving revision 1.66
retrieving revision 1.67
diff -u -d -r1.66 -r1.67
--- or.h	16 Apr 2003 17:04:58 -0000	1.66
+++ or.h	16 Apr 2003 17:44:33 -0000	1.67
@@ -197,6 +197,11 @@
   unsigned char command;
   unsigned char length; /* of payload if data cell, else value of sendme */
   uint32_t seq; /* sequence number */
+
+  /* The following 2 fields are only set when command is CELL_DATA */
+  unsigned char topic_command;
+  uint16_t topic_id;
+
   unsigned char payload[CELL_PAYLOAD_SIZE];
 } cell_t;
 
@@ -613,6 +618,9 @@
 
 int connection_consider_sending_sendme(connection_t *conn, int edge_type);
 int connection_finished_flushing(connection_t *conn);
+
+void cell_pack(char *dest, const cell_t *src);
+void cell_unpack(cell_t *dest, const char *src);
 
 /********************************* connection_ap.c ****************************/
 



More information about the tor-commits mailing list