Преглед изворни кода

Merge branch 'disable_network'

Nick Mathewson пре 14 година
родитељ
комит
83f66db79e
12 измењених фајлова са 138 додато и 32 уклоњено
  1. 9 0
      changes/disable_network
  2. 6 0
      doc/tor.1.txt
  3. 12 1
      src/or/config.c
  4. 63 5
      src/or/connection.c
  5. 3 0
      src/or/connection.h
  6. 7 0
      src/or/dns.c
  7. 1 10
      src/or/hibernate.c
  8. 16 13
      src/or/main.c
  9. 4 0
      src/or/or.h
  10. 10 2
      src/or/router.c
  11. 2 0
      src/or/router.h
  12. 5 1
      src/or/routerlist.c

+ 9 - 0
changes/disable_network

@@ -0,0 +1,9 @@
+  o Minor features:
+
+    - New "DisableNetwork" option to prevent Tor from launching any
+      connections or accepting any connections except on a control
+      port. Some bundles and controllers want to use this so they can
+      configure Tor before letting Tor talk to the rest of the
+      network--for example, to prevent any connections from being made
+      to a non-bridge address.
+

+ 6 - 0
doc/tor.1.txt

@@ -125,6 +125,12 @@ Other options can be specified either on the command-line (--option
     You probably don't need to adjust this. It has no effect on Windows
     You probably don't need to adjust this. It has no effect on Windows
     since that platform lacks getrlimit(). (Default: 1000)
     since that platform lacks getrlimit(). (Default: 1000)
 
 
+**DisableNetwork** **0**|**1**::
+    When this option is set, we don't listen for or accept any connections
+    other than controller connections, and we don't make any outbound
+    connections.  Controllers sometimes use this option to avoid using
+    the network until Tor is fully configured. (Default: 0)
+
 **ConstrainedSockets** **0**|**1**::
 **ConstrainedSockets** **0**|**1**::
     If set, Tor will tell the kernel to attempt to shrink the buffers for all
     If set, Tor will tell the kernel to attempt to shrink the buffers for all
     sockets to the size specified in **ConstrainedSockSize**. This is useful for
     sockets to the size specified in **ConstrainedSockSize**. This is useful for

+ 12 - 1
src/or/config.c

@@ -231,6 +231,7 @@ static config_var_t _option_vars[] = {
   V(CountPrivateBandwidth,       BOOL,     "0"),
   V(CountPrivateBandwidth,       BOOL,     "0"),
   V(DataDirectory,               FILENAME, NULL),
   V(DataDirectory,               FILENAME, NULL),
   OBSOLETE("DebugLogFile"),
   OBSOLETE("DebugLogFile"),
+  V(DisableNetwork,              BOOL,     "0"),
   V(DirAllowPrivateAddresses,    BOOL,     NULL),
   V(DirAllowPrivateAddresses,    BOOL,     NULL),
   V(TestingAuthDirTimeToLearnReachability, INTERVAL, "30 minutes"),
   V(TestingAuthDirTimeToLearnReachability, INTERVAL, "30 minutes"),
   V(DirListenAddress,            LINELIST, NULL),
   V(DirListenAddress,            LINELIST, NULL),
@@ -1100,13 +1101,22 @@ options_act_reversible(const or_options_t *old_options, char **msg)
     consider_hibernation(time(NULL));
     consider_hibernation(time(NULL));
 
 
     /* Launch the listeners.  (We do this before we setuid, so we can bind to
     /* Launch the listeners.  (We do this before we setuid, so we can bind to
-     * ports under 1024.)  We don't want to rebind if we're hibernating. */
+     * ports under 1024.)  We don't want to rebind if we're hibernating. If
+     * networking is disabled, this will close all but the control listeners,
+     * but disable those. */
     if (!we_are_hibernating()) {
     if (!we_are_hibernating()) {
       if (retry_all_listeners(replaced_listeners, new_listeners) < 0) {
       if (retry_all_listeners(replaced_listeners, new_listeners) < 0) {
         *msg = tor_strdup("Failed to bind one of the listener ports.");
         *msg = tor_strdup("Failed to bind one of the listener ports.");
         goto rollback;
         goto rollback;
       }
       }
     }
     }
+    if (options->DisableNetwork) {
+      /* Aggressively close non-controller stuff, NOW */
+      log_notice(LD_NET, "DisableNetwork is set. Tor will not make or accept "
+                 "non-control network connections. Shutting down all existing "
+                 "connections.");
+      connection_mark_all_noncontrol_connections();
+    }
   }
   }
 
 
 #if defined(HAVE_NET_IF_H) && defined(HAVE_NET_PFVAR_H)
 #if defined(HAVE_NET_IF_H) && defined(HAVE_NET_PFVAR_H)
