mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-12-06 19:41:15 +01:00
circuit-level sendmes weren't working, because the exit
thought it was an exit. i overhauled the edge_type mechanism. hopefully this will help. svn:r1570
This commit is contained in:
+49
-39
@@ -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;
|
||||
|
||||
+22
-25
@@ -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);
|
||||
|
||||
+7
-7
@@ -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);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user