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

[or-cvs] Checkpoint in-progress fixes:



Update of /home2/or/cvsroot/tor/src/or
In directory moria.mit.edu:/home2/arma/work/onion/cvs/tor/src/or

Modified Files:
	circuitbuild.c circuituse.c config.c directory.c main.c or.h 
	router.c routerlist.c 
Log Message:
Checkpoint in-progress fixes:
Add 'testing' circuit purpose, for reachability testing.
Notice when our IP changes, and reset stats.
Try to pull down a directory via Tor to see if our DirPort is working.
Try to extend a circuit back to us to see if our ORPort is working.
Only publish a descriptor if they're both reachable.

These mostly work, and I'd better get them in before I cause conflicts.


Index: circuitbuild.c
===================================================================
RCS file: /home2/or/cvsroot/tor/src/or/circuitbuild.c,v
retrieving revision 1.83
retrieving revision 1.84
diff -u -d -r1.83 -r1.84
--- circuitbuild.c	22 Feb 2005 08:18:34 -0000	1.83
+++ circuitbuild.c	27 Feb 2005 09:47:00 -0000	1.84
@@ -753,6 +753,8 @@
 #else
   if (purpose == CIRCUIT_PURPOSE_C_GENERAL)
     routelen = 3;
+  else if (purpose == CIRCUIT_PURPOSE_TESTING)
+    routelen = 3;
   else if (purpose == CIRCUIT_PURPOSE_C_INTRODUCING)
     routelen = 4;
   else if (purpose == CIRCUIT_PURPOSE_C_ESTABLISH_REND)

Index: circuituse.c
===================================================================
RCS file: /home2/or/cvsroot/tor/src/or/circuituse.c,v
retrieving revision 1.50
retrieving revision 1.51
diff -u -d -r1.50 -r1.51
--- circuituse.c	22 Feb 2005 00:53:07 -0000	1.50
+++ circuituse.c	27 Feb 2005 09:47:00 -0000	1.51
@@ -541,6 +541,31 @@
   }
 }
 
+/** A testing circuit has completed. Take whatever stats we want. */
+static void
+circuit_testing_opened(circuit_t *circ) {
+
+  /* For now, we only use testing circuits to see if our ORPort is
+     reachable. So, if this circuit ends at us, remember that. */
+  routerinfo_t *exit = router_get_by_digest(circ->build_state->chosen_exit_digest);
+  if(exit && router_is_me(exit)) {
+    log_fn(LOG_NOTICE,"Your ORPort is reachable from the outside. Excellent.");
+    router_orport_found_reachable();
+  }
+  circuit_mark_for_close(circ);
+}
+
+/** A testing circuit has failed to build. Take whatever stats we want. */
+static void
+circuit_testing_failed(circuit_t *circ, int at_last_hop) {
+  routerinfo_t *me = router_get_my_routerinfo();
+
+  if (!at_last_hop)
+    circuit_launch_by_identity(CIRCUIT_PURPOSE_TESTING, me->identity_digest, 0, 0, 1);
+  else
+    log_fn(LOG_NOTICE,"The testing circuit has failed. Guess you're not reachable yet.");
+}
+
 /** The circuit <b>circ</b> has just become open. Take the next
  * step: for rendezvous circuits, we pass circ to the appropriate
  * function in rendclient or rendservice. For general circuits, we
@@ -572,6 +597,9 @@
       /* at Bob, connecting to rend point */
       rend_service_rendezvous_has_opened(circ);
       break;
+    case CIRCUIT_PURPOSE_TESTING:
+      circuit_testing_opened(circ);
+      break;
     default:
       log_fn(LOG_ERR,"unhandled purpose %d",circ->purpose);
       tor_assert(0);
@@ -603,6 +631,9 @@
         circuit_increment_failure_count();
       }
       break;
+    case CIRCUIT_PURPOSE_TESTING:
+      circuit_testing_failed(circ, failed_at_last_hop);
+      break;
     case CIRCUIT_PURPOSE_S_ESTABLISH_INTRO:
       /* at Bob, waiting for introductions */
       if (circ->state != CIRCUIT_STATE_OPEN) {
@@ -666,7 +697,8 @@
     return NULL;
   }
 
-  if (purpose != CIRCUIT_PURPOSE_C_GENERAL) {
+  if (purpose != CIRCUIT_PURPOSE_C_GENERAL &&
+      purpose != CIRCUIT_PURPOSE_TESTING) {
     /* see if there are appropriate circs available to cannibalize. */
     if ((circ = circuit_get_clean_open(CIRCUIT_PURPOSE_C_GENERAL, need_uptime,
                                        need_capacity, internal))) {

Index: config.c
===================================================================
RCS file: /home2/or/cvsroot/tor/src/or/config.c,v
retrieving revision 1.318
retrieving revision 1.319
diff -u -d -r1.318 -r1.319
--- config.c	25 Feb 2005 20:46:13 -0000	1.318
+++ config.c	27 Feb 2005 09:47:00 -0000	1.319
@@ -933,6 +933,7 @@
   char hostname[256];
   int explicit_ip=1;
   char tmpbuf[INET_NTOA_BUF_LEN];
+  static uint32_t old_addr=0;
 
   tor_assert(addr);
 
@@ -972,6 +973,11 @@
 
   log_fn(LOG_DEBUG, "Resolved Address to %s.", tmpbuf);
   *addr = ntohl(in.s_addr);
+  if (old_addr && old_addr != *addr) {
+    log_fn(LOG_NOTICE,"Your IP seems to have changed. Updating.");
+    server_has_changed_ip();
+  }
+  old_addr = *addr;
   return 0;
 }
 

Index: directory.c
===================================================================
RCS file: /home2/or/cvsroot/tor/src/or/directory.c,v
retrieving revision 1.215
retrieving revision 1.216
diff -u -d -r1.215 -r1.216
--- directory.c	25 Feb 2005 20:46:13 -0000	1.215
+++ directory.c	27 Feb 2005 09:47:00 -0000	1.216
@@ -28,19 +28,20 @@
  *   connection_finished_connecting() in connection.c
  */
 
-static void
+void
 directory_initiate_command_router(routerinfo_t *router, uint8_t purpose,
-                                  const char *resource,
+                                  int private_connection, const char *resource,
                                   const char *payload, size_t payload_len);
 static void
 directory_initiate_command_trusted_dir(trusted_dir_server_t *dirserv,
-                                      uint8_t purpose, const char *resource,
+                                      uint8_t purpose, int private_connection,
+                                      const char *resource,
                                       const char *payload, size_t payload_len);
 static void
 directory_initiate_command(const char *address, uint32_t addr, uint16_t port,
                            const char *platform,
                            const char *digest, uint8_t purpose,
-                           const char *resource,
+                           int private_connection, const char *resource,
                            const char *payload, size_t payload_len);
 
 static void
@@ -111,6 +112,14 @@
   return 0;
 }
 
+int purpose_is_private(uint8_t purpose) {
+  if (purpose == DIR_PURPOSE_FETCH_DIR ||
+      purpose == DIR_PURPOSE_UPLOAD_DIR ||
+      purpose == DIR_PURPOSE_FETCH_RUNNING_LIST)
+    return 0;
+  return 1;
+}
+
 /** 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
@@ -137,8 +146,8 @@
         if (!smartlist_string_num_isin(get_options()->FirewallPorts, ds->dir_port))
           continue;
       }
-      directory_initiate_command_trusted_dir(ds, purpose, NULL,
-                                             payload, payload_len);
+      directory_initiate_command_trusted_dir(ds, purpose, purpose_is_private(purpose),
+                                             NULL, payload, payload_len);
     });
 }
 
@@ -159,6 +168,7 @@
   int directconn = purpose == DIR_PURPOSE_FETCH_DIR ||
                    purpose == DIR_PURPOSE_FETCH_RUNNING_LIST;
   int fetch_fresh_first = advertised_server_mode();
+  int priv = purpose_is_private(purpose);
 
   if (directconn) {
     if (fetch_fresh_first) {
@@ -186,9 +196,9 @@
   }
 
   if (r)
-    directory_initiate_command_router(r, purpose, resource, NULL, 0);
+    directory_initiate_command_router(r, purpose, priv, resource, NULL, 0);
   else if (ds)
-    directory_initiate_command_trusted_dir(ds, purpose, resource, NULL, 0);
+    directory_initiate_command_trusted_dir(ds, purpose, priv, resource, NULL, 0);
   else {
     log_fn(LOG_NOTICE,"No running dirservers known. Not trying. (purpose %d)",
            purpose);
@@ -210,25 +220,28 @@
  * When fetching a rendezvous descriptor, <b>resource</b> is the service ID we
  * want to fetch.
  */
-static void
+void
 directory_initiate_command_router(routerinfo_t *router, uint8_t purpose,
-                                  const char *resource,
+                                  int private_connection, const char *resource,
                                   const char *payload, size_t payload_len)
 {
   directory_initiate_command(router->address, router->addr, router->dir_port,
                              router->platform, router->identity_digest,
-                             purpose, resource, payload, payload_len);
+                             purpose, private_connection, resource,
+                             payload, payload_len);
 }
 
 /** As directory_initiate_command_router, but send the command to a trusted
  * directory server <b>dirserv</b>. **/
 static void
 directory_initiate_command_trusted_dir(trusted_dir_server_t *dirserv,
-                                       uint8_t purpose, const char *resource,
+                                       uint8_t purpose, int private_connection,
+                                       const char *resource,
                                        const char *payload, size_t payload_len)
 {
   directory_initiate_command(dirserv->address, dirserv->addr,dirserv->dir_port,
-               NULL, dirserv->digest, purpose, resource, payload, payload_len);
+               NULL, dirserv->digest, purpose, private_connection, resource,
+               payload, payload_len);
 }
 
 /** Called when we are unable to complete our connection to a
@@ -256,7 +269,7 @@
 directory_initiate_command(const char *address, uint32_t addr,
                            uint16_t dir_port, const char *platform,
                            const char *digest, uint8_t purpose,
-                           const char *resource,
+                           int private_connection, const char *resource,
                            const char *payload, size_t payload_len)
 {
   connection_t *conn;
@@ -292,17 +305,7 @@
   /* set up conn so it's got all the data we need to remember */
   conn->addr = addr;
   conn->port = dir_port;
