[or-cvs] deal with hardware word alignment

Roger Dingledine arma at seul.org
Sat Mar 20 09:30:33 UTC 2004


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_edge.c cpuworker.c dns.c 
Log Message:
deal with hardware word alignment
this was causing the seg faults on sparc processors

i wonder if i got them all.


Index: buffers.c
===================================================================
RCS file: /home/or/cvsroot/src/or/buffers.c,v
retrieving revision 1.72
retrieving revision 1.73
diff -u -d -r1.72 -r1.73
--- buffers.c	11 Mar 2004 20:15:53 -0000	1.72
+++ buffers.c	20 Mar 2004 09:30:30 -0000	1.73
@@ -483,7 +483,8 @@
           }
           memcpy(req->address,buf->mem+5,len);
           req->address[len] = 0;
-          req->port = ntohs(*(uint16_t*)(buf->mem+5+len));
+          memcpy(&req->port, buf->mem+5+len, 2);
+          req->port = ntohs(req->port);
           buf_remove_from_front(buf, 5+len+2);
           return 1;
         default: /* unsupported */

Index: circuit.c
===================================================================
RCS file: /home/or/cvsroot/src/or/circuit.c,v
retrieving revision 1.153
retrieving revision 1.154
diff -u -d -r1.153 -r1.154
--- circuit.c	20 Mar 2004 04:59:29 -0000	1.153
+++ circuit.c	20 Mar 2004 09:30:30 -0000	1.154
@@ -1116,8 +1116,13 @@
     return -1;
   }
 
