From af42f9b9125fb3f50f7383e63fb02bab1df82db9 Mon Sep 17 00:00:00 2001
From: George Kadianakis <desnacked@riseup.net>
Date: Wed, 12 Mar 2014 20:25:05 -0700
Subject: [PATCH] Don't do directory fetches before all PTs have been
 configured.

---
 src/or/microdesc.c     |  2 +-
 src/or/networkstatus.c | 36 ++++++++++++++++++++++++++++++------
 src/or/networkstatus.h |  2 +-
 src/or/nodelist.c      |  8 ++++----
 src/or/routerlist.c    |  6 +++---
 5 files changed, 39 insertions(+), 15 deletions(-)

diff --git a/src/or/microdesc.c b/src/or/microdesc.c
index 90ac0ac..1f12347 100644
--- a/src/or/microdesc.c
+++ b/src/or/microdesc.c
@@ -725,7 +725,7 @@ update_microdesc_downloads(time_t now)
   smartlist_t *missing;
   digestmap_t *pending;
 
-  if (should_delay_dir_fetches(options))
+  if (should_delay_dir_fetches(options, NULL))
     return;
   if (directory_too_idle_to_fetch_descriptors(options, now))
     return;
diff --git a/src/or/networkstatus.c b/src/or/networkstatus.c
index 1b5c6db..bcadc52 100644
--- a/src/or/networkstatus.c
+++ b/src/or/networkstatus.c
@@ -31,6 +31,7 @@
 #include "router.h"
 #include "routerlist.h"
 #include "routerparse.h"
+#include "transports.h"
 
 /* For tracking v2 networkstatus documents.  Only caches do this now. */
 
@@ -1380,14 +1381,37 @@ update_consensus_networkstatus_fetch_time(time_t now)
 
 /** Return 1 if there's a reason we shouldn't try any directory
  * fetches yet (e.g. we demand bridges and none are yet known).
- * Else return 0. */
+ * Else return 0.
+
+ * If we return 1 and <b>msg_out</b> is provided, set <b>msg_out</b>
+ * to an explanation of why directory fetches are delayed. (If we
+ * return 0, we set msg_out to NULL.)
+ */
 int
