summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoger Dingledine <arma@torproject.org>2004-05-10 01:32:57 +0000
committerRoger Dingledine <arma@torproject.org>2004-05-10 01:32:57 +0000
commit8f6aa6688fa6c5bfa60e0935780f6f6f0c70410b (patch)
tree4d83ba8bb91f4e223859c08eda7fe16e821b75db
parentc6d4a00c5fac0ca22d1a24bc7fc37a6751b74a95 (diff)
downloadtor-8f6aa6688fa6c5bfa60e0935780f6f6f0c70410b.tar.gz
tor-8f6aa6688fa6c5bfa60e0935780f6f6f0c70410b.zip
function header comments for connection.c, including doxygen markup
svn:r1825
-rw-r--r--src/or/connection.c174
1 files changed, 148 insertions, 26 deletions
diff --git a/src/or/connection.c b/src/or/connection.c
index 75d0981f32..e165dae33b 100644
--- a/src/or/connection.c
+++ b/src/or/connection.c
@@ -6,9 +6,9 @@
/********* START VARIABLES **********/
-extern or_options_t options; /* command-line and config-file options */
+extern or_options_t options; /**< command-line and config-file options */
-/* Array of strings to make conn->type human-readable */
+/** Array of strings to make conn->type human-readable */
char *conn_type_to_string[] = {
"", /* 0 */
"OP listener", /* 1 */
@@ -24,7 +24,7 @@ char *conn_type_to_string[] = {
"CPU worker", /* 11 */
};
-/* Array of string arrays to make {conn->type,conn->state} human-readable */
+/** Array of string arrays to make {conn->type,conn->state} human-readable */
char *conn_state_to_string[][_CONN_TYPE_MAX+1] = {
{ NULL }, /* no type associated with 0 */
{ NULL }, /* op listener, obsolete */
@@ -74,7 +74,7 @@ static int connection_receiver_bucket_should_increase(connection_t *conn);
/**************************************************************/
-/* Allocate space for a new connection_t. This function just initializes
+/** Allocate space for a new connection_t. This function just initializes
* conn; you must call connection_add() to link it into the main array.
*
* Set conn->type to 'type'. Set conn->s and conn->poll_index to
@@ -114,8 +114,8 @@ connection_t *connection_new(int type) {
return conn;
}
-/* Deallocate memory used by 'conn'. Deallocate its buffers if necessary,
- * close its socket if necessary, and mark the directory as dirty if conn
+/** Deallocate memory used by <b>conn</b>. Deallocate its buffers if necessary,
+ * close its socket if necessary, and mark the directory as dirty if <b>conn</b>
* is an OR or OP connection.
*/
void connection_free(connection_t *conn) {
@@ -147,6 +147,10 @@ void connection_free(connection_t *conn) {
free(conn);
}
+/** Call connection_free() on every connection in our array.
+ * This is used by cpuworkers and dnsworkers when they fork,
+ * so they don't keep resources held open (especially sockets).
+ */
void connection_free_all(void) {
int i, n;
connection_t **carray;
@@ -156,8 +160,9 @@ void connection_free_all(void) {
connection_free(carray[i]);
}
-/* Close the underlying socket for conn, so we don't try to flush it.
- * Must be used in conjunction with (right before) connection_mark_for_close
+/** Close the underlying socket for <b>conn</b>, so we don't try to
+ * flush it. Must be used in conjunction with (right before)
+ * connection_mark_for_close().
*/
void connection_close_immediate(connection_t *conn)
{
@@ -178,6 +183,16 @@ void connection_close_immediate(connection_t *conn)
}
}
+/** Mark <b>conn</b> to be closed next time we loop through
+ * conn_close_if_marked() in main.c. Do any cleanup needed:
+ * - Directory conns that fail to fetch a rendezvous descriptor need
+ * to inform pending rendezvous streams.
+ * - OR conns need to call rep_hist_note_*() to record status.
+ * - AP conns need to send a socks reject if necessary.
+ * - Exit conns need to call connection_dns_remove() if necessary.
+ * - AP and Exit conns need to send an end cell if they can.
+ * - DNS conns need to fail any resolves that are pending on them.
+ */
int
_connection_mark_for_close(connection_t *conn, char reason)
{
@@ -214,7 +229,6 @@ _connection_mark_for_close(connection_t *conn, char reason)
} else {
rep_hist_note_connection_died(conn->nickname, time(NULL));
}
- /* No special processing needed. */
break;
case CONN_TYPE_AP:
if (conn->socks_request->has_finished == 0) {
@@ -250,6 +264,11 @@ _connection_mark_for_close(connection_t *conn, char reason)
return retval;
}
+/** Find each connection that has hold_open_until_flushed set to
+ * 1 but hasn't written in the past 15 seconds, and set
+ * hold_open_until_flushed to 0. This means it will get cleaned
+ * up in the next loop through close_if_marked() in main.c.
+ */
void connection_expire_held_open(void)
{
connection_t **carray, *conn;
@@ -275,6 +294,10 @@ void connection_expire_held_open(void)
}
}
+/** Bind a new non-blocking socket listening to
+ * <b>bindaddress</b>:<b>bindport</b>, and add this new connection
+ * (of type <b>type</b>) to the connection array.
+ */
int connection_create_listener(char *bindaddress, uint16_t bindport, int type) {
struct sockaddr_in bindaddr; /* where to bind */
connection_t *conn;
@@ -328,6 +351,9 @@ int connection_create_listener(char *bindaddress, uint16_t bindport, int type) {
return 0;
}
+/** The listener connection <b>conn</b> told poll() it wanted to read.
+ * Call accept() on conn->s, and add the new connection if necessary.
+ */
static int connection_handle_listener_read(connection_t *conn, int new_type) {
int news; /* the new socket */
connection_t *newconn;
@@ -367,6 +393,9 @@ static int connection_handle_listener_read(connection_t *conn, int new_type) {
return 0;
}
+/** Initialize states for newly accepted connection <b>conn</b>.
+ * If conn is an OR, start the tls handshake.
+ */
static int connection_init_accepted_conn(connection_t *conn) {
connection_start_reading(conn);
@@ -385,11 +414,13 @@ static int connection_init_accepted_conn(connection_t *conn) {
return 0;
}
-/* Take conn, make a nonblocking socket; try to connect to
+/** Take conn, make a nonblocking socket; try to connect to
* addr:port (they arrive in *host order*). If fail, return -1. Else
* assign s to conn->s: if connected return 1, if eagain return 0.
- * address is used to make the logs useful. On success, add 'conn' to
- * the list of polled connections.
+ *
+ * address is used to make the logs useful.
+ *
+ * On success, add 'conn' to the list of polled connections.
*/
int connection_connect(connection_t *conn, char *address, uint32_t addr, uint16_t port) {
int s;
@@ -434,6 +465,9 @@ int connection_connect(connection_t *conn, char *address, uint32_t addr, uint16_
return 1;
}
+/** If there exists a listener of type <b>type</b> in the connection
+ * array, mark it for close.
+ */
static void listener_close_if_present(int type) {
connection_t *conn;
tor_assert(type == CONN_TYPE_OR_LISTENER ||
@@ -446,7 +480,10 @@ static void listener_close_if_present(int type) {
}
}
-/* start all connections that should be up but aren't */
+/** Start all connections that should be up but aren't.
+ * - Connect to all ORs if you're an OR.
+ * - Relaunch listeners for each port you have open.
+ */
int retry_all_connections(void) {
if(options.ORPort) {
@@ -480,9 +517,9 @@ int retry_all_connections(void) {
return 0;
}
-extern int global_read_bucket;
+extern int global_read_bucket; /**< from main.c */
-/* how many bytes at most can we read onto this connection? */
+/** How many bytes at most can we read onto this connection? */
int connection_bucket_read_limit(connection_t *conn) {
int at_most;
@@ -507,7 +544,7 @@ int connection_bucket_read_limit(connection_t *conn) {
return at_most;
}
-/* we just read num_read onto conn. Decrement buckets appropriately. */
+/** We just read num_read onto conn. Decrement buckets appropriately. */
void connection_bucket_decrement(connection_t *conn, int num_read) {
global_read_bucket -= num_read; tor_assert(global_read_bucket >= 0);
if(connection_speaks_cells(conn) && conn->state == OR_CONN_STATE_OPEN) {
@@ -528,15 +565,17 @@ void connection_bucket_decrement(connection_t *conn, int num_read) {
}
}
-/* keep a timeval to know when time has passed enough to refill buckets */
+/** Keep a timeval to know when time has passed enough to refill buckets */
static struct timeval current_time;
+/** Initiatialize the global read bucket to options.BandwidthBurst,
+ * and current_time to the current time. */
void connection_bucket_init(void) {
tor_gettimeofday(&current_time);
global_read_bucket = options.BandwidthBurst; /* start it at max traffic */
}
-/* some time has passed; increment buckets appropriately. */
+/** Some time has passed; increment buckets appropriately. */
void connection_bucket_refill(struct timeval *now) {
int i, n;
connection_t *conn;
@@ -581,6 +620,9 @@ void connection_bucket_refill(struct timeval *now) {
}
}
+/** Is the receiver bucket for connection <b>conn</b> low enough that we
+ * should add another pile of tokens to it?
+ */
static int connection_receiver_bucket_should_increase(connection_t *conn) {
tor_assert(conn);
@@ -596,6 +638,18 @@ static int connection_receiver_bucket_should_increase(connection_t *conn) {
return 1;
}
+/** Read bytes from conn->s and process them.
+ *
+ * This function gets called from conn_read() in main.c, either
+ * when poll() has declared that conn wants to read, or (for OR conns)
+ * when there are pending TLS bytes.
+ *
+ * It calls connection_read_to_buf() to bring in any new bytes,
+ * and then calls connection_process_inbuf() to process them.
+ *
+ * Mark the connection and return -1 if you want to close it, else
+ * return 0.
+ */
int connection_handle_read(connection_t *conn) {
conn->timestamp_lastread = time(NULL);
@@ -628,7 +682,12 @@ int connection_handle_read(connection_t *conn) {
return 0;
}
-/* return -1 if we want to break conn, else return 0 */
+/** Pull in new bytes from conn->s onto conn->inbuf, either
+ * directly or via TLS. Reduce the token buckets by the number of
+ * bytes read.
+ *
+ * Return -1 if we want to break conn, else return 0.
+ */
int connection_read_to_buf(connection_t *conn) {
int result;
int at_most;
@@ -676,19 +735,39 @@ int connection_read_to_buf(connection_t *conn) {
return 0;
}
+/** A pass-through to fetch_from_buf. */
int connection_fetch_from_buf(char *string, int len, connection_t *conn) {
return fetch_from_buf(string, len, conn->inbuf);
}
+/** Return conn->outbuf_flushlen: how many bytes conn wants to flush
+ * from its outbuf. */
int connection_wants_to_flush(connection_t *conn) {
return conn->outbuf_flushlen;
}
+/** Are there too many bytes on edge connection <b>conn</b>'s outbuf to
+ * send back a relay-level sendme yet? Return 1 if so, 0 if not. Used by
+ * connection_edge_consider_sending_sendme().
+ */
int connection_outbuf_too_full(connection_t *conn) {
return (conn->outbuf_flushlen > 10*CELL_PAYLOAD_SIZE);
}
-/* mark and return -1 if you want to break the conn, else return 0 */
+/** Try to flush more bytes onto conn->s.
+ *
+ * This function gets called either from conn_write() in main.c
+ * when poll() has declared that conn wants to write, or below
+ * from connection_write_to_buf() when an entire TLS record is ready.
+ *
+ * Update conn->timestamp_lastwritten to now, and call flush_buf
+ * or flush_buf_tls appropriately. If it succeeds and there no more
+ * more bytes on conn->outbuf, then call connection_finished_flushing
+ * on it too.
+ *
+ * Mark the connection and return -1 if you want to close it, else
+ * return 0.
+ */
int connection_handle_write(connection_t *conn) {
tor_assert(!connection_is_listener(conn));
@@ -754,6 +833,10 @@ int connection_handle_write(connection_t *conn) {
return 0;
}
+/** Append <b>len</b> bytes of <b>string</b> onto <b>conn</b>'s
+ * outbuf, and ask it to start writing. If it's an OR conn, and an
+ * entire TLS record is ready, then try to flush it now.
+ */
void connection_write_to_buf(const char *string, int len, connection_t *conn) {
if(!len || conn->marked_for_close)
@@ -788,7 +871,8 @@ void connection_write_to_buf(const char *string, int len, connection_t *conn) {
}
}
-/* get the conn to addr/port that has the most recent timestamp_created */
+/** Return the conn to addr/port that has the most recent
+ * timestamp_created, or NULL if no such conn exists. */
connection_t *connection_exact_get_by_addr_port(uint32_t addr, uint16_t port) {
int i, n;
connection_t *conn, *best=NULL;
@@ -804,12 +888,14 @@ connection_t *connection_exact_get_by_addr_port(uint32_t addr, uint16_t port) {
return best;
}
+/** Find a connection to the router described by addr and port,
+ * or alternately any router with the same identity key.
+ * This connection *must* be in 'open' state.
+ * If not, return NULL.
+ */
+/* XXX this twin thing is busted, now that we're rotating onion
+ * keys. abandon/patch? */
connection_t *connection_twin_get_by_addr_port(uint32_t addr, uint16_t port) {
- /* Find a connection to the router described by addr and port,
- * or alternately any router which knows its key.
- * This connection *must* be in 'open' state.
- * If not, return NULL.
- */
int i, n;
connection_t *conn;
routerinfo_t *router;
@@ -841,6 +927,9 @@ connection_t *connection_twin_get_by_addr_port(uint32_t addr, uint16_t port) {
return NULL;
}
+/** Return a connection of type <b>type</b> that is not marked for
+ * close.
+ */
connection_t *connection_get_by_type(int type) {
int i, n;
connection_t *conn;
@@ -855,6 +944,9 @@ connection_t *connection_get_by_type(int type) {
return NULL;
}
+/** Return a connection of type <b>type</b> that is in state <b>state</b>,
+ * and that is not marked for close.
+ */
connection_t *connection_get_by_type_state(int type, int state) {
int i, n;
connection_t *conn;
@@ -869,6 +961,10 @@ connection_t *connection_get_by_type_state(int type, int state) {
return NULL;
}
+/** Return the connection of type <b>type</b> that is in state
+ * <b>state</b>, that was written to least recently, and that is not
+ * marked for close.
+ */
connection_t *connection_get_by_type_state_lastwritten(int type, int state) {
int i, n;
connection_t *conn, *best=NULL;
@@ -884,6 +980,9 @@ connection_t *connection_get_by_type_state_lastwritten(int type, int state) {
return best;
}
+/** Return a connection of type <b>type</b> that has rendquery equal
+ * to <b>rendquery</b>, and that is not marked for close.
+ */
connection_t *connection_get_by_type_rendquery(int type, const char *rendquery) {
int i, n;
connection_t *conn;
@@ -900,6 +999,7 @@ connection_t *connection_get_by_type_rendquery(int type, const char *rendquery)
return NULL;
}
+/** Return 1 if <b>conn</b> is a listener conn, else return 0. */
int connection_is_listener(connection_t *conn) {
if(conn->type == CONN_TYPE_OR_LISTENER ||
conn->type == CONN_TYPE_AP_LISTENER ||
@@ -908,6 +1008,9 @@ int connection_is_listener(connection_t *conn) {
return 0;
}
+/** Return 1 if <b>conn</b> is in state 'open' and is not marked
+ * for close, else return 0.
+ */
int connection_state_is_open(connection_t *conn) {
tor_assert(conn);
@@ -922,6 +1025,11 @@ int connection_state_is_open(connection_t *conn) {
return 0;
}
+/** Write a 'destroy' cell with circ ID <b>circ_id</b> onto OR connection
+ * <b>conn</b>.
+ *
+ * Return 0.
+ */
int connection_send_destroy(uint16_t circ_id, connection_t *conn) {
cell_t cell;
@@ -936,6 +1044,11 @@ int connection_send_destroy(uint16_t circ_id, connection_t *conn) {
return 0;
}
+/** Process new bytes that have arrived on conn->inbuf.
+ *
+ * This function just passes conn to the connection-specific
+ * connection_*_process_inbuf() function.
+ */
int connection_process_inbuf(connection_t *conn) {
tor_assert(conn);
@@ -958,6 +1071,12 @@ int connection_process_inbuf(connection_t *conn) {
}
}
+/** We just finished flushing bytes from conn->outbuf, and there
+ * are no more bytes remaining.
+ *
+ * This function just passes conn to the connection-specific
+ * connection_*_finished_flushing() function.
+ */
int connection_finished_flushing(connection_t *conn) {
tor_assert(conn);
@@ -982,6 +1101,9 @@ int connection_finished_flushing(connection_t *conn) {
}
}
+/** Verify that connection <b>conn</b> has all of its invariants
+ * correct. Trigger an assert if anything is invalid.
+ */
void assert_connection_ok(connection_t *conn, time_t now)
{
tor_assert(conn);