diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/or/circuit.c | 6 | ||||
-rw-r--r-- | src/or/command.c | 20 | ||||
-rw-r--r-- | src/or/connection_edge.c | 131 | ||||
-rw-r--r-- | src/or/main.c | 14 | ||||
-rw-r--r-- | src/or/or.h | 4 |
5 files changed, 70 insertions, 105 deletions
diff --git a/src/or/circuit.c b/src/or/circuit.c index 356e89559..b23b55701 100644 --- a/src/or/circuit.c +++ b/src/or/circuit.c @@ -543,10 +543,8 @@ void circuit_about_to_close_connection(connection_t *conn) { log_fn(LOG_ERR,"edge conn not in circuit's list?"); assert(0); /* should never get here */ send_end: - if(connection_edge_send_command(conn, circ, RELAY_COMMAND_END) < 0) { - log_fn(LOG_DEBUG,"sending end failed. Closing."); - circuit_close(circ); - } + connection_edge_send_command(conn, circ, RELAY_COMMAND_END, + NULL, 0, conn->cpath_layer); return; } diff --git a/src/or/command.c b/src/or/command.c index 8caabf41d..129dcfecb 100644 --- a/src/or/command.c +++ b/src/or/command.c @@ -122,7 +122,6 @@ static void command_process_create_cell(cell_t *cell, connection_t *conn) { static void command_process_created_cell(cell_t *cell, connection_t *conn) { circuit_t *circ; - cell_t newcell; circ = circuit_get_by_aci_conn(cell->aci, conn); @@ -152,21 +151,9 @@ static void command_process_created_cell(cell_t *cell, connection_t *conn) { return; } } else { /* pack it into an extended relay cell, and send it. */ - memset(&newcell, 0, sizeof(cell_t)); - newcell.command = CELL_RELAY; - newcell.aci = circ->p_aci; - SET_CELL_RELAY_COMMAND(newcell, RELAY_COMMAND_EXTENDED); - SET_CELL_STREAM_ID(newcell, ZERO_STREAM); - - newcell.length = RELAY_HEADER_SIZE + cell->length; - memcpy(newcell.payload+RELAY_HEADER_SIZE, cell->payload, DH_KEY_LEN); - log_fn(LOG_INFO,"Converting created cell to extended relay cell, sending."); - if(circuit_deliver_relay_cell(&newcell, circ, CELL_DIRECTION_IN, NULL) < 0) { - log_fn(LOG_WARNING,"failed to deliver extended cell. Closing."); - circuit_close(circ); - return; - } + connection_edge_send_command(NULL, circ, RELAY_COMMAND_EXTENDED, + cell->payload, DH_KEY_LEN, NULL); } } @@ -225,7 +212,8 @@ static void command_process_destroy_cell(cell_t *cell, connection_t *conn) { } else { /* the destroy came from ahead */ circ->n_conn = NULL; log_fn(LOG_DEBUG, "Delivering 'truncated' back."); - connection_edge_send_command(NULL, circ, RELAY_COMMAND_TRUNCATED); + connection_edge_send_command(NULL, circ, RELAY_COMMAND_TRUNCATED, + NULL, 0, NULL); } } diff --git a/src/or/connection_edge.c b/src/or/connection_edge.c index b8a5d3eec..051ba16d9 100644 --- a/src/or/connection_edge.c +++ b/src/or/connection_edge.c @@ -28,21 +28,8 @@ int connection_edge_process_inbuf(connection_t *conn) { /*ENDCLOSE*/ conn->marked_for_close = 1; /* XXX Factor out common logic here and in circuit_about_to_close NM */ - circ = circuit_get_by_conn(conn); - if (!circ) - return -1; - - memset(&cell, 0, sizeof(cell_t)); - cell.command = CELL_RELAY; - cell.length = RELAY_HEADER_SIZE; - SET_CELL_RELAY_COMMAND(cell, RELAY_COMMAND_END); - SET_CELL_STREAM_ID(cell, conn->stream_id); - cell.aci = circ->n_aci; - - if (circuit_deliver_relay_cell(&cell, circ, CELL_DIRECTION(conn->type), conn->cpath_layer) < 0) { - log_fn(LOG_WARNING,"(fd %d) circuit_deliver_relay_cell failed. Closing.", conn->s); - circuit_close(circ); - } + connection_edge_send_command(conn, circuit_get_by_conn(conn), RELAY_COMMAND_END, + NULL, 0, conn->cpath_layer); return 0; #else /* eof reached, kill it. */ @@ -67,15 +54,20 @@ int connection_edge_process_inbuf(connection_t *conn) { return 0; } -int connection_edge_send_command(connection_t *fromconn, circuit_t *circ, int relay_command) { +void connection_edge_send_command(connection_t *fromconn, circuit_t *circ, int relay_command, + void *payload, int payload_len, crypt_path_t *cpath_layer) { cell_t cell; int cell_direction; + int is_control_cell=0; if(!circ) { log_fn(LOG_WARNING,"no circ. Closing."); - return -1; + return; } + if(!fromconn || relay_command == RELAY_COMMAND_BEGIN) /* XXX more */ + is_control_cell = 1; + memset(&cell, 0, sizeof(cell_t)); if(fromconn && fromconn->type == CONN_TYPE_AP) { cell.aci = circ->n_aci; @@ -88,20 +80,22 @@ int connection_edge_send_command(connection_t *fromconn, circuit_t *circ, int re cell.command = CELL_RELAY; SET_CELL_RELAY_COMMAND(cell, relay_command); - if(fromconn) - SET_CELL_STREAM_ID(cell, fromconn->stream_id); - else + if(is_control_cell) SET_CELL_STREAM_ID(cell, ZERO_STREAM); + else + SET_CELL_STREAM_ID(cell, fromconn->stream_id); - cell.length = RELAY_HEADER_SIZE; - log_fn(LOG_INFO,"delivering %d cell %s.", relay_command, cell_direction == CELL_DIRECTION_OUT ? "forward" : "backward"); + cell.length = RELAY_HEADER_SIZE + payload_len; + if(payload_len) { + memcpy(cell.payload+RELAY_HEADER_SIZE,payload,payload_len); + } + log_fn(LOG_INFO,"delivering %d cell %s.", relay_command, + cell_direction == CELL_DIRECTION_OUT ? "forward" : "backward"); - if(circuit_deliver_relay_cell(&cell, circ, cell_direction, fromconn ? fromconn->cpath_layer : NULL) < 0) { + if(circuit_deliver_relay_cell(&cell, circ, cell_direction, cpath_layer) < 0) { log_fn(LOG_WARNING,"circuit_deliver_relay_cell failed. Closing."); circuit_close(circ); - return 0; } - return 0; } /* an incoming relay cell has arrived. return -1 if you want to tear down the @@ -217,7 +211,9 @@ int connection_edge_process_relay_cell(cell_t *cell, circuit_t *circ, connection circ->n_conn = NULL; } log_fn(LOG_DEBUG, "Processed 'truncate', replying."); - return connection_edge_send_command(NULL, circ, RELAY_COMMAND_TRUNCATED); + connection_edge_send_command(NULL, circ, RELAY_COMMAND_TRUNCATED, + NULL, 0, NULL); + return 0; case RELAY_COMMAND_TRUNCATED: if(edge_type == EDGE_EXIT) { log_fn(LOG_WARNING,"'truncated' unsupported at exit. Dropping."); @@ -292,9 +288,10 @@ int connection_edge_finished_flushing(connection_t *conn) { connection_watch_events(conn, POLLIN); /* stop writing, continue reading */ if(connection_wants_to_flush(conn)) /* in case there are any queued relay cells */ connection_start_writing(conn); - return - connection_edge_send_command(conn, circuit_get_by_conn(conn), RELAY_COMMAND_CONNECTED) || /* deliver a 'connected' relay cell back through the circuit. */ - connection_process_inbuf(conn); /* in case the server has written anything */ + /* deliver a 'connected' relay cell back through the circuit. */ + connection_edge_send_command(conn, circuit_get_by_conn(conn), RELAY_COMMAND_CONNECTED, + NULL, 0, conn->cpath_layer); + return connection_process_inbuf(conn); /* in case the server has written anything */ case AP_CONN_STATE_OPEN: case EXIT_CONN_STATE_OPEN: connection_stop_writing(conn); @@ -316,8 +313,8 @@ uint64_t stats_n_data_cells_received = 0; uint64_t stats_n_data_bytes_received = 0; int connection_package_raw_inbuf(connection_t *conn) { - int amount_to_process; - cell_t cell; + int amount_to_process, length; + char payload[CELL_PAYLOAD_SIZE]; circuit_t *circ; assert(conn); @@ -345,49 +342,31 @@ repeat_connection_package_raw_inbuf: if(!amount_to_process) return 0; - /* Initialize the cell with 0's */ - memset(&cell, 0, sizeof(cell_t)); - if(amount_to_process > CELL_PAYLOAD_SIZE - RELAY_HEADER_SIZE) { - cell.length = CELL_PAYLOAD_SIZE - RELAY_HEADER_SIZE; + length = CELL_PAYLOAD_SIZE - RELAY_HEADER_SIZE; } else { - cell.length = amount_to_process; + length = amount_to_process; } - stats_n_data_bytes_packaged += cell.length; + stats_n_data_bytes_packaged += length; stats_n_data_cells_packaged += 1; - connection_fetch_from_buf(cell.payload+RELAY_HEADER_SIZE, cell.length, conn); - - log_fn(LOG_DEBUG,"(%d) Packaging %d bytes (%d waiting).",conn->s,cell.length, + connection_fetch_from_buf(payload, length, conn); + + log_fn(LOG_DEBUG,"(%d) Packaging %d bytes (%d waiting).",conn->s,length, (int)buf_datalen(conn->inbuf)); - cell.command = CELL_RELAY; - SET_CELL_RELAY_COMMAND(cell, RELAY_COMMAND_DATA); - SET_CELL_STREAM_ID(cell, conn->stream_id); - cell.length += RELAY_HEADER_SIZE; - + connection_edge_send_command(conn, circ, RELAY_COMMAND_DATA, + payload, length, conn->cpath_layer); + if(conn->type == CONN_TYPE_EXIT) { - cell.aci = circ->p_aci; - if(circuit_deliver_relay_cell(&cell, circ, CELL_DIRECTION_IN, NULL) < 0) { - log_fn(LOG_WARNING,"circuit_deliver_relay_cell (backward) failed. Closing."); - circuit_close(circ); - return 0; - } assert(circ->package_window > 0); circ->package_window--; - } else { /* send it forward. we're an AP */ + } else { /* we're an AP */ assert(conn->type == CONN_TYPE_AP); - cell.aci = circ->n_aci; - if(circuit_deliver_relay_cell(&cell, circ, CELL_DIRECTION_OUT, conn->cpath_layer) < 0) { - log_fn(LOG_WARNING,"circuit_deliver_relay_cell (forward) failed. Closing."); - circuit_close(circ); - return 0; - } assert(conn->cpath_layer->package_window > 0); conn->cpath_layer->package_window--; } - assert(conn->package_window > 0); if(--conn->package_window <= 0) { /* is it 0 after decrement? */ connection_stop_reading(conn); log_fn(LOG_DEBUG,"conn->package_window reached 0."); @@ -493,27 +472,23 @@ static int connection_ap_handshake_process_socks(connection_t *conn) { /* deliver the destaddr:destport in a relay cell */ static int connection_ap_handshake_send_begin(connection_t *ap_conn, circuit_t *circ, char *destaddr, uint16_t destport) { - cell_t cell; - memset(&cell, 0, sizeof(cell_t)); + char payload[CELL_PAYLOAD_SIZE]; + int payload_len; - cell.command = CELL_RELAY; - cell.aci = circ->n_aci; - SET_CELL_RELAY_COMMAND(cell, RELAY_COMMAND_BEGIN); if(crypto_pseudo_rand(STREAM_ID_SIZE, ap_conn->stream_id) < 0) return -1; /* FIXME check for collisions */ - SET_CELL_STREAM_ID(cell, ZERO_STREAM); - - memcpy(cell.payload+RELAY_HEADER_SIZE, ap_conn->stream_id, STREAM_ID_SIZE); - cell.length = - snprintf(cell.payload+RELAY_HEADER_SIZE+STREAM_ID_SIZE, CELL_PAYLOAD_SIZE-RELAY_HEADER_SIZE-STREAM_ID_SIZE, - "%s:%d", destaddr, destport) + - 1 + STREAM_ID_SIZE + RELAY_HEADER_SIZE; - log_fn(LOG_DEBUG,"Sending relay cell (id %d) to begin stream %d.", *(int *)(cell.payload+1),*(int *)ap_conn->stream_id); - if(circuit_deliver_relay_cell(&cell, circ, CELL_DIRECTION_OUT, ap_conn->cpath_layer) < 0) { - log_fn(LOG_WARNING,"failed to deliver begin cell. Closing."); - return -1; - } + + memcpy(payload, ap_conn->stream_id, STREAM_ID_SIZE); + payload_len = STREAM_ID_SIZE + 1 + + snprintf(payload+STREAM_ID_SIZE,CELL_PAYLOAD_SIZE-RELAY_HEADER_SIZE-STREAM_ID_SIZE, + "%s:%d", destaddr, destport); + + log_fn(LOG_DEBUG,"Sending relay cell to begin stream %d.",*(int *)ap_conn->stream_id); + + connection_edge_send_command(ap_conn, circ, RELAY_COMMAND_BEGIN, + payload, payload_len, ap_conn->cpath_layer); + ap_conn->package_window = STREAMWINDOW_START; ap_conn->deliver_window = STREAMWINDOW_START; ap_conn->state = AP_CONN_STATE_OPEN; @@ -640,7 +615,9 @@ int connection_exit_connect(connection_t *conn) { connection_watch_events(conn, POLLIN); /* also, deliver a 'connected' cell back through the circuit. */ - return connection_edge_send_command(conn, circuit_get_by_conn(conn), RELAY_COMMAND_CONNECTED); + connection_edge_send_command(conn, circuit_get_by_conn(conn), RELAY_COMMAND_CONNECTED, + NULL, 0, conn->cpath_layer); + return 0; } /* diff --git a/src/or/main.c b/src/or/main.c index e0bec8c78..f66f2c68b 100644 --- a/src/or/main.c +++ b/src/or/main.c @@ -676,12 +676,12 @@ static void dumpstats(void) { /* dump stats to stdout */ circuit_dump_by_conn(conn); /* dump info about all the circuits using this conn */ printf("\n"); } - printf("Cells processed: %10lud padding\n" - " %10lud create\n" - " %10lud created\n" - " %10lud relay\n" - " (%10lud relayed)\n" - " (%10lud delivered)\n" + printf("Cells processed: %10lu padding\n" + " %10lu create\n" + " %10lu created\n" + " %10lu relay\n" + " (%10lu relayed)\n" + " (%10lu delivered)\n" " %10lud destroy\n", stats_n_padding_cells_processed, stats_n_create_cells_processed, @@ -695,7 +695,7 @@ static void dumpstats(void) { /* dump stats to stdout */ 100*(((double)stats_n_data_bytes_packaged) / (stats_n_data_cells_packaged*(CELL_PAYLOAD_SIZE-RELAY_HEADER_SIZE))) ); if (stats_n_data_cells_packaged) - printf("Average incomoing cell fullness: %2.3f%%\n", + printf("Average incoming cell fullness: %2.3f%%\n", 100*(((double)stats_n_data_bytes_received) / (stats_n_data_cells_received*(CELL_PAYLOAD_SIZE-RELAY_HEADER_SIZE))) ); diff --git a/src/or/or.h b/src/or/or.h index 857ed5d48..a50f2002f 100644 --- a/src/or/or.h +++ b/src/or/or.h @@ -575,7 +575,9 @@ void assert_connection_ok(connection_t *conn, time_t now); /********************************* connection_edge.c ***************************/ int connection_edge_process_inbuf(connection_t *conn); -int connection_edge_send_command(connection_t *fromconn, circuit_t *circ, int relay_command); +void connection_edge_send_command(connection_t *fromconn, circuit_t *circ, int relay_command, + void *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, crypt_path_t *layer_hint); int connection_edge_finished_flushing(connection_t *conn); |