-should_delay_dir_fetches(const or_options_t *options)
+should_delay_dir_fetches(const or_options_t *options, const char **msg_out)
 {
-  if (options->UseBridges && !any_bridge_descriptors_known()) {
-    log_info(LD_DIR, "delaying dir fetches (no running bridges known)");
-    return 1;
+  if (msg_out) {
+    *msg_out = NULL;
   }
+
+  if (options->UseBridges) {
+    if (!any_bridge_descriptors_known()) {
+      if (msg_out) {
+        *msg_out = "No running bridges";
+      }
+      log_info(LD_DIR, "Delaying dir fetches (no running bridges known)");
+      return 1;
+    }
+
+    if (pt_proxies_configuration_pending()) {
+      if (msg_out) {
+        *msg_out = "Pluggable transport proxies still configuring";
+      }
+      log_info(LD_DIR, "Delaying dir fetches (pt proxies still configuring)");
+      return 1;
+    }
+  }
+
   return 0;
 }
 
@@ -1397,7 +1421,7 @@ void
 update_networkstatus_downloads(time_t now)
 {
   const or_options_t *options = get_options();
-  if (should_delay_dir_fetches(options))
+  if (should_delay_dir_fetches(options, NULL))
     return;
   if (authdir_mode_any_main(options) || options->FetchV2Networkstatus)
     update_v2_networkstatus_cache_downloads(now);
diff --git a/src/or/networkstatus.h b/src/or/networkstatus.h
index 761f8e7..f50f6f1 100644
--- a/src/or/networkstatus.h
+++ b/src/or/networkstatus.h
@@ -69,7 +69,7 @@ int networkstatus_nickname_is_unnamed(const char *nickname);
 void networkstatus_consensus_download_failed(int status_code,
                                              const char *flavname);
 void update_consensus_networkstatus_fetch_time(time_t now);
-int should_delay_dir_fetches(const or_options_t *options);
+int should_delay_dir_fetches(const or_options_t *options,const char **msg_out);
 void update_networkstatus_downloads(time_t now);
 void update_certificate_downloads(time_t now);
 int consensus_is_waiting_for_certs(void);
diff --git a/src/or/nodelist.c b/src/or/nodelist.c
index 178f084..600a1fd 100644
--- a/src/or/nodelist.c
+++ b/src/or/nodelist.c
@@ -1439,6 +1439,7 @@ update_router_have_minimum_dir_info(void)
   const networkstatus_t *consensus =
     networkstatus_get_reasonably_live_consensus(now,usable_consensus_flavor());
   int using_md;
+  const char *delay_fetches_msg = NULL;
 
   if (!consensus) {
     if (!networkstatus_get_latest_consensus())
@@ -1451,10 +1452,9 @@ update_router_have_minimum_dir_info(void)
     goto done;
   }
 
-  if (should_delay_dir_fetches(get_options())) {
-    log_notice(LD_DIR, "no known bridge descriptors running yet; stalling");
-    strlcpy(dir_info_status, "No live bridge descriptors.",
-            sizeof(dir_info_status));
+  if (should_delay_dir_fetches(get_options(), &delay_fetches_msg)) {
+    log_notice(LD_DIR, "Delaying dir fetches: %s", delay_fetches_msg);
+    strlcpy(dir_info_status, "%s",  sizeof(dir_info_status));
     res = 0;
     goto done;
   }
diff --git a/src/or/routerlist.c b/src/or/routerlist.c
index cb39729..d78c7bb 100644
--- a/src/or/routerlist.c
+++ b/src/or/routerlist.c
@@ -684,7 +684,7 @@ authority_certs_fetch_missing(networkstatus_t *status, time_t now)
   char id_digest_str[2*DIGEST_LEN+1];
   char sk_digest_str[2*DIGEST_LEN+1];
 
-  if (should_delay_dir_fetches(get_options()))
+  if (should_delay_dir_fetches(get_options(), NULL))
     return;
 
   pending_cert = fp_pair_map_new();
@@ -4901,7 +4901,7 @@ void
 update_router_descriptor_downloads(time_t now)
 {
   const or_options_t *options = get_options();
-  if (should_delay_dir_fetches(options))
+  if (should_delay_dir_fetches(options, NULL))
     return;
   if (!we_fetch_router_descriptors(options))
     return;
@@ -4925,7 +4925,7 @@ update_extrainfo_downloads(time_t now)
   int n_no_ei = 0, n_pending = 0, n_have = 0, n_delay = 0;
   if (! options->DownloadExtraInfo)
     return;
-  if (should_delay_dir_fetches(options))
+  if (should_delay_dir_fetches(options, NULL))
     return;
   if (!router_have_minimum_dir_info())
     return;
-- 
1.8.1.2

From 1a3eb5c72dd0feb43a542ca465c57dd0801ff7cc Mon Sep 17 00:00:00 2001
From: George Kadianakis <desnacked@riseup.net>
Date: Tue, 8 Apr 2014 16:59:46 +0100
Subject: [PATCH 1/4] Don't halt bootstrap to figure out if we should restart
 PT proxies.

Instead, figure out if we should restart PT proxies _immediately_ after
we re-read the config file.
---
 changes/bug11156    | 5 +++++
 src/or/config.c     | 6 ++++++
 src/or/transports.c | 3 +--
 3 files changed, 12 insertions(+), 2 deletions(-)
 create mode 100644 changes/bug11156

diff --git a/changes/bug11156 b/changes/bug11156
new file mode 100644
index 0000000..bb20ed1e
--- /dev/null
+++ b/changes/bug11156
@@ -0,0 +1,5 @@
+  o Minor bugfixes (clients):
+    - Fix a bug where a client-side Tor with pluggable transports
+      would take 60 seconds to bootstrap if a config re-read was
+      triggered at just the right timing during bootstrap. Refixes bug
+      11156; bugfix on 0.2.5.3-alpha.
\ No newline at end of file
diff --git a/src/or/config.c b/src/or/config.c
index dbf643c..c2d6545 100644
--- a/src/or/config.c
+++ b/src/or/config.c
@@ -1433,6 +1433,12 @@ options_act(const or_options_t *old_options)
   sweep_transport_list();
   sweep_proxy_list();
 
+  /* Start the PT proxy configuration. By doing this configuration
+     here, we also figure out which proxies need to be restarted and
+     which not. */
+  if (pt_proxies_configuration_pending())
+    pt_configure_remaining_proxies();
+
   /* Bail out at this point if we're not going to be a client or server:
    * we want to not fork, and to log stuff to stderr. */
   if (!running_tor)
diff --git a/src/or/transports.c b/src/or/transports.c
index 7e496fe..e1876d6 100644
--- a/src/or/transports.c
+++ b/src/or/transports.c
@@ -534,8 +534,7 @@ launch_managed_proxy(managed_proxy_t *mp)
 }
 
 /** Check if any of the managed proxies we are currently trying to
- *  configure have anything new to say. This is called from
- *  run_scheduled_events(). */
+ *  configure has anything new to say. */
 void
 pt_configure_remaining_proxies(void)
 {
-- 
1.8.1.2

From 4719a2f5248b8cf6d70daef91fd1cf9fd65628f4 Mon Sep 17 00:00:00 2001
From: George Kadianakis <desnacked@riseup.net>
Date: Mon, 21 Apr 2014 14:17:35 +0300
Subject: [PATCH 4/4] fixup! Don't halt bootstrap to figure out if we should
 restart PT proxies.

---
 src/or/config.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/or/config.c b/src/or/config.c
index c2d6545..551b09f 100644
--- a/src/or/config.c
+++ b/src/or/config.c
@@ -1436,7 +1436,7 @@ options_act(const or_options_t *old_options)
   /* Start the PT proxy configuration. By doing this configuration
      here, we also figure out which proxies need to be restarted and
      which not. */
-  if (pt_proxies_configuration_pending())
+  if (pt_proxies_configuration_pending() && !net_is_disabled())
     pt_configure_remaining_proxies();
 
   /* Bail out at this point if we're not going to be a client or server:
-- 
1.8.1.2

From dfcbc4500aad07a641e9e856d442c848d86d2c7e Mon Sep 17 00:00:00 2001
From: George Kadianakis <desnacked@riseup.net>
Date: Thu, 1 May 2014 17:32:29 +0100
Subject: [PATCH] fixup! Fix a misuse of strlcpy() introduced by the #11156
 patch.

---
 changes/bug11654 | 4 ++++
 1 file changed, 4 insertions(+)
 create mode 100644 changes/bug11654

diff --git a/changes/bug11654 b/changes/bug11654
new file mode 100644
index 0000000..97c70b2
--- /dev/null
+++ b/changes/bug11654
@@ -0,0 +1,4 @@
+  o Minor bugfixes:
+    - Fix a broken log message about delayed directory fetches that
+      was caused by a misuse of strlcpy(). Fixes bug 11654; bugfix on
+      0.2.5.3-alpha.
-- 
1.9.1

