diff options
-rw-r--r-- | src/or/circuit.c | 88 | ||||
-rw-r--r-- | src/or/connection_edge.c | 47 | ||||
-rw-r--r-- | src/or/or.h | 14 |
3 files changed, 78 insertions, 71 deletions
diff --git a/src/or/circuit.c b/src/or/circuit.c index 0c2dfad27..34cf31000 100644 --- a/src/or/circuit.c +++ b/src/or/circuit.c @@ -9,6 +9,9 @@ extern or_options_t options; /* command-line and config-file options */ static int relay_crypt(circuit_t *circ, cell_t *cell, int cell_direction, crypt_path_t **layer_hint, char *recognized); static connection_t *relay_lookup_conn(circuit_t *circ, cell_t *cell, int cell_direction); +static int circuit_resume_edge_reading_helper(connection_t *conn, + circuit_t *circ, + crypt_path_t *layer_hint); static void circuit_free_cpath_node(crypt_path_t *victim); static uint16_t get_unique_circ_id_by_conn(connection_t *conn, int circ_id_type); static void circuit_rep_hist_note_result(circuit_t *circ); @@ -603,17 +606,17 @@ int circuit_receive_relay_cell(cell_t *cell, circuit_t *circ, conn = relay_lookup_conn(circ, cell, cell_direction); if(cell_direction == CELL_DIRECTION_OUT) { ++stats_n_relay_cells_delivered; - log_fn(LOG_DEBUG,"Sending to exit."); - if (connection_edge_process_relay_cell(cell, circ, conn, EDGE_EXIT, NULL) < 0) { - log_fn(LOG_WARN,"connection_edge_process_relay_cell (at exit) failed."); + log_fn(LOG_DEBUG,"Sending away from origin."); + if (connection_edge_process_relay_cell(cell, circ, conn, NULL) < 0) { + log_fn(LOG_WARN,"connection_edge_process_relay_cell (away from origin) failed."); return -1; } } if(cell_direction == CELL_DIRECTION_IN) { ++stats_n_relay_cells_delivered; - log_fn(LOG_DEBUG,"Sending to AP."); - if (connection_edge_process_relay_cell(cell, circ, conn, EDGE_AP, layer_hint) < 0) { - log_fn(LOG_WARN,"connection_edge_process_relay_cell (at AP) failed."); + log_fn(LOG_DEBUG,"Sending to origin."); + if (connection_edge_process_relay_cell(cell, circ, conn, layer_hint) < 0) { + log_fn(LOG_WARN,"connection_edge_process_relay_cell (at origin) failed."); return -1; } } @@ -793,61 +796,68 @@ relay_lookup_conn(circuit_t *circ, cell_t *cell, int cell_direction) return NULL; /* probably a begin relay cell */ } -void circuit_resume_edge_reading(circuit_t *circ, int edge_type, crypt_path_t *layer_hint) { - connection_t *conn; - - assert(edge_type == EDGE_EXIT || edge_type == EDGE_AP); +void circuit_resume_edge_reading(circuit_t *circ, crypt_path_t *layer_hint) { log_fn(LOG_DEBUG,"resuming"); - if(edge_type == EDGE_EXIT) - conn = circ->n_streams; - else - conn = circ->p_streams; + /* have to check both n_streams and p_streams, to handle rendezvous */ + if(circuit_resume_edge_reading_helper(circ->n_streams, circ, layer_hint) >= 0) + circuit_resume_edge_reading_helper(circ->p_streams, circ, layer_hint); +} + +static int +circuit_resume_edge_reading_helper(connection_t *conn, + circuit_t *circ, + crypt_path_t *layer_hint) { for( ; conn; conn=conn->next_stream) { - if((edge_type == EDGE_EXIT && conn->package_window > 0) || - (edge_type == EDGE_AP && conn->package_window > 0 && conn->cpath_layer == layer_hint)) { + if((!layer_hint && conn->package_window > 0) || + (layer_hint && conn->package_window > 0 && conn->cpath_layer == layer_hint)) { connection_start_reading(conn); - connection_edge_package_raw_inbuf(conn); /* handle whatever might still be on the inbuf */ + /* handle whatever might still be on the inbuf */ + connection_edge_package_raw_inbuf(conn); /* If the circuit won't accept any more data, return without looking * at any more of the streams. Any connections that should be stopped * have already been stopped by connection_edge_package_raw_inbuf. */ - if(circuit_consider_stop_edge_reading(circ, edge_type, layer_hint)) - return; + if(circuit_consider_stop_edge_reading(circ, layer_hint)) + return -1; } } + return 0; } -/* 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, crypt_path_t *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, 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); - log_fn(LOG_DEBUG,"considering"); - if(edge_type == EDGE_EXIT && circ->package_window <= 0) - conn = circ->n_streams; - else if(edge_type == EDGE_AP && layer_hint->package_window <= 0) - conn = circ->p_streams; - else - return 0; - - for( ; conn; conn=conn->next_stream) - if(!layer_hint || conn->cpath_layer == layer_hint) + if(!layer_hint && circ->package_window <= 0) { + log_fn(LOG_DEBUG,"yes, not-at-origin. stopped."); + for(conn = circ->n_streams; conn; conn=conn->next_stream) connection_stop_reading(conn); - - log_fn(LOG_DEBUG,"yes. stopped."); - return 1; + return -1; + } else if(layer_hint && layer_hint->package_window <= 0) { + log_fn(LOG_DEBUG,"yes, at-origin. stopped."); + for(conn = circ->n_streams; conn; conn=conn->next_stream) + if(conn->cpath_layer == layer_hint) + connection_stop_reading(conn); + for(conn = circ->p_streams; conn; conn=conn->next_stream) + if(conn->cpath_layer == layer_hint) + connection_stop_reading(conn); + return -1; + } + return 0; } -void circuit_consider_sending_sendme(circuit_t *circ, int edge_type, crypt_path_t *layer_hint) { - while((edge_type == EDGE_AP ? layer_hint->deliver_window : circ->deliver_window) < +void circuit_consider_sending_sendme(circuit_t *circ, crypt_path_t *layer_hint) { +// log_fn(LOG_INFO,"Considering: layer_hint is %s", +// layer_hint ? "defined" : "null"); + while((layer_hint ? layer_hint->deliver_window : circ->deliver_window) < CIRCWINDOW_START - CIRCWINDOW_INCREMENT) { log_fn(LOG_DEBUG,"Queueing circuit sendme."); - if(edge_type == EDGE_AP) + if(layer_hint) layer_hint->deliver_window += CIRCWINDOW_INCREMENT; else circ->deliver_window += CIRCWINDOW_INCREMENT; diff --git a/src/or/connection_edge.c b/src/or/connection_edge.c index 9f3c0aae1..f99da535c 100644 --- a/src/or/connection_edge.c +++ b/src/or/connection_edge.c @@ -219,7 +219,7 @@ int connection_edge_send_command(connection_t *fromconn, circuit_t *circ, /* an incoming relay cell has arrived. return -1 if you want to tear down the * circuit, else 0. */ int connection_edge_process_relay_cell(cell_t *cell, circuit_t *circ, - connection_t *conn, int edge_type, + connection_t *conn, crypt_path_t *layer_hint) { static int num_seen=0; uint32_t addr; @@ -283,7 +283,7 @@ int connection_edge_process_relay_cell(cell_t *cell, circuit_t *circ, log_fn(LOG_INFO,"Got a relay-level padding cell. Dropping."); return 0; case RELAY_COMMAND_BEGIN: - if (edge_type == EDGE_AP && + if (layer_hint && circ->purpose != CIRCUIT_PURPOSE_S_REND_JOINED) { log_fn(LOG_WARN,"relay begin request unsupported at AP. Dropping."); return 0; @@ -296,16 +296,16 @@ int connection_edge_process_relay_cell(cell_t *cell, circuit_t *circ, return 0; case RELAY_COMMAND_DATA: ++stats_n_data_cells_received; - if((edge_type == EDGE_AP && --layer_hint->deliver_window < 0) || - (edge_type == EDGE_EXIT && --circ->deliver_window < 0)) { + if((layer_hint && --layer_hint->deliver_window < 0) || + (!layer_hint && --circ->deliver_window < 0)) { log_fn(LOG_WARN,"(relay data) circ deliver_window below 0. Killing."); connection_mark_for_close(conn, END_STREAM_REASON_MISC); return -1; } - log_fn(LOG_DEBUG,"circ deliver_window now %d.", edge_type == EDGE_AP ? + log_fn(LOG_DEBUG,"circ deliver_window now %d.", layer_hint ? layer_hint->deliver_window : circ->deliver_window); - circuit_consider_sending_sendme(circ, edge_type, layer_hint); + circuit_consider_sending_sendme(circ, layer_hint); if(!conn) { log_fn(LOG_INFO,"data cell dropped, unknown stream."); @@ -373,8 +373,8 @@ int connection_edge_process_relay_cell(cell_t *cell, circuit_t *circ, } return circuit_extend(cell, circ); case RELAY_COMMAND_EXTENDED: - if(edge_type == EDGE_EXIT) { - log_fn(LOG_WARN,"'extended' unsupported at exit. Dropping."); + if(!layer_hint) { + log_fn(LOG_WARN,"'extended' unsupported at non-origin. Dropping."); return 0; } log_fn(LOG_DEBUG,"Got an extended cell! Yay."); @@ -388,8 +388,8 @@ int connection_edge_process_relay_cell(cell_t *cell, circuit_t *circ, } return 0; case RELAY_COMMAND_TRUNCATE: - if(edge_type == EDGE_AP) { - log_fn(LOG_WARN,"'truncate' unsupported at AP. Dropping."); + if(layer_hint) { + log_fn(LOG_WARN,"'truncate' unsupported at origin. Dropping."); return 0; } if(circ->n_conn) { @@ -401,33 +401,31 @@ int connection_edge_process_relay_cell(cell_t *cell, circuit_t *circ, NULL, 0, NULL); return 0; case RELAY_COMMAND_TRUNCATED: - if(edge_type == EDGE_EXIT) { - log_fn(LOG_WARN,"'truncated' unsupported at exit. Dropping."); + if(!layer_hint) { + log_fn(LOG_WARN,"'truncated' unsupported at non-origin. Dropping."); return 0; } circuit_truncated(circ, layer_hint); return 0; case RELAY_COMMAND_CONNECTED: if(conn) { - log_fn(LOG_WARN,"'connected' unsupported while open. Closing conn."); + log_fn(LOG_WARN,"'connected' unsupported while open. Closing circ."); return -1; } log_fn(LOG_INFO,"'connected' received, no conn attached anymore. Ignoring."); return 0; case RELAY_COMMAND_SENDME: if(!conn) { - if(edge_type == EDGE_AP) { - assert(layer_hint); + if(layer_hint) { layer_hint->package_window += CIRCWINDOW_INCREMENT; - log_fn(LOG_DEBUG,"circ-level sendme at AP, packagewindow %d.", + log_fn(LOG_DEBUG,"circ-level sendme at origin, packagewindow %d.", layer_hint->package_window); - circuit_resume_edge_reading(circ, EDGE_AP, layer_hint); + circuit_resume_edge_reading(circ, layer_hint); } else { - assert(!layer_hint); circ->package_window += CIRCWINDOW_INCREMENT; - log_fn(LOG_DEBUG,"circ-level sendme at exit, packagewindow %d.", + log_fn(LOG_DEBUG,"circ-level sendme at non-origin, packagewindow %d.", circ->package_window); - circuit_resume_edge_reading(circ, EDGE_EXIT, layer_hint); + circuit_resume_edge_reading(circ, layer_hint); } return 0; } @@ -533,7 +531,7 @@ repeat_connection_edge_package_raw_inbuf: return -1; } - if(circuit_consider_stop_edge_reading(circ, conn->type, conn->cpath_layer)) + if(circuit_consider_stop_edge_reading(circ, conn->cpath_layer)) return 0; if(conn->package_window <= 0) { @@ -564,11 +562,10 @@ repeat_connection_edge_package_raw_inbuf: payload, length, conn->cpath_layer) < 0) return 0; /* circuit is closed, don't continue */ - if(conn->type == CONN_TYPE_EXIT) { + if(!conn->cpath_layer) { /* non-rendezvous exit */ assert(circ->package_window > 0); circ->package_window--; - } else { /* we're an AP */ - assert(conn->type == CONN_TYPE_AP); + } else { /* we're an AP, or an exit on a rendezvous circ */ assert(conn->cpath_layer->package_window > 0); conn->cpath_layer->package_window--; } @@ -576,7 +573,7 @@ repeat_connection_edge_package_raw_inbuf: if(--conn->package_window <= 0) { /* is it 0 after decrement? */ connection_stop_reading(conn); log_fn(LOG_DEBUG,"conn->package_window reached 0."); - circuit_consider_stop_edge_reading(circ, conn->type, conn->cpath_layer); + circuit_consider_stop_edge_reading(circ, conn->cpath_layer); return 0; /* don't process the inbuf any more */ } log_fn(LOG_DEBUG,"conn->package_window is now %d",conn->package_window); diff --git a/src/or/or.h b/src/or/or.h index ca557c37b..a28885464 100644 --- a/src/or/or.h +++ b/src/or/or.h @@ -271,9 +271,9 @@ #define CELL_DIRECTION_IN 1 #define CELL_DIRECTION_OUT 2 -#define EDGE_EXIT CONN_TYPE_EXIT -#define EDGE_AP CONN_TYPE_AP -#define CELL_DIRECTION(x) ((x) == EDGE_EXIT ? CELL_DIRECTION_IN : CELL_DIRECTION_OUT) +//#define EDGE_EXIT CONN_TYPE_EXIT +//#define EDGE_AP CONN_TYPE_AP +//#define CELL_DIRECTION(x) ((x) == EDGE_EXIT ? CELL_DIRECTION_IN : CELL_DIRECTION_OUT) #ifdef TOR_PERF #define CIRCWINDOW_START 10000 @@ -721,9 +721,9 @@ int circuit_receive_relay_cell(cell_t *cell, circuit_t *circ, int circuit_package_relay_cell(cell_t *cell, circuit_t *circ, int cell_direction, crypt_path_t *layer_hint); -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, crypt_path_t *layer_hint); -void circuit_consider_sending_sendme(circuit_t *circ, int edge_type, crypt_path_t *layer_hint); +void circuit_resume_edge_reading(circuit_t *circ, crypt_path_t *layer_hint); +int circuit_consider_stop_edge_reading(circuit_t *circ, crypt_path_t *layer_hint); +void circuit_consider_sending_sendme(circuit_t *circ, crypt_path_t *layer_hint); void circuit_detach_stream(circuit_t *circ, connection_t *conn); void circuit_about_to_close_connection(connection_t *conn); @@ -850,7 +850,7 @@ int connection_edge_send_command(connection_t *fromconn, circuit_t *circ, int relay_command, const char *payload, int payload_len, crypt_path_t *cpath_layer); int connection_edge_process_relay_cell(cell_t *cell, circuit_t *circ, - connection_t *conn, int edge_type, + connection_t *conn, crypt_path_t *layer_hint); int connection_edge_finished_flushing(connection_t *conn); |