[or-cvs] r20767: {tor} Update SVN to git master 0c70390dd7d006938def5cefc70b093b652 (in tor/trunk: . doc doc/spec src/or)

nickm at seul.org nickm at seul.org
Thu Oct 8 23:52:01 UTC 2009


Author: nickm
Date: 2009-10-08 19:52:01 -0400 (Thu, 08 Oct 2009)
New Revision: 20767

Removed:
   tor/trunk/doc/FAQ
Modified:
   tor/trunk/ChangeLog
   tor/trunk/doc/HACKING
   tor/trunk/doc/TODO.future
   tor/trunk/doc/spec/dir-spec.txt
   tor/trunk/doc/tor.1.in
   tor/trunk/src/or/circuitbuild.c
   tor/trunk/src/or/config.c
   tor/trunk/src/or/dirserv.c
   tor/trunk/src/or/ntmain.c
   tor/trunk/src/or/or.h
   tor/trunk/src/or/router.c
Log:
Update SVN to git master 0c70390dd7d006938def5cefc70b093b652ebf5f

Modified: tor/trunk/ChangeLog
===================================================================
--- tor/trunk/ChangeLog	2009-10-08 22:24:42 UTC (rev 20766)
+++ tor/trunk/ChangeLog	2009-10-08 23:52:01 UTC (rev 20767)
@@ -1,27 +1,43 @@
-Changes in version 0.2.2.4-alpha - 2009-??-??
+Changes in version 0.2.2.4-alpha - 2009-10-??
+  o Major bugfixes:
+    - Fix several more asserts in the circuit_build_times code, for
+      example one that causes Tor to fail to start once we have
+      accumulated 5000 build times in the state file. Bugfixes on
+      0.2.2.2-alpha; fixes bug 1108.
+
+  o New directory authorities:
+    - Move moria1 and Tonga to alternate IP addresses.
+
   o Minor features:
     - Log SSL state transitions at debug level during handshake, and
-      include SSL states in error messages.  This may help debug
-      future SSL handshake issues.
+      include SSL states in error messages. This may help debug future
+      SSL handshake issues.
     - Add a new "Handshake" log domain for activities that happen
       during the TLS handshake.
     - Revert to the "June 3 2009" ip-to-country file. The September one
       seems to have removed most US IP addresses.
+    - Directory authorities now reject Tor relays with versions less than
+      0.1.2.14. This step cuts out four relays from the current network,
+      none of which are very big.
 
-  o Code simplifications and refactoring:
-    - Revise our unit tests to use the "tinytest" framework, so we
-      can run tests in their own processes, have smarter setup/teardown
-      code, and so on.  The unit test code has moved to its own
-      subdirectory, and has been split into multiple modules.
-
   o Minor bugfixes:
     - Fix a couple of smaller issues with gathering statistics. Bugfixes
       on 0.2.2.1-alpha.
     - Fix two memory leaks in the error case of
       circuit_build_times_parse_state. Bugfix on 0.2.2.2-alpha.
     - Make it explicit that we can't overflow in
-      connection_ap_handshake_send_resolve. Bugfix on 0.0.7.1-1.
+      connection_ap_handshake_send_resolve. Bugfix on 0.0.7.1.
+    - Don't count one-hop circuits when we're estimating how long it
+      takes circuits to build on average. Otherwise we'll set our circuit
+      build timeout lower than we should. Bugfix on 0.2.2.2-alpha.
 
+  o Code simplifications and refactoring:
+    - Revise our unit tests to use the "tinytest" framework, so we
+      can run tests in their own processes, have smarter setup/teardown
+      code, and so on.  The unit test code has moved to its own
+      subdirectory, and has been split into multiple modules.
+
+
 Changes in version 0.2.2.3-alpha - 2009-09-23
   o Major bugfixes:
     - Fix an overzealous assert in our new circuit build timeout code.

Deleted: tor/trunk/doc/FAQ
===================================================================
--- tor/trunk/doc/FAQ	2009-10-08 22:24:42 UTC (rev 20766)
+++ tor/trunk/doc/FAQ	2009-10-08 23:52:01 UTC (rev 20767)
@@ -1,4 +0,0 @@
-This file is obsolete. Check out the online FAQ at the wiki
-for more accurate and complete questions and answers:
-http://wiki.noreply.org/wiki/TheOnionRouter/TorFAQ
-

