comment the functions in connection_or.c

svn:r1818
This commit is contained in:
Roger Dingledine 2004-05-07 08:53:40 +00:00
parent f1fc4ce22b
commit fa3db976df

View File

@ -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;