@@ -4187,6 +4197,7 @@ options_transition_affects_descriptor(const or_options_t *old_options,
       old_options->ORPort != new_options->ORPort ||
       old_options->ORPort != new_options->ORPort ||
       old_options->DirPort != new_options->DirPort ||
       old_options->DirPort != new_options->DirPort ||
       old_options->ClientOnly != new_options->ClientOnly ||
       old_options->ClientOnly != new_options->ClientOnly ||
+      old_options->DisableNetwork != new_options->DisableNetwork ||
       old_options->_PublishServerDescriptor !=
       old_options->_PublishServerDescriptor !=
         new_options->_PublishServerDescriptor ||
         new_options->_PublishServerDescriptor ||
       get_effective_bwrate(old_options) != get_effective_bwrate(new_options) ||
       get_effective_bwrate(old_options) != get_effective_bwrate(new_options) ||

+ 63 - 5
src/or/connection.c

@@ -1318,6 +1318,24 @@ connection_connect(connection_t *conn, const char *address,
   else
   else
     protocol_family = PF_INET;
     protocol_family = PF_INET;
 
 
+  if (get_options()->DisableNetwork) {
+    /* We should never even try to connect anyplace if DisableNetwork is set.
+     * Warn if we do, and refuse to make the connection. */
+    static ratelim_t disablenet_violated = RATELIM_INIT(30*60);
+    char *m;
+#ifdef MS_WINDOWS
+    *socket_error = WSAENETUNREACH;
+#else
+    *socket_error = ENETUNREACH;
+#endif
+    if ((m = rate_limit_log(&disablenet_violated, approx_time()))) {
+      log_warn(LD_BUG, "Tried to open a socket with DisableNetwork set.%s", m);
+      tor_free(m);
+    }
+    tor_fragile_assert();
+    return -1;
+  }
+
   s = tor_open_socket(protocol_family,SOCK_STREAM,IPPROTO_TCP);
   s = tor_open_socket(protocol_family,SOCK_STREAM,IPPROTO_TCP);
   if (s < 0) {
   if (s < 0) {
     *socket_error = tor_socket_errno(-1);
     *socket_error = tor_socket_errno(-1);
@@ -1968,7 +1986,7 @@ retry_all_listeners(smartlist_t *replaced_conns,
       smartlist_add(listeners, conn);
       smartlist_add(listeners, conn);
   } SMARTLIST_FOREACH_END(conn);
   } SMARTLIST_FOREACH_END(conn);
 
 
-  if (! options->ClientOnly) {
+  if (! options->ClientOnly && ! options->DisableNetwork) {
     if (retry_listeners(listeners,
     if (retry_listeners(listeners,
                         CONN_TYPE_OR_LISTENER, options->ORListenAddress,
                         CONN_TYPE_OR_LISTENER, options->ORListenAddress,
                         options->ORPort, "0.0.0.0",
                         options->ORPort, "0.0.0.0",
@@ -1981,10 +1999,13 @@ retry_all_listeners(smartlist_t *replaced_conns,
       retval = -1;
       retval = -1;
   }
   }
 
 
-  if (retry_listener_ports(listeners,
-                           get_configured_client_ports(),
-                           new_conns) < 0)
-    retval = -1;
+  if (!options->DisableNetwork) {
+    if (retry_listener_ports(listeners,
+                             get_configured_client_ports(),
+                             new_conns) < 0)
+      retval = -1;
+  }
+
   if (retry_listeners(listeners,
   if (retry_listeners(listeners,
                       CONN_TYPE_CONTROL_LISTENER,
                       CONN_TYPE_CONTROL_LISTENER,
                       options->ControlListenAddress,
                       options->ControlListenAddress,
@@ -2025,6 +2046,43 @@ retry_all_listeners(smartlist_t *replaced_conns,
   return retval;
   return retval;
 }
 }
 
 
+/** Mark every listener of type other than CONTROL_LISTENER to be closed. */
+void
+connection_mark_all_noncontrol_listeners(void)
+{
+  SMARTLIST_FOREACH_BEGIN(get_connection_array(), connection_t *, conn) {
+    if (conn->marked_for_close)
+      continue;
+    if (conn->type == CONN_TYPE_CONTROL_LISTENER)
+      continue;
+    if (connection_is_listener(conn))
+      connection_mark_for_close(conn);
+  } SMARTLIST_FOREACH_END(conn);
+}
+
+/** Mark every external conection not used for controllers for close. */
+void
+connection_mark_all_noncontrol_connections(void)
+{
+  SMARTLIST_FOREACH_BEGIN(get_connection_array(), connection_t *, conn) {
+    if (conn->marked_for_close)
+      continue;
+    switch (conn->type) {
+      case CONN_TYPE_CPUWORKER:
+      case CONN_TYPE_CONTROL_LISTENER:
+      case CONN_TYPE_CONTROL:
+        break;
+      case CONN_TYPE_AP:
+        connection_mark_unattached_ap(TO_ENTRY_CONN(conn),
+                                      END_STREAM_REASON_HIBERNATING);
+        break;
+      default:
+        connection_mark_for_close(conn);
+        break;
+    }
+  } SMARTLIST_FOREACH_END(conn);
+}
+
 /** Return 1 if we should apply rate limiting to <b>conn</b>, and 0
 /** Return 1 if we should apply rate limiting to <b>conn</b>, and 0
  * otherwise.
  * otherwise.
  * Right now this just checks if it's an internal IP address or an
  * Right now this just checks if it's an internal IP address or an

+ 3 - 0
src/or/connection.h

@@ -66,6 +66,9 @@ int get_proxy_addrport(tor_addr_t *addr, uint16_t *port, int *proxy_type,
 int retry_all_listeners(smartlist_t *replaced_conns,
 int retry_all_listeners(smartlist_t *replaced_conns,
                         smartlist_t *new_conns);
                         smartlist_t *new_conns);
 
 
+void connection_mark_all_noncontrol_listeners(void);
+void connection_mark_all_noncontrol_connections(void);
+
 ssize_t connection_bucket_write_limit(connection_t *conn, time_t now);
 ssize_t connection_bucket_write_limit(connection_t *conn, time_t now);
 int global_write_bucket_low(connection_t *conn, size_t attempt, int priority);
 int global_write_bucket_low(connection_t *conn, size_t attempt, int priority);
 void connection_bucket_init(void);
 void connection_bucket_init(void);

+ 7 - 0
src/or/dns.c

@@ -1395,6 +1395,10 @@ launch_resolve(edge_connection_t *exitconn)
   int r;
   int r;
   int options = get_options()->ServerDNSSearchDomains ? 0
   int options = get_options()->ServerDNSSearchDomains ? 0
     : DNS_QUERY_NO_SEARCH;
     : DNS_QUERY_NO_SEARCH;
+
+  if (get_options()->DisableNetwork)
+    return -1;
+
   /* What? Nameservers not configured?  Sounds like a bug. */
   /* What? Nameservers not configured?  Sounds like a bug. */
   if (!nameservers_configured) {
   if (!nameservers_configured) {
     log_warn(LD_EXIT, "(Harmless.) Nameservers not configured, but resolve "
     log_warn(LD_EXIT, "(Harmless.) Nameservers not configured, but resolve "
@@ -1601,6 +1605,9 @@ launch_test_addresses(int fd, short event, void *args)
   (void)event;
   (void)event;
   (void)args;
   (void)args;
 
 
+  if (options->DisableNetwork)
+    return;
+
   log_info(LD_EXIT, "Launching checks to see whether our nameservers like to "
   log_info(LD_EXIT, "Launching checks to see whether our nameservers like to "
            "hijack *everything*.");
            "hijack *everything*.");
   /* This situation is worse than the failure-hijacking situation.  When this
   /* This situation is worse than the failure-hijacking situation.  When this

+ 1 - 10
src/or/hibernate.c

@@ -735,7 +735,6 @@ hibernate_soft_limit_reached(void)
 static void
 static void
 hibernate_begin(hibernate_state_t new_state, time_t now)
 hibernate_begin(hibernate_state_t new_state, time_t now)
 {
 {
-  connection_t *conn;
   const or_options_t *options = get_options();
   const or_options_t *options = get_options();
 
 
   if (new_state == HIBERNATE_STATE_EXITING &&
   if (new_state == HIBERNATE_STATE_EXITING &&
@@ -756,15 +755,7 @@ hibernate_begin(hibernate_state_t new_state, time_t now)
   }
   }
 
 
   /* close listeners. leave control listener(s). */
   /* close listeners. leave control listener(s). */
-  while ((conn = connection_get_by_type(CONN_TYPE_OR_LISTENER)) ||
-         (conn = connection_get_by_type(CONN_TYPE_AP_LISTENER)) ||
-         (conn = connection_get_by_type(CONN_TYPE_AP_TRANS_LISTENER)) ||
-         (conn = connection_get_by_type(CONN_TYPE_AP_DNS_LISTENER)) ||
-         (conn = connection_get_by_type(CONN_TYPE_AP_NATD_LISTENER)) ||
-         (conn = connection_get_by_type(CONN_TYPE_DIR_LISTENER))) {
-    log_info(LD_NET,"Closing listener type %d", conn->type);
-    connection_mark_for_close(conn);
-  }
+  connection_mark_all_noncontrol_listeners();
 
 
   /* XXX kill intro point circs */
   /* XXX kill intro point circs */
   /* XXX upload rendezvous service descriptors with no intro points */
   /* XXX upload rendezvous service descriptors with no intro points */

+ 16 - 13
src/or/main.c

@@ -934,7 +934,7 @@ directory_info_has_arrived(time_t now, int from_cache)
       update_extrainfo_downloads(now);
       update_extrainfo_downloads(now);
   }
   }
 
 
-  if (server_mode(options) && !we_are_hibernating() && !from_cache &&
+  if (server_mode(options) && !net_is_disabled() && !from_cache &&
       (can_complete_circuit || !any_predicted_circuits(now)))
       (can_complete_circuit || !any_predicted_circuits(now)))
     consider_testing_reachability(1, 1);
     consider_testing_reachability(1, 1);
 }
 }
@@ -1161,11 +1161,11 @@ run_scheduled_events(time_t now)
     if (router_rebuild_descriptor(1)<0) {
     if (router_rebuild_descriptor(1)<0) {
       log_info(LD_CONFIG, "Couldn't rebuild router descriptor");
       log_info(LD_CONFIG, "Couldn't rebuild router descriptor");
     }
     }
-    if (advertised_server_mode())
+    if (advertised_server_mode() & !options->DisableNetwork)
       router_upload_dir_desc_to_dirservers(0);
       router_upload_dir_desc_to_dirservers(0);
   }
   }
 
 
-  if (time_to_try_getting_descriptors < now) {
+  if (!options->DisableNetwork && time_to_try_getting_descriptors < now) {
     update_all_descriptor_downloads(now);
     update_all_descriptor_downloads(now);
     update_extrainfo_downloads(now);
     update_extrainfo_downloads(now);
     if (router_have_minimum_dir_info())
     if (router_have_minimum_dir_info())
@@ -1219,7 +1219,7 @@ run_scheduled_events(time_t now)
 
 
   if (time_to_launch_reachability_tests < now &&
   if (time_to_launch_reachability_tests < now &&
       (authdir_mode_tests_reachability(options)) &&
       (authdir_mode_tests_reachability(options)) &&
-       !we_are_hibernating()) {
+       !net_is_disabled()) {
     time_to_launch_reachability_tests = now + REACHABILITY_TEST_INTERVAL;
     time_to_launch_reachability_tests = now + REACHABILITY_TEST_INTERVAL;
     /* try to determine reachability of the other Tor relays */
     /* try to determine reachability of the other Tor relays */
     dirserv_test_reachability(now);
     dirserv_test_reachability(now);
@@ -1355,7 +1355,7 @@ run_scheduled_events(time_t now)
 
 
   /* 2b. Once per minute, regenerate and upload the descriptor if the old
   /* 2b. Once per minute, regenerate and upload the descriptor if the old
    * one is inaccurate. */
    * one is inaccurate. */
-  if (time_to_check_descriptor < now) {
+  if (time_to_check_descriptor < now && !options->DisableNetwork) {
     static int dirport_reachability_count = 0;
     static int dirport_reachability_count = 0;
     time_to_check_descriptor = now + CHECK_DESCRIPTOR_INTERVAL;
     time_to_check_descriptor = now + CHECK_DESCRIPTOR_INTERVAL;
     check_descriptor_bandwidth_changed(now);
     check_descriptor_bandwidth_changed(now);
@@ -1430,7 +1430,7 @@ run_scheduled_events(time_t now)
   connection_expire_held_open();
   connection_expire_held_open();
 
 
   /** 3d. And every 60 seconds, we relaunch listeners if any died. */
   /** 3d. And every 60 seconds, we relaunch listeners if any died. */
-  if (!we_are_hibernating() && time_to_check_listeners < now) {
+  if (!net_is_disabled() && time_to_check_listeners < now) {
     retry_all_listeners(NULL, NULL);
     retry_all_listeners(NULL, NULL);
     time_to_check_listeners = now+60;
     time_to_check_listeners = now+60;
   }
   }
@@ -1441,7 +1441,7 @@ run_scheduled_events(time_t now)
    *    and we make a new circ if there are no clean circuits.
    *    and we make a new circ if there are no clean circuits.
    */
    */
   have_dir_info = router_have_minimum_dir_info();
   have_dir_info = router_have_minimum_dir_info();
-  if (have_dir_info && !we_are_hibernating())
+  if (have_dir_info && !net_is_disabled())
     circuit_build_needed_circs(now);
     circuit_build_needed_circs(now);
 
 
   /* every 10 seconds, but not at the same second as other such events */
   /* every 10 seconds, but not at the same second as other such events */
@@ -1472,7 +1472,7 @@ run_scheduled_events(time_t now)
   circuit_close_all_marked();
   circuit_close_all_marked();
 
 
   /** 7. And upload service descriptors if necessary. */
   /** 7. And upload service descriptors if necessary. */
-  if (can_complete_circuit && !we_are_hibernating()) {
+  if (can_complete_circuit && !net_is_disabled()) {
     rend_consider_services_upload(now);
     rend_consider_services_upload(now);
     rend_consider_descriptor_republication();
     rend_consider_descriptor_republication();
   }
   }
@@ -1489,7 +1489,8 @@ run_scheduled_events(time_t now)
 
 
   /** 9. and if we're a server, check whether our DNS is telling stories to
   /** 9. and if we're a server, check whether our DNS is telling stories to
    * us. */
    * us. */
-  if (public_server_mode(options) && time_to_check_for_correct_dns < now) {
+  if (!net_is_disabled() &&
+      public_server_mode(options) && time_to_check_for_correct_dns < now) {
     if (!time_to_check_for_correct_dns) {
     if (!time_to_check_for_correct_dns) {
       time_to_check_for_correct_dns = now + 60 + crypto_rand_int(120);
       time_to_check_for_correct_dns = now + 60 + crypto_rand_int(120);
     } else {
     } else {
@@ -1508,7 +1509,8 @@ run_scheduled_events(time_t now)
   }
   }
 
 
   /** 11. check the port forwarding app */
   /** 11. check the port forwarding app */
-  if (time_to_check_port_forwarding < now &&
+  if (!net_is_disabled() &&
+      time_to_check_port_forwarding < now &&
       options->PortForwarding &&
       options->PortForwarding &&
       is_server) {
       is_server) {
 #define PORT_FORWARDING_CHECK_INTERVAL 5
 #define PORT_FORWARDING_CHECK_INTERVAL 5
@@ -1520,7 +1522,7 @@ run_scheduled_events(time_t now)
   }
   }
 
 
   /** 11b. check pending unconfigured managed proxies */
   /** 11b. check pending unconfigured managed proxies */
-  if (pt_proxies_configuration_pending())
+  if (!net_is_disabled() && pt_proxies_configuration_pending())
     pt_configure_remaining_proxies();
     pt_configure_remaining_proxies();
 
 
   /** 11c. validate pluggable transports configuration if we need to */
   /** 11c. validate pluggable transports configuration if we need to */
@@ -1592,7 +1594,7 @@ second_elapsed_callback(periodic_timer_t *timer, void *arg)
   control_event_stream_bandwidth_used();
   control_event_stream_bandwidth_used();
 
 
   if (server_mode(options) &&
   if (server_mode(options) &&
-      !we_are_hibernating() &&
+      !net_is_disabled() &&
       seconds_elapsed > 0 &&
       seconds_elapsed > 0 &&
       can_complete_circuit &&
       can_complete_circuit &&
       stats_n_seconds_working / TIMEOUT_UNTIL_UNREACHABILITY_COMPLAINT !=
       stats_n_seconds_working / TIMEOUT_UNTIL_UNREACHABILITY_COMPLAINT !=
@@ -1793,7 +1795,8 @@ do_hup(void)
   /* retry appropriate downloads */
   /* retry appropriate downloads */
   router_reset_status_download_failures();
   router_reset_status_download_failures();
   router_reset_descriptor_download_failures();
   router_reset_descriptor_download_failures();
-  update_networkstatus_downloads(time(NULL));
+  if (!options->DisableNetwork)
+    update_networkstatus_downloads(time(NULL));
 
 
   /* We'll retry routerstatus downloads in about 10 seconds; no need to
   /* We'll retry routerstatus downloads in about 10 seconds; no need to
    * force a retry there. */
    * force a retry there. */

+ 4 - 0
src/or/or.h

@@ -3455,6 +3455,10 @@ typedef struct {
    * issue. */
    * issue. */
   int UserspaceIOCPBuffers;
   int UserspaceIOCPBuffers;
 
 
+  /** If 1, we accept and launch no external network connections, except on
+   * control ports. */
+  int DisableNetwork;
+
 } or_options_t;
 } or_options_t;
 
 
 /** Persistent state for an onion router, as saved to disk. */
 /** Persistent state for an onion router, as saved to disk. */

+ 10 - 2
src/or/router.c

@@ -780,7 +780,7 @@ check_whether_dirport_reachable(void)
   const or_options_t *options = get_options();
   const or_options_t *options = get_options();
   return !options->DirPort ||
   return !options->DirPort ||
          options->AssumeReachable ||
          options->AssumeReachable ||
-         we_are_hibernating() ||
+         net_is_disabled() ||
          can_reach_dir_port;
          can_reach_dir_port;
 }
 }
 
 
@@ -806,7 +806,7 @@ decide_to_advertise_dirport(const or_options_t *options, uint16_t dir_port)
     return 0;
     return 0;
   if (authdir_mode(options)) /* always publish */
   if (authdir_mode(options)) /* always publish */
     return dir_port;
     return dir_port;
-  if (we_are_hibernating())
+  if (net_is_disabled())
     return 0;
     return 0;
   if (!check_whether_dirport_reachable())
   if (!check_whether_dirport_reachable())
     return 0;
     return 0;
@@ -974,6 +974,14 @@ router_perform_bandwidth_test(int num_circs, time_t now)
   }
   }
 }
 }
 
 
+/** Return true iff our network is in some sense disabled: either we're
+ * hibernating, entering hibernation, or */
+int
+net_is_disabled(void)
+{
+  return get_options()->DisableNetwork || we_are_hibernating();
+}
+
 /** Return true iff we believe ourselves to be an authoritative
 /** Return true iff we believe ourselves to be an authoritative
  * directory server.
  * directory server.
  */
  */

+ 2 - 0
src/or/router.h

@@ -39,6 +39,8 @@ void router_orport_found_reachable(void);
 void router_dirport_found_reachable(void);
 void router_dirport_found_reachable(void);
 void router_perform_bandwidth_test(int num_circs, time_t now);
 void router_perform_bandwidth_test(int num_circs, time_t now);
 
 
+int net_is_disabled(void);
+
 int authdir_mode(const or_options_t *options);
 int authdir_mode(const or_options_t *options);
 int authdir_mode_v1(const or_options_t *options);
 int authdir_mode_v1(const or_options_t *options);
 int authdir_mode_v2(const or_options_t *options);
 int authdir_mode_v2(const or_options_t *options);

+ 5 - 1
src/or/routerlist.c

@@ -3244,7 +3244,7 @@ router_set_status(const char *digest, int up)
     log_debug(LD_DIR,"Marking router %s as %s.",
     log_debug(LD_DIR,"Marking router %s as %s.",
               node_describe(node), up ? "up" : "down");
               node_describe(node), up ? "up" : "down");
 #endif
 #endif
-    if (!up && node_is_me(node) && !we_are_hibernating())
+    if (!up && node_is_me(node) && !net_is_disabled())
       log_warn(LD_NET, "We just marked ourself as down. Are your external "
       log_warn(LD_NET, "We just marked ourself as down. Are your external "
                "addresses reachable?");
                "addresses reachable?");
     node->is_running = up;
     node->is_running = up;
@@ -4009,6 +4009,8 @@ signed_desc_digest_is_recognized(signed_descriptor_t *desc)
 void
 void
 update_all_descriptor_downloads(time_t now)
 update_all_descriptor_downloads(time_t now)
 {
 {
+  if (get_options()->DisableNetwork)
+    return;
   update_router_descriptor_downloads(now);
   update_router_descriptor_downloads(now);
   update_microdesc_downloads(now);
   update_microdesc_downloads(now);
   launch_dummy_descriptor_download_as_needed(now, get_options());
   launch_dummy_descriptor_download_as_needed(now, get_options());
@@ -4021,6 +4023,8 @@ routerlist_retry_directory_downloads(time_t now)
 {
 {
   router_reset_status_download_failures();
   router_reset_status_download_failures();
   router_reset_descriptor_download_failures();
   router_reset_descriptor_download_failures();
+  if (get_options()->DisableNetwork)
+    return;
   update_networkstatus_downloads(now);
   update_networkstatus_downloads(now);
   update_all_descriptor_downloads(now);
   update_all_descriptor_downloads(now);
 }
 }