summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoger Dingledine <arma@torproject.org>2003-12-16 09:48:17 +0000
committerRoger Dingledine <arma@torproject.org>2003-12-16 09:48:17 +0000
commit8712a30e91fa61de03ed1525b174b3d0ae8cddac (patch)
tree98349cff3e7462fba74fcf173229e75ac800695b
parent961ecf7abfc80571ab858099d1d4f6362b791ea0 (diff)
downloadtor-8712a30e91fa61de03ed1525b174b3d0ae8cddac.tar.gz
tor-8712a30e91fa61de03ed1525b174b3d0ae8cddac.zip
move cell size to 512 bytes
move length to 2 bytes, put it in the relay header remove 4 reserved bytes in cell add 4 bytes to relay header for the integrity check svn:r942
-rw-r--r--src/or/circuit.c39
-rw-r--r--src/or/command.c10
-rw-r--r--src/or/connection_edge.c50
-rw-r--r--src/or/connection_or.c8
-rw-r--r--src/or/onion.c1
-rw-r--r--src/or/or.h44
6 files changed, 74 insertions, 78 deletions
diff --git a/src/or/circuit.c b/src/or/circuit.c
index fa5883ec1e..7a7cc13b63 100644
--- a/src/or/circuit.c
+++ b/src/or/circuit.c
@@ -303,24 +303,18 @@ int circuit_deliver_relay_cell(cell_t *cell, circuit_t *circ,
int cell_direction, crypt_path_t *layer_hint) {
connection_t *conn=NULL;
char recognized=0;
- char buf[1+CELL_PAYLOAD_SIZE];
assert(cell && circ);
assert(cell_direction == CELL_DIRECTION_OUT || cell_direction == CELL_DIRECTION_IN);
- buf[0] = cell->length;
- memcpy(buf+1, cell->payload, CELL_PAYLOAD_SIZE);
-
log_fn(LOG_DEBUG,"direction %d, streamid %d before crypt.", cell_direction, *(int*)(cell->payload+1));
- if(relay_crypt(circ, buf, 1+CELL_PAYLOAD_SIZE, cell_direction, &layer_hint, &recognized, &conn) < 0) {
+ if(relay_crypt(circ, cell->payload, CELL_PAYLOAD_SIZE, cell_direction,
+ &layer_hint, &recognized, &conn) < 0) {
log_fn(LOG_WARN,"relay crypt failed. Dropping connection.");
return -1;
}
- cell->length = buf[0];
- memcpy(cell->payload, buf+1, CELL_PAYLOAD_SIZE);
-
if(recognized) {
if(cell_direction == CELL_DIRECTION_OUT) {
#if 0
@@ -374,11 +368,11 @@ int circuit_deliver_relay_cell(cell_t *cell, circuit_t *circ,
int relay_crypt(circuit_t *circ, char *in, int inlen, char cell_direction,
crypt_path_t **layer_hint, char *recognized, connection_t **conn) {
crypt_path_t *thishop;
- char out[256];
+ char out[CELL_NETWORK_SIZE];
assert(circ && in && recognized && conn);
- assert(inlen < 256);
+ assert(inlen < CELL_NETWORK_SIZE);
if(cell_direction == CELL_DIRECTION_IN) {
if(circ->cpath) { /* we're at the beginning of the circuit.
@@ -391,16 +385,16 @@ int relay_crypt(circuit_t *circ, char *in, int inlen, char cell_direction,
do { /* Remember: cpath is in forward order, that is, first hop first. */
assert(thishop);
- log_fn(LOG_DEBUG,"before decrypt: %d",*(int*)(in+2));
+ log_fn(LOG_DEBUG,"before decrypt: %d",*(int*)(in+1));
/* decrypt */
if(crypto_cipher_decrypt(thishop->b_crypto, in, inlen, out)) {
log_fn(LOG_WARN,"Error performing onion decryption: %s", crypto_perror());
return -1;
}
memcpy(in,out,inlen);
- log_fn(LOG_DEBUG,"after decrypt: %d",*(int*)(in+2));
+ log_fn(LOG_DEBUG,"after decrypt: %d",*(int*)(in+1));
- if( (*recognized = relay_check_recognized(circ, cell_direction, in+2, conn))) {
+ if( (*recognized = relay_check_recognized(circ, cell_direction, in+1, conn))) {
*layer_hint = thishop;
return 0;
}
@@ -411,14 +405,14 @@ int relay_crypt(circuit_t *circ, char *in, int inlen, char cell_direction,
return 0;
} else { /* we're in the middle. Just one crypt. */
- log_fn(LOG_DEBUG,"before encrypt: %d",*(int*)(in+2));
+ log_fn(LOG_DEBUG,"before encrypt: %d",*(int*)(in+1));
if(crypto_cipher_encrypt(circ->p_crypto, in, inlen, out)) {
log_fn(LOG_WARN,"Onion encryption failed for circID %u: %s",
circ->p_circ_id, crypto_perror());
return -1;
}
memcpy(in,out,inlen);
- log_fn(LOG_DEBUG,"after encrypt: %d",*(int*)(in+2));
+ log_fn(LOG_DEBUG,"after encrypt: %d",*(int*)(in+1));
log_fn(LOG_DEBUG,"Skipping recognized check, because we're not the OP.");
/* don't check for recognized. only the OP can recognize a stream on the way back. */
@@ -432,13 +426,13 @@ int relay_crypt(circuit_t *circ, char *in, int inlen, char cell_direction,
do {
assert(thishop);
- log_fn(LOG_DEBUG,"before encrypt: %d",*(int*)(in+2));
+ log_fn(LOG_DEBUG,"before encrypt: %d",*(int*)(in+1));
if(crypto_cipher_encrypt(thishop->f_crypto, in, inlen, out)) {
log_fn(LOG_WARN,"Error performing encryption: %s", crypto_perror());
return -1;
}
memcpy(in,out,inlen);
- log_fn(LOG_DEBUG,"after encrypt: %d",*(int*)(in+2));
+ log_fn(LOG_DEBUG,"after encrypt: %d",*(int*)(in+1));
thishop = thishop->prev;
} while(thishop != circ->cpath->prev);
@@ -451,7 +445,7 @@ int relay_crypt(circuit_t *circ, char *in, int inlen, char cell_direction,
}
memcpy(in,out,inlen);
- if( (*recognized = relay_check_recognized(circ, cell_direction, in+2, conn)))
+ if( (*recognized = relay_check_recognized(circ, cell_direction, in+1, conn)))
return 0;
}
@@ -556,8 +550,8 @@ int circuit_consider_sending_sendme(circuit_t *circ, int edge_type, crypt_path_t
cell.command = CELL_RELAY;
SET_CELL_RELAY_COMMAND(cell, RELAY_COMMAND_SENDME);
SET_CELL_STREAM_ID(cell, ZERO_STREAM);
+ SET_CELL_RELAY_LENGTH(cell, 0);
- cell.length = RELAY_HEADER_SIZE;
if(edge_type == EDGE_AP) { /* i'm the AP */
cell.circ_id = circ->n_circ_id;
while(layer_hint->deliver_window < CIRCWINDOW_START-CIRCWINDOW_INCREMENT) {
@@ -862,7 +856,6 @@ int circuit_send_next_onion_skin(circuit_t *circ) {
memset(&cell, 0, sizeof(cell_t));
cell.command = CELL_CREATE;
cell.circ_id = circ->n_circ_id;
- cell.length = ONIONSKIN_CHALLENGE_LEN;
if(onion_skin_create(circ->n_conn->onion_pkey, &(circ->cpath->handshake_state), cell.payload) < 0) {
log_fn(LOG_WARN,"onion_skin_create (first hop) failed.");
@@ -899,11 +892,12 @@ int circuit_send_next_onion_skin(circuit_t *circ) {
cell.circ_id = circ->n_circ_id;
SET_CELL_RELAY_COMMAND(cell, RELAY_COMMAND_EXTEND);
SET_CELL_STREAM_ID(cell, ZERO_STREAM);
+ SET_CELL_RELAY_LENGTH(cell, 6+ONIONSKIN_CHALLENGE_LEN);
- cell.length = RELAY_HEADER_SIZE + 6 + ONIONSKIN_CHALLENGE_LEN;
*(uint32_t*)(cell.payload+RELAY_HEADER_SIZE) = htonl(hop->addr);
*(uint16_t*)(cell.payload+RELAY_HEADER_SIZE+4) = htons(hop->port);
- if(onion_skin_create(router->onion_pkey, &(hop->handshake_state), cell.payload+RELAY_HEADER_SIZE+6) < 0) {
+ if(onion_skin_create(router->onion_pkey, &(hop->handshake_state),
+ cell.payload+RELAY_HEADER_SIZE+6) < 0) {
log_fn(LOG_WARN,"onion_skin_create failed.");
return -1;
}
@@ -971,7 +965,6 @@ int circuit_extend(cell_t *cell, circuit_t *circ) {
memset(&newcell, 0, sizeof(cell_t));
newcell.command = CELL_CREATE;
newcell.circ_id = circ->n_circ_id;
- newcell.length = ONIONSKIN_CHALLENGE_LEN;
memcpy(newcell.payload, cell->payload+RELAY_HEADER_SIZE+6,
ONIONSKIN_CHALLENGE_LEN);
diff --git a/src/or/command.c b/src/or/command.c
index ed0a8d04d0..8935fcb082 100644
--- a/src/or/command.c
+++ b/src/or/command.c
@@ -103,13 +103,8 @@ static void command_process_create_cell(cell_t *cell, connection_t *conn) {
circ = circuit_new(cell->circ_id, conn);
circ->state = CIRCUIT_STATE_ONIONSKIN_PENDING;
- if(cell->length != ONIONSKIN_CHALLENGE_LEN) {
- log_fn(LOG_WARN,"Bad cell length %d. Dropping.", cell->length);
- circuit_close(circ);
- return;
- }
- memcpy(circ->onionskin,cell->payload,cell->length);
+ memcpy(circ->onionskin, cell->payload, ONIONSKIN_CHALLENGE_LEN);
/* hand it off to the cpuworkers, and then return */
if(assign_to_cpuworker(NULL, CPUWORKER_TASK_ONION, circ) < 0) {
@@ -135,7 +130,6 @@ static void command_process_created_cell(cell_t *cell, connection_t *conn) {
circuit_close(circ);
return;
}
- assert(cell->length == ONIONSKIN_REPLY_LEN);
if(circ->cpath) { /* we're the OP. Handshake this. */
log_fn(LOG_DEBUG,"at OP. Finishing handshake.");
@@ -153,7 +147,7 @@ static void command_process_created_cell(cell_t *cell, connection_t *conn) {
} else { /* pack it into an extended relay cell, and send it. */
log_fn(LOG_INFO,"Converting created cell to extended relay cell, sending.");
connection_edge_send_command(NULL, circ, RELAY_COMMAND_EXTENDED,
- cell->payload, cell->length, NULL);
+ cell->payload, ONIONSKIN_REPLY_LEN, NULL);
}
}
diff --git a/src/or/connection_edge.c b/src/or/connection_edge.c
index 32b7c688bc..4d6be11068 100644
--- a/src/or/connection_edge.c
+++ b/src/or/connection_edge.c
@@ -75,7 +75,7 @@ int connection_edge_process_inbuf(connection_t *conn) {
return 0;
}
-char *connection_edge_end_reason(char *payload, unsigned char length) {
+static char *connection_edge_end_reason(char *payload, uint16_t length) {
if(length < 1) {
log_fn(LOG_WARN,"End cell arrived with length 0. Should be at least 1.");
return "MALFORMED";
@@ -155,7 +155,7 @@ int connection_edge_send_command(connection_t *fromconn, circuit_t *circ, int re
else
SET_CELL_STREAM_ID(cell, fromconn->stream_id);
- cell.length = RELAY_HEADER_SIZE + payload_len;
+ SET_CELL_RELAY_LENGTH(cell, payload_len);
if(payload_len) {
memcpy(cell.payload+RELAY_HEADER_SIZE,payload,payload_len);
}
@@ -191,7 +191,7 @@ int connection_edge_process_relay_cell(cell_t *cell, circuit_t *circ, connection
if(conn && conn->state != AP_CONN_STATE_OPEN && conn->state != EXIT_CONN_STATE_OPEN) {
if(conn->type == CONN_TYPE_EXIT && relay_command == RELAY_COMMAND_END) {
log_fn(LOG_INFO,"Exit got end (%s) before we're connected. Marking for close.",
- connection_edge_end_reason(cell->payload+RELAY_HEADER_SIZE, cell->length));
+ connection_edge_end_reason(cell->payload+RELAY_HEADER_SIZE, CELL_RELAY_LENGTH(*cell)));
if(conn->state == EXIT_CONN_STATE_RESOLVING) {
log_fn(LOG_INFO,"...and informing resolver we don't want the answer anymore.");
dns_cancel_pending_resolve(conn->address, conn);
@@ -248,19 +248,19 @@ int connection_edge_process_relay_cell(cell_t *cell, circuit_t *circ, connection
}
// printf("New text for buf (%d bytes): '%s'", cell->length - RELAY_HEADER_SIZE, cell->payload + RELAY_HEADER_SIZE);
- stats_n_data_bytes_received += (cell->length - RELAY_HEADER_SIZE);
+ stats_n_data_bytes_received += CELL_RELAY_LENGTH(*cell);
connection_write_to_buf(cell->payload + RELAY_HEADER_SIZE,
- cell->length - RELAY_HEADER_SIZE, conn);
+ CELL_RELAY_LENGTH(*cell), conn);
connection_edge_consider_sending_sendme(conn);
return 0;
case RELAY_COMMAND_END:
if(!conn) {
log_fn(LOG_INFO,"end cell (%s) dropped, unknown stream %d.",
- connection_edge_end_reason(cell->payload+RELAY_HEADER_SIZE, cell->length),
+ connection_edge_end_reason(cell->payload+RELAY_HEADER_SIZE, CELL_RELAY_LENGTH(*cell)),
*(int*)conn->stream_id);
return 0;
}
- if(cell->length-RELAY_HEADER_SIZE >= 5 &&
+ if(CELL_RELAY_LENGTH(*cell) >= 5 &&
*(cell->payload+RELAY_HEADER_SIZE) == END_STREAM_REASON_EXITPOLICY) {
/* No need to close the connection. We'll hold it open while
* we try a new exit node.
@@ -281,7 +281,7 @@ int connection_edge_process_relay_cell(cell_t *cell, circuit_t *circ, connection
}
}
log_fn(LOG_INFO,"end cell (%s) for stream %d. Removing stream.",
- connection_edge_end_reason(cell->payload+RELAY_HEADER_SIZE, cell->length),
+ connection_edge_end_reason(cell->payload+RELAY_HEADER_SIZE, CELL_RELAY_LENGTH(*cell)),
*(int*)conn->stream_id);
#ifdef HALF_OPEN
@@ -347,7 +347,7 @@ int connection_edge_process_relay_cell(cell_t *cell, circuit_t *circ, connection
return 0;
}
log_fn(LOG_INFO,"Connected! Notifying application.");
- if (cell->length-RELAY_HEADER_SIZE == 4) {
+ if (CELL_RELAY_LENGTH(*cell) >= 4) {
addr = ntohl(*(uint32_t*)(cell->payload + RELAY_HEADER_SIZE));
client_dns_set_entry(conn->socks_request->address, addr);
}
@@ -444,45 +444,45 @@ int connection_edge_package_raw_inbuf(connection_t *conn) {
int amount_to_process, length;
char payload[CELL_PAYLOAD_SIZE];
circuit_t *circ;
-
+
assert(conn);
assert(!connection_speaks_cells(conn));
-
+
repeat_connection_edge_package_raw_inbuf:
-
+
circ = circuit_get_by_conn(conn);
if(!circ) {
log_fn(LOG_INFO,"conn has no circuits! Closing.");
return -1;
}
-
+
if(circuit_consider_stop_edge_reading(circ, conn->type, conn->cpath_layer))
return 0;
-
+
if(conn->package_window <= 0) {
log_fn(LOG_WARN,"called with package_window %d. Tell Roger.", conn->package_window);
connection_stop_reading(conn);
return 0;
}
-
+
amount_to_process = buf_datalen(conn->inbuf);
-
+
if(!amount_to_process)
return 0;
-
- if(amount_to_process > CELL_PAYLOAD_SIZE - RELAY_HEADER_SIZE) {
- length = CELL_PAYLOAD_SIZE - RELAY_HEADER_SIZE;
+
+ if(amount_to_process > RELAY_PAYLOAD_SIZE) {
+ length = RELAY_PAYLOAD_SIZE;
} else {
length = amount_to_process;
}
stats_n_data_bytes_packaged += length;
stats_n_data_cells_packaged += 1;
-
+
connection_fetch_from_buf(payload, length, conn);
- log_fn(LOG_DEBUG,"(%d) Packaging %d bytes (%d waiting).",conn->s,length,
+ log_fn(LOG_DEBUG,"(%d) Packaging %d bytes (%d waiting).", conn->s, length,
(int)buf_datalen(conn->inbuf));
-
+
if(connection_edge_send_command(conn, circ, RELAY_COMMAND_DATA,
payload, length, conn->cpath_layer) < 0)
return 0; /* circuit is closed, don't continue */
@@ -495,7 +495,7 @@ repeat_connection_edge_package_raw_inbuf:
assert(conn->cpath_layer->package_window > 0);
conn->cpath_layer->package_window--;
}
-
+
if(--conn->package_window <= 0) { /* is it 0 after decrement? */
connection_stop_reading(conn);
log_fn(LOG_DEBUG,"conn->package_window reached 0.");
@@ -503,7 +503,7 @@ repeat_connection_edge_package_raw_inbuf:
return 0; /* don't process the inbuf any more */
}
log_fn(LOG_DEBUG,"conn->package_window is now %d",conn->package_window);
-
+
/* handle more if there's more, or return 0 if there isn't */
goto repeat_connection_edge_package_raw_inbuf;
}
@@ -740,7 +740,7 @@ static int connection_exit_begin_conn(cell_t *cell, circuit_t *circ) {
*/
if(!memchr(cell->payload+RELAY_HEADER_SIZE+STREAM_ID_SIZE,0,
- cell->length-RELAY_HEADER_SIZE-STREAM_ID_SIZE)) {
+ CELL_RELAY_LENGTH(*cell)-STREAM_ID_SIZE)) {
log_fn(LOG_WARN,"relay begin cell has no \\0. Dropping.");
return 0;
}
diff --git a/src/or/connection_or.c b/src/or/connection_or.c
index 212453411b..e516913877 100644
--- a/src/or/connection_or.c
+++ b/src/or/connection_or.c
@@ -14,17 +14,13 @@ static int connection_or_process_cell_from_inbuf(connection_t *conn);
static void cell_pack(char *dest, const cell_t *src) {
*(uint16_t*)dest = htons(src->circ_id);
*(uint8_t*)(dest+2) = src->command;
- *(uint8_t*)(dest+3) = src->length;
- *(uint32_t*)(dest+4) = 0; /* Reserved */
- memcpy(dest+8, src->payload, CELL_PAYLOAD_SIZE);
+ memcpy(dest+3, src->payload, CELL_PAYLOAD_SIZE);
}
static void cell_unpack(cell_t *dest, const char *src) {
dest->circ_id = ntohs(*(uint16_t*)(src));
dest->command = *(uint8_t*)(src+2);
- dest->length = *(uint8_t*)(src+3);
- dest->seq = ntohl(*(uint32_t*)(src+4));
- memcpy(dest->payload, src+8, CELL_PAYLOAD_SIZE);
+ memcpy(dest->payload, src+3, CELL_PAYLOAD_SIZE);
}
/**************************************************************/
diff --git a/src/or/onion.c b/src/or/onion.c
index 0923741d92..5c52dd6295 100644
--- a/src/or/onion.c
+++ b/src/or/onion.c
@@ -124,7 +124,6 @@ int onionskin_answer(circuit_t *circ, unsigned char *payload, unsigned char *key
memset(&cell, 0, sizeof(cell_t));
cell.command = CELL_CREATED;
cell.circ_id = circ->p_circ_id;
- cell.length = ONIONSKIN_REPLY_LEN;
circ->state = CIRCUIT_STATE_OPEN;
diff --git a/src/or/or.h b/src/or/or.h
index 7cab9f17be..0b63ccf286 100644
--- a/src/or/or.h
+++ b/src/or/or.h
@@ -190,8 +190,6 @@
#define RELAY_COMMAND_TRUNCATED 9
#define RELAY_COMMAND_DROP 10
-#define RELAY_HEADER_SIZE 8
-
#define END_STREAM_REASON_MISC 1
#define END_STREAM_REASON_RESOLVEFAILED 2
#define END_STREAM_REASON_CONNECTFAILED 3
@@ -225,9 +223,6 @@
#define CELL_RELAY 3
#define CELL_DESTROY 4
-#define CELL_PAYLOAD_SIZE 248
-#define CELL_NETWORK_SIZE 256
-
/* legal characters in a filename */
#define CONFIG_LEGAL_FILENAME_CHARACTERS "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.-_/"
/* legal characters in a nickname */
@@ -237,27 +232,45 @@
typedef uint16_t circ_id_t;
-/* cell definition */
-typedef struct {
- circ_id_t circ_id;
- unsigned char command;
- unsigned char length; /* of payload if relay cell */
- uint32_t seq; /* sequence number */
+/*
+ * Relay payload:
+ * Relay command [1 byte]
+ * Stream ID [7 bytes]
+ * Partial SHA-1 [4 bytes]
+ * Length [2 bytes]
+ * Relay payload [495 bytes]
+ */
- unsigned char payload[CELL_PAYLOAD_SIZE];
-} cell_t;
#define CELL_RELAY_COMMAND(c) (*(uint8_t*)((c).payload))
#define SET_CELL_RELAY_COMMAND(c,cmd) (*(uint8_t*)((c).payload) = (cmd))
+
#define STREAM_ID_SIZE 7
#define SET_CELL_STREAM_ID(c,id) memcpy((c).payload+1,(id),STREAM_ID_SIZE)
+#define ZERO_STREAM "\0\0\0\0\0\0\0"
+
#define CELL_RELAY_COMMAND_END_REASON(c) (*(uint8_t)((c).payload+1))
-#define ZERO_STREAM "\0\0\0\0\0\0\0\0"
+/* relay length is how many bytes are used in the cell payload past relay_header_size */
+#define CELL_RELAY_LENGTH(c) (*(uint16_t*)((c).payload+1+STREAM_ID_SIZE+4))
+#define SET_CELL_RELAY_LENGTH(c,len) (*(uint16_t*)((c).payload+1+STREAM_ID_SIZE+4) = (len))
+
+#define CELL_PAYLOAD_SIZE 509
+#define CELL_NETWORK_SIZE 512
+
+/* cell definition */
+typedef struct {
+ circ_id_t circ_id;
+ unsigned char command;
+ unsigned char payload[CELL_PAYLOAD_SIZE];
+} cell_t;
+
+#define RELAY_HEADER_SIZE (1+STREAM_ID_SIZE+4+2)
+#define RELAY_PAYLOAD_SIZE (CELL_PAYLOAD_SIZE-RELAY_HEADER_SIZE)
typedef struct buf_t buf_t;
typedef struct socks_request_t socks_request_t;
-struct connection_t {
+struct connection_t {
uint8_t type;
uint8_t state;
@@ -476,6 +489,7 @@ typedef struct {
int loglevel;
} or_options_t;
+/* XXX are these good enough defaults? */
#define MAX_SOCKS_REPLY_LEN 256
/* Not 256; addresses must fit in a begin cell. */
#define MAX_SOCKS_ADDR_LEN 200