From fa3db976df7e999c1644146ad3f3aed4ca056fa2 Mon Sep 17 00:00:00 2001 From: Roger Dingledine Date: Fri, 7 May 2004 08:53:40 +0000 Subject: [PATCH] comment the functions in connection_or.c svn:r1818 --- src/or/connection_or.c | 88 ++++++++++++++++++++++++++++++++++++++---- 1 file changed, 80 insertions(+), 8 deletions(-) diff --git a/src/or/connection_or.c b/src/or/connection_or.c index 133caca472..85afb01505 100644 --- a/src/or/connection_or.c +++ b/src/or/connection_or.c @@ -11,12 +11,19 @@ static int connection_or_process_cells_from_inbuf(connection_t *conn); /**************************************************************/ +/* Pack the cell_t host-order structure 'src' into network-order + * in the buffer 'dest'. See tor-spec.txt for details about the + * wire format. + */ static void cell_pack(char *dest, const cell_t *src) { *(uint16_t*)dest = htons(src->circ_id); *(uint8_t*)(dest+2) = src->command; memcpy(dest+3, src->payload, CELL_PAYLOAD_SIZE); } +/* Unpack the network-order buffer 'src' into a host-order + * cell_t structure 'dest'. + */ static void cell_unpack(cell_t *dest, const char *src) { dest->circ_id = ntohs(*(uint16_t*)(src)); dest->command = *(uint8_t*)(src+2); @@ -25,6 +32,11 @@ static void cell_unpack(cell_t *dest, const char *src) { /**************************************************************/ +/* Handle any new bytes that have come in on connection 'conn'. + * If conn is in 'open' state, hand it to + * connection_or_process_cells_from_inbuf() + * (else do nothing). + */ int connection_or_process_inbuf(connection_t *conn) { tor_assert(conn && conn->type == CONN_TYPE_OR); @@ -40,6 +52,14 @@ int connection_or_process_inbuf(connection_t *conn) { return connection_or_process_cells_from_inbuf(conn); } +/* Connection 'conn' has finished writing and has no bytes left on + * its outbuf. + * + * If it's in state 'connecting', then take a look at the socket, and + * begin the tls handshake if the connect succeeded. + * + * Otherwise it's in state 'open': stop writing and return. + */ int connection_or_finished_flushing(connection_t *conn) { int e, len=sizeof(e); @@ -79,7 +99,13 @@ int connection_or_finished_flushing(connection_t *conn) { /*********************/ -void connection_or_init_conn_from_router(connection_t *conn, routerinfo_t *router) { +/* Initialize conn to include all the relevant data from router. + * This function is called either from connection_or_connect(), if + * we initiated the connect, or from connection_tls_finish_handshake() + * if the other side initiated it. + */ +static void +connection_or_init_conn_from_router(connection_t *conn, routerinfo_t *router) { conn->addr = router->addr; conn->port = router->or_port; conn->receiver_bucket = conn->bandwidth = router->bandwidthburst; @@ -89,6 +115,19 @@ void connection_or_init_conn_from_router(connection_t *conn, routerinfo_t *route conn->address = tor_strdup(router->address); } +/* Launch a new OR connection to 'router'. + * + * If router is me, do nothing. If we're already connected to router, + * return that connection. If the connect is in progress, set conn's + * state to 'connecting' and return. If connect to router succeeds, call + * connection_tls_start_handshake() on it. + * + * This function is called from router_retry_connections() , for + * ORs connecting to ORs, and circuit_establish_circuit(), for + * OPs connecting to ORs. + * + * Return the launched conn, or NULL if it failed. + */ connection_t *connection_or_connect(routerinfo_t *router) { connection_t *conn; @@ -131,8 +170,14 @@ connection_t *connection_or_connect(routerinfo_t *router) { return NULL; } -/* ********************************** */ - +/* Begin the tls handshake with conn. 'receiving' is 0 if we initiated + * the connection, else it's 1. + * + * Assign a new tls object to conn->tls, begin reading on conn, and pass + * conn to connection_tls_continue_handshake(). + * + * Return -1 if conn is broken, else return 0. + */ int connection_tls_start_handshake(connection_t *conn, int receiving) { conn->state = OR_CONN_STATE_HANDSHAKING; conn->tls = tor_tls_new(conn->s, receiving); @@ -148,6 +193,11 @@ int connection_tls_start_handshake(connection_t *conn, int receiving) { return 0; } +/* Move forward with ths tls handshake. If it finishes, hand + * conn to connection_tls_finish_handshake(). + * + * Return -1 if conn is broken, else return 0. + */ int connection_tls_continue_handshake(connection_t *conn) { switch(tor_tls_handshake(conn->tls)) { case TOR_TLS_ERROR: @@ -167,13 +217,32 @@ int connection_tls_continue_handshake(connection_t *conn) { return 0; } -static int connection_tls_finish_handshake(connection_t *conn) { +/* The tls handshake is finished. + * + * Make sure we are happy with the person we just handshaked with: + * If it's an OP (that is, it has no certificate), make sure I'm an OR. + * If it's an OR (is has a certificate), make sure it has a recognized + * nickname, its cert is signed by the identity key of that nickname; + * if I initiated the connection, make sure it's the right guy, and if + * he initiated the connection, make sure he's not already connected. + * + * If he initiated the conn, also initialize conn from the information + * in router. + * + * If either of us is an OP, set bandwidth to the default OP bandwidth. + * + * If all is successful and he's an OR, then call circuit_n_conn_open() + * to handle events that have been pending on the tls handshake + * completion, and set the directory to be dirty (only matters if I'm + * a dirserver). + */ +static int +connection_tls_finish_handshake(connection_t *conn) { routerinfo_t *router; char nickname[MAX_NICKNAME_LEN+1]; connection_t *c; conn->state = OR_CONN_STATE_OPEN; - directory_set_dirty(); connection_watch_events(conn, POLLIN); log_fn(LOG_DEBUG,"tls handshake done. verifying."); if (! tor_tls_peer_has_cert(conn->tls)) { /* It's an OP. */ @@ -225,14 +294,14 @@ static int connection_tls_finish_handshake(connection_t *conn) { if (!options.ORPort) { /* If I'm an OP... */ conn->receiver_bucket = conn->bandwidth = DEFAULT_BANDWIDTH_OP; } + directory_set_dirty(); circuit_n_conn_open(conn); /* send the pending creates, if any. */ /* Note the success */ rep_hist_note_connect_succeeded(nickname, time(NULL)); return 0; } -/* ********************************** */ - +/* Pack 'cell' into wire-format, and write it onto conn's outbuf. */ void connection_or_write_cell_to_buf(const cell_t *cell, connection_t *conn) { char networkcell[CELL_NETWORK_SIZE]; char *n = networkcell; @@ -245,7 +314,10 @@ void connection_or_write_cell_to_buf(const cell_t *cell, connection_t *conn) { connection_write_to_buf(n, CELL_NETWORK_SIZE, conn); } -/* if there's a whole cell there, pull it off and process it. */ +/* Process cells from conn's inbuf. Loop: while inbuf contains a cell, pull + * it off the inbuf, unpack it, and hand it to command_process_cell(). + * Always return 0. + */ static int connection_or_process_cells_from_inbuf(connection_t *conn) { char buf[CELL_NETWORK_SIZE]; cell_t cell;