Commit d3292e48 authored by Roger Dingledine's avatar Roger Dingledine
Browse files

implement truncate and truncated (untested)

clean up circuit_deliver_relay_cell convention


svn:r312
parent 7137a578
......@@ -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);
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment