Loading src/or/buffers.c +6 −4 Changes for src/or/buffers.c: 6 added lines, 4 removed lines. Original line number Diff line number Diff line Loading @@ -219,8 +219,9 @@ int read_to_buf_tls(tor_tls *tls, size_t at_most, buf_t *buf) { tor_assert(tls); assert_buf_ok(buf); log_fn(LOG_DEBUG,"start: %d on buf, %d pending, at_most %d.",(int)buf_datalen(buf), tor_tls_get_pending_bytes(tls), at_most); log_fn(LOG_DEBUG,"start: %d on buf, %d pending, at_most %d.", (int)buf_datalen(buf), (int)tor_tls_get_pending_bytes(tls), (int)at_most); if (buf_ensure_capacity(buf, at_most+buf->datalen)) return TOR_TLS_ERROR; Loading @@ -231,8 +232,9 @@ int read_to_buf_tls(tor_tls *tls, size_t at_most, buf_t *buf) { if (at_most == 0) return 0; log_fn(LOG_DEBUG,"before: %d on buf, %d pending, at_most %d.",(int)buf_datalen(buf), tor_tls_get_pending_bytes(tls), at_most); log_fn(LOG_DEBUG,"before: %d on buf, %d pending, at_most %d.", (int)buf_datalen(buf), (int)tor_tls_get_pending_bytes(tls), (int)at_most); assert_no_tls_errors(); r = tor_tls_read(tls, buf->mem+buf->datalen, at_most); Loading src/or/cpuworker.c +50 −4 Changes for src/or/cpuworker.c: 50 added lines, 4 removed lines. Original line number Diff line number Diff line Loading @@ -2,6 +2,13 @@ /* See LICENSE for licensing information */ /* $Id$ */ /***** * cpuworker.c: 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 */ Loading @@ -14,6 +21,9 @@ extern or_options_t options; /* command-line and config-file options */ static int num_cpuworkers=0; static int num_cpuworkers_busy=0; /* 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; int cpuworker_main(void *data); Loading @@ -21,34 +31,45 @@ static int spawn_cpuworker(void); static void spawn_enough_cpuworkers(void); static void process_pending_task(connection_t *cpuworker); /* 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. */ 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 * 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; *(uint16_t *)(tag+4) = port; *(uint16_t *)(tag+6) = circ_id; } static void tag_unpack(char *tag, uint32_t *addr, uint16_t *port, uint16_t *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; *addr = *(uint32_t *)tag; *port = *(uint16_t *)(tag+4); *circ_id = *(uint16_t *)(tag+6); *addr = *(const uint32_t *)tag; *port = *(const uint16_t *)(tag+4); *circ_id = *(const uint16_t *)(tag+6); in.s_addr = htonl(*addr); 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 * cpuworkers. Close all currently idle cpuworkers, and mark the last * rotation time as now. */ void cpuworkers_rotate(void) { connection_t *cpuworker; Loading @@ -61,6 +82,11 @@ void cpuworkers_rotate(void) spawn_enough_cpuworkers(); } /* 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. */ int connection_cpu_process_inbuf(connection_t *conn) { char success; unsigned char buf[LEN_ONION_RESPONSE]; Loading Loading @@ -136,6 +162,20 @@ done_processing: return 0; } /* Implement a cpuworker. 'data' is an fdarray as returned by socketpair. * Read and writes from fdarray[1]. Reads requests, writes answers. * * Request format: * Task type [1 byte, always ONIONSKIN_CHALLENGE_LEN] * Opaque tag TAG_LEN * Onionskin challenge ONIONSKIN_CHALLENGE_LEN * Response format: * Success/failure [1 byte, boolean.] * Opaque tag TAG_LEN * Onionskin challenge ONIONSKIN_REPLY_LEN * Negotiated keys KEY_LEN*2+DIGEST_LEN*2 */ int cpuworker_main(void *data) { unsigned char question[ONIONSKIN_CHALLENGE_LEN]; unsigned char question_type; Loading Loading @@ -209,6 +249,8 @@ int cpuworker_main(void *data) { return 0; /* windows wants this function to return an int */ } /* Launch a new cpuworker. */ static int spawn_cpuworker(void) { int fd[2]; connection_t *conn; Loading Loading @@ -243,6 +285,9 @@ static int spawn_cpuworker(void) { return 0; /* success */ } /* 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) { int num_cpuworkers_needed = options.NumCpus; Loading @@ -260,6 +305,7 @@ static void spawn_enough_cpuworkers(void) { } } /* Take a pending task from the queue and assign it to 'cpuworker' */ static void process_pending_task(connection_t *cpuworker) { circuit_t *circ; Loading src/or/dns.c +76 −3 Changes for src/or/dns.c: 76 added lines, 3 removed lines. Original line number Diff line number Diff line Loading @@ -2,6 +2,10 @@ /* See LICENSE for licensing information */ /* $Id$ */ /***** * dns.c: 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 * them becomes more commonly available. Loading @@ -12,12 +16,19 @@ extern or_options_t options; /* command-line and config-file options */ /* Longest hostname we're willing to resolve. */ #define MAX_ADDRESSLEN 256 /* Maximum DNS processes to spawn. */ #define MAX_DNSWORKERS 50 /* Minimum DNS processes to spawn. */ #define MIN_DNSWORKERS 3 /* If more than this many processes are idle, shut down the extras. */ #define MAX_IDLE_DNSWORKERS 10 /* 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 Loading @@ -25,11 +36,16 @@ extern or_options_t options; /* command-line and config-file options */ int num_dnsworkers=0; int num_dnsworkers_busy=0; /* 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 * 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 */ Loading @@ -38,7 +54,7 @@ struct cached_resolve { #define CACHE_STATE_PENDING 0 #define CACHE_STATE_VALID 1 #define CACHE_STATE_FAILED 2 uint32_t expire; /* remove untouched items from cache after some time? */ uint32_t expire; /* remove items from cache after this time */ struct pending_connection_t *pending_connections; struct cached_resolve *next; }; Loading @@ -51,8 +67,11 @@ int dnsworker_main(void *data); static int spawn_dnsworker(void); static void spawn_enough_dnsworkers(void); /* 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 * implement splay trees. */ static int compare_cached_resolves(struct cached_resolve *a, struct cached_resolve *b) { /* make this smarter one day? */ Loading @@ -62,10 +81,12 @@ 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 */ static void init_cache_tree(void) { SPLAY_INIT(&cache_root); } /* Initialize the DNS subsystem; called by the OR process. */ void dns_init(void) { init_cache_tree(); spawn_enough_dnsworkers(); Loading @@ -74,6 +95,8 @@ void dns_init(void) { static struct cached_resolve *oldest_cached_resolve = NULL; /* linked list, */ static struct cached_resolve *newest_cached_resolve = NULL; /* oldest to newest */ /* 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; Loading Loading @@ -178,6 +201,9 @@ int dns_resolve(connection_t *exitconn) { return assign_to_dnsworker(exitconn); } /* 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) { connection_t *dnsconn; unsigned char len; Loading Loading @@ -210,6 +236,8 @@ static int assign_to_dnsworker(connection_t *exitconn) { return 0; } /* Remove 'conn' from the list of connections waiting for conn->address. */ void connection_dns_remove(connection_t *conn) { struct pending_connection_t *pend, *victim; Loading Loading @@ -251,6 +279,8 @@ void connection_dns_remove(connection_t *conn) } } /* 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; struct cached_resolve *resolve; Loading @@ -264,6 +294,8 @@ void assert_connection_edge_not_dns_pending(connection_t *conn) { } } /* 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; struct cached_resolve *resolve; Loading @@ -277,8 +309,9 @@ void assert_all_pending_dns_resolves_ok(void) { } } /* Cancel all pending connections. Then cancel the resolve itself, * and remove the 'struct cached_resolve' from the cache. /* 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. */ void dns_cancel_pending_resolve(char *address) { struct pending_connection_t *pend; Loading Loading @@ -314,6 +347,8 @@ void dns_cancel_pending_resolve(char *address) { dns_purge_resolve(resolve); } /* Remove 'resolve' from the cache. */ static void dns_purge_resolve(struct cached_resolve *resolve) { struct cached_resolve *tmp; Loading @@ -338,6 +373,12 @@ 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 * 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 * one of DNS_RESOLVE_{FAILED_TRANSIENT|FAILED_PERMANENT|SUCCEEDED}. */ static void dns_found_answer(char *address, uint32_t addr, char outcome) { struct pending_connection_t *pend; struct cached_resolve search; Loading @@ -356,6 +397,8 @@ static void dns_found_answer(char *address, uint32_t addr, char outcome) { } if (resolve->state != CACHE_STATE_PENDING) { /* XXXX Maybe update addr? or check addr for consistency? Or let * VALID replace FAILED? */ log_fn(LOG_WARN, "Resolved '%s' which was already resolved; ignoring", address); tor_assert(resolve->pending_connections == NULL); Loading Loading @@ -401,12 +444,21 @@ 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. */ 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 * 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. */ int connection_dns_process_inbuf(connection_t *conn) { char success; uint32_t addr; Loading Loading @@ -447,6 +499,23 @@ int connection_dns_process_inbuf(connection_t *conn) { return 0; } /* 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: * The OR says: * ADDRESSLEN [1 byte] * ADDRESS [ADDRESSLEN bytes] * The DNS worker does the lookup, and replies: * OUTCOME [1 byte] * IP [4 bytes] * * OUTCOME is one of DNS_RESOLVE_{FAILED_TRANSIENT|FAILED_PERMANENT|SUCCEEDED}. * IP is in host order. * * The dnsworker runs indefinitely, until its connection is closed or an error * occurs. */ int dnsworker_main(void *data) { char address[MAX_ADDRESSLEN]; unsigned char address_len; Loading Loading @@ -498,6 +567,8 @@ 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. */ static int spawn_dnsworker(void) { int fd[2]; connection_t *conn; Loading Loading @@ -532,6 +603,8 @@ static int spawn_dnsworker(void) { return 0; /* success */ } /* 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, * but no less than min and no more than max */ Loading src/or/main.c +73 −7 Changes for src/or/main.c: 73 added lines, 7 removed lines. Original line number Diff line number Diff line Loading @@ -2,6 +2,10 @@ /* See LICENSE for licensing information */ /* $Id$ */ /***** * main.c: Tor main loop and startup functions. *****/ #include "or.h" /********* PROTOTYPES **********/ Loading @@ -11,18 +15,26 @@ static int init_from_config(int argc, char **argv); /********* START VARIABLES **********/ /* 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 */ /* 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? */ static uint64_t stats_n_bytes_read = 0; /* 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 * 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(). */ static struct pollfd poll_array[MAXCONNECTIONS]; static int nfds=0; /* number of connections currently active */ Loading @@ -33,14 +45,14 @@ 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 */ int has_fetched_directory=0; /* 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; int has_completed_circuit=0; /* 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; /********* END VARIABLES ************/ Loading @@ -52,6 +64,10 @@ int has_completed_circuit=0; * ****************************************************************************/ /* Add 'conn' 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. */ int connection_add(connection_t *conn) { tor_assert(conn); tor_assert(conn->s >= 0); Loading Loading @@ -112,11 +128,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. */ 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().) */ void connection_watch_events(connection_t *conn, short events) { tor_assert(conn && conn->poll_index < nfds); Loading @@ -124,10 +146,12 @@ 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. */ int connection_is_reading(connection_t *conn) { return poll_array[conn->poll_index].events & POLLIN; } /* Tell the main loop to stop notifying 'conn' of any read events. */ void connection_stop_reading(connection_t *conn) { tor_assert(conn && conn->poll_index < nfds); Loading @@ -137,6 +161,7 @@ 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. */ void connection_start_reading(connection_t *conn) { tor_assert(conn && conn->poll_index < nfds); Loading @@ -144,10 +169,12 @@ void connection_start_reading(connection_t *conn) { poll_array[conn->poll_index].events |= POLLIN; } /* Return true iff the 'conn' 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. */ void connection_stop_writing(connection_t *conn) { tor_assert(conn && conn->poll_index < nfds); Loading @@ -156,6 +183,7 @@ void connection_stop_writing(connection_t *conn) { poll_array[conn->poll_index].events -= POLLOUT; } /* Tell the main loop to start notifying 'conn' of any write events. */ void connection_start_writing(connection_t *conn) { tor_assert(conn && conn->poll_index < nfds); Loading @@ -163,6 +191,10 @@ void connection_start_writing(connection_t *conn) { poll_array[conn->poll_index].events |= POLLOUT; } /* Called when the connection at connection_array[i] has a read event: * checks for validity, catches numerous errors, and dispatches to * connection_handle_read. */ static void conn_read(int i) { connection_t *conn = connection_array[i]; Loading Loading @@ -200,6 +232,10 @@ static void conn_read(int i) { assert_all_pending_dns_resolves_ok(); } /* Called when the connection at connection_array[i] has a write event: * checks for validity, catches numerous errors, and dispatches to * connection_handle_write. */ static void conn_write(int i) { connection_t *conn; Loading Loading @@ -227,6 +263,15 @@ 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 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. * - Otherwise, remove the connection from connection_array and from * all other lists, close it, and free it. * If we remove the connection, then call conn_closed_if_marked at the new * connection at position i. */ static void conn_close_if_marked(int i) { connection_t *conn; int retval; Loading Loading @@ -280,8 +325,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."); Loading @@ -304,11 +348,13 @@ static void run_connection_housekeeping(int i, time_t now) { cell_t cell; connection_t *conn = connection_array[i]; /* Expire any directory connections that haven't sent anything for 5 min */ if(conn->type == CONN_TYPE_DIR && !conn->marked_for_close && conn->timestamp_lastwritten + 5*60 < now) { log_fn(LOG_WARN,"Expiring wedged directory conn (purpose %d)", conn->purpose); connection_mark_for_close(conn,0); /* XXXX Does this next part make sense, really? */ conn->hold_open_until_flushed = 1; /* give it a last chance */ return; } Loading @@ -317,6 +363,8 @@ static void run_connection_housekeeping(int i, time_t now) { if(!connection_speaks_cells(conn)) return; /* If we haven't written to an OR connection for a while, then either nuke the connection or send a keepalive, depending. */ if(now >= conn->timestamp_lastwritten + options.KeepalivePeriod) { if((!options.ORPort && !circuit_get_by_conn(conn)) || (!connection_state_is_open(conn))) { Loading Loading @@ -450,6 +498,10 @@ 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, * and adjusts token buckets. Returns the number of milliseconds to use for * the poll() timeout. */ static int prepare_for_poll(void) { static long current_second = 0; /* from previous calls to gettimeofday */ connection_t *conn; Loading @@ -458,8 +510,8 @@ static int prepare_for_poll(void) { tor_gettimeofday(&now); /* Check how much bandwidth we've consumed, * and increment the token buckets. */ /* Check how much bandwidth we've consumed, and increment the token * buckets. */ stats_n_bytes_read += stats_prev_global_read_bucket-global_read_bucket; connection_bucket_refill(&now); stats_prev_global_read_bucket = global_read_bucket; Loading @@ -486,23 +538,30 @@ 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 * configuration file. */ static int init_from_config(int argc, char **argv) { /* read the configuration file. */ if(getconfig(argc,argv,&options)) { log_fn(LOG_ERR,"Reading config failed. For usage, try -h."); return -1; } close_logs(); /* we'll close, then open with correct loglevel if necessary */ /* Setuid/setgid as appropriate */ if(options.User || options.Group) { if(switch_id(options.User, options.Group) != 0) { return -1; } } /* Start backgrounding the process, if requested. */ if (options.RunAsDaemon) { start_daemon(options.DataDirectory); } /* Configure the log(s) */ if(!options.LogFile && !options.RunAsDaemon) add_stream_log(options.loglevel, "<stdout>", stdout); if(options.LogFile) { Loading @@ -520,21 +579,26 @@ static int init_from_config(int argc, char **argv) { log_fn(LOG_DEBUG, "Successfully opened DebugLogFile '%s'.", options.DebugLogFile); } /* Set up our buckets */ connection_bucket_init(); stats_prev_global_read_bucket = global_read_bucket; /* Finish backgrounding the process */ if(options.RunAsDaemon) { /* XXXX Can we delay this any more? */ finish_daemon(); } /* write our pid to the pid file, if we do not have write permissions we will log a warning */ /* Write our pid to the pid file. if we do not have write permissions we * will log a warning */ if(options.PidFile) write_pidfile(options.PidFile); return 0; } /* 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]; Loading Loading @@ -580,6 +644,7 @@ static int do_hup(void) { return 0; } /* Tor main loop. */ static int do_main_loop(void) { int i; int timeout; Loading Loading @@ -675,6 +740,7 @@ static int do_main_loop(void) { } } /* Unix signal handler. */ static void catch(int the_signal) { #ifndef MS_WINDOWS /* do signal stuff only on unix */ Loading src/or/or.h +6 −6 Changes for src/or/or.h: 6 added lines, 6 removed lines. Original line number Diff line number Diff line Loading @@ -1046,8 +1046,8 @@ void rep_hist_dump_stats(time_t now, int severity); void rend_client_introcirc_is_open(circuit_t *circ); void rend_client_rendcirc_is_open(circuit_t *circ); int rend_client_introduction_acked(circuit_t *circ, const char *request, int request_len); void rend_client_refetch_renddesc(char *query); int rend_client_remove_intro_point(char *failed_intro, char *query); void rend_client_refetch_renddesc(const char *query); int rend_client_remove_intro_point(char *failed_intro, const char *query); int rend_client_rendezvous_acked(circuit_t *circ, const char *request, int request_len); int rend_client_receive_rendezvous(circuit_t *circ, const char *request, int request_len); void rend_client_desc_fetched(char *query, int success); Loading Loading @@ -1088,10 +1088,10 @@ typedef struct rend_cache_entry_t { void rend_cache_init(void); void rend_cache_clean(void); int rend_valid_service_id(char *query); int rend_cache_lookup_desc(char *query, const char **desc, int *desc_len); int rend_cache_lookup_entry(char *query, rend_cache_entry_t **entry_out); int rend_cache_store(char *desc, int desc_len); int rend_valid_service_id(const char *query); int rend_cache_lookup_desc(const char *query, const char **desc, int *desc_len); int rend_cache_lookup_entry(const char *query, rend_cache_entry_t **entry_out); int rend_cache_store(const char *desc, int desc_len); /********************************* rendservice.c ***************************/ Loading Loading
src/or/buffers.c +6 −4 Changes for src/or/buffers.c: 6 added lines, 4 removed lines. Original line number Diff line number Diff line Loading @@ -219,8 +219,9 @@ int read_to_buf_tls(tor_tls *tls, size_t at_most, buf_t *buf) { tor_assert(tls); assert_buf_ok(buf); log_fn(LOG_DEBUG,"start: %d on buf, %d pending, at_most %d.",(int)buf_datalen(buf), tor_tls_get_pending_bytes(tls), at_most); log_fn(LOG_DEBUG,"start: %d on buf, %d pending, at_most %d.", (int)buf_datalen(buf), (int)tor_tls_get_pending_bytes(tls), (int)at_most); if (buf_ensure_capacity(buf, at_most+buf->datalen)) return TOR_TLS_ERROR; Loading @@ -231,8 +232,9 @@ int read_to_buf_tls(tor_tls *tls, size_t at_most, buf_t *buf) { if (at_most == 0) return 0; log_fn(LOG_DEBUG,"before: %d on buf, %d pending, at_most %d.",(int)buf_datalen(buf), tor_tls_get_pending_bytes(tls), at_most); log_fn(LOG_DEBUG,"before: %d on buf, %d pending, at_most %d.", (int)buf_datalen(buf), (int)tor_tls_get_pending_bytes(tls), (int)at_most); assert_no_tls_errors(); r = tor_tls_read(tls, buf->mem+buf->datalen, at_most); Loading
src/or/cpuworker.c +50 −4 Changes for src/or/cpuworker.c: 50 added lines, 4 removed lines. Original line number Diff line number Diff line Loading @@ -2,6 +2,13 @@ /* See LICENSE for licensing information */ /* $Id$ */ /***** * cpuworker.c: 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 */ Loading @@ -14,6 +21,9 @@ extern or_options_t options; /* command-line and config-file options */ static int num_cpuworkers=0; static int num_cpuworkers_busy=0; /* 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; int cpuworker_main(void *data); Loading @@ -21,34 +31,45 @@ static int spawn_cpuworker(void); static void spawn_enough_cpuworkers(void); static void process_pending_task(connection_t *cpuworker); /* 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. */ 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 * 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; *(uint16_t *)(tag+4) = port; *(uint16_t *)(tag+6) = circ_id; } static void tag_unpack(char *tag, uint32_t *addr, uint16_t *port, uint16_t *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; *addr = *(uint32_t *)tag; *port = *(uint16_t *)(tag+4); *circ_id = *(uint16_t *)(tag+6); *addr = *(const uint32_t *)tag; *port = *(const uint16_t *)(tag+4); *circ_id = *(const uint16_t *)(tag+6); in.s_addr = htonl(*addr); 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 * cpuworkers. Close all currently idle cpuworkers, and mark the last * rotation time as now. */ void cpuworkers_rotate(void) { connection_t *cpuworker; Loading @@ -61,6 +82,11 @@ void cpuworkers_rotate(void) spawn_enough_cpuworkers(); } /* 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. */ int connection_cpu_process_inbuf(connection_t *conn) { char success; unsigned char buf[LEN_ONION_RESPONSE]; Loading Loading @@ -136,6 +162,20 @@ done_processing: return 0; } /* Implement a cpuworker. 'data' is an fdarray as returned by socketpair. * Read and writes from fdarray[1]. Reads requests, writes answers. * * Request format: * Task type [1 byte, always ONIONSKIN_CHALLENGE_LEN] * Opaque tag TAG_LEN * Onionskin challenge ONIONSKIN_CHALLENGE_LEN * Response format: * Success/failure [1 byte, boolean.] * Opaque tag TAG_LEN * Onionskin challenge ONIONSKIN_REPLY_LEN * Negotiated keys KEY_LEN*2+DIGEST_LEN*2 */ int cpuworker_main(void *data) { unsigned char question[ONIONSKIN_CHALLENGE_LEN]; unsigned char question_type; Loading Loading @@ -209,6 +249,8 @@ int cpuworker_main(void *data) { return 0; /* windows wants this function to return an int */ } /* Launch a new cpuworker. */ static int spawn_cpuworker(void) { int fd[2]; connection_t *conn; Loading Loading @@ -243,6 +285,9 @@ static int spawn_cpuworker(void) { return 0; /* success */ } /* 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) { int num_cpuworkers_needed = options.NumCpus; Loading @@ -260,6 +305,7 @@ static void spawn_enough_cpuworkers(void) { } } /* Take a pending task from the queue and assign it to 'cpuworker' */ static void process_pending_task(connection_t *cpuworker) { circuit_t *circ; Loading
src/or/dns.c +76 −3 Changes for src/or/dns.c: 76 added lines, 3 removed lines. Original line number Diff line number Diff line Loading @@ -2,6 +2,10 @@ /* See LICENSE for licensing information */ /* $Id$ */ /***** * dns.c: 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 * them becomes more commonly available. Loading @@ -12,12 +16,19 @@ extern or_options_t options; /* command-line and config-file options */ /* Longest hostname we're willing to resolve. */ #define MAX_ADDRESSLEN 256 /* Maximum DNS processes to spawn. */ #define MAX_DNSWORKERS 50 /* Minimum DNS processes to spawn. */ #define MIN_DNSWORKERS 3 /* If more than this many processes are idle, shut down the extras. */ #define MAX_IDLE_DNSWORKERS 10 /* 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 Loading @@ -25,11 +36,16 @@ extern or_options_t options; /* command-line and config-file options */ int num_dnsworkers=0; int num_dnsworkers_busy=0; /* 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 * 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 */ Loading @@ -38,7 +54,7 @@ struct cached_resolve { #define CACHE_STATE_PENDING 0 #define CACHE_STATE_VALID 1 #define CACHE_STATE_FAILED 2 uint32_t expire; /* remove untouched items from cache after some time? */ uint32_t expire; /* remove items from cache after this time */ struct pending_connection_t *pending_connections; struct cached_resolve *next; }; Loading @@ -51,8 +67,11 @@ int dnsworker_main(void *data); static int spawn_dnsworker(void); static void spawn_enough_dnsworkers(void); /* 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 * implement splay trees. */ static int compare_cached_resolves(struct cached_resolve *a, struct cached_resolve *b) { /* make this smarter one day? */ Loading @@ -62,10 +81,12 @@ 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 */ static void init_cache_tree(void) { SPLAY_INIT(&cache_root); } /* Initialize the DNS subsystem; called by the OR process. */ void dns_init(void) { init_cache_tree(); spawn_enough_dnsworkers(); Loading @@ -74,6 +95,8 @@ void dns_init(void) { static struct cached_resolve *oldest_cached_resolve = NULL; /* linked list, */ static struct cached_resolve *newest_cached_resolve = NULL; /* oldest to newest */ /* 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; Loading Loading @@ -178,6 +201,9 @@ int dns_resolve(connection_t *exitconn) { return assign_to_dnsworker(exitconn); } /* 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) { connection_t *dnsconn; unsigned char len; Loading Loading @@ -210,6 +236,8 @@ static int assign_to_dnsworker(connection_t *exitconn) { return 0; } /* Remove 'conn' from the list of connections waiting for conn->address. */ void connection_dns_remove(connection_t *conn) { struct pending_connection_t *pend, *victim; Loading Loading @@ -251,6 +279,8 @@ void connection_dns_remove(connection_t *conn) } } /* 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; struct cached_resolve *resolve; Loading @@ -264,6 +294,8 @@ void assert_connection_edge_not_dns_pending(connection_t *conn) { } } /* 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; struct cached_resolve *resolve; Loading @@ -277,8 +309,9 @@ void assert_all_pending_dns_resolves_ok(void) { } } /* Cancel all pending connections. Then cancel the resolve itself, * and remove the 'struct cached_resolve' from the cache. /* 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. */ void dns_cancel_pending_resolve(char *address) { struct pending_connection_t *pend; Loading Loading @@ -314,6 +347,8 @@ void dns_cancel_pending_resolve(char *address) { dns_purge_resolve(resolve); } /* Remove 'resolve' from the cache. */ static void dns_purge_resolve(struct cached_resolve *resolve) { struct cached_resolve *tmp; Loading @@ -338,6 +373,12 @@ 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 * 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 * one of DNS_RESOLVE_{FAILED_TRANSIENT|FAILED_PERMANENT|SUCCEEDED}. */ static void dns_found_answer(char *address, uint32_t addr, char outcome) { struct pending_connection_t *pend; struct cached_resolve search; Loading @@ -356,6 +397,8 @@ static void dns_found_answer(char *address, uint32_t addr, char outcome) { } if (resolve->state != CACHE_STATE_PENDING) { /* XXXX Maybe update addr? or check addr for consistency? Or let * VALID replace FAILED? */ log_fn(LOG_WARN, "Resolved '%s' which was already resolved; ignoring", address); tor_assert(resolve->pending_connections == NULL); Loading Loading @@ -401,12 +444,21 @@ 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. */ 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 * 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. */ int connection_dns_process_inbuf(connection_t *conn) { char success; uint32_t addr; Loading Loading @@ -447,6 +499,23 @@ int connection_dns_process_inbuf(connection_t *conn) { return 0; } /* 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: * The OR says: * ADDRESSLEN [1 byte] * ADDRESS [ADDRESSLEN bytes] * The DNS worker does the lookup, and replies: * OUTCOME [1 byte] * IP [4 bytes] * * OUTCOME is one of DNS_RESOLVE_{FAILED_TRANSIENT|FAILED_PERMANENT|SUCCEEDED}. * IP is in host order. * * The dnsworker runs indefinitely, until its connection is closed or an error * occurs. */ int dnsworker_main(void *data) { char address[MAX_ADDRESSLEN]; unsigned char address_len; Loading Loading @@ -498,6 +567,8 @@ 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. */ static int spawn_dnsworker(void) { int fd[2]; connection_t *conn; Loading Loading @@ -532,6 +603,8 @@ static int spawn_dnsworker(void) { return 0; /* success */ } /* 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, * but no less than min and no more than max */ Loading
src/or/main.c +73 −7 Changes for src/or/main.c: 73 added lines, 7 removed lines. Original line number Diff line number Diff line Loading @@ -2,6 +2,10 @@ /* See LICENSE for licensing information */ /* $Id$ */ /***** * main.c: Tor main loop and startup functions. *****/ #include "or.h" /********* PROTOTYPES **********/ Loading @@ -11,18 +15,26 @@ static int init_from_config(int argc, char **argv); /********* START VARIABLES **********/ /* 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 */ /* 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? */ static uint64_t stats_n_bytes_read = 0; /* 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 * 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(). */ static struct pollfd poll_array[MAXCONNECTIONS]; static int nfds=0; /* number of connections currently active */ Loading @@ -33,14 +45,14 @@ 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 */ int has_fetched_directory=0; /* 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; int has_completed_circuit=0; /* 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; /********* END VARIABLES ************/ Loading @@ -52,6 +64,10 @@ int has_completed_circuit=0; * ****************************************************************************/ /* Add 'conn' 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. */ int connection_add(connection_t *conn) { tor_assert(conn); tor_assert(conn->s >= 0); Loading Loading @@ -112,11 +128,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. */ 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().) */ void connection_watch_events(connection_t *conn, short events) { tor_assert(conn && conn->poll_index < nfds); Loading @@ -124,10 +146,12 @@ 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. */ int connection_is_reading(connection_t *conn) { return poll_array[conn->poll_index].events & POLLIN; } /* Tell the main loop to stop notifying 'conn' of any read events. */ void connection_stop_reading(connection_t *conn) { tor_assert(conn && conn->poll_index < nfds); Loading @@ -137,6 +161,7 @@ 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. */ void connection_start_reading(connection_t *conn) { tor_assert(conn && conn->poll_index < nfds); Loading @@ -144,10 +169,12 @@ void connection_start_reading(connection_t *conn) { poll_array[conn->poll_index].events |= POLLIN; } /* Return true iff the 'conn' 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. */ void connection_stop_writing(connection_t *conn) { tor_assert(conn && conn->poll_index < nfds); Loading @@ -156,6 +183,7 @@ void connection_stop_writing(connection_t *conn) { poll_array[conn->poll_index].events -= POLLOUT; } /* Tell the main loop to start notifying 'conn' of any write events. */ void connection_start_writing(connection_t *conn) { tor_assert(conn && conn->poll_index < nfds); Loading @@ -163,6 +191,10 @@ void connection_start_writing(connection_t *conn) { poll_array[conn->poll_index].events |= POLLOUT; } /* Called when the connection at connection_array[i] has a read event: * checks for validity, catches numerous errors, and dispatches to * connection_handle_read. */ static void conn_read(int i) { connection_t *conn = connection_array[i]; Loading Loading @@ -200,6 +232,10 @@ static void conn_read(int i) { assert_all_pending_dns_resolves_ok(); } /* Called when the connection at connection_array[i] has a write event: * checks for validity, catches numerous errors, and dispatches to * connection_handle_write. */ static void conn_write(int i) { connection_t *conn; Loading Loading @@ -227,6 +263,15 @@ 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 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. * - Otherwise, remove the connection from connection_array and from * all other lists, close it, and free it. * If we remove the connection, then call conn_closed_if_marked at the new * connection at position i. */ static void conn_close_if_marked(int i) { connection_t *conn; int retval; Loading Loading @@ -280,8 +325,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."); Loading @@ -304,11 +348,13 @@ static void run_connection_housekeeping(int i, time_t now) { cell_t cell; connection_t *conn = connection_array[i]; /* Expire any directory connections that haven't sent anything for 5 min */ if(conn->type == CONN_TYPE_DIR && !conn->marked_for_close && conn->timestamp_lastwritten + 5*60 < now) { log_fn(LOG_WARN,"Expiring wedged directory conn (purpose %d)", conn->purpose); connection_mark_for_close(conn,0); /* XXXX Does this next part make sense, really? */ conn->hold_open_until_flushed = 1; /* give it a last chance */ return; } Loading @@ -317,6 +363,8 @@ static void run_connection_housekeeping(int i, time_t now) { if(!connection_speaks_cells(conn)) return; /* If we haven't written to an OR connection for a while, then either nuke the connection or send a keepalive, depending. */ if(now >= conn->timestamp_lastwritten + options.KeepalivePeriod) { if((!options.ORPort && !circuit_get_by_conn(conn)) || (!connection_state_is_open(conn))) { Loading Loading @@ -450,6 +498,10 @@ 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, * and adjusts token buckets. Returns the number of milliseconds to use for * the poll() timeout. */ static int prepare_for_poll(void) { static long current_second = 0; /* from previous calls to gettimeofday */ connection_t *conn; Loading @@ -458,8 +510,8 @@ static int prepare_for_poll(void) { tor_gettimeofday(&now); /* Check how much bandwidth we've consumed, * and increment the token buckets. */ /* Check how much bandwidth we've consumed, and increment the token * buckets. */ stats_n_bytes_read += stats_prev_global_read_bucket-global_read_bucket; connection_bucket_refill(&now); stats_prev_global_read_bucket = global_read_bucket; Loading @@ -486,23 +538,30 @@ 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 * configuration file. */ static int init_from_config(int argc, char **argv) { /* read the configuration file. */ if(getconfig(argc,argv,&options)) { log_fn(LOG_ERR,"Reading config failed. For usage, try -h."); return -1; } close_logs(); /* we'll close, then open with correct loglevel if necessary */ /* Setuid/setgid as appropriate */ if(options.User || options.Group) { if(switch_id(options.User, options.Group) != 0) { return -1; } } /* Start backgrounding the process, if requested. */ if (options.RunAsDaemon) { start_daemon(options.DataDirectory); } /* Configure the log(s) */ if(!options.LogFile && !options.RunAsDaemon) add_stream_log(options.loglevel, "<stdout>", stdout); if(options.LogFile) { Loading @@ -520,21 +579,26 @@ static int init_from_config(int argc, char **argv) { log_fn(LOG_DEBUG, "Successfully opened DebugLogFile '%s'.", options.DebugLogFile); } /* Set up our buckets */ connection_bucket_init(); stats_prev_global_read_bucket = global_read_bucket; /* Finish backgrounding the process */ if(options.RunAsDaemon) { /* XXXX Can we delay this any more? */ finish_daemon(); } /* write our pid to the pid file, if we do not have write permissions we will log a warning */ /* Write our pid to the pid file. if we do not have write permissions we * will log a warning */ if(options.PidFile) write_pidfile(options.PidFile); return 0; } /* 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]; Loading Loading @@ -580,6 +644,7 @@ static int do_hup(void) { return 0; } /* Tor main loop. */ static int do_main_loop(void) { int i; int timeout; Loading Loading @@ -675,6 +740,7 @@ static int do_main_loop(void) { } } /* Unix signal handler. */ static void catch(int the_signal) { #ifndef MS_WINDOWS /* do signal stuff only on unix */ Loading
src/or/or.h +6 −6 Changes for src/or/or.h: 6 added lines, 6 removed lines. Original line number Diff line number Diff line Loading @@ -1046,8 +1046,8 @@ void rep_hist_dump_stats(time_t now, int severity); void rend_client_introcirc_is_open(circuit_t *circ); void rend_client_rendcirc_is_open(circuit_t *circ); int rend_client_introduction_acked(circuit_t *circ, const char *request, int request_len); void rend_client_refetch_renddesc(char *query); int rend_client_remove_intro_point(char *failed_intro, char *query); void rend_client_refetch_renddesc(const char *query); int rend_client_remove_intro_point(char *failed_intro, const char *query); int rend_client_rendezvous_acked(circuit_t *circ, const char *request, int request_len); int rend_client_receive_rendezvous(circuit_t *circ, const char *request, int request_len); void rend_client_desc_fetched(char *query, int success); Loading Loading @@ -1088,10 +1088,10 @@ typedef struct rend_cache_entry_t { void rend_cache_init(void); void rend_cache_clean(void); int rend_valid_service_id(char *query); int rend_cache_lookup_desc(char *query, const char **desc, int *desc_len); int rend_cache_lookup_entry(char *query, rend_cache_entry_t **entry_out); int rend_cache_store(char *desc, int desc_len); int rend_valid_service_id(const char *query); int rend_cache_lookup_desc(const char *query, const char **desc, int *desc_len); int rend_cache_lookup_entry(const char *query, rend_cache_entry_t **entry_out); int rend_cache_store(const char *desc, int desc_len); /********************************* rendservice.c ***************************/ Loading