[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
[or-cvs] streams are now 8 bytes, and are recognized by intermediate...
- To: or-cvs@freehaven.net
- Subject: [or-cvs] streams are now 8 bytes, and are recognized by intermediate...
- From: arma@seul.org (Roger Dingledine)
- Date: Fri, 2 May 2003 17:29:27 -0400 (EDT)
- Delivered-to: archiver@seul.org
- Delivered-to: or-cvs-outgoing@seul.org
- Delivered-to: or-cvs@seul.org
- Delivery-date: Fri, 02 May 2003 17:29:38 -0400
- Reply-to: or-dev@freehaven.net
- Sender: owner-or-cvs@freehaven.net
Update of /home/or/cvsroot/src/or
In directory moria.mit.edu:/home/arma/work/onion/cvs/src/or
Modified Files:
circuit.c command.c connection.c connection_ap.c
connection_edge.c connection_exit.c onion.c or.h
Log Message:
streams are now 8 bytes, and are recognized by intermediate hops
the OP only crypts the appropriate number of times depending on which
layer (hop on the path) it's for/from.
Index: circuit.c
===================================================================
RCS file: /home/or/cvsroot/src/or/circuit.c,v
retrieving revision 1.40
retrieving revision 1.41
diff -u -d -r1.40 -r1.41
--- circuit.c 1 May 2003 22:55:50 -0000 1.40
+++ circuit.c 2 May 2003 21:29:25 -0000 1.41
@@ -281,7 +281,8 @@
return bestcirc;
}
-int circuit_deliver_relay_cell_from_edge(cell_t *cell, circuit_t *circ, char edge_type) {
+int circuit_deliver_relay_cell_from_edge(cell_t *cell, circuit_t *circ,
+ char edge_type, crypt_path_t *layer_hint) {
int cell_direction;
static int numsent_ap=0, numsent_exit=0;
@@ -293,7 +294,7 @@
log(LOG_DEBUG,"circuit_deliver_relay_cell_from_edge(): now sent %d relay cells from ap", numsent_ap);
if(circ->p_receive_circwindow <= 0) {
log(LOG_DEBUG,"circuit_deliver_relay_cell_from_edge(): pwindow 0, queueing for later.");
- circ->relay_queue = relay_queue_add(circ->relay_queue, cell);
+ circ->relay_queue = relay_queue_add(circ->relay_queue, cell, layer_hint);
return 0;
}
circ->p_receive_circwindow--;
@@ -304,13 +305,13 @@
log(LOG_DEBUG,"circuit_deliver_relay_cell_from_edge(): now sent %d relay cells from exit", numsent_exit);
if(circ->n_receive_circwindow <= 0) {
log(LOG_DEBUG,"circuit_deliver_relay_cell_from_edge(): nwindow 0, queueing for later.");
- circ->relay_queue = relay_queue_add(circ->relay_queue, cell);
+ circ->relay_queue = relay_queue_add(circ->relay_queue, cell, layer_hint);
return 0;
}
circ->n_receive_circwindow--;
}
- if(circuit_deliver_relay_cell(cell, circ, cell_direction) < 0) {
+ if(circuit_deliver_relay_cell(cell, circ, cell_direction, layer_hint) < 0) {
return -1;
}
@@ -318,113 +319,168 @@
return 0;
}
-int circuit_deliver_relay_cell(cell_t *cell, circuit_t *circ, int cell_direction) {
- connection_t *conn;
+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[256];
assert(cell && circ);
assert(cell_direction == CELL_DIRECTION_OUT || cell_direction == CELL_DIRECTION_IN);
- if(cell_direction == CELL_DIRECTION_OUT)
- conn = circ->n_conn;
- else
- conn = circ->p_conn;
- /* first crypt cell->length */
- if(circuit_crypt(circ, &(cell->length), 1, cell_direction) < 0) {
- log(LOG_DEBUG,"circuit_deliver_relay_cell(): length crypt failed. Dropping connection.");
- return -1;
- }
+ buf[0] = cell->length;
+ memcpy(buf+1, cell->payload, CELL_PAYLOAD_SIZE);
- /* then crypt the payload */
- if(circuit_crypt(circ, (char *)&(cell->payload), CELL_PAYLOAD_SIZE, cell_direction) < 0) {
- log(LOG_DEBUG,"circuit_deliver_relay_cell(): payload crypt failed. Dropping connection.");
+ log(LOG_DEBUG,"circuit_deliver_relay_cell(): streamid %d before crypt.", *(int*)(cell->payload+1));
+
+ if(relay_crypt(circ, buf, 1+CELL_PAYLOAD_SIZE, cell_direction, layer_hint, &recognized, &conn) < 0) {
+ log(LOG_DEBUG,"circuit_deliver_relay_cell(): relay crypt failed. Dropping connection.");
return -1;
}
- if(cell_direction == CELL_DIRECTION_OUT && (!conn || conn->type == CONN_TYPE_EXIT)) {
- log(LOG_DEBUG,"circuit_deliver_relay_cell(): Sending to exit.");
- return connection_edge_process_relay_cell(cell, circ, EDGE_EXIT);
+ cell->length = buf[0];
+ memcpy(cell->payload, buf+1, CELL_PAYLOAD_SIZE);
+
+ if(recognized) {
+ if(cell_direction == CELL_DIRECTION_OUT) {
+ log(LOG_DEBUG,"circuit_deliver_relay_cell(): Sending to exit.");
+ return connection_edge_process_relay_cell(cell, circ, conn, EDGE_EXIT);
+ }
+ if(cell_direction == CELL_DIRECTION_IN) {
+ log(LOG_DEBUG,"circuit_deliver_relay_cell(): Sending to AP.");
+ return connection_edge_process_relay_cell(cell, circ, conn, EDGE_AP);
+ }
}
- if(cell_direction == CELL_DIRECTION_IN && (!conn || conn->type == CONN_TYPE_AP)) {
- log(LOG_DEBUG,"circuit_deliver_relay_cell(): Sending to AP.");
- return connection_edge_process_relay_cell(cell, circ, EDGE_AP);
+
+ /* not recognized. pass it on. */
+ if(cell_direction == CELL_DIRECTION_OUT)
+ conn = circ->n_conn;
+ else
+ conn = circ->p_conn;
+
+ if(!conn || !connection_speaks_cells(conn)) {
+ log(LOG_INFO,"circuit_deliver_relay_cell(): Didn't recognize cell (%d), but circ stops here! Dropping.", *(int *)(cell->payload+1));
+ return 0;
}
- /* else send it as a cell */
- assert(conn);
- //log(LOG_DEBUG,"circuit_deliver_relay_cell(): Sending to connection.");
+
return connection_write_cell_to_buf(cell, conn);
}
-int circuit_crypt(circuit_t *circ, char *in, int inlen, char cell_direction) {
- char *out;
+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];
- assert(circ && in);
+ assert(circ && in && recognized && conn);
- out = (char *)malloc(inlen);
- if(!out)
- return -1;
+ assert(inlen < 256);
if(cell_direction == CELL_DIRECTION_IN) {
if(circ->cpath) { /* we're at the beginning of the circuit. We'll want to do layered crypts. */
thishop = circ->cpath;
- /* Remember: cpath is in forward order, that is, first hop first. */
- do {
+ do { /* Remember: cpath is in forward order, that is, first hop first. */
assert(thishop);
+
/* decrypt */
if(crypto_cipher_decrypt(thishop->b_crypto, in, inlen, out)) {
log(LOG_ERR,"Error performing decryption:%s",crypto_perror());
- free(out);
return -1;
}
-
- /* copy ciphertext back to buf */
memcpy(in,out,inlen);
+
+ if( (*recognized = relay_check_recognized(circ, cell_direction, in+2, conn)))
+ return 0;
+
thishop = thishop->next;
} while(thishop != circ->cpath);
+ log(LOG_INFO,"relay_crypt(): in-cell at OP not recognized. Killing circuit.");
+ return -1;
} else { /* we're in the middle. Just one crypt. */
- if(crypto_cipher_encrypt(circ->p_crypto,in, inlen, out)) {
+
+ if(crypto_cipher_encrypt(circ->p_crypto, in, inlen, out)) {
log(LOG_ERR,"circuit_encrypt(): Encryption failed for ACI : %u (%s).",
circ->p_aci, crypto_perror());
- free(out);
return -1;
}
memcpy(in,out,inlen);
+
+ /* don't check for recognized. only the OP can recognize a stream on the way back. */
+
}
} else if(cell_direction == CELL_DIRECTION_OUT) {
if(circ->cpath) { /* we're at the beginning of the circuit. We'll want to do layered crypts. */
- thishop = circ->cpath->prev;
+
+ thishop = layer_hint; /* we already know which layer, from when we package_raw_inbuf'ed */
/* moving from last to first hop */
do {
assert(thishop);
+
/* encrypt */
- if(crypto_cipher_encrypt(thishop->f_crypto, in, inlen, (unsigned char *)out)) {
+ if(crypto_cipher_encrypt(thishop->f_crypto, in, inlen, out)) {
log(LOG_ERR,"Error performing encryption:%s",crypto_perror());
- free(out);
return -1;
}
-
- /* copy ciphertext back to buf */
memcpy(in,out,inlen);
+
thishop = thishop->prev;
} while(thishop != circ->cpath->prev);
} else { /* we're in the middle. Just one crypt. */
+
if(crypto_cipher_decrypt(circ->n_crypto,in, inlen, out)) {
log(LOG_ERR,"circuit_crypt(): Decryption failed for ACI : %u (%s).",
circ->n_aci, crypto_perror());
- free(out);
return -1;
}
memcpy(in,out,inlen);
+
+ if( (*recognized = relay_check_recognized(circ, cell_direction, in+2, conn)))
+ return 0;
+
}
} else {
log(LOG_ERR,"circuit_crypt(): unknown cell direction %d.", cell_direction);
assert(0);
}
- free(out);
return 0;
}
+int relay_check_recognized(circuit_t *circ, int cell_direction, char *stream, connection_t **conn) {
+/* FIXME can optimize by passing thishop in */
+ connection_t *tmpconn;
+
+ log(LOG_DEBUG,"relay_check_recognized(): entering");
+ if(!memcmp(stream,ZERO_STREAM,STREAM_ID_SIZE))
+ return 1; /* the zero stream is always recognized */
+
+ if(cell_direction == CELL_DIRECTION_OUT)
+ tmpconn = circ->n_conn;
+ else
+ tmpconn = circ->p_conn;
+
+ log(LOG_DEBUG,"relay_check_recognized(): not the zero stream.");
+ if(!tmpconn)
+ return 0; /* no conns? don't recognize it */
+
+ while(tmpconn && tmpconn->type == CONN_TYPE_OR) {
+ log(LOG_DEBUG,"relay_check_recognized(): skipping over an OR conn");
+ tmpconn = tmpconn->next_stream;
+ }
+
+ for( ; tmpconn; tmpconn=tmpconn->next_stream) {
+ if(!memcmp(stream,tmpconn->stream_id, STREAM_ID_SIZE)) {
+ log(LOG_DEBUG,"relay_check_recognized(): recognized stream %d.", *(int*)stream);
+ *conn = tmpconn;
+ return 1;
+ }
+ log(LOG_DEBUG,"relay_check_recognized(): considered stream %d, not it.",*(int*)tmpconn->stream_id);
+ }
+
+ log(LOG_DEBUG,"relay_check_recognized(): Didn't recognize. Giving up.");
+ return 0;
+
+}
+
void circuit_resume_edge_reading(circuit_t *circ, int edge_type) {
connection_t *conn;
struct relay_queue_t *tmpd;
@@ -438,7 +494,7 @@
circ->n_receive_circwindow--;
assert(circ->n_receive_circwindow >= 0);
- if(circuit_deliver_relay_cell(circ->relay_queue->cell, circ, CELL_DIRECTION_IN) < 0) {
+ if(circuit_deliver_relay_cell(circ->relay_queue->cell, circ, CELL_DIRECTION_IN, circ->relay_queue->layer_hint) < 0) {
circuit_close(circ);
return;
}
@@ -446,7 +502,7 @@
circ->p_receive_circwindow--;
assert(circ->p_receive_circwindow >= 0);
- if(circuit_deliver_relay_cell(circ->relay_queue->cell, circ, CELL_DIRECTION_OUT) < 0) {
+ if(circuit_deliver_relay_cell(circ->relay_queue->cell, circ, CELL_DIRECTION_OUT, circ->relay_queue->layer_hint) < 0) {
circuit_close(circ);
return;
}
Index: command.c
===================================================================
RCS file: /home/or/cvsroot/src/or/command.c,v
retrieving revision 1.25
retrieving revision 1.26
diff -u -d -r1.25 -r1.26
--- command.c 1 May 2003 06:42:28 -0000 1.25
+++ command.c 2 May 2003 21:29:25 -0000 1.26
@@ -241,14 +241,14 @@
if(cell->aci == circ->p_aci) { /* it's an outgoing cell */
cell->aci = circ->n_aci; /* switch it */
- if(circuit_deliver_relay_cell(cell, circ, CELL_DIRECTION_OUT) < 0) {
+ if(circuit_deliver_relay_cell(cell, circ, CELL_DIRECTION_OUT, conn->cpath_layer) < 0) {
log(LOG_INFO,"command_process_relay_cell(): circuit_deliver_relay_cell (forward) failed. Closing.");
circuit_close(circ);
return;
}
} else { /* it's an ingoing cell */
cell->aci = circ->p_aci; /* switch it */
- if(circuit_deliver_relay_cell(cell, circ, CELL_DIRECTION_IN) < 0) {
+ if(circuit_deliver_relay_cell(cell, circ, CELL_DIRECTION_IN, NULL) < 0) {
log(LOG_DEBUG,"command_process_relay_cell(): circuit_deliver_relay_cell (backward) failed. Closing.");
circuit_close(circ);
return;
Index: connection.c
===================================================================
RCS file: /home/or/cvsroot/src/or/connection.c,v
retrieving revision 1.58
retrieving revision 1.59
diff -u -d -r1.58 -r1.59
--- connection.c 1 May 2003 06:42:28 -0000 1.58
+++ connection.c 2 May 2003 21:29:25 -0000 1.59
@@ -706,7 +706,7 @@
if(conn->type == CONN_TYPE_EXIT) {
cell.aci = circ->p_aci;
- if(circuit_deliver_relay_cell_from_edge(&cell, circ, EDGE_EXIT) < 0) {
+ if(circuit_deliver_relay_cell_from_edge(&cell, circ, EDGE_EXIT, NULL) < 0) {
log(LOG_DEBUG,"connection_package_raw_inbuf(): circuit_deliver_relay_cell_from_edge (backward) failed. Closing.");
circuit_close(circ);
return 0;
@@ -721,7 +721,7 @@
} else { /* send it forward. we're an AP */
assert(conn->type == CONN_TYPE_AP);
cell.aci = circ->n_aci;
- if(circuit_deliver_relay_cell_from_edge(&cell, circ, EDGE_AP) < 0) {
+ if(circuit_deliver_relay_cell_from_edge(&cell, circ, EDGE_AP, conn->cpath_layer) < 0) {
log(LOG_DEBUG,"connection_package_raw_inbuf(): circuit_deliver_relay_cell_from_edge (forward) failed. Closing.");
circuit_close(circ);
return 0;
@@ -763,7 +763,7 @@
log(LOG_DEBUG,"connection_consider_sending_sendme(): Outbuf %d, Queueing stream sendme back.", conn->outbuf_flushlen);
conn->p_receive_streamwindow += STREAMWINDOW_INCREMENT;
cell.aci = circ->p_aci;
- if(circuit_deliver_relay_cell_from_edge(&cell, circ, edge_type) < 0) {
+ if(circuit_deliver_relay_cell_from_edge(&cell, circ, edge_type, NULL) < 0) {
log(LOG_DEBUG,"connection_consider_sending_sendme(): circuit_deliver_relay_cell_from_edge (backward) failed. Closing.");
circuit_close(circ);
return 0;
@@ -775,7 +775,7 @@
log(LOG_DEBUG,"connection_consider_sending_sendme(): Outbuf %d, Queueing stream sendme forward.", conn->outbuf_flushlen);
conn->n_receive_streamwindow += STREAMWINDOW_INCREMENT;
cell.aci = circ->n_aci;
- if(circuit_deliver_relay_cell_from_edge(&cell, circ, edge_type) < 0) {
+ if(circuit_deliver_relay_cell_from_edge(&cell, circ, edge_type, conn->cpath_layer) < 0) {
log(LOG_DEBUG,"connection_consider_sending_sendme(): circuit_deliver_relay_cell_from_edge (forward) failed. Closing.");
circuit_close(circ);
return 0;
Index: connection_ap.c
===================================================================
RCS file: /home/or/cvsroot/src/or/connection_ap.c,v
retrieving revision 1.40
retrieving revision 1.41
diff -u -d -r1.40 -r1.41
--- connection_ap.c 1 May 2003 22:55:50 -0000 1.40
+++ connection_ap.c 2 May 2003 21:29:25 -0000 1.41
@@ -108,6 +108,10 @@
conn->next_stream = circ->p_conn;
circ->p_conn = conn;
+ assert(circ->cpath && circ->cpath->prev);
+ assert(circ->cpath->prev->state == CPATH_STATE_OPEN);
+ conn->cpath_layer = circ->cpath->prev;
+
if(ap_handshake_send_begin(conn, circ) < 0) {
circuit_close(circ);
return -1;
@@ -118,23 +122,24 @@
int ap_handshake_send_begin(connection_t *ap_conn, circuit_t *circ) {
cell_t cell;
- uint16_t stream_id;
memset(&cell, 0, sizeof(cell_t));
/* deliver the dest_addr in a relay cell */
cell.command = CELL_RELAY;
cell.aci = circ->n_aci;
SET_CELL_RELAY_COMMAND(cell, RELAY_COMMAND_BEGIN);
- if (CRYPTO_PSEUDO_RAND_INT(stream_id))
+ if(crypto_pseudo_rand(STREAM_ID_SIZE, ap_conn->stream_id) < 0)
return -1;
- SET_CELL_STREAM_ID(cell, stream_id);
/* FIXME check for collisions */
- ap_conn->stream_id = stream_id;
+ SET_CELL_STREAM_ID(cell, ZERO_STREAM);
- snprintf(cell.payload+4, CELL_PAYLOAD_SIZE-4, "%s:%d", ap_conn->dest_addr, ap_conn->dest_port);
- cell.length = strlen(cell.payload+RELAY_HEADER_SIZE)+1+RELAY_HEADER_SIZE;
- log(LOG_DEBUG,"ap_handshake_send_begin(): Sending relay cell to begin stream %d.", ap_conn->stream_id);
- if(circuit_deliver_relay_cell_from_edge(&cell, circ, EDGE_AP) < 0) {
+ memcpy(cell.payload+RELAY_HEADER_SIZE, ap_conn->stream_id, STREAM_ID_SIZE);
+ cell.length =
+ snprintf(cell.payload+RELAY_HEADER_SIZE+STREAM_ID_SIZE, CELL_PAYLOAD_SIZE-RELAY_HEADER_SIZE-STREAM_ID_SIZE,
+ "%s:%d", ap_conn->dest_addr, ap_conn->dest_port) +
+ 1 + STREAM_ID_SIZE + RELAY_HEADER_SIZE;
+ log(LOG_DEBUG,"ap_handshake_send_begin(): Sending relay cell (id %d) to begin stream %d.", *(int *)(cell.payload+1),*(int *)ap_conn->stream_id);
+ if(circuit_deliver_relay_cell_from_edge(&cell, circ, EDGE_AP, ap_conn->cpath_layer) < 0) {
log(LOG_DEBUG,"ap_handshake_send_begin(): failed to deliver begin cell. Closing.");
return -1;
}
Index: connection_edge.c
===================================================================
RCS file: /home/or/cvsroot/src/or/connection_edge.c,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -d -r1.6 -r1.7
--- connection_edge.c 1 May 2003 06:42:28 -0000 1.6
+++ connection_edge.c 2 May 2003 21:29:25 -0000 1.7
@@ -31,7 +31,7 @@
SET_CELL_STREAM_ID(cell, conn->stream_id);
cell.aci = circ->n_aci;
- if (circuit_deliver_relay_cell_from_edge(&cell, circ, conn->type) < 0) {
+ if (circuit_deliver_relay_cell_from_edge(&cell, circ, conn->type, conn->cpath_layer) < 0) {
log(LOG_DEBUG,"connection_edge_process_inbuf: circuit_deliver_relay_cell_from_edge failed. Closing");
circuit_close(circ);
}
@@ -82,18 +82,16 @@
cell.length = RELAY_HEADER_SIZE;
log(LOG_INFO,"connection_edge_send_command(): delivering %d cell %s.", relay_command, conn->type == CONN_TYPE_AP ? "forward" : "backward");
- if(circuit_deliver_relay_cell_from_edge(&cell, circ, conn->type) < 0) {
- log(LOG_DEBUG,"connection_edge_send_command(): circuit_deliver_relay_cell failed. Closing.");
+ if(circuit_deliver_relay_cell_from_edge(&cell, circ, conn->type, conn->cpath_layer) < 0) {
+ log(LOG_DEBUG,"connection_edge_send_command(): circuit_deliver_relay_cell_from_edge failed. Closing.");
circuit_close(circ);
return 0;
}
return 0;
}
-int connection_edge_process_relay_cell(cell_t *cell, circuit_t *circ, int edge_type) {
- connection_t *conn;
+int connection_edge_process_relay_cell(cell_t *cell, circuit_t *circ, connection_t *conn, int edge_type) {
int relay_command;
- int stream_id;
static int num_seen=0;
/* an incoming relay cell has arrived */
@@ -101,23 +99,14 @@
assert(cell && circ);
relay_command = CELL_RELAY_COMMAND(*cell);
- stream_id = CELL_STREAM_ID(*cell);
- log(LOG_DEBUG,"connection_edge_process_relay_cell(): command %d stream %d", relay_command, stream_id);
+// log(LOG_DEBUG,"connection_edge_process_relay_cell(): command %d stream %d", relay_command, stream_id);
num_seen++;
log(LOG_DEBUG,"connection_edge_process_relay_cell(): Now seen %d relay cells here.", num_seen);
circuit_consider_sending_sendme(circ, edge_type);
- if(edge_type == EDGE_AP)
- conn = circ->p_conn;
- else
- conn = circ->n_conn;
-
- for( ; conn && conn->stream_id != stream_id; conn = conn->next_stream) ;
-
- /* now conn is either NULL, in which case we don't recognize the stream_id, or
- * it is set, in which case cell is talking about this conn.
- */
+ /* either conn is NULL, in which case we've got a control cell, or else
+ * conn points to the recognized stream. */
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) {
@@ -143,7 +132,7 @@
}
case RELAY_COMMAND_DATA:
if(!conn) {
- log(LOG_DEBUG,"connection_edge_process_relay_cell(): relay cell dropped, unknown stream %d.",stream_id);
+ log(LOG_DEBUG,"connection_edge_process_relay_cell(): relay cell dropped, unknown stream %d.",*(int*)conn->stream_id);
return 0;
}
if((edge_type == EDGE_AP && --conn->n_receive_streamwindow < 0) ||
@@ -172,10 +161,10 @@
return 0;
case RELAY_COMMAND_END:
if(!conn) {
- log(LOG_DEBUG,"connection_edge_process_relay_cell(): end cell dropped, unknown stream %d.",stream_id);
+ log(LOG_DEBUG,"connection_edge_process_relay_cell(): end cell dropped, unknown stream %d.",*(int*)conn->stream_id);
return 0;
}
- log(LOG_DEBUG,"connection_edge_process_relay_cell(): end cell for stream %d. Removing stream.",stream_id);
+ log(LOG_DEBUG,"connection_edge_process_relay_cell(): end cell for stream %d. Removing stream.",*(int*)conn->stream_id);
/* go through and identify who points to conn. remove conn from the list. */
#if 0
@@ -199,7 +188,7 @@
return 0;
}
if(!conn) {
- log(LOG_DEBUG,"connection_edge_process_relay_cell(): connected cell dropped, unknown stream %d.",stream_id);
+ log(LOG_DEBUG,"connection_edge_process_relay_cell(): connected cell dropped, unknown stream %d.",*(int*)conn->stream_id);
break;
}
log(LOG_DEBUG,"connection_edge_process_relay_cell(): Connected! Notifying application.");
@@ -209,7 +198,7 @@
break;
case RELAY_COMMAND_SENDME:
if(!conn) {
- log(LOG_DEBUG,"connection_edge_process_relay_cell(): sendme cell dropped, unknown stream %d.",stream_id);
+ log(LOG_DEBUG,"connection_edge_process_relay_cell(): sendme cell dropped, unknown stream %d.",*(int*)conn->stream_id);
return 0;
}
if(edge_type == EDGE_AP)
Index: connection_exit.c
===================================================================
RCS file: /home/or/cvsroot/src/or/connection_exit.c,v
retrieving revision 1.32
retrieving revision 1.33
diff -u -d -r1.32 -r1.33
--- connection_exit.c 1 May 2003 06:42:28 -0000 1.32
+++ connection_exit.c 2 May 2003 21:29:25 -0000 1.33
@@ -8,11 +8,11 @@
connection_t *n_conn;
char *colon;
- if(!memchr(cell->payload + RELAY_HEADER_SIZE,0,cell->length - RELAY_HEADER_SIZE)) {
+ if(!memchr(cell->payload+RELAY_HEADER_SIZE+STREAM_ID_SIZE,0,cell->length-RELAY_HEADER_SIZE-STREAM_ID_SIZE)) {
log(LOG_WARNING,"connection_exit_begin_conn(): relay begin cell has no \\0. Dropping.");
return 0;
}
- colon = strchr(cell->payload + RELAY_HEADER_SIZE, ':');
+ colon = strchr(cell->payload+RELAY_HEADER_SIZE+STREAM_ID_SIZE, ':');
if(!colon) {
log(LOG_WARNING,"connection_exit_begin_conn(): relay begin cell has no colon. Dropping.");
return 0;
@@ -31,10 +31,8 @@
return 0;
}
-// cell->payload[0] = 0;
- n_conn->stream_id = CELL_STREAM_ID(*cell);
-
- n_conn->address = strdup(cell->payload + RELAY_HEADER_SIZE);
+ memcpy(n_conn->stream_id, cell->payload + RELAY_HEADER_SIZE, STREAM_ID_SIZE);
+ n_conn->address = strdup(cell->payload + RELAY_HEADER_SIZE + STREAM_ID_SIZE);
n_conn->port = atoi(colon+1);
n_conn->state = EXIT_CONN_STATE_RESOLVING;
n_conn->receiver_bucket = -1; /* edge connections don't do receiver buckets */
Index: onion.c
===================================================================
RCS file: /home/or/cvsroot/src/or/onion.c,v
retrieving revision 1.41
retrieving revision 1.42
diff -u -d -r1.41 -r1.42
--- onion.c 1 May 2003 22:55:51 -0000 1.41
+++ onion.c 2 May 2003 21:29:25 -0000 1.42
@@ -141,13 +141,14 @@
}
-struct relay_queue_t *relay_queue_add(struct relay_queue_t *list, cell_t *cell) {
+struct relay_queue_t *relay_queue_add(struct relay_queue_t *list, cell_t *cell, crypt_path_t *layer_hint) {
struct relay_queue_t *tmpd, *newd;
newd = malloc(sizeof(struct relay_queue_t));
memset(newd, 0, sizeof(struct relay_queue_t));
newd->cell = malloc(sizeof(cell_t));
memcpy(newd->cell, cell, sizeof(cell_t));
+ newd->layer_hint = layer_hint;
if(!list) {
return newd;
@@ -167,7 +168,7 @@
for(tmpo=ol_list; tmpo; tmpo=tmpo->next) {
if(tmpo->circ == circ) {
- tmpo->relay_cells = relay_queue_add(tmpo->relay_cells, cell);
+ tmpo->relay_cells = relay_queue_add(tmpo->relay_cells, cell, NULL);
return;
}
}
Index: or.h
===================================================================
RCS file: /home/or/cvsroot/src/or/or.h,v
retrieving revision 1.70
retrieving revision 1.71
diff -u -d -r1.70 -r1.71
--- or.h 1 May 2003 22:55:51 -0000 1.70
+++ or.h 2 May 2003 21:29:25 -0000 1.71
@@ -128,7 +128,7 @@
#define RELAY_COMMAND_CONNECTED 4
#define RELAY_COMMAND_SENDME 5
-#define RELAY_HEADER_SIZE 4
+#define RELAY_HEADER_SIZE 8
#define RELAY_STATE_RESOLVING
@@ -195,15 +195,17 @@
typedef struct {
aci_t aci; /* Anonymous Connection Identifier */
unsigned char command;
- unsigned char length; /* of payload if relay cell, else value of sendme */
+ unsigned char length; /* of payload if relay cell */
uint32_t seq; /* sequence number */
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 CELL_STREAM_ID(c) ntohs(*(uint16_t*)((c).payload+2))
-#define SET_CELL_STREAM_ID(c,id) (*(uint16_t*)((c).payload+2) = htons(id))
+#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\0"
#define SOCKS4_REQUEST_GRANTED 90
#define SOCKS4_REQUEST_REJECT 91
@@ -265,8 +267,9 @@
uint16_t port;
/* used by exit and ap: */
- uint16_t stream_id;
+ char stream_id[STREAM_ID_SIZE];
struct connection_t *next_stream;
+ struct crypt_path_t *cpath_layer; /* a pointer to which node in the circ this conn exits at */
int n_receive_streamwindow;
int p_receive_streamwindow;
int done_sending;
@@ -335,7 +338,7 @@
void *next;
} routerinfo_t;
-typedef struct {
+struct crypt_path_t {
char digest2[20]; /* second SHA output for onion_layer_t.keyseed */
char digest3[20]; /* third SHA output for onion_layer_t.keyseed */
@@ -347,13 +350,16 @@
#define CPATH_STATE_CLOSED 0
#define CPATH_STATE_AWAITING_KEY 1
#define CPATH_STATE_OPEN 2
- void *next;
- void *prev; /* doubly linked list */
+ struct crypt_path_t *next;
+ struct crypt_path_t *prev; /* doubly linked list */
-} crypt_path_t;
+};
+
+typedef struct crypt_path_t crypt_path_t;
struct relay_queue_t {
cell_t *cell;
+ crypt_path_t *layer_hint;
struct relay_queue_t *next;
};
@@ -506,9 +512,13 @@
circuit_t *circuit_get_newest_ap(void);
circuit_t *circuit_enumerate_by_naddr_nport(circuit_t *start, uint32_t naddr, uint16_t nport);
-int circuit_deliver_relay_cell_from_edge(cell_t *cell, circuit_t *circ, char edge_type);
-int circuit_deliver_relay_cell(cell_t *cell, circuit_t *circ, int crypt_type);
-int circuit_crypt(circuit_t *circ, char *in, int inlen, char crypt_type);
+int circuit_deliver_relay_cell_from_edge(cell_t *cell, circuit_t *circ,
+ char edge_type, crypt_path_t *layer_hint);
+int circuit_deliver_relay_cell(cell_t *cell, circuit_t *circ,
+ int cell_direction, crypt_path_t *layer_hint);
+int relay_crypt(circuit_t *circ, char *in, int inlen, char cell_direction,
+ crypt_path_t *layer_hint, char *recognized, connection_t **conn);
+int relay_check_recognized(circuit_t *circ, int cell_direction, char *stream, connection_t **conn);
void circuit_resume_edge_reading(circuit_t *circ, int edge_type);
int circuit_consider_stop_edge_reading(circuit_t *circ, int edge_type);
@@ -645,7 +655,7 @@
int connection_edge_process_inbuf(connection_t *conn);
int connection_edge_send_command(connection_t *conn, circuit_t *circ, int relay_command);
-int connection_edge_process_relay_cell(cell_t *cell, circuit_t *circ, int edge_type);
+int connection_edge_process_relay_cell(cell_t *cell, circuit_t *circ, connection_t *conn, int edge_type);
int connection_edge_finished_flushing(connection_t *conn);
/********************************* connection_exit.c ***************************/
@@ -753,7 +763,7 @@
int onion_pending_check(void);
void onion_pending_process_one(void);
void onion_pending_remove(circuit_t *circ);
-struct relay_queue_t *relay_queue_add(struct relay_queue_t *list, cell_t *cell);
+struct relay_queue_t *relay_queue_add(struct relay_queue_t *list, cell_t *cell, crypt_path_t *layer_hint);
void onion_pending_relay_add(circuit_t *circ, cell_t *cell);
/* uses a weighted coin with weight cw to choose a route length */