Modified: tor/trunk/doc/HACKING
===================================================================
--- tor/trunk/doc/HACKING	2009-10-08 22:24:42 UTC (rev 20766)
+++ tor/trunk/doc/HACKING	2009-10-08 23:52:01 UTC (rev 20767)
@@ -150,7 +150,7 @@
 
 1.4. Log conventions
 
-  http://wiki.noreply.org/noreply/TheOnionRouter/TorFAQ#LogLevels
+  https://wiki.torproject.org/noreply/TheOnionRouter/TorFAQ#LogLevels
 
   No error or warning messages should be expected during normal OR or OP
   operation.

Modified: tor/trunk/doc/TODO.future
===================================================================
--- tor/trunk/doc/TODO.future	2009-10-08 22:24:42 UTC (rev 20766)
+++ tor/trunk/doc/TODO.future	2009-10-08 23:52:01 UTC (rev 20767)
@@ -272,7 +272,7 @@
       the RPM and other startup scripts should too?
     - add a "default.action" file to the tor/vidalia bundle so we can
       fix the https thing in the default configuration:
-      http://wiki.noreply.org/noreply/TheOnionRouter/TorFAQ#PrivoxyWeirdSSLPort
+      https://wiki.torproject.org/noreply/TheOnionRouter/TorFAQ#PrivoxyWeirdSSLPort
 
 
 =======================================================================

Modified: tor/trunk/doc/spec/dir-spec.txt
===================================================================
--- tor/trunk/doc/spec/dir-spec.txt	2009-10-08 22:24:42 UTC (rev 20766)
+++ tor/trunk/doc/spec/dir-spec.txt	2009-10-08 23:52:01 UTC (rev 20767)
@@ -1342,7 +1342,7 @@
     least one /8 address space.
 
    "Fast" -- A router is 'Fast' if it is active, and its bandwidth is
-   either in the top 7/8ths for known active routers or at least 100KB/s.
+   either in the top 7/8ths for known active routers or at least 20KB/s.
 
    "Guard" -- A router is a possible 'Guard' if its Weighted Fractional
    Uptime is at least the median for "familiar" active routers, and if

Modified: tor/trunk/doc/tor.1.in
===================================================================
--- tor/trunk/doc/tor.1.in	2009-10-08 22:24:42 UTC (rev 20766)
+++ tor/trunk/doc/tor.1.in	2009-10-08 23:52:01 UTC (rev 20767)
@@ -41,7 +41,7 @@
 \fB--nt-service\fP
 \fB--service [install|remove|start|stop]\fP
 Manage the Tor Windows NT/2000/XP service.  Current instructions can
-be found at http://wiki.noreply.org/noreply/TheOnionRouter/TorFAQ#WinNTService
+be found at https://wiki.torproject.org/noreply/TheOnionRouter/TorFAQ#WinNTService
 .LP
 .TP
 \fB--list-torrc-options\fP

Modified: tor/trunk/src/or/circuitbuild.c
===================================================================
--- tor/trunk/src/or/circuitbuild.c	2009-10-08 22:24:42 UTC (rev 20766)
+++ tor/trunk/src/or/circuitbuild.c	2009-10-08 23:52:01 UTC (rev 20767)
@@ -162,7 +162,7 @@
 }
 
 /**
- * Rewind our timeout history by n positions.
+ * Rewind our timeout history by n timeout positions.
  */
 static void
 circuit_build_times_rewind_history(circuit_build_times_t *cbt, int n)
@@ -170,6 +170,8 @@
   int i = 0;
 
   if (cbt->pre_timeouts) {
+    /* If we have pre-timeouts, it means we're not yet storing
+     * timeouts in our normal array. Only rewind the counter. */
     if (cbt->pre_timeouts > n) {
       cbt->pre_timeouts -= n;
     } else {
@@ -180,8 +182,6 @@
              "Pre-timeouts: %d", n, cbt->build_times_idx,
              cbt->total_build_times, cbt->pre_timeouts);
 
-    tor_assert(cbt->build_times_idx == 0);
-    tor_assert(cbt->total_build_times == 0);
     return;
   }
 
