add circuit-level sendme relay cells

remove sendme cells
replace malloc with tor_malloc
patch (but not track down) bug in onion pending list
streamline connection_ap handshake


svn:r293
This commit is contained in:
Roger Dingledine 2003-05-20 06:41:23 +00:00
parent 59029a3eed
commit 39e9d79038
15 changed files with 233 additions and 283 deletions

View File

@ -10,15 +10,13 @@ extern or_options_t options; /* command-line and config-file options */
/* Create a new buf of size MAX_BUF_SIZE. Write a pointer to it /* Create a new buf of size MAX_BUF_SIZE. Write a pointer to it
* into *buf, write MAX_BUF_SIZE into *buflen, and initialize * into *buf, write MAX_BUF_SIZE into *buflen, and initialize
* *buf_datalen to 0. Return 0 if success, or -1 if malloc fails. * *buf_datalen to 0. Return 0.
*/ */
int buf_new(char **buf, int *buflen, int *buf_datalen) { int buf_new(char **buf, int *buflen, int *buf_datalen) {
assert(buf && buflen && buf_datalen); assert(buf && buflen && buf_datalen);
*buf = (char *)malloc(MAX_BUF_SIZE); *buf = (char *)tor_malloc(MAX_BUF_SIZE);
if(!*buf)
return -1;
// memset(*buf,0,MAX_BUF_SIZE); // memset(*buf,0,MAX_BUF_SIZE);
*buflen = MAX_BUF_SIZE; *buflen = MAX_BUF_SIZE;
*buf_datalen = 0; *buf_datalen = 0;
@ -139,9 +137,7 @@ int write_to_buf(char *string, int string_len,
z_stream *zstream_new(int compression) z_stream *zstream_new(int compression)
{ {
z_stream* stream; z_stream* stream;
stream = malloc(sizeof(z_stream)); stream = tor_malloc(sizeof(z_stream));
if (!stream)
return NULL;
memset(stream, 0, sizeof(z_stream)); memset(stream, 0, sizeof(z_stream));
if (compression) { if (compression) {
if (deflateInit(stream, Z_DEFAULT_COMPRESSION) != Z_OK) { if (deflateInit(stream, Z_DEFAULT_COMPRESSION) != Z_OK) {

View File

@ -55,9 +55,7 @@ circuit_t *circuit_new(aci_t p_aci, connection_t *p_conn) {
my_gettimeofday(&now); my_gettimeofday(&now);
circ = (circuit_t *)malloc(sizeof(circuit_t)); circ = (circuit_t *)tor_malloc(sizeof(circuit_t));
if(!circ)
return NULL;
memset(circ,0,sizeof(circuit_t)); /* zero it out */ memset(circ,0,sizeof(circuit_t)); /* zero it out */
circ->timestamp_created = now.tv_sec; circ->timestamp_created = now.tv_sec;
@ -71,8 +69,8 @@ circuit_t *circuit_new(aci_t p_aci, connection_t *p_conn) {
circ->p_aci = p_aci; circ->p_aci = p_aci;
/* circ->n_aci remains 0 because we haven't identified the next hop yet */ /* circ->n_aci remains 0 because we haven't identified the next hop yet */
circ->n_receive_circwindow = CIRCWINDOW_START; circ->package_window = CIRCWINDOW_START;
circ->p_receive_circwindow = CIRCWINDOW_START; circ->deliver_window = CIRCWINDOW_START;
circuit_add(circ); circuit_add(circ);
@ -230,30 +228,36 @@ int circuit_deliver_relay_cell_from_edge(cell_t *cell, circuit_t *circ,
cell_direction = CELL_DIRECTION_OUT; cell_direction = CELL_DIRECTION_OUT;
numsent_ap++; numsent_ap++;
log(LOG_DEBUG,"circuit_deliver_relay_cell_from_edge(): now sent %d relay 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 0
log(LOG_DEBUG,"circuit_deliver_relay_cell_from_edge(): pwindow 0, queueing for later."); if(layer_hint->package_window <= 0) {
log(LOG_DEBUG,"circuit_deliver_relay_cell_from_edge(): package_window 0, queueing for later.");
circ->relay_queue = relay_queue_add(circ->relay_queue, cell, layer_hint); circ->relay_queue = relay_queue_add(circ->relay_queue, cell, layer_hint);
return 0; return 0;
} }
circ->p_receive_circwindow--; layer_hint->package_window--;
// log(LOG_INFO,"circuit_deliver_relay_cell_from_edge(): p_receive_circwindow now %d.",circ->p_receive_circwindow); // log(LOG_INFO,"circuit_deliver_relay_cell_from_edge(): package_window now %d.",layer_hint->package_window);
#endif
} else { /* i'm the exit */ } else { /* i'm the exit */
cell_direction = CELL_DIRECTION_IN; cell_direction = CELL_DIRECTION_IN;
// assert(layer_hint == NULL);
// assert(circ->cpath == NULL);
numsent_exit++; numsent_exit++;
log(LOG_DEBUG,"circuit_deliver_relay_cell_from_edge(): now sent %d relay 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 0
log(LOG_DEBUG,"circuit_deliver_relay_cell_from_edge(): nwindow 0, queueing for later."); if(circ->package_window <= 0) {
log(LOG_DEBUG,"circuit_deliver_relay_cell_from_edge(): package_window 0, queueing for later.");
circ->relay_queue = relay_queue_add(circ->relay_queue, cell, layer_hint); circ->relay_queue = relay_queue_add(circ->relay_queue, cell, layer_hint);
return 0; return 0;
} }
circ->n_receive_circwindow--; circ->package_window--;
#endif
} }
if(circuit_deliver_relay_cell(cell, circ, cell_direction, layer_hint) < 0) { if(circuit_deliver_relay_cell(cell, circ, cell_direction, layer_hint) < 0) {
return -1; return -1;
} }
circuit_consider_stop_edge_reading(circ, edge_type); /* has window reached 0? */ // circuit_consider_stop_edge_reading(circ, edge_type, layer_hint); /* has window reached 0? */
return 0; return 0;
} }
@ -271,7 +275,7 @@ int circuit_deliver_relay_cell(cell_t *cell, circuit_t *circ,
log(LOG_DEBUG,"circuit_deliver_relay_cell(): direction %d, streamid %d before crypt.", cell_direction, *(int*)(cell->payload+1)); log(LOG_DEBUG,"circuit_deliver_relay_cell(): direction %d, streamid %d before crypt.", cell_direction, *(int*)(cell->payload+1));
if(relay_crypt(circ, buf, 1+CELL_PAYLOAD_SIZE, cell_direction, layer_hint, &recognized, &conn) < 0) { if(relay_crypt(circ, buf, 1+CELL_PAYLOAD_SIZE, cell_direction, &layer_hint, &recognized, &conn) < 0) {
log(LOG_DEBUG,"circuit_deliver_relay_cell(): relay crypt failed. Dropping connection."); log(LOG_DEBUG,"circuit_deliver_relay_cell(): relay crypt failed. Dropping connection.");
return -1; return -1;
} }
@ -282,11 +286,11 @@ int circuit_deliver_relay_cell(cell_t *cell, circuit_t *circ,
if(recognized) { if(recognized) {
if(cell_direction == CELL_DIRECTION_OUT) { if(cell_direction == CELL_DIRECTION_OUT) {
log(LOG_DEBUG,"circuit_deliver_relay_cell(): Sending to exit."); log(LOG_DEBUG,"circuit_deliver_relay_cell(): Sending to exit.");
return connection_edge_process_relay_cell(cell, circ, conn, EDGE_EXIT); return connection_edge_process_relay_cell(cell, circ, conn, EDGE_EXIT, NULL);
} }
if(cell_direction == CELL_DIRECTION_IN) { if(cell_direction == CELL_DIRECTION_IN) {
log(LOG_DEBUG,"circuit_deliver_relay_cell(): Sending to AP."); log(LOG_DEBUG,"circuit_deliver_relay_cell(): Sending to AP.");
return connection_edge_process_relay_cell(cell, circ, conn, EDGE_AP); return connection_edge_process_relay_cell(cell, circ, conn, EDGE_AP, layer_hint);
} }
} }
@ -306,7 +310,7 @@ int circuit_deliver_relay_cell(cell_t *cell, circuit_t *circ,
} }
int relay_crypt(circuit_t *circ, char *in, int inlen, char cell_direction, 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 **layer_hint, char *recognized, connection_t **conn) {
crypt_path_t *thishop; crypt_path_t *thishop;
char out[256]; char out[256];
@ -333,8 +337,10 @@ int relay_crypt(circuit_t *circ, char *in, int inlen, char cell_direction,
memcpy(in,out,inlen); memcpy(in,out,inlen);
log(LOG_DEBUG,"relay_crypt(): after decrypt: %d",*(int*)(in+2)); log(LOG_DEBUG,"relay_crypt(): after decrypt: %d",*(int*)(in+2));
if( (*recognized = relay_check_recognized(circ, cell_direction, in+2, conn))) if( (*recognized = relay_check_recognized(circ, cell_direction, in+2, conn))) {
*layer_hint = thishop;
return 0; return 0;
}
thishop = thishop->next; thishop = thishop->next;
} while(thishop != circ->cpath && thishop->state == CPATH_STATE_OPEN); } while(thishop != circ->cpath && thishop->state == CPATH_STATE_OPEN);
@ -359,7 +365,7 @@ int relay_crypt(circuit_t *circ, char *in, int inlen, char cell_direction,
} else if(cell_direction == CELL_DIRECTION_OUT) { } 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. */ if(circ->cpath) { /* we're at the beginning of the circuit. We'll want to do layered crypts. */
thishop = layer_hint; /* we already know which layer, from when we package_raw_inbuf'ed */ thishop = *layer_hint; /* we already know which layer, from when we package_raw_inbuf'ed */
/* moving from last to first hop */ /* moving from last to first hop */
do { do {
assert(thishop); assert(thishop);
@ -435,40 +441,53 @@ int relay_check_recognized(circuit_t *circ, int cell_direction, char *stream, co
} }
void circuit_resume_edge_reading(circuit_t *circ, int edge_type) { void circuit_resume_edge_reading(circuit_t *circ, int edge_type, crypt_path_t *layer_hint) {
connection_t *conn; connection_t *conn;
struct relay_queue_t *tmpd; struct relay_queue_t *relay, *victim;
assert(edge_type == EDGE_EXIT || edge_type == EDGE_AP); assert(edge_type == EDGE_EXIT || edge_type == EDGE_AP);
log(LOG_DEBUG,"circuit_resume_edge_reading(): resuming");
#if 0
/* first, send the queue waiting at circ onto the circuit */ /* first, send the queue waiting at circ onto the circuit */
while(circ->relay_queue) { relay = circ->relay_queue;
assert(circ->relay_queue->cell); while(relay) {
assert(relay->cell);
if(edge_type == EDGE_EXIT) { if(edge_type == EDGE_EXIT) {
circ->n_receive_circwindow--; assert(relay->layer_hint == NULL);
assert(circ->n_receive_circwindow >= 0); circ->package_window--;
assert(circ->package_window >= 0);
if(circuit_deliver_relay_cell(circ->relay_queue->cell, circ, CELL_DIRECTION_IN, circ->relay_queue->layer_hint) < 0) { if(circuit_deliver_relay_cell(relay->cell, circ, CELL_DIRECTION_IN, relay->layer_hint) < 0) {
circuit_close(circ); circuit_close(circ);
return; return;
} }
} else { /* ap */ } else { /* ap */
circ->p_receive_circwindow--; assert(relay->layer_hint);
assert(circ->p_receive_circwindow >= 0); if(relay->layer_hint != layer_hint) {
relay=relay->next; /* this cell isn't destined for this layer. don't send it. */
continue;
}
relay->layer_hint->package_window--;
assert(relay->layer_hint->package_window >= 0);
if(circuit_deliver_relay_cell(circ->relay_queue->cell, circ, CELL_DIRECTION_OUT, circ->relay_queue->layer_hint) < 0) { if(circuit_deliver_relay_cell(relay->cell, circ, CELL_DIRECTION_OUT, relay->layer_hint) < 0) {
circuit_close(circ); circuit_close(circ);
return; return;
} }
} }
tmpd = circ->relay_queue; victim = relay;
circ->relay_queue = tmpd->next; relay=relay->next;
free(tmpd->cell); if(circ->relay_queue == victim) {
free(tmpd); circ->relay_queue = relay;
}
free(victim->cell);
free(victim);
if(circuit_consider_stop_edge_reading(circ, edge_type)) if(circuit_consider_stop_edge_reading(circ, edge_type, layer_hint))
return; return;
} }
#endif
if(edge_type == EDGE_EXIT) if(edge_type == EDGE_EXIT)
conn = circ->n_conn; conn = circ->n_conn;
@ -476,58 +495,64 @@ void circuit_resume_edge_reading(circuit_t *circ, int edge_type) {
conn = circ->p_conn; conn = circ->p_conn;
for( ; conn; conn=conn->next_stream) { for( ; conn; conn=conn->next_stream) {
if((edge_type == EDGE_EXIT && conn->n_receive_streamwindow > 0) || if((edge_type == EDGE_EXIT && conn->package_window > 0) ||
(edge_type == EDGE_AP && conn->p_receive_streamwindow > 0)) { (edge_type == EDGE_AP && conn->package_window > 0 && conn->cpath_layer == layer_hint)) {
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, layer_hint);
} }
/* returns 1 if the window is empty, else 0. If it's empty, tell edge conns to stop reading. */ /* returns 1 if the window is empty, else 0. If it's empty, tell edge conns to stop reading. */
int circuit_consider_stop_edge_reading(circuit_t *circ, int edge_type) { int circuit_consider_stop_edge_reading(circuit_t *circ, int edge_type, crypt_path_t *layer_hint) {
connection_t *conn = NULL; connection_t *conn = NULL;
assert(edge_type == EDGE_EXIT || edge_type == EDGE_AP); assert(edge_type == EDGE_EXIT || edge_type == EDGE_AP);
assert(edge_type == EDGE_EXIT || layer_hint);
if(edge_type == EDGE_EXIT && circ->n_receive_circwindow <= 0) 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_conn;
else if(edge_type == EDGE_AP && circ->p_receive_circwindow <= 0) else if(edge_type == EDGE_AP && layer_hint->package_window <= 0)
conn = circ->p_conn; conn = circ->p_conn;
else else
return 0; return 0;
for( ; conn; conn=conn->next_stream) for( ; conn; conn=conn->next_stream)
connection_stop_reading(conn); if(!layer_hint || conn->cpath_layer == layer_hint)
connection_stop_reading(conn);
log(LOG_DEBUG,"circuit_consider_stop_edge_reading(): yes. stopped.");
return 1; return 1;
} }
int circuit_consider_sending_sendme(circuit_t *circ, int edge_type) { int circuit_consider_sending_sendme(circuit_t *circ, int edge_type, crypt_path_t *layer_hint) {
cell_t sendme; cell_t cell;
assert(circ); assert(circ);
memset(&sendme, 0, sizeof(cell_t)); memset(&cell, 0, sizeof(cell_t));
sendme.command = CELL_SENDME; cell.command = CELL_RELAY;
sendme.length = CIRCWINDOW_INCREMENT; SET_CELL_RELAY_COMMAND(cell, RELAY_COMMAND_SENDME);
SET_CELL_STREAM_ID(cell, ZERO_STREAM);
cell.length = RELAY_HEADER_SIZE;
if(edge_type == EDGE_AP) { /* i'm the AP */ if(edge_type == EDGE_AP) { /* i'm the AP */
while(circ->n_receive_circwindow < CIRCWINDOW_START-CIRCWINDOW_INCREMENT) { cell.aci = circ->n_aci;
log(LOG_DEBUG,"circuit_consider_sending_sendme(): n_receive_circwindow %d, Queueing sendme forward.", circ->n_receive_circwindow); while(layer_hint->deliver_window < CIRCWINDOW_START-CIRCWINDOW_INCREMENT) {
circ->n_receive_circwindow += CIRCWINDOW_INCREMENT; log(LOG_DEBUG,"circuit_consider_sending_sendme(): deliver_window %d, Queueing sendme forward.", layer_hint->deliver_window);
sendme.aci = circ->n_aci; layer_hint->deliver_window += CIRCWINDOW_INCREMENT;
if(connection_write_cell_to_buf(&sendme, circ->n_conn) < 0) { if(circuit_deliver_relay_cell_from_edge(&cell, circ, edge_type, layer_hint) < 0) {
return -1; return -1;
} }
} }
} else if(edge_type == EDGE_EXIT) { /* i'm the exit */ } else if(edge_type == EDGE_EXIT) { /* i'm the exit */
while(circ->p_receive_circwindow < CIRCWINDOW_START-CIRCWINDOW_INCREMENT) { cell.aci = circ->p_aci;
log(LOG_DEBUG,"circuit_consider_sending_sendme(): p_receive_circwindow %d, Queueing sendme back.", circ->p_receive_circwindow); while(circ->deliver_window < CIRCWINDOW_START-CIRCWINDOW_INCREMENT) {
circ->p_receive_circwindow += CIRCWINDOW_INCREMENT; log(LOG_DEBUG,"circuit_consider_sending_sendme(): deliver_window %d, Queueing sendme back.", circ->deliver_window);
sendme.aci = circ->p_aci; circ->deliver_window += CIRCWINDOW_INCREMENT;
if(connection_write_cell_to_buf(&sendme, circ->p_conn) < 0) { if(circuit_deliver_relay_cell_from_edge(&cell, circ, edge_type, layer_hint) < 0) {
return -1; return -1;
} }
} }

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_created=0, num_relay=0, num_destroy=0, num_sendme=0; static int num_create=0, num_created=0, num_relay=0, num_destroy=0;
static int create_time=0, created_time=0, relay_time=0, destroy_time=0, sendme_time=0; static int create_time=0, created_time=0, relay_time=0, destroy_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;
@ -42,11 +42,10 @@ void command_process_cell(cell_t *cell, connection_t *conn) {
log(LOG_INFO,"Created: %d (%d ms)", num_created, created_time/1000); log(LOG_INFO,"Created: %d (%d ms)", num_created, created_time/1000);
log(LOG_INFO,"Relay: %d (%d ms)", num_relay, relay_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);
/* zero out stats */ /* zero out stats */
num_create = num_created = num_relay = num_destroy = num_sendme = 0; num_create = num_created = num_relay = num_destroy = 0;
create_time = created_time = relay_time = destroy_time = sendme_time = 0; create_time = created_time = relay_time = destroy_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;
@ -72,10 +71,6 @@ void command_process_cell(cell_t *cell, connection_t *conn) {
command_time_process_cell(cell, conn, &num_destroy, &destroy_time, command_time_process_cell(cell, conn, &num_destroy, &destroy_time,
command_process_destroy_cell); command_process_destroy_cell);
break; break;
case CELL_SENDME:
command_time_process_cell(cell, conn, &num_sendme, &sendme_time,
command_process_sendme_cell);
break;
default: default:
log(LOG_DEBUG,"Cell of unknown type (%d) received. Dropping.", cell->command); log(LOG_DEBUG,"Cell of unknown type (%d) received. Dropping.", cell->command);
break; break;
@ -161,63 +156,6 @@ void command_process_created_cell(cell_t *cell, connection_t *conn) {
return; return;
} }
void command_process_sendme_cell(cell_t *cell, connection_t *conn) {
circuit_t *circ;
circ = circuit_get_by_aci_conn(cell->aci, conn);
if(!circ) {
log(LOG_DEBUG,"command_process_sendme_cell(): unknown circuit %d. Dropping.", cell->aci);
return;
}
#if 0
if(circ->state == CIRCUIT_STATE_ONION_WAIT) {
log(LOG_DEBUG,"command_process_sendme_cell(): circuit in onion_wait. Dropping.");
return;
}
if(circ->state == CIRCUIT_STATE_OR_WAIT) {
log(LOG_DEBUG,"command_process_sendme_cell(): circuit in or_wait. Dropping.");
return;
}
#endif
/* at this point both circ->n_conn and circ->p_conn are guaranteed to be set */
if(cell->length != CIRCWINDOW_INCREMENT) {
log(LOG_WARNING,"command_process_sendme_cell(): non-standard sendme value %d.",cell->length);
}
if(cell->aci == circ->p_aci) { /* it's an outgoing cell */
circ->n_receive_circwindow += cell->length;
assert(circ->n_receive_circwindow <= CIRCWINDOW_START);
log(LOG_DEBUG,"command_process_sendme_cell(): n_receive_circwindow for aci %d is %d.",circ->n_aci,circ->n_receive_circwindow);
if(!circ->n_conn || circ->n_conn->type == CONN_TYPE_EXIT) {
circuit_resume_edge_reading(circ, EDGE_EXIT);
} else {
cell->aci = circ->n_aci; /* switch it */
if(connection_write_cell_to_buf(cell, circ->n_conn) < 0) {
circuit_close(circ);
return;
}
}
} else { /* it's an ingoing cell */
assert(cell->aci == circ->n_aci);
circ->p_receive_circwindow += cell->length;
log(LOG_DEBUG,"command_process_sendme_cell(): p_receive_circwindow for aci %d is %d.",circ->p_aci,circ->p_receive_circwindow);
assert(circ->p_receive_circwindow <= CIRCWINDOW_START);
if(!circ->p_conn || circ->p_conn->type == CONN_TYPE_AP) {
circuit_resume_edge_reading(circ, EDGE_AP);
} else {
cell->aci = circ->p_aci; /* switch it */
if(connection_write_cell_to_buf(cell, circ->p_conn) < 0) {
circuit_close(circ);
return;
}
}
}
}
void command_process_relay_cell(cell_t *cell, connection_t *conn) { void command_process_relay_cell(cell_t *cell, connection_t *conn) {
circuit_t *circ; circuit_t *circ;
@ -234,6 +172,7 @@ void command_process_relay_cell(cell_t *cell, connection_t *conn) {
return; return;
} }
#if 0
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,"command_process_relay_cell(): Too many relay cells for out circuit (aci %d). Closing.", circ->p_aci); log(LOG_INFO,"command_process_relay_cell(): Too many relay cells for out circuit (aci %d). Closing.", circ->p_aci);
@ -251,6 +190,7 @@ void command_process_relay_cell(cell_t *cell, connection_t *conn) {
} }
log(LOG_DEBUG,"command_process_relay_cell(): n_receive_circwindow for aci %d is %d.",circ->n_aci,circ->n_receive_circwindow); log(LOG_DEBUG,"command_process_relay_cell(): n_receive_circwindow for aci %d is %d.",circ->n_aci,circ->n_receive_circwindow);
} }
#endif
#if 0 #if 0
if(circ->state == CIRCUIT_STATE_ONION_WAIT) { if(circ->state == CIRCUIT_STATE_ONION_WAIT) {

View File

@ -43,7 +43,7 @@ struct config_line *config_get_commandlines(int argc, char **argv) {
continue; continue;
} }
new = malloc(sizeof(struct config_line)); new = tor_malloc(sizeof(struct config_line));
s = argv[i]; s = argv[i];
while(*s == '-') while(*s == '-')
s++; s++;
@ -107,7 +107,7 @@ struct config_line *config_get_lines(FILE *f) {
*end = 0; /* null it out */ *end = 0; /* null it out */
/* prepare to parse the string into key / value */ /* prepare to parse the string into key / value */
new = malloc(sizeof(struct config_line)); new = tor_malloc(sizeof(struct config_line));
new->key = strdup(start); new->key = strdup(start);
new->value = strdup(s); new->value = strdup(s);

View File

@ -70,9 +70,7 @@ connection_t *connection_new(int type) {
my_gettimeofday(&now); my_gettimeofday(&now);
conn = (connection_t *)malloc(sizeof(connection_t)); conn = (connection_t *)tor_malloc(sizeof(connection_t));
if(!conn)
return NULL;
memset(conn,0,sizeof(connection_t)); /* zero it out to start */ memset(conn,0,sizeof(connection_t)); /* zero it out to start */
conn->type = type; conn->type = type;
@ -655,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_streamwindow is 0 */ /* this function should never get called if either package_window is 0 */
repeat_connection_package_raw_inbuf: repeat_connection_package_raw_inbuf:
@ -713,13 +711,8 @@ repeat_connection_package_raw_inbuf:
circuit_close(circ); circuit_close(circ);
return 0; return 0;
} }
assert(conn->n_receive_streamwindow > 0); assert(circ->package_window > 0);
if(--conn->n_receive_streamwindow <= 0) { /* is it 0 after decrement? */ circ->package_window--;
connection_stop_reading(conn);
log(LOG_DEBUG,"connection_package_raw_inbuf(): receive_streamwindow at exit reached 0.");
return 0; /* don't process the inbuf any more */
}
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;
@ -728,14 +721,23 @@ repeat_connection_package_raw_inbuf:
circuit_close(circ); circuit_close(circ);
return 0; return 0;
} }
assert(conn->p_receive_streamwindow > 0); assert(conn->cpath_layer->package_window > 0);
if(--conn->p_receive_streamwindow <= 0) { /* is it 0 after decrement? */ conn->cpath_layer->package_window--;
connection_stop_reading(conn);
log(LOG_DEBUG,"connection_package_raw_inbuf(): receive_streamwindow at AP reached 0.");
return 0; /* don't process the inbuf any more */
}
log(LOG_DEBUG,"connection_package_raw_inbuf(): receive_streamwindow at AP is %d",conn->p_receive_streamwindow);
} }
if(circuit_consider_stop_edge_reading(circ,
conn->type == CONN_TYPE_EXIT ? EDGE_EXIT : EDGE_AP, conn->cpath_layer))
return 0;
assert(conn->package_window > 0);
if(--conn->package_window <= 0) { /* is it 0 after decrement? */
connection_stop_reading(conn);
log(LOG_DEBUG,"connection_package_raw_inbuf(): conn->package_window reached 0.");
return 0; /* don't process the inbuf any more */
}
log(LOG_DEBUG,"connection_package_raw_inbuf(): conn->package_window is %d",conn->package_window);
/* 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;
} }
@ -760,32 +762,23 @@ int connection_consider_sending_sendme(connection_t *conn, int edge_type) {
SET_CELL_STREAM_ID(cell, conn->stream_id); SET_CELL_STREAM_ID(cell, conn->stream_id);
cell.length += RELAY_HEADER_SIZE; cell.length += RELAY_HEADER_SIZE;
if(edge_type == EDGE_EXIT) { /* we're at an exit */ if(edge_type == EDGE_EXIT)
if(conn->p_receive_streamwindow < STREAMWINDOW_START - STREAMWINDOW_INCREMENT) { cell.aci = circ->p_aci;
log(LOG_DEBUG,"connection_consider_sending_sendme(): Outbuf %d, Queueing stream sendme back.", conn->outbuf_flushlen); else
conn->p_receive_streamwindow += STREAMWINDOW_INCREMENT; cell.aci = circ->n_aci;
cell.aci = circ->p_aci;
if(circuit_deliver_relay_cell_from_edge(&cell, circ, edge_type, NULL) < 0) { while(conn->deliver_window < STREAMWINDOW_START - STREAMWINDOW_INCREMENT) {
log(LOG_DEBUG,"connection_consider_sending_sendme(): circuit_deliver_relay_cell_from_edge (backward) failed. Closing."); log(LOG_DEBUG,"connection_consider_sending_sendme(): Outbuf %d, Queueing stream sendme.", conn->outbuf_flushlen);
circuit_close(circ); conn->deliver_window += STREAMWINDOW_INCREMENT;
return 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 failed. Closing.");
} circuit_close(circ);
} else { /* we're at an AP */ return 0;
assert(edge_type == EDGE_AP);
if(conn->n_receive_streamwindow < STREAMWINDOW_START-STREAMWINDOW_INCREMENT) {
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, 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;
}
} }
} }
return 0; return 0;
} }
int connection_finished_flushing(connection_t *conn) { int connection_finished_flushing(connection_t *conn) {

View File

@ -5,9 +5,10 @@
#include "or.h" #include "or.h"
int ap_handshake_process_socks(connection_t *conn) { int ap_handshake_process_socks(connection_t *conn) {
char c;
socks4_t socks4_info; socks4_t socks4_info;
circuit_t *circ; circuit_t *circ;
char tmpbuf[512];
int amt;
assert(conn); assert(conn);
@ -49,48 +50,44 @@ int ap_handshake_process_socks(connection_t *conn) {
socks4_info.destip[2] || socks4_info.destip[2] ||
!socks4_info.destip[3]) { /* not 0.0.0.x */ !socks4_info.destip[3]) { /* not 0.0.0.x */
log(LOG_NOTICE,"ap_handshake_process_socks(): destip not in form 0.0.0.x."); log(LOG_NOTICE,"ap_handshake_process_socks(): destip not in form 0.0.0.x.");
sprintf(conn->dest_tmp, "%d.%d.%d.%d", socks4_info.destip[0], sprintf(tmpbuf, "%d.%d.%d.%d", socks4_info.destip[0],
socks4_info.destip[1], socks4_info.destip[2], socks4_info.destip[3]); socks4_info.destip[1], socks4_info.destip[2], socks4_info.destip[3]);
conn->dest_addr = strdup(conn->dest_tmp); conn->dest_addr = strdup(tmpbuf);
log(LOG_DEBUG,"ap_handshake_process_socks(): Successfully read destip (%s)", conn->dest_addr); log(LOG_DEBUG,"ap_handshake_process_socks(): Successfully read destip (%s)", conn->dest_addr);
} }
} }
if(!conn->read_username) { /* the socks spec says we've got to read stuff until we get a null */ if(!conn->read_username) { /* the socks spec says we've got to read stuff until we get a null */
for(;;) { amt = connection_find_on_inbuf("\0", 1, conn);
if(!conn->inbuf_datalen) if(amt < 0) /* not there yet */
return 0; /* maybe next time */ return 0;
if(connection_fetch_from_buf((char *)&c,1,conn) < 0) if(amt > 500) {
return -1; log(LOG_NOTICE,"ap_handshake_process_socks(): username too long.");
if(!c) { ap_handshake_socks_reply(conn, SOCKS4_REQUEST_REJECT);
conn->read_username = 1; return -1;
log(LOG_DEBUG,"ap_handshake_process_socks(): Successfully read username.");
break;
}
} }
if(connection_fetch_from_buf(tmpbuf,amt,conn) < 0)
return -1;
conn->read_username = 1;
log(LOG_DEBUG,"ap_handshake_process_socks(): Successfully read username.");
} }
if(!conn->dest_addr) { /* no dest_addr found yet */ if(!conn->dest_addr) { /* no dest_addr found yet */
amt = connection_find_on_inbuf("\0", 1, conn);
for(;;) { if(amt < 0) /* not there yet */
if(!conn->inbuf_datalen) return 0;
return 0; /* maybe next time */ if(amt > 500) {
if(connection_fetch_from_buf((char *)&c,1,conn) < 0) log(LOG_NOTICE,"ap_handshake_process_socks(): dest_addr too long.");
return -1; ap_handshake_socks_reply(conn, SOCKS4_REQUEST_REJECT);
conn->dest_tmp[conn->dest_tmplen++] = c; return -1;
if(conn->dest_tmplen > 500) {
log(LOG_NOTICE,"ap_handshake_process_socks(): dest_addr too long!");
ap_handshake_socks_reply(conn, SOCKS4_REQUEST_REJECT);
return -1;
}
if(!c) { /* we found the null; we're done */
conn->dest_addr = strdup(conn->dest_tmp);
log(LOG_NOTICE,"ap_handshake_process_socks(): successfully read dest addr '%s'",
conn->dest_addr);
break;
}
} }
if(connection_fetch_from_buf(tmpbuf,amt,conn) < 0)
return -1;
conn->dest_addr = strdup(tmpbuf);
log(LOG_NOTICE,"ap_handshake_process_socks(): successfully read dest addr '%s'",
conn->dest_addr);
} }
/* find the circuit that we should use, if there is one. */ /* find the circuit that we should use, if there is one. */
@ -143,8 +140,8 @@ int ap_handshake_send_begin(connection_t *ap_conn, circuit_t *circ) {
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_streamwindow = STREAMWINDOW_START; ap_conn->package_window = STREAMWINDOW_START;
ap_conn->p_receive_streamwindow = STREAMWINDOW_START; ap_conn->deliver_window = 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

@ -50,7 +50,7 @@ int connection_edge_process_inbuf(connection_t *conn) {
case EXIT_CONN_STATE_OPEN: case EXIT_CONN_STATE_OPEN:
if(connection_package_raw_inbuf(conn) < 0) if(connection_package_raw_inbuf(conn) < 0)
return -1; return -1;
circuit_consider_stop_edge_reading(circuit_get_by_conn(conn), EDGE_AP); circuit_consider_stop_edge_reading(circuit_get_by_conn(conn), conn->type == CONN_TYPE_AP ? EDGE_AP : EDGE_EXIT, conn->cpath_layer);
return 0; return 0;
case EXIT_CONN_STATE_CONNECTING: case EXIT_CONN_STATE_CONNECTING:
log(LOG_DEBUG,"connection_edge_process_inbuf(): text from server while in 'connecting' state at exit. Leaving it on buffer."); log(LOG_DEBUG,"connection_edge_process_inbuf(): text from server while in 'connecting' state at exit. Leaving it on buffer.");
@ -90,7 +90,8 @@ int connection_edge_send_command(connection_t *conn, circuit_t *circ, int relay_
return 0; return 0;
} }
int connection_edge_process_relay_cell(cell_t *cell, circuit_t *circ, connection_t *conn, int edge_type) { int connection_edge_process_relay_cell(cell_t *cell, circuit_t *circ, connection_t *conn,
int edge_type, crypt_path_t *layer_hint) {
int relay_command; int relay_command;
static int num_seen=0; static int num_seen=0;
@ -103,8 +104,6 @@ int connection_edge_process_relay_cell(cell_t *cell, circuit_t *circ, connection
num_seen++; num_seen++;
log(LOG_DEBUG,"connection_edge_process_relay_cell(): Now seen %d relay 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);
/* either conn is NULL, in which case we've got a control cell, or else /* either conn is NULL, in which case we've got a control cell, or else
* conn points to the recognized stream. */ * conn points to the recognized stream. */
@ -130,13 +129,23 @@ int connection_edge_process_relay_cell(cell_t *cell, circuit_t *circ, connection
} }
return connection_exit_begin_conn(cell, circ); return connection_exit_begin_conn(cell, circ);
case RELAY_COMMAND_DATA: case RELAY_COMMAND_DATA:
if((edge_type == EDGE_AP && --layer_hint->deliver_window < 0) ||
(edge_type == EDGE_EXIT && --circ->deliver_window < 0)) {
log(LOG_DEBUG,"connection_edge_process_relay_cell(): circ deliver_window below 0. Killing.");
return -1; /* XXX kill the whole circ? */
}
log(LOG_DEBUG,"connection_edge_process_relay_cell(): circ deliver_window now %d.", edge_type == EDGE_AP ? layer_hint->deliver_window : circ->deliver_window);
if(circuit_consider_sending_sendme(circ, edge_type, layer_hint) < 0)
return -1;
if(!conn) { if(!conn) {
log(LOG_DEBUG,"connection_edge_process_relay_cell(): relay cell dropped, unknown stream %d.",*(int*)conn->stream_id); log(LOG_DEBUG,"connection_edge_process_relay_cell(): relay cell dropped, unknown stream %d.",*(int*)conn->stream_id);
return 0; return 0;
} }
if((edge_type == EDGE_AP && --conn->n_receive_streamwindow < 0) ||
(edge_type == EDGE_EXIT && --conn->p_receive_streamwindow < 0)) { /* is it below 0 after decrement? */ if(--conn->deliver_window < 0) { /* is it below 0 after decrement? */
log(LOG_DEBUG,"connection_edge_process_relay_cell(): receive_streamwindow below 0. Killing."); log(LOG_DEBUG,"connection_edge_process_relay_cell(): conn deliver_window below 0. Killing.");
return -1; /* somebody's breaking protocol. kill the whole circuit. */ return -1; /* somebody's breaking protocol. kill the whole circuit. */
} }
@ -206,16 +215,23 @@ int connection_edge_process_relay_cell(cell_t *cell, circuit_t *circ, connection
break; break;
case RELAY_COMMAND_SENDME: case RELAY_COMMAND_SENDME:
if(!conn) { if(!conn) {
log(LOG_DEBUG,"connection_edge_process_relay_cell(): sendme cell dropped, unknown stream %d.",*(int*)conn->stream_id); if(edge_type == EDGE_AP) {
assert(layer_hint);
layer_hint->package_window += CIRCWINDOW_INCREMENT;
log(LOG_DEBUG,"connection_edge_process_relay_cell(): circ-level sendme at AP, packagewindow %d.", layer_hint->package_window);
circuit_resume_edge_reading(circ, EDGE_AP, layer_hint);
} else {
assert(!layer_hint);
circ->package_window += CIRCWINDOW_INCREMENT;
log(LOG_DEBUG,"connection_edge_process_relay_cell(): circ-level sendme at exit, packagewindow %d.", circ->package_window);
circuit_resume_edge_reading(circ, EDGE_EXIT, layer_hint);
}
return 0; return 0;
} }
if(edge_type == EDGE_AP) conn->package_window += STREAMWINDOW_INCREMENT;
conn->p_receive_streamwindow += STREAMWINDOW_INCREMENT;
else
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, layer_hint);
break; break;
default: default:
log(LOG_DEBUG,"connection_edge_process_relay_cell(): unknown relay command %d.",relay_command); log(LOG_DEBUG,"connection_edge_process_relay_cell(): unknown relay command %d.",relay_command);

View File

@ -38,8 +38,8 @@ int connection_exit_begin_conn(cell_t *cell, circuit_t *circ) {
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_streamwindow = STREAMWINDOW_START; n_conn->package_window = STREAMWINDOW_START;
n_conn->p_receive_streamwindow = STREAMWINDOW_START; n_conn->deliver_window = 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);

View File

@ -224,7 +224,7 @@ int directory_handle_reading(connection_t *conn) {
amt = connection_find_on_inbuf("\r\n\r\n", 4, conn); amt = connection_find_on_inbuf("\r\n\r\n", 4, conn);
if(amt < 0) /* not there yet */ if(amt < 0) /* not there yet */
return 0; return 0;
headers = malloc(amt+1); headers = tor_malloc(amt+1);
if(connection_fetch_from_buf(headers,amt,conn) < 0) { if(connection_fetch_from_buf(headers,amt,conn) < 0) {
log(LOG_DEBUG,"directory_handle_reading(): fetch_from_buf failed (reading headers)."); log(LOG_DEBUG,"directory_handle_reading(): fetch_from_buf failed (reading headers).");
return -1; return -1;

View File

@ -460,7 +460,7 @@ int dns_resolve(connection_t *exitconn) {
switch(resolve->state) { switch(resolve->state) {
case CACHE_STATE_PENDING: case CACHE_STATE_PENDING:
/* add us to the pending list */ /* add us to the pending list */
pending_connection = malloc(sizeof(struct pending_connection_t)); pending_connection = tor_malloc(sizeof(struct pending_connection_t));
pending_connection->conn = exitconn; pending_connection->conn = exitconn;
pending_connection->next = resolve->pending_connections; pending_connection->next = resolve->pending_connections;
resolve->pending_connections = pending_connection; resolve->pending_connections = pending_connection;
@ -472,13 +472,13 @@ int dns_resolve(connection_t *exitconn) {
return -1; return -1;
} }
} else { /* need to add it */ } else { /* need to add it */
resolve = malloc(sizeof(struct cached_resolve)); resolve = tor_malloc(sizeof(struct cached_resolve));
memset(resolve, 0, sizeof(struct cached_resolve)); memset(resolve, 0, sizeof(struct cached_resolve));
resolve->state = CACHE_STATE_PENDING; resolve->state = CACHE_STATE_PENDING;
strncpy(resolve->question, exitconn->address, MAX_ADDRESSLEN); strncpy(resolve->question, exitconn->address, MAX_ADDRESSLEN);
/* add us to the pending list */ /* add us to the pending list */
pending_connection = malloc(sizeof(struct pending_connection_t)); pending_connection = tor_malloc(sizeof(struct pending_connection_t));
pending_connection->conn = exitconn; pending_connection->conn = exitconn;
pending_connection->next = resolve->pending_connections; pending_connection->next = resolve->pending_connections;
resolve->pending_connections = pending_connection; resolve->pending_connections = pending_connection;

View File

@ -652,11 +652,7 @@ build_directory(directory_t *dir) {
routerinfo_t *router; routerinfo_t *router;
int i, n = 0; int i, n = 0;
routers = (routerinfo_t**) malloc(sizeof(routerinfo_t*) * (nfds+1)); routers = (routerinfo_t **)tor_malloc(sizeof(routerinfo_t*) * (nfds+1));
if (!routers) {
log(LOG_ERR, "build_directory(): couldn't allocate space for routerinfo");
return -1;
}
if (my_routerinfo) { if (my_routerinfo) {
log(LOG_INFO, "build_directory(): adding self (%s:%d)", log(LOG_INFO, "build_directory(): adding self (%s:%d)",
my_routerinfo->address, my_routerinfo->or_port); my_routerinfo->address, my_routerinfo->or_port);

View File

@ -30,7 +30,7 @@ static int ol_length=0;
int onion_pending_add(circuit_t *circ) { int onion_pending_add(circuit_t *circ) {
struct onion_queue_t *tmp; struct onion_queue_t *tmp;
tmp = malloc(sizeof(struct onion_queue_t)); tmp = tor_malloc(sizeof(struct onion_queue_t));
memset(tmp, 0, sizeof(struct onion_queue_t)); memset(tmp, 0, sizeof(struct onion_queue_t));
tmp->circ = circ; tmp->circ = circ;
@ -74,6 +74,12 @@ void onion_pending_process_one(void) {
return; /* no onions pending, we're done */ return; /* no onions pending, we're done */
assert(ol_list->circ); assert(ol_list->circ);
if(!ol_list->circ->p_conn) {
log(LOG_INFO,"onion_pending_process_one(): ol_list->circ->p_conn null, must have died?");
onion_pending_remove(ol_list->circ);
return; /* it died on us */
}
assert(ol_list->circ->p_conn); assert(ol_list->circ->p_conn);
assert(ol_length > 0); assert(ol_length > 0);
circ = ol_list->circ; circ = ol_list->circ;
@ -143,9 +149,9 @@ void onion_pending_remove(circuit_t *circ) {
struct relay_queue_t *relay_queue_add(struct relay_queue_t *list, cell_t *cell, crypt_path_t *layer_hint) { 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; struct relay_queue_t *tmpd, *newd;
newd = malloc(sizeof(struct relay_queue_t)); newd = tor_malloc(sizeof(struct relay_queue_t));
memset(newd, 0, sizeof(struct relay_queue_t)); memset(newd, 0, sizeof(struct relay_queue_t));
newd->cell = malloc(sizeof(cell_t)); newd->cell = tor_malloc(sizeof(cell_t));
memcpy(newd->cell, cell, sizeof(cell_t)); memcpy(newd->cell, cell, sizeof(cell_t));
newd->layer_hint = layer_hint; newd->layer_hint = layer_hint;
@ -279,11 +285,7 @@ unsigned int *new_route(double cw, routerinfo_t **rarray, int rarray_len, int *r
} }
/* allocate memory for the new route */ /* allocate memory for the new route */
route = (unsigned int *)malloc(*routelen * sizeof(unsigned int)); route = (unsigned int *)tor_malloc(*routelen * sizeof(unsigned int));
if (!route) {
log(LOG_ERR,"Memory allocation failed.");
return NULL;
}
oldchoice = rarray_len; oldchoice = rarray_len;
for(i=0;i<*routelen;i++) { for(i=0;i<*routelen;i++) {
@ -385,13 +387,7 @@ crypt_path_t *onion_generate_cpath(routerinfo_t **firsthop) {
router = rarray[route[i]]; router = rarray[route[i]];
/* build up the crypt_path */ /* build up the crypt_path */
hop = (crypt_path_t *)malloc(sizeof(crypt_path_t)); hop = (crypt_path_t *)tor_malloc(sizeof(crypt_path_t));
if(!hop) {
log(LOG_ERR,"Error allocating crypt path hop memory.");
circuit_free_cpath(cpath);
free(route);
return NULL;
}
memset(hop, 0, sizeof(crypt_path_t)); memset(hop, 0, sizeof(crypt_path_t));
/* link hop into the cpath, at the front */ /* link hop into the cpath, at the front */
@ -412,6 +408,9 @@ crypt_path_t *onion_generate_cpath(routerinfo_t **firsthop) {
hop->port = rarray[route[i]]->or_port; hop->port = rarray[route[i]]->or_port;
hop->addr = rarray[route[i]]->addr; hop->addr = rarray[route[i]]->addr;
hop->package_window = CIRCWINDOW_START;
hop->deliver_window = CIRCWINDOW_START;
log(LOG_DEBUG,"onion_generate_cpath() : Building hop %u of crypt path.",i+1); log(LOG_DEBUG,"onion_generate_cpath() : Building hop %u of crypt path.",i+1);
} }
@ -457,8 +456,7 @@ onion_skin_create(crypto_pk_env_t *dest_router_key,
dhbytes = crypto_dh_get_bytes(dh); dhbytes = crypto_dh_get_bytes(dh);
pkbytes = crypto_pk_keysize(dest_router_key); pkbytes = crypto_pk_keysize(dest_router_key);
assert(dhbytes+16 == DH_ONIONSKIN_LEN); assert(dhbytes+16 == DH_ONIONSKIN_LEN);
if (!(pubkey = malloc(dhbytes+16))) pubkey = (char *)tor_malloc(dhbytes+16);
goto err;
if (crypto_rand(16, pubkey)) if (crypto_rand(16, pubkey))
goto err; goto err;

View File

@ -153,7 +153,6 @@
#define CELL_CREATED 2 #define CELL_CREATED 2
#define CELL_RELAY 3 #define CELL_RELAY 3
#define CELL_DESTROY 4 #define CELL_DESTROY 4
#define CELL_SENDME 5
#define CELL_PAYLOAD_SIZE 248 #define CELL_PAYLOAD_SIZE 248
#define CELL_NETWORK_SIZE 256 #define CELL_NETWORK_SIZE 256
@ -259,8 +258,12 @@ struct connection_t {
char stream_id[STREAM_ID_SIZE]; char stream_id[STREAM_ID_SIZE];
struct connection_t *next_stream; struct connection_t *next_stream;
struct crypt_path_t *cpath_layer; /* a pointer to which node in the circ this conn exits at */ struct crypt_path_t *cpath_layer; /* a pointer to which node in the circ this conn exits at */
int package_window;
int deliver_window;
#if 0
int n_receive_streamwindow; int n_receive_streamwindow;
int p_receive_streamwindow; int p_receive_streamwindow;
#endif
int done_sending; int done_sending;
int done_receiving; int done_receiving;
#ifdef USE_ZLIB #ifdef USE_ZLIB
@ -280,10 +283,6 @@ struct connection_t {
char *dest_addr; char *dest_addr;
uint16_t dest_port; /* host order */ uint16_t dest_port; /* host order */
/* Used by ap: */
char dest_tmp[512];
int dest_tmplen;
/* Used by everyone */ /* Used by everyone */
char *address; /* strdup into this, because free_connection frees it */ char *address; /* strdup into this, because free_connection frees it */
/* Used for cell connections */ /* Used for cell connections */
@ -351,6 +350,8 @@ struct crypt_path_t {
struct crypt_path_t *next; struct crypt_path_t *next;
struct crypt_path_t *prev; /* doubly linked list */ struct crypt_path_t *prev; /* doubly linked list */
int package_window;
int deliver_window;
}; };
#define DH_KEY_LEN CRYPTO_DH_SIZE #define DH_KEY_LEN CRYPTO_DH_SIZE
@ -370,8 +371,8 @@ typedef struct {
uint16_t n_port; uint16_t n_port;
connection_t *p_conn; connection_t *p_conn;
connection_t *n_conn; /* convention: first conn is the OR conn, if there is one */ connection_t *n_conn; /* convention: first conn is the OR conn, if there is one */
int n_receive_circwindow; int package_window;
int p_receive_circwindow; int deliver_window;
aci_t p_aci; /* connection identifiers */ aci_t p_aci; /* connection identifiers */
aci_t n_aci; aci_t n_aci;
@ -504,12 +505,12 @@ int circuit_deliver_relay_cell_from_edge(cell_t *cell, circuit_t *circ,
int circuit_deliver_relay_cell(cell_t *cell, circuit_t *circ, int circuit_deliver_relay_cell(cell_t *cell, circuit_t *circ,
int cell_direction, crypt_path_t *layer_hint); int cell_direction, crypt_path_t *layer_hint);
int relay_crypt(circuit_t *circ, char *in, int inlen, char cell_direction, 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 **layer_hint, char *recognized, connection_t **conn);
int relay_check_recognized(circuit_t *circ, int cell_direction, char *stream, 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); void circuit_resume_edge_reading(circuit_t *circ, int edge_type, crypt_path_t *layer_hint);
int circuit_consider_stop_edge_reading(circuit_t *circ, int edge_type); int circuit_consider_stop_edge_reading(circuit_t *circ, int edge_type, crypt_path_t *layer_hint);
int circuit_consider_sending_sendme(circuit_t *circ, int edge_type); int circuit_consider_sending_sendme(circuit_t *circ, int edge_type, crypt_path_t *layer_hint);
void circuit_free(circuit_t *circ); void circuit_free(circuit_t *circ);
void circuit_free_cpath(crypt_path_t *cpath); void circuit_free_cpath(crypt_path_t *cpath);
@ -642,7 +643,7 @@ int connection_ap_handle_listener_read(connection_t *conn);
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 relay_command); 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, connection_t *conn, int edge_type); int connection_edge_process_relay_cell(cell_t *cell, circuit_t *circ, connection_t *conn, int edge_type, crypt_path_t *layer_hint);
int connection_edge_finished_flushing(connection_t *conn); int connection_edge_finished_flushing(connection_t *conn);
/********************************* connection_exit.c ***************************/ /********************************* connection_exit.c ***************************/

View File

@ -215,11 +215,7 @@ int router_get_list_from_file(char *routerfile)
return -1; return -1;
} }
string = malloc(statbuf.st_size+1); string = tor_malloc(statbuf.st_size+1);
if(!string) {
log(LOG_ERR,"router_get_list_from_file(): Out of memory.");
return -1;
}
if(read(fd,string,statbuf.st_size) != statbuf.st_size) { if(read(fd,string,statbuf.st_size) != statbuf.st_size) {
log(LOG_ERR,"router_get_list_from_file(): Couldn't read all %d bytes of file '%s'.",statbuf.st_size,routerfile); log(LOG_ERR,"router_get_list_from_file(): Couldn't read all %d bytes of file '%s'.",statbuf.st_size,routerfile);
@ -325,7 +321,7 @@ _router_get_next_token(char **s, directory_token_t *tok) {
next = strstr(*s, OR_SIGNATURE_END_TAG); next = strstr(*s, OR_SIGNATURE_END_TAG);
if (!next) { tok->val.error = "No signature end tag found"; return -1; } if (!next) { tok->val.error = "No signature end tag found"; return -1; }
signature = malloc(256); signature = tor_malloc(256);
i = base64_decode(signature, 256, *s, next-*s); i = base64_decode(signature, 256, *s, next-*s);
if (i<0) { if (i<0) {
free(signature); free(signature);
@ -604,10 +600,7 @@ static int router_get_list_from_string_tok(char **s, directory_t **dest,
assert(s); assert(s);
if (!(rarray = malloc((sizeof(routerinfo_t *))*MAX_ROUTERS_IN_DIR))) { rarray = (routerinfo_t **)tor_malloc((sizeof(routerinfo_t *))*MAX_ROUTERS_IN_DIR);
log(LOG_ERR, "router_get_list_from_string_tok(): malloc failed");
return -1;
}
while (tok->tp == K_ROUTER) { while (tok->tp == K_ROUTER) {
router = router_get_entry_from_string_tok(s, tok); router = router_get_entry_from_string_tok(s, tok);
@ -625,10 +618,7 @@ static int router_get_list_from_string_tok(char **s, directory_t **dest,
if (*dest) if (*dest)
directory_free(*dest); directory_free(*dest);
if (!(*dest = (directory_t*) malloc(sizeof(directory_t)))) { *dest = (directory_t *)tor_malloc(sizeof(directory_t));
log(LOG_ERR, "router_get_list_from_string_tok(): malloc failed");
return -1;
}
(*dest)->routers = rarray; (*dest)->routers = rarray;
(*dest)->n_routers = rarray_len; (*dest)->n_routers = rarray_len;
return 0; return 0;
@ -710,10 +700,8 @@ static routerinfo_t *router_get_entry_from_string_tok(char**s, directory_token_t
log(LOG_ERR,"router_get_entry_from_string(): Entry does not start with \"router\""); log(LOG_ERR,"router_get_entry_from_string(): Entry does not start with \"router\"");
return NULL; return NULL;
} }
if (!(router = malloc(sizeof(routerinfo_t)))) {
log(LOG_ERR,"router_get_entry_from_string(): Could not allocate memory."); router = tor_malloc(sizeof(routerinfo_t));
return NULL;
}
memset(router,0,sizeof(routerinfo_t)); /* zero it out first */ memset(router,0,sizeof(routerinfo_t)); /* zero it out first */
/* C doesn't guarantee that NULL is represented by 0 bytes. You'll /* C doesn't guarantee that NULL is represented by 0 bytes. You'll
thank me for this someday. */ thank me for this someday. */
@ -828,10 +816,10 @@ static int router_add_exit_policy(routerinfo_t *router,
return -1; return -1;
arg = tok->val.cmd.args[0]; arg = tok->val.cmd.args[0];
newe = malloc(sizeof(struct exit_policy_t)); newe = tor_malloc(sizeof(struct exit_policy_t));
memset(newe,0,sizeof(struct exit_policy_t)); memset(newe,0,sizeof(struct exit_policy_t));
newe->string = malloc(8+strlen(arg)); newe->string = tor_malloc(8+strlen(arg));
if (tok->tp == K_REJECT) { if (tok->tp == K_REJECT) {
strcpy(newe->string, "reject "); strcpy(newe->string, "reject ");
newe->policy_type = EXIT_POLICY_REJECT; newe->policy_type = EXIT_POLICY_REJECT;

View File

@ -275,9 +275,9 @@ test_crypto()
CRYPTO_CIPHER_3DES, CRYPTO_CIPHER_3DES,
-1 }; -1 };
data1 = malloc(1024); data1 = tor_malloc(1024);
data2 = malloc(1024); data2 = tor_malloc(1024);
data3 = malloc(1024); data3 = tor_malloc(1024);
test_assert(data1 && data2 && data3); test_assert(data1 && data2 && data3);
/* Try out identity ciphers. */ /* Try out identity ciphers. */
@ -623,9 +623,9 @@ test_dir_format()
test_assert(rp2->exit_policy->next->next == NULL); test_assert(rp2->exit_policy->next->next == NULL);
/* Okay, now for the directories. */ /* Okay, now for the directories. */
dir1 = (directory_t*) malloc(sizeof(directory_t)); dir1 = (directory_t*) tor_malloc(sizeof(directory_t));
dir1->n_routers = 2; dir1->n_routers = 2;
dir1->routers = (routerinfo_t**) malloc(sizeof(routerinfo_t*)*2); dir1->routers = (routerinfo_t**) tor_malloc(sizeof(routerinfo_t*)*2);
dir1->routers[0] = &r1; dir1->routers[0] = &r1;
dir1->routers[1] = &r2; dir1->routers[1] = &r2;
test_assert(! dump_signed_directory_to_string_impl(buf, 2048, dir1, pk1)); test_assert(! dump_signed_directory_to_string_impl(buf, 2048, dir1, pk1));