mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-12-06 19:41:15 +01:00
more doxygen markup
plenty more remains svn:r1824
This commit is contained in:
+37
-40
@@ -1,4 +1,4 @@
|
||||
/* Copyright 2001,2002,2003 Roger Dingledine, Matej Pfajfar. */
|
||||
/* Copyright 2001 Matej Pfajfar, 2001-2004 Roger Dingledine. */
|
||||
/* See LICENSE for licensing information */
|
||||
/* $Id$ */
|
||||
|
||||
@@ -13,8 +13,8 @@
|
||||
struct buf_t {
|
||||
uint32_t magic; /**< Magic cookie for debugging: Must be set to BUFFER_MAGIC */
|
||||
char *mem; /**< Storage for data in the buffer */
|
||||
size_t len; /**< Maximum amount of data that 'mem' can hold. */
|
||||
size_t datalen; /**< Number of bytes currently in 'mem'. */
|
||||
size_t len; /**< Maximum amount of data that <b>mem</b> can hold. */
|
||||
size_t datalen; /**< Number of bytes currently in <b>mem</b>. */
|
||||
};
|
||||
|
||||
/** Size, in bytes, for newly allocated buffers. Should be a power of 2. */
|
||||
@@ -26,7 +26,7 @@ struct buf_t {
|
||||
* than this size. */
|
||||
#define MIN_BUF_SHRINK_SIZE (16*1024)
|
||||
|
||||
/** Change a buffer's capacity. new_capacity must be \<= buf->datalen. */
|
||||
/** Change a buffer's capacity. <b>new_capacity</b> must be \<= buf->datalen. */
|
||||
static INLINE void buf_resize(buf_t *buf, size_t new_capacity)
|
||||
{
|
||||
tor_assert(buf->datalen <= new_capacity);
|
||||
@@ -35,7 +35,7 @@ static INLINE void buf_resize(buf_t *buf, size_t new_capacity)
|
||||
buf->len = new_capacity;
|
||||
}
|
||||
|
||||
/** If the buffer is not large enough to hold "capacity" bytes, resize
|
||||
/** If the buffer is not large enough to hold <b>capacity</b> bytes, resize
|
||||
* it so that it can. (The new size will be a power of 2 times the old
|
||||
* size.)
|
||||
*/
|
||||
@@ -82,7 +82,7 @@ static INLINE void buf_shrink_if_underfull(buf_t *buf) {
|
||||
buf_resize(buf, new_len);
|
||||
}
|
||||
|
||||
/** Remove the first 'n' bytes from buf.
|
||||
/** Remove the first <b>n</b> bytes from buf.
|
||||
*/
|
||||
static INLINE void buf_remove_from_front(buf_t *buf, size_t n) {
|
||||
tor_assert(buf->datalen >= n);
|
||||
@@ -91,8 +91,8 @@ static INLINE void buf_remove_from_front(buf_t *buf, size_t n) {
|
||||
buf_shrink_if_underfull(buf);
|
||||
}
|
||||
|
||||
/** Find the first instance of the str_len byte string 'sr' on the
|
||||
* buf_len byte string 'bufstr'. Strings are not necessary
|
||||
/** Find the first instance of the str_len byte string <b>str</b> on the
|
||||
* buf_len byte string <b>bufstr</b>. Strings are not necessary
|
||||
* NUL-terminated. If none exists, return -1. Otherwise, return index
|
||||
* of the first character in bufstr _after_ the first instance of str.
|
||||
*/
|
||||
@@ -116,7 +116,7 @@ static int find_mem_in_mem(const char *str, int str_len,
|
||||
return -1;
|
||||
}
|
||||
|
||||
/** Create and return a new buf with capacity 'size'.
|
||||
/** Create and return a new buf with capacity <b>size</b>.
|
||||
*/
|
||||
buf_t *buf_new_with_capacity(size_t size) {
|
||||
buf_t *buf;
|
||||
@@ -137,33 +137,33 @@ buf_t *buf_new()
|
||||
return buf_new_with_capacity(INITIAL_BUF_SIZE);
|
||||
}
|
||||
|
||||
/** Remove all data from 'buf' */
|
||||
/** Remove all data from <b>buf</b> */
|
||||
void buf_clear(buf_t *buf)
|
||||
{
|
||||
buf->datalen = 0;
|
||||
}
|
||||
|
||||
/** Return the number of bytes stored in 'buf' */
|
||||
/** Return the number of bytes stored in <b>buf</b> */
|
||||
size_t buf_datalen(const buf_t *buf)
|
||||
{
|
||||
return buf->datalen;
|
||||
}
|
||||
|
||||
/** Return the maximum bytes that can be stored in 'buf' before buf
|
||||
/** Return the maximum bytes that can be stored in <b>buf</b> before buf
|
||||
* needs to resize. */
|
||||
size_t buf_capacity(const buf_t *buf)
|
||||
{
|
||||
return buf->len;
|
||||
}
|
||||
|
||||
/** For testing only: Return a pointer to the raw memory stored in 'buf'.
|
||||
/** For testing only: Return a pointer to the raw memory stored in <b>buf</b>.
|
||||
*/
|
||||
const char *_buf_peek_raw_buffer(const buf_t *buf)
|
||||
{
|
||||
return buf->mem;
|
||||
}
|
||||
|
||||
/** Release storage held by 'buf'.
|
||||
/** Release storage held by <b>buf</b>.
|
||||
*/
|
||||
void buf_free(buf_t *buf) {
|
||||
assert_buf_ok(buf);
|
||||
@@ -172,9 +172,9 @@ void buf_free(buf_t *buf) {
|
||||
tor_free(buf);
|
||||
}
|
||||
|
||||
/** Read from socket s, writing onto end of buf. Read at most
|
||||
* 'at_most' bytes, resizing the buffer as necessary. If read()
|
||||
* returns 0, set *reached_eof to 1 and return 0. Return -1 on error;
|
||||
/** Read from socket <b>s</s>, writing onto end of <b>buf</b>. Read at most
|
||||
* <b>at_most</b> bytes, resizing the buffer as necessary. If read()
|
||||
* returns 0, set <b>*reached_eof</b> to 1 and return 0. Return -1 on error;
|
||||
* else return the number of bytes read. Return 0 if read() would
|
||||
* block.
|
||||
*/
|
||||
@@ -247,17 +247,14 @@ int read_to_buf_tls(tor_tls *tls, size_t at_most, buf_t *buf) {
|
||||
return r;
|
||||
}
|
||||
|
||||
/** Write data from 'buf' to the socket 's'. Write at most
|
||||
* *buf_flushlen bytes, and decrement *buf_flushlen by the number of
|
||||
* bytes actually written. Return the number of bytes written on
|
||||
* success, -1 on failure. Return 0 if write() would block.
|
||||
/** Write data from <b>buf</b> to the socket <b>s</b>. Write at most
|
||||
* <b>*buf_flushlen</b> bytes, decrement <b>*buf_flushlen</b> by
|
||||
* the number of bytes actually written, and remove the written bytes
|
||||
* from the buffer. Return the number of bytes written on success,
|
||||
* -1 on failure. Return 0 if write() would block.
|
||||
*/
|
||||
int flush_buf(int s, buf_t *buf, int *buf_flushlen)
|
||||
{
|
||||
/* push from buf onto s
|
||||
* then memmove to front of buf
|
||||
* return -1 or how many bytes you just flushed */
|
||||
|
||||
int write_result;
|
||||
|
||||
assert_buf_ok(buf);
|
||||
@@ -306,7 +303,9 @@ int flush_buf_tls(tor_tls *tls, buf_t *buf, int *buf_flushlen)
|
||||
return r;
|
||||
}
|
||||
|
||||
/** Append string_len bytes from 'string' to the end of 'buf'.
|
||||
/** Append <b>string_len</b> bytes from <b>string</b> to the end of
|
||||
* <b>buf</b>.
|
||||
*
|
||||
* Return the new length of the buffer on success, -1 on failure.
|
||||
*/
|
||||
int write_to_buf(const char *string, int string_len, buf_t *buf) {
|
||||
@@ -329,9 +328,8 @@ int write_to_buf(const char *string, int string_len, buf_t *buf) {
|
||||
return buf->datalen;
|
||||
}
|
||||
|
||||
|
||||
/* Remove string_len bytes from the front of 'buf', and store them
|
||||
* into 'string'. Return the new buffer size. string_len must be <=
|
||||
/** Remove <b>string_len</b> bytes from the front of <b>buf</b>, and store them
|
||||
* into <b>string</b>. Return the new buffer size. <b>string_len</b> must be \<=
|
||||
* the number of bytes on the buffer.
|
||||
*/
|
||||
int fetch_from_buf(char *string, size_t string_len, buf_t *buf) {
|
||||
@@ -350,15 +348,15 @@ int fetch_from_buf(char *string, size_t string_len, buf_t *buf) {
|
||||
return buf->datalen;
|
||||
}
|
||||
|
||||
/** There is a (possibly incomplete) http statement on *buf, of the
|
||||
/** There is a (possibly incomplete) http statement on <b>buf</b>, of the
|
||||
* form "\%s\\r\\n\\r\\n\%s", headers, body. (body may contain nuls.)
|
||||
* If a) the headers include a Content-Length field and all bytes in
|
||||
* the body are present, or b) there's no Content-Length field and
|
||||
* all headers are present, then:
|
||||
*
|
||||
* - strdup headers into *headers_out, and nul-terminate it.
|
||||
* - memdup body into *body_out, and nul-terminate it.
|
||||
* - Then remove them from buf, and return 1.
|
||||
* - strdup headers into <b>*headers_out</b>, and nul-terminate it.
|
||||
* - memdup body into <b>*body_out</b>, and nul-terminate it.
|
||||
* - Then remove them from <b>buf</b>, and return 1.
|
||||
*
|
||||
* - If headers or body is NULL, discard that part of the buf.
|
||||
* - If a headers or body doesn't fit in the arg, return -1.
|
||||
@@ -427,7 +425,7 @@ int fetch_from_buf_http(buf_t *buf,
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** There is a (possibly incomplete) socks handshake on buf, of one
|
||||
/** There is a (possibly incomplete) socks handshake on <b>buf</b>, of one
|
||||
* of the forms
|
||||
* - socks4: "socksheader username\\0"
|
||||
* - socks4a: "socksheader username\\0 destaddr\\0"
|
||||
@@ -435,16 +433,16 @@ int fetch_from_buf_http(buf_t *buf,
|
||||
* - socks5 phase two: "version command 0 addresstype..."
|
||||
* If it's a complete and valid handshake, and destaddr fits in
|
||||
* MAX_SOCKS_ADDR_LEN bytes, then pull the handshake off the buf,
|
||||
* assign to req, and return 1.
|
||||
* assign to <b>req</b>, and return 1.
|
||||
*
|
||||
* If it's invalid or too big, return -1.
|
||||
*
|
||||
* Else it's not all there yet, leave buf alone and return 0.
|
||||
*
|
||||
* If you want to specify the socks reply, write it into req->reply
|
||||
* and set req->replylen, else leave req->replylen alone.
|
||||
* If you want to specify the socks reply, write it into <b>req->reply</b>
|
||||
* and set <b>req->replylen</b>, else leave <b>req->replylen</b> alone.
|
||||
*
|
||||
* If returning 0 or -1, req->address and req->port are undefined.
|
||||
* If returning 0 or -1, <b>req->address</b> and <b>req->port</b> are undefined.
|
||||
*/
|
||||
int fetch_from_buf_socks(buf_t *buf, socks_request_t *req) {
|
||||
unsigned char len;
|
||||
@@ -618,7 +616,7 @@ int fetch_from_buf_socks(buf_t *buf, socks_request_t *req) {
|
||||
}
|
||||
}
|
||||
|
||||
/** Log an error and exit if 'buf' is corrupted.
|
||||
/** Log an error and exit if <b>buf</b> is corrupted.
|
||||
*/
|
||||
void assert_buf_ok(buf_t *buf)
|
||||
{
|
||||
@@ -628,7 +626,6 @@ void assert_buf_ok(buf_t *buf)
|
||||
tor_assert(buf->datalen <= buf->len);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Local Variables:
|
||||
mode:c
|
||||
|
||||
+19
-14
@@ -2,26 +2,31 @@
|
||||
/* See LICENSE for licensing information */
|
||||
/* $Id$ */
|
||||
|
||||
/**
|
||||
* \file command.c
|
||||
* \brief Functions for processing incoming cells
|
||||
**/
|
||||
|
||||
#include "or.h"
|
||||
|
||||
extern or_options_t options; /* command-line and config-file options */
|
||||
extern or_options_t options; /**< command-line and config-file options */
|
||||
|
||||
/* keep statistics about how many of each type of cell we've received */
|
||||
/** keep statistics about how many of each type of cell we've received */
|
||||
unsigned long stats_n_padding_cells_processed = 0;
|
||||
unsigned long stats_n_create_cells_processed = 0;
|
||||
unsigned long stats_n_created_cells_processed = 0;
|
||||
unsigned long stats_n_relay_cells_processed = 0;
|
||||
unsigned long stats_n_destroy_cells_processed = 0;
|
||||
|
||||
/* These are the main four functions for processing cells */
|
||||
/** These are the main four functions for processing cells */
|
||||
static void command_process_create_cell(cell_t *cell, connection_t *conn);
|
||||
static void command_process_created_cell(cell_t *cell, connection_t *conn);
|
||||
static void command_process_relay_cell(cell_t *cell, connection_t *conn);
|
||||
static void command_process_destroy_cell(cell_t *cell, connection_t *conn);
|
||||
|
||||
/* This is a wrapper function around the actual function that processes
|
||||
* 'cell' that just arrived on 'conn'. Increment *time by the number of
|
||||
* microseconds used by the call to *func(cell, conn).
|
||||
/** This is a wrapper function around the actual function that processes the
|
||||
* <b>cell</b> that just arrived on <b>conn</b>. Increment <b>*time</b>
|
||||
* by the number of microseconds used by the call to <b>*func(cell, conn)</b>.
|
||||
*/
|
||||
static void command_time_process_cell(cell_t *cell, connection_t *conn, int *time,
|
||||
void (*func)(cell_t *, connection_t *)) {
|
||||
@@ -41,7 +46,7 @@ static void command_time_process_cell(cell_t *cell, connection_t *conn, int *tim
|
||||
*time += time_passed;
|
||||
}
|
||||
|
||||
/* Process a cell that was just received on conn. Keep internal
|
||||
/** Process a <b>cell</b> that was just received on <b>conn</b>. Keep internal
|
||||
* statistics about how many of each cell we've processed so far
|
||||
* this second, and the total number of microseconds it took to
|
||||
* process each type of cell.
|
||||
@@ -107,7 +112,7 @@ void command_process_cell(cell_t *cell, connection_t *conn) {
|
||||
}
|
||||
}
|
||||
|
||||
/* Process a 'create' cell that just arrived from conn. Make a new circuit
|
||||
/** Process a 'create' <b>cell</b> that just arrived from <b>conn</b>. Make a new circuit
|
||||
* with the p_circ_id specified in cell. Put the circuit in state
|
||||
* onionskin_pending, and pass the onionskin to the cpuworker. Circ will
|
||||
* get picked up again when the cpuworker finishes decrypting it.
|
||||
@@ -137,9 +142,9 @@ static void command_process_create_cell(cell_t *cell, connection_t *conn) {
|
||||
log_fn(LOG_DEBUG,"success: handed off onionskin.");
|
||||
}
|
||||
|
||||
/* Process a 'created' cell that just arrived from conn. Find the circuit
|
||||
* that it's intended for. If you're not the origin of the circuit, package
|
||||
* the 'created' cell in an 'extended' relay cell and pass it back. If you
|
||||
/** Process a 'created' <b>cell</b> that just arrived from <b>conn</b>. Find the circuit
|
||||
* that it's intended for. If we're not the origin of the circuit, package
|
||||
* the 'created' cell in an 'extended' relay cell and pass it back. If we
|
||||
* are the origin of the circuit, send it to circuit_finish_handshake() to
|
||||
* finish processing keys, and then call circuit_send_next_onion_skin() to
|
||||
* extend to the next hop in the circuit if necessary.
|
||||
@@ -180,7 +185,7 @@ static void command_process_created_cell(cell_t *cell, connection_t *conn) {
|
||||
}
|
||||
}
|
||||
|
||||
/* Process a 'relay' cell that just arrived from conn. Make sure
|
||||
/** Process a 'relay' <b>cell</b> that just arrived from <b>conn</b>. Make sure
|
||||
* it came in with a recognized circ_id. Pass it on to
|
||||
* circuit_receive_relay_cell() for actual processing.
|
||||
*/
|
||||
@@ -216,8 +221,8 @@ static void command_process_relay_cell(cell_t *cell, connection_t *conn) {
|
||||
}
|
||||
}
|
||||
|
||||
/* Process a 'destroy' cell that just arrived from conn. Find the
|
||||
* circ that it refers to (if any).
|
||||
/** Process a 'destroy' <b>cell</b> that just arrived from
|
||||
* <b>conn</b>. Find the circ that it refers to (if any).
|
||||
*
|
||||
* If the circ is in state
|
||||
* onionskin_pending, then call onion_pending_remove() to remove it
|
||||
|
||||
@@ -2,17 +2,23 @@
|
||||
/* See LICENSE for licensing information */
|
||||
/* $Id$ */
|
||||
|
||||
/**
|
||||
* \file connection_or.c
|
||||
* \brief Functions to handle OR connections, TLS handshaking, and
|
||||
* cells on the network.
|
||||
**/
|
||||
|
||||
#include "or.h"
|
||||
|
||||
extern or_options_t options; /* command-line and config-file options */
|
||||
extern or_options_t options; /**< command-line and config-file options */
|
||||
|
||||
static int connection_tls_finish_handshake(connection_t *conn);
|
||||
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
|
||||
/** Pack the cell_t host-order structure <b>src</b> into network-order
|
||||
* in the buffer <b>dest</b>. See tor-spec.txt for details about the
|
||||
* wire format.
|
||||
*/
|
||||
static void cell_pack(char *dest, const cell_t *src) {
|
||||
@@ -21,8 +27,8 @@ static void cell_pack(char *dest, const cell_t *src) {
|
||||
memcpy(dest+3, src->payload, CELL_PAYLOAD_SIZE);
|
||||
}
|
||||
|
||||
/* Unpack the network-order buffer 'src' into a host-order
|
||||
* cell_t structure 'dest'.
|
||||
/** Unpack the network-order buffer <b>src</b> into a host-order
|
||||
* cell_t structure <b>dest</b>.
|
||||
*/
|
||||
static void cell_unpack(cell_t *dest, const char *src) {
|
||||
dest->circ_id = ntohs(*(uint16_t*)(src));
|
||||
@@ -30,9 +36,7 @@ static void cell_unpack(cell_t *dest, const char *src) {
|
||||
memcpy(dest->payload, src+3, CELL_PAYLOAD_SIZE);
|
||||
}
|
||||
|
||||
/**************************************************************/
|
||||
|
||||
/* Handle any new bytes that have come in on connection 'conn'.
|
||||
/** Handle any new bytes that have come in on connection <b>conn</b>.
|
||||
* If conn is in 'open' state, hand it to
|
||||
* connection_or_process_cells_from_inbuf()
|
||||
* (else do nothing).
|
||||
@@ -52,7 +56,7 @@ 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
|
||||
/** Connection <b>conn</b> 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
|
||||
@@ -68,7 +72,8 @@ int connection_or_finished_flushing(connection_t *conn) {
|
||||
|
||||
switch(conn->state) {
|
||||
case OR_CONN_STATE_CONNECTING:
|
||||
if (getsockopt(conn->s, SOL_SOCKET, SO_ERROR, (void*)&e, &len) < 0) { /* not yet */
|
||||
if (getsockopt(conn->s, SOL_SOCKET, SO_ERROR, (void*)&e, &len) < 0) {
|
||||
/* not yet */
|
||||
if(!ERRNO_IS_CONN_EINPROGRESS(tor_socket_errno(conn->s))) {
|
||||
log_fn(LOG_DEBUG,"in-progress connect failed. Removing.");
|
||||
connection_mark_for_close(conn,0);
|
||||
@@ -97,9 +102,7 @@ int connection_or_finished_flushing(connection_t *conn) {
|
||||
}
|
||||
}
|
||||
|
||||
/*********************/
|
||||
|
||||
/* Initialize conn to include all the relevant data from router.
|
||||
/** Initialize <b>conn</b> to include all the relevant data from <b>router</b>.
|
||||
* 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.
|
||||
@@ -115,11 +118,11 @@ connection_or_init_conn_from_router(connection_t *conn, routerinfo_t *router) {
|
||||
conn->address = tor_strdup(router->address);
|
||||
}
|
||||
|
||||
/* Launch a new OR connection to 'router'.
|
||||
/** Launch a new OR connection to <b>router</b>.
|
||||
*
|
||||
* If router is me, do nothing. If we're already connected to router,
|
||||
* If <b>router</b> is me, do nothing. If we're already connected to <b>router</b>,
|
||||
* return that connection. If the connect is in progress, set conn's
|
||||
* state to 'connecting' and return. If connect to router succeeds, call
|
||||
* state to 'connecting' and return. If connect to <b>router</b> succeeds, call
|
||||
* connection_tls_start_handshake() on it.
|
||||
*
|
||||
* This function is called from router_retry_connections(), for
|
||||
@@ -170,13 +173,13 @@ 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.
|
||||
/** Begin the tls handshake with <b>conn</b>. <b>receiving</b> 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().
|
||||
* Assign a new tls object to conn->tls, begin reading on <b>conn</b>, and pass
|
||||
* <b>conn</b> to connection_tls_continue_handshake().
|
||||
*
|
||||
* Return -1 if conn is broken, else return 0.
|
||||
* Return -1 if <b>conn</b> is broken, else return 0.
|
||||
*/
|
||||
int connection_tls_start_handshake(connection_t *conn, int receiving) {
|
||||
conn->state = OR_CONN_STATE_HANDSHAKING;
|
||||
@@ -193,10 +196,10 @@ int connection_tls_start_handshake(connection_t *conn, int receiving) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Move forward with the tls handshake. If it finishes, hand
|
||||
* conn to connection_tls_finish_handshake().
|
||||
/** Move forward with the tls handshake. If it finishes, hand
|
||||
* <b>conn</b> to connection_tls_finish_handshake().
|
||||
*
|
||||
* Return -1 if conn is broken, else return 0.
|
||||
* Return -1 if <b>conn</b> is broken, else return 0.
|
||||
*/
|
||||
int connection_tls_continue_handshake(connection_t *conn) {
|
||||
switch(tor_tls_handshake(conn->tls)) {
|
||||
@@ -217,7 +220,7 @@ int connection_tls_continue_handshake(connection_t *conn) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* The tls handshake is finished.
|
||||
/** 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.
|
||||
@@ -301,7 +304,7 @@ connection_tls_finish_handshake(connection_t *conn) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Pack 'cell' into wire-format, and write it onto conn's outbuf. */
|
||||
/** Pack <b>cell</b> into wire-format, and write it onto <b>conn</b>'s outbuf. */
|
||||
void connection_or_write_cell_to_buf(const cell_t *cell, connection_t *conn) {
|
||||
char networkcell[CELL_NETWORK_SIZE];
|
||||
char *n = networkcell;
|
||||
@@ -314,8 +317,11 @@ void connection_or_write_cell_to_buf(const cell_t *cell, connection_t *conn) {
|
||||
connection_write_to_buf(n, CELL_NETWORK_SIZE, conn);
|
||||
}
|
||||
|
||||
/* 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().
|
||||
/** Process cells from <b>conn</b>'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) {
|
||||
|
||||
+24
-18
@@ -2,26 +2,34 @@
|
||||
/* See LICENSE for licensing information */
|
||||
/* $Id$ */
|
||||
|
||||
/*****
|
||||
* cpuworker.c: Run computation-intensive tasks (generally for crypto) in
|
||||
/**
|
||||
* \file cpuworker.c
|
||||
* \brief Run computation-intensive tasks (generally for crypto) in
|
||||
* a separate execution context. [OR only.]
|
||||
*
|
||||
* Right now, we only use this for processing onionskins.
|
||||
*****/
|
||||
**/
|
||||
|
||||
#include "or.h"
|
||||
extern or_options_t options; /* command-line and config-file options */
|
||||
extern or_options_t options; /**< command-line and config-file options */
|
||||
|
||||
/** The maximum number of cpuworker processes we will keep around */
|
||||
#define MAX_CPUWORKERS 16
|
||||
/** The minimum number of cpuworker processes we will keep around */
|
||||
#define MIN_CPUWORKERS 1
|
||||
|
||||
/** The tag specifies which circuit this onionskin was from */
|
||||
#define TAG_LEN 8
|
||||
/** How many bytes are sent from tor to the cpuworker? */
|
||||
#define LEN_ONION_QUESTION (1+TAG_LEN+ONIONSKIN_CHALLENGE_LEN)
|
||||
/** How many bytes are sent from the cpuworker back to tor? */
|
||||
#define LEN_ONION_RESPONSE (1+TAG_LEN+ONIONSKIN_REPLY_LEN+40+32)
|
||||
|
||||
/** How many cpuworkers we have running right now */
|
||||
static int num_cpuworkers=0;
|
||||
/** How many of the running cpuworkers have an assigned task right now */
|
||||
static int num_cpuworkers_busy=0;
|
||||
/* We need to spawn new cpuworkers whenever we rotate the onion keys
|
||||
/** We need to spawn new cpuworkers whenever we rotate the onion keys
|
||||
* on platforms where execution contexts==processes. This variable stores
|
||||
* the last time we got a key rotation event.*/
|
||||
static time_t last_rotation_time=0;
|
||||
@@ -31,21 +39,21 @@ static int spawn_cpuworker(void);
|
||||
static void spawn_enough_cpuworkers(void);
|
||||
static void process_pending_task(connection_t *cpuworker);
|
||||
|
||||
/* Initialize the cpuworker subsystem.
|
||||
/** Initialize the cpuworker subsystem.
|
||||
*/
|
||||
void cpu_init(void) {
|
||||
last_rotation_time=time(NULL);
|
||||
spawn_enough_cpuworkers();
|
||||
}
|
||||
|
||||
/* Called when we're done sending a request to a cpuworker. */
|
||||
/** Called when we're done sending a request to a cpuworker. */
|
||||
int connection_cpu_finished_flushing(connection_t *conn) {
|
||||
tor_assert(conn && conn->type == CONN_TYPE_CPUWORKER);
|
||||
connection_stop_writing(conn);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Pack addr,port,and circ_id; set *tag to the result. (See note on
|
||||
/** Pack addr,port,and circ_id; set *tag to the result. (See note on
|
||||
* cpuworker_main for wire format.) */
|
||||
static void tag_pack(char *tag, uint32_t addr, uint16_t port, uint16_t circ_id) {
|
||||
*(uint32_t *)tag = addr;
|
||||
@@ -53,7 +61,7 @@ static void tag_pack(char *tag, uint32_t addr, uint16_t port, uint16_t circ_id)
|
||||
*(uint16_t *)(tag+6) = circ_id;
|
||||
}
|
||||
|
||||
/* Unpack 'tag' into addr, port, and circ_id.
|
||||
/** Unpack 'tag' into addr, port, and circ_id.
|
||||
*/
|
||||
static void tag_unpack(const char *tag, uint32_t *addr, uint16_t *port, uint16_t *circ_id) {
|
||||
struct in_addr in;
|
||||
@@ -66,7 +74,7 @@ static void tag_unpack(const char *tag, uint32_t *addr, uint16_t *port, uint16_t
|
||||
log_fn(LOG_DEBUG,"onion was from %s:%d, circ_id %d.", inet_ntoa(in), *port, *circ_id);
|
||||
}
|
||||
|
||||
/* Called when the onion key has changed and we need to spawn new
|
||||
/** Called when the onion key has changed and we need to spawn new
|
||||
* cpuworkers. Close all currently idle cpuworkers, and mark the last
|
||||
* rotation time as now.
|
||||
*/
|
||||
@@ -82,7 +90,7 @@ void cpuworkers_rotate(void)
|
||||
spawn_enough_cpuworkers();
|
||||
}
|
||||
|
||||
/* Called when we get data from a cpuworker. If the answer is not complete,
|
||||
/** Called when we get data from a cpuworker. If the answer is not complete,
|
||||
* wait for a complete answer. If the cpuworker closes the connection,
|
||||
* mark it as closed and spawn a new one as needed. If the answer is complete,
|
||||
* process it as appropriate.
|
||||
@@ -162,8 +170,7 @@ done_processing:
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* Implement a cpuworker. 'data' is an fdarray as returned by socketpair.
|
||||
/** Implement a cpuworker. 'data' is an fdarray as returned by socketpair.
|
||||
* Read and writes from fdarray[1]. Reads requests, writes answers.
|
||||
*
|
||||
* Request format:
|
||||
@@ -249,7 +256,7 @@ int cpuworker_main(void *data) {
|
||||
return 0; /* windows wants this function to return an int */
|
||||
}
|
||||
|
||||
/* Launch a new cpuworker.
|
||||
/** Launch a new cpuworker.
|
||||
*/
|
||||
static int spawn_cpuworker(void) {
|
||||
int fd[2];
|
||||
@@ -285,7 +292,7 @@ static int spawn_cpuworker(void) {
|
||||
return 0; /* success */
|
||||
}
|
||||
|
||||
/* If we have too few or too many active cpuworkers, try to spawn new ones
|
||||
/** If we have too few or too many active cpuworkers, try to spawn new ones
|
||||
* or kill idle ones.
|
||||
*/
|
||||
static void spawn_enough_cpuworkers(void) {
|
||||
@@ -305,7 +312,7 @@ static void spawn_enough_cpuworkers(void) {
|
||||
}
|
||||
}
|
||||
|
||||
/* Take a pending task from the queue and assign it to 'cpuworker' */
|
||||
/** Take a pending task from the queue and assign it to 'cpuworker' */
|
||||
static void process_pending_task(connection_t *cpuworker) {
|
||||
circuit_t *circ;
|
||||
|
||||
@@ -320,7 +327,7 @@ static void process_pending_task(connection_t *cpuworker) {
|
||||
log_fn(LOG_WARN,"assign_to_cpuworker failed. Ignoring.");
|
||||
}
|
||||
|
||||
/* if cpuworker is defined, assert that he's idle, and use him. else,
|
||||
/** if cpuworker is defined, assert that he's idle, and use him. else,
|
||||
* look for an idle cpuworker and use him. if none idle, queue task onto
|
||||
* the pending onion list and return.
|
||||
* If question_type is CPUWORKER_TASK_ONION then task is a circ.
|
||||
@@ -371,4 +378,3 @@ int assign_to_cpuworker(connection_t *cpuworker, unsigned char question_type,
|
||||
c-basic-offset:2
|
||||
End:
|
||||
*/
|
||||
|
||||
|
||||
+15
-14
@@ -4,9 +4,10 @@
|
||||
|
||||
#include "or.h"
|
||||
|
||||
/*****
|
||||
* directory.c: Implement directory HTTP protocol.
|
||||
*****/
|
||||
/**
|
||||
* \file directory.c
|
||||
* \brief Implement directory HTTP protocol.
|
||||
**/
|
||||
|
||||
static void directory_send_command(connection_t *conn, int purpose,
|
||||
const char *payload, int payload_len);
|
||||
@@ -16,9 +17,9 @@ static int directory_handle_command(connection_t *conn);
|
||||
|
||||
extern or_options_t options; /* command-line and config-file options */
|
||||
|
||||
/* URL for publishing rendezvous descriptors. */
|
||||
/** URL for publishing rendezvous descriptors. */
|
||||
char rend_publish_string[] = "/rendezvous/publish";
|
||||
/* Prefix for downloading rendezvous descriptors. */
|
||||
/** Prefix for downloading rendezvous descriptors. */
|
||||
char rend_fetch_url[] = "/rendezvous/";
|
||||
|
||||
#define MAX_HEADERS_SIZE 10000
|
||||
@@ -26,7 +27,7 @@ char rend_fetch_url[] = "/rendezvous/";
|
||||
|
||||
/********* END VARIABLES ************/
|
||||
|
||||
/* Launch a new connection to the directory server 'router' to upload
|
||||
/** Launch a new connection to the directory server 'router' to upload
|
||||
* or download a service or rendezvous descriptor. 'purpose' determines what
|
||||
* kind of directory connection we're launching, and must be one of
|
||||
* DIR_PURPOSE_{FETCH|UPLOAD}_{DIR|RENDDESC}.
|
||||
@@ -117,7 +118,7 @@ void directory_initiate_command(routerinfo_t *router, int purpose,
|
||||
}
|
||||
}
|
||||
|
||||
/* Queue an appropriate HTTP command on conn->outbuf. The args
|
||||
/** Queue an appropriate HTTP command on conn->outbuf. The args
|
||||
* 'purpose', 'payload', and 'payload_len' are as in
|
||||
* directory_initiate_command.
|
||||
*/
|
||||
@@ -163,7 +164,7 @@ static void directory_send_command(connection_t *conn, int purpose,
|
||||
}
|
||||
}
|
||||
|
||||
/* Parse an HTTP request string 'headers' of the form "%s %s HTTP/1..."
|
||||
/** Parse an HTTP request string 'headers' of the form "%s %s HTTP/1..."
|
||||
* If it's well-formed, point *url to the second %s,
|
||||
* null-terminate it (this modifies headers!) and return 0.
|
||||
* Otherwise, return -1.
|
||||
@@ -185,7 +186,7 @@ int parse_http_url(char *headers, char **url) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Parse an HTTP response string 'headers' of the form "HTTP/1.%d %d%s\r\n...".
|
||||
/** Parse an HTTP response string 'headers' of the form "HTTP/1.%d %d%s\r\n...".
|
||||
* If it's well-formed, assign *code, point *message to the first
|
||||
* non-space character after code if there is one and message is non-NULL
|
||||
* (else leave it alone), and return 0.
|
||||
@@ -210,7 +211,7 @@ int parse_http_response(char *headers, int *code, char **message) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Read handler for directory connections. (That's connections *to*
|
||||
/** Read handler for directory connections. (That's connections *to*
|
||||
* directory servers and connections *at* directory servers.)
|
||||
*/
|
||||
int connection_dir_process_inbuf(connection_t *conn) {
|
||||
@@ -361,7 +362,7 @@ static char answer403[] = "HTTP/1.0 403 Unapproved server\r\n\r\n";
|
||||
static char answer404[] = "HTTP/1.0 404 Not found\r\n\r\n";
|
||||
static char answer503[] = "HTTP/1.0 503 Directory unavailable\r\n\r\n";
|
||||
|
||||
/* Helper function: called when a dirserver gets a complete HTTP GET
|
||||
/** Helper function: called when a dirserver gets a complete HTTP GET
|
||||
* request. Look for a request for a directory or for a rendezvous
|
||||
* service descriptor. On finding one, write a response into
|
||||
* conn->outbuf. If the request is unrecognized, send a 404.
|
||||
@@ -427,7 +428,7 @@ static int directory_handle_command_get(connection_t *conn,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Helper function: called when a dirserver gets a complete HTTP POST
|
||||
/** Helper function: called when a dirserver gets a complete HTTP POST
|
||||
* request. Look for an uploaded server descriptor or rendezvous
|
||||
* service descriptor. On finding one, process it and write a
|
||||
* response into conn->outbuf. If the request is unrecognized, send a
|
||||
@@ -481,7 +482,7 @@ static int directory_handle_command_post(connection_t *conn,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Called when a dirserver receives data on a directory connection;
|
||||
/** Called when a dirserver receives data on a directory connection;
|
||||
* looks for an HTTP request. If the request is complete, remove it
|
||||
* from the inbuf, try to process it; otherwise, leave it on the
|
||||
* buffer. Return a 0 on success, or -1 on error.
|
||||
@@ -520,7 +521,7 @@ static int directory_handle_command(connection_t *conn) {
|
||||
return r;
|
||||
}
|
||||
|
||||
/* Write handler for directory connections; called when all data has
|
||||
/** Write handler for directory connections; called when all data has
|
||||
* been flushed. Handle a completed connection: close the connection
|
||||
* or wait for a response as appropriate.
|
||||
*/
|
||||
|
||||
+27
-24
@@ -4,19 +4,20 @@
|
||||
|
||||
#include "or.h"
|
||||
|
||||
/*****
|
||||
* dirserv.c: Directory server core implementation.
|
||||
/**
|
||||
* \file dirserv.c
|
||||
* \brief Directory server core implementation.
|
||||
*****/
|
||||
|
||||
/* How old do we allow a router to get before removing it? (seconds) */
|
||||
/** How old do we allow a router to get before removing it? (seconds) */
|
||||
#define ROUTER_MAX_AGE (60*60*24)
|
||||
|
||||
/* How far in the future do we allow a router to get? (seconds) */
|
||||
/** How far in the future do we allow a router to get? (seconds) */
|
||||
#define ROUTER_ALLOW_SKEW (30*60)
|
||||
|
||||
extern or_options_t options; /* command-line and config-file options */
|
||||
extern or_options_t options; /**< command-line and config-file options */
|
||||
|
||||
/* Do we need to regenerate the directory when someone asks for it? */
|
||||
/** Do we need to regenerate the directory when someone asks for it? */
|
||||
static int the_directory_is_dirty = 1;
|
||||
|
||||
static int list_running_servers(char **nicknames_out);
|
||||
@@ -29,12 +30,12 @@ typedef struct fingerprint_entry_t {
|
||||
char *fingerprint;
|
||||
} fingerprint_entry_t;
|
||||
|
||||
/* List of nickname->identity fingerprint mappings for all the routers
|
||||
/** List of nickname->identity fingerprint mappings for all the routers
|
||||
* that we recognize. Used to prevent Sybil attacks. */
|
||||
static fingerprint_entry_t fingerprint_list[MAX_ROUTERS_IN_DIR];
|
||||
static int n_fingerprints = 0;
|
||||
|
||||
/* Add the fingerprint 'fp' for the nickname 'nickname' to the global
|
||||
/** Add the fingerprint 'fp' for the nickname 'nickname' to the global
|
||||
* list of recognized identity key fingerprints.
|
||||
*/
|
||||
void /* Should be static; exposed for testing */
|
||||
@@ -53,7 +54,7 @@ add_fingerprint_to_dir(const char *nickname, const char *fp)
|
||||
++n_fingerprints;
|
||||
}
|
||||
|
||||
/* Add the nickname and fingerprint for this OR to the recognized list.
|
||||
/** Add the nickname and fingerprint for this OR to the recognized list.
|
||||
*/
|
||||
int
|
||||
dirserv_add_own_fingerprint(const char *nickname, crypto_pk_env_t *pk)
|
||||
@@ -67,7 +68,7 @@ dirserv_add_own_fingerprint(const char *nickname, crypto_pk_env_t *pk)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Parse the nickname->fingerprint mappings stored in the file named
|
||||
/** Parse the nickname->fingerprint mappings stored in the file named
|
||||
* 'fname'. The file format is line-based, with each non-blank
|
||||
* holding one nickname, some space, and a fingerprint for that
|
||||
* nickname. On success, replace the current fingerprint list with
|
||||
@@ -129,7 +130,7 @@ dirserv_parse_fingerprint_file(const char *fname)
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Check whether 'router' has a nickname/identity key combination that
|
||||
/** Check whether 'router' has a nickname/identity key combination that
|
||||
* we recognize from the fingerprint list. Return 1 if router's
|
||||
* identity and nickname match, -1 if we recognize the nickname but
|
||||
* the identity key is wrong, and 0 if the nickname is not known. */
|
||||
@@ -166,7 +167,7 @@ dirserv_router_fingerprint_is_known(const routerinfo_t *router)
|
||||
}
|
||||
}
|
||||
|
||||
/* Return true iff any router named 'nickname' is in the fingerprint
|
||||
/** Return true iff any router named 'nickname' is in the fingerprint
|
||||
* list. */
|
||||
static int
|
||||
router_nickname_is_approved(const char *nickname)
|
||||
@@ -180,7 +181,7 @@ router_nickname_is_approved(const char *nickname)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Clear the current fingerprint list. */
|
||||
/** Clear the current fingerprint list. */
|
||||
void
|
||||
dirserv_free_fingerprint_list()
|
||||
{
|
||||
@@ -196,7 +197,7 @@ dirserv_free_fingerprint_list()
|
||||
* Descriptor list
|
||||
*/
|
||||
|
||||
/* A directory server's view of a server descriptor. Contains both
|
||||
/** A directory server's view of a server descriptor. Contains both
|
||||
* parsed and unparsed versions. */
|
||||
typedef struct descriptor_entry_t {
|
||||
char *nickname;
|
||||
@@ -206,11 +207,11 @@ typedef struct descriptor_entry_t {
|
||||
routerinfo_t *router;
|
||||
} descriptor_entry_t;
|
||||
|
||||
/* List of all server descriptors that this dirserv is holding. */
|
||||
/** List of all server descriptors that this dirserv is holding. */
|
||||
static descriptor_entry_t *descriptor_list[MAX_ROUTERS_IN_DIR];
|
||||
static int n_descriptors = 0;
|
||||
|
||||
/* Release the storage held by 'desc' */
|
||||
/** Release the storage held by 'desc' */
|
||||
static void free_descriptor_entry(descriptor_entry_t *desc)
|
||||
{
|
||||
tor_free(desc->descriptor);
|
||||
@@ -219,7 +220,7 @@ static void free_descriptor_entry(descriptor_entry_t *desc)
|
||||
free(desc);
|
||||
}
|
||||
|
||||
/* Release all storage that the dirserv is holding for server
|
||||
/** Release all storage that the dirserv is holding for server
|
||||
* descriptors. */
|
||||
void
|
||||
dirserv_free_descriptors()
|
||||
@@ -231,7 +232,7 @@ dirserv_free_descriptors()
|
||||
n_descriptors = 0;
|
||||
}
|
||||
|
||||
/* Parse the server descriptor at *desc and maybe insert it into the
|
||||
/** Parse the server descriptor at *desc and maybe insert it into the
|
||||
* list of service descriptors, and (if the descriptor is well-formed)
|
||||
* advance *desc immediately past the descriptor's end.
|
||||
*
|
||||
@@ -349,7 +350,7 @@ dirserv_add_descriptor(const char **desc)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Remove all descriptors whose nicknames or fingerprints we don't
|
||||
/** Remove all descriptors whose nicknames or fingerprints we don't
|
||||
* recognize. (Descriptors that used to be good can become
|
||||
* unrecognized when we reload the fingerprint list.)
|
||||
*/
|
||||
@@ -367,7 +368,7 @@ directory_remove_unrecognized(void)
|
||||
}
|
||||
}
|
||||
|
||||
/* Mark the directory as 'dirty' -- when we're next asked for a
|
||||
/** Mark the directory as 'dirty' -- when we're next asked for a
|
||||
* directory, we will rebuild it instead of reusing the most recently
|
||||
* generated one.
|
||||
*/
|
||||
@@ -377,7 +378,7 @@ directory_set_dirty()
|
||||
the_directory_is_dirty = 1;
|
||||
}
|
||||
|
||||
/* Load all descriptors from an earlier directory stored in the string
|
||||
/** Load all descriptors from an earlier directory stored in the string
|
||||
* 'dir'.
|
||||
*/
|
||||
int
|
||||
@@ -396,7 +397,7 @@ dirserv_init_from_directory_string(const char *dir)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Set *nicknames_out to a comma-separated list of all the ORs that we
|
||||
/** Set *nicknames_out to a comma-separated list of all the ORs that we
|
||||
* believe are currently running (because we have open connections to
|
||||
* them). Return 0 on success; -1 on error.
|
||||
*/
|
||||
@@ -440,7 +441,7 @@ list_running_servers(char **nicknames_out)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Remove any descriptors from the directory that are more than ROUTER_MAX_AGE
|
||||
/** Remove any descriptors from the directory that are more than ROUTER_MAX_AGE
|
||||
* seconds old.
|
||||
*/
|
||||
void
|
||||
@@ -461,7 +462,7 @@ dirserv_remove_old_servers(void)
|
||||
}
|
||||
}
|
||||
|
||||
/* Dump all routers currently in the directory into the string <s>, using
|
||||
/** Dump all routers currently in the directory into the string <s>, using
|
||||
* at most <maxlen> characters, and signing the directory with <private_key>.
|
||||
* Return 0 on success, -1 on failure.
|
||||
*/
|
||||
@@ -535,9 +536,11 @@ dirserv_dump_directory_to_string(char *s, unsigned int maxlen,
|
||||
return -1;
|
||||
}
|
||||
|
||||
/** XXX */
|
||||
static char *the_directory = NULL;
|
||||
static int the_directory_len = -1;
|
||||
|
||||
/** XXX */
|
||||
size_t dirserv_get_directory(const char **directory)
|
||||
{
|
||||
char *new_directory;
|
||||
|
||||
+39
-35
@@ -2,9 +2,10 @@
|
||||
/* See LICENSE for licensing information */
|
||||
/* $Id$ */
|
||||
|
||||
/*****
|
||||
* dns.c: Resolve hostnames in separate processes.
|
||||
*****/
|
||||
/**
|
||||
* \file dns.c
|
||||
* \brief Resolve hostnames in separate processes.
|
||||
**/
|
||||
|
||||
/* See http://elvin.dstc.com/ListArchive/elvin-dev/archive/2001/09/msg00027.html
|
||||
* for some approaches to asynchronous dns. We will want to switch once one of
|
||||
@@ -14,47 +15,49 @@
|
||||
#include "or.h"
|
||||
#include "tree.h"
|
||||
|
||||
extern or_options_t options; /* command-line and config-file options */
|
||||
extern or_options_t options; /**< command-line and config-file options */
|
||||
|
||||
/* Longest hostname we're willing to resolve. */
|
||||
/** Longest hostname we're willing to resolve. */
|
||||
#define MAX_ADDRESSLEN 256
|
||||
|
||||
/* Maximum DNS processes to spawn. */
|
||||
/** Maximum DNS processes to spawn. */
|
||||
#define MAX_DNSWORKERS 50
|
||||
/* Minimum DNS processes to spawn. */
|
||||
/** Minimum DNS processes to spawn. */
|
||||
#define MIN_DNSWORKERS 3
|
||||
|
||||
/* If more than this many processes are idle, shut down the extras. */
|
||||
/** If more than this many processes are idle, shut down the extras. */
|
||||
#define MAX_IDLE_DNSWORKERS 10
|
||||
|
||||
/* Possible outcomes from hostname lookup: permanent failure,
|
||||
/** Possible outcomes from hostname lookup: permanent failure,
|
||||
* transient (retryable) failure, and success */
|
||||
#define DNS_RESOLVE_FAILED_TRANSIENT 1
|
||||
#define DNS_RESOLVE_FAILED_PERMANENT 2
|
||||
#define DNS_RESOLVE_SUCCEEDED 3
|
||||
|
||||
/** How many dnsworkers we have running right now */
|
||||
int num_dnsworkers=0;
|
||||
/** How many of the running dnsworkers have an assigned task right now */
|
||||
int num_dnsworkers_busy=0;
|
||||
|
||||
/* Linked list of connections waiting for a DNS answer. */
|
||||
/** Linked list of connections waiting for a DNS answer. */
|
||||
struct pending_connection_t {
|
||||
struct connection_t *conn;
|
||||
struct pending_connection_t *next;
|
||||
};
|
||||
|
||||
/* A DNS request: possibly completed, possibly pending; cached_resolve
|
||||
/** A DNS request: possibly completed, possibly pending; cached_resolve
|
||||
* structs are stored at the OR side in a splay tree, and as a linked
|
||||
* list from oldest to newest.
|
||||
*/
|
||||
struct cached_resolve {
|
||||
SPLAY_ENTRY(cached_resolve) node;
|
||||
char address[MAX_ADDRESSLEN]; /* the hostname to be resolved */
|
||||
uint32_t addr; /* in host order. I know I'm horrible for assuming ipv4 */
|
||||
char state; /* 0 is pending; 1 means answer is valid; 2 means resolve failed */
|
||||
char address[MAX_ADDRESSLEN]; /**< the hostname to be resolved */
|
||||
uint32_t addr; /**< in host order. I know I'm horrible for assuming ipv4 */
|
||||
char state; /**< 0 is pending; 1 means answer is valid; 2 means resolve failed */
|
||||
#define CACHE_STATE_PENDING 0
|
||||
#define CACHE_STATE_VALID 1
|
||||
#define CACHE_STATE_FAILED 2
|
||||
uint32_t expire; /* remove items from cache after this time */
|
||||
uint32_t expire; /**< remove items from cache after this time */
|
||||
struct pending_connection_t *pending_connections;
|
||||
struct cached_resolve *next;
|
||||
};
|
||||
@@ -67,10 +70,10 @@ int dnsworker_main(void *data);
|
||||
static int spawn_dnsworker(void);
|
||||
static void spawn_enough_dnsworkers(void);
|
||||
|
||||
/* Splay tree of cached_resolve objects */
|
||||
/** Splay tree of cached_resolve objects */
|
||||
static SPLAY_HEAD(cache_tree, cached_resolve) cache_root;
|
||||
|
||||
/* Function to compare hashed resolves on their addresses; used to
|
||||
/** Function to compare hashed resolves on their addresses; used to
|
||||
* implement splay trees. */
|
||||
static int compare_cached_resolves(struct cached_resolve *a,
|
||||
struct cached_resolve *b) {
|
||||
@@ -81,21 +84,22 @@ static int compare_cached_resolves(struct cached_resolve *a,
|
||||
SPLAY_PROTOTYPE(cache_tree, cached_resolve, node, compare_cached_resolves);
|
||||
SPLAY_GENERATE(cache_tree, cached_resolve, node, compare_cached_resolves);
|
||||
|
||||
/* Initialize the DNS cache */
|
||||
/** Initialize the DNS cache */
|
||||
static void init_cache_tree(void) {
|
||||
SPLAY_INIT(&cache_root);
|
||||
}
|
||||
|
||||
/* Initialize the DNS subsystem; called by the OR process. */
|
||||
/** Initialize the DNS subsystem; called by the OR process. */
|
||||
void dns_init(void) {
|
||||
init_cache_tree();
|
||||
spawn_enough_dnsworkers();
|
||||
}
|
||||
|
||||
static struct cached_resolve *oldest_cached_resolve = NULL; /* linked list, */
|
||||
static struct cached_resolve *newest_cached_resolve = NULL; /* oldest to newest */
|
||||
/** linked list of resolved addresses, oldest to newest */
|
||||
static struct cached_resolve *oldest_cached_resolve = NULL;
|
||||
static struct cached_resolve *newest_cached_resolve = NULL;
|
||||
|
||||
/* Remove every cached_resolve whose 'expire' time is before 'now'
|
||||
/** Remove every cached_resolve whose 'expire' time is before 'now'
|
||||
* from the cache. */
|
||||
static void purge_expired_resolves(uint32_t now) {
|
||||
struct cached_resolve *resolve;
|
||||
@@ -120,7 +124,7 @@ static void purge_expired_resolves(uint32_t now) {
|
||||
}
|
||||
}
|
||||
|
||||
/* See if we have a cache entry for 'exitconn->address'. if so,
|
||||
/** See if we have a cache entry for 'exitconn->address'. if so,
|
||||
* if resolve valid, put it into exitconn->addr and return 1.
|
||||
* If resolve failed, return -1.
|
||||
*
|
||||
@@ -201,7 +205,7 @@ int dns_resolve(connection_t *exitconn) {
|
||||
return assign_to_dnsworker(exitconn);
|
||||
}
|
||||
|
||||
/* Find or spawn a dns worker process to handle resolving
|
||||
/** Find or spawn a dns worker process to handle resolving
|
||||
* exitconn->address; tell that dns worker to begin resolving.
|
||||
*/
|
||||
static int assign_to_dnsworker(connection_t *exitconn) {
|
||||
@@ -236,7 +240,7 @@ static int assign_to_dnsworker(connection_t *exitconn) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Remove 'conn' from the list of connections waiting for conn->address.
|
||||
/** Remove 'conn' from the list of connections waiting for conn->address.
|
||||
*/
|
||||
void connection_dns_remove(connection_t *conn)
|
||||
{
|
||||
@@ -279,7 +283,7 @@ void connection_dns_remove(connection_t *conn)
|
||||
}
|
||||
}
|
||||
|
||||
/* Log an error and abort if conn is waiting for a DNS resolve.
|
||||
/** Log an error and abort if conn is waiting for a DNS resolve.
|
||||
*/
|
||||
void assert_connection_edge_not_dns_pending(connection_t *conn) {
|
||||
struct pending_connection_t *pend;
|
||||
@@ -294,7 +298,7 @@ void assert_connection_edge_not_dns_pending(connection_t *conn) {
|
||||
}
|
||||
}
|
||||
|
||||
/* Log an error and abort if any connection waiting for a DNS resolve is
|
||||
/** Log an error and abort if any connection waiting for a DNS resolve is
|
||||
* corrupted. */
|
||||
void assert_all_pending_dns_resolves_ok(void) {
|
||||
struct pending_connection_t *pend;
|
||||
@@ -309,7 +313,7 @@ void assert_all_pending_dns_resolves_ok(void) {
|
||||
}
|
||||
}
|
||||
|
||||
/* Mark all connections waiting for 'address' for close. Then cancel
|
||||
/** Mark all connections waiting for 'address' for close. Then cancel
|
||||
* the resolve for 'address' itself, and remove any cached results for
|
||||
* 'address' from the cache.
|
||||
*/
|
||||
@@ -347,7 +351,7 @@ void dns_cancel_pending_resolve(char *address) {
|
||||
dns_purge_resolve(resolve);
|
||||
}
|
||||
|
||||
/* Remove 'resolve' from the cache.
|
||||
/** Remove 'resolve' from the cache.
|
||||
*/
|
||||
static void dns_purge_resolve(struct cached_resolve *resolve) {
|
||||
struct cached_resolve *tmp;
|
||||
@@ -373,7 +377,7 @@ static void dns_purge_resolve(struct cached_resolve *resolve) {
|
||||
tor_free(resolve);
|
||||
}
|
||||
|
||||
/* Called on the OR side when a DNS worker tells us the outcome of a DNS
|
||||
/** Called on the OR side when a DNS worker tells us the outcome of a DNS
|
||||
* resolve: tell all pending connections about the result of the lookup, and
|
||||
* cache the value. ('address' is a NUL-terminated string containing the
|
||||
* address to look up; 'addr' is an IPv4 address in host order; 'outcome' is
|
||||
@@ -459,14 +463,14 @@ static void dns_found_answer(char *address, uint32_t addr, char outcome) {
|
||||
* Connection between OR and dnsworker
|
||||
*****/
|
||||
|
||||
/* Write handler: called when we've pushed a request to a dnsworker. */
|
||||
/** Write handler: called when we've pushed a request to a dnsworker. */
|
||||
int connection_dns_finished_flushing(connection_t *conn) {
|
||||
tor_assert(conn && conn->type == CONN_TYPE_DNSWORKER);
|
||||
connection_stop_writing(conn);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Read handler: called when we get data from a dnsworker. If the
|
||||
/** Read handler: called when we get data from a dnsworker. If the
|
||||
* connection is closed, mark the dnsworker as dead. Otherwise, see
|
||||
* if we have a complete answer. If so, call dns_found_answer on the
|
||||
* result. If not, wait. Returns 0. */
|
||||
@@ -510,7 +514,7 @@ int connection_dns_process_inbuf(connection_t *conn) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Implementation for DNS workers; this code runs in a separate
|
||||
/** Implementation for DNS workers; this code runs in a separate
|
||||
* execution context. It takes as its argument an fdarray as returned
|
||||
* by socketpair(), and communicates via fdarray[1]. The protocol is
|
||||
* as follows:
|
||||
@@ -578,7 +582,7 @@ int dnsworker_main(void *data) {
|
||||
return 0; /* windows wants this function to return an int */
|
||||
}
|
||||
|
||||
/* Launch a new DNS worker; return 0 on success, -1 on failure.
|
||||
/** Launch a new DNS worker; return 0 on success, -1 on failure.
|
||||
*/
|
||||
static int spawn_dnsworker(void) {
|
||||
int fd[2];
|
||||
@@ -614,7 +618,7 @@ static int spawn_dnsworker(void) {
|
||||
return 0; /* success */
|
||||
}
|
||||
|
||||
/* If we have too many or too few DNS workers, spawn or kill some.
|
||||
/** If we have too many or too few DNS workers, spawn or kill some.
|
||||
*/
|
||||
static void spawn_enough_dnsworkers(void) {
|
||||
int num_dnsworkers_needed; /* aim to have 1 more than needed,
|
||||
|
||||
+57
-55
@@ -2,9 +2,10 @@
|
||||
/* See LICENSE for licensing information */
|
||||
/* $Id$ */
|
||||
|
||||
/*****
|
||||
* main.c: Tor main loop and startup functions.
|
||||
*****/
|
||||
/**
|
||||
* \file main.c
|
||||
* \brief Tor main loop and startup functions.
|
||||
**/
|
||||
|
||||
#include "or.h"
|
||||
|
||||
@@ -15,42 +16,42 @@ static int init_from_config(int argc, char **argv);
|
||||
|
||||
/********* START VARIABLES **********/
|
||||
|
||||
/* declared in connection.c */
|
||||
/** declared in connection.c */
|
||||
extern char *conn_state_to_string[][_CONN_TYPE_MAX+1];
|
||||
|
||||
or_options_t options; /* command-line and config-file options */
|
||||
int global_read_bucket; /* max number of bytes I can read this second */
|
||||
or_options_t options; /**< command-line and config-file options */
|
||||
int global_read_bucket; /**< max number of bytes I can read this second */
|
||||
|
||||
/* What was the read bucket before the last call to prepare_for_pool?
|
||||
/** What was the read bucket before the last call to prepare_for_pool?
|
||||
* (used to determine how many bytes we've read). */
|
||||
static int stats_prev_global_read_bucket;
|
||||
/* How many bytes have we read since we started the process? */
|
||||
/** How many bytes have we read since we started the process? */
|
||||
static uint64_t stats_n_bytes_read = 0;
|
||||
/* How many seconds have we been running? */
|
||||
/** How many seconds have we been running? */
|
||||
static long stats_n_seconds_reading = 0;
|
||||
|
||||
/* Array of all open connections; each element corresponds to the element of
|
||||
/** Array of all open connections; each element corresponds to the element of
|
||||
* poll_array in the same position. The first nfds elements are valid. */
|
||||
static connection_t *connection_array[MAXCONNECTIONS] =
|
||||
{ NULL };
|
||||
|
||||
/* Array of pollfd objects for calls to poll(). */
|
||||
/** Array of pollfd objects for calls to poll(). */
|
||||
static struct pollfd poll_array[MAXCONNECTIONS];
|
||||
|
||||
static int nfds=0; /* number of connections currently active */
|
||||
static int nfds=0; /**< number of connections currently active */
|
||||
|
||||
#ifndef MS_WINDOWS /* do signal stuff only on unix */
|
||||
static int please_dumpstats=0; /* whether we should dump stats during the loop */
|
||||
static int please_reset=0; /* whether we just got a sighup */
|
||||
static int please_reap_children=0; /* whether we should waitpid for exited children */
|
||||
static int please_dumpstats=0; /**< whether we should dump stats during the loop */
|
||||
static int please_reset=0; /**< whether we just got a sighup */
|
||||
static int please_reap_children=0; /**< whether we should waitpid for exited children */
|
||||
#endif /* signal stuff */
|
||||
|
||||
/* we set this to 1 when we've fetched a dir, to know whether to complain
|
||||
/** We set this to 1 when we've fetched a dir, to know whether to complain
|
||||
* yet about unrecognized nicknames in entrynodes, exitnodes, etc.
|
||||
* Also, we don't try building circuits unless this is 1. */
|
||||
int has_fetched_directory=0;
|
||||
|
||||
/* we set this to 1 when we've opened a circuit, so we can print a log
|
||||
/** We set this to 1 when we've opened a circuit, so we can print a log
|
||||
* entry to inform the user that Tor is working. */
|
||||
int has_completed_circuit=0;
|
||||
|
||||
@@ -64,7 +65,7 @@ int has_completed_circuit=0;
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/* Add 'conn' to the array of connections that we can poll on. The
|
||||
/** Add <b>conn</b> to the array of connections that we can poll on. The
|
||||
* connection's socket must be set; the connection starts out
|
||||
* non-reading and non-writing.
|
||||
*/
|
||||
@@ -95,7 +96,7 @@ int connection_add(connection_t *conn) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Remove the connection from the global list, and remove the
|
||||
/** Remove the connection from the global list, and remove the
|
||||
* corresponding poll entry. Calling this function will shift the last
|
||||
* connection (if any) into the position occupied by conn.
|
||||
*/
|
||||
@@ -126,16 +127,17 @@ int connection_remove(connection_t *conn) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Set *array to an array of all connections, and *n to the length
|
||||
* of the array. *array and *n must not be modified.
|
||||
/** Set <b>*array</b> to an array of all connections, and <b>*n</b>
|
||||
* to the length of the array. <b>*array</b> and <b>*n</b> must not
|
||||
* be modified.
|
||||
*/
|
||||
void get_connection_array(connection_t ***array, int *n) {
|
||||
*array = connection_array;
|
||||
*n = nfds;
|
||||
}
|
||||
|
||||
/* Set the event mask on 'conn' to 'events'. (The form of the event mask is
|
||||
* as for poll().)
|
||||
/** Set the event mask on <b>conn</b> to <b>events</b>. (The form of
|
||||
* the event mask is as for poll().)
|
||||
*/
|
||||
void connection_watch_events(connection_t *conn, short events) {
|
||||
|
||||
@@ -144,13 +146,13 @@ void connection_watch_events(connection_t *conn, short events) {
|
||||
poll_array[conn->poll_index].events = events;
|
||||
}
|
||||
|
||||
/* Return true iff the 'conn' is listening for read events. */
|
||||
/** Return true iff <b>conn</b> is listening for read events. */
|
||||
int connection_is_reading(connection_t *conn) {
|
||||
tor_assert(conn && conn->poll_index >= 0);
|
||||
return poll_array[conn->poll_index].events & POLLIN;
|
||||
}
|
||||
|
||||
/* Tell the main loop to stop notifying 'conn' of any read events. */
|
||||
/** Tell the main loop to stop notifying <b>conn</b> of any read events. */
|
||||
void connection_stop_reading(connection_t *conn) {
|
||||
tor_assert(conn && conn->poll_index >= 0 && conn->poll_index < nfds);
|
||||
|
||||
@@ -159,31 +161,31 @@ void connection_stop_reading(connection_t *conn) {
|
||||
poll_array[conn->poll_index].events -= POLLIN;
|
||||
}
|
||||
|
||||
/* Tell the main loop to start notifying 'conn' of any read events. */
|
||||
/** Tell the main loop to start notifying <b>conn</b> of any read events. */
|
||||
void connection_start_reading(connection_t *conn) {
|
||||
tor_assert(conn && conn->poll_index >= 0 && conn->poll_index < nfds);
|
||||
poll_array[conn->poll_index].events |= POLLIN;
|
||||
}
|
||||
|
||||
/* Return true iff the 'conn' is listening for write events. */
|
||||
/** Return true iff <b>conn</b> is listening for write events. */
|
||||
int connection_is_writing(connection_t *conn) {
|
||||
return poll_array[conn->poll_index].events & POLLOUT;
|
||||
}
|
||||
|
||||
/* Tell the main loop to stop notifying 'conn' of any write events. */
|
||||
/** Tell the main loop to stop notifying <b>conn</b> of any write events. */
|
||||
void connection_stop_writing(connection_t *conn) {
|
||||
tor_assert(conn && conn->poll_index >= 0 && conn->poll_index < nfds);
|
||||
if(poll_array[conn->poll_index].events & POLLOUT)
|
||||
poll_array[conn->poll_index].events -= POLLOUT;
|
||||
}
|
||||
|
||||
/* Tell the main loop to start notifying 'conn' of any write events. */
|
||||
/** Tell the main loop to start notifying <b>conn</b> of any write events. */
|
||||
void connection_start_writing(connection_t *conn) {
|
||||
tor_assert(conn && conn->poll_index >= 0 && conn->poll_index < nfds);
|
||||
poll_array[conn->poll_index].events |= POLLOUT;
|
||||
}
|
||||
|
||||
/* Called when the connection at connection_array[i] has a read event,
|
||||
/** Called when the connection at connection_array[i] has a read event,
|
||||
* or it has pending tls data waiting to be read: checks for validity,
|
||||
* catches numerous errors, and dispatches to connection_handle_read.
|
||||
*/
|
||||
@@ -224,7 +226,7 @@ static void conn_read(int i) {
|
||||
assert_all_pending_dns_resolves_ok();
|
||||
}
|
||||
|
||||
/* Called when the connection at connection_array[i] has a write event:
|
||||
/** Called when the connection at connection_array[i] has a write event:
|
||||
* checks for validity, catches numerous errors, and dispatches to
|
||||
* connection_handle_write.
|
||||
*/
|
||||
@@ -255,7 +257,7 @@ static void conn_write(int i) {
|
||||
assert_all_pending_dns_resolves_ok();
|
||||
}
|
||||
|
||||
/* If the connection at connection_array[i] is marked for close, then:
|
||||
/** If the connection at connection_array[i] is marked for close, then:
|
||||
* - If it has data that it wants to flush, try to flush it.
|
||||
* - If it _still_ has data to flush, and conn->hold_open_until_flushed is
|
||||
* true, then leave the connection open and return.
|
||||
@@ -322,7 +324,7 @@ static void conn_close_if_marked(int i) {
|
||||
}
|
||||
}
|
||||
|
||||
/* This function is called whenever we successfully pull down a directory */
|
||||
/** This function is called whenever we successfully pull down a directory */
|
||||
void directory_has_arrived(void) {
|
||||
|
||||
log_fn(LOG_INFO, "A directory has arrived.");
|
||||
@@ -338,7 +340,7 @@ void directory_has_arrived(void) {
|
||||
}
|
||||
}
|
||||
|
||||
/* Perform regular maintenance tasks for a single connection. This
|
||||
/** Perform regular maintenance tasks for a single connection. This
|
||||
* function gets run once per second per connection by run_housekeeping.
|
||||
*/
|
||||
static void run_connection_housekeeping(int i, time_t now) {
|
||||
@@ -382,7 +384,7 @@ static void run_connection_housekeeping(int i, time_t now) {
|
||||
}
|
||||
}
|
||||
|
||||
/* Perform regular maintenance tasks. This function gets run once per
|
||||
/** Perform regular maintenance tasks. This function gets run once per
|
||||
* second by prepare_for_poll.
|
||||
*/
|
||||
static void run_scheduled_events(time_t now) {
|
||||
@@ -392,7 +394,7 @@ static void run_scheduled_events(time_t now) {
|
||||
int i;
|
||||
|
||||
|
||||
/* 1a. Every MIN_ONION_KEY_LIFETIME seconds, rotate the onion keys,
|
||||
/** 1a. Every MIN_ONION_KEY_LIFETIME seconds, rotate the onion keys,
|
||||
* shut down and restart all cpuworkers, and update the directory if
|
||||
* necessary.
|
||||
*/
|
||||
@@ -406,7 +408,7 @@ static void run_scheduled_events(time_t now) {
|
||||
router_upload_dir_desc_to_dirservers();
|
||||
}
|
||||
|
||||
/* 1b. Every MAX_SSL_KEY_LIFETIME seconds, we change our TLS context. */
|
||||
/** 1b. Every MAX_SSL_KEY_LIFETIME seconds, we change our TLS context. */
|
||||
if (!last_rotated_certificate)
|
||||
last_rotated_certificate = now;
|
||||
if (options.ORPort && last_rotated_certificate+MAX_SSL_KEY_LIFETIME < now) {
|
||||
@@ -420,7 +422,7 @@ static void run_scheduled_events(time_t now) {
|
||||
* XXXX them at all. */
|
||||
}
|
||||
|
||||
/* 1c. Every DirFetchPostPeriod seconds, we get a new directory and upload
|
||||
/** 1c. Every DirFetchPostPeriod seconds, we get a new directory and upload
|
||||
* our descriptor (if any). */
|
||||
if(time_to_fetch_directory < now) {
|
||||
/* it's time to fetch a new directory and/or post our descriptor */
|
||||
@@ -445,14 +447,14 @@ static void run_scheduled_events(time_t now) {
|
||||
}
|
||||
|
||||
|
||||
/* 2. Every second, we examine pending circuits and prune the
|
||||
/** 2. Every second, we examine pending circuits and prune the
|
||||
* ones which have been pending for more than a few seconds.
|
||||
* We do this before step 3, so it can try building more if
|
||||
* it's not comfortable with the number of available circuits.
|
||||
*/
|
||||
circuit_expire_building(now);
|
||||
|
||||
/* 2b. Also look at pending streams and prune the ones that 'began'
|
||||
/** 2b. Also look at pending streams and prune the ones that 'began'
|
||||
* a long time ago but haven't gotten a 'connected' yet.
|
||||
* Do this before step 3, so we can put them back into pending
|
||||
* state to be picked up by the new circuit.
|
||||
@@ -460,11 +462,11 @@ static void run_scheduled_events(time_t now) {
|
||||
connection_ap_expire_beginning();
|
||||
|
||||
|
||||
/* 2c. And expire connections that we've held open for too long.
|
||||
/** 2c. And expire connections that we've held open for too long.
|
||||
*/
|
||||
connection_expire_held_open();
|
||||
|
||||
/* 3. Every second, we try a new circuit if there are no valid
|
||||
/** 3. Every second, we try a new circuit if there are no valid
|
||||
* circuits. Every NewCircuitPeriod seconds, we expire circuits
|
||||
* that became dirty more than NewCircuitPeriod seconds ago,
|
||||
* and we make a new circ if there are no clean circuits.
|
||||
@@ -472,22 +474,22 @@ static void run_scheduled_events(time_t now) {
|
||||
if(has_fetched_directory)
|
||||
circuit_build_needed_circs(now);
|
||||
|
||||
/* 4. We do housekeeping for each connection... */
|
||||
/** 4. We do housekeeping for each connection... */
|
||||
for(i=0;i<nfds;i++) {
|
||||
run_connection_housekeeping(i, now);
|
||||
}
|
||||
|
||||
/* 5. And remove any marked circuits... */
|
||||
/** 5. And remove any marked circuits... */
|
||||
circuit_close_all_marked();
|
||||
|
||||
/* 6. And upload service descriptors for any services whose intro points
|
||||
/** 6. And upload service descriptors for any services whose intro points
|
||||
* have changed in the last second. */
|
||||
if (last_uploaded_services < now-5) {
|
||||
rend_services_upload(0);
|
||||
last_uploaded_services = now;
|
||||
}
|
||||
|
||||
/* 6. and blow away any connections that need to die. have to do this now,
|
||||
/** 7. and blow away any connections that need to die. have to do this now,
|
||||
* because if we marked a conn for close and left its socket -1, then
|
||||
* we'll pass it to poll/select and bad things will happen.
|
||||
*/
|
||||
@@ -495,7 +497,7 @@ static void run_scheduled_events(time_t now) {
|
||||
conn_close_if_marked(i);
|
||||
}
|
||||
|
||||
/* Called every time we're about to call tor_poll. Increments statistics,
|
||||
/** Called every time we're about to call tor_poll. Increments statistics,
|
||||
* and adjusts token buckets. Returns the number of milliseconds to use for
|
||||
* the poll() timeout.
|
||||
*/
|
||||
@@ -535,7 +537,7 @@ static int prepare_for_poll(void) {
|
||||
return (1000 - (now.tv_usec / 1000)); /* how many milliseconds til the next second? */
|
||||
}
|
||||
|
||||
/* Configure the Tor process from the command line arguments and from the
|
||||
/** Configure the Tor process from the command line arguments and from the
|
||||
* configuration file.
|
||||
*/
|
||||
static int init_from_config(int argc, char **argv) {
|
||||
@@ -594,7 +596,7 @@ static int init_from_config(int argc, char **argv) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Called when we get a SIGHUP: reload configuration files and keys,
|
||||
/** Called when we get a SIGHUP: reload configuration files and keys,
|
||||
* retry all connections, re-upload all descriptors, and so on. */
|
||||
static int do_hup(void) {
|
||||
char keydir[512];
|
||||
@@ -641,7 +643,7 @@ static int do_hup(void) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Tor main loop. */
|
||||
/** Tor main loop. */
|
||||
static int do_main_loop(void) {
|
||||
int i;
|
||||
int timeout;
|
||||
@@ -737,7 +739,7 @@ static int do_main_loop(void) {
|
||||
}
|
||||
}
|
||||
|
||||
/* Unix signal handler. */
|
||||
/** Unix signal handler. */
|
||||
static void catch(int the_signal) {
|
||||
|
||||
#ifndef MS_WINDOWS /* do signal stuff only on unix */
|
||||
@@ -769,7 +771,7 @@ static void catch(int the_signal) {
|
||||
#endif /* signal stuff */
|
||||
}
|
||||
|
||||
/* Write all statistics to the log, with log level 'severity'. Called
|
||||
/** Write all statistics to the log, with log level 'severity'. Called
|
||||
* in response to a SIGUSR1. */
|
||||
static void dumpstats(int severity) {
|
||||
int i;
|
||||
@@ -825,7 +827,7 @@ static void dumpstats(int severity) {
|
||||
rend_service_dump_stats(severity);
|
||||
}
|
||||
|
||||
/* Called before we make any calls to network-related functions.
|
||||
/** Called before we make any calls to network-related functions.
|
||||
* (Some operating systems require their network libraries to be
|
||||
* initialized.) */
|
||||
int network_init(void)
|
||||
@@ -845,7 +847,7 @@ int network_init(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Called by exit() as we shut down the process.
|
||||
/** Called by exit() as we shut down the process.
|
||||
*/
|
||||
void exit_function(void)
|
||||
{
|
||||
@@ -854,7 +856,7 @@ void exit_function(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Main entry point for the Tor command-line client.
|
||||
/** Main entry point for the Tor command-line client.
|
||||
*/
|
||||
int tor_main(int argc, char *argv[]) {
|
||||
|
||||
|
||||
+17
-15
@@ -2,13 +2,14 @@
|
||||
/* See LICENSE for licensing information */
|
||||
/* $Id$ */
|
||||
|
||||
/*****
|
||||
* rendclient.c: Client code to access location-hiddenn services.
|
||||
*****/
|
||||
/**
|
||||
* \file rendclient.c
|
||||
* \brief Client code to access location-hiddenn services.
|
||||
**/
|
||||
|
||||
#include "or.h"
|
||||
|
||||
/* Called when we've established a circuit to an introduction point:
|
||||
/** Called when we've established a circuit to an introduction point:
|
||||
* send the introduction request. */
|
||||
void
|
||||
rend_client_introcirc_is_open(circuit_t *circ)
|
||||
@@ -20,7 +21,7 @@ rend_client_introcirc_is_open(circuit_t *circ)
|
||||
connection_ap_attach_pending();
|
||||
}
|
||||
|
||||
/* Send the establish-rendezvous cell along a rendezvous circuit. if
|
||||
/** Send the establish-rendezvous cell along a rendezvous circuit. if
|
||||
* it fails, mark the circ for close and return -1. else return 0.
|
||||
*/
|
||||
int
|
||||
@@ -46,7 +47,7 @@ rend_client_send_establish_rendezvous(circuit_t *circ)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Called when we're trying to connect an ap conn; sends an INTRODUCE1 cell
|
||||
/** Called when we're trying to connect an ap conn; sends an INTRODUCE1 cell
|
||||
* down introcirc if possible.
|
||||
*/
|
||||
int
|
||||
@@ -129,7 +130,7 @@ err:
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Called when a rendezvous circuit is open; sends a establish
|
||||
/** Called when a rendezvous circuit is open; sends a establish
|
||||
* rendezvous circuit as appropriate. */
|
||||
void
|
||||
rend_client_rendcirc_is_open(circuit_t *circ)
|
||||
@@ -147,7 +148,7 @@ rend_client_rendcirc_is_open(circuit_t *circ)
|
||||
connection_ap_attach_pending();
|
||||
}
|
||||
|
||||
/* Called when get an ACK or a NAK for a REND_INTRODUCE1 cell.
|
||||
/** Called when get an ACK or a NAK for a REND_INTRODUCE1 cell.
|
||||
*/
|
||||
int
|
||||
rend_client_introduction_acked(circuit_t *circ,
|
||||
@@ -216,7 +217,7 @@ rend_client_introduction_acked(circuit_t *circ,
|
||||
}
|
||||
|
||||
|
||||
/* If we are not currently fetching a rendezvous service descriptor
|
||||
/** If we are not currently fetching a rendezvous service descriptor
|
||||
* for the service ID 'query', start a directory connection to fetch a
|
||||
* new one.
|
||||
*/
|
||||
@@ -233,7 +234,7 @@ rend_client_refetch_renddesc(const char *query)
|
||||
}
|
||||
}
|
||||
|
||||
/* remove failed_intro from ent. if ent now has no intro points, or
|
||||
/** remove failed_intro from ent. if ent now has no intro points, or
|
||||
* service is unrecognized, then launch a new renddesc fetch.
|
||||
*
|
||||
* Return -1 if error, 0 if no intro points remain or service
|
||||
@@ -274,7 +275,7 @@ rend_client_remove_intro_point(char *failed_intro, const char *query)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Called when we receive a RENDEZVOUS_ESTABLISHED cell; changes the state of
|
||||
/** Called when we receive a RENDEZVOUS_ESTABLISHED cell; changes the state of
|
||||
* the circuit to C_REND_READY.
|
||||
*/
|
||||
int
|
||||
@@ -291,7 +292,7 @@ rend_client_rendezvous_acked(circuit_t *circ, const char *request, int request_l
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Bob sent us a rendezvous cell; join the circuits. */
|
||||
/** Bob sent us a rendezvous cell; join the circuits. */
|
||||
int
|
||||
rend_client_receive_rendezvous(circuit_t *circ, const char *request, int request_len)
|
||||
{
|
||||
@@ -350,7 +351,7 @@ rend_client_receive_rendezvous(circuit_t *circ, const char *request, int request
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Find all the apconns in state AP_CONN_STATE_RENDDESC_WAIT that
|
||||
/** Find all the apconns in state AP_CONN_STATE_RENDDESC_WAIT that
|
||||
* are waiting on query. If success==1, move them to the next state.
|
||||
* If success==0, fail them.
|
||||
*/
|
||||
@@ -388,11 +389,12 @@ void rend_client_desc_fetched(char *query, int success) {
|
||||
}
|
||||
}
|
||||
|
||||
/** Return 0 if one and two are the same service ids, else -1 or 1 */
|
||||
int rend_cmp_service_ids(const char *one, const char *two) {
|
||||
return strcasecmp(one,two);
|
||||
}
|
||||
|
||||
/* strdup a nickname for a random introduction
|
||||
/** strdup a nickname for a random introduction
|
||||
* point of query. return NULL if error.
|
||||
*/
|
||||
char *rend_client_get_random_intro(char *query) {
|
||||
@@ -423,7 +425,7 @@ char *rend_client_get_random_intro(char *query) {
|
||||
return nickname;
|
||||
}
|
||||
|
||||
/* If address is of the form "y.onion" with a well-formed handle y,
|
||||
/** If address is of the form "y.onion" with a well-formed handle y,
|
||||
* then put a '\0' after y, lower-case it, and return 0.
|
||||
* Else return -1 and change nothing.
|
||||
*/
|
||||
|
||||
+17
-15
@@ -2,14 +2,15 @@
|
||||
/* See LICENSE for licensing information */
|
||||
/* $Id$ */
|
||||
|
||||
/*****
|
||||
* rendcommon.c: Rendezvous implementation: shared code between
|
||||
/**
|
||||
* \file rendcommon.c
|
||||
* \brief Rendezvous implementation: shared code between
|
||||
* introducers, services, clients, and rendezvous points.
|
||||
*****/
|
||||
**/
|
||||
|
||||
#include "or.h"
|
||||
|
||||
/* Free the storage held by the service descriptor 'desc'.
|
||||
/** Free the storage held by the service descriptor 'desc'.
|
||||
*/
|
||||
void rend_service_descriptor_free(rend_service_descriptor_t *desc)
|
||||
{
|
||||
@@ -25,7 +26,7 @@ void rend_service_descriptor_free(rend_service_descriptor_t *desc)
|
||||
tor_free(desc);
|
||||
}
|
||||
|
||||
/* Encode a service descriptor for 'desc', and sign it with 'key'. Store
|
||||
/** Encode a service descriptor for 'desc', and sign it with 'key'. Store
|
||||
* the descriptor in *str_out, and set *len_out to its length.
|
||||
*/
|
||||
int
|
||||
@@ -71,7 +72,7 @@ rend_encode_service_descriptor(rend_service_descriptor_t *desc,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Parse a service descriptor at 'str' (len bytes). On success,
|
||||
/** Parse a service descriptor at 'str' (len bytes). On success,
|
||||
* return a newly alloced service_descriptor_t. On failure, return
|
||||
* NULL.
|
||||
*/
|
||||
@@ -128,7 +129,7 @@ rend_service_descriptor_t *rend_parse_service_descriptor(
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Sets out to the first 10 bytes of the digest of 'pk', base32
|
||||
/** Sets out to the first 10 bytes of the digest of 'pk', base32
|
||||
* encoded. NUL-terminates out. (We use this string to identify
|
||||
* services in directory requests and .onion URLs.)
|
||||
*/
|
||||
@@ -144,21 +145,22 @@ int rend_get_service_id(crypto_pk_env_t *pk, char *out)
|
||||
}
|
||||
|
||||
/* ==== Rendezvous service descriptor cache. */
|
||||
|
||||
#define REND_CACHE_MAX_AGE (24*60*60)
|
||||
#define REND_CACHE_MAX_SKEW (90*60)
|
||||
|
||||
/* Map from service id (as generated by rend_get_service_id) to
|
||||
/** Map from service id (as generated by rend_get_service_id) to
|
||||
* rend_cache_entry_t. */
|
||||
static strmap_t *rend_cache = NULL;
|
||||
|
||||
/* Initializes the service descriptor cache.
|
||||
/** Initializes the service descriptor cache.
|
||||
*/
|
||||
void rend_cache_init(void)
|
||||
{
|
||||
rend_cache = strmap_new();
|
||||
}
|
||||
|
||||
/* Removes all old entries from the service descriptor cache.
|
||||
/** Removes all old entries from the service descriptor cache.
|
||||
*/
|
||||
void rend_cache_clean(void)
|
||||
{
|
||||
@@ -182,7 +184,7 @@ void rend_cache_clean(void)
|
||||
}
|
||||
}
|
||||
|
||||
/* Return true iff 'query' is a syntactically valid service ID (as
|
||||
/** Return true iff 'query' is a syntactically valid service ID (as
|
||||
* generated by rend_get_service_id). */
|
||||
int rend_valid_service_id(const char *query) {
|
||||
if(strlen(query) != REND_SERVICE_ID_LEN)
|
||||
@@ -194,7 +196,7 @@ int rend_valid_service_id(const char *query) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* If we have a cached rend_cache_entry_t for the service ID 'query', set
|
||||
/** If we have a cached rend_cache_entry_t for the service ID 'query', set
|
||||
* *e to that entry and return 1. Else return 0.
|
||||
*/
|
||||
int rend_cache_lookup_entry(const char *query, rend_cache_entry_t **e)
|
||||
@@ -208,7 +210,7 @@ int rend_cache_lookup_entry(const char *query, rend_cache_entry_t **e)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* 'query' is a base-32'ed service id. If it's malformed, return -1.
|
||||
/** 'query' is a base-32'ed service id. If it's malformed, return -1.
|
||||
* Else look it up.
|
||||
* If it is found, point *desc to it, and write its length into
|
||||
* *desc_len, and return 1.
|
||||
@@ -227,7 +229,7 @@ int rend_cache_lookup_desc(const char *query, const char **desc, int *desc_len)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Parse *desc, calculate its service id, and store it in the cache.
|
||||
/** Parse *desc, calculate its service id, and store it in the cache.
|
||||
* If we have a newer descriptor with the same ID, ignore this one.
|
||||
* If we have an older descriptor with the same ID, replace it.
|
||||
* Returns -1 if it's malformed or otherwise rejected, else return 0.
|
||||
@@ -289,7 +291,7 @@ int rend_cache_store(const char *desc, int desc_len)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Called when we get a rendezvous-related relay cell on circuit
|
||||
/** Called when we get a rendezvous-related relay cell on circuit
|
||||
* *circ. Dispatch on rendezvous relay command. */
|
||||
void rend_process_relay_cell(circuit_t *circ, int command, int length,
|
||||
const char *payload)
|
||||
|
||||
@@ -2,13 +2,14 @@
|
||||
/* See LICENSE for licensing information */
|
||||
/* $Id$ */
|
||||
|
||||
/*****
|
||||
* rendmid.c: Implement introductions points and rendezvous points.
|
||||
*****/
|
||||
/**
|
||||
* \file rendmid.c
|
||||
* \brief Implement introductions points and rendezvous points.
|
||||
**/
|
||||
|
||||
#include "or.h"
|
||||
|
||||
/* Respond to an ESTABLISH_INTRO cell by checking the signed data and
|
||||
/** Respond to an ESTABLISH_INTRO cell by checking the signed data and
|
||||
* setting the circuit's purpose and service pk digest.
|
||||
*/
|
||||
int
|
||||
@@ -107,7 +108,7 @@ rend_mid_establish_intro(circuit_t *circ, const char *request, int request_len)
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Process an INTRODUCE1 cell by finding the corresponding introduction
|
||||
/** Process an INTRODUCE1 cell by finding the corresponding introduction
|
||||
* circuit, and relaying the body of the INTRODUCE1 cell inside an
|
||||
* INTRODUCE2 cell.
|
||||
*/
|
||||
@@ -177,7 +178,7 @@ rend_mid_introduce(circuit_t *circ, const char *request, int request_len)
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Process an ESTABLISH_RENDEZVOUS cell by setting the circuit's purpose and
|
||||
/** Process an ESTABLISH_RENDEZVOUS cell by setting the circuit's purpose and
|
||||
* rendezvous cookie.
|
||||
*/
|
||||
int
|
||||
@@ -223,7 +224,7 @@ rend_mid_establish_rendezvous(circuit_t *circ, const char *request, int request_
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Process a RENDEZVOUS1 cell by looking up the correct rendezvous
|
||||
/** Process a RENDEZVOUS1 cell by looking up the correct rendezvous
|
||||
* circuit by its relaying the cell's body in a RENDEZVOUS2 cell, and
|
||||
* connecting the two circuits.
|
||||
*/
|
||||
|
||||
+37
-37
@@ -2,15 +2,16 @@
|
||||
/* See LICENSE for licensing information */
|
||||
/* $Id$ */
|
||||
|
||||
/*****
|
||||
* rendservice.c: The hidden-service side of rendezvous functionality.
|
||||
*****/
|
||||
/**
|
||||
* \file rendservice.c
|
||||
* \brief The hidden-service side of rendezvous functionality.
|
||||
**/
|
||||
|
||||
#include "or.h"
|
||||
|
||||
static circuit_t *find_intro_circuit(routerinfo_t *router, const char *pk_digest);
|
||||
|
||||
/* Represents the mapping from a virtual port of a rendezvous service to
|
||||
/** Represents the mapping from a virtual port of a rendezvous service to
|
||||
* a real port on some IP.
|
||||
*/
|
||||
typedef struct rend_service_port_config_t {
|
||||
@@ -19,33 +20,31 @@ typedef struct rend_service_port_config_t {
|
||||
uint32_t real_address;
|
||||
} rend_service_port_config_t;
|
||||
|
||||
/* Try to maintain this many intro points per service if possible.
|
||||
*/
|
||||
/** Try to maintain this many intro points per service if possible. */
|
||||
#define NUM_INTRO_POINTS 3
|
||||
|
||||
/* Represents a single hidden service running at this OP.
|
||||
*/
|
||||
/** Represents a single hidden service running at this OP. */
|
||||
typedef struct rend_service_t {
|
||||
/* Fields specified in config file */
|
||||
char *directory; /* where in the filesystem it stores it */
|
||||
smartlist_t *ports; /* List of rend_service_port_config_t */
|
||||
char *intro_prefer_nodes; /* comma-separated list of nicknames */
|
||||
char *intro_exclude_nodes; /* comma-separated list of nicknames */
|
||||
/** Fields specified in config file */
|
||||
char *directory; /**< where in the filesystem it stores it */
|
||||
smartlist_t *ports; /**< List of rend_service_port_config_t */
|
||||
char *intro_prefer_nodes; /**< comma-separated list of nicknames */
|
||||
char *intro_exclude_nodes; /**< comma-separated list of nicknames */
|
||||
/* Other fields */
|
||||
crypto_pk_env_t *private_key;
|
||||
char service_id[REND_SERVICE_ID_LEN+1];
|
||||
char pk_digest[DIGEST_LEN];
|
||||
smartlist_t *intro_nodes; /* list of nicknames for intro points we have,
|
||||
smartlist_t *intro_nodes; /**< list of nicknames for intro points we have,
|
||||
* or are trying to establish. */
|
||||
rend_service_descriptor_t *desc;
|
||||
int desc_is_dirty;
|
||||
} rend_service_t;
|
||||
|
||||
/* A list of rend_service_t's for services run on this OP.
|
||||
/** A list of rend_service_t's for services run on this OP.
|
||||
*/
|
||||
static smartlist_t *rend_service_list = NULL;
|
||||
|
||||
/* Release the storage held by 'service'.
|
||||
/** Release the storage held by 'service'.
|
||||
*/
|
||||
static void rend_service_free(rend_service_t *service)
|
||||
{
|
||||
@@ -64,7 +63,7 @@ static void rend_service_free(rend_service_t *service)
|
||||
tor_free(service);
|
||||
}
|
||||
|
||||
/* Release all the storage held in rend_service_list, and allocate a new,
|
||||
/** Release all the storage held in rend_service_list, and allocate a new,
|
||||
* empty rend_service_list.
|
||||
*/
|
||||
static void rend_service_free_all(void)
|
||||
@@ -79,7 +78,7 @@ static void rend_service_free_all(void)
|
||||
rend_service_list = smartlist_create();
|
||||
}
|
||||
|
||||
/* Validate 'service' and add it to rend_service_list if possible.
|
||||
/** Validate 'service' and add it to rend_service_list if possible.
|
||||
*/
|
||||
static void add_service(rend_service_t *service)
|
||||
{
|
||||
@@ -108,7 +107,7 @@ static void add_service(rend_service_t *service)
|
||||
}
|
||||
}
|
||||
|
||||
/* Parses a real-port to virtual-port mapping and returns a new
|
||||
/** Parses a real-port to virtual-port mapping and returns a new
|
||||
* rend_service_port_config_t.
|
||||
*
|
||||
* The format is: VirtualPort (IP|RealPort|IP:RealPort)?
|
||||
@@ -176,7 +175,7 @@ static rend_service_port_config_t *parse_port_config(const char *string)
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Set up rend_service_list, based on the values of HiddenServiceDir and
|
||||
/** Set up rend_service_list, based on the values of HiddenServiceDir and
|
||||
* HiddenServicePort in 'options'. Return 0 on success and -1 on
|
||||
* failure.
|
||||
*/
|
||||
@@ -230,7 +229,7 @@ int rend_config_services(or_options_t *options)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Replace the old value of service->desc with one that reflects
|
||||
/** Replace the old value of service->desc with one that reflects
|
||||
* the other fields in service.
|
||||
*/
|
||||
static void rend_service_update_descriptor(rend_service_t *service)
|
||||
@@ -260,7 +259,7 @@ static void rend_service_update_descriptor(rend_service_t *service)
|
||||
}
|
||||
}
|
||||
|
||||
/* Load and/or generate private keys for all hidden services. Return 0 on
|
||||
/** Load and/or generate private keys for all hidden services. Return 0 on
|
||||
* success, -1 on failure.
|
||||
*/
|
||||
int rend_service_load_keys(void)
|
||||
@@ -311,7 +310,7 @@ int rend_service_load_keys(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Return the service whose public key has a digest of 'digest'. Return
|
||||
/** Return the service whose public key has a digest of 'digest'. Return
|
||||
* NULL if no such service exists.
|
||||
*/
|
||||
static rend_service_t *
|
||||
@@ -326,7 +325,7 @@ rend_service_get_by_pk_digest(const char* digest)
|
||||
* Handle cells
|
||||
******/
|
||||
|
||||
/* Respond to an INTRODUCE2 cell by launching a circuit to the chosen
|
||||
/** Respond to an INTRODUCE2 cell by launching a circuit to the chosen
|
||||
* rendezvous points.
|
||||
*/
|
||||
int
|
||||
@@ -459,9 +458,11 @@ rend_service_introduce(circuit_t *circuit, const char *request, int request_len)
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/** How many times will a hidden service operator attempt to connect to
|
||||
* a requested rendezvous point before giving up? */
|
||||
#define MAX_REND_FAILURES 3
|
||||
/* Called when we fail building a rendezvous circuit at some point other
|
||||
|
||||
/** Called when we fail building a rendezvous circuit at some point other
|
||||
* than the last hop: launches a new circuit to the same rendezvous point.
|
||||
*/
|
||||
void
|
||||
@@ -501,7 +502,7 @@ rend_service_relaunch_rendezvous(circuit_t *oldcirc)
|
||||
memcpy(newcirc->rend_cookie, oldcirc->rend_cookie, REND_COOKIE_LEN);
|
||||
}
|
||||
|
||||
/* Launch a circuit to serve as an introduction point for the service
|
||||
/** Launch a circuit to serve as an introduction point for the service
|
||||
* 'service' at the introduction point 'nickname'
|
||||
*/
|
||||
static int
|
||||
@@ -524,7 +525,7 @@ rend_service_launch_establish_intro(rend_service_t *service, const char *nicknam
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Called when we're done building a circuit to an introduction point:
|
||||
/** Called when we're done building a circuit to an introduction point:
|
||||
* sends a RELAY_ESTABLISH_INTRO cell.
|
||||
*/
|
||||
void
|
||||
@@ -585,7 +586,7 @@ rend_service_intro_is_ready(circuit_t *circuit)
|
||||
circuit_mark_for_close(circuit);
|
||||
}
|
||||
|
||||
/* Called when we get an INTRO_ESTABLISHED cell; mark the circuit as a
|
||||
/** Called when we get an INTRO_ESTABLISHED cell; mark the circuit as a
|
||||
* live introduction point, and note that the service descriptor is
|
||||
* now out-of-date.*/
|
||||
int
|
||||
@@ -612,7 +613,7 @@ rend_service_intro_established(circuit_t *circuit, const char *request, int requ
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Called once a circuit to a rendezvous point is established: sends a
|
||||
/** Called once a circuit to a rendezvous point is established: sends a
|
||||
* RELAY_COMMAND_RENDEZVOUS1 cell.
|
||||
*/
|
||||
void
|
||||
@@ -690,7 +691,7 @@ rend_service_rendezvous_is_ready(circuit_t *circuit)
|
||||
* Manage introduction points
|
||||
******/
|
||||
|
||||
/* Return the (possibly non-open) introduction circuit ending at
|
||||
/** Return the (possibly non-open) introduction circuit ending at
|
||||
* 'router' for the service whose public key is 'pk_digest'. Return
|
||||
* NULL if no such service is found.
|
||||
*/
|
||||
@@ -720,7 +721,7 @@ find_intro_circuit(routerinfo_t *router, const char *pk_digest)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* If the directory servers don't have an up-to-date descriptor for
|
||||
/** If the directory servers don't have an up-to-date descriptor for
|
||||
* 'service', Encode and sign the service descriptor for 'service',
|
||||
* and upload it to all the dirservers.
|
||||
*/
|
||||
@@ -748,12 +749,11 @@ upload_service_descriptor(rend_service_t *service)
|
||||
service->desc_is_dirty = 0;
|
||||
}
|
||||
|
||||
|
||||
/* XXXX Make this longer once directories remember service descriptors across
|
||||
* restarts.*/
|
||||
#define MAX_SERVICE_PUBLICATION_INTERVAL (15*60)
|
||||
|
||||
/* For every service, check how many intro points it currently has, and:
|
||||
/** For every service, check how many intro points it currently has, and:
|
||||
* - Pick new intro points as necessary.
|
||||
* - Launch circuits to any new intro points.
|
||||
*/
|
||||
@@ -840,7 +840,7 @@ void rend_services_introduce(void) {
|
||||
smartlist_free(exclude_routers);
|
||||
}
|
||||
|
||||
/* Regenerate and upload rendezvous service descriptors for all
|
||||
/** Regenerate and upload rendezvous service descriptors for all
|
||||
* services. If 'force' is false, skip services where we've already
|
||||
* uploaded an up-to-date copy; if 'force' is true, regenerate and
|
||||
* upload everything.
|
||||
@@ -860,7 +860,7 @@ rend_services_upload(int force)
|
||||
}
|
||||
}
|
||||
|
||||
/* Log the status of introduction points for all rendezvous services
|
||||
/** Log the status of introduction points for all rendezvous services
|
||||
* at log severity 'serverity'.
|
||||
*/
|
||||
void
|
||||
@@ -893,7 +893,7 @@ rend_service_dump_stats(int severity)
|
||||
}
|
||||
}
|
||||
|
||||
/* 'conn' is a rendezvous exit stream. Look up the hidden service for
|
||||
/** 'conn' is a rendezvous exit stream. Look up the hidden service for
|
||||
* 'circ', and look up the port and address based on conn->port.
|
||||
* Assign the actual conn->addr and conn->port. Return -1 if failure,
|
||||
* or 0 for success.
|
||||
|
||||
+32
-31
@@ -4,14 +4,15 @@
|
||||
|
||||
#include "or.h"
|
||||
|
||||
/*****
|
||||
* router.c: OR functionality, including key maintenance, generating
|
||||
/**
|
||||
* \file router.c
|
||||
* \brief OR functionality, including key maintenance, generating
|
||||
* and uploading server descriptors, retrying OR connections.
|
||||
*****/
|
||||
**/
|
||||
|
||||
extern or_options_t options; /* command-line and config-file options */
|
||||
|
||||
/* exposed for test.c */ void get_platform_str(char *platform, int len);
|
||||
/** exposed for test.c */ void get_platform_str(char *platform, int len);
|
||||
|
||||
/************************************************************/
|
||||
|
||||
@@ -19,14 +20,14 @@ extern or_options_t options; /* command-line and config-file options */
|
||||
* Key management: ORs only.
|
||||
*****/
|
||||
|
||||
/* Private keys for this OR. There is also an SSL key managed by tortls.c.
|
||||
/** Private keys for this OR. There is also an SSL key managed by tortls.c.
|
||||
*/
|
||||
static time_t onionkey_set_at=0; /* When was onionkey last changed? */
|
||||
static crypto_pk_env_t *onionkey=NULL;
|
||||
static crypto_pk_env_t *lastonionkey=NULL;
|
||||
static crypto_pk_env_t *identitykey=NULL;
|
||||
|
||||
/* Replace the current onion key with 'k'. Does not affect lastonionkey;
|
||||
/** Replace the current onion key with 'k'. Does not affect lastonionkey;
|
||||
* to update onionkey correctly, call rotate_onion_key().
|
||||
*/
|
||||
void set_onion_key(crypto_pk_env_t *k) {
|
||||
@@ -34,14 +35,14 @@ void set_onion_key(crypto_pk_env_t *k) {
|
||||
onionkey_set_at = time(NULL);
|
||||
}
|
||||
|
||||
/* Return the current onion key. Requires that the onion key has been
|
||||
/** Return the current onion key. Requires that the onion key has been
|
||||
* loaded or generated. */
|
||||
crypto_pk_env_t *get_onion_key(void) {
|
||||
tor_assert(onionkey);
|
||||
return onionkey;
|
||||
}
|
||||
|
||||
/* Return the onion key that was current before the most recent onion
|
||||
/** Return the onion key that was current before the most recent onion
|
||||
* key rotation. If no rotation has been performed since this process
|
||||
* started, return NULL.
|
||||
*/
|
||||
@@ -49,7 +50,7 @@ crypto_pk_env_t *get_previous_onion_key(void) {
|
||||
return lastonionkey;
|
||||
}
|
||||
|
||||
/* Return the time when the onion key was last set. This is either the time
|
||||
/** Return the time when the onion key was last set. This is either the time
|
||||
* when the process launched, or the time of the most recent key rotation since
|
||||
* the process launched.
|
||||
*/
|
||||
@@ -57,13 +58,13 @@ time_t get_onion_key_set_at(void) {
|
||||
return onionkey_set_at;
|
||||
}
|
||||
|
||||
/* Set the current identity key to k.
|
||||
/** Set the current identity key to k.
|
||||
*/
|
||||
void set_identity_key(crypto_pk_env_t *k) {
|
||||
identitykey = k;
|
||||
}
|
||||
|
||||
/* Returns the current identity key; requires that the identity key has been
|
||||
/** Returns the current identity key; requires that the identity key has been
|
||||
* set.
|
||||
*/
|
||||
crypto_pk_env_t *get_identity_key(void) {
|
||||
@@ -71,12 +72,12 @@ crypto_pk_env_t *get_identity_key(void) {
|
||||
return identitykey;
|
||||
}
|
||||
|
||||
/* Replace the previous onion key with the current onion key, and generate
|
||||
/** Replace the previous onion key with the current onion key, and generate
|
||||
* a new previous onion key. Immediately after calling this function,
|
||||
* the OR should:
|
||||
* a) schedule all previous cpuworkers to shut down _after_ processing
|
||||
* pending work. (This will cause fresh cpuworkers to be generated.)
|
||||
* b) generate and upload a fresh routerinfo.
|
||||
* - schedule all previous cpuworkers to shut down _after_ processing
|
||||
* pending work. (This will cause fresh cpuworkers to be generated.)
|
||||
* - generate and upload a fresh routerinfo.
|
||||
*/
|
||||
void rotate_onion_key(void)
|
||||
{
|
||||
@@ -107,7 +108,7 @@ void rotate_onion_key(void)
|
||||
log_fn(LOG_WARN, "Couldn't rotate onion key.");
|
||||
}
|
||||
|
||||
/* Try to read an RSA key from 'fname'. If 'fname' doesn't exist, create a new
|
||||
/** Try to read an RSA key from 'fname'. If 'fname' doesn't exist, create a new
|
||||
* RSA key and save it in 'fname'. Return the read/created key, or NULL on
|
||||
* error.
|
||||
*/
|
||||
@@ -160,7 +161,7 @@ crypto_pk_env_t *init_key_from_file(const char *fname)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Initialize all OR private keys, and the TLS context, as necessary.
|
||||
/** Initialize all OR private keys, and the TLS context, as necessary.
|
||||
* On OPs, this only initializes the tls context.
|
||||
*/
|
||||
int init_keys(void) {
|
||||
@@ -280,7 +281,7 @@ int init_keys(void) {
|
||||
* Clique maintenance
|
||||
*****/
|
||||
|
||||
/* OR only: try to open connections to all of the otehr ORs we know about.
|
||||
/** OR only: try to open connections to all of the other ORs we know about.
|
||||
*/
|
||||
void router_retry_connections(void) {
|
||||
int i;
|
||||
@@ -304,12 +305,12 @@ void router_retry_connections(void) {
|
||||
* OR descriptor generation.
|
||||
*****/
|
||||
|
||||
/* my routerinfo. */
|
||||
/** my routerinfo. */
|
||||
static routerinfo_t *desc_routerinfo = NULL;
|
||||
/* string representation of my descriptor, signed by me. */
|
||||
/** string representation of my descriptor, signed by me. */
|
||||
static char descriptor[8192];
|
||||
|
||||
/* OR only: try to upload our signed descriptor to all the directory servers
|
||||
/** OR only: try to upload our signed descriptor to all the directory servers
|
||||
* we know about.
|
||||
*/
|
||||
void router_upload_dir_desc_to_dirservers(void) {
|
||||
@@ -323,7 +324,7 @@ void router_upload_dir_desc_to_dirservers(void) {
|
||||
router_post_to_dirservers(DIR_PURPOSE_UPLOAD_DIR, s, strlen(s));
|
||||
}
|
||||
|
||||
/* Start a connection to every known directory server, using
|
||||
/** Start a connection to every known directory server, using
|
||||
* connection purpose 'purpose' and uploading the payload 'payload'
|
||||
* (length 'payload_len'). The purpose should be one of
|
||||
* 'DIR_PURPOSE_UPLOAD_DIR' or 'DIR_PURPOSE_UPLOAD_RENDDESC'.
|
||||
@@ -346,7 +347,7 @@ void router_post_to_dirservers(uint8_t purpose, const char *payload, int payload
|
||||
}
|
||||
}
|
||||
|
||||
/* Append the comma-separated sequence of exit policies in 's' to the
|
||||
/** Append the comma-separated sequence of exit policies in 's' to the
|
||||
* exit policy in 'router'. */
|
||||
static void router_add_exit_policy_from_config_helper(const char *s, routerinfo_t *router) {
|
||||
char *e;
|
||||
@@ -383,7 +384,7 @@ static void router_add_exit_policy_from_config_helper(const char *s, routerinfo_
|
||||
|
||||
#define DEFAULT_EXIT_POLICY "reject 0.0.0.0/8,reject 169.254.0.0/16,reject 127.0.0.0/8,reject 192.168.0.0/16,reject 10.0.0.0/8,reject 172.16.0.0/12,accept *:20-22,accept *:53,accept *:79-81,accept *:110,accept *:143,accept *:443,accept *:873,accept *:993,accept *:995,accept *:1024-65535,reject *:*"
|
||||
|
||||
/* Set the exit policy on 'router' to match the exit policy in the current
|
||||
/** Set the exit policy on 'router' to match the exit policy in the current
|
||||
* configuration file. If the exit policy doesn't have a catch-all rule,
|
||||
* then append the default exit policy as well.
|
||||
*/
|
||||
@@ -398,7 +399,7 @@ static void router_add_exit_policy_from_config(routerinfo_t *router) {
|
||||
}
|
||||
}
|
||||
|
||||
/* OR only: Return false if my exit policy says to allow connection to
|
||||
/** OR only: Return false if my exit policy says to allow connection to
|
||||
* conn. Else return true.
|
||||
*/
|
||||
int router_compare_to_my_exit_policy(connection_t *conn)
|
||||
@@ -412,7 +413,7 @@ int router_compare_to_my_exit_policy(connection_t *conn)
|
||||
|
||||
}
|
||||
|
||||
/* Return true iff 'router' has the same nickname as this OR. (For an OP,
|
||||
/** Return true iff 'router' has the same nickname as this OR. (For an OP,
|
||||
* always returns false.)
|
||||
*/
|
||||
int router_is_me(routerinfo_t *router)
|
||||
@@ -421,7 +422,7 @@ int router_is_me(routerinfo_t *router)
|
||||
return options.Nickname && !strcasecmp(router->nickname, options.Nickname);
|
||||
}
|
||||
|
||||
/* Return a routerinfo for this OR, rebuilding a fresh one if
|
||||
/** Return a routerinfo for this OR, rebuilding a fresh one if
|
||||
* necessary. Return NULL on error, or if called on an OP. */
|
||||
routerinfo_t *router_get_my_routerinfo(void)
|
||||
{
|
||||
@@ -435,7 +436,7 @@ routerinfo_t *router_get_my_routerinfo(void)
|
||||
return desc_routerinfo;
|
||||
}
|
||||
|
||||
/* OR only: Return a signed server descriptor for this OR, rebuilding a fresh
|
||||
/** OR only: Return a signed server descriptor for this OR, rebuilding a fresh
|
||||
* one if necessary. Return NULL on error.
|
||||
*/
|
||||
const char *router_get_my_descriptor(void) {
|
||||
@@ -447,7 +448,7 @@ const char *router_get_my_descriptor(void) {
|
||||
return descriptor;
|
||||
}
|
||||
|
||||
/* Rebuild a fresh routerinfo and signed server descriptor for this
|
||||
/** Rebuild a fresh routerinfo and signed server descriptor for this
|
||||
* OR. Return 0 on success, -1 on error.
|
||||
*/
|
||||
int router_rebuild_descriptor(void) {
|
||||
@@ -485,7 +486,7 @@ int router_rebuild_descriptor(void) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Set 'platform' (max length 'len') to a NUL-terminated short string
|
||||
/** Set 'platform' (max length 'len') to a NUL-terminated short string
|
||||
* describing the version of Tor and the operating system we're
|
||||
* currently running on.
|
||||
*/
|
||||
@@ -502,7 +503,7 @@ void get_platform_str(char *platform, int len)
|
||||
*/
|
||||
#define DEBUG_ROUTER_DUMP_ROUTER_TO_STRING
|
||||
|
||||
/* OR only: Given a routerinfo for this router, and an identity key to
|
||||
/** OR only: Given a routerinfo for this router, and an identity key to
|
||||
* sign with, encode the routerinfo as a signed server descriptor and
|
||||
* write the result into 's', using at most 'maxlen' bytes. Return -1
|
||||
* on failure, and the number of bytes used on success.
|
||||
|
||||
+69
-67
@@ -9,26 +9,27 @@
|
||||
|
||||
#include "or.h"
|
||||
|
||||
/*****
|
||||
* routerlist.c: Code to parse descriptors and directories, and to
|
||||
/**
|
||||
* \file routerlist.c
|
||||
* \brief Code to parse descriptors and directories, and to
|
||||
* maintain and access the global list of routerinfos for known
|
||||
* servers.
|
||||
*****/
|
||||
**/
|
||||
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
extern or_options_t options; /* command-line and config-file options */
|
||||
extern or_options_t options; /**< command-line and config-file options */
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
/* We parse a directory by breaking it into "tokens", each consisting
|
||||
/** We parse a directory by breaking it into "tokens", each consisting
|
||||
* of a keyword, a line full of arguments, and a binary object. The
|
||||
* arguments and object are both optional, depending on the keyword
|
||||
* type.
|
||||
*/
|
||||
|
||||
/* Enumeration of possible token types. The ones starting with K_
|
||||
/** Enumeration of possible token types. The ones starting with K_
|
||||
* correspond to directory 'keywords'. _UNRECOGNIZED is for an
|
||||
* unrecognized keyword; _ERR is an error in the tokenizing process,
|
||||
* _EOF is an end-of-file marker, and _NIL is used to encode
|
||||
@@ -57,46 +58,46 @@ typedef enum {
|
||||
_NIL
|
||||
} directory_keyword;
|
||||
|
||||
/* Structure to hold a single directory tokon.
|
||||
/** Structure to hold a single directory tokon.
|
||||
*/
|
||||
typedef struct directory_token_t {
|
||||
directory_keyword tp; /* Type of the token. */
|
||||
int n_args; /* Number of elements in args */
|
||||
char **args; /* Array of arguments from keyword line. */
|
||||
char *object_type; /* -----BEGIN [object_type]-----*/
|
||||
int object_size; /* Bytes in object_body */
|
||||
char *object_body; /* Contents of object, base64-decoded. */
|
||||
crypto_pk_env_t *key; /* For public keys only. */
|
||||
char *error; /* For _ERR tokens only. */
|
||||
directory_keyword tp; /**< Type of the token. */
|
||||
int n_args; /**< Number of elements in args */
|
||||
char **args; /**< Array of arguments from keyword line. */
|
||||
char *object_type; /**< -----BEGIN [object_type]-----*/
|
||||
int object_size; /**< Bytes in object_body */
|
||||
char *object_body; /**< Contents of object, base64-decoded. */
|
||||
crypto_pk_env_t *key; /**< For public keys only. */
|
||||
char *error; /**< For _ERR tokens only. */
|
||||
} directory_token_t;
|
||||
|
||||
/* ********************************************************************** */
|
||||
|
||||
/* We use a table of rules to decide how to parse each token type. */
|
||||
/** We use a table of rules to decide how to parse each token type. */
|
||||
|
||||
/* Rules for how many arguments a keyword can take. */
|
||||
/** Rules for how many arguments a keyword can take. */
|
||||
typedef enum {
|
||||
NO_ARGS, /* (1) no arguments, ever */
|
||||
ARGS, /* (2) a list of arguments separated by spaces */
|
||||
CONCAT_ARGS, /* or (3) the rest of the line, treated as a single argument. */
|
||||
NO_ARGS, /**< (1) no arguments, ever */
|
||||
ARGS, /**< (2) a list of arguments separated by spaces */
|
||||
CONCAT_ARGS, /**< or (3) the rest of the line, treated as a single argument. */
|
||||
} arg_syntax;
|
||||
|
||||
/* Rules for whether the keyword needs an object. */
|
||||
/** Rules for whether the keyword needs an object. */
|
||||
typedef enum {
|
||||
NO_OBJ, /* (1) no object, ever */
|
||||
NEED_OBJ, /* (2) object is required */
|
||||
NEED_KEY, /* (3) object is required, and must be a public key. */
|
||||
OBJ_OK, /* or (4) object is optional. */
|
||||
NO_OBJ, /**< (1) no object, ever */
|
||||
NEED_OBJ, /**< (2) object is required */
|
||||
NEED_KEY, /**< (3) object is required, and must be a public key. */
|
||||
OBJ_OK, /**< or (4) object is optional. */
|
||||
} obj_syntax;
|
||||
|
||||
/* Rules for where a keyword can appear. */
|
||||
/** Rules for where a keyword can appear. */
|
||||
typedef enum {
|
||||
ANY = 0, /* Appears in router descriptor or in directory sections. */
|
||||
DIR_ONLY, /* Appears only in directory. */
|
||||
RTR_ONLY, /* Appears only in router descriptor. */
|
||||
ANY = 0, /**< Appears in router descriptor or in directory sections. */
|
||||
DIR_ONLY, /**< Appears only in directory. */
|
||||
RTR_ONLY, /**< Appears only in router descriptor. */
|
||||
} where_syntax;
|
||||
|
||||
/* Table mapping keywords to token value and to argument rules. */
|
||||
/** Table mapping keywords to token value and to argument rules. */
|
||||
static struct {
|
||||
char *t; int v; arg_syntax s; obj_syntax os; where_syntax ws;
|
||||
} token_table[] = {
|
||||
@@ -155,12 +156,12 @@ static directory_token_t *get_next_token(const char **s, where_syntax where);
|
||||
* descriptors.)
|
||||
*****/
|
||||
|
||||
/* Global list of all of the routers that we, as an OR or OP, know about. */
|
||||
/** Global list of all of the routers that we, as an OR or OP, know about. */
|
||||
static routerlist_t *routerlist = NULL;
|
||||
|
||||
extern int has_fetched_directory; /* from main.c */
|
||||
extern int has_fetched_directory; /**< from main.c */
|
||||
|
||||
/* Try to find a running dirserver. If there are no running dirservers
|
||||
/** Try to find a running dirserver. If there are no running dirservers
|
||||
* in our routerlist, reload the routerlist and try again. */
|
||||
routerinfo_t *router_pick_directory_server(void) {
|
||||
routerinfo_t *choice;
|
||||
@@ -182,7 +183,7 @@ routerinfo_t *router_pick_directory_server(void) {
|
||||
return choice;
|
||||
}
|
||||
|
||||
/* Pick a random running router with a positive dir_port from our
|
||||
/** Pick a random running router with a positive dir_port from our
|
||||
* routerlist. */
|
||||
static routerinfo_t *router_pick_directory_server_impl(void) {
|
||||
int i;
|
||||
@@ -221,7 +222,7 @@ static routerinfo_t *router_pick_directory_server_impl(void) {
|
||||
return dirserver;
|
||||
}
|
||||
|
||||
/* Given a comma-and-whitespace separated list of nicknames, see which
|
||||
/** Given a comma-and-whitespace separated list of nicknames, see which
|
||||
* nicknames in 'list' name routers in our routerlist that are
|
||||
* currently running. Add the routerinfos for those routers to 'sl'.
|
||||
*/
|
||||
@@ -254,7 +255,7 @@ void add_nickname_list_to_smartlist(smartlist_t *sl, const char *list) {
|
||||
}
|
||||
}
|
||||
|
||||
/* Add every router from our routerlist that is currently running to 'sl'.
|
||||
/** Add every router from our routerlist that is currently running to 'sl'.
|
||||
*/
|
||||
void router_add_running_routers_to_smartlist(smartlist_t *sl) {
|
||||
routerinfo_t *router;
|
||||
@@ -272,7 +273,7 @@ void router_add_running_routers_to_smartlist(smartlist_t *sl) {
|
||||
}
|
||||
}
|
||||
|
||||
/* Pick a random running router from a routerlist 'dir'. If any node
|
||||
/** Pick a random running router from a routerlist 'dir'. If any node
|
||||
* named in 'preferred' is available, pick one of those. Never pick a
|
||||
* node named in 'excluded', or whose routerinfo is in
|
||||
* 'excludedsmartlist', even if they are the only nodes available.
|
||||
@@ -310,7 +311,7 @@ routerinfo_t *router_choose_random_node(routerlist_t *dir,
|
||||
return choice;
|
||||
}
|
||||
|
||||
/* Return the router in our routerlist whose address is 'addr' and
|
||||
/** Return the router in our routerlist whose address is 'addr' and
|
||||
* whose OR port is 'port'. Return NULL if no such router is known.
|
||||
*/
|
||||
routerinfo_t *router_get_by_addr_port(uint32_t addr, uint16_t port) {
|
||||
@@ -327,7 +328,7 @@ routerinfo_t *router_get_by_addr_port(uint32_t addr, uint16_t port) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Return the router in our routerlist whose nickname is 'nickname'
|
||||
/** Return the router in our routerlist whose nickname is 'nickname'
|
||||
* (case insensitive). Return NULL if no such router is known.
|
||||
*/
|
||||
routerinfo_t *router_get_by_nickname(char *nickname)
|
||||
@@ -346,12 +347,12 @@ routerinfo_t *router_get_by_nickname(char *nickname)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Set *prouterlist to the current list of all known routers. */
|
||||
/** Set *prouterlist to the current list of all known routers. */
|
||||
void router_get_routerlist(routerlist_t **prouterlist) {
|
||||
*prouterlist = routerlist;
|
||||
}
|
||||
|
||||
/* Free all storage held by 'router'. */
|
||||
/** Free all storage held by 'router'. */
|
||||
void routerinfo_free(routerinfo_t *router)
|
||||
{
|
||||
struct exit_policy_t *e;
|
||||
@@ -375,7 +376,7 @@ void routerinfo_free(routerinfo_t *router)
|
||||
free(router);
|
||||
}
|
||||
|
||||
/* Allocate a fresh copy of 'router' */
|
||||
/** Allocate a fresh copy of 'router' */
|
||||
routerinfo_t *routerinfo_copy(const routerinfo_t *router)
|
||||
{
|
||||
routerinfo_t *r;
|
||||
@@ -402,7 +403,7 @@ routerinfo_t *routerinfo_copy(const routerinfo_t *router)
|
||||
return r;
|
||||
}
|
||||
|
||||
/* Free all storage held by a routerlist 'rl' */
|
||||
/** Free all storage held by a routerlist 'rl' */
|
||||
static void routerlist_free(routerlist_t *rl)
|
||||
{
|
||||
SMARTLIST_FOREACH(rl->routers, routerinfo_t *, r,
|
||||
@@ -412,7 +413,7 @@ static void routerlist_free(routerlist_t *rl)
|
||||
tor_free(rl);
|
||||
}
|
||||
|
||||
/* Mark the router named 'nickname' as non-running in our routerlist. */
|
||||
/** Mark the router named 'nickname' as non-running in our routerlist. */
|
||||
void router_mark_as_down(char *nickname) {
|
||||
routerinfo_t *router = router_get_by_nickname(nickname);
|
||||
if(!router) /* we don't seem to know about him in the first place */
|
||||
@@ -425,7 +426,7 @@ void router_mark_as_down(char *nickname) {
|
||||
* Code to parse router descriptors and directories.
|
||||
*****/
|
||||
|
||||
/* Replace the current router list with the one stored in 'routerfile'. */
|
||||
/** Replace the current router list with the one stored in 'routerfile'. */
|
||||
int router_set_routerlist_from_file(char *routerfile)
|
||||
{
|
||||
char *string;
|
||||
@@ -447,7 +448,7 @@ int router_set_routerlist_from_file(char *routerfile)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Helper function: read routerinfo elements from s, and throw out the
|
||||
/** Helper function: read routerinfo elements from s, and throw out the
|
||||
* ones that don't parse and resolve. Replace the current
|
||||
* routerlist. */
|
||||
int router_set_routerlist_from_string(const char *s)
|
||||
@@ -465,7 +466,7 @@ int router_set_routerlist_from_string(const char *s)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Set 'digest' to the SHA-1 digest of the hash of the directory in 's'.
|
||||
/** Set 'digest' to the SHA-1 digest of the hash of the directory in 's'.
|
||||
* Return 0 on success, nonzero on failure.
|
||||
*/
|
||||
int router_get_dir_hash(const char *s, char *digest)
|
||||
@@ -473,7 +474,8 @@ int router_get_dir_hash(const char *s, char *digest)
|
||||
return router_get_hash_impl(s,digest,
|
||||
"signed-directory","directory-signature");
|
||||
}
|
||||
/* Set 'digest' to the SHA-1 digest of the hash of the first router in 's'.
|
||||
|
||||
/** Set 'digest' to the SHA-1 digest of the hash of the first router in 's'.
|
||||
* Return 0 on success, nonzero on failure.
|
||||
*/
|
||||
int router_get_router_hash(const char *s, char *digest)
|
||||
@@ -482,7 +484,7 @@ int router_get_router_hash(const char *s, char *digest)
|
||||
"router ","router-signature");
|
||||
}
|
||||
|
||||
/* Return 1 if myversion is in versionlist. Else return 0.
|
||||
/** Return 1 if myversion is in versionlist. Else return 0.
|
||||
* (versionlist is a comma-separated list of versions.) */
|
||||
int is_recommended_version(const char *myversion,
|
||||
const char *versionlist) {
|
||||
@@ -504,7 +506,7 @@ int is_recommended_version(const char *myversion,
|
||||
}
|
||||
}
|
||||
|
||||
/* Replace the current routerlist with the routers stored in the
|
||||
/** Replace the current routerlist with the routers stored in the
|
||||
* signed directory 's'. If pkey is provided, make sure that 's' is
|
||||
* signed with pkey. */
|
||||
int router_set_routerlist_from_directory(const char *s, crypto_pk_env_t *pkey)
|
||||
@@ -533,7 +535,7 @@ int router_set_routerlist_from_directory(const char *s, crypto_pk_env_t *pkey)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Helper function: resolve the hostname for 'router'. */
|
||||
/** Helper function: resolve the hostname for 'router'. */
|
||||
static int
|
||||
router_resolve(routerinfo_t *router)
|
||||
{
|
||||
@@ -547,7 +549,7 @@ router_resolve(routerinfo_t *router)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Helper function: resolve every router in rl, and ensure that our own
|
||||
/** Helper function: resolve every router in rl, and ensure that our own
|
||||
* routerinfo is at the front.
|
||||
*/
|
||||
static int
|
||||
@@ -582,7 +584,7 @@ router_resolve_routerlist(routerlist_t *rl)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Decide whether a given addr:port is definitely accepted, definitely
|
||||
/** Decide whether a given addr:port is definitely accepted, definitely
|
||||
* rejected, or neither by a given exit policy. If 'addr' is 0, we
|
||||
* don't know the IP of the target address.
|
||||
*
|
||||
@@ -649,7 +651,7 @@ int router_compare_addr_to_exit_policy(uint32_t addr, uint16_t port,
|
||||
return maybe_reject ? ADDR_POLICY_UNKNOWN : ADDR_POLICY_ACCEPTED;
|
||||
}
|
||||
|
||||
/* Return 1 if all running routers will reject addr:port, return 0 if
|
||||
/** Return 1 if all running routers will reject addr:port, return 0 if
|
||||
* any might accept it. */
|
||||
int router_exit_policy_all_routers_reject(uint32_t addr, uint16_t port) {
|
||||
int i;
|
||||
@@ -664,14 +666,14 @@ int router_exit_policy_all_routers_reject(uint32_t addr, uint16_t port) {
|
||||
return 1; /* all will reject. */
|
||||
}
|
||||
|
||||
/* Return true iff 'router' does not permit exit streams.
|
||||
/** Return true iff 'router' does not permit exit streams.
|
||||
*/
|
||||
int router_exit_policy_rejects_all(routerinfo_t *router) {
|
||||
return router_compare_addr_to_exit_policy(0, 0, router->exit_policy)
|
||||
== ADDR_POLICY_REJECTED;
|
||||
}
|
||||
|
||||
/* Parse a date of the format 'YYYY-MM-DD hh:mm:ss" and store the result into
|
||||
/** Parse a date of the format 'YYYY-MM-DD hh:mm:ss" and store the result into
|
||||
* *t.
|
||||
*/
|
||||
/* XXX this should go in util.c, yes? -RD */
|
||||
@@ -704,7 +706,7 @@ static int parse_time(const char *cp, time_t *t)
|
||||
}
|
||||
|
||||
|
||||
/* Helper function: parse a directory from 's' and, when done, store the
|
||||
/** Helper function: parse a directory from 's' and, when done, store the
|
||||
* resulting routerlist in *dest, freeing the old value if necessary.
|
||||
* If pkey is provided, we check the directory signature with pkey.
|
||||
*/
|
||||
@@ -854,7 +856,7 @@ router_get_routerlist_from_directory_impl(const char *str,
|
||||
return r;
|
||||
}
|
||||
|
||||
/* Helper function: Given a string *s containing a concatenated
|
||||
/** Helper function: Given a string *s containing a concatenated
|
||||
* sequence of router descriptors, parses them and stores the result
|
||||
* in *dest. If good_nickname_lst is provided, then routers whose
|
||||
* nicknames are not listed are marked as nonrunning. Advances *s to
|
||||
@@ -921,7 +923,7 @@ router_get_list_from_string_impl(const char **s, routerlist_t **dest,
|
||||
}
|
||||
|
||||
|
||||
/* Helper function: reads a single router entry from *s ... *end.
|
||||
/** Helper function: reads a single router entry from *s ... *end.
|
||||
* Mallocs a new router and returns it if all goes well, else returns
|
||||
* NULL.
|
||||
*/
|
||||
@@ -1118,7 +1120,7 @@ routerinfo_t *router_get_entry_from_string(const char *s,
|
||||
return router;
|
||||
}
|
||||
|
||||
/* Parse the exit policy in the string 's' and add it to 'router'.
|
||||
/** Parse the exit policy in the string 's' and add it to 'router'.
|
||||
*/
|
||||
int
|
||||
router_add_exit_policy_from_string(routerinfo_t *router, const char *s)
|
||||
@@ -1158,7 +1160,7 @@ router_add_exit_policy_from_string(routerinfo_t *router, const char *s)
|
||||
return r;
|
||||
}
|
||||
|
||||
/* Given a K_ACCEPT or K_REJECT token and a router, create a new exit_policy_t
|
||||
/** Given a K_ACCEPT or K_REJECT token and a router, create a new exit_policy_t
|
||||
* corresponding to the token, and add it to 'router' */
|
||||
static int
|
||||
router_add_exit_policy(routerinfo_t *router, directory_token_t *tok) {
|
||||
@@ -1281,7 +1283,7 @@ policy_read_failed:
|
||||
*****/
|
||||
|
||||
|
||||
/* Free all resources allocated for 'tok' */
|
||||
/** Free all resources allocated for 'tok' */
|
||||
static void
|
||||
token_free(directory_token_t *tok)
|
||||
{
|
||||
@@ -1300,7 +1302,7 @@ token_free(directory_token_t *tok)
|
||||
tor_free(tok);
|
||||
}
|
||||
|
||||
/* Helper function: read the next token from *s, advance *s to the end
|
||||
/** Helper function: read the next token from *s, advance *s to the end
|
||||
* of the token, and return the parsed token. If 'where' is DIR_ONLY
|
||||
* or RTR_ONLY, reject all tokens of the wrong type.
|
||||
*/
|
||||
@@ -1485,7 +1487,7 @@ get_next_token(const char **s, where_syntax where) {
|
||||
#undef RET_ERR
|
||||
}
|
||||
|
||||
/* Read all tokens from a string between 'start' and 'end', and add
|
||||
/** Read all tokens from a string between 'start' and 'end', and add
|
||||
* them to 'out'. If 'is_dir' is true, reject all non-directory
|
||||
* tokens; else reject all non-routerdescriptor tokens.
|
||||
*/
|
||||
@@ -1510,7 +1512,7 @@ tokenize_string(const char *start, const char *end, smartlist_t *out,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Find the first token in 's' whose keyword is 'keyword'; return NULL if no
|
||||
/** Find the first token in 's' whose keyword is 'keyword'; return NULL if no
|
||||
* such keyword is found.
|
||||
*/
|
||||
static directory_token_t *
|
||||
@@ -1520,7 +1522,7 @@ find_first_by_keyword(smartlist_t *s, directory_keyword keyword)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Return a newly allocated smartlist of all accept or reject tokens in 's'.
|
||||
/** Return a newly allocated smartlist of all accept or reject tokens in 's'.
|
||||
*/
|
||||
static smartlist_t *
|
||||
find_all_exitpolicy(smartlist_t *s)
|
||||
@@ -1533,7 +1535,7 @@ find_all_exitpolicy(smartlist_t *s)
|
||||
}
|
||||
|
||||
|
||||
/* Compute the SHA digest of the substring of s taken from the first
|
||||
/** Compute the SHA digest of the substring of s taken from the first
|
||||
* occurrence of start_str through the first newline after the first
|
||||
* subsequent occurrence of end_str; store the 20-byte result in 'digest';
|
||||
* return 0 on success.
|
||||
|
||||
Reference in New Issue
Block a user