summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/tor-spec.txt14
-rw-r--r--src/or/connection.c65
-rw-r--r--src/or/connection_edge.c18
-rw-r--r--src/or/or.h8
4 files changed, 67 insertions, 38 deletions
diff --git a/doc/tor-spec.txt b/doc/tor-spec.txt
index 196349d4c3..58c4fdf2a4 100644
--- a/doc/tor-spec.txt
+++ b/doc/tor-spec.txt
@@ -281,12 +281,6 @@ which reveals the downstream node.
The value of Version is currently 2.
- The forward and backward ciphers fields can take the following values:
- 0: Identity
- 1: Single DES in OFB
- 2: RC4
- 3: Triple DES (encrypt-decrypt-encrypt) in OFB
-
The port and address field denote the IPV4 address and port of
the next onion router in the circuit, or are set to 0 for the
last hop.
@@ -316,7 +310,7 @@ which reveals the downstream node.
D. Encrypt the first 128 bytes of M with the RSA key of
OR_I, using no padding. Encrypt the remaining portion of
- M with DES/OFB, using K1_I as a key and an all-0 IV.
+ M with 3DES/OFB, using K1_I as a key and an all-0 IV.
3. M is now the onion.
@@ -365,7 +359,7 @@ which reveals the downstream node.
in the past, then tear down the circuit (see section 4.2).
Compute K1 through K3 as above. Use K1 to decrypt the rest
- of the onion using DES/OFB.
+ of the onion using 3DES/OFB.
If we are not the exit node, remove the first layer from the
decrypted onion, and send the remainder to the next OR
@@ -403,14 +397,14 @@ which reveals the downstream node.
Otherwise, if the OR is not at the OP edge of the circuit (that is,
either an 'exit node' or a non-edge node), it de/encrypts the length
- field and the payload with DES/OFB, as follows:
+ field and the payload with 3DES/OFB, as follows:
'Forward' data cell (same direction as onion):
Use K2 as key; encrypt.
'Back' data cell (opposite direction from onion):
Use K3 as key; decrypt.
Otherwise, if the data cell has arrived to the OP edge of the circuit,
- the OP de/encrypts the length and payload fields with DES/OFB as
+ the OP de/encrypts the length and payload fields with 3DES/OFB as
follows:
OP sends data cell:
For I=1...N, decrypt with K2_I.
diff --git a/src/or/connection.c b/src/or/connection.c
index c15eb00100..4ef246d838 100644
--- a/src/or/connection.c
+++ b/src/or/connection.c
@@ -543,7 +543,6 @@ void connection_send_cell(connection_t *conn) {
*/
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 @@ int connection_write_cell_to_buf(const cell_t *cellp, connection_t *conn) {
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 @@ repeat_connection_package_raw_inbuf:
* 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 @@ repeat_connection_package_raw_inbuf:
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 @@ repeat_connection_package_raw_inbuf:
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 @@ int connection_consider_sending_sendme(connection_t *conn, int edge_type) {
}
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,11 +845,7 @@ int connection_process_cell_from_inbuf(connection_t *conn) {
#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);
@@ -862,6 +853,40 @@ int connection_process_cell_from_inbuf(connection_t *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);
+ }
+}
+
/*
Local Variables:
mode:c
diff --git a/src/or/connection_edge.c b/src/or/connection_edge.c
index 4f0a25b990..4a82d65a90 100644
--- a/src/or/connection_edge.c
+++ b/src/or/connection_edge.c
@@ -27,9 +27,10 @@ int connection_edge_process_inbuf(connection_t *conn) {
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 @@ int connection_edge_send_command(connection_t *conn, circuit_t *circ, int topic_
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 @@ int connection_edge_process_data_cell(cell_t *cell, circuit_t *circ, int edge_ty
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 @@ int connection_edge_process_data_cell(cell_t *cell, circuit_t *circ, int edge_ty
}
#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 @@ int connection_edge_process_data_cell(cell_t *cell, circuit_t *circ, int edge_ty
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;
diff --git a/src/or/or.h b/src/or/or.h
index 5e84ec3b83..1687cae38d 100644
--- a/src/or/or.h
+++ b/src/or/or.h
@@ -197,6 +197,11 @@ typedef struct {
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;
@@ -614,6 +619,9 @@ int connection_process_cell_from_inbuf(connection_t *conn);
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 ****************************/
int ap_handshake_process_socks(connection_t *conn);