-
-  if (get_options()->HttpProxy) {
-    addr = get_options()->HttpProxyAddr;
-    dir_port = get_options()->HttpProxyPort;
-  }
-
   conn->address = tor_strdup(address);
-  /* conn->nickname = tor_strdup(router->nickname); */
-  /* tor_assert(router->identity_pkey); */
-  /* conn->identity_pkey = crypto_pk_dup_key(router->identity_pkey); */
-  /* crypto_pk_get_digest(conn->identity_pkey, conn->identity_digest); */
   memcpy(conn->identity_digest, digest, DIGEST_LEN);
 
   conn->purpose = purpose;
@@ -310,10 +313,14 @@
   /* give it an initial state */
   conn->state = DIR_CONN_STATE_CONNECTING;
 
-  if (purpose == DIR_PURPOSE_FETCH_DIR ||
-      purpose == DIR_PURPOSE_UPLOAD_DIR ||
-      purpose == DIR_PURPOSE_FETCH_RUNNING_LIST) {
+  if (!private_connection) {
     /* then we want to connect directly */
+
+    if (get_options()->HttpProxy) {
+      addr = get_options()->HttpProxyAddr;
+      dir_port = get_options()->HttpProxyPort;
+    }
+
     switch (connection_connect(conn, conn->address, addr, dir_port)) {
       case -1:
         connection_dir_connect_failed(conn);
@@ -703,7 +710,8 @@
     } else {
       log_fn(LOG_INFO,"updated routers.");
     }
-    directory_has_arrived(time(NULL)); /* do things we've been waiting to do */
+    /* do things we've been waiting to do */
+    directory_has_arrived(time(NULL), conn->identity_digest);
   }
 
   if (conn->purpose == DIR_PURPOSE_FETCH_RUNNING_LIST) {

Index: main.c
===================================================================
RCS file: /home2/or/cvsroot/tor/src/or/main.c,v
retrieving revision 1.451
retrieving revision 1.452
diff -u -d -r1.451 -r1.452
--- main.c	25 Feb 2005 05:42:01 -0000	1.451
+++ main.c	27 Feb 2005 09:47:01 -0000	1.452
@@ -263,7 +263,6 @@
 
 /** Return true iff <b>conn</b> is listening for read events. */
 int connection_is_reading(connection_t *conn) {
-  int r;
   tor_assert(conn);
 
   return conn->read_event && event_pending(conn->read_event, EV_READ, NULL);
@@ -578,8 +577,10 @@
   }
 }
 
-/** This function is called whenever we successfully pull down a directory */
-void directory_has_arrived(time_t now) {
+/** This function is called whenever we successfully pull down a directory.
+ * If <b>identity_digest</b> is defined, it contains the digest of the
+ * router that just gave us this directory. */
+void directory_has_arrived(time_t now, char *identity_digest) {
   or_options_t *options = get_options();
 
   log_fn(LOG_INFO, "A directory has arrived.");
@@ -597,14 +598,26 @@
   if (!time_to_fetch_running_routers)
     time_to_fetch_running_routers = now + options->StatusFetchPeriod;
 
+  if (identity_digest) { /* if this is us, then our dirport is reachable */
+    routerinfo_t *router = router_get_by_digest(identity_digest);
+    if (!router) // XXX
+      log_fn(LOG_WARN,"Roger, router_get_by_digest doesn't find me.");
+    if (router && router_is_me(router)) {
+      log_fn(LOG_NOTICE,"Your DirPort is reachable from the outside. Excellent.");
+      router_dirport_found_reachable();
+    }
+  }
+
   if (server_mode(options) &&
       !we_are_hibernating()) { /* connect to the appropriate routers */
     router_retry_connections();
+    if (identity_digest) /* we got a fresh directory */
+      consider_testing_reachability();
   }
 }
 
 /** Perform regular maintenance tasks for a single connection.  This
- * function gets run once per second per connection by run_housekeeping.
+ * function gets run once per second per connection by run_scheduled_events.
  */
 static void run_connection_housekeeping(int i, time_t now) {
   cell_t cell;
@@ -648,81 +661,6 @@
   }
 }
 
-#define MIN_BW_TO_PUBLISH_DESC 5000 /* 5000 bytes/s sustained */
-#define MIN_UPTIME_TO_PUBLISH_DESC (30*60) /* half an hour */
-
-/** Decide if we're a publishable server or just a client. We are a server if:
- * - We have the AuthoritativeDirectory option set.
- * or
- * - We don't have the ClientOnly option set; and
- * - We have ORPort set; and
- * - We have been up for at least MIN_UPTIME_TO_PUBLISH_DESC seconds; and
- * - We have processed some suitable minimum bandwidth recently; and
- * - We believe we are reachable from the outside.
- */
-static int decide_if_publishable_server(time_t now) {
-  int bw;
-  or_options_t *options = get_options();
-
-  bw = rep_hist_bandwidth_assess();
-  router_set_bandwidth_capacity(bw);
-
-  if (options->ClientOnly)
-    return 0;
-  if (!options->ORPort)
-    return 0;
-
-  /* XXX for now, you're only a server if you're a server */
-  return server_mode(options);
-
-  /* here, determine if we're reachable */
-  if (0) { /* we've recently failed to reach our IP/ORPort from the outside */
-    return 0;
-  }
-
-  if (bw < MIN_BW_TO_PUBLISH_DESC)
-    return 0;
-  if (options->AuthoritativeDir)
-    return 1;
-  if (stats_n_seconds_working < MIN_UPTIME_TO_PUBLISH_DESC)
-    return 0;
-
-  return 1;
-}
-
-/** Return true iff we believe ourselves to be an authoritative
- * directory server.
- */
-int authdir_mode(or_options_t *options) {
-  return options->AuthoritativeDir != 0;
-}
-
-/** Return true iff we try to stay connected to all ORs at once.
- */
-int clique_mode(or_options_t *options) {
-  return authdir_mode(options);
-}
-
-/** Return true iff we are trying to be a server.
- */
-int server_mode(or_options_t *options) {
-  return (options->ORPort != 0 || options->ORBindAddress);
-}
-
-/** Remember if we've advertised ourselves to the dirservers. */
-static int server_is_advertised=0;
-
-/** Return true iff we have published our descriptor lately.
- */
-int advertised_server_mode(void) {
-  return server_is_advertised;
-}
-
-/** Return true iff we are trying to be a socks proxy. */
-int proxy_mode(or_options_t *options) {
-  return (options->SocksPort != 0 || options->SocksBindAddress);
-}
-
 /** Perform regular maintenance tasks.  This function gets run once per
  * second by prepare_for_poll.
  */
@@ -810,13 +748,7 @@
   }
 
   if (time_to_force_upload_descriptor < now) {
-    if (decide_if_publishable_server(now)) {
-      server_is_advertised = 1;
-      router_rebuild_descriptor(1);
-      router_upload_dir_desc_to_dirservers(1);
-    } else {
-      server_is_advertised = 0;
-    }
+    consider_publishable_server(now, 1);
 
     rend_cache_clean(); /* this should go elsewhere? */
 
@@ -827,13 +759,7 @@
    * one is inaccurate. */
   if (time_to_check_descriptor < now) {
     time_to_check_descriptor = now + CHECK_DESCRIPTOR_INTERVAL;
-    if (decide_if_publishable_server(now)) {
-      server_is_advertised=1;
-      router_rebuild_descriptor(0);
-      router_upload_dir_desc_to_dirservers(0);
-    } else {
-      server_is_advertised=0;
-    }
+    consider_publishable_server(now, 0);
   }
 
   /** 3a. Every second, we examine pending circuits and prune the

Index: or.h
===================================================================
RCS file: /home2/or/cvsroot/tor/src/or/or.h,v
retrieving revision 1.542
retrieving revision 1.543
diff -u -d -r1.542 -r1.543
--- or.h	25 Feb 2005 20:46:13 -0000	1.542
+++ or.h	27 Feb 2005 09:47:01 -0000	1.543
@@ -381,7 +381,9 @@
 #define CIRCUIT_PURPOSE_S_CONNECT_REND 15
 /** Hidden-service-side circuit purpose: at Bob, rendezvous established. */
 #define CIRCUIT_PURPOSE_S_REND_JOINED 16
-#define _CIRCUIT_PURPOSE_MAX 16
+/** A testing circuit; not meant to be used for actual traffic. */
+#define CIRCUIT_PURPOSE_TESTING 17
+#define _CIRCUIT_PURPOSE_MAX 17
 
 /** True iff the circuit purpose <b>p</b> is for a circuit at the OP
  * that this OP has originated. */
@@ -1378,6 +1380,10 @@
                                   size_t payload_len);
 void directory_get_from_dirserver(uint8_t purpose, const char *resource,
                                   int retry_if_no_servers);
