terminology shift: data->relay, topic->relay, topic->stream

svn:r258
This commit is contained in:
Roger Dingledine 2003-05-01 06:42:29 +00:00
parent 6af79f3a03
commit 0560008497
9 changed files with 248 additions and 247 deletions

View File

@ -54,8 +54,8 @@ int read_to_buf(int s, int at_most, char **buf, int *buflen, int *buf_datalen, i
/* if no linkpadding: do a rudimentary round-robin so one /* if no linkpadding: do a rudimentary round-robin so one
* connection can't hog a thickpipe * connection can't hog a thickpipe
*/ */
at_most = 10*(CELL_PAYLOAD_SIZE - TOPIC_HEADER_SIZE); at_most = 10*(CELL_PAYLOAD_SIZE - RELAY_HEADER_SIZE);
/* XXX this still isn't perfect. now we read 10 data payloads per read -- /* XXX this still isn't perfect. now we read 10 relay data payloads per read --
* but if we're reading from a connection that speaks cells, we always * but if we're reading from a connection that speaks cells, we always
* read a partial cell from the network and can't process it yet. Good * read a partial cell from the network and can't process it yet. Good
* enough for now though. (And maybe best, to stress our code more.) * enough for now though. (And maybe best, to stress our code more.)

View File

@ -80,7 +80,7 @@ circuit_t *circuit_new(aci_t p_aci, connection_t *p_conn) {
} }
void circuit_free(circuit_t *circ) { void circuit_free(circuit_t *circ) {
struct data_queue_t *tmpd; struct relay_queue_t *tmpd;
if (circ->n_crypto) if (circ->n_crypto)
crypto_free_cipher_env(circ->n_crypto); crypto_free_cipher_env(circ->n_crypto);
@ -91,9 +91,9 @@ void circuit_free(circuit_t *circ) {
free(circ->onion); free(circ->onion);
if(circ->cpath) if(circ->cpath)
circuit_free_cpath(circ->cpath, circ->cpathlen); circuit_free_cpath(circ->cpath, circ->cpathlen);
while(circ->data_queue) { while(circ->relay_queue) {
tmpd = circ->data_queue; tmpd = circ->relay_queue;
circ->data_queue = tmpd->next; circ->relay_queue = tmpd->next;
free(tmpd->cell); free(tmpd->cell);
free(tmpd); free(tmpd);
} }
@ -220,13 +220,13 @@ circuit_t *circuit_get_by_aci_conn(aci_t aci, connection_t *conn) {
for(circ=global_circuitlist;circ;circ = circ->next) { for(circ=global_circuitlist;circ;circ = circ->next) {
if(circ->p_aci == aci) { if(circ->p_aci == aci) {
for(tmpconn = circ->p_conn; tmpconn; tmpconn = tmpconn->next_topic) { for(tmpconn = circ->p_conn; tmpconn; tmpconn = tmpconn->next_stream) {
if(tmpconn == conn) if(tmpconn == conn)
return circ; return circ;
} }
} }
if(circ->n_aci == aci) { if(circ->n_aci == aci) {
for(tmpconn = circ->n_conn; tmpconn; tmpconn = tmpconn->next_topic) { for(tmpconn = circ->n_conn; tmpconn; tmpconn = tmpconn->next_stream) {
if(tmpconn == conn) if(tmpconn == conn)
return circ; return circ;
} }
@ -240,10 +240,10 @@ circuit_t *circuit_get_by_conn(connection_t *conn) {
connection_t *tmpconn; connection_t *tmpconn;
for(circ=global_circuitlist;circ;circ = circ->next) { for(circ=global_circuitlist;circ;circ = circ->next) {
for(tmpconn = circ->p_conn; tmpconn; tmpconn=tmpconn->next_topic) for(tmpconn = circ->p_conn; tmpconn; tmpconn=tmpconn->next_stream)
if(tmpconn == conn) if(tmpconn == conn)
return circ; return circ;
for(tmpconn = circ->n_conn; tmpconn; tmpconn=tmpconn->next_topic) for(tmpconn = circ->n_conn; tmpconn; tmpconn=tmpconn->next_stream)
if(tmpconn == conn) if(tmpconn == conn)
return circ; return circ;
} }
@ -271,36 +271,36 @@ circuit_t *circuit_get_newest_by_edge_type(char edge_type) {
return bestcirc; return bestcirc;
} }
int circuit_deliver_data_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) {
int cell_direction; int cell_direction;
static int numsent_ap=0, numsent_exit=0; static int numsent_ap=0, numsent_exit=0;
log(LOG_DEBUG,"circuit_deliver_data_cell_from_edge(): called, edge_type %d.", edge_type); log(LOG_DEBUG,"circuit_deliver_relay_cell_from_edge(): called, edge_type %d.", edge_type);
if(edge_type == EDGE_AP) { /* i'm the AP */ if(edge_type == EDGE_AP) { /* i'm the AP */
cell_direction = CELL_DIRECTION_OUT; cell_direction = CELL_DIRECTION_OUT;
numsent_ap++; numsent_ap++;
log(LOG_DEBUG,"circuit_deliver_data_cell_from_edge(): now sent %d data cells from ap", numsent_ap); log(LOG_DEBUG,"circuit_deliver_relay_cell_from_edge(): now sent %d relay cells from ap", numsent_ap);
if(circ->p_receive_circwindow <= 0) { if(circ->p_receive_circwindow <= 0) {
log(LOG_DEBUG,"circuit_deliver_data_cell_from_edge(): pwindow 0, queueing for later."); log(LOG_DEBUG,"circuit_deliver_relay_cell_from_edge(): pwindow 0, queueing for later.");
circ->data_queue = data_queue_add(circ->data_queue, cell); circ->relay_queue = relay_queue_add(circ->relay_queue, cell);
return 0; return 0;
} }
circ->p_receive_circwindow--; circ->p_receive_circwindow--;
// log(LOG_INFO,"circuit_deliver_data_cell_from_edge(): p_receive_circwindow now %d.",circ->p_receive_circwindow); // log(LOG_INFO,"circuit_deliver_relay_cell_from_edge(): p_receive_circwindow now %d.",circ->p_receive_circwindow);
} else { /* i'm the exit */ } else { /* i'm the exit */
cell_direction = CELL_DIRECTION_IN; cell_direction = CELL_DIRECTION_IN;
numsent_exit++; numsent_exit++;
log(LOG_DEBUG,"circuit_deliver_data_cell_from_edge(): now sent %d data cells from exit", numsent_exit); log(LOG_DEBUG,"circuit_deliver_relay_cell_from_edge(): now sent %d relay cells from exit", numsent_exit);
if(circ->n_receive_circwindow <= 0) { if(circ->n_receive_circwindow <= 0) {
log(LOG_DEBUG,"circuit_deliver_data_cell_from_edge(): nwindow 0, queueing for later."); log(LOG_DEBUG,"circuit_deliver_relay_cell_from_edge(): nwindow 0, queueing for later.");
circ->data_queue = data_queue_add(circ->data_queue, cell); circ->relay_queue = relay_queue_add(circ->relay_queue, cell);
return 0; return 0;
} }
circ->n_receive_circwindow--; circ->n_receive_circwindow--;
} }
if(circuit_deliver_data_cell(cell, circ, cell_direction) < 0) { if(circuit_deliver_relay_cell(cell, circ, cell_direction) < 0) {
return -1; return -1;
} }
@ -308,7 +308,7 @@ int circuit_deliver_data_cell_from_edge(cell_t *cell, circuit_t *circ, char edge
return 0; return 0;
} }
int circuit_deliver_data_cell(cell_t *cell, circuit_t *circ, int cell_direction) { int circuit_deliver_relay_cell(cell_t *cell, circuit_t *circ, int cell_direction) {
connection_t *conn; connection_t *conn;
assert(cell && circ); assert(cell && circ);
@ -320,27 +320,27 @@ int circuit_deliver_data_cell(cell_t *cell, circuit_t *circ, int cell_direction)
/* first crypt cell->length */ /* first crypt cell->length */
if(circuit_crypt(circ, &(cell->length), 1, cell_direction) < 0) { if(circuit_crypt(circ, &(cell->length), 1, cell_direction) < 0) {
log(LOG_DEBUG,"circuit_deliver_data_cell(): length crypt failed. Dropping connection."); log(LOG_DEBUG,"circuit_deliver_relay_cell(): length crypt failed. Dropping connection.");
return -1; return -1;
} }
/* then crypt the payload */ /* then crypt the payload */
if(circuit_crypt(circ, (char *)&(cell->payload), CELL_PAYLOAD_SIZE, cell_direction) < 0) { if(circuit_crypt(circ, (char *)&(cell->payload), CELL_PAYLOAD_SIZE, cell_direction) < 0) {
log(LOG_DEBUG,"circuit_deliver_data_cell(): payload crypt failed. Dropping connection."); log(LOG_DEBUG,"circuit_deliver_relay_cell(): payload crypt failed. Dropping connection.");
return -1; return -1;
} }
if(cell_direction == CELL_DIRECTION_OUT && (!conn || conn->type == CONN_TYPE_EXIT)) { if(cell_direction == CELL_DIRECTION_OUT && (!conn || conn->type == CONN_TYPE_EXIT)) {
log(LOG_DEBUG,"circuit_deliver_data_cell(): Sending to exit."); log(LOG_DEBUG,"circuit_deliver_relay_cell(): Sending to exit.");
return connection_edge_process_data_cell(cell, circ, EDGE_EXIT); return connection_edge_process_relay_cell(cell, circ, EDGE_EXIT);
} }
if(cell_direction == CELL_DIRECTION_IN && (!conn || conn->type == CONN_TYPE_AP)) { if(cell_direction == CELL_DIRECTION_IN && (!conn || conn->type == CONN_TYPE_AP)) {
log(LOG_DEBUG,"circuit_deliver_data_cell(): Sending to AP."); log(LOG_DEBUG,"circuit_deliver_relay_cell(): Sending to AP.");
return connection_edge_process_data_cell(cell, circ, EDGE_AP); return connection_edge_process_relay_cell(cell, circ, EDGE_AP);
} }
/* else send it as a cell */ /* else send it as a cell */
assert(conn); assert(conn);
//log(LOG_DEBUG,"circuit_deliver_data_cell(): Sending to connection."); //log(LOG_DEBUG,"circuit_deliver_relay_cell(): Sending to connection.");
return connection_write_cell_to_buf(cell, conn); return connection_write_cell_to_buf(cell, conn);
} }
@ -420,18 +420,18 @@ int circuit_crypt(circuit_t *circ, char *in, int inlen, char cell_direction) {
void circuit_resume_edge_reading(circuit_t *circ, int edge_type) { void circuit_resume_edge_reading(circuit_t *circ, int edge_type) {
connection_t *conn; connection_t *conn;
struct data_queue_t *tmpd; struct relay_queue_t *tmpd;
assert(edge_type == EDGE_EXIT || edge_type == EDGE_AP); assert(edge_type == EDGE_EXIT || edge_type == EDGE_AP);
/* first, send the queue waiting at circ onto the circuit */ /* first, send the queue waiting at circ onto the circuit */
while(circ->data_queue) { while(circ->relay_queue) {
assert(circ->data_queue->cell); assert(circ->relay_queue->cell);
if(edge_type == EDGE_EXIT) { if(edge_type == EDGE_EXIT) {
circ->n_receive_circwindow--; circ->n_receive_circwindow--;
assert(circ->n_receive_circwindow >= 0); assert(circ->n_receive_circwindow >= 0);
if(circuit_deliver_data_cell(circ->data_queue->cell, circ, CELL_DIRECTION_IN) < 0) { if(circuit_deliver_relay_cell(circ->relay_queue->cell, circ, CELL_DIRECTION_IN) < 0) {
circuit_close(circ); circuit_close(circ);
return; return;
} }
@ -439,13 +439,13 @@ void circuit_resume_edge_reading(circuit_t *circ, int edge_type) {
circ->p_receive_circwindow--; circ->p_receive_circwindow--;
assert(circ->p_receive_circwindow >= 0); assert(circ->p_receive_circwindow >= 0);
if(circuit_deliver_data_cell(circ->data_queue->cell, circ, CELL_DIRECTION_OUT) < 0) { if(circuit_deliver_relay_cell(circ->relay_queue->cell, circ, CELL_DIRECTION_OUT) < 0) {
circuit_close(circ); circuit_close(circ);
return; return;
} }
} }
tmpd = circ->data_queue; tmpd = circ->relay_queue;
circ->data_queue = tmpd->next; circ->relay_queue = tmpd->next;
free(tmpd->cell); free(tmpd->cell);
free(tmpd); free(tmpd);
@ -458,9 +458,9 @@ void circuit_resume_edge_reading(circuit_t *circ, int edge_type) {
else else
conn = circ->p_conn; conn = circ->p_conn;
for( ; conn; conn=conn->next_topic) { for( ; conn; conn=conn->next_stream) {
if((edge_type == EDGE_EXIT && conn->n_receive_topicwindow > 0) || if((edge_type == EDGE_EXIT && conn->n_receive_streamwindow > 0) ||
(edge_type == EDGE_AP && conn->p_receive_topicwindow > 0)) { (edge_type == EDGE_AP && conn->p_receive_streamwindow > 0)) {
connection_start_reading(conn); connection_start_reading(conn);
connection_package_raw_inbuf(conn); /* handle whatever might still be on the inbuf */ connection_package_raw_inbuf(conn); /* handle whatever might still be on the inbuf */
} }
@ -481,7 +481,7 @@ int circuit_consider_stop_edge_reading(circuit_t *circ, int edge_type) {
else else
return 0; return 0;
for( ; conn; conn=conn->next_topic) for( ; conn; conn=conn->next_stream)
connection_stop_reading(conn); connection_stop_reading(conn);
return 1; return 1;
@ -528,10 +528,10 @@ void circuit_close(circuit_t *circ) {
log(LOG_DEBUG,"circuit_close(): youngest %d, circ %d.",youngest,circ); log(LOG_DEBUG,"circuit_close(): youngest %d, circ %d.",youngest,circ);
} }
circuit_remove(circ); circuit_remove(circ);
for(conn=circ->n_conn; conn; conn=conn->next_topic) { for(conn=circ->n_conn; conn; conn=conn->next_stream) {
connection_send_destroy(circ->n_aci, circ->n_conn); connection_send_destroy(circ->n_aci, circ->n_conn);
} }
for(conn=circ->p_conn; conn; conn=conn->next_topic) { for(conn=circ->p_conn; conn; conn=conn->next_stream) {
connection_send_destroy(circ->p_aci, circ->p_conn); connection_send_destroy(circ->p_aci, circ->p_conn);
} }
if(options.APPort && youngest == circ) { /* check this after we've sent the destroys, to reduce races */ if(options.APPort && youngest == circ) { /* check this after we've sent the destroys, to reduce races */
@ -552,7 +552,7 @@ void circuit_about_to_close_connection(connection_t *conn) {
if(!connection_speaks_cells(conn)) { if(!connection_speaks_cells(conn)) {
/* it's an edge conn. need to remove it from the linked list of /* it's an edge conn. need to remove it from the linked list of
* conn's for this circuit. Send an 'end' data topic. * conn's for this circuit. Send an 'end' relay command.
* But don't kill the circuit. * But don't kill the circuit.
*/ */
@ -561,27 +561,27 @@ void circuit_about_to_close_connection(connection_t *conn) {
return; return;
if(conn == circ->p_conn) { if(conn == circ->p_conn) {
circ->p_conn = conn->next_topic; circ->p_conn = conn->next_stream;
goto send_end; goto send_end;
} }
if(conn == circ->n_conn) { if(conn == circ->n_conn) {
circ->n_conn = conn->next_topic; circ->n_conn = conn->next_stream;
goto send_end; goto send_end;
} }
for(prevconn = circ->p_conn; prevconn->next_topic && prevconn->next_topic != conn; prevconn = prevconn->next_topic) ; for(prevconn = circ->p_conn; prevconn->next_stream && prevconn->next_stream != conn; prevconn = prevconn->next_stream) ;
if(prevconn->next_topic) { if(prevconn->next_stream) {
prevconn->next_topic = conn->next_topic; prevconn->next_stream = conn->next_stream;
goto send_end; goto send_end;
} }
for(prevconn = circ->n_conn; prevconn->next_topic && prevconn->next_topic != conn; prevconn = prevconn->next_topic) ; for(prevconn = circ->n_conn; prevconn->next_stream && prevconn->next_stream != conn; prevconn = prevconn->next_stream) ;
if(prevconn->next_topic) { if(prevconn->next_stream) {
prevconn->next_topic = conn->next_topic; prevconn->next_stream = conn->next_stream;
goto send_end; goto send_end;
} }
log(LOG_ERR,"circuit_about_to_close_connection(): edge conn not in circuit's list?"); log(LOG_ERR,"circuit_about_to_close_connection(): edge conn not in circuit's list?");
assert(0); /* should never get here */ assert(0); /* should never get here */
send_end: send_end:
if(connection_edge_send_command(conn, circ, TOPIC_COMMAND_END) < 0) { if(connection_edge_send_command(conn, circ, RELAY_COMMAND_END) < 0) {
log(LOG_DEBUG,"circuit_about_to_close_connection(): sending end failed. Closing."); log(LOG_DEBUG,"circuit_about_to_close_connection(): sending end failed. Closing.");
circuit_close(circ); circuit_close(circ);
} }
@ -604,13 +604,13 @@ void circuit_dump_by_conn(connection_t *conn) {
connection_t *tmpconn; connection_t *tmpconn;
for(circ=global_circuitlist;circ;circ = circ->next) { for(circ=global_circuitlist;circ;circ = circ->next) {
for(tmpconn=circ->p_conn; tmpconn; tmpconn=tmpconn->next_topic) { for(tmpconn=circ->p_conn; tmpconn; tmpconn=tmpconn->next_stream) {
if(tmpconn == conn) { if(tmpconn == conn) {
printf("Conn %d has App-ward circuit: aci %d (other side %d), state %d (%s)\n", 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]); 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_topic) { for(tmpconn=circ->n_conn; tmpconn; tmpconn=tmpconn->next_stream) {
if(tmpconn == conn) { if(tmpconn == conn) {
printf("Conn %d has Exit-ward circuit: aci %d (other side %d), state %d (%s)\n", 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]); conn->poll_index, circ->n_aci, circ->p_aci, circ->state, circuit_state_to_string[circ->state]);

View File

@ -28,8 +28,8 @@ void command_time_process_cell(cell_t *cell, connection_t *conn,
} }
void command_process_cell(cell_t *cell, connection_t *conn) { void command_process_cell(cell_t *cell, connection_t *conn) {
static int num_create=0, num_data=0, num_destroy=0, num_sendme=0; static int num_create=0, num_relay=0, num_destroy=0, num_sendme=0;
static int create_time=0, data_time=0, destroy_time=0, sendme_time=0; static int create_time=0, relay_time=0, destroy_time=0, sendme_time=0;
static long current_second = 0; /* from previous calls to gettimeofday */ static long current_second = 0; /* from previous calls to gettimeofday */
struct timeval now; struct timeval now;
@ -39,13 +39,13 @@ void command_process_cell(cell_t *cell, connection_t *conn) {
/* print stats */ /* print stats */
log(LOG_INFO,"At end of second:"); log(LOG_INFO,"At end of second:");
log(LOG_INFO,"Create: %d (%d ms)", num_create, create_time/1000); log(LOG_INFO,"Create: %d (%d ms)", num_create, create_time/1000);
log(LOG_INFO,"Data: %d (%d ms)", num_data, data_time/1000); log(LOG_INFO,"Relay: %d (%d ms)", num_relay, relay_time/1000);
log(LOG_INFO,"Destroy: %d (%d ms)", num_destroy, destroy_time/1000); log(LOG_INFO,"Destroy: %d (%d ms)", num_destroy, destroy_time/1000);
log(LOG_INFO,"Sendme: %d (%d ms)", num_sendme, sendme_time/1000); log(LOG_INFO,"Sendme: %d (%d ms)", num_sendme, sendme_time/1000);
/* zero out stats */ /* zero out stats */
num_create = num_data = num_destroy = num_sendme = 0; num_create = num_relay = num_destroy = num_sendme = 0;
create_time = data_time = destroy_time = sendme_time = 0; create_time = relay_time = destroy_time = sendme_time = 0;
/* remember which second it is, for next time */ /* remember which second it is, for next time */
current_second = now.tv_sec; current_second = now.tv_sec;
@ -59,9 +59,9 @@ void command_process_cell(cell_t *cell, connection_t *conn) {
command_time_process_cell(cell, conn, &num_create, &create_time, command_time_process_cell(cell, conn, &num_create, &create_time,
command_process_create_cell); command_process_create_cell);
break; break;
case CELL_DATA: case CELL_RELAY:
command_time_process_cell(cell, conn, &num_data, &data_time, command_time_process_cell(cell, conn, &num_relay, &relay_time,
command_process_data_cell); command_process_relay_cell);
break; break;
case CELL_DESTROY: case CELL_DESTROY:
command_time_process_cell(cell, conn, &num_destroy, &destroy_time, command_time_process_cell(cell, conn, &num_destroy, &destroy_time,
@ -195,61 +195,61 @@ void command_process_sendme_cell(cell_t *cell, connection_t *conn) {
} }
} }
void command_process_data_cell(cell_t *cell, connection_t *conn) { void command_process_relay_cell(cell_t *cell, connection_t *conn) {
circuit_t *circ; circuit_t *circ;
circ = circuit_get_by_aci_conn(cell->aci, conn); circ = circuit_get_by_aci_conn(cell->aci, conn);
if(!circ) { if(!circ) {
log(LOG_DEBUG,"command_process_data_cell(): unknown circuit %d. Dropping.", cell->aci); log(LOG_DEBUG,"command_process_relay_cell(): unknown circuit %d. Dropping.", cell->aci);
return; return;
} }
if(circ->state == CIRCUIT_STATE_ONION_PENDING) { if(circ->state == CIRCUIT_STATE_ONION_PENDING) {
log(LOG_DEBUG,"command_process_data_cell(): circuit in create_wait. Queueing data cell."); log(LOG_DEBUG,"command_process_relay_cell(): circuit in create_wait. Queueing relay cell.");
onion_pending_data_add(circ, cell); onion_pending_relay_add(circ, cell);
return; return;
} }
if(cell->aci == circ->p_aci) { /* it's an outgoing cell */ if(cell->aci == circ->p_aci) { /* it's an outgoing cell */
if(--circ->p_receive_circwindow < 0) { /* is it less than 0 after decrement? */ if(--circ->p_receive_circwindow < 0) { /* is it less than 0 after decrement? */
log(LOG_INFO,"connection_process_data_cell(): Too many data cells for out circuit (aci %d). Closing.", circ->p_aci); log(LOG_INFO,"connection_process_relay_cell(): Too many relay cells for out circuit (aci %d). Closing.", circ->p_aci);
circuit_close(circ); circuit_close(circ);
return; return;
} }
log(LOG_DEBUG,"connection_process_data_cell(): p_receive_circwindow for aci %d is %d.",circ->p_aci,circ->p_receive_circwindow); log(LOG_DEBUG,"connection_process_relay_cell(): p_receive_circwindow for aci %d is %d.",circ->p_aci,circ->p_receive_circwindow);
} }
if(cell->aci == circ->n_aci) { /* it's an ingoing cell */ if(cell->aci == circ->n_aci) { /* it's an ingoing cell */
if(--circ->n_receive_circwindow < 0) { /* is it less than 0 after decrement? */ if(--circ->n_receive_circwindow < 0) { /* is it less than 0 after decrement? */
log(LOG_INFO,"connection_process_data_cell(): Too many data cells for in circuit (aci %d). Closing.", circ->n_aci); log(LOG_INFO,"connection_process_relay_cell(): Too many relay cells for in circuit (aci %d). Closing.", circ->n_aci);
circuit_close(circ); circuit_close(circ);
return; return;
} }
log(LOG_DEBUG,"connection_process_data_cell(): n_receive_circwindow for aci %d is %d.",circ->n_aci,circ->n_receive_circwindow); log(LOG_DEBUG,"connection_process_relay_cell(): n_receive_circwindow for aci %d is %d.",circ->n_aci,circ->n_receive_circwindow);
} }
if(circ->state == CIRCUIT_STATE_ONION_WAIT) { if(circ->state == CIRCUIT_STATE_ONION_WAIT) {
log(LOG_WARNING,"command_process_data_cell(): circuit in onion_wait. Dropping data cell."); log(LOG_WARNING,"command_process_relay_cell(): circuit in onion_wait. Dropping relay cell.");
return; return;
} }
if(circ->state == CIRCUIT_STATE_OR_WAIT) { if(circ->state == CIRCUIT_STATE_OR_WAIT) {
log(LOG_WARNING,"command_process_data_cell(): circuit in or_wait. Dropping data cell."); log(LOG_WARNING,"command_process_relay_cell(): circuit in or_wait. Dropping relay cell.");
return; return;
} }
/* circ->p_conn and n_conn are only null if we're at an edge point with no connections yet */ /* circ->p_conn and n_conn are only null if we're at an edge point with no connections yet */
if(cell->aci == circ->p_aci) { /* it's an outgoing cell */ if(cell->aci == circ->p_aci) { /* it's an outgoing cell */
cell->aci = circ->n_aci; /* switch it */ cell->aci = circ->n_aci; /* switch it */
if(circuit_deliver_data_cell(cell, circ, CELL_DIRECTION_OUT) < 0) { if(circuit_deliver_relay_cell(cell, circ, CELL_DIRECTION_OUT) < 0) {
log(LOG_INFO,"command_process_data_cell(): circuit_deliver_data_cell (forward) failed. Closing."); log(LOG_INFO,"command_process_relay_cell(): circuit_deliver_relay_cell (forward) failed. Closing.");
circuit_close(circ); circuit_close(circ);
return; return;
} }
} else { /* it's an ingoing cell */ } else { /* it's an ingoing cell */
cell->aci = circ->p_aci; /* switch it */ cell->aci = circ->p_aci; /* switch it */
if(circuit_deliver_data_cell(cell, circ, CELL_DIRECTION_IN) < 0) { if(circuit_deliver_relay_cell(cell, circ, CELL_DIRECTION_IN) < 0) {
log(LOG_DEBUG,"command_process_data_cell(): circuit_deliver_data_cell (backward) failed. Closing."); log(LOG_DEBUG,"command_process_relay_cell(): circuit_deliver_relay_cell (backward) failed. Closing.");
circuit_close(circ); circuit_close(circ);
return; return;
} }

View File

@ -283,6 +283,7 @@ int retry_all_connections(uint16_t or_listenport,
if(ap_listenport) { if(ap_listenport) {
bindaddr.sin_port = htons(ap_listenport); bindaddr.sin_port = htons(ap_listenport);
inet_aton("127.0.0.1", &(bindaddr.sin_addr)); /* the AP listens only on localhost! */ inet_aton("127.0.0.1", &(bindaddr.sin_addr)); /* the AP listens only on localhost! */
/* XXX inet_aton is missing on solaris. use something simpler? */
if(!connection_get_by_type(CONN_TYPE_AP_LISTENER)) { if(!connection_get_by_type(CONN_TYPE_AP_LISTENER)) {
connection_ap_create_listener(&bindaddr); connection_ap_create_listener(&bindaddr);
} }
@ -652,7 +653,7 @@ int connection_package_raw_inbuf(connection_t *conn) {
assert(conn); assert(conn);
assert(!connection_speaks_cells(conn)); assert(!connection_speaks_cells(conn));
/* this function should never get called if the receive_topicwindow is 0 */ /* this function should never get called if the receive_streamwindow is 0 */
repeat_connection_package_raw_inbuf: repeat_connection_package_raw_inbuf:
@ -670,21 +671,21 @@ repeat_connection_package_raw_inbuf:
* compressing. * compressing.
* 2) * 2)
*/ */
len = connection_compress_from_buf(cell.payload+TOPIC_HEADER_SIZE, len = connection_compress_from_buf(cell.payload+RELAY_HEADER_SIZE,
CELL_PAYLOAD_SIZE - TOPIC_HEADER_SIZE, CELL_PAYLOAD_SIZE - RELAY_HEADER_SIZE,
conn, Z_SYNC_FLUSH); conn, Z_SYNC_FLUSH);
if (len < 0) if (len < 0)
return -1; return -1;
cell.length = len; cell.length = len;
#else #else
if(amount_to_process > CELL_PAYLOAD_SIZE - TOPIC_HEADER_SIZE) { if(amount_to_process > CELL_PAYLOAD_SIZE - RELAY_HEADER_SIZE) {
cell.length = CELL_PAYLOAD_SIZE - TOPIC_HEADER_SIZE; cell.length = CELL_PAYLOAD_SIZE - RELAY_HEADER_SIZE;
} else { } else {
cell.length = amount_to_process; cell.length = amount_to_process;
} }
if(connection_fetch_from_buf(cell.payload+TOPIC_HEADER_SIZE, if(connection_fetch_from_buf(cell.payload+RELAY_HEADER_SIZE,
cell.length, conn) < 0) cell.length, conn) < 0)
return -1; return -1;
#endif #endif
@ -698,40 +699,40 @@ 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); log(LOG_DEBUG,"connection_package_raw_inbuf(): (%d) Packaging %d bytes (%d waiting).",conn->s,cell.length, conn->inbuf_datalen);
cell.command = CELL_DATA; cell.command = CELL_RELAY;
SET_CELL_TOPIC_COMMAND(cell, TOPIC_COMMAND_DATA); SET_CELL_RELAY_COMMAND(cell, RELAY_COMMAND_DATA);
SET_CELL_TOPIC_ID(cell, conn->topic_id); SET_CELL_STREAM_ID(cell, conn->stream_id);
cell.length += TOPIC_HEADER_SIZE; cell.length += RELAY_HEADER_SIZE;
if(conn->type == CONN_TYPE_EXIT) { if(conn->type == CONN_TYPE_EXIT) {
cell.aci = circ->p_aci; cell.aci = circ->p_aci;
if(circuit_deliver_data_cell_from_edge(&cell, circ, EDGE_EXIT) < 0) { if(circuit_deliver_relay_cell_from_edge(&cell, circ, EDGE_EXIT) < 0) {
log(LOG_DEBUG,"connection_package_raw_inbuf(): circuit_deliver_data_cell_from_edge (backward) failed. Closing."); log(LOG_DEBUG,"connection_package_raw_inbuf(): circuit_deliver_relay_cell_from_edge (backward) failed. Closing.");
circuit_close(circ); circuit_close(circ);
return 0; return 0;
} }
assert(conn->n_receive_topicwindow > 0); assert(conn->n_receive_streamwindow > 0);
if(--conn->n_receive_topicwindow <= 0) { /* is it 0 after decrement? */ if(--conn->n_receive_streamwindow <= 0) { /* is it 0 after decrement? */
connection_stop_reading(conn); connection_stop_reading(conn);
log(LOG_DEBUG,"connection_package_raw_inbuf(): receive_topicwindow at exit reached 0."); log(LOG_DEBUG,"connection_package_raw_inbuf(): receive_streamwindow at exit reached 0.");
return 0; /* don't process the inbuf any more */ return 0; /* don't process the inbuf any more */
} }
log(LOG_DEBUG,"connection_package_raw_inbuf(): receive_topicwindow at exit is %d",conn->n_receive_topicwindow); log(LOG_DEBUG,"connection_package_raw_inbuf(): receive_streamwindow at exit is %d",conn->n_receive_streamwindow);
} else { /* send it forward. we're an AP */ } else { /* send it forward. we're an AP */
assert(conn->type == CONN_TYPE_AP); assert(conn->type == CONN_TYPE_AP);
cell.aci = circ->n_aci; cell.aci = circ->n_aci;
if(circuit_deliver_data_cell_from_edge(&cell, circ, EDGE_AP) < 0) { if(circuit_deliver_relay_cell_from_edge(&cell, circ, EDGE_AP) < 0) {
log(LOG_DEBUG,"connection_package_raw_inbuf(): circuit_deliver_data_cell_from_edge (forward) failed. Closing."); log(LOG_DEBUG,"connection_package_raw_inbuf(): circuit_deliver_relay_cell_from_edge (forward) failed. Closing.");
circuit_close(circ); circuit_close(circ);
return 0; return 0;
} }
assert(conn->p_receive_topicwindow > 0); assert(conn->p_receive_streamwindow > 0);
if(--conn->p_receive_topicwindow <= 0) { /* is it 0 after decrement? */ if(--conn->p_receive_streamwindow <= 0) { /* is it 0 after decrement? */
connection_stop_reading(conn); connection_stop_reading(conn);
log(LOG_DEBUG,"connection_package_raw_inbuf(): receive_topicwindow at AP reached 0."); log(LOG_DEBUG,"connection_package_raw_inbuf(): receive_streamwindow at AP reached 0.");
return 0; /* don't process the inbuf any more */ return 0; /* don't process the inbuf any more */
} }
log(LOG_DEBUG,"connection_package_raw_inbuf(): receive_topicwindow at AP is %d",conn->p_receive_topicwindow); log(LOG_DEBUG,"connection_package_raw_inbuf(): receive_streamwindow at AP is %d",conn->p_receive_streamwindow);
} }
/* handle more if there's more, or return 0 if there isn't */ /* handle more if there's more, or return 0 if there isn't */
goto repeat_connection_package_raw_inbuf; goto repeat_connection_package_raw_inbuf;
@ -752,30 +753,30 @@ int connection_consider_sending_sendme(connection_t *conn, int edge_type) {
} }
memset(&cell, 0, sizeof(cell_t)); memset(&cell, 0, sizeof(cell_t));
cell.command = CELL_DATA; cell.command = CELL_RELAY;
SET_CELL_TOPIC_COMMAND(cell, TOPIC_COMMAND_SENDME); SET_CELL_RELAY_COMMAND(cell, RELAY_COMMAND_SENDME);
SET_CELL_TOPIC_ID(cell, conn->topic_id); SET_CELL_STREAM_ID(cell, conn->stream_id);
cell.length += TOPIC_HEADER_SIZE; cell.length += RELAY_HEADER_SIZE;
if(edge_type == EDGE_EXIT) { /* we're at an exit */ if(edge_type == EDGE_EXIT) { /* we're at an exit */
if(conn->p_receive_topicwindow < TOPICWINDOW_START - TOPICWINDOW_INCREMENT) { if(conn->p_receive_streamwindow < STREAMWINDOW_START - STREAMWINDOW_INCREMENT) {
log(LOG_DEBUG,"connection_consider_sending_sendme(): Outbuf %d, Queueing topic sendme back.", conn->outbuf_flushlen); log(LOG_DEBUG,"connection_consider_sending_sendme(): Outbuf %d, Queueing stream sendme back.", conn->outbuf_flushlen);
conn->p_receive_topicwindow += TOPICWINDOW_INCREMENT; conn->p_receive_streamwindow += STREAMWINDOW_INCREMENT;
cell.aci = circ->p_aci; cell.aci = circ->p_aci;
if(circuit_deliver_data_cell_from_edge(&cell, circ, edge_type) < 0) { if(circuit_deliver_relay_cell_from_edge(&cell, circ, edge_type) < 0) {
log(LOG_DEBUG,"connection_consider_sending_sendme(): circuit_deliver_data_cell_from_edge (backward) failed. Closing."); log(LOG_DEBUG,"connection_consider_sending_sendme(): circuit_deliver_relay_cell_from_edge (backward) failed. Closing.");
circuit_close(circ); circuit_close(circ);
return 0; return 0;
} }
} }
} else { /* we're at an AP */ } else { /* we're at an AP */
assert(edge_type == EDGE_AP); assert(edge_type == EDGE_AP);
if(conn->n_receive_topicwindow < TOPICWINDOW_START-TOPICWINDOW_INCREMENT) { if(conn->n_receive_streamwindow < STREAMWINDOW_START-STREAMWINDOW_INCREMENT) {
log(LOG_DEBUG,"connection_consider_sending_sendme(): Outbuf %d, Queueing topic sendme forward.", conn->outbuf_flushlen); log(LOG_DEBUG,"connection_consider_sending_sendme(): Outbuf %d, Queueing stream sendme forward.", conn->outbuf_flushlen);
conn->n_receive_topicwindow += TOPICWINDOW_INCREMENT; conn->n_receive_streamwindow += STREAMWINDOW_INCREMENT;
cell.aci = circ->n_aci; cell.aci = circ->n_aci;
if(circuit_deliver_data_cell_from_edge(&cell, circ, edge_type) < 0) { if(circuit_deliver_relay_cell_from_edge(&cell, circ, edge_type) < 0) {
log(LOG_DEBUG,"connection_consider_sending_sendme(): circuit_deliver_data_cell_from_edge (forward) failed. Closing."); log(LOG_DEBUG,"connection_consider_sending_sendme(): circuit_deliver_relay_cell_from_edge (forward) failed. Closing.");
circuit_close(circ); circuit_close(circ);
return 0; return 0;
} }

View File

@ -103,9 +103,9 @@ int ap_handshake_process_socks(connection_t *conn) {
circ->dirty = 1; circ->dirty = 1;
/* add it into the linked list of topics on this circuit */ /* 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); log(LOG_DEBUG,"ap_handshake_process_socks(): attaching new conn to circ. n_aci %d.", circ->n_aci);
conn->next_topic = circ->p_conn; conn->next_stream = circ->p_conn;
circ->p_conn = conn; circ->p_conn = conn;
if(ap_handshake_send_begin(conn, circ) < 0) { if(ap_handshake_send_begin(conn, circ) < 0) {
@ -118,28 +118,28 @@ int ap_handshake_process_socks(connection_t *conn) {
int ap_handshake_send_begin(connection_t *ap_conn, circuit_t *circ) { int ap_handshake_send_begin(connection_t *ap_conn, circuit_t *circ) {
cell_t cell; cell_t cell;
uint16_t topic_id; uint16_t stream_id;
memset(&cell, 0, sizeof(cell_t)); memset(&cell, 0, sizeof(cell_t));
/* deliver the dest_addr in a data cell */ /* deliver the dest_addr in a relay cell */
cell.command = CELL_DATA; cell.command = CELL_RELAY;
cell.aci = circ->n_aci; cell.aci = circ->n_aci;
SET_CELL_TOPIC_COMMAND(cell, TOPIC_COMMAND_BEGIN); SET_CELL_RELAY_COMMAND(cell, RELAY_COMMAND_BEGIN);
if (CRYPTO_PSEUDO_RAND_INT(topic_id)) if (CRYPTO_PSEUDO_RAND_INT(stream_id))
return -1; return -1;
SET_CELL_TOPIC_ID(cell, topic_id); SET_CELL_STREAM_ID(cell, stream_id);
/* FIXME check for collisions */ /* FIXME check for collisions */
ap_conn->topic_id = topic_id; ap_conn->stream_id = stream_id;
snprintf(cell.payload+4, CELL_PAYLOAD_SIZE-4, "%s:%d", ap_conn->dest_addr, ap_conn->dest_port); snprintf(cell.payload+4, CELL_PAYLOAD_SIZE-4, "%s:%d", ap_conn->dest_addr, ap_conn->dest_port);
cell.length = strlen(cell.payload+TOPIC_HEADER_SIZE)+1+TOPIC_HEADER_SIZE; cell.length = strlen(cell.payload+RELAY_HEADER_SIZE)+1+RELAY_HEADER_SIZE;
log(LOG_DEBUG,"ap_handshake_send_begin(): Sending data cell to begin topic %d.", ap_conn->topic_id); log(LOG_DEBUG,"ap_handshake_send_begin(): Sending relay cell to begin stream %d.", ap_conn->stream_id);
if(circuit_deliver_data_cell_from_edge(&cell, circ, EDGE_AP) < 0) { if(circuit_deliver_relay_cell_from_edge(&cell, circ, EDGE_AP) < 0) {
log(LOG_DEBUG,"ap_handshake_send_begin(): failed to deliver begin cell. Closing."); log(LOG_DEBUG,"ap_handshake_send_begin(): failed to deliver begin cell. Closing.");
return -1; return -1;
} }
ap_conn->n_receive_topicwindow = TOPICWINDOW_START; ap_conn->n_receive_streamwindow = STREAMWINDOW_START;
ap_conn->p_receive_topicwindow = TOPICWINDOW_START; ap_conn->p_receive_streamwindow = STREAMWINDOW_START;
ap_conn->state = AP_CONN_STATE_OPEN; ap_conn->state = AP_CONN_STATE_OPEN;
log(LOG_INFO,"ap_handshake_send_begin(): Address/port sent, ap socket %d, n_aci %d",ap_conn->s,circ->n_aci); log(LOG_INFO,"ap_handshake_send_begin(): Address/port sent, ap socket %d, n_aci %d",ap_conn->s,circ->n_aci);
return 0; return 0;

View File

@ -25,14 +25,14 @@ int connection_edge_process_inbuf(connection_t *conn) {
return -1; return -1;
memset(&cell, 0, sizeof(cell_t)); memset(&cell, 0, sizeof(cell_t));
cell.command = CELL_DATA; cell.command = CELL_RELAY;
cell.length = TOPIC_HEADER_SIZE; cell.length = RELAY_HEADER_SIZE;
SET_CELL_TOPIC_COMMAND(cell, TOPIC_COMMAND_END); SET_CELL_RELAY_COMMAND(cell, RELAY_COMMAND_END);
SET_CELL_TOPIC_ID(cell, conn->topic_id); SET_CELL_STREAM_ID(cell, conn->stream_id);
cell.aci = circ->n_aci; cell.aci = circ->n_aci;
if (circuit_deliver_data_cell_from_edge(&cell, circ, conn->type) < 0) { if (circuit_deliver_relay_cell_from_edge(&cell, circ, conn->type) < 0) {
log(LOG_DEBUG,"connection_edge_process_inbuf: circuit_deliver_data_cell_from_edge failed. Closing"); log(LOG_DEBUG,"connection_edge_process_inbuf: circuit_deliver_relay_cell_from_edge failed. Closing");
circuit_close(circ); circuit_close(circ);
} }
return 0; return 0;
@ -60,7 +60,7 @@ int connection_edge_process_inbuf(connection_t *conn) {
return 0; return 0;
} }
int connection_edge_send_command(connection_t *conn, circuit_t *circ, int topic_command) { int connection_edge_send_command(connection_t *conn, circuit_t *circ, int relay_command) {
cell_t cell; cell_t cell;
assert(conn); assert(conn);
@ -75,36 +75,36 @@ int connection_edge_send_command(connection_t *conn, circuit_t *circ, int topic_
cell.aci = circ->n_aci; cell.aci = circ->n_aci;
else else
cell.aci = circ->p_aci; cell.aci = circ->p_aci;
cell.command = CELL_DATA; cell.command = CELL_RELAY;
SET_CELL_TOPIC_COMMAND(cell, topic_command); SET_CELL_RELAY_COMMAND(cell, relay_command);
SET_CELL_TOPIC_ID(cell, conn->topic_id); SET_CELL_STREAM_ID(cell, conn->stream_id);
cell.length = TOPIC_HEADER_SIZE; cell.length = RELAY_HEADER_SIZE;
log(LOG_INFO,"connection_edge_send_command(): delivering %d cell %s.", topic_command, conn->type == CONN_TYPE_AP ? "forward" : "backward"); log(LOG_INFO,"connection_edge_send_command(): delivering %d cell %s.", relay_command, conn->type == CONN_TYPE_AP ? "forward" : "backward");
if(circuit_deliver_data_cell_from_edge(&cell, circ, conn->type) < 0) { if(circuit_deliver_relay_cell_from_edge(&cell, circ, conn->type) < 0) {
log(LOG_DEBUG,"connection_edge_send_command(): circuit_deliver_data_cell failed. Closing."); log(LOG_DEBUG,"connection_edge_send_command(): circuit_deliver_relay_cell failed. Closing.");
circuit_close(circ); circuit_close(circ);
return 0; return 0;
} }
return 0; return 0;
} }
int connection_edge_process_data_cell(cell_t *cell, circuit_t *circ, int edge_type) { int connection_edge_process_relay_cell(cell_t *cell, circuit_t *circ, int edge_type) {
connection_t *conn; connection_t *conn;
int topic_command; int relay_command;
int topic_id; int stream_id;
static int num_seen=0; static int num_seen=0;
/* an incoming data cell has arrived */ /* an incoming relay cell has arrived */
assert(cell && circ); assert(cell && circ);
topic_command = CELL_TOPIC_COMMAND(*cell); relay_command = CELL_RELAY_COMMAND(*cell);
topic_id = CELL_TOPIC_ID(*cell); stream_id = CELL_STREAM_ID(*cell);
log(LOG_DEBUG,"connection_edge_process_data_cell(): command %d topic %d", topic_command, topic_id); log(LOG_DEBUG,"connection_edge_process_relay_cell(): command %d stream %d", relay_command, stream_id);
num_seen++; num_seen++;
log(LOG_DEBUG,"connection_edge_process_data_cell(): Now seen %d data cells here.", 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); circuit_consider_sending_sendme(circ, edge_type);
@ -113,56 +113,56 @@ int connection_edge_process_data_cell(cell_t *cell, circuit_t *circ, int edge_ty
else else
conn = circ->n_conn; conn = circ->n_conn;
for( ; conn && conn->topic_id != topic_id; conn = conn->next_topic) ; for( ; conn && conn->stream_id != stream_id; conn = conn->next_stream) ;
/* now conn is either NULL, in which case we don't recognize the topic_id, or /* 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. * it is set, in which case cell is talking about this conn.
*/ */
if(conn && conn->state != AP_CONN_STATE_OPEN && conn->state != EXIT_CONN_STATE_OPEN) { if(conn && conn->state != AP_CONN_STATE_OPEN && conn->state != EXIT_CONN_STATE_OPEN) {
if(conn->type == CONN_TYPE_EXIT && topic_command == TOPIC_COMMAND_END) { if(conn->type == CONN_TYPE_EXIT && relay_command == RELAY_COMMAND_END) {
log(LOG_INFO,"connection_edge_process_data_cell(): Exit got end before we're connected. Marking for close."); log(LOG_INFO,"connection_edge_process_relay_cell(): Exit got end before we're connected. Marking for close.");
conn->marked_for_close = 1; conn->marked_for_close = 1;
} else { } else {
log(LOG_DEBUG,"connection_edge_process_data_cell(): Got an unexpected data cell, not in 'open' state. Dropping."); log(LOG_DEBUG,"connection_edge_process_relay_cell(): Got an unexpected relay cell, not in 'open' state. Dropping.");
} }
return 0; return 0;
} }
switch(topic_command) { switch(relay_command) {
case TOPIC_COMMAND_BEGIN: case RELAY_COMMAND_BEGIN:
if(edge_type == EDGE_AP) { if(edge_type == EDGE_AP) {
log(LOG_INFO,"connection_edge_process_data_cell(): topic begin request unsupported. Dropping."); log(LOG_INFO,"connection_edge_process_relay_cell(): relay begin request unsupported. Dropping.");
return 0; return 0;
} else { } else {
if(conn) { if(conn) {
log(LOG_INFO,"connection_edge_process_data_cell(): begin cell for known topic. Dropping."); log(LOG_INFO,"connection_edge_process_relay_cell(): begin cell for known stream. Dropping.");
return 0; return 0;
} }
return connection_exit_begin_conn(cell, circ); return connection_exit_begin_conn(cell, circ);
} }
case TOPIC_COMMAND_DATA: case RELAY_COMMAND_DATA:
if(!conn) { if(!conn) {
log(LOG_DEBUG,"connection_edge_process_data_cell(): data cell dropped, unknown topic %d.",topic_id); log(LOG_DEBUG,"connection_edge_process_relay_cell(): relay cell dropped, unknown stream %d.",stream_id);
return 0; return 0;
} }
if((edge_type == EDGE_AP && --conn->n_receive_topicwindow < 0) || if((edge_type == EDGE_AP && --conn->n_receive_streamwindow < 0) ||
(edge_type == EDGE_EXIT && --conn->p_receive_topicwindow < 0)) { /* is it below 0 after decrement? */ (edge_type == EDGE_EXIT && --conn->p_receive_streamwindow < 0)) { /* is it below 0 after decrement? */
log(LOG_DEBUG,"connection_edge_process_data_cell(): receive_topicwindow below 0. Killing."); log(LOG_DEBUG,"connection_edge_process_relay_cell(): receive_streamwindow below 0. Killing.");
return -1; /* somebody's breaking protocol. kill the whole circuit. */ return -1; /* somebody's breaking protocol. kill the whole circuit. */
} }
#ifdef USE_ZLIB #ifdef USE_ZLIB
if(connection_decompress_to_buf(cell->payload + TOPIC_HEADER_SIZE, if(connection_decompress_to_buf(cell->payload + RELAY_HEADER_SIZE,
cell->length - TOPIC_HEADER_SIZE, cell->length - RELAY_HEADER_SIZE,
conn, Z_SYNC_FLUSH) < 0) { conn, Z_SYNC_FLUSH) < 0) {
log(LOG_INFO,"connection_edge_process_data_cell(): write to buf failed. Marking for close."); log(LOG_INFO,"connection_edge_process_relay_cell(): write to buf failed. Marking for close.");
conn->marked_for_close = 1; conn->marked_for_close = 1;
return 0; return 0;
} }
#else #else
if(connection_write_to_buf(cell->payload + TOPIC_HEADER_SIZE, if(connection_write_to_buf(cell->payload + RELAY_HEADER_SIZE,
cell->length - TOPIC_HEADER_SIZE, conn) < 0) { cell->length - RELAY_HEADER_SIZE, conn) < 0) {
conn->marked_for_close = 1; conn->marked_for_close = 1;
return 0; return 0;
} }
@ -170,20 +170,20 @@ int connection_edge_process_data_cell(cell_t *cell, circuit_t *circ, int edge_ty
if(connection_consider_sending_sendme(conn, edge_type) < 0) if(connection_consider_sending_sendme(conn, edge_type) < 0)
conn->marked_for_close = 1; conn->marked_for_close = 1;
return 0; return 0;
case TOPIC_COMMAND_END: case RELAY_COMMAND_END:
if(!conn) { if(!conn) {
log(LOG_DEBUG,"connection_edge_process_data_cell(): end cell dropped, unknown topic %d.",topic_id); log(LOG_DEBUG,"connection_edge_process_relay_cell(): end cell dropped, unknown stream %d.",stream_id);
return 0; return 0;
} }
log(LOG_DEBUG,"connection_edge_process_data_cell(): end cell for topic %d. Removing topic.",topic_id); log(LOG_DEBUG,"connection_edge_process_relay_cell(): end cell for stream %d. Removing stream.",stream_id);
/* go through and identify who points to conn. remove conn from the list. */ /* go through and identify who points to conn. remove conn from the list. */
#if 0 #if 0
if(conn == circ->p_conn) { if(conn == circ->p_conn) {
circ->p_conn = conn->next_topic; circ->p_conn = conn->next_stream;
} }
for(prevconn = circ->p_conn; prevconn->next_topic != conn; prevconn = prevconn->next_topic) ; for(prevconn = circ->p_conn; prevconn->next_stream != conn; prevconn = prevconn->next_stream) ;
prevconn->next_topic = conn->next_topic; prevconn->next_stream = conn->next_stream;
#endif #endif
#ifdef HALF_OPEN #ifdef HALF_OPEN
conn->done_sending = 1; conn->done_sending = 1;
@ -193,35 +193,35 @@ int connection_edge_process_data_cell(cell_t *cell, circuit_t *circ, int edge_ty
#endif #endif
conn->marked_for_close = 1; conn->marked_for_close = 1;
break; break;
case TOPIC_COMMAND_CONNECTED: case RELAY_COMMAND_CONNECTED:
if(edge_type == EDGE_EXIT) { if(edge_type == EDGE_EXIT) {
log(LOG_INFO,"connection_edge_process_data_cell(): 'connected' unsupported at exit. Dropping."); log(LOG_INFO,"connection_edge_process_relay_cell(): 'connected' unsupported at exit. Dropping.");
return 0; return 0;
} }
if(!conn) { if(!conn) {
log(LOG_DEBUG,"connection_edge_process_data_cell(): connected cell dropped, unknown topic %d.",topic_id); log(LOG_DEBUG,"connection_edge_process_relay_cell(): connected cell dropped, unknown stream %d.",stream_id);
break; break;
} }
log(LOG_DEBUG,"connection_edge_process_data_cell(): Connected! Notifying application."); log(LOG_DEBUG,"connection_edge_process_relay_cell(): Connected! Notifying application.");
if(ap_handshake_socks_reply(conn, SOCKS4_REQUEST_GRANTED) < 0) { if(ap_handshake_socks_reply(conn, SOCKS4_REQUEST_GRANTED) < 0) {
conn->marked_for_close = 1; conn->marked_for_close = 1;
} }
break; break;
case TOPIC_COMMAND_SENDME: case RELAY_COMMAND_SENDME:
if(!conn) { if(!conn) {
log(LOG_DEBUG,"connection_edge_process_data_cell(): sendme cell dropped, unknown topic %d.",topic_id); log(LOG_DEBUG,"connection_edge_process_relay_cell(): sendme cell dropped, unknown stream %d.",stream_id);
return 0; return 0;
} }
if(edge_type == EDGE_AP) if(edge_type == EDGE_AP)
conn->p_receive_topicwindow += TOPICWINDOW_INCREMENT; conn->p_receive_streamwindow += STREAMWINDOW_INCREMENT;
else else
conn->n_receive_topicwindow += TOPICWINDOW_INCREMENT; conn->n_receive_streamwindow += STREAMWINDOW_INCREMENT;
connection_start_reading(conn); connection_start_reading(conn);
connection_package_raw_inbuf(conn); /* handle whatever might still be on the inbuf */ connection_package_raw_inbuf(conn); /* handle whatever might still be on the inbuf */
circuit_consider_stop_edge_reading(circ, edge_type); circuit_consider_stop_edge_reading(circ, edge_type);
break; break;
default: default:
log(LOG_DEBUG,"connection_edge_process_data_cell(): unknown topic command %d.",topic_command); log(LOG_DEBUG,"connection_edge_process_relay_cell(): unknown relay command %d.",relay_command);
} }
return 0; return 0;
} }
@ -251,10 +251,10 @@ int connection_edge_finished_flushing(connection_t *conn) {
conn->state = EXIT_CONN_STATE_OPEN; conn->state = EXIT_CONN_STATE_OPEN;
connection_watch_events(conn, POLLIN); /* stop writing, continue reading */ connection_watch_events(conn, POLLIN); /* stop writing, continue reading */
if(connection_wants_to_flush(conn)) /* in case there are any queued data cells */ if(connection_wants_to_flush(conn)) /* in case there are any queued relay cells */
connection_start_writing(conn); connection_start_writing(conn);
return return
connection_edge_send_command(conn, circuit_get_by_conn(conn), TOPIC_COMMAND_CONNECTED) || /* deliver a 'connected' data cell back through the circuit. */ connection_edge_send_command(conn, circuit_get_by_conn(conn), RELAY_COMMAND_CONNECTED) || /* deliver a 'connected' relay cell back through the circuit. */
connection_process_inbuf(conn); /* in case the server has written anything */ connection_process_inbuf(conn); /* in case the server has written anything */
case AP_CONN_STATE_OPEN: case AP_CONN_STATE_OPEN:
case EXIT_CONN_STATE_OPEN: case EXIT_CONN_STATE_OPEN:

View File

@ -8,19 +8,19 @@ int connection_exit_begin_conn(cell_t *cell, circuit_t *circ) {
connection_t *n_conn; connection_t *n_conn;
char *colon; char *colon;
if(!memchr(cell->payload + TOPIC_HEADER_SIZE,0,cell->length - TOPIC_HEADER_SIZE)) { if(!memchr(cell->payload + RELAY_HEADER_SIZE,0,cell->length - RELAY_HEADER_SIZE)) {
log(LOG_WARNING,"connection_exit_begin_conn(): topic begin cell has no \\0. Dropping."); log(LOG_WARNING,"connection_exit_begin_conn(): relay begin cell has no \\0. Dropping.");
return 0; return 0;
} }
colon = strchr(cell->payload + TOPIC_HEADER_SIZE, ':'); colon = strchr(cell->payload + RELAY_HEADER_SIZE, ':');
if(!colon) { if(!colon) {
log(LOG_WARNING,"connection_exit_begin_conn(): topic begin cell has no colon. Dropping."); log(LOG_WARNING,"connection_exit_begin_conn(): relay begin cell has no colon. Dropping.");
return 0; return 0;
} }
*colon = 0; *colon = 0;
if(!atoi(colon+1)) { /* bad port */ if(!atoi(colon+1)) { /* bad port */
log(LOG_DEBUG,"connection_exit_begin_conn(): topic begin cell has invalid port. Dropping."); log(LOG_DEBUG,"connection_exit_begin_conn(): relay begin cell has invalid port. Dropping.");
return 0; return 0;
} }
@ -31,25 +31,25 @@ int connection_exit_begin_conn(cell_t *cell, circuit_t *circ) {
return 0; return 0;
} }
cell->payload[0] = 0; // cell->payload[0] = 0;
n_conn->topic_id = ntohs(*(uint16_t *)(cell->payload+2)); n_conn->stream_id = CELL_STREAM_ID(*cell);
n_conn->address = strdup(cell->payload + TOPIC_HEADER_SIZE); n_conn->address = strdup(cell->payload + RELAY_HEADER_SIZE);
n_conn->port = atoi(colon+1); n_conn->port = atoi(colon+1);
n_conn->state = EXIT_CONN_STATE_RESOLVING; n_conn->state = EXIT_CONN_STATE_RESOLVING;
n_conn->receiver_bucket = -1; /* edge connections don't do receiver buckets */ n_conn->receiver_bucket = -1; /* edge connections don't do receiver buckets */
n_conn->bandwidth = -1; n_conn->bandwidth = -1;
n_conn->s = -1; /* not yet valid */ n_conn->s = -1; /* not yet valid */
n_conn->n_receive_topicwindow = TOPICWINDOW_START; n_conn->n_receive_streamwindow = STREAMWINDOW_START;
n_conn->p_receive_topicwindow = TOPICWINDOW_START; n_conn->p_receive_streamwindow = STREAMWINDOW_START;
if(connection_add(n_conn) < 0) { /* no space, forget it */ if(connection_add(n_conn) < 0) { /* no space, forget it */
log(LOG_DEBUG,"connection_exit_begin_conn(): connection_add failed. Dropping."); log(LOG_DEBUG,"connection_exit_begin_conn(): connection_add failed. Dropping.");
connection_free(n_conn); connection_free(n_conn);
return 0; return 0;
} }
/* add it into the linked list of topics on this circuit */ /* add it into the linked list of streams on this circuit */
n_conn->next_topic = circ->n_conn; n_conn->next_stream = circ->n_conn;
circ->n_conn = n_conn; circ->n_conn = n_conn;
/* send it off to the gethostbyname farm */ /* send it off to the gethostbyname farm */
@ -119,7 +119,7 @@ int connection_exit_connect(connection_t *conn) {
connection_watch_events(conn, POLLIN); connection_watch_events(conn, POLLIN);
/* also, deliver a 'connected' cell back through the circuit. */ /* also, deliver a 'connected' cell back through the circuit. */
return connection_edge_send_command(conn, circuit_get_by_conn(conn), TOPIC_COMMAND_CONNECTED); return connection_edge_send_command(conn, circuit_get_by_conn(conn), RELAY_COMMAND_CONNECTED);
} }
/* /*

View File

@ -70,7 +70,7 @@ int onion_pending_check(void) {
} }
void onion_pending_process_one(void) { void onion_pending_process_one(void) {
struct data_queue_t *tmpd; struct relay_queue_t *tmpd;
circuit_t *circ; circuit_t *circ;
if(!ol_list) if(!ol_list)
@ -85,9 +85,9 @@ void onion_pending_process_one(void) {
onion_pending_remove(circ); onion_pending_remove(circ);
circuit_close(circ); circuit_close(circ);
} else { } else {
log(LOG_DEBUG,"onion_pending_process_one(): Succeeded. Delivering queued data cells."); log(LOG_DEBUG,"onion_pending_process_one(): Succeeded. Delivering queued relay cells.");
for(tmpd = ol_list->data_cells; tmpd; tmpd=tmpd->next) { for(tmpd = ol_list->relay_cells; tmpd; tmpd=tmpd->next) {
command_process_data_cell(tmpd->cell, circ->p_conn); command_process_relay_cell(tmpd->cell, circ->p_conn);
} }
onion_pending_remove(circ); onion_pending_remove(circ);
} }
@ -99,7 +99,7 @@ void onion_pending_process_one(void) {
*/ */
void onion_pending_remove(circuit_t *circ) { void onion_pending_remove(circuit_t *circ) {
struct onion_queue_t *tmpo, *victim; struct onion_queue_t *tmpo, *victim;
struct data_queue_t *tmpd; struct relay_queue_t *tmpd;
if(!ol_list) if(!ol_list)
return; /* nothing here. */ return; /* nothing here. */
@ -129,10 +129,10 @@ void onion_pending_remove(circuit_t *circ) {
/* now victim points to the element that needs to be removed */ /* now victim points to the element that needs to be removed */
/* first dump the attached data cells too, if any */ /* first dump the attached relay cells too, if any */
while(victim->data_cells) { while(victim->relay_cells) {
tmpd = victim->data_cells; tmpd = victim->relay_cells;
victim->data_cells = tmpd->next; victim->relay_cells = tmpd->next;
free(tmpd->cell); free(tmpd->cell);
free(tmpd); free(tmpd);
} }
@ -141,11 +141,11 @@ void onion_pending_remove(circuit_t *circ) {
} }
struct data_queue_t *data_queue_add(struct data_queue_t *list, cell_t *cell) { struct relay_queue_t *relay_queue_add(struct relay_queue_t *list, cell_t *cell) {
struct data_queue_t *tmpd, *newd; struct relay_queue_t *tmpd, *newd;
newd = malloc(sizeof(struct data_queue_t)); newd = malloc(sizeof(struct relay_queue_t));
memset(newd, 0, sizeof(struct data_queue_t)); memset(newd, 0, sizeof(struct relay_queue_t));
newd->cell = malloc(sizeof(cell_t)); newd->cell = malloc(sizeof(cell_t));
memcpy(newd->cell, cell, sizeof(cell_t)); memcpy(newd->cell, cell, sizeof(cell_t));
@ -158,16 +158,16 @@ struct data_queue_t *data_queue_add(struct data_queue_t *list, cell_t *cell) {
return list; return list;
} }
/* a data cell has arrived for a circuit which is still pending. Find /* a relay cell has arrived for a circuit which is still pending. Find
* the right entry in ol_list, and add it to the end of the 'data_cells' * the right entry in ol_list, and add it to the end of the 'relay_cells'
* list. * list.
*/ */
void onion_pending_data_add(circuit_t *circ, cell_t *cell) { void onion_pending_relay_add(circuit_t *circ, cell_t *cell) {
struct onion_queue_t *tmpo; struct onion_queue_t *tmpo;
for(tmpo=ol_list; tmpo; tmpo=tmpo->next) { for(tmpo=ol_list; tmpo; tmpo=tmpo->next) {
if(tmpo->circ == circ) { if(tmpo->circ == circ) {
tmpo->data_cells = data_queue_add(tmpo->data_cells, cell); tmpo->relay_cells = relay_queue_add(tmpo->relay_cells, cell);
return; return;
} }
} }

View File

@ -122,15 +122,15 @@
// (or if just one was sent, waiting for that one */ // (or if just one was sent, waiting for that one */
//#define CIRCUIT_STATE_CLOSE 4 /* both acks received, connection is dead */ /* NOT USED */ //#define CIRCUIT_STATE_CLOSE 4 /* both acks received, connection is dead */ /* NOT USED */
#define TOPIC_COMMAND_BEGIN 1 #define RELAY_COMMAND_BEGIN 1
#define TOPIC_COMMAND_DATA 2 #define RELAY_COMMAND_DATA 2
#define TOPIC_COMMAND_END 3 #define RELAY_COMMAND_END 3
#define TOPIC_COMMAND_CONNECTED 4 #define RELAY_COMMAND_CONNECTED 4
#define TOPIC_COMMAND_SENDME 5 #define RELAY_COMMAND_SENDME 5
#define TOPIC_HEADER_SIZE 4 #define RELAY_HEADER_SIZE 4
#define TOPIC_STATE_RESOLVING #define RELAY_STATE_RESOLVING
/* available cipher functions */ /* available cipher functions */
#if 0 #if 0
@ -154,13 +154,13 @@
#define CIRCWINDOW_START 1000 #define CIRCWINDOW_START 1000
#define CIRCWINDOW_INCREMENT 100 #define CIRCWINDOW_INCREMENT 100
#define TOPICWINDOW_START 500 #define STREAMWINDOW_START 500
#define TOPICWINDOW_INCREMENT 50 #define STREAMWINDOW_INCREMENT 50
/* cell commands */ /* cell commands */
#define CELL_PADDING 0 #define CELL_PADDING 0
#define CELL_CREATE 1 #define CELL_CREATE 1
#define CELL_DATA 2 #define CELL_RELAY 2
#define CELL_DESTROY 3 #define CELL_DESTROY 3
#define CELL_SENDME 4 #define CELL_SENDME 4
@ -195,15 +195,15 @@ typedef uint16_t aci_t;
typedef struct { typedef struct {
aci_t aci; /* Anonymous Connection Identifier */ aci_t aci; /* Anonymous Connection Identifier */
unsigned char command; unsigned char command;
unsigned char length; /* of payload if data cell, else value of sendme */ unsigned char length; /* of payload if relay cell, else value of sendme */
uint32_t seq; /* sequence number */ uint32_t seq; /* sequence number */
unsigned char payload[CELL_PAYLOAD_SIZE]; unsigned char payload[CELL_PAYLOAD_SIZE];
} cell_t; } cell_t;
#define CELL_TOPIC_COMMAND(c) (*(uint8_t*)((c).payload)) #define CELL_RELAY_COMMAND(c) (*(uint8_t*)((c).payload))
#define SET_CELL_TOPIC_COMMAND(c,cmd) (*(uint8_t*)((c).payload) = (cmd)) #define SET_CELL_RELAY_COMMAND(c,cmd) (*(uint8_t*)((c).payload) = (cmd))
#define CELL_TOPIC_ID(c) ntohs(*(uint16_t*)((c).payload+2)) #define CELL_STREAM_ID(c) ntohs(*(uint16_t*)((c).payload+2))
#define SET_CELL_TOPIC_ID(c,id) (*(uint16_t*)((c).payload+2) = htons(id)) #define SET_CELL_STREAM_ID(c,id) (*(uint16_t*)((c).payload+2) = htons(id))
#define SOCKS4_REQUEST_GRANTED 90 #define SOCKS4_REQUEST_GRANTED 90
#define SOCKS4_REQUEST_REJECT 91 #define SOCKS4_REQUEST_REJECT 91
@ -265,10 +265,10 @@ struct connection_t {
uint16_t port; uint16_t port;
/* used by exit and ap: */ /* used by exit and ap: */
uint16_t topic_id; uint16_t stream_id;
struct connection_t *next_topic; struct connection_t *next_stream;
int n_receive_topicwindow; int n_receive_streamwindow;
int p_receive_topicwindow; int p_receive_streamwindow;
int done_sending; int done_sending;
int done_receiving; int done_receiving;
#ifdef USE_ZLIB #ifdef USE_ZLIB
@ -345,9 +345,9 @@ typedef struct {
} crypt_path_t; } crypt_path_t;
struct data_queue_t { struct relay_queue_t {
cell_t *cell; cell_t *cell;
struct data_queue_t *next; struct relay_queue_t *next;
}; };
/* struct for a path (circuit) through the network */ /* struct for a path (circuit) through the network */
@ -362,7 +362,7 @@ typedef struct {
aci_t p_aci; /* connection identifiers */ aci_t p_aci; /* connection identifiers */
aci_t n_aci; aci_t n_aci;
struct data_queue_t *data_queue; /* for queueing cells at the edges */ struct relay_queue_t *relay_queue; /* for queueing cells at the edges */
crypto_cipher_env_t *p_crypto; /* crypto environments */ crypto_cipher_env_t *p_crypto; /* crypto environments */
crypto_cipher_env_t *n_crypto; crypto_cipher_env_t *n_crypto;
@ -385,7 +385,7 @@ typedef struct {
struct onion_queue_t { struct onion_queue_t {
circuit_t *circ; circuit_t *circ;
struct data_queue_t *data_cells; struct relay_queue_t *relay_cells;
struct onion_queue_t *next; struct onion_queue_t *next;
}; };
@ -461,16 +461,16 @@ void compression_free(z_compression *);
void decompression_free(z_decompression *); void decompression_free(z_decompression *);
int compress_from_buf(char *string, int string_len, int compress_from_buf(char *string, int string_len,
char **buf_in, int *buflen_in, int *buf_datalen_in, char **buf_in, int *buflen_in, int *buf_datalen_in,
z_compression *compression, int flush); z_compression *compression, int flush);
/* read and compress as many characters as possible from buf, writing up to /* read and compress as many characters as possible from buf, writing up to
* string_len of them onto string, then memmove buf back. Return number of * string_len of them onto string, then memmove buf back. Return number of
* characters written. * characters written.
*/ */
int decompress_buf_to_buf(char **buf_in, int *buflen_in, int *buf_datalen_in, int decompress_buf_to_buf(char **buf_in, int *buflen_in, int *buf_datalen_in,
char **buf_out, int *buflen_out, int *buf_datalen_out, char **buf_out, int *buflen_out, int *buf_datalen_out,
z_decompression *decompression, int flush); z_decompression *decompression, int flush);
/* XXX document this NM /* XXX document this NM
*/ */
@ -500,8 +500,8 @@ circuit_t *circuit_get_by_conn(connection_t *conn);
circuit_t *circuit_get_newest_by_edge_type(char edge_type); circuit_t *circuit_get_newest_by_edge_type(char edge_type);
circuit_t *circuit_enumerate_by_naddr_nport(circuit_t *start, uint32_t naddr, uint16_t nport); circuit_t *circuit_enumerate_by_naddr_nport(circuit_t *start, uint32_t naddr, uint16_t nport);
int circuit_deliver_data_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);
int circuit_deliver_data_cell(cell_t *cell, circuit_t *circ, int crypt_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_crypt(circuit_t *circ, char *in, int inlen, char crypt_type);
void circuit_resume_edge_reading(circuit_t *circ, int edge_type); void circuit_resume_edge_reading(circuit_t *circ, int edge_type);
@ -533,7 +533,7 @@ void command_process_cell(cell_t *cell, connection_t *conn);
void command_process_create_cell(cell_t *cell, connection_t *conn); void command_process_create_cell(cell_t *cell, connection_t *conn);
void command_process_sendme_cell(cell_t *cell, connection_t *conn); void command_process_sendme_cell(cell_t *cell, connection_t *conn);
void command_process_data_cell(cell_t *cell, connection_t *conn); void command_process_relay_cell(cell_t *cell, connection_t *conn);
void command_process_destroy_cell(cell_t *cell, connection_t *conn); void command_process_destroy_cell(cell_t *cell, connection_t *conn);
void command_process_connected_cell(cell_t *cell, connection_t *conn); void command_process_connected_cell(cell_t *cell, connection_t *conn);
@ -637,8 +637,8 @@ int connection_ap_handle_listener_read(connection_t *conn);
/********************************* connection_edge.c ***************************/ /********************************* connection_edge.c ***************************/
int connection_edge_process_inbuf(connection_t *conn); int connection_edge_process_inbuf(connection_t *conn);
int connection_edge_send_command(connection_t *conn, circuit_t *circ, int topic_command); int connection_edge_send_command(connection_t *conn, circuit_t *circ, int relay_command);
int connection_edge_process_data_cell(cell_t *cell, circuit_t *circ, int edge_type); int connection_edge_process_relay_cell(cell_t *cell, circuit_t *circ, int edge_type);
int connection_edge_finished_flushing(connection_t *conn); int connection_edge_finished_flushing(connection_t *conn);
/********************************* connection_exit.c ***************************/ /********************************* connection_exit.c ***************************/
@ -746,8 +746,8 @@ int onion_pending_add(circuit_t *circ);
int onion_pending_check(void); int onion_pending_check(void);
void onion_pending_process_one(void); void onion_pending_process_one(void);
void onion_pending_remove(circuit_t *circ); void onion_pending_remove(circuit_t *circ);
struct data_queue_t *data_queue_add(struct data_queue_t *list, cell_t *cell); struct relay_queue_t *relay_queue_add(struct relay_queue_t *list, cell_t *cell);
void onion_pending_data_add(circuit_t *circ, cell_t *cell); void onion_pending_relay_add(circuit_t *circ, cell_t *cell);
/* uses a weighted coin with weight cw to choose a route length */ /* uses a weighted coin with weight cw to choose a route length */
int chooselen(double cw); int chooselen(double cw);