mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-10 21:23:58 +01:00
function header comments for connection.c, including doxygen markup
svn:r1825
This commit is contained in:
parent
c6d4a00c5f
commit
8f6aa6688f
@ -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(¤t_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;
|
||||
}
|
||||
|
||||
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.
|
||||
/** 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) {
|
||||
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);
|
||||
|
Loading…
Reference in New Issue
Block a user