diff options
author | Roger Dingledine <arma@torproject.org> | 2004-03-20 09:30:30 +0000 |
---|---|---|
committer | Roger Dingledine <arma@torproject.org> | 2004-03-20 09:30:30 +0000 |
commit | 66f878513f1aa62c14984eddad32c6a3c7b26025 (patch) | |
tree | eddaf299cda394bea7b5ffb23c9e9b0732ea8941 | |
parent | 2ba2f0218130731e46fed9cc565d0b802d4f4a31 (diff) | |
download | tor-66f878513f1aa62c14984eddad32c6a3c7b26025.tar tor-66f878513f1aa62c14984eddad32c6a3c7b26025.tar.gz |
deal with hardware word alignment
this was causing the seg faults on sparc processors
i wonder if i got them all.
svn:r1314
-rw-r--r-- | src/or/buffers.c | 3 | ||||
-rw-r--r-- | src/or/circuit.c | 9 | ||||
-rw-r--r-- | src/or/connection_edge.c | 51 | ||||
-rw-r--r-- | src/or/cpuworker.c | 10 | ||||
-rw-r--r-- | src/or/dns.c | 12 |
5 files changed, 68 insertions, 17 deletions
diff --git a/src/or/buffers.c b/src/or/buffers.c index 65b77e06e..8dc8df1f6 100644 --- a/src/or/buffers.c +++ b/src/or/buffers.c @@ -483,7 +483,8 @@ int fetch_from_buf_socks(buf_t *buf, socks_request_t *req) { } 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 */ diff --git a/src/or/circuit.c b/src/or/circuit.c index 2cadd6d7d..9c07532ff 100644 --- a/src/or/circuit.c +++ b/src/or/circuit.c @@ -1116,8 +1116,13 @@ int circuit_extend(cell_t *cell, circuit_t *circ) { 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) { diff --git a/src/or/connection_edge.c b/src/or/connection_edge.c index 4d2ce00cc..867fe78c9 100644 --- a/src/or/connection_edge.c +++ b/src/or/connection_edge.c @@ -22,19 +22,56 @@ 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) { + 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 @@ int connection_edge_end(connection_t *conn, char reason, crypt_path_t *cpath_lay 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 @@ int connection_edge_process_relay_cell(cell_t *cell, circuit_t *circ, connection // 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 @@ int connection_edge_process_relay_cell(cell_t *cell, circuit_t *circ, connection * 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 @@ void connection_exit_connect(connection_t *conn) { 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); } diff --git a/src/or/cpuworker.c b/src/or/cpuworker.c index ba7a0837a..17216cc18 100644 --- a/src/or/cpuworker.c +++ b/src/or/cpuworker.c @@ -48,6 +48,7 @@ static void tag_unpack(char *tag, uint32_t *addr, uint16_t *port, uint16_t *circ } 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 @@ int connection_cpu_process_inbuf(connection_t *conn) { 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 @@ int connection_cpu_process_inbuf(connection_t *conn) { 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; diff --git a/src/or/dns.c b/src/or/dns.c index 199958bb0..61aa55458 100644 --- a/src/or/dns.c +++ b/src/or/dns.c @@ -363,7 +363,7 @@ int connection_dns_finished_flushing(connection_t *conn) { } 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 @@ int connection_dns_process_inbuf(connection_t *conn) { 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>"); |