+void directory_initiate_command_router(routerinfo_t *router, uint8_t purpose,
+                                       int private_connection, const char *resource,
+                                       const char *payload, size_t payload_len);
+
 int parse_http_response(const char *headers, int *code, time_t *date,
                         int *compression);
 
@@ -1455,13 +1461,7 @@
 void connection_start_writing(connection_t *conn);
 
 void directory_all_unreachable(time_t now);
-void directory_has_arrived(time_t now);
-
-int authdir_mode(or_options_t *options);
-int clique_mode(or_options_t *options);
-int server_mode(or_options_t *options);
-int advertised_server_mode(void);
-int proxy_mode(or_options_t *options);
+void directory_has_arrived(time_t now, char *identity_digest);
 
 int control_signal_act(int the_signal);
 void handle_signals(int is_parent);
@@ -1624,11 +1624,21 @@
 crypto_pk_env_t *get_identity_key(void);
 int identity_key_is_set(void);
 void dup_onion_keys(crypto_pk_env_t **key, crypto_pk_env_t **last);
-int init_keys(void);
-crypto_pk_env_t *init_key_from_file(const char *fname);
 void rotate_onion_key(void);
-void router_set_bandwidth_capacity(int bw);
-int router_get_bandwidth_capacity(void);
+crypto_pk_env_t *init_key_from_file(const char *fname);
+int init_keys(void);
+
+void consider_testing_reachability(void);
+void router_orport_found_reachable(void);
+void router_dirport_found_reachable(void);
+void server_has_changed_ip(void);
+void consider_publishable_server(time_t now, int force);
+
+int authdir_mode(or_options_t *options);
+int clique_mode(or_options_t *options);
+int server_mode(or_options_t *options);
+int advertised_server_mode(void);
+int proxy_mode(or_options_t *options);
 
 void router_retry_connections(void);
 int router_is_clique_mode(routerinfo_t *router);

Index: router.c
===================================================================
RCS file: /home2/or/cvsroot/tor/src/or/router.c,v
retrieving revision 1.148
retrieving revision 1.149
diff -u -d -r1.148 -r1.149
--- router.c	25 Feb 2005 20:46:13 -0000	1.148
+++ router.c	27 Feb 2005 09:47:01 -0000	1.149
@@ -143,19 +143,6 @@
   log_fn(LOG_WARN, "Couldn't rotate onion key.");
 }
 
-/** The latest calculated bandwidth usage for our node. */
-static int bw_capacity = 0;
-/** Tuck <b>bw</b> away so we can produce it when somebody
- * calls router_get_bandwidth_capacity() below.
- */
-void router_set_bandwidth_capacity(int bw) {
-  bw_capacity = bw;
-}
-/** Return the value we tucked away above, or zero by default. */
-int router_get_bandwidth_capacity(void) {
-  return bw_capacity;
-}
-
 /* Read an RSA secret key key from a file that was once named fname_old,
  * but is now named fname_new.  Rename the file from old to new as needed.
  */
@@ -382,6 +369,120 @@
   return 0;
 }
 
+/* Keep track of whether we should upload our server descriptor,
+ * and what type of server we are.
+ */
+
+/** Whether we can reach our ORPort from the outside. */
+static int can_reach_or_port = 0;
+/** Whether we can reach our DirPort from the outside. */
+static int can_reach_dir_port = 0;
+
+void consider_testing_reachability(void) {
+  routerinfo_t *me = router_get_my_routerinfo();
+
+  if (!can_reach_or_port) {
+    circuit_launch_by_identity(CIRCUIT_PURPOSE_TESTING, me->identity_digest, 0, 0, 1);
+  }
+
+  if (!can_reach_dir_port && me->dir_port) {
+    if (me) {
+      directory_initiate_command_router(me, DIR_PURPOSE_FETCH_DIR, 1, NULL, NULL, 0);
+    } else {
+      log_fn(LOG_NOTICE,"Delaying checking DirPort reachability; can't build descriptor.");
+    }
+  }
+}
+
+/** Annotate that we found our ORPort reachable. */
+void router_orport_found_reachable(void) {
+  can_reach_or_port = 1;
+}
+
+/** Annotate that we found our DirPort reachable. */
+void router_dirport_found_reachable(void) {
+  can_reach_dir_port = 1;
+}
+
+/** Our router has just moved to a new IP. Reset stats. */
+void server_has_changed_ip(void) {
+  stats_n_seconds_working = 0;
+  can_reach_or_port = 0;
+  can_reach_dir_port = 0;
+  mark_my_descriptor_dirty();
+}
+
+/** Return true iff we believe ourselves to be an authoritative
+ * directory server.
+ */
+int authdir_mode(or_options_t *options) {
+  return options->AuthoritativeDir != 0;
+}
+/** Return true iff we try to stay connected to all ORs at once.
+ */
+int clique_mode(or_options_t *options) {
+  return authdir_mode(options);
+}
+
+/** Return true iff we are trying to be a server.
+ */
+int server_mode(or_options_t *options) {
+  return (options->ORPort != 0 || options->ORBindAddress);
+}
+
+/** Remember if we've advertised ourselves to the dirservers. */
+static int server_is_advertised=0;
+
+/** Return true iff we have published our descriptor lately.
+ */
+int advertised_server_mode(void) {
+  return server_is_advertised;
+}
+
+static void set_server_advertised(int s) {
+  server_is_advertised = s;
+}
+
+/** Return true iff we are trying to be a socks proxy. */
+int proxy_mode(or_options_t *options) {
+  return (options->SocksPort != 0 || options->SocksBindAddress);
+}
+
+/** Decide if we're a publishable server or just a client. We are a server if:
+ * - We have the AuthoritativeDirectory option set.
+ * or
+ * - We don't have the ClientOnly option set; and
+ * - We have ORPort set; and
+ * - We believe we are reachable from the outside.
+ */
+static int decide_if_publishable_server(time_t now) {
+  or_options_t *options = get_options();
+
+  if (options->ClientOnly)
+    return 0;
+  if (!server_mode(options))
+    return 0;
+  if (options->AuthoritativeDir)
+    return 1;
+
+  if (!can_reach_or_port)
+    return 0;
+  if (options->DirPort && !can_reach_dir_port)
+    return 0;
+
+  return 1;
+}
+
+void consider_publishable_server(time_t now, int force) {
+  if (decide_if_publishable_server(now)) {
+    set_server_advertised(1);
+    router_rebuild_descriptor(force);
+    router_upload_dir_desc_to_dirservers(force);
+  } else {
+    set_server_advertised(0);
+  }
+}
+
 /*
  * Clique maintenance
  */
