[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

[or-cvs] Comments for nearly all non-tricky files



Update of /home/or/cvsroot/src/or
In directory moria.mit.edu:/tmp/cvs-serv15755/src/or

Modified Files:
	buffers.c cpuworker.c dns.c main.c or.h rendclient.c 
	rendcommon.c rendmid.c rendservice.c rephist.c tor_main.c 
Log Message:
Comments for nearly all non-tricky files

Index: buffers.c
===================================================================
RCS file: /home/or/cvsroot/src/or/buffers.c,v
retrieving revision 1.88
retrieving revision 1.89
diff -u -d -r1.88 -r1.89
--- buffers.c	2 May 2004 03:15:55 -0000	1.88
+++ buffers.c	5 May 2004 21:32:43 -0000	1.89
@@ -219,8 +219,9 @@
   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;
@@ -231,8 +232,9 @@
   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);

Index: cpuworker.c
===================================================================
RCS file: /home/or/cvsroot/src/or/cpuworker.c,v
retrieving revision 1.33
retrieving revision 1.34
diff -u -d -r1.33 -r1.34
--- cpuworker.c	2 May 2004 20:18:21 -0000	1.33
+++ cpuworker.c	5 May 2004 21:32:43 -0000	1.34
@@ -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 */
 
@@ -14,6 +21,9 @@
 
 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);
@@ -21,34 +31,45 @@
 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;
@@ -61,6 +82,11 @@
   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];
@@ -136,6 +162,20 @@
   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;
@@ -209,6 +249,8 @@
   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;
@@ -243,6 +285,9 @@
   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;
 
@@ -260,6 +305,7 @@
   }
 }
 
+/* Take a pending task from the queue and assign it to 'cpuworker' */
 static void process_pending_task(connection_t *cpuworker) {
   circuit_t *circ;
 

Index: dns.c
===================================================================
RCS file: /home/or/cvsroot/src/or/dns.c,v
retrieving revision 1.84
retrieving revision 1.85
diff -u -d -r1.84 -r1.85
--- dns.c	2 May 2004 20:18:21 -0000	1.84
+++ dns.c	5 May 2004 21:32:43 -0000	1.85
@@ -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.
@@ -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
@@ -25,11 +36,16 @@
 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 */
@@ -38,7 +54,7 @@
 #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;
 };
@@ -51,8 +67,11 @@
 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? */
@@ -62,10 +81,12 @@
 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();
@@ -74,6 +95,8 @@
 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;
 
@@ -178,6 +201,9 @@
   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;
@@ -210,6 +236,8 @@
   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;
@@ -251,6 +279,8 @@
   }
 }
 
+/* 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;
@@ -264,6 +294,8 @@
   }
 }
 
+/* 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;
@@ -277,8 +309,9 @@
   }
 }
 
-/* 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;
@@ -314,6 +347,8 @@
   dns_purge_resolve(resolve);
 }
 
+/* Remove 'resolve' from the cache.
+ */
 static void dns_purge_resolve(struct cached_resolve *resolve) {
   struct cached_resolve *tmp;
 
@@ -338,6 +373,12 @@
   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;
@@ -356,6 +397,8 @@
   }
 
   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);
@@ -401,12 +444,21 @@
 
 /******************************************************************/
 
+/*****
+ * 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;
@@ -447,6 +499,23 @@
   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;
@@ -498,6 +567,8 @@
   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;
@@ -532,6 +603,8 @@
   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 */

Index: main.c
===================================================================
RCS file: /home/or/cvsroot/src/or/main.c,v
retrieving revision 1.255
retrieving revision 1.256
diff -u -d -r1.255 -r1.256
--- main.c	5 May 2004 01:26:57 -0000	1.255
+++ main.c	5 May 2004 21:32:43 -0000	1.256
@@ -2,6 +2,10 @@
 /* See LICENSE for licensing information */
 /* $Id$ */
 
+/*****
+ * main.c: Tor main loop and startup functions.
+ *****/
+
 #include "or.h"
 
 /********* PROTOTYPES **********/
@@ -11,18 +15,26 @@
 
 /********* 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 */
@@ -33,14 +45,14 @@
 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 ************/
 
@@ -52,6 +64,10 @@
 *
 ****************************************************************************/
 
+/* 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);
@@ -112,11 +128,17 @@
   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);
@@ -124,10 +146,12 @@
   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);
@@ -137,6 +161,7 @@
     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);
@@ -144,10 +169,12 @@
   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);
@@ -156,6 +183,7 @@
     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);
@@ -163,6 +191,10 @@
   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];
 
@@ -200,6 +232,10 @@
   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;
 
@@ -227,6 +263,15 @@
   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;
@@ -280,8 +325,7 @@
   }
 }
 
-/* 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.");
@@ -304,11 +348,13 @@
   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;
   }
@@ -317,6 +363,8 @@
   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))) {
@@ -450,6 +498,10 @@
     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;
@@ -458,8 +510,8 @@
 
   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;
@@ -486,23 +538,30 @@
   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) {
@@ -520,21 +579,26 @@
     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];
 
@@ -580,6 +644,7 @@
   return 0;
 }
 
+/* Tor main loop. */
 static int do_main_loop(void) {
   int i;
   int timeout;
@@ -675,6 +740,7 @@
   }
 }
 