@@ -204,21 +204,18 @@
 }
 
 /**
- * Add a timeoutout value to the set of build times. Time units
- * are milliseconds
+ * Add a new timeout value <b>time</b> to the set of build times. Time
+ * units are milliseconds.
  *
- * circuit_build_times is a circular array, so loop around when
+ * circuit_build_times <b>cbt</a> is a circular array, so loop around when
  * array is full.
  */
 int
 circuit_build_times_add_time(circuit_build_times_t *cbt, build_time_t time)
 {
-  if (time > BUILD_TIME_MAX) {
-    log_notice(LD_CIRC,
-       "Circuit build time of %ums exceeds max. Capping at 65536ms", time);
-    time = BUILD_TIME_MAX;
-  } else if (time <= 0) {
-    log_err(LD_CIRC, "Circuit build time is %u!", time);
+  tor_assert(time <= BUILD_TIME_MAX);
+  if (time <= 0) {
+    log_warn(LD_CIRC, "Circuit build time is %u!", time);
     return -1;
   }
 
@@ -372,18 +369,29 @@
  * Stolen from http://en.wikipedia.org/wiki/Fisher\u2013Yates_shuffle
  */
 static void
-circuit_build_times_shuffle_array(circuit_build_times_t *cbt)
+circuit_build_times_shuffle_and_store_array(circuit_build_times_t *cbt,
+                                            build_time_t *raw_times,
+                                            int num_times)
 {
-   int n = cbt->total_build_times;
+  int n = num_times;
+  if (num_times > NCIRCUITS_TO_OBSERVE) {
+    log_notice(LD_CIRC, "Decreasing circuit_build_times size from %d to %d",
+               num_times, NCIRCUITS_TO_OBSERVE);
+  }
 
-   /* This code can only be run on a compact array */
-   tor_assert(cbt->total_build_times == cbt->build_times_idx);
-   while (n-- > 1) {
-     int k = crypto_rand_int(n + 1); /* 0 <= k <= n. */
-     build_time_t tmp = cbt->circuit_build_times[k];
-     cbt->circuit_build_times[k] = cbt->circuit_build_times[n];
-     cbt->circuit_build_times[n] = tmp;
-   }
+  /* This code can only be run on a compact array */
+  while (n-- > 1) {
+    int k = crypto_rand_int(n + 1); /* 0 <= k <= n. */
+    build_time_t tmp = raw_times[k];
+    raw_times[k] = raw_times[n];
+    raw_times[n] = tmp;
+  }
+
+  /* Since the times are now shuffled, take a random NCIRCUITS_TO_OBSERVE
+   * subset (ie the first NCIRCUITS_TO_OBSERVE values) */
+  for (n = 0; n < MIN(num_times, NCIRCUITS_TO_OBSERVE); n++) {
+    circuit_build_times_add_time(cbt, raw_times[n]);
+  }
 }
 
 /**
@@ -397,15 +405,15 @@
 circuit_build_times_parse_state(circuit_build_times_t *cbt,
                                 or_state_t *state, char **msg)
 {
-  int tot_values = 0, N = 0;
+  int tot_values = 0;
+  uint32_t loaded_cnt = 0, N = 0;
   config_line_t *line;
   int i;
+  build_time_t *loaded_times = tor_malloc(sizeof(build_time_t)
+                                          * state->TotalBuildTimes);
+  circuit_build_times_init(cbt);
   *msg = NULL;
-  circuit_build_times_init(cbt);
 
-  /* We don't support decreasing the table size yet */
-  tor_assert(state->TotalBuildTimes <= NCIRCUITS_TO_OBSERVE);
-
   for (line = state->BuildtimeHistogram; line; line = line->next) {
     smartlist_t *args = smartlist_create();
     smartlist_split_string(args, line->value, " ",
@@ -441,17 +449,30 @@
         break;
       }
 
+      if (loaded_cnt+count > state->TotalBuildTimes) {
+        log_warn(LD_CIRC,
+                 "Too many build times in state file. "
+                 "Stopping short before %d",
+                 loaded_cnt+count);
+        break;
+      }
+
       for (k = 0; k < count; k++) {
-        circuit_build_times_add_time(cbt, ms);
+        loaded_times[loaded_cnt++] = ms;
       }
       N++;
       SMARTLIST_FOREACH(args, char*, cp, tor_free(cp));
       smartlist_free(args);
     }
+  }
 
+  if (loaded_cnt != state->TotalBuildTimes) {
+    log_warn(LD_CIRC,
+            "Corrupt state file? Build times count mismatch. "
+            "Read %d, file says %d", loaded_cnt, state->TotalBuildTimes);
   }
 
-  circuit_build_times_shuffle_array(cbt);
+  circuit_build_times_shuffle_and_store_array(cbt, loaded_times, loaded_cnt);
 
   /* Verify that we didn't overwrite any indexes */
   for (i=0; i < NCIRCUITS_TO_OBSERVE; i++) {
@@ -462,9 +483,10 @@
   log_info(LD_CIRC,
            "Loaded %d/%d values from %d lines in circuit time histogram",
            tot_values, cbt->total_build_times, N);
-  tor_assert(cbt->total_build_times == state->TotalBuildTimes);
-  tor_assert(tot_values == cbt->total_build_times);
+  tor_assert(cbt->total_build_times == tot_values);
+  tor_assert(cbt->total_build_times <= NCIRCUITS_TO_OBSERVE);
   circuit_build_times_set_timeout(cbt);
+  tor_free(loaded_times);
   return *msg ? -1 : 0;
 }
 
@@ -602,10 +624,10 @@
              "%ums vs %lfms using Xm: %d a: %lf, q: %lf",
              gentime, cbt->timeout_ms, cbt->Xm, cbt->alpha, quantile_cutoff);
   } else if (gentime > BUILD_TIME_MAX) {
-    gentime = BUILD_TIME_MAX;
     log_info(LD_CIRC,
              "Generated a synthetic timeout larger than the max: %u",
              gentime);
+    gentime = BUILD_TIME_MAX;
   } else {
     log_info(LD_CIRC, "Generated synthetic circuit build time %u for timeout",
             gentime);
@@ -628,7 +650,7 @@
   // CircBuildTimeout = Xm*((1-0.8))^(-1/a))
   // ln(CircBuildTimeout) = ln(Xm)+ln(((1-0.8)))*(-1/a)
   // -ln(1-0.8)/(ln(CircBuildTimeout)-ln(Xm))=a
-  tor_assert(quantile > 0);
+  tor_assert(quantile >= 0);
   tor_assert(cbt->Xm > 0);
   cbt->alpha = ln(1.0-quantile)/(ln(cbt->Xm)-ln(timeout_ms));
   tor_assert(cbt->alpha > 0);
@@ -731,10 +753,8 @@
   if (cbt->liveness.network_last_live <= start_time &&
           start_time <= (now - cbt->timeout_ms/1000.0)) {
     cbt->liveness.nonlive_timeouts++;
-  }
-
-  /* Check for one-hop timeout */
-  if (did_onehop) {
+  } else if (did_onehop) {
+    /* Count a one-hop timeout */
     cbt->liveness.timeouts_after_firsthop[cbt->liveness.after_firsthop_idx]=1;
     cbt->liveness.after_firsthop_idx++;
     cbt->liveness.after_firsthop_idx %= RECENT_CIRCUITS;
@@ -801,7 +821,7 @@
     timeout_count += cbt->liveness.timeouts_after_firsthop[i];
   }
 
-  /* If 75% of our recent circuits are timing out after the first hop,
+  /* If 80% of our recent circuits are timing out after the first hop,
    * we need to re-estimate a new initial alpha and timeout. */
   if (timeout_count < MAX_RECENT_TIMEOUT_COUNT) {
     return 0;
@@ -1481,17 +1501,19 @@
     log_debug(LD_CIRC,"starting to send subsequent skin.");
     hop = onion_next_hop_in_cpath(circ->cpath);
     if (!hop) {
-      struct timeval end;
-      long timediff;
-      tor_gettimeofday(&end);
-      timediff = tv_mdiff(&circ->_base.highres_created, &end);
-      if (timediff > INT32_MAX)
-        timediff = INT32_MAX;
       /* done building the circuit. whew. */
       circuit_set_state(TO_CIRCUIT(circ), CIRCUIT_STATE_OPEN);
-      circuit_build_times_add_time(&circ_times, (build_time_t)timediff);
-      circuit_build_times_network_circ_success(&circ_times);
-      circuit_build_times_set_timeout(&circ_times);
+      if (!circ->build_state->onehop_tunnel) {
+        struct timeval end;
+        long timediff;
+        tor_gettimeofday(&end);
+        timediff = tv_mdiff(&circ->_base.highres_created, &end);
+        if (timediff > INT32_MAX)
+          timediff = INT32_MAX;
+        circuit_build_times_add_time(&circ_times, (build_time_t)timediff);
+        circuit_build_times_network_circ_success(&circ_times);
+        circuit_build_times_set_timeout(&circ_times);
+      }
       log_info(LD_CIRC,"circuit built!");
       circuit_reset_failure_count(0);
       if (circ->build_state->onehop_tunnel)

Modified: tor/trunk/src/or/config.c
===================================================================
--- tor/trunk/src/or/config.c	2009-10-08 22:24:42 UTC (rev 20766)
+++ tor/trunk/src/or/config.c	2009-10-08 23:52:01 UTC (rev 20767)
@@ -915,14 +915,14 @@
   int i;
   const char *dirservers[] = {
     "moria1 v1 orport=9001 v3ident=E2A2AF570166665D738736D0DD58169CC61D8A8B "
-      "128.31.0.34:9031 FFCB 46DB 1339 DA84 674C 70D7 CB58 6434 C437 0441",
+      "128.31.0.39:9031 FFCB 46DB 1339 DA84 674C 70D7 CB58 6434 C437 0441",
     "moria2 v1 orport=9002 128.31.0.34:9032 "
       "719B E45D E224 B607 C537 07D0 E214 3E2D 423E 74CF",
     "tor26 v1 orport=443 v3ident=14C131DFC5C6F93646BE72FA1401C02A8DF2E8B4 "
       "86.59.21.38:80 847B 1F85 0344 D787 6491 A548 92F9 0493 4E4E B85D",
     "dizum orport=443 v3ident=E8A9C45EDE6D711294FADF8E7951F4DE6CA56B58 "
       "194.109.206.212:80 7EA6 EAD6 FD83 083C 538F 4403 8BBF A077 587D D755",
-    "Tonga orport=443 bridge no-v2 82.94.251.206:80 "
+    "Tonga orport=443 bridge no-v2 82.94.251.203:80 "
       "4A0C CD2D DC79 9508 3D73 F5D6 6710 0C8A 5831 F16D",
     "ides orport=9090 no-v2 v3ident=27B6B5996C426270A5C95488AA5BCEB6BCC86956 "
       "216.224.124.114:9030 F397 038A DC51 3361 35E7 B80B D99C A384 4360 292B",
@@ -2696,6 +2696,8 @@
                          const config_line_t *listen_options)
 {
 #ifdef MS_WINDOWS
+  (void) port_option;
+  (void) listen_options;
   return 0; /* No port is too low for windows. */
 #else
   const config_line_t *l;

Modified: tor/trunk/src/or/dirserv.c
===================================================================
--- tor/trunk/src/or/dirserv.c	2009-10-08 22:24:42 UTC (rev 20766)
+++ tor/trunk/src/or/dirserv.c	2009-10-08 23:52:01 UTC (rev 20767)
@@ -371,10 +371,10 @@
               strmap_size(fingerprint_list->fp_by_name),
               digestmap_size(fingerprint_list->status_by_digest));
 
-  /* 0.1.1.17-rc was the first version that claimed to be stable, doesn't
-   * crash and drop circuits all the time, and is even vaguely compatible with
-   * the current network */
-  if (platform && !tor_version_as_new_as(platform,"0.1.1.17-rc")) {
+  /* Tor 0.1.2.x is pretty old, but there are a lot of them running still,
+   * and there aren't any critical relay-side vulnerabilities. Once more
+   * of them die off, we should raise this minimum to 0.2.0.x. */
+  if (platform && !tor_version_as_new_as(platform,"0.1.2.14")) {
     if (msg)
       *msg = "Tor version is far too old to work.";
     return FP_REJECT;

Modified: tor/trunk/src/or/ntmain.c
===================================================================
--- tor/trunk/src/or/ntmain.c	2009-10-08 22:24:42 UTC (rev 20766)
+++ tor/trunk/src/or/ntmain.c	2009-10-08 23:52:01 UTC (rev 20767)
@@ -6,6 +6,12 @@
 #define MAIN_PRIVATE
 #include "or.h"
 
+#ifdef HAVE_EVENT2_EVENT_H
+#include <event2/event.h>
+#else
+#include <event.h>
+#endif
+
 #include <tchar.h>
 #define GENSRV_SERVICENAME  TEXT("tor")
 #define GENSRV_DISPLAYNAME  TEXT("Tor Win32 Service")
@@ -218,7 +224,7 @@
           log_notice(LD_GENERAL,
                      "Got stop/shutdown request; shutting down cleanly.");
           service_status.dwCurrentState = SERVICE_STOP_PENDING;
-          event_loopexit(&exit_now);
+          event_base_loopexit(tor_libevent_get_base(), &exit_now);
           return;
   }
   service_fns.SetServiceStatus_fn(hStatus, &service_status);

Modified: tor/trunk/src/or/or.h
===================================================================
--- tor/trunk/src/or/or.h	2009-10-08 22:24:42 UTC (rev 20766)
+++ tor/trunk/src/or/or.h	2009-10-08 23:52:01 UTC (rev 20767)
@@ -2927,7 +2927,7 @@
  * This tells us to abandon timeout history and set
  * the timeout back to BUILD_TIMEOUT_INITIAL_VALUE.
  */
-#define MAX_RECENT_TIMEOUT_COUNT (lround(RECENT_CIRCUITS*0.75))
+#define MAX_RECENT_TIMEOUT_COUNT (lround(RECENT_CIRCUITS*0.8))
 
 /** Information about the state of our local network connection */
 typedef struct {

Modified: tor/trunk/src/or/router.c
===================================================================
--- tor/trunk/src/or/router.c	2009-10-08 22:24:42 UTC (rev 20766)
+++ tor/trunk/src/or/router.c	2009-10-08 23:52:01 UTC (rev 20767)
@@ -1826,9 +1826,9 @@
 /** Load the contents of <b>filename</b>, find the last line starting with
  * <b>end_line</b>, ensure that its timestamp is not more than 25 hours in
  * the past or more than 1 hour in the future with respect to <b>now</b>,
- * and write the file contents starting with that line to **<b>out</b>.
- * Return 1 for success, 0 if the file does not exist or does not contain
- * a line matching these criteria, or -1 for failure. */
+ * and write the file contents starting with that line to *<b>out</b>.
+ * Return 1 for success, 0 if the file does not exist, or -1 if the file
+ * does not contain a line matching these criteria or other failure. */
 static int
 load_stats_file(const char *filename, const char *end_line, time_t now,
                 char **out)
@@ -1903,11 +1903,11 @@
 
   if (options->ExtraInfoStatistics && write_stats_to_extrainfo) {
     char *contents = NULL;
-    time_t since = time(NULL) - (24*60*60);
+    time_t now = time(NULL);
     log_info(LD_GENERAL, "Adding stats to extra-info descriptor.");
     if (options->DirReqStatistics &&
         load_stats_file("stats"PATH_SEPARATOR"dirreq-stats",
-                        "dirreq-stats-end", since, &contents) > 0) {
+                        "dirreq-stats-end", now, &contents) > 0) {
       size_t pos = strlen(s);
       if (strlcpy(s + pos, contents, maxlen - strlen(s)) !=
           strlen(contents)) {
@@ -1919,7 +1919,7 @@
     }
     if (options->EntryStatistics &&
         load_stats_file("stats"PATH_SEPARATOR"entry-stats",
-                        "entry-stats-end", since, &contents) > 0) {
+                        "entry-stats-end", now, &contents) > 0) {
       size_t pos = strlen(s);
       if (strlcpy(s + pos, contents, maxlen - strlen(s)) !=
           strlen(contents)) {
@@ -1931,7 +1931,7 @@
     }
     if (options->CellStatistics &&
         load_stats_file("stats"PATH_SEPARATOR"buffer-stats",
-                        "cell-stats-end", since, &contents) > 0) {
+                        "cell-stats-end", now, &contents) > 0) {
       size_t pos = strlen(s);
       if (strlcpy(s + pos, contents, maxlen - strlen(s)) !=
           strlen(contents)) {
@@ -1943,7 +1943,7 @@
     }
     if (options->ExitPortStatistics &&
         load_stats_file("stats"PATH_SEPARATOR"exit-stats",
-                        "exit-stats-end", since, &contents) > 0) {
+                        "exit-stats-end", now, &contents) > 0) {
       size_t pos = strlen(s);
       if (strlcpy(s + pos, contents, maxlen - strlen(s)) !=
           strlen(contents)) {



More information about the tor-commits mailing list