@@ -568,7 +669,7 @@
   ri->platform = tor_strdup(platform);
   ri->bandwidthrate = (int)options->BandwidthRate;
   ri->bandwidthburst = (int)options->BandwidthBurst;
-  ri->bandwidthcapacity = hibernating ? 0 : router_get_bandwidth_capacity();
+  ri->bandwidthcapacity = hibernating ? 0 : rep_hist_bandwidth_assess();
   router_add_exit_policy_from_config(ri);
   if (desc_routerinfo) /* inherit values */
     ri->is_verified = desc_routerinfo->is_verified;

Index: routerlist.c
===================================================================
RCS file: /home2/or/cvsroot/tor/src/or/routerlist.c,v
retrieving revision 1.215
retrieving revision 1.216
diff -u -d -r1.215 -r1.216
--- routerlist.c	27 Feb 2005 07:23:42 -0000	1.215
+++ routerlist.c	27 Feb 2005 09:47:01 -0000	1.216
@@ -66,7 +66,7 @@
     if (routerlist &&
         ((routerlist->published_on > time(NULL) - MIN_ONION_KEY_LIFETIME/2)
          || is_recent)) {
-      directory_has_arrived(st.st_mtime); /* do things we've been waiting to do */
+      directory_has_arrived(st.st_mtime, NULL); /* do things we've been waiting to do */
     }
     tor_free(s);
   }
@@ -634,11 +634,11 @@
   routerinfo_t *router;
 
   tor_assert(digest);
-  if (!routerlist) return NULL;
   if (server_mode(get_options()) &&
       (router = router_get_my_routerinfo()) &&
       !memcmp(digest, router->identity_digest, DIGEST_LEN))
     return router;
+  if (!routerlist) return NULL;
 
   for (i=0;i<smartlist_len(routerlist->routers);i++) {
     router = smartlist_get(routerlist->routers, i);