+/* Unix signal handler. */
 static void catch(int the_signal) {
 
 #ifndef MS_WINDOWS /* do signal stuff only on unix */

Index: or.h
===================================================================
RCS file: /home/or/cvsroot/src/or/or.h,v
retrieving revision 1.330
retrieving revision 1.331
diff -u -d -r1.330 -r1.331
--- or.h	5 May 2004 01:26:57 -0000	1.330
+++ or.h	5 May 2004 21:32:43 -0000	1.331
@@ -1046,8 +1046,8 @@
 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);
@@ -1088,10 +1088,10 @@
 
 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 ***************************/
 

Index: rendclient.c
===================================================================
RCS file: /home/or/cvsroot/src/or/rendclient.c,v
retrieving revision 1.45
retrieving revision 1.46
diff -u -d -r1.45 -r1.46
--- rendclient.c	25 Apr 2004 20:37:37 -0000	1.45
+++ rendclient.c	5 May 2004 21:32:43 -0000	1.46
@@ -2,9 +2,14 @@
 /* See LICENSE for licensing information */
 /* $Id$ */
 
+/*****
+ * rendclient.c: Client code to access location-hiddenn services.
+ *****/
+
 #include "or.h"
 
-/* send the introduce cell */
+/* Called when we've established a circuit to an introduction point:
+ * send the introduction request. */
 void
 rend_client_introcirc_is_open(circuit_t *circ)
 {
@@ -15,8 +20,8 @@
   connection_ap_attach_pending();
 }
 
-/* send the establish-rendezvous cell. if it fails, mark
- * the circ for close and return -1. else return 0.
+/* Send the establish-rendezvous cell along a rendezvous circuit. if
+ * it fails, mark the circ for close and return -1. else return 0.
  */
 int
 rend_client_send_establish_rendezvous(circuit_t *circ)
@@ -124,7 +129,8 @@
   return -1;
 }
 
-/* send the rendezvous cell */
+/* Called when a rendezvous circuit is open; sends a establish
+ * rendezvous circuit as appropriate. */
 void
 rend_client_rendcirc_is_open(circuit_t *circ)
 {
@@ -209,8 +215,13 @@
   return 0;
 }
 
+
+/* If we are not currently fetching a rendezvous service descriptor
+ * for the service ID 'query', start a directory connection to fetch a
+ * new one.
+ */
 void
