mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2025-02-22 22:25:51 +01:00
Factor out cell packing and unpacking
svn:r240
This commit is contained in:
parent
1bbea670bc
commit
97d847b9e3
4 changed files with 67 additions and 38 deletions
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Add table
Reference in a new issue