mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-10 21:23:58 +01:00
implement truncate and truncated (untested)
clean up circuit_deliver_relay_cell convention svn:r312
This commit is contained in:
parent
7137a57849
commit
d3292e484a
@ -225,30 +225,6 @@ circuit_t *circuit_get_newest_ap(void) {
|
||||
return bestcirc;
|
||||
}
|
||||
|
||||
int circuit_deliver_relay_cell_from_edge(cell_t *cell, circuit_t *circ,
|
||||
char edge_type, crypt_path_t *layer_hint) {
|
||||
int cell_direction;
|
||||
static int numsent_ap=0, numsent_exit=0;
|
||||
|
||||
log(LOG_DEBUG,"circuit_deliver_relay_cell_from_edge(): called, edge_type %d.", edge_type);
|
||||
|
||||
if(edge_type == EDGE_AP) { /* i'm the AP */
|
||||
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);
|
||||
} else { /* i'm the exit */
|
||||
cell_direction = CELL_DIRECTION_IN;
|
||||
numsent_exit++;
|
||||
log(LOG_DEBUG,"circuit_deliver_relay_cell_from_edge(): now sent %d relay cells from exit", numsent_exit);
|
||||
}
|
||||
|
||||
if(circuit_deliver_relay_cell(cell, circ, cell_direction, layer_hint) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int circuit_deliver_relay_cell(cell_t *cell, circuit_t *circ,
|
||||
int cell_direction, crypt_path_t *layer_hint) {
|
||||
connection_t *conn=NULL;
|
||||
@ -483,7 +459,7 @@ int circuit_consider_sending_sendme(circuit_t *circ, int edge_type, crypt_path_t
|
||||
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) {
|
||||
if(circuit_deliver_relay_cell(&cell, circ, CELL_DIRECTION_OUT, layer_hint) < 0) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@ -492,7 +468,7 @@ int circuit_consider_sending_sendme(circuit_t *circ, int edge_type, crypt_path_t
|
||||
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) {
|
||||
if(circuit_deliver_relay_cell(&cell, circ, CELL_DIRECTION_IN, layer_hint) < 0) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@ -801,7 +777,7 @@ int circuit_send_next_onion_skin(circuit_t *circ) {
|
||||
|
||||
log(LOG_DEBUG,"circuit_send_next_onion_skin(): Sending extend relay cell.");
|
||||
/* send it to hop->prev, because it will transfer it to a create cell and then send to hop */
|
||||
if(circuit_deliver_relay_cell_from_edge(&cell, circ, EDGE_AP, hop->prev) < 0) {
|
||||
if(circuit_deliver_relay_cell(&cell, circ, CELL_DIRECTION_OUT, hop->prev) < 0) {
|
||||
log(LOG_DEBUG,"circuit_send_next_onion_skin(): failed to deliver extend cell. Closing.");
|
||||
return -1;
|
||||
}
|
||||
@ -921,6 +897,33 @@ int circuit_finish_handshake(circuit_t *circ, char *reply) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int circuit_truncated(circuit_t *circ, crypt_path_t *layer) {
|
||||
crypt_path_t *victim;
|
||||
connection_t *stream;
|
||||
|
||||
assert(circ);
|
||||
assert(layer);
|
||||
|
||||
while(layer->next != circ->cpath) {
|
||||
/* we need to clear out layer->next */
|
||||
victim = layer->next;
|
||||
log(LOG_DEBUG, "circuit_truncated(): Killing a layer of the cpath.");
|
||||
|
||||
for(stream = circ->p_streams; stream; stream=stream->next_stream) {
|
||||
if(stream->cpath_layer == victim) {
|
||||
log(LOG_DEBUG, "circuit_truncated(): Marking stream %d for close.", *(int*)stream->stream_id);
|
||||
stream->marked_for_close = 1;
|
||||
}
|
||||
}
|
||||
|
||||
layer->next = victim->next;
|
||||
circuit_free_cpath_node(victim);
|
||||
}
|
||||
|
||||
log(LOG_DEBUG, "circuit_truncated(): Complete.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
Local Variables:
|
||||
mode:c
|
||||
|
@ -147,7 +147,7 @@ void command_process_created_cell(cell_t *cell, connection_t *conn) {
|
||||
memcpy(newcell.payload+RELAY_HEADER_SIZE, cell->payload, DH_KEY_LEN);
|
||||
|
||||
log(LOG_DEBUG,"command_process_created_cell(): Sending extended relay cell.");
|
||||
if(circuit_deliver_relay_cell_from_edge(&newcell, circ, EDGE_EXIT, NULL) < 0) {
|
||||
if(circuit_deliver_relay_cell(&newcell, circ, CELL_DIRECTION_IN, NULL) < 0) {
|
||||
log(LOG_DEBUG,"command_process_created_cell(): failed to deliver extended cell. Closing.");
|
||||
circuit_close(circ);
|
||||
return;
|
||||
|
@ -685,8 +685,8 @@ repeat_connection_package_raw_inbuf:
|
||||
|
||||
if(conn->type == CONN_TYPE_EXIT) {
|
||||
cell.aci = circ->p_aci;
|
||||
if(circuit_deliver_relay_cell_from_edge(&cell, circ, EDGE_EXIT, NULL) < 0) {
|
||||
log(LOG_DEBUG,"connection_package_raw_inbuf(): circuit_deliver_relay_cell_from_edge (backward) failed. Closing.");
|
||||
if(circuit_deliver_relay_cell(&cell, circ, CELL_DIRECTION_IN, NULL) < 0) {
|
||||
log(LOG_DEBUG,"connection_package_raw_inbuf(): circuit_deliver_relay_cell (backward) failed. Closing.");
|
||||
circuit_close(circ);
|
||||
return 0;
|
||||
}
|
||||
@ -695,8 +695,8 @@ repeat_connection_package_raw_inbuf:
|
||||
} else { /* send it forward. we're an AP */
|
||||
assert(conn->type == CONN_TYPE_AP);
|
||||
cell.aci = circ->n_aci;
|
||||
if(circuit_deliver_relay_cell_from_edge(&cell, circ, EDGE_AP, conn->cpath_layer) < 0) {
|
||||
log(LOG_DEBUG,"connection_package_raw_inbuf(): circuit_deliver_relay_cell_from_edge (forward) failed. Closing.");
|
||||
if(circuit_deliver_relay_cell(&cell, circ, CELL_DIRECTION_OUT, conn->cpath_layer) < 0) {
|
||||
log(LOG_DEBUG,"connection_package_raw_inbuf(): circuit_deliver_relay_cell (forward) failed. Closing.");
|
||||
circuit_close(circ);
|
||||
return 0;
|
||||
}
|
||||
@ -749,8 +749,8 @@ int connection_consider_sending_sendme(connection_t *conn, int edge_type) {
|
||||
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.");
|
||||
if(circuit_deliver_relay_cell(&cell, circ, CELL_DIRECTION(edge_type), conn->cpath_layer) < 0) {
|
||||
log(LOG_DEBUG,"connection_consider_sending_sendme(): circuit_deliver_relay_cell failed. Closing.");
|
||||
circuit_close(circ);
|
||||
return 0;
|
||||
}
|
||||
|
@ -136,7 +136,7 @@ int ap_handshake_send_begin(connection_t *ap_conn, circuit_t *circ) {
|
||||
"%s:%d", ap_conn->dest_addr, ap_conn->dest_port) +
|
||||
1 + STREAM_ID_SIZE + RELAY_HEADER_SIZE;
|
||||
log(LOG_DEBUG,"ap_handshake_send_begin(): Sending relay cell (id %d) to begin stream %d.", *(int *)(cell.payload+1),*(int *)ap_conn->stream_id);
|
||||
if(circuit_deliver_relay_cell_from_edge(&cell, circ, EDGE_AP, ap_conn->cpath_layer) < 0) {
|
||||
if(circuit_deliver_relay_cell(&cell, circ, CELL_DIRECTION_OUT, ap_conn->cpath_layer) < 0) {
|
||||
log(LOG_DEBUG,"ap_handshake_send_begin(): failed to deliver begin cell. Closing.");
|
||||
return -1;
|
||||
}
|
||||
|
@ -31,8 +31,8 @@ int connection_edge_process_inbuf(connection_t *conn) {
|
||||
SET_CELL_STREAM_ID(cell, conn->stream_id);
|
||||
cell.aci = circ->n_aci;
|
||||
|
||||
if (circuit_deliver_relay_cell_from_edge(&cell, circ, conn->type, conn->cpath_layer) < 0) {
|
||||
log(LOG_DEBUG,"connection_edge_process_inbuf: circuit_deliver_relay_cell_from_edge failed. Closing");
|
||||
if (circuit_deliver_relay_cell(&cell, circ, CELL_DIRECTION(conn->type), conn->cpath_layer) < 0) {
|
||||
log(LOG_DEBUG,"connection_edge_process_inbuf: circuit_deliver_relay_cell failed. Closing.");
|
||||
circuit_close(circ);
|
||||
}
|
||||
return 0;
|
||||
@ -60,30 +60,37 @@ int connection_edge_process_inbuf(connection_t *conn) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int connection_edge_send_command(connection_t *conn, circuit_t *circ, int relay_command) {
|
||||
int connection_edge_send_command(connection_t *fromconn, circuit_t *circ, int relay_command) {
|
||||
cell_t cell;
|
||||
|
||||
assert(conn);
|
||||
int cell_direction;
|
||||
|
||||
if(!circ) {
|
||||
log(LOG_DEBUG,"connection_edge_send_command(): conn has no circ. Closing.");
|
||||
log(LOG_DEBUG,"connection_edge_send_command(): no circ. Closing.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
memset(&cell, 0, sizeof(cell_t));
|
||||
if(conn->type == CONN_TYPE_AP)
|
||||
if(fromconn && fromconn->type == CONN_TYPE_AP) {
|
||||
cell.aci = circ->n_aci;
|
||||
else
|
||||
cell_direction = CELL_DIRECTION_OUT;
|
||||
} else {
|
||||
/* NOTE: if !fromconn, we assume that it's heading towards the OP */
|
||||
cell.aci = circ->p_aci;
|
||||
cell_direction = CELL_DIRECTION_IN;
|
||||
}
|
||||
|
||||
cell.command = CELL_RELAY;
|
||||
SET_CELL_RELAY_COMMAND(cell, relay_command);
|
||||
SET_CELL_STREAM_ID(cell, conn->stream_id);
|
||||
if(fromconn)
|
||||
SET_CELL_STREAM_ID(cell, fromconn->stream_id);
|
||||
else
|
||||
SET_CELL_STREAM_ID(cell, ZERO_STREAM);
|
||||
|
||||
cell.length = RELAY_HEADER_SIZE;
|
||||
log(LOG_INFO,"connection_edge_send_command(): delivering %d cell %s.", relay_command, conn->type == CONN_TYPE_AP ? "forward" : "backward");
|
||||
log(LOG_INFO,"connection_edge_send_command(): delivering %d cell %s.", relay_command, cell_direction == CELL_DIRECTION_OUT ? "forward" : "backward");
|
||||
|
||||
if(circuit_deliver_relay_cell_from_edge(&cell, circ, conn->type, conn->cpath_layer) < 0) {
|
||||
log(LOG_DEBUG,"connection_edge_send_command(): circuit_deliver_relay_cell_from_edge failed. Closing.");
|
||||
if(circuit_deliver_relay_cell(&cell, circ, cell_direction, fromconn ? fromconn->cpath_layer : NULL) < 0) {
|
||||
log(LOG_DEBUG,"connection_edge_send_command(): circuit_deliver_relay_cell failed. Closing.");
|
||||
circuit_close(circ);
|
||||
return 0;
|
||||
}
|
||||
@ -199,6 +206,23 @@ int connection_edge_process_relay_cell(cell_t *cell, circuit_t *circ, connection
|
||||
return -1;
|
||||
}
|
||||
return circuit_send_next_onion_skin(circ);
|
||||
case RELAY_COMMAND_TRUNCATE:
|
||||
if(edge_type == EDGE_AP) {
|
||||
log(LOG_INFO,"connection_edge_process_relay_cell(): 'truncate' unsupported at AP. Dropping.");
|
||||
return 0;
|
||||
}
|
||||
if(circ->n_conn) {
|
||||
connection_send_destroy(circ->n_aci, circ->n_conn);
|
||||
circ->n_conn = NULL;
|
||||
}
|
||||
log(LOG_DEBUG, "connection_edge_process_relay_cell(): Processed 'truncate', replying.");
|
||||
return connection_edge_send_command(NULL, circ, RELAY_COMMAND_TRUNCATED);
|
||||
case RELAY_COMMAND_TRUNCATED:
|
||||
if(edge_type == EDGE_EXIT) {
|
||||
log(LOG_INFO,"connection_edge_process_relay_cell(): 'truncated' unsupported at exit. Dropping.");
|
||||
return 0;
|
||||
}
|
||||
return circuit_truncated(circ, layer_hint);
|
||||
case RELAY_COMMAND_CONNECTED:
|
||||
if(edge_type == EDGE_EXIT) {
|
||||
log(LOG_INFO,"connection_edge_process_relay_cell(): 'connected' unsupported at exit. Dropping.");
|
||||
|
@ -286,6 +286,7 @@ static int dns_find_idle_slave(int max) {
|
||||
}
|
||||
|
||||
assert(0); /* should never get here */
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dns_assign_to_slave(int from, int to) {
|
||||
|
@ -428,20 +428,6 @@ crypt_path_t *onion_generate_cpath(routerinfo_t **firsthop) {
|
||||
* The first 128 bytes are RSA-encrypted with the server's public key,
|
||||
* and the last 16 are encrypted with the symmetric key.
|
||||
*/
|
||||
/* FIXME:
|
||||
Nick: looks like we could simplify this by just using 128 bytes for g^x.
|
||||
|
||||
Problem: this will fail if g^x is greater than the RSA modulus.
|
||||
We'd need to repeatedly generate g^x, until we got one that was
|
||||
< the RSA modulus. Also, if we ever can afford to revert to a
|
||||
bigger DH key, we'll need to revert. Are these 'features' ok?
|
||||
If so, we can omit the symmetric encryption.
|
||||
|
||||
Convesely, we can just increment RSA key sizes. Since we don't
|
||||
use them very often comparatively, we may be able to afford 1536
|
||||
bits. (Just a thought.)
|
||||
-NM
|
||||
*/
|
||||
int
|
||||
onion_skin_create(crypto_pk_env_t *dest_router_key,
|
||||
crypto_dh_env_t **handshake_state_out,
|
||||
|
@ -122,6 +122,8 @@
|
||||
#define RELAY_COMMAND_SENDME 5
|
||||
#define RELAY_COMMAND_EXTEND 6
|
||||
#define RELAY_COMMAND_EXTENDED 7
|
||||
#define RELAY_COMMAND_TRUNCATE 8
|
||||
#define RELAY_COMMAND_TRUNCATED 9
|
||||
|
||||
#define RELAY_HEADER_SIZE 8
|
||||
|
||||
@ -134,6 +136,7 @@
|
||||
#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 CIRCWINDOW_START 1000
|
||||
#define CIRCWINDOW_INCREMENT 100
|
||||
@ -492,8 +495,6 @@ circuit_t *circuit_get_by_conn(connection_t *conn);
|
||||
circuit_t *circuit_get_newest_ap(void);
|
||||
circuit_t *circuit_enumerate_by_naddr_nport(circuit_t *start, uint32_t naddr, uint16_t nport);
|
||||
|
||||
int circuit_deliver_relay_cell_from_edge(cell_t *cell, circuit_t *circ,
|
||||
char edge_type, crypt_path_t *layer_hint);
|
||||
int circuit_deliver_relay_cell(cell_t *cell, circuit_t *circ,
|
||||
int cell_direction, crypt_path_t *layer_hint);
|
||||
int relay_crypt(circuit_t *circ, char *in, int inlen, char cell_direction,
|
||||
@ -522,6 +523,7 @@ void circuit_n_conn_open(connection_t *or_conn);
|
||||
int circuit_send_next_onion_skin(circuit_t *circ);
|
||||
int circuit_extend(cell_t *cell, circuit_t *circ);
|
||||
int circuit_finish_handshake(circuit_t *circ, char *reply);
|
||||
int circuit_truncated(circuit_t *circ, crypt_path_t *layer);
|
||||
|
||||
/********************************* command.c ***************************/
|
||||
|
||||
@ -633,7 +635,7 @@ int connection_ap_handle_listener_read(connection_t *conn);
|
||||
/********************************* connection_edge.c ***************************/
|
||||
|
||||
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 *fromconn, circuit_t *circ, int relay_command);
|
||||
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);
|
||||
|
||||
|
@ -510,6 +510,7 @@ test_onion_handshake() {
|
||||
crypto_dh_free(c_dh);
|
||||
crypto_free_pk_env(pk);
|
||||
|
||||
/* FIXME sometimes (infrequently) the following fails! Why? */
|
||||
test_memeq(c_keys, s_keys, 40);
|
||||
memset(s_buf, 0, 40);
|
||||
test_memneq(c_keys, s_buf, 40);
|
||||
|
Loading…
Reference in New Issue
Block a user