Commit 39e9d790 authored by Roger Dingledine's avatar Roger Dingledine
Browse files

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
parent 59029a3e
......@@ -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
* 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) {
assert(buf && buflen && buf_datalen);
*buf = (char *)malloc(MAX_BUF_SIZE);
if(!*buf)
return -1;
*buf = (char *)tor_malloc(MAX_BUF_SIZE);
// memset(*buf,0,MAX_BUF_SIZE);
*buflen = MAX_BUF_SIZE;
*buf_datalen = 0;
......@@ -139,9 +137,7 @@ int write_to_buf(char *string, int string_len,
z_stream *zstream_new(int compression)
{
z_stream* stream;
stream = malloc(sizeof(z_stream));
if (!stream)
return NULL;
stream = tor_malloc(sizeof(z_stream));
memset(stream, 0, sizeof(z_stream));
if (compression) {
if (deflateInit(stream, Z_DEFAULT_COMPRESSION) != Z_OK) {
......
......@@ -55,9 +55,7 @@ circuit_t *circuit_new(aci_t p_aci, connection_t *p_conn) {
my_gettimeofday(&now);
circ = (circuit_t *)malloc(sizeof(circuit_t));
if(!circ)
return NULL;
circ = (circuit_t *)tor_malloc(sizeof(circuit_t));
memset(circ,0,sizeof(circuit_t)); /* zero it out */
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->n_aci remains 0 because we haven't identified the next hop yet */
circ->n_receive_circwindow = CIRCWINDOW_START;
circ->p_receive_circwindow = CIRCWINDOW_START;
circ->package_window = CIRCWINDOW_START;
circ->deliver_window = CIRCWINDOW_START;
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;
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) {
log(LOG_DEBUG,"circuit_deliver_relay_cell_from_edge(): pwindow 0, queueing for later.");
#if 0
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);
return 0;
}
circ->p_receive_circwindow--;
// log(LOG_INFO,"circuit_deliver_relay_cell_from_edge(): p_receive_circwindow now %d.",circ->p_receive_circwindow);
layer_hint->package_window--;
// log(LOG_INFO,"circuit_deliver_relay_cell_from_edge(): package_window now %d.",layer_hint->package_window);
#endif
} else { /* i'm the exit */
cell_direction = CELL_DIRECTION_IN;
// assert(layer_hint == NULL);
// assert(circ->cpath == NULL);
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) {
log(LOG_DEBUG,"circuit_deliver_relay_cell_from_edge(): nwindow 0, queueing for later.");
#if 0
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);
return 0;
}
circ->n_receive_circwindow--;
circ->package_window--;
#endif
}
if(circuit_deliver_relay_cell(cell, circ, cell_direction, layer_hint) < 0) {
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;
}
......@@ -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));
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.");
return -1;
}
......@@ -282,11 +286,11 @@ int circuit_deliver_relay_cell(cell_t *cell, circuit_t *circ,
if(recognized) {
if(cell_direction == CELL_DIRECTION_OUT) {
log(LOG_DEBUG,"circuit_deliver_relay_cell(): Sending to exit.");
return connection_edge_process_relay_cell(cell, circ, conn, EDGE_EXIT);
return connection_edge_process_relay_cell(cell, circ, conn, EDGE_EXIT, NULL);
}
if(cell_direction == CELL_DIRECTION_IN) {
log(LOG_DEBUG,"circuit_deliver_relay_cell(): Sending to AP.");
return connection_edge_process_relay_cell(cell, circ, conn, EDGE_AP);
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,
crypt_path_t *layer_hint, char *recognized, connection_t **conn) {
crypt_path_t **layer_hint, char *recognized, connection_t **conn) {
crypt_path_t *thishop;
char out[256];
......@@ -333,8 +337,10 @@ int relay_crypt(circuit_t *circ, char *in, int inlen, char cell_direction,
memcpy(in,out,inlen);
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;
}
thishop = thishop->next;
} 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) {
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 */
do {
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;
struct relay_queue_t *tmpd;
struct relay_queue_t *relay, *victim;
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 */
while(circ->relay_queue) {
assert(circ->relay_queue->cell);
relay = circ->relay_queue;
while(relay) {
assert(relay->cell);
if(edge_type == EDGE_EXIT) {
circ->n_receive_circwindow--;
assert(circ->n_receive_circwindow >= 0);
assert(relay->layer_hint == NULL);
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);
return;
}
} else { /* ap */
circ->p_receive_circwindow--;
assert(circ->p_receive_circwindow >= 0);
assert(relay->layer_hint);
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);
return;
}
}
tmpd = circ->relay_queue;
circ->relay_queue = tmpd->next;
free(tmpd->cell);
free(tmpd);
victim = relay;
relay=relay->next;
if(circ->relay_queue == victim) {
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;
}
#endif
if(edge_type == EDGE_EXIT)
conn = circ->n_conn;
......@@ -476,58 +495,64 @@ void circuit_resume_edge_reading(circuit_t *circ, int edge_type) {
conn = circ->p_conn;
for( ; conn; conn=conn->next_stream) {
if((edge_type == EDGE_EXIT && conn->n_receive_streamwindow > 0) ||
(edge_type == EDGE_AP && conn->p_receive_streamwindow > 0)) {
if((edge_type == EDGE_EXIT && conn->package_window > 0) ||
(edge_type == EDGE_AP && conn->package_window > 0 && conn->cpath_layer == layer_hint)) {
connection_start_reading(conn);
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. */
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;
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;
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;
else
return 0;
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;
}
int circuit_consider_sending_sendme(circuit_t *circ, int edge_type) {
cell_t sendme;
int circuit_consider_sending_sendme(circuit_t *circ, int edge_type, crypt_path_t *layer_hint) {
cell_t cell;
assert(circ);
memset(&sendme, 0, sizeof(cell_t));
sendme.command = CELL_SENDME;
sendme.length = CIRCWINDOW_INCREMENT;
memset(&cell, 0, sizeof(cell_t));
cell.command = CELL_RELAY;
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 */
while(circ->n_receive_circwindow < CIRCWINDOW_START-CIRCWINDOW_INCREMENT) {
log(LOG_DEBUG,"circuit_consider_sending_sendme(): n_receive_circwindow %d, Queueing sendme forward.", circ->n_receive_circwindow);
circ->n_receive_circwindow += CIRCWINDOW_INCREMENT;
sendme.aci = circ->n_aci;
if(connection_write_cell_to_buf(&sendme, circ->n_conn) < 0) {
cell.aci = circ->n_aci;
while(layer_hint->deliver_window < CIRCWINDOW_START-CIRCWINDOW_INCREMENT) {
log(LOG_DEBUG,"circuit_consider_sending_sendme(): deliver_window %d, Queueing sendme forward.", layer_hint->deliver_window);
layer_hint->deliver_window += CIRCWINDOW_INCREMENT;
if(circuit_deliver_relay_cell_from_edge(&cell, circ, edge_type, layer_hint) < 0) {
return -1;
}
}
} else if(edge_type == EDGE_EXIT) { /* i'm the exit */
while(circ->p_receive_circwindow < CIRCWINDOW_START-CIRCWINDOW_INCREMENT) {
log(LOG_DEBUG,"circuit_consider_sending_sendme(): p_receive_circwindow %d, Queueing sendme back.", circ->p_receive_circwindow);
circ->p_receive_circwindow += CIRCWINDOW_INCREMENT;
sendme.aci = circ->p_aci;
if(connection_write_cell_to_buf(&sendme, circ->p_conn) < 0) {
cell.aci = circ->p_aci;
while(circ->deliver_window < CIRCWINDOW_START-CIRCWINDOW_INCREMENT) {
log(LOG_DEBUG,"circuit_consider_sending_sendme(): deliver_window %d, Queueing sendme back.", circ->deliver_window);
circ->deliver_window += CIRCWINDOW_INCREMENT;
if(circuit_deliver_relay_cell_from_edge(&cell, circ, edge_type, layer_hint) < 0) {
return -1;
}
}
......
......@@ -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) {
static int num_create=0, num_created=0, num_relay=0, num_destroy=0, num_sendme=0;
static int create_time=0, created_time=0, relay_time=0, destroy_time=0, sendme_time=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;
static long current_second = 0; /* from previous calls to gettimeofday */
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,"Relay: %d (%d ms)", num_relay, relay_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 */
num_create = num_created = num_relay = num_destroy = num_sendme = 0;
create_time = created_time = relay_time = destroy_time = sendme_time = 0;
num_create = num_created = num_relay = num_destroy = 0;
create_time = created_time = relay_time = destroy_time = 0;
/* remember which second it is, for next time */
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_process_destroy_cell);
break;
case CELL_SENDME:
command_time_process_cell(cell, conn, &num_sendme, &sendme_time,
command_process_sendme_cell);
break;
default:
log(LOG_DEBUG,"Cell of unknown type (%d) received. Dropping.", cell->command);
break;
......@@ -161,63 +156,6 @@ void command_process_created_cell(cell_t *cell, connection_t *conn) {
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) {
circuit_t *circ;
......@@ -234,6 +172,7 @@ void command_process_relay_cell(cell_t *cell, connection_t *conn) {
return;
}
#if 0
if(cell->aci == circ->p_aci) { /* it's an outgoing cell */
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);
......@@ -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);
}
#endif
#if 0
if(circ->state == CIRCUIT_STATE_ONION_WAIT) {
......
......@@ -43,7 +43,7 @@ struct config_line *config_get_commandlines(int argc, char **argv) {
continue;
}
new = malloc(sizeof(struct config_line));
new = tor_malloc(sizeof(struct config_line));
s = argv[i];
while(*s == '-')
s++;
......@@ -107,7 +107,7 @@ struct config_line *config_get_lines(FILE *f) {
*end = 0; /* null it out */
/* 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->value = strdup(s);
......
......@@ -70,9 +70,7 @@ connection_t *connection_new(int type) {
my_gettimeofday(&now);
conn = (connection_t *)malloc(sizeof(connection_t));
if(!conn)
return NULL;
conn = (connection_t *)tor_malloc(sizeof(connection_t));
memset(conn,0,sizeof(connection_t)); /* zero it out to start */
conn->type = type;
......@@ -655,7 +653,7 @@ int connection_package_raw_inbuf(connection_t *conn) {
assert(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:
......@@ -713,13 +711,8 @@ repeat_connection_package_raw_inbuf:
circuit_close(circ);
return 0;
}
assert(conn->n_receive_streamwindow > 0);
if(--conn->n_receive_streamwindow <= 0) { /* is it 0 after decrement? */
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);
assert(circ->package_window > 0);
circ->package_window--;
} else { /* send it forward. we're an AP */
assert(conn->type == CONN_TYPE_AP);
cell.aci = circ->n_aci;
......@@ -728,14 +721,23 @@ repeat_connection_package_raw_inbuf:
circuit_close(circ);
return 0;
}
assert(conn->p_receive_streamwindow > 0);
if(--conn->p_receive_streamwindow <= 0) { /* is it 0 after decrement? */
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);
assert(conn->cpath_layer->package_window > 0);
conn->cpath_layer->package_window--;
}
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 */
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);
cell.length += RELAY_HEADER_SIZE;
if(edge_type == EDGE_EXIT) { /* we're at an exit */
if(conn->p_receive_streamwindow < STREAMWINDOW_START - STREAMWINDOW_INCREMENT) {
log(LOG_DEBUG,"connection_consider_sending_sendme(): Outbuf %d, Queueing stream sendme back.", conn->outbuf_flushlen);
conn->p_receive_streamwindow += STREAMWINDOW_INCREMENT;
cell.aci = circ->p_aci;
if(circuit_deliver_relay_cell_from_edge(&cell, circ, edge_type, NULL) < 0) {
log(LOG_DEBUG,"connection_consider_sending_sendme(): circuit_deliver_relay_cell_from_edge (backward) failed. Closing.");
circuit_close(circ);
return 0;
}
}
} else { /* we're at an AP */
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;
}
if(edge_type == EDGE_EXIT)
cell.aci = circ->p_aci;
else
cell.aci = circ->n_aci;
while(conn->deliver_window < STREAMWINDOW_START - STREAMWINDOW_INCREMENT) {
log(LOG_DEBUG,"connection_consider_sending_sendme(): Outbuf %d, Queueing stream sendme.", conn->outbuf_flushlen);
conn->deliver_window += STREAMWINDOW_INCREMENT;
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);
return 0;
}
}
return 0;
}
}
int connection_finished_flushing(connection_t *conn) {
......
......@@ -5,9 +5,10 @@
#include "or.h"
int ap_handshake_process_socks(connection_t *conn) {
char c;
socks4_t socks4_info;
circuit_t *circ;
char tmpbuf[512];
int amt;
assert(conn);
......@@ -49,48 +50,44 @@ int ap_handshake_process_socks(connection_t *conn) {
socks4_info.destip[2] ||
!socks4_info.destip[3]) { /* not 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]);
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);
}
}
if(!conn->read_username) { /* the socks spec says we've got to read stuff until we get a null */
for(;;) {
if(!conn->inbuf_datalen)
return 0; /* maybe next time */
if(connection_fetch_from_buf((char *)&c,1,conn) < 0)
return -1;
if(!c) {
conn->read_username = 1;
log(LOG_DEBUG,"ap_handshake_process_socks(): Successfully read username.");
break;
}
amt = connection_find_on_inbuf("\0", 1, conn);
if(amt < 0) /* not there yet */
return 0;
if(amt > 500) {
log(LOG_NOTICE,"ap_handshake_process_socks(): username too long.");
ap_handshake_socks_reply(conn, SOCKS4_REQUEST_REJECT);
return -1;
}
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 */
for(;;) {
if(!conn->inbuf_datalen)
return 0; /* maybe next time */
if(connection_fetch_from_buf((char *)&c,1,conn) < 0)
return -1;
conn->dest_tmp[conn->dest_tmplen++] = c;
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'",