[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
[or-cvs] fix design bug: circ->n_conn is shared among circs, so it c...
- To: or-cvs@freehaven.net
- Subject: [or-cvs] fix design bug: circ->n_conn is shared among circs, so it c...
- From: arma@seul.org (Roger Dingledine)
- Date: Tue, 27 May 2003 19:39:07 -0400 (EDT)
- Delivered-to: archiver@seul.org
- Delivered-to: or-cvs-outgoing@seul.org
- Delivered-to: or-cvs@seul.org
- Delivery-date: Tue, 27 May 2003 19:39:19 -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 connection_ap.c connection_exit.c or.h
Log Message:
fix design bug: circ->n_conn is shared among circs, so it can't
point to the streams for this circ.
Index: circuit.c
===================================================================
RCS file: /home/or/cvsroot/src/or/circuit.c,v
retrieving revision 1.45
retrieving revision 1.46
diff -u -d -r1.45 -r1.46
--- circuit.c 20 May 2003 06:53:10 -0000 1.45
+++ circuit.c 27 May 2003 23:39:04 -0000 1.46
@@ -173,13 +173,17 @@
for(circ=global_circuitlist;circ;circ = circ->next) {
if(circ->p_aci == aci) {
- for(tmpconn = circ->p_conn; tmpconn; tmpconn = tmpconn->next_stream) {
+ if(circ->p_conn == conn)
+ return circ;
+ for(tmpconn = circ->p_streams; tmpconn; tmpconn = tmpconn->next_stream) {
if(tmpconn == conn)
return circ;
}
}
if(circ->n_aci == aci) {
- for(tmpconn = circ->n_conn; tmpconn; tmpconn = tmpconn->next_stream) {
+ if(circ->n_conn == conn)
+ return circ;
+ for(tmpconn = circ->n_streams; tmpconn; tmpconn = tmpconn->next_stream) {
if(tmpconn == conn)
return circ;
}
@@ -193,10 +197,14 @@
connection_t *tmpconn;
for(circ=global_circuitlist;circ;circ = circ->next) {
- for(tmpconn = circ->p_conn; tmpconn; tmpconn=tmpconn->next_stream)
+ if(circ->p_conn == conn)
+ return circ;
+ if(circ->n_conn == conn)
+ return circ;
+ for(tmpconn = circ->p_streams; tmpconn; tmpconn=tmpconn->next_stream)
if(tmpconn == conn)
return circ;
- for(tmpconn = circ->n_conn; tmpconn; tmpconn=tmpconn->next_stream)
+ for(tmpconn = circ->n_streams; tmpconn; tmpconn=tmpconn->next_stream)
if(tmpconn == conn)
return circ;
}
@@ -280,7 +288,7 @@
else
conn = circ->p_conn;
- if(!conn || !connection_speaks_cells(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;
}
@@ -384,26 +392,20 @@
/* 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)) {
log(LOG_DEBUG,"relay_check_recognized(): It's the zero stream. Recognized.");
return 1; /* the zero stream is always recognized */
}
+ log(LOG_DEBUG,"relay_check_recognized(): not the zero stream.");
if(cell_direction == CELL_DIRECTION_OUT)
- tmpconn = circ->n_conn;
+ tmpconn = circ->n_streams;
else
- tmpconn = circ->p_conn;
+ tmpconn = circ->p_streams;
- log(LOG_DEBUG,"relay_check_recognized(): not the zero stream.");
if(!tmpconn) {
log(LOG_DEBUG,"relay_check_recognized(): No conns. Not recognized.");
- 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;
+ return 0;
}
for( ; tmpconn; tmpconn=tmpconn->next_stream) {
@@ -422,16 +424,15 @@
void circuit_resume_edge_reading(circuit_t *circ, int edge_type, crypt_path_t *layer_hint) {
connection_t *conn;
- struct relay_queue_t *relay, *victim;
assert(edge_type == EDGE_EXIT || edge_type == EDGE_AP);
log(LOG_DEBUG,"circuit_resume_edge_reading(): resuming");
if(edge_type == EDGE_EXIT)
- conn = circ->n_conn;
+ conn = circ->n_streams;
else
- conn = circ->p_conn;
+ conn = circ->p_streams;
for( ; conn; conn=conn->next_stream) {
if((edge_type == EDGE_EXIT && conn->package_window > 0) ||
@@ -452,9 +453,9 @@
log(LOG_DEBUG,"circuit_consider_stop_edge_reading(): considering");
if(edge_type == EDGE_EXIT && circ->package_window <= 0)
- conn = circ->n_conn;
+ conn = circ->n_streams;
else if(edge_type == EDGE_AP && layer_hint->package_window <= 0)
- conn = circ->p_conn;
+ conn = circ->p_streams;
else
return 0;
@@ -509,11 +510,15 @@
log(LOG_DEBUG,"circuit_close(): youngest %d, circ %d.",youngest,circ);
}
circuit_remove(circ);
- for(conn=circ->n_conn; conn; conn=conn->next_stream) {
- connection_send_destroy(circ->n_aci, circ->n_conn);
+ if(circ->n_conn)
+ connection_send_destroy(circ->n_aci, circ->n_conn);
+ for(conn=circ->n_streams; conn; conn=conn->next_stream) {
+ connection_send_destroy(circ->n_aci, conn);
}
- for(conn=circ->p_conn; conn; conn=conn->next_stream) {
- connection_send_destroy(circ->p_aci, circ->p_conn);
+ if(circ->p_conn)
+ connection_send_destroy(circ->n_aci, circ->p_conn);
+ for(conn=circ->p_streams; conn; conn=conn->next_stream) {
+ connection_send_destroy(circ->p_aci, conn);
}
if(options.APPort && youngest == circ) { /* check this after we've sent the destroys, to reduce races */
/* our current circuit just died. Launch another one pronto. */
@@ -541,20 +546,20 @@
if(!circ)
return;
- if(conn == circ->p_conn) {
- circ->p_conn = conn->next_stream;
+ if(conn == circ->p_streams) {
+ circ->p_streams = conn->next_stream;
goto send_end;
}
- if(conn == circ->n_conn) {
- circ->n_conn = conn->next_stream;
+ if(conn == circ->n_streams) {
+ circ->n_streams = conn->next_stream;
goto send_end;
}
- for(prevconn = circ->p_conn; prevconn->next_stream && prevconn->next_stream != conn; prevconn = prevconn->next_stream) ;
+ for(prevconn = circ->p_streams; prevconn->next_stream && prevconn->next_stream != conn; prevconn = prevconn->next_stream) ;
if(prevconn->next_stream) {
prevconn->next_stream = conn->next_stream;
goto send_end;
}
- for(prevconn = circ->n_conn; prevconn->next_stream && prevconn->next_stream != conn; prevconn = prevconn->next_stream) ;
+ for(prevconn = circ->n_streams; prevconn->next_stream && prevconn->next_stream != conn; prevconn = prevconn->next_stream) ;
if(prevconn->next_stream) {
prevconn->next_stream = conn->next_stream;
goto send_end;
@@ -585,13 +590,19 @@
connection_t *tmpconn;
for(circ=global_circuitlist;circ;circ = circ->next) {
- for(tmpconn=circ->p_conn; tmpconn; tmpconn=tmpconn->next_stream) {
+ if(circ->p_conn == conn)
+ printf("Conn %d has App-ward circuit: aci %d (other side %d), state %d (%s)\n",
+ conn->poll_index, circ->p_aci, circ->n_aci, circ->state, circuit_state_to_string[circ->state]);
+ for(tmpconn=circ->p_streams; tmpconn; tmpconn=tmpconn->next_stream) {
if(tmpconn == conn) {
printf("Conn %d has App-ward circuit: aci %d (other side %d), state %d (%s)\n",
conn->poll_index, circ->p_aci, circ->n_aci, circ->state, circuit_state_to_string[circ->state]);
}
}
- for(tmpconn=circ->n_conn; tmpconn; tmpconn=tmpconn->next_stream) {
+ if(circ->n_conn == conn)
+ printf("Conn %d has Exit-ward circuit: aci %d (other side %d), state %d (%s)\n",
+ conn->poll_index, circ->n_aci, circ->p_aci, circ->state, circuit_state_to_string[circ->state]);
+ for(tmpconn=circ->n_streams; tmpconn; tmpconn=tmpconn->next_stream) {
if(tmpconn == conn) {
printf("Conn %d has Exit-ward circuit: aci %d (other side %d), state %d (%s)\n",
conn->poll_index, circ->n_aci, circ->p_aci, circ->state, circuit_state_to_string[circ->state]);
@@ -807,6 +818,11 @@
aci_t aci_type;
struct sockaddr_in me; /* my router identity */
cell_t newcell;
+
+ if(circ->n_conn) {
+ log(LOG_WARNING,"circuit_extend(): n_conn already set. Bug/attack. Closing.");
+ 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));
Index: connection_ap.c
===================================================================
RCS file: /home/or/cvsroot/src/or/connection_ap.c,v
retrieving revision 1.42
retrieving revision 1.43
diff -u -d -r1.42 -r1.43
--- connection_ap.c 20 May 2003 06:41:22 -0000 1.42
+++ connection_ap.c 27 May 2003 23:39:04 -0000 1.43
@@ -102,8 +102,8 @@
/* add it into the linked list of streams on this circuit */
log(LOG_DEBUG,"ap_handshake_process_socks(): attaching new conn to circ. n_aci %d.", circ->n_aci);
- conn->next_stream = circ->p_conn;
- circ->p_conn = conn;
+ conn->next_stream = circ->p_streams;
+ circ->p_streams = conn;
assert(circ->cpath && circ->cpath->prev);
assert(circ->cpath->prev->state == CPATH_STATE_OPEN);
Index: connection_exit.c
===================================================================
RCS file: /home/or/cvsroot/src/or/connection_exit.c,v
retrieving revision 1.34
retrieving revision 1.35
diff -u -d -r1.34 -r1.35
--- connection_exit.c 20 May 2003 06:41:22 -0000 1.34
+++ connection_exit.c 27 May 2003 23:39:04 -0000 1.35
@@ -5,7 +5,7 @@
#include "or.h"
int connection_exit_begin_conn(cell_t *cell, circuit_t *circ) {
- connection_t *n_conn;
+ connection_t *n_stream;
char *colon;
if(!memchr(cell->payload+RELAY_HEADER_SIZE+STREAM_ID_SIZE,0,cell->length-RELAY_HEADER_SIZE-STREAM_ID_SIZE)) {
@@ -25,36 +25,36 @@
}
log(LOG_DEBUG,"connection_exit_begin_conn(): Creating new exit connection.");
- n_conn = connection_new(CONN_TYPE_EXIT);
- if(!n_conn) {
+ n_stream = connection_new(CONN_TYPE_EXIT);
+ if(!n_stream) {
log(LOG_DEBUG,"connection_exit_begin_conn(): connection_new failed. Dropping.");
return 0;
}
- 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 */
- n_conn->bandwidth = -1;
- n_conn->s = -1; /* not yet valid */
- n_conn->package_window = STREAMWINDOW_START;
- n_conn->deliver_window = STREAMWINDOW_START;
- if(connection_add(n_conn) < 0) { /* no space, forget it */
+ memcpy(n_stream->stream_id, cell->payload + RELAY_HEADER_SIZE, STREAM_ID_SIZE);
+ n_stream->address = strdup(cell->payload + RELAY_HEADER_SIZE + STREAM_ID_SIZE);
+ n_stream->port = atoi(colon+1);
+ n_stream->state = EXIT_CONN_STATE_RESOLVING;
+ n_stream->receiver_bucket = -1; /* edge connections don't do receiver buckets */
+ n_stream->bandwidth = -1;
+ n_stream->s = -1; /* not yet valid */
+ n_stream->package_window = STREAMWINDOW_START;
+ n_stream->deliver_window = STREAMWINDOW_START;
+ if(connection_add(n_stream) < 0) { /* no space, forget it */
log(LOG_DEBUG,"connection_exit_begin_conn(): connection_add failed. Dropping.");
- connection_free(n_conn);
+ connection_free(n_stream);
return 0;
}
/* add it into the linked list of streams on this circuit */
- n_conn->next_stream = circ->n_conn;
- circ->n_conn = n_conn;
+ n_stream->next_stream = circ->n_streams;
+ circ->n_streams = n_stream;
/* send it off to the gethostbyname farm */
- if(dns_resolve(n_conn) < 0) {
+ if(dns_resolve(n_stream) < 0) {
log(LOG_DEBUG,"connection_exit_begin_conn(): Couldn't queue resolve request.");
- connection_remove(n_conn);
- connection_free(n_conn);
+ connection_remove(n_stream);
+ connection_free(n_stream);
return 0;
}
Index: or.h
===================================================================
RCS file: /home/or/cvsroot/src/or/or.h,v
retrieving revision 1.86
retrieving revision 1.87
diff -u -d -r1.86 -r1.87
--- or.h 20 May 2003 06:53:10 -0000 1.86
+++ or.h 27 May 2003 23:39:04 -0000 1.87
@@ -362,7 +362,9 @@
uint32_t n_addr;
uint16_t n_port;
connection_t *p_conn;
- connection_t *n_conn; /* convention: first conn is the OR conn, if there is one */
+ connection_t *n_conn; /* for the OR conn, if there is one */
+ connection_t *p_streams;
+ connection_t *n_streams;
int package_window;
int deliver_window;