-rend_client_refetch_renddesc(char *query)
+rend_client_refetch_renddesc(const char *query)
 {
   if(connection_get_by_type_rendquery(CONN_TYPE_DIR, query)) {
     log_fn(LOG_INFO,"Would fetch a new renddesc here (for %s), but one is already in progress.", query);
@@ -229,7 +240,7 @@
  * unrecognized, 1 if recognized and some intro points remain.
  */
 int
-rend_client_remove_intro_point(char *failed_intro, char *query)
+rend_client_remove_intro_point(char *failed_intro, const char *query)
 {
   int i, r;
   rend_cache_entry_t *ent;
@@ -280,7 +291,7 @@
   return 0;
 }
 
-/* bob sent us a rendezvous cell, join the circs. */
+/* Bob sent us a rendezvous cell; join the circuits. */
 int
 rend_client_receive_rendezvous(circuit_t *circ, const char *request, int request_len)
 {

Index: rendcommon.c
===================================================================
RCS file: /home/or/cvsroot/src/or/rendcommon.c,v
retrieving revision 1.28
retrieving revision 1.29
diff -u -d -r1.28 -r1.29
--- rendcommon.c	25 Apr 2004 20:37:37 -0000	1.28
+++ rendcommon.c	5 May 2004 21:32:43 -0000	1.29
@@ -2,9 +2,14 @@
 /* See LICENSE for licensing information */
 /* $Id$ */
 
+/*****
+ * rendcommon.c: Rendezvous implementation: shared code between
+ * introducers, services, clients, and rendezvous points.
+ *****/
+
 #include "or.h"
 
-/* Free the storage held by 'desc'.
+/* Free the storage held by the service descriptor 'desc'.
  */
 void rend_service_descriptor_free(rend_service_descriptor_t *desc)
 {
@@ -66,8 +71,10 @@
   return 0;
 }
 
-/* malloc a service_descriptor_t and return it.
- * return NULL if invalid descriptor or error */
+/* Parse a service descriptor at 'str' (len bytes).  On success,
+ * return a newly alloced service_descriptor_t.  On failure, return
+ * NULL.
+ */
 rend_service_descriptor_t *rend_parse_service_descriptor(
                            const char *str, int len)
 {
@@ -121,8 +128,9 @@
   return NULL;
 }
 
-/* Sets out to the first 10 bytes of the digest of 'pk', base32 encoded.
- * NUL-terminates out.
+/* 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.)
  */
 int rend_get_service_id(crypto_pk_env_t *pk, char *out)
 {
@@ -139,6 +147,8 @@
 #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
+ * rend_cache_entry_t. */
 static strmap_t *rend_cache = NULL;
 
 /* Initializes the service descriptor cache.
@@ -172,8 +182,9 @@
   }
 }
 
-/* return 1 if query is a valid service id, else return 0. */
-int rend_valid_service_id(char *query) {
+/* 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)
     return 0;
 
@@ -183,7 +194,10 @@
   return 1;
 }
 
-int rend_cache_lookup_entry(char *query, rend_cache_entry_t **e)
+/* 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)
 {
   tor_assert(rend_cache);
   if (!rend_valid_service_id(query))
@@ -199,8 +213,10 @@
  *   If it is found, point *desc to it, and write its length into
  *   *desc_len, and return 1.
  *   If it is not found, return 0.
+ * Note: calls to rend_cache_clean or rend_cache_store may invalidate
+ * *desc.
  */
-int rend_cache_lookup_desc(char *query, const char **desc, int *desc_len)
+int rend_cache_lookup_desc(const char *query, const char **desc, int *desc_len)
 {
   rend_cache_entry_t *e;
   int r;
@@ -211,12 +227,12 @@
   return 1;
 }
 
-
-/* Calculate desc's service id, and store it.
- * Return -1 if it's malformed or otherwise rejected and you
- * want the caller to fail, else return 0.
+/* 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.
  */
-int rend_cache_store(char *desc, int desc_len)
+int rend_cache_store(const char *desc, int desc_len)
 {
   rend_cache_entry_t *e;
   rend_service_descriptor_t *parsed;
@@ -273,7 +289,8 @@
   return 0;
 }
 
-/* Dispatch on rendezvous relay command. */
+/* 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)
 {

Index: rendmid.c
===================================================================
RCS file: /home/or/cvsroot/src/or/rendmid.c,v
retrieving revision 1.20
retrieving revision 1.21
diff -u -d -r1.20 -r1.21
--- rendmid.c	27 Apr 2004 21:48:37 -0000	1.20
+++ rendmid.c	5 May 2004 21:32:43 -0000	1.21
@@ -2,10 +2,14 @@
 /* See LICENSE for licensing information */
 /* $Id$ */
 
+/*****
+ * rendmid.c: Implement introductions points and rendezvous points.
+ *****/
+
 #include "or.h"
 
-/* Respond to an ESTABLISH_INTRO cell by setting the circuit's purpose and
- * service pk digest..
+/* Respond to an ESTABLISH_INTRO cell by checking the signed data and
+ * setting the circuit's purpose and service pk digest.
  */
 int
 rend_mid_establish_intro(circuit_t *circ, const char *request, int request_len)
@@ -219,8 +223,9 @@
   return -1;
 }
 
-/* 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.
+/* 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.
  */
 int
 rend_mid_rendezvous(circuit_t *circ, const char *request, int request_len)

Index: rendservice.c
===================================================================
RCS file: /home/or/cvsroot/src/or/rendservice.c,v
retrieving revision 1.61
retrieving revision 1.62
diff -u -d -r1.61 -r1.62
--- rendservice.c	30 Apr 2004 16:35:48 -0000	1.61
+++ rendservice.c	5 May 2004 21:32:43 -0000	1.62
@@ -2,8 +2,9 @@
 /* See LICENSE for licensing information */
 /* $Id$ */
 
-/* This module implements the hidden-service side of rendezvous functionality.
- */
+/*****
+ * rendservice.c: The hidden-service side of rendezvous functionality.
+ *****/
 
 #include "or.h"
 
@@ -27,14 +28,15 @@
 typedef struct rend_service_t {
   /* Fields specified in config file */
   char *directory; /* where in the filesystem it stores it */
-  smartlist_t *ports;
-  char *intro_prefer_nodes;
-  char *intro_exclude_nodes;
+  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 _want_ */
+  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;
@@ -457,7 +459,11 @@
   return -1;
 }
 
+
 #define MAX_REND_FAILURES 3
+/* 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
 rend_service_relaunch_rendezvous(circuit_t *oldcirc)
 {
@@ -495,10 +501,11 @@
   memcpy(newcirc->rend_cookie, oldcirc->rend_cookie, REND_COOKIE_LEN);
 }
 
-/* Launch a circuit to serve as an introduction point.
+/* Launch a circuit to serve as an introduction point for the service
+ * 'service' at the introduction point 'nickname'
  */
 static int
-rend_service_launch_establish_intro(rend_service_t *service, char *nickname)
+rend_service_launch_establish_intro(rend_service_t *service, const char *nickname)
 {
   circuit_t *launched;
 
@@ -578,7 +585,9 @@
   circuit_mark_for_close(circuit);
 }
 
-/* Handle an INTRO_ESTABLISHED cell. */
+/* 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
 rend_service_intro_established(circuit_t *circuit, const char *request, int request_len)
 {
@@ -603,7 +612,7 @@
   return -1;
 }
 
-/* Called once a circuit to a rendezvous point is ready: sends a
+/* Called once a circuit to a rendezvous point is established: sends a
  *  RELAY_COMMAND_RENDEZVOUS1 cell.
  */
 void
@@ -711,6 +720,10 @@
   return NULL;
 }
 
+/* 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.
+ */
 static void
 upload_service_descriptor(rend_service_t *service)
 {
@@ -827,6 +840,11 @@
   smartlist_free(exclude_routers);
 }
 
+/* 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.
+ */
 void
 rend_services_upload(int force)
 {
@@ -842,6 +860,9 @@
   }
 }
 
+/* Log the status of introduction points for all rendezvous services
+ * at log severity 'serverity'.
+ */
 void
 rend_service_dump_stats(int severity)
 {
@@ -872,9 +893,10 @@
   }
 }
 
-/* This is a beginning rendezvous stream. Look up conn->port,
- * and assign the actual conn->addr and conn->port. Return -1
- * if failure, or 0 for success.
+/* '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.
  */
 int
 rend_service_set_connection_addr_port(connection_t *conn, circuit_t *circ)

Index: rephist.c
===================================================================
RCS file: /home/or/cvsroot/src/or/rephist.c,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -d -r1.6 -r1.7
--- rephist.c	25 Apr 2004 20:37:37 -0000	1.6
+++ rephist.c	5 May 2004 21:32:43 -0000	1.7
@@ -2,26 +2,47 @@
 /* See LICENSE for licensing information */
 /* $Id$ */
 
+/*****
+ * rephist.c: Basic history functionality for reputation module.
+ *****/
+
 #include "or.h"
 
+/* History of an or->or link. */
 typedef struct link_history_t {
+  /* When did we start tracking this list? */
   time_t since;
+  /* How many times did extending from OR1 to OR2 succeeed? */
   unsigned long n_extend_ok;
+  /* How many times did extending from OR1 to OR2 fail? */
   unsigned long n_extend_fail;
 } link_history_t;
 
+/* History of an OR. */
 typedef struct or_history_t {
+  /* When did we start tracking this OR? */
   time_t since;
+  /* How many times did we successfully connect? */
   unsigned long n_conn_ok;
+  /*How many times did we try to connect and fail?*/
   unsigned long n_conn_fail;
+  /* How many seconds have we been connected to this OR before
+   * 'up_since'? */
   unsigned long uptime;
+  /* How many seconds have we been unable to connect to this OR before
+   * 'down_since'? */
   unsigned long downtime;
+  /* If nonzero, we have been connected since this time. */
   time_t up_since;
+  /* If nonzero, we have been unable to connect since this time. */
   time_t down_since;
+  /* Map from lowercased OR2 name to a link_history_t for the link
+   * from this OR to OR2. */
   strmap_t *link_history_map;
 } or_history_t;
 
-static strmap_t *history_map;
+/* Map from lowercased OR nickname to or_history_t. */
+static strmap_t *history_map = NULL;
 
 /* Return the or_history_t for the named OR, creating it if necessary.
  */
@@ -57,7 +78,7 @@
 }
 
 /* Update an or_history_t object so that its uptime/downtime count is
- * up-to-date.
+ * up-to-date as of 'when'.
  */
 static void update_or_history(or_history_t *hist, time_t when)
 {
@@ -227,8 +248,6 @@
   }
 }
 
-
-
 /*
   Local Variables:
   mode:c

Index: tor_main.c
===================================================================
RCS file: /home/or/cvsroot/src/or/tor_main.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -d -r1.3 -r1.4
--- tor_main.c	17 Dec 2003 21:09:31 -0000	1.3
+++ tor_main.c	5 May 2004 21:32:43 -0000	1.4
@@ -2,6 +2,11 @@
 /* See LICENSE for licensing information */
 /* $Id$ */
 
+/*****
+ * tor_main.c: Entry point for tor binary.  (We keep main() in a
+ * separate file so that our unit tests can use functions from main.c)
+ *****/
+
 int tor_main(int argc, char *argv[]);
 
 int main(int argc, char *argv[])