-  circ->n_addr = ntohl(*(uint32_t*)(cell->payload+RELAY_HEADER_SIZE));
-  circ->n_port = ntohs(*(uint16_t*)(cell->payload+RELAY_HEADER_SIZE+4));
+  memcpy(&circ->n_addr, cell->payload+RELAY_HEADER_SIZE, 4);
+  circ->n_addr = ntohl(circ->n_addr);
+  memcpy(&circ->n_port, cell->payload+RELAY_HEADER_SIZE+4, 2);
+  circ->n_port = ntohs(circ->n_port);
+
+//  circ->n_addr = ntohl(*(uint32_t*)(cell->payload+RELAY_HEADER_SIZE));
+//  circ->n_port = ntohs(*(uint16_t*)(cell->payload+RELAY_HEADER_SIZE+4));
 
   n_conn = connection_twin_get_by_addr_port(circ->n_addr,circ->n_port);
   if(!n_conn || n_conn->type != CONN_TYPE_OR) {

Index: connection_edge.c
===================================================================
RCS file: /home/or/cvsroot/src/or/connection_edge.c,v
retrieving revision 1.117
retrieving revision 1.118
diff -u -d -r1.117 -r1.118
--- connection_edge.c	20 Mar 2004 04:59:29 -0000	1.117
+++ connection_edge.c	20 Mar 2004 09:30:30 -0000	1.118
@@ -22,19 +22,56 @@
 static void client_dns_set_entry(const char *address, uint32_t val);
 
 void relay_header_pack(char *dest, const relay_header_t *src) {
+  uint16_t tmp;
+
+  /* we have to do slow memcpy's here, because we screwed up
+   * and made our cell payload not word-aligned. we should fix
+   * this someday.
+   */
+
+  *(uint8_t*)(dest) = src->command;
+
+  tmp = htons(src->recognized);
+  memcpy(dest+1, &tmp, 2);
+
+  tmp = htons(src->stream_id);
+  memcpy(dest+3, &tmp, 2);
+
+  memcpy(dest+5, src->integrity, 4);
+
+  tmp = htons(src->length);
+  memcpy(dest+9, &tmp, 2);
+
+#if 0
   *(uint8_t*)(dest)    = src->command;
   *(uint16_t*)(dest+1) = htons(src->recognized);
   *(uint16_t*)(dest+3) = htons(src->stream_id);
   memcpy(dest+5, src->integrity, 4);
   *(uint16_t*)(dest+9) = htons(src->length);
+#endif
 }
 
 void relay_header_unpack(relay_header_t *dest, const char *src) {
+  dest->command = *(uint8_t*)(src);
+
+  memcpy(&dest->recognized, src+1, 2);
+  dest->recognized = ntohs(dest->recognized);
+
+  memcpy(&dest->stream_id, src+3, 2);
+  dest->stream_id = ntohs(dest->stream_id);
+
+  memcpy(dest->integrity, src+5, 4);
+
+  memcpy(&dest->length, src+9, 2);
+  dest->length = ntohs(dest->length);
+
+#if 0
   dest->command    = *(uint8_t*)(src);
   dest->recognized = ntohs(*(uint16_t*)(src+1));
   dest->stream_id  = ntohs(*(uint16_t*)(src+3));
   memcpy(dest->integrity, src+5, 4);
   dest->length     = ntohs(*(uint16_t*)(src+9));
+#endif
 }
 
 int connection_edge_process_inbuf(connection_t *conn) {
@@ -138,7 +175,9 @@
 
   payload[0] = reason;
   if(reason == END_STREAM_REASON_EXITPOLICY) {
-    *(uint32_t *)(payload+1) = htonl(conn->addr);
+    uint32_t tmp = htonl(conn->addr);
+    memcpy(payload+1, &tmp, 4);
+//    *(uint32_t *)(payload+1) = htonl(conn->addr);
     payload_len += 4;
   }
 
@@ -236,7 +275,9 @@
 //      log_fn(LOG_INFO,"Connected! Notifying application.");
       conn->state = AP_CONN_STATE_OPEN;
       if (rh.length >= 4) {
-        addr = ntohl(*(uint32_t*)(cell->payload + RELAY_HEADER_SIZE));
+        memcpy(&addr, cell->payload + RELAY_HEADER_SIZE, 4);
+        addr = ntohl(addr);
+//        addr = ntohl(*(uint32_t*)(cell->payload + RELAY_HEADER_SIZE));
         client_dns_set_entry(conn->socks_request->address, addr);
       }
       log_fn(LOG_INFO,"'connected' received after %d seconds.",
@@ -311,7 +352,9 @@
          * we try a new exit node.
          * cell->payload+RELAY_HEADER_SIZE+1 holds the destination addr.
          */
-        addr = ntohl(*(uint32_t*)(cell->payload+RELAY_HEADER_SIZE+1));
+        memcpy(&addr, cell->payload+RELAY_HEADER_SIZE+1, 4);
+        addr = ntohl(addr);
+//        addr = ntohl(*(uint32_t*)(cell->payload+RELAY_HEADER_SIZE+1));
         client_dns_set_entry(conn->socks_request->address, addr);
         conn->state = AP_CONN_STATE_CIRCUIT_WAIT;
         if(connection_ap_handshake_attach_circuit(conn) >= 0)
@@ -936,7 +979,7 @@
   connection_watch_events(conn, POLLIN);
 
   /* also, deliver a 'connected' cell back through the circuit. */
-  *((uint32_t*) connected_payload) = htonl(conn->addr);
+  *(uint32_t*)connected_payload = htonl(conn->addr);
   connection_edge_send_command(conn, circuit_get_by_conn(conn), RELAY_COMMAND_CONNECTED,
                                connected_payload, 4, NULL);
 }

Index: cpuworker.c
===================================================================
RCS file: /home/or/cvsroot/src/or/cpuworker.c,v
retrieving revision 1.27
retrieving revision 1.28
diff -u -d -r1.27 -r1.28
--- cpuworker.c	12 Mar 2004 21:52:15 -0000	1.27
+++ cpuworker.c	20 Mar 2004 09:30:30 -0000	1.28
@@ -48,6 +48,7 @@
 }
 
 int connection_cpu_process_inbuf(connection_t *conn) {
+  char success;
   unsigned char buf[LEN_ONION_RESPONSE];
   uint32_t addr;
   uint16_t port;
@@ -77,10 +78,11 @@
       return 0; /* not yet */
     assert(buf_datalen(conn->inbuf) == LEN_ONION_RESPONSE);
 
-    connection_fetch_from_buf(buf,LEN_ONION_RESPONSE,conn);
+    connection_fetch_from_buf(&success,1,conn);
+    connection_fetch_from_buf(buf,LEN_ONION_RESPONSE-1,conn);
 
     /* parse out the circ it was talking about */
-    tag_unpack(buf+1, &addr, &port, &circ_id);
+    tag_unpack(buf, &addr, &port, &circ_id);
     circ = NULL;
     p_conn = connection_exact_get_by_addr_port(addr,port);
     if(p_conn)
@@ -91,12 +93,12 @@
       goto done_processing;
     }
     assert(circ->p_conn);
-    if(*buf == 0) {
+    if(success == 0) {
       log_fn(LOG_WARN,"decoding onionskin failed. Closing.");
       circuit_mark_for_close(circ);
       goto done_processing;
     }
-    if(onionskin_answer(circ, buf+1+TAG_LEN, buf+1+TAG_LEN+ONIONSKIN_REPLY_LEN) < 0) {
+    if(onionskin_answer(circ, buf+TAG_LEN, buf+TAG_LEN+ONIONSKIN_REPLY_LEN) < 0) {
       log_fn(LOG_WARN,"onionskin_answer failed. Closing.");
       circuit_mark_for_close(circ);
       goto done_processing;

Index: dns.c
===================================================================
RCS file: /home/or/cvsroot/src/or/dns.c,v
retrieving revision 1.67
retrieving revision 1.68
diff -u -d -r1.67 -r1.68
--- dns.c	12 Mar 2004 21:52:15 -0000	1.67
+++ dns.c	20 Mar 2004 09:30:30 -0000	1.68
@@ -363,7 +363,7 @@
 }
 
 int connection_dns_process_inbuf(connection_t *conn) {
-  char answer[5];
+  char success;
   uint32_t addr;
 
   assert(conn && conn->type == CONN_TYPE_DNSWORKER);
@@ -384,15 +384,15 @@
     return 0; /* not yet */
   assert(buf_datalen(conn->inbuf) == 5);
 
-  connection_fetch_from_buf(answer,sizeof(answer),conn);
-  addr = *(uint32_t*)(answer+1);
+  connection_fetch_from_buf(&success,1,conn);
+  connection_fetch_from_buf((char *)&addr,sizeof(uint32_t),conn);
 
   log_fn(LOG_DEBUG, "DNSWorker (fd %d) returned answer for '%s'",
          conn->s, conn->address);
 
-  assert(answer[0] >= DNS_RESOLVE_FAILED_TRANSIENT);
-  assert(answer[0] <= DNS_RESOLVE_SUCCEEDED);
-  dns_found_answer(conn->address, addr, answer[0]);
+  assert(success >= DNS_RESOLVE_FAILED_TRANSIENT);
+  assert(success <= DNS_RESOLVE_SUCCEEDED);
+  dns_found_answer(conn->address, addr, success);
 
   tor_free(conn->address);
   conn->address = tor_strdup("<idle>");



More information about the tor-commits mailing list