aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xautogen.sh12
-rw-r--r--changes/46644
-rw-r--r--changes/bug58235
-rw-r--r--changes/bug77085
-rw-r--r--changes/bug780211
-rw-r--r--changes/bug80934
-rw-r--r--changes/double-0-check8
-rw-r--r--changes/feature59568
-rw-r--r--changes/rename_log_75994
-rw-r--r--changes/rename_queue_macros6
-rw-r--r--changes/timed_onionqueue11
-rw-r--r--configure.ac24
-rw-r--r--doc/tor.1.txt60
-rw-r--r--src/common/address.c4
-rw-r--r--src/common/compat.h4
-rw-r--r--src/common/compat_libevent.c53
-rw-r--r--src/common/crypto.c11
-rw-r--r--src/common/crypto_curve25519.c2
-rw-r--r--src/common/procmon.c2
-rw-r--r--src/common/torlog.h1
-rw-r--r--src/common/tortls.c20
-rw-r--r--src/common/util.c5
-rw-r--r--src/ext/README4
-rw-r--r--src/ext/eventdns.c112
-rw-r--r--src/ext/tor_queue.h341
-rw-r--r--src/or/buffers.c6
-rw-r--r--src/or/channel.c136
-rw-r--r--src/or/channel.h4
-rw-r--r--src/or/circuitbuild.c786
-rw-r--r--src/or/circuitbuild.h4
-rw-r--r--src/or/circuitlist.c10
-rw-r--r--src/or/circuitstats.c10
-rw-r--r--src/or/circuituse.c38
-rw-r--r--src/or/config.c94
-rw-r--r--src/or/connection.c30
-rw-r--r--src/or/connection_edge.c17
-rw-r--r--src/or/connection_or.c4
-rw-r--r--src/or/control.c2
-rw-r--r--src/or/cpuworker.c169
-rw-r--r--src/or/cpuworker.h5
-rw-r--r--src/or/directory.c29
-rw-r--r--src/or/dirserv.c2
-rw-r--r--src/or/dirvote.c2
-rw-r--r--src/or/dns.c16
-rw-r--r--src/or/entrynodes.c48
-rw-r--r--src/or/entrynodes.h7
-rw-r--r--src/or/geoip.c194
-rw-r--r--src/or/geoip.h7
-rw-r--r--src/or/main.c37
-rw-r--r--src/or/networkstatus.c25
-rw-r--r--src/or/networkstatus.h1
-rw-r--r--src/or/nodelist.c156
-rw-r--r--src/or/onion.c180
-rw-r--r--src/or/or.h81
-rw-r--r--src/or/policies.c4
-rw-r--r--src/or/relay.c10
-rw-r--r--src/or/rendclient.c9
-rw-r--r--src/or/rendservice.c22
-rw-r--r--src/or/rephist.c8
-rw-r--r--src/or/router.c46
-rw-r--r--src/or/routerlist.c94
-rw-r--r--src/or/routerlist.h4
-rw-r--r--src/or/routerparse.c4
-rw-r--r--src/or/routerset.c2
-rw-r--r--src/or/statefile.c1
-rw-r--r--src/or/status.c2
-rw-r--r--src/test/test.c37
-rw-r--r--src/test/test_util.c16
-rw-r--r--src/tools/tor-gencert.c7
-rw-r--r--src/win32/orconfig.h3
70 files changed, 2024 insertions, 1066 deletions
diff --git a/autogen.sh b/autogen.sh
index 0592f16c2e..efa2251c24 100755
--- a/autogen.sh
+++ b/autogen.sh
@@ -1,7 +1,17 @@
#!/bin/sh
if [ -x "`which autoreconf 2>/dev/null`" ] ; then
- exec autoreconf -ivf
+ opt="-if"
+
+ for i in $@; do
+ case "$i" in
+ -v)
+ opt=$opt"v"
+ ;;
+ esac
+ done
+
+ exec autoreconf $opt
fi
set -e
diff --git a/changes/4664 b/changes/4664
new file mode 100644
index 0000000000..eb81da925e
--- /dev/null
+++ b/changes/4664
@@ -0,0 +1,4 @@
+ o Minor features (build):
+ - Do not report status verbosely from autogen.sh unless the -v flag
+ is specified. Fixes issue 4664. Patch from Onizuka.
+
diff --git a/changes/bug5823 b/changes/bug5823
new file mode 100644
index 0000000000..d76b590889
--- /dev/null
+++ b/changes/bug5823
@@ -0,0 +1,5 @@
+ o Removed featurs:
+ - Stop exporting estimates of v2 and v3 directory traffic shares
+ in extrainfo documents. They were unneeded and sometimes inaccurate.
+ Also stop exporting any v2 directory request statistics. Resolves
+ ticket 5823.
diff --git a/changes/bug7708 b/changes/bug7708
new file mode 100644
index 0000000000..e272adf227
--- /dev/null
+++ b/changes/bug7708
@@ -0,0 +1,5 @@
+ o Major bugfixes:
+ - When a TLS write is partially successful but incomplete, remember
+ that the flushed part has been flushed, and notice that bytes were
+ actually written. Reported and fixed pseudonymously. Fixes bug
+ 7708; bugfix on Tor 0.1.0.5-rc.
diff --git a/changes/bug7802 b/changes/bug7802
new file mode 100644
index 0000000000..9bc0f36fe1
--- /dev/null
+++ b/changes/bug7802
@@ -0,0 +1,11 @@
+ o Minor features:
+ - Path Use Bias: Perform separate accounting for successful circuit use.
+ Separate statistics on stream attempt versus success rates are kept
+ for each guard. Configurable thresholds are provided to determine
+ when to emit log messages or disable use of guards that fail too
+ many stream attempts.
+ o Minor bugfixes:
+ - Remove a source of rounding error during path bias count scaling.
+ - Don't count cannibalized circuits as used for path bias until we
+ actually try to use them.
+ - Fix circuit_package_relay_cell warning message about n_chan==NULL.
diff --git a/changes/bug8093 b/changes/bug8093
new file mode 100644
index 0000000000..cbddfd990f
--- /dev/null
+++ b/changes/bug8093
@@ -0,0 +1,4 @@
+ o Minor features:
+ - Improve the log message when "Bug/attack: unexpected sendme cell
+ from client" occurs, to help us track bug 8093.
+
diff --git a/changes/double-0-check b/changes/double-0-check
new file mode 100644
index 0000000000..74554cd272
--- /dev/null
+++ b/changes/double-0-check
@@ -0,0 +1,8 @@
+ o Build improvements (bizarre platform detection):
+ - Try to detect it if we are ever building on a platform where
+ memset(...,0,...) does not set the value of a double to 0.0. Such
+ platforms are permitted by the C standard, though in practice
+ they're pretty rare (since IEEE 754 is nigh-ubiquitous). We don't
+ currently support them, but it's better to detect them and fail
+ than to perform erroneously.
+
diff --git a/changes/feature5956 b/changes/feature5956
new file mode 100644
index 0000000000..2e18810588
--- /dev/null
+++ b/changes/feature5956
@@ -0,0 +1,8 @@
+ o Major features:
+ - When deciding whether we have enough descriptors to build circuits,
+ instead of looking at raw circuit counts, look at which fraction of
+ (bandwidth-weighted) paths we're able to build. This approach keeps
+ clients from building circuits if their paths are likely to stand out
+ statistically. The default fraction of paths needed is taken from the
+ consensus directory; you can override it with the new
+ PathsNeededToBuildCircuits option. Fixes issue 5956.
diff --git a/changes/rename_log_7599 b/changes/rename_log_7599
new file mode 100644
index 0000000000..38e843f066
--- /dev/null
+++ b/changes/rename_log_7599
@@ -0,0 +1,4 @@
+ o Code simplification and refactoring:
+ - Rename Tor's logging function log() to tor_log(), to avoid conflicts
+ with the natural logarithm function from the system libm. Resolves
+ ticket 7599.
diff --git a/changes/rename_queue_macros b/changes/rename_queue_macros
new file mode 100644
index 0000000000..29373ac234
--- /dev/null
+++ b/changes/rename_queue_macros
@@ -0,0 +1,6 @@
+ o Major bugfixes:
+ - Rename all macros in our local copy of queue.h to begin with TOR_;
+ this seems the only good way to permanently prevent conflicts
+ with queue.h on various operating systems. Fixes bug 8107; bugfix on
+ 0.2.4.6-alpha.
+
diff --git a/changes/timed_onionqueue b/changes/timed_onionqueue
new file mode 100644
index 0000000000..fe54d78ac8
--- /dev/null
+++ b/changes/timed_onionqueue
@@ -0,0 +1,11 @@
+ o Minor features (relay):
+ - Instead of limiting the number of queued onionskins to a configured,
+ hard-to-configure number, we limit the size of the queue based on how
+ many we expect to be able to process in a given amount of time. We
+ estimate the time it will take to process an onionskin based on average
+ processing time of previous onionskins. Closes ticket 7291. You'll
+ never have to configure MaxOnionsPending again.
+
+ - We compute the overhead from passing onionskins back and forth to
+ cpuworkers, and report it when dumping statistics in response to
+ SIGUSR1.
diff --git a/configure.ac b/configure.ac
index f047ab9027..6c4a0792fe 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1033,6 +1033,30 @@ if test "$tor_cv_null_is_zero" != no; then
[Define to 1 iff memset(0) sets pointers to NULL])
fi
+AC_CACHE_CHECK([whether memset(0) sets doubles to 0.0], tor_cv_dbl0_is_zero,
+[AC_RUN_IFELSE([AC_LANG_SOURCE(
+[[#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#ifdef HAVE_STDDEF_H
+#include <stddef.h>
+#endif
+int main () { double d1,d2; d1=0; memset(&d2,0,sizeof(d2));
+return memcmp(&d1,&d2,sizeof(d1))?1:0; }]])],
+ [tor_cv_dbl0_is_zero=yes],
+ [tor_cv_dbl0_is_zero=no],
+ [tor_cv_dbl0_is_zero=cross])])
+
+if test "$tor_cv_dbl0_is_zero" = cross ; then
+ # Cross-compiling; let's hope that the target isn't raving mad.
+ AC_MSG_NOTICE([Cross-compiling: we'll assume that 0.0 can be represented as a sequence of 0-valued bytes.])
+fi
+
+if test "$tor_cv_dbl0_is_zero" != no; then
+ AC_DEFINE([DOUBLE_0_REP_IS_ZERO_BYTES], 1,
+ [Define to 1 iff memset(0) sets doubles to 0.0])
+fi
+
# And what happens when we malloc zero?
AC_CACHE_CHECK([whether we can malloc(0) safely.], tor_cv_malloc_zero_works,
[AC_RUN_IFELSE([AC_LANG_SOURCE(
diff --git a/doc/tor.1.txt b/doc/tor.1.txt
index 947322161a..a15aecb488 100644
--- a/doc/tor.1.txt
+++ b/doc/tor.1.txt
@@ -1250,20 +1250,11 @@ The following options are useful only for clients (that is, if
**PathBiasDropGuards** __NUM__ +
-**PathBiasScaleThreshold** __NUM__ +
-
-**PathBiasMultFactor** __NUM__ +
-
-**PathBiasScaleFactor** __NUM__ +
-
-**PathBiasUseCloseCounts** __NUM__::
+**PathBiasScaleThreshold** __NUM__::
These options override the default behavior of Tor's (**currently
experimental**) path bias detection algorithm. To try to find broken or
misbehaving guard nodes, Tor looks for nodes where more than a certain
- fraction of circuits through that guard fail to get built. If
- PathBiasUseCloseCounts is set to 1 (the default), usage-based accounting is
- performed, and circuits that fail to carry streams are also counted as
- failures. +
+ fraction of circuits through that guard fail to get built.
+
The PathBiasCircThreshold option controls how many circuits we need to build
through a guard before we make these checks. The PathBiasNoticeRate,
@@ -1273,14 +1264,35 @@ The following options are useful only for clients (that is, if
is set to 1, we disable use of that guard. +
+
When we have seen more than PathBiasScaleThreshold
- circuits through a guard, we scale our observations by
- PathBiasMultFactor/PathBiasScaleFactor, so that new observations don't get
- swamped by old ones. +
+ circuits through a guard, we scale our observations by 0.5 (governed by
+ the consensus) so that new observations don't get swamped by old ones. +
+
By default, or if a negative value is provided for one of these options,
Tor uses reasonable defaults from the networkstatus consensus document.
If no defaults are available there, these options default to 150, .70,
- .50, .30, 0, 300, 1, and 2 respectively.
+ .50, .30, 0, and 300 respectively.
+
+**PathBiasUseThreshold** __NUM__ +
+
+**PathBiasNoticeUseRate** __NUM__ +
+
+**PathBiasExtremeUseRate** __NUM__ +
+
+**PathBiasScaleUseThreshold** __NUM__::
+ Similar to the above options, these options override the default behavior
+ of Tor's (**currently experimental**) path use bias detection algorithm.
+ +
+ Where as the path bias parameters govern thresholds for successfully
+ building circuits, these four path use bias parameters govern thresholds
+ only for circuit usage. Circuits which receive no stream usage
+ are not counted by this detection algorithm. A used circuit is considered
+ successful if it is capable of carrying streams or otherwise receiving
+ well-formed responses to RELAY cells.
+ +
+ By default, or if a negative value is provided for one of these options,
+ Tor uses reasonable defaults from the networkstatus consensus document.
+ If no defaults are available there, these options default to 20, .90,
+ .70, and 100, respectively.
**ClientUseIPv6** **0**|**1**::
If this option is set to 1, Tor might connect to entry nodes over
@@ -1294,6 +1306,18 @@ The following options are useful only for clients (that is, if
things may influence the choice. This option breaks a tie to the
favor of IPv6. (Default: 0)
+**PathsNeededToBuildCircuits** __NUM__::
+ Tor clients don't build circuits for user traffic until they know
+ about enough of the network so that they could potentially construct
+ enough of the possible paths through the network. If this option
+ is set to a fraction between 0.25 and 0.95, Tor won't build circuits
+ until it has enough descriptors or microdescriptors to construct
+ that fraction of possible paths. Note that setting this option too low
+ can make your Tor client less anonymous, and setting it too high can
+ prevent your Tor client from bootstrapping. If this option is negative,
+ Tor will use a default value chosen by the directory
+ authorities. (Default: -1.)
+
SERVER OPTIONS
--------------
@@ -1388,9 +1412,9 @@ is non-zero):
If set, and we are an exit node, allow clients to use us for IPv6
traffic. (Default: 0)
-**MaxOnionsPending** __NUM__::
- If you have more than this number of onionskins queued for decrypt, reject
- new ones. (Default: 100)
+**MaxOnionQueueDelay** __NUM__ [**msec**|**second**]::
+ If we have more onionskins queued for processing than we can process in
+ this amount of time, reject new ones. (Default: 1750 msec)
**MyFamily** __node__,__node__,__...__::
Declare that this Tor server is controlled or administered by a group or
diff --git a/src/common/address.c b/src/common/address.c
index 3529b10c1a..6fc9fb3c47 100644
--- a/src/common/address.c
+++ b/src/common/address.c
@@ -1270,14 +1270,14 @@ get_interface_addresses_raw(int severity)
/* This interface, AFAICT, only supports AF_INET addresses */
fd = socket(AF_INET, SOCK_DGRAM, 0);
if (fd < 0) {
- log(severity, LD_NET, "socket failed: %s", strerror(errno));
+ tor_log(severity, LD_NET, "socket failed: %s", strerror(errno));
goto done;
}
/* Guess how much space we need. */
ifc.ifc_len = sz = 15*1024;
ifc.ifc_ifcu.ifcu_req = tor_malloc(sz);
if (ioctl(fd, SIOCGIFCONF, &ifc) < 0) {
- log(severity, LD_NET, "ioctl failed: %s", strerror(errno));
+ tor_log(severity, LD_NET, "ioctl failed: %s", strerror(errno));
close(fd);
goto done;
}
diff --git a/src/common/compat.h b/src/common/compat.h
index 25293a4ed6..d2944e6f48 100644
--- a/src/common/compat.h
+++ b/src/common/compat.h
@@ -74,6 +74,10 @@
#error "It seems your platform does not represent NULL as zero. We can't cope."
#endif
+#ifndef DOUBLE_0_REP_IS_ZERO_BYTES
+#error "It seems your platform does not represent 0.0 as zeros. We can't cope."
+#endif
+
#if 'a'!=97 || 'z'!=122 || 'A'!=65 || ' '!=32
#error "It seems that you encode characters in something other than ASCII."
#endif
diff --git a/src/common/compat_libevent.c b/src/common/compat_libevent.c
index fc5b0accfe..200a7c65fb 100644
--- a/src/common/compat_libevent.c
+++ b/src/common/compat_libevent.c
@@ -76,19 +76,19 @@ libevent_logging_callback(int severity, const char *msg)
}
switch (severity) {
case _EVENT_LOG_DEBUG:
- log(LOG_DEBUG, LD_NOCB|LD_NET, "Message from libevent: %s", buf);
+ log_debug(LD_NOCB|LD_NET, "Message from libevent: %s", buf);
break;
case _EVENT_LOG_MSG:
- log(LOG_INFO, LD_NOCB|LD_NET, "Message from libevent: %s", buf);
+ log_info(LD_NOCB|LD_NET, "Message from libevent: %s", buf);
break;
case _EVENT_LOG_WARN:
- log(LOG_WARN, LD_NOCB|LD_GENERAL, "Warning from libevent: %s", buf);
+ log_warn(LD_NOCB|LD_GENERAL, "Warning from libevent: %s", buf);
break;
case _EVENT_LOG_ERR:
- log(LOG_ERR, LD_NOCB|LD_GENERAL, "Error from libevent: %s", buf);
+ log_err(LD_NOCB|LD_GENERAL, "Error from libevent: %s", buf);
break;
default:
- log(LOG_WARN, LD_NOCB|LD_GENERAL, "Message [%d] from libevent: %s",
+ log_warn(LD_NOCB|LD_GENERAL, "Message [%d] from libevent: %s",
severity, buf);
break;
}
@@ -187,13 +187,6 @@ tor_libevent_initialize(tor_libevent_cfg *torcfg)
/* some paths below don't use torcfg, so avoid unused variable warnings */
(void)torcfg;
-#ifdef __APPLE__
- if (MACOSX_KQUEUE_IS_BROKEN ||
- tor_get_libevent_version(NULL) < V_OLD(1,1,'b')) {
- setenv("EVENT_NOKQUEUE","1",1);
- }
-#endif
-
#ifdef HAVE_EVENT2_EVENT_H
{
int attempts = 0;
@@ -268,13 +261,13 @@ tor_libevent_initialize(tor_libevent_cfg *torcfg)
#if defined(HAVE_EVENT_GET_VERSION) && defined(HAVE_EVENT_GET_METHOD)
/* Making this a NOTICE for now so we can link bugs to a libevent versions
* or methods better. */
- log(LOG_INFO, LD_GENERAL,
+ log_info(LD_GENERAL,
"Initialized libevent version %s using method %s. Good.",
event_get_version(), tor_libevent_get_method());
#else
- log(LOG_NOTICE, LD_GENERAL,
+ log_notice(LD_GENERAL,
"Initialized old libevent (version 1.0b or earlier).");
- log(LOG_WARN, LD_GENERAL,
+ log_warn(LD_GENERAL,
"You have a *VERY* old version of libevent. It is likely to be buggy; "
"please build Tor with a more recent version.");
#endif
@@ -411,35 +404,9 @@ void
tor_check_libevent_version(const char *m, int server,
const char **badness_out)
{
- int thread_unsafe = 0;
- const char *v = NULL;
- const char *badness = NULL;
- const char *sad_os = "";
(void) m;
(void) server;
-
- /* Libevent versions before 1.3b do very badly on operating systems with
- * user-space threading implementations. */
-#if defined(__OpenBSD__) || defined(__FreeBSD__) || defined(__NetBSD__)
- if (server && version < V_OLD(1,3,'b')) {
- thread_unsafe = 1;
- sad_os = "BSD variants";
- }
-#elif defined(__APPLE__) || defined(__darwin__)
- if (server && version < V_OLD(1,3,'b')) {
- thread_unsafe = 1;
- sad_os = "Mac OS X";
- }
-#endif
-
- if (thread_unsafe) {
- log(LOG_WARN, LD_GENERAL,
- "Libevent version %s often crashes when running a Tor server with %s. "
- "Please use the latest version of libevent (1.3b or later)",v,sad_os);
- badness = "BROKEN";
- }
-
- *badness_out = badness;
+ *badness_out = NULL;
}
#if defined(LIBEVENT_VERSION)
@@ -473,7 +440,7 @@ tor_check_libevent_header_compatibility(void)
verybad = compat1 != compat2;
- log(verybad ? LOG_WARN : LOG_NOTICE,
+ tor_log(verybad ? LOG_WARN : LOG_NOTICE,
LD_GENERAL, "We were compiled with headers from version %s "
"of Libevent, but we're using a Libevent library that says it's "
"version %s.", HEADER_VERSION, event_get_version());
diff --git a/src/common/crypto.c b/src/common/crypto.c
index 7c73f79cff..70bd45299f 100644
--- a/src/common/crypto.c
+++ b/src/common/crypto.c
@@ -151,10 +151,11 @@ crypto_log_errors(int severity, const char *doing)
if (!lib) lib = "(null)";
if (!func) func = "(null)";
if (doing) {
- log(severity, LD_CRYPTO, "crypto error while %s: %s (in %s:%s)",
- doing, msg, lib, func);
+ tor_log(severity, LD_CRYPTO, "crypto error while %s: %s (in %s:%s)",
+ doing, msg, lib, func);
} else {
- log(severity, LD_CRYPTO, "crypto error: %s (in %s:%s)", msg, lib, func);
+ tor_log(severity, LD_CRYPTO, "crypto error: %s (in %s:%s)",
+ msg, lib, func);
}
}
}
@@ -168,10 +169,10 @@ log_engine(const char *fn, ENGINE *e)
const char *name, *id;
name = ENGINE_get_name(e);
id = ENGINE_get_id(e);
- log(LOG_NOTICE, LD_CRYPTO, "Using OpenSSL engine %s [%s] for %s",
+ log_notice(LD_CRYPTO, "Using OpenSSL engine %s [%s] for %s",
name?name:"?", id?id:"?", fn);
} else {
- log(LOG_INFO, LD_CRYPTO, "Using default implementation for %s", fn);
+ log_info(LD_CRYPTO, "Using default implementation for %s", fn);
}
}
#endif
diff --git a/src/common/crypto_curve25519.c b/src/common/crypto_curve25519.c
index 88705427a8..62398f62e6 100644
--- a/src/common/crypto_curve25519.c
+++ b/src/common/crypto_curve25519.c
@@ -69,7 +69,7 @@ curve25519_secret_key_generate(curve25519_secret_key_t *key_out,
return -1;
if (extra_strong && !crypto_strongest_rand(k_tmp, CURVE25519_SECKEY_LEN)) {
/* If they asked for extra-strong entropy and we have some, use it as an
- * HMAC key to improve not-so-good entopy rather than using it directly,
+ * HMAC key to improve not-so-good entropy rather than using it directly,
* just in case the extra-strong entropy is less amazing than we hoped. */
crypto_hmac_sha256((char *)key_out->secret_key,
(const char *)k_tmp, sizeof(k_tmp),
diff --git a/src/common/procmon.c b/src/common/procmon.c
index efb39e5bb7..0a49689e3a 100644
--- a/src/common/procmon.c
+++ b/src/common/procmon.c
@@ -321,7 +321,7 @@ tor_process_monitor_poll_cb(evutil_socket_t unused1, short unused2,
its_dead_jim = its_dead_jim && (errno == ESRCH);
#endif
- log(its_dead_jim ? LOG_NOTICE : LOG_INFO,
+ tor_log(its_dead_jim ? LOG_NOTICE : LOG_INFO,
procmon->log_domain, "Monitored process "PID_T_FORMAT" is %s.",
procmon->pid,
its_dead_jim ? "dead" : "still alive");
diff --git a/src/common/torlog.h b/src/common/torlog.h
index 97271fa81e..23ee597a4e 100644
--- a/src/common/torlog.h
+++ b/src/common/torlog.h
@@ -153,7 +153,6 @@ void set_log_time_granularity(int granularity_msec);
void tor_log(int severity, log_domain_mask_t domain, const char *format, ...)
CHECK_PRINTF(3,4);
-#define log tor_log /* hack it so we don't conflict with log() as much */
#if defined(__GNUC__) || defined(RUNNING_DOXYGEN)
extern int log_global_min_severity_;
diff --git a/src/common/tortls.c b/src/common/tortls.c
index 6151d3fde4..94cedba24b 100644
--- a/src/common/tortls.c
+++ b/src/common/tortls.c
@@ -334,11 +334,11 @@ tor_tls_log_one_error(tor_tls_t *tls, unsigned long err,
if (!lib) lib = "(null)";
if (!func) func = "(null)";
if (doing) {
- log(severity, domain, "TLS error while %s%s%s: %s (in %s:%s:%s)",
+ tor_log(severity, domain, "TLS error while %s%s%s: %s (in %s:%s:%s)",
doing, addr?" with ":"", addr?addr:"",
msg, lib, func, state);
} else {
- log(severity, domain, "TLS error%s%s: %s (in %s:%s:%s)",
+ tor_log(severity, domain, "TLS error%s%s: %s (in %s:%s:%s)",
addr?" with ":"", addr?addr:"",
msg, lib, func, state);
}
@@ -427,12 +427,12 @@ tor_tls_get_error(tor_tls_t *tls, int r, int extra,
if (extra&CATCH_SYSCALL)
return TOR_TLS_SYSCALL_;
if (r == 0) {
- log(severity, LD_NET, "TLS error: unexpected close while %s (%s)",
+ tor_log(severity, LD_NET, "TLS error: unexpected close while %s (%s)",
doing, SSL_state_string_long(tls->ssl));
tor_error = TOR_TLS_ERROR_IO;
} else {
int e = tor_socket_errno(tls->socket);
- log(severity, LD_NET,
+ tor_log(severity, LD_NET,
"TLS error: <syscall error while %s> (errno=%d: %s; state=%s)",
doing, e, tor_socket_strerror(e),
SSL_state_string_long(tls->ssl));
@@ -443,7 +443,7 @@ tor_tls_get_error(tor_tls_t *tls, int r, int extra,
case SSL_ERROR_ZERO_RETURN:
if (extra&CATCH_ZERO)
return TOR_TLS_ZERORETURN_;
- log(severity, LD_NET, "TLS connection closed while %s in state %s",
+ tor_log(severity, LD_NET, "TLS connection closed while %s in state %s",
doing, SSL_state_string_long(tls->ssl));
tls_log_errors(tls, severity, domain, doing);
return TOR_TLS_CLOSE;
@@ -1224,7 +1224,7 @@ tor_tls_context_new(crypto_pk_t *identity, unsigned int key_lifetime,
authcert = tor_tls_create_certificate(rsa_auth, identity, nickname, nn2,
key_lifetime);
if (!cert || !idcert || !authcert) {
- log(LOG_WARN, LD_CRYPTO, "Error creating certificate");
+ log_warn(LD_CRYPTO, "Error creating certificate");
goto error;
}
}
@@ -2272,7 +2272,7 @@ tor_tls_shutdown(tor_tls_t *tls)
*/
if (tls->state == TOR_TLS_ST_GOTCLOSE ||
tls->state == TOR_TLS_ST_SENTCLOSE) {
- log(LOG_WARN, LD_NET,
+ log_warn(LD_NET,
"TLS returned \"half-closed\" value while already half-closed");
return TOR_TLS_ERROR_MISC;
}
@@ -2322,7 +2322,7 @@ log_cert_lifetime(int severity, const X509 *cert, const char *problem)
struct tm tm;
if (problem)
- log(severity, LD_GENERAL,
+ tor_log(severity, LD_GENERAL,
"Certificate %s. Either their clock is set wrong, or your clock "
"is wrong.",
problem);
@@ -2347,7 +2347,7 @@ log_cert_lifetime(int severity, const X509 *cert, const char *problem)
strftime(mytime, 32, "%b %d %H:%M:%S %Y UTC", tor_gmtime_r(&now, &tm));
- log(severity, LD_GENERAL,
+ tor_log(severity, LD_GENERAL,
"(certificate lifetime runs from %s through %s. Your time is %s.)",
s1,s2,mytime);
@@ -2568,7 +2568,7 @@ check_no_tls_errors_(const char *fname, int line)
{
if (ERR_peek_error() == 0)
return;
- log(LOG_WARN, LD_CRYPTO, "Unhandled OpenSSL errors found at %s:%d: ",
+ log_warn(LD_CRYPTO, "Unhandled OpenSSL errors found at %s:%d: ",
tor_fix_source_file(fname), line);
tls_log_errors(NULL, LOG_WARN, LD_NET, NULL);
}
diff --git a/src/common/util.c b/src/common/util.c
index 49ec75dc4a..7d72a896f9 100644
--- a/src/common/util.c
+++ b/src/common/util.c
@@ -20,7 +20,6 @@
#define UTIL_PRIVATE
#include "util.h"
#include "torlog.h"
-#undef log
#include "crypto.h"
#include "torint.h"
#include "container.h"
@@ -323,8 +322,8 @@ tor_log_mallinfo(int severity)
* ===== */
/**
- * Returns the natural logarithm of d base 2. We define this wrapper here so
- * as to make it easier not to conflict with Tor's log() macro.
+ * Returns the natural logarithm of d base e. We defined this wrapper here so
+ * to avoid conflicts with old versions of tor_log(), which were named log().
*/
double
tor_mathlog(double d)
diff --git a/src/ext/README b/src/ext/README
index cd23f29496..58ba7f699d 100644
--- a/src/ext/README
+++ b/src/ext/README
@@ -34,7 +34,9 @@ tor_queue.h
A copy of sys/queue.h from OpenBSD. We keep our own copy rather
than using sys/queue.h, since some platforms don't have a
sys/queue.h, and the ones that do have diverged in incompatible
- ways. (CIRCLEQ or no CIRCLEQ? SIMPLQ or STAILQ?)
+ ways. (CIRCLEQ or no CIRCLEQ? SIMPLQ or STAILQ?) We also rename
+ the identifiers with a TOR_ prefix to avoid conflicts with
+ the system headers.
curve25519_donna/*.c
diff --git a/src/ext/eventdns.c b/src/ext/eventdns.c
index b1f586b2fb..5316338dc2 100644
--- a/src/ext/eventdns.c
+++ b/src/ext/eventdns.c
@@ -534,7 +534,7 @@ nameserver_probe_failed(struct nameserver *const ns) {
ns->failed_times++;
if (add_timeout_event(ns, (struct timeval *) timeout) < 0) {
- log(EVDNS_LOG_WARN,
+ tor_log(EVDNS_LOG_WARN,
"Error from libevent when adding timer event for %s",
debug_ntop((struct sockaddr *)&ns->address));
/* ???? Do more? */
@@ -550,19 +550,19 @@ nameserver_failed(struct nameserver *const ns, const char *msg) {
/* then don't do anything */
if (!ns->state) return;
- log(EVDNS_LOG_WARN, "Nameserver %s has failed: %s",
+ tor_log(EVDNS_LOG_WARN, "Nameserver %s has failed: %s",
debug_ntop((struct sockaddr *)&ns->address), msg);
global_good_nameservers--;
assert(global_good_nameservers >= 0);
if (global_good_nameservers == 0) {
- log(EVDNS_LOG_WARN, "All nameservers have failed");
+ tor_log(EVDNS_LOG_WARN, "All nameservers have failed");
}
ns->state = 0;
ns->failed_times = 1;
if (add_timeout_event(ns, (struct timeval *) &global_nameserver_timeouts[0]) < 0) {
- log(EVDNS_LOG_WARN,
+ tor_log(EVDNS_LOG_WARN,
"Error from libevent when adding timer event for %s",
debug_ntop((struct sockaddr *)&ns->address));
/* ???? Do more? */
@@ -593,7 +593,7 @@ nameserver_failed(struct nameserver *const ns, const char *msg) {
static void
nameserver_up(struct nameserver *const ns) {
if (ns->state) return;
- log(EVDNS_LOG_WARN, "Nameserver %s is back up",
+ tor_log(EVDNS_LOG_WARN, "Nameserver %s is back up",
debug_ntop((struct sockaddr *)&ns->address));
del_timeout_event(ns);
ns->state = 1;
@@ -624,7 +624,7 @@ request_finished(struct evdns_request *const req, struct evdns_request **head) {
}
}
- log(EVDNS_LOG_DEBUG, "Removing timeout for request %lx",
+ tor_log(EVDNS_LOG_DEBUG, "Removing timeout for request %lx",
(unsigned long) req);
del_timeout_event(req);
@@ -776,7 +776,7 @@ reply_handle(struct evdns_request *const req, u16 flags, u32 ttl, struct reply *
* confusing." Treat this as a timeout, not a failure.
*/
/*XXXX refactor the parts of */
- log(EVDNS_LOG_DEBUG, "Got a SERVERFAILED from nameserver %s; "
+ tor_log(EVDNS_LOG_DEBUG, "Got a SERVERFAILED from nameserver %s; "
"will allow the request to time out.",
debug_ntop((struct sockaddr *)&req->ns->address));
break;
@@ -1268,7 +1268,7 @@ nameserver_read(struct nameserver *ns) {
}
/* XXX Match port too? */
if (!sockaddr_eq(sa, (struct sockaddr*)&ns->address, 0)) {
- log(EVDNS_LOG_WARN,
+ tor_log(EVDNS_LOG_WARN,
"Address mismatch on received DNS packet. Address was %s",
debug_ntop(sa));
return;
@@ -1294,7 +1294,7 @@ server_port_read(struct evdns_server_port *s) {
if (r < 0) {
int err = last_error(s->socket);
if (error_is_eagain(err)) return;
- log(EVDNS_LOG_WARN, "Error %s (%d) while reading request.",
+ tor_log(EVDNS_LOG_WARN, "Error %s (%d) while reading request.",
tor_socket_strerror(err), err);
return;
}
@@ -1314,7 +1314,7 @@ server_port_flush(struct evdns_server_port *port)
int err = last_error(port->socket);
if (error_is_eagain(err))
return;
- log(EVDNS_LOG_WARN, "Error %s (%d) while writing response to port; dropping", tor_socket_strerror(err), err);
+ tor_log(EVDNS_LOG_WARN, "Error %s (%d) while writing response to port; dropping", tor_socket_strerror(err), err);
}
if (server_request_free(req)) {
/* we released the last reference to req->port. */
@@ -1331,7 +1331,7 @@ server_port_flush(struct evdns_server_port *port)
event_set(&port->event, port->socket, EV_READ | EV_PERSIST,
server_port_ready_callback, port);
if (event_add(&port->event, NULL) < 0) {
- log(EVDNS_LOG_WARN, "Error from libevent when adding event for DNS server.");
+ tor_log(EVDNS_LOG_WARN, "Error from libevent when adding event for DNS server.");
/* ???? Do more? */
}
}
@@ -1349,7 +1349,7 @@ nameserver_write_waiting(struct nameserver *ns, char waiting) {
event_set(&ns->event, ns->socket, EV_READ | (waiting ? EV_WRITE : 0) | EV_PERSIST,
nameserver_ready_callback, ns);
if (event_add(&ns->event, NULL) < 0) {
- log(EVDNS_LOG_WARN, "Error from libevent when adding event for %s",
+ tor_log(EVDNS_LOG_WARN, "Error from libevent when adding event for %s",
debug_ntop((struct sockaddr *)&ns->address));
/* ???? Do more? */
}
@@ -1859,7 +1859,7 @@ evdns_server_request_respond(struct evdns_server_request *_req, int err)
event_set(&port->event, port->socket, (port->closing?0:EV_READ) | EV_WRITE | EV_PERSIST, server_port_ready_callback, port);
if (event_add(&port->event, NULL) < 0) {
- log(EVDNS_LOG_WARN, "Error from libevent when adding event for DNS server");
+ tor_log(EVDNS_LOG_WARN, "Error from libevent when adding event for DNS server");
}
}
@@ -1995,7 +1995,7 @@ evdns_request_timeout_callback(int fd, short events, void *arg) {
(void) fd;
(void) events;
- log(EVDNS_LOG_DEBUG, "Request %lx timed out", (unsigned long) arg);
+ tor_log(EVDNS_LOG_DEBUG, "Request %lx timed out", (unsigned long) arg);
req->ns->timedout++;
if (req->ns->timedout > global_max_nameserver_timeout) {
@@ -2074,11 +2074,11 @@ evdns_request_transmit(struct evdns_request *req) {
* and make us retransmit the request anyway. */
default:
/* transmitted; we need to check for timeout. */
- log(EVDNS_LOG_DEBUG,
+ tor_log(EVDNS_LOG_DEBUG,
"Setting timeout for request %lx", (unsigned long) req);
if (add_timeout_event(req, &global_timeout) < 0) {
- log(EVDNS_LOG_WARN,
+ tor_log(EVDNS_LOG_WARN,
"Error from libevent when adding timer for request %lx",
(unsigned long) req);
/* ???? Do more? */
@@ -2126,7 +2126,7 @@ nameserver_send_probe(struct nameserver *const ns) {
addr = mm_malloc(sizeof(struct sockaddr_storage));
memcpy(addr, &ns->address, sizeof(struct sockaddr_storage));
- log(EVDNS_LOG_DEBUG, "Sending probe to %s", debug_ntop((struct sockaddr *)&ns->address));
+ tor_log(EVDNS_LOG_DEBUG, "Sending probe to %s", debug_ntop((struct sockaddr *)&ns->address));
req = request_new(TYPE_A, "www.google.com", DNS_QUERY_NO_SEARCH, nameserver_probe_callback, addr);
if (!req) {
@@ -2282,14 +2282,14 @@ _evdns_nameserver_add_impl(const struct sockaddr *address,
if (server) {
do {
if (sockaddr_eq(address, (struct sockaddr *)&server->address, 1)) {
- log(EVDNS_LOG_DEBUG, "Duplicate nameserver.");
+ tor_log(EVDNS_LOG_DEBUG, "Duplicate nameserver.");
return 3;
}
server = server->next;
} while (server != started_at);
}
if (addrlen > (int)sizeof(ns->address)) {
- log(EVDNS_LOG_DEBUG, "Addrlen %d too long.", (int)addrlen);
+ tor_log(EVDNS_LOG_DEBUG, "Addrlen %d too long.", (int)addrlen);
return 2;
}
@@ -2315,14 +2315,14 @@ _evdns_nameserver_add_impl(const struct sockaddr *address,
!sockaddr_is_loopback((struct sockaddr*)&global_bind_address)) {
if (bind(ns->socket, (struct sockaddr *)&global_bind_address,
global_bind_addrlen) < 0) {
- log(EVDNS_LOG_DEBUG, "Couldn't bind to outgoing address.");
+ tor_log(EVDNS_LOG_DEBUG, "Couldn't bind to outgoing address.");
err = 2;
goto out2;
}
}
if (connect(ns->socket, address, addrlen) != 0) {
- log(EVDNS_LOG_DEBUG, "Couldn't open socket to nameserver.");
+ tor_log(EVDNS_LOG_DEBUG, "Couldn't open socket to nameserver.");
err = 2;
goto out2;
}
@@ -2331,12 +2331,12 @@ _evdns_nameserver_add_impl(const struct sockaddr *address,
ns->state = 1;
event_set(&ns->event, ns->socket, EV_READ | EV_PERSIST, nameserver_ready_callback, ns);
if (event_add(&ns->event, NULL) < 0) {
- log(EVDNS_LOG_DEBUG, "Couldn't add event for nameserver.");
+ tor_log(EVDNS_LOG_DEBUG, "Couldn't add event for nameserver.");
err = 2;
goto out2;
}
- log(EVDNS_LOG_DEBUG, "Added nameserver %s", debug_ntop(address));
+ tor_log(EVDNS_LOG_DEBUG, "Added nameserver %s", debug_ntop(address));
/* insert this nameserver into the list of them */
if (!server_head) {
@@ -2360,7 +2360,7 @@ out2:
out1:
CLEAR(ns);
mm_free(ns);
- log(EVDNS_LOG_WARN, "Unable to add nameserver %s: error %d", debug_ntop(address), err);
+ tor_log(EVDNS_LOG_WARN, "Unable to add nameserver %s: error %d", debug_ntop(address), err);
return err;
}
@@ -2393,18 +2393,18 @@ evdns_nameserver_ip_add(const char *ip_as_string) {
* ipv4
*/
- log(EVDNS_LOG_DEBUG, "Trying to add nameserver <%s>", ip_as_string);
+ tor_log(EVDNS_LOG_DEBUG, "Trying to add nameserver <%s>", ip_as_string);
cp = strchr(ip_as_string, ':');
if (*ip_as_string == '[') {
size_t len;
if (!(cp = strchr(ip_as_string, ']'))) {
- log(EVDNS_LOG_DEBUG, "Nameserver missing closing ]");
+ tor_log(EVDNS_LOG_DEBUG, "Nameserver missing closing ]");
return 4;
}
len = cp-(ip_as_string + 1);
if (len > sizeof(buf)-1) {
- log(EVDNS_LOG_DEBUG, "[Nameserver] does not fit in buffer.");
+ tor_log(EVDNS_LOG_DEBUG, "[Nameserver] does not fit in buffer.");
return 4;
}
memcpy(buf, ip_as_string+1, len);
@@ -2422,7 +2422,7 @@ evdns_nameserver_ip_add(const char *ip_as_string) {
} else if (cp) {
is_ipv6 = 0;
if (cp - ip_as_string > (int)sizeof(buf)-1) {
- log(EVDNS_LOG_DEBUG, "Nameserver does not fit in buffer.");
+ tor_log(EVDNS_LOG_DEBUG, "Nameserver does not fit in buffer.");
return 4;
}
memcpy(buf, ip_as_string, cp-ip_as_string);
@@ -2440,7 +2440,7 @@ evdns_nameserver_ip_add(const char *ip_as_string) {
} else {
port = strtoint(port_part);
if (port <= 0 || port > 65535) {
- log(EVDNS_LOG_DEBUG, "Nameserver port <%s> out of range",
+ tor_log(EVDNS_LOG_DEBUG, "Nameserver port <%s> out of range",
port_part);
return 4;
}
@@ -2457,7 +2457,7 @@ evdns_nameserver_ip_add(const char *ip_as_string) {
sin6.sin6_family = AF_INET6;
sin6.sin6_port = htons(port);
if (1 != tor_inet_pton(AF_INET6, addr_part, &sin6.sin6_addr)) {
- log(EVDNS_LOG_DEBUG, "inet_pton(%s) failed", addr_part);
+ tor_log(EVDNS_LOG_DEBUG, "inet_pton(%s) failed", addr_part);
return 4;
}
return _evdns_nameserver_add_impl((struct sockaddr*)&sin6,
@@ -2471,7 +2471,7 @@ evdns_nameserver_ip_add(const char *ip_as_string) {
sin.sin_family = AF_INET;
sin.sin_port = htons(port);
if (!inet_aton(addr_part, &sin.sin_addr)) {
- log(EVDNS_LOG_DEBUG, "inet_pton(%s) failed", addr_part);
+ tor_log(EVDNS_LOG_DEBUG, "inet_pton(%s) failed", addr_part);
return 4;
}
return _evdns_nameserver_add_impl((struct sockaddr*)&sin,
@@ -2594,7 +2594,7 @@ request_submit(struct evdns_request *const req) {
/* exported function */
int evdns_resolve_ipv4(const char *name, int flags,
evdns_callback_type callback, void *ptr) {
- log(EVDNS_LOG_DEBUG, "Resolve requested for %s", name);
+ tor_log(EVDNS_LOG_DEBUG, "Resolve requested for %s", name);
if (flags & DNS_QUERY_NO_SEARCH) {
struct evdns_request *const req =
request_new(TYPE_A, name, flags, callback, ptr);
@@ -2610,7 +2610,7 @@ int evdns_resolve_ipv4(const char *name, int flags,
/* exported function */
int evdns_resolve_ipv6(const char *name, int flags,
evdns_callback_type callback, void *ptr) {
- log(EVDNS_LOG_DEBUG, "Resolve requested for %s", name);
+ tor_log(EVDNS_LOG_DEBUG, "Resolve requested for %s", name);
if (flags & DNS_QUERY_NO_SEARCH) {
struct evdns_request *const req =
request_new(TYPE_AAAA, name, flags, callback, ptr);
@@ -2634,7 +2634,7 @@ int evdns_resolve_reverse(const struct in_addr *in, int flags, evdns_callback_ty
(int)(u8)((a>>8 )&0xff),
(int)(u8)((a>>16)&0xff),
(int)(u8)((a>>24)&0xff));
- log(EVDNS_LOG_DEBUG, "Resolve requested for %s (reverse)", buf);
+ tor_log(EVDNS_LOG_DEBUG, "Resolve requested for %s (reverse)", buf);
req = request_new(TYPE_PTR, buf, flags, callback, ptr);
if (!req) return 1;
request_submit(req);
@@ -2658,7 +2658,7 @@ int evdns_resolve_reverse_ipv6(const struct in6_addr *in, int flags, evdns_callb
}
assert(cp + strlen("ip6.arpa") < buf+sizeof(buf));
memcpy(cp, "ip6.arpa", strlen("ip6.arpa")+1);
- log(EVDNS_LOG_DEBUG, "Resolve requested for %s (reverse)", buf);
+ tor_log(EVDNS_LOG_DEBUG, "Resolve requested for %s (reverse)", buf);
req = request_new(TYPE_PTR, buf, flags, callback, ptr);
if (!req) return 1;
request_submit(req);
@@ -2874,7 +2874,7 @@ search_try_next(struct evdns_request *const req) {
if (string_num_dots(req->search_origname) < req->search_state->ndots) {
/* yep, we need to try it raw */
struct evdns_request *const newreq = request_new(req->request_type, req->search_origname, req->search_flags, req->user_callback, req->user_pointer);
- log(EVDNS_LOG_DEBUG, "Search: trying raw query %s", req->search_origname);
+ tor_log(EVDNS_LOG_DEBUG, "Search: trying raw query %s", req->search_origname);
if (newreq) {
request_submit(newreq);
return 0;
@@ -2885,7 +2885,7 @@ search_try_next(struct evdns_request *const req) {
new_name = search_make_new(req->search_state, req->search_index, req->search_origname);
if (!new_name) return 1;
- log(EVDNS_LOG_DEBUG, "Search: now trying %s (%d)", new_name, req->search_index);
+ tor_log(EVDNS_LOG_DEBUG, "Search: now trying %s (%d)", new_name, req->search_index);
newreq = request_new(req->request_type, new_name, req->search_flags, req->user_callback, req->user_pointer);
mm_free(new_name);
if (!newreq) return 1;
@@ -2955,7 +2955,7 @@ evdns_set_option(const char *option, const char *val, int flags)
const int ndots = strtoint(val);
if (ndots == -1) return -1;
if (!(flags & DNS_OPTION_SEARCH)) return 0;
- log(EVDNS_LOG_DEBUG, "Setting ndots to %d", ndots);
+ tor_log(EVDNS_LOG_DEBUG, "Setting ndots to %d", ndots);
if (!global_search_state) global_search_state = search_state_new();
if (!global_search_state) return -1;
global_search_state->ndots = ndots;
@@ -2963,20 +2963,20 @@ evdns_set_option(const char *option, const char *val, int flags)
const int timeout = strtoint(val);
if (timeout == -1) return -1;
if (!(flags & DNS_OPTION_MISC)) return 0;
- log(EVDNS_LOG_DEBUG, "Setting timeout to %d", timeout);
+ tor_log(EVDNS_LOG_DEBUG, "Setting timeout to %d", timeout);
global_timeout.tv_sec = timeout;
} else if (!strncmp(option, "max-timeouts:", 12)) {
const int maxtimeout = strtoint_clipped(val, 1, 255);
if (maxtimeout == -1) return -1;
if (!(flags & DNS_OPTION_MISC)) return 0;
- log(EVDNS_LOG_DEBUG, "Setting maximum allowed timeouts to %d",
+ tor_log(EVDNS_LOG_DEBUG, "Setting maximum allowed timeouts to %d",
maxtimeout);
global_max_nameserver_timeout = maxtimeout;
} else if (!strncmp(option, "max-inflight:", 13)) {
const int maxinflight = strtoint_clipped(val, 1, 65000);
if (maxinflight == -1) return -1;
if (!(flags & DNS_OPTION_MISC)) return 0;
- log(EVDNS_LOG_DEBUG, "Setting maximum inflight requests to %d",
+ tor_log(EVDNS_LOG_DEBUG, "Setting maximum inflight requests to %d",
maxinflight);
global_max_requests_inflight = maxinflight;
} else if (!strncmp(option, "attempts:", 9)) {
@@ -2984,12 +2984,12 @@ evdns_set_option(const char *option, const char *val, int flags)
if (retries == -1) return -1;
if (retries > 255) retries = 255;
if (!(flags & DNS_OPTION_MISC)) return 0;
- log(EVDNS_LOG_DEBUG, "Setting retries to %d", retries);
+ tor_log(EVDNS_LOG_DEBUG, "Setting retries to %d", retries);
global_max_retransmits = retries;
} else if (!strncmp(option, "randomize-case:", 15)) {
int randcase = strtoint(val);
if (!(flags & DNS_OPTION_MISC)) return 0;
- log(EVDNS_LOG_DEBUG, "Setting randomize_case to %d", randcase);
+ tor_log(EVDNS_LOG_DEBUG, "Setting randomize_case to %d", randcase);
global_randomize_case = randcase;
}
return 0;
@@ -3047,7 +3047,7 @@ evdns_resolv_conf_parse(int flags, const char *const filename) {
char *start;
int err = 0;
- log(EVDNS_LOG_DEBUG, "Parsing resolv.conf file %s", filename);
+ tor_log(EVDNS_LOG_DEBUG, "Parsing resolv.conf file %s", filename);
fd = tor_open_cloexec(filename, O_RDONLY, 0);
if (fd < 0) {
@@ -3146,13 +3146,13 @@ load_nameservers_with_getnetworkparams(void)
GetNetworkParams_fn_t fn;
if (!(handle = load_windows_system_library(TEXT("iphlpapi.dll")))) {
- log(EVDNS_LOG_WARN, "Could not open iphlpapi.dll");
+ tor_log(EVDNS_LOG_WARN, "Could not open iphlpapi.dll");
/* right now status = 0, doesn't that mean "good" - mikec */
status = -1;
goto done;
}
if (!(fn = (GetNetworkParams_fn_t) GetProcAddress(handle, TEXT("GetNetworkParams")))) {
- log(EVDNS_LOG_WARN, "Could not get address of function.");
+ tor_log(EVDNS_LOG_WARN, "Could not get address of function.");
/* same as above */
status = -1;
goto done;
@@ -3173,7 +3173,7 @@ load_nameservers_with_getnetworkparams(void)
fixed = buf;
r = fn(fixed, &size);
if (r != ERROR_SUCCESS) {
- log(EVDNS_LOG_DEBUG, "fn() failed.");
+ tor_log(EVDNS_LOG_DEBUG, "fn() failed.");
status = -1;
goto done;
}
@@ -3185,12 +3185,12 @@ load_nameservers_with_getnetworkparams(void)
while (ns) {
r = evdns_nameserver_ip_add_line(ns->IpAddress.String);
if (r) {
- log(EVDNS_LOG_DEBUG,"Could not add nameserver %s to list, "
+ tor_log(EVDNS_LOG_DEBUG,"Could not add nameserver %s to list, "
"error: %d; status: %d",
(ns->IpAddress.String),(int)GetLastError(), r);
status = r;
} else {
- log(EVDNS_LOG_DEBUG,"Successfully added %s as nameserver",ns->IpAddress.String);
+ tor_log(EVDNS_LOG_DEBUG,"Successfully added %s as nameserver",ns->IpAddress.String);
added_any++;
}
@@ -3198,7 +3198,7 @@ load_nameservers_with_getnetworkparams(void)
}
if (!added_any) {
- log(EVDNS_LOG_DEBUG, "No nameservers added.");
+ tor_log(EVDNS_LOG_DEBUG, "No nameservers added.");
if (status == 0)
status = -1;
} else {
@@ -3254,10 +3254,10 @@ load_nameservers_from_registry(void)
#define TRY(k, name) \
if (!found && config_nameserver_from_reg_key(k,TEXT(name)) == 0) { \
- log(EVDNS_LOG_DEBUG,"Found nameservers in %s/%s",#k,name); \
+ tor_log(EVDNS_LOG_DEBUG,"Found nameservers in %s/%s",#k,name); \
found = 1; \
} else if (!found) { \
- log(EVDNS_LOG_DEBUG,"Didn't find nameservers in %s/%s", \
+ tor_log(EVDNS_LOG_DEBUG,"Didn't find nameservers in %s/%s", \
#k,#name); \
}
@@ -3266,14 +3266,14 @@ load_nameservers_from_registry(void)
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, WIN_NS_NT_KEY, 0,
KEY_READ, &nt_key) != ERROR_SUCCESS) {
- log(EVDNS_LOG_DEBUG,"Couldn't open nt key, %d",(int)GetLastError());
+ tor_log(EVDNS_LOG_DEBUG,"Couldn't open nt key, %d",(int)GetLastError());
return -1;
}
r = RegOpenKeyEx(nt_key, TEXT("Interfaces"), 0,
KEY_QUERY_VALUE|KEY_ENUMERATE_SUB_KEYS,
&interfaces_key);
if (r != ERROR_SUCCESS) {
- log(EVDNS_LOG_DEBUG,"Couldn't open interfaces key, %d",(int)GetLastError());
+ tor_log(EVDNS_LOG_DEBUG,"Couldn't open interfaces key, %d",(int)GetLastError());
return -1;
}
TRY(nt_key, "NameServer");
@@ -3286,7 +3286,7 @@ load_nameservers_from_registry(void)
HKEY win_key = 0;
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, WIN_NS_9X_KEY, 0,
KEY_READ, &win_key) != ERROR_SUCCESS) {
- log(EVDNS_LOG_DEBUG, "Couldn't open registry key, %d", (int)GetLastError());
+ tor_log(EVDNS_LOG_DEBUG, "Couldn't open registry key, %d", (int)GetLastError());
return -1;
}
TRY(win_key, "NameServer");
@@ -3294,7 +3294,7 @@ load_nameservers_from_registry(void)
}
if (found == 0) {
- log(EVDNS_LOG_WARN,"Didn't find any nameservers.");
+ tor_log(EVDNS_LOG_WARN,"Didn't find any nameservers.");
}
return found ? 0 : -1;
diff --git a/src/ext/tor_queue.h b/src/ext/tor_queue.h
index 595e4a3423..f05e48c18e 100644
--- a/src/ext/tor_queue.h
+++ b/src/ext/tor_queue.h
@@ -32,8 +32,8 @@
* @(#)queue.h 8.5 (Berkeley) 8/20/94
*/
-#ifndef _SYS_QUEUE_H_
-#define _SYS_QUEUE_H_
+#ifndef TOR_QUEUE_H_
+#define TOR_QUEUE_H_
/*
* This file defines five types of data structures: singly-linked lists,
@@ -83,78 +83,73 @@
*/
#if defined(QUEUE_MACRO_DEBUG) || (defined(_KERNEL) && defined(DIAGNOSTIC))
-#define _Q_INVALIDATE(a) (a) = ((void *)-1)
+#define TOR_Q_INVALIDATE_(a) (a) = ((void *)-1)
#else
-#define _Q_INVALIDATE(a)
+#define TOR_Q_INVALIDATE_(a)
#endif
/*
* Singly-linked List definitions.
*/
-#define SLIST_HEAD(name, type) \
+#define TOR_SLIST_HEAD(name, type) \
struct name { \
struct type *slh_first; /* first element */ \
}
-#define SLIST_HEAD_INITIALIZER(head) \
+#define TOR_SLIST_HEAD_INITIALIZER(head) \
{ NULL }
-/* XXXX This macro name conflicts with a typedef in winnt.h, so Tor
- * has to redefine it. */
#define TOR_SLIST_ENTRY(type) \
struct { \
struct type *sle_next; /* next element */ \
}
-#ifndef _WIN32
-#define SLIST_ENTRY(type) TOR_SLIST_ENTRY(type)
-#endif
/*
* Singly-linked List access methods.
*/
-#define SLIST_FIRST(head) ((head)->slh_first)
-#define SLIST_END(head) NULL
-#define SLIST_EMPTY(head) (SLIST_FIRST(head) == SLIST_END(head))
-#define SLIST_NEXT(elm, field) ((elm)->field.sle_next)
-
-#define SLIST_FOREACH(var, head, field) \
- for((var) = SLIST_FIRST(head); \
- (var) != SLIST_END(head); \
- (var) = SLIST_NEXT(var, field))
-
-#define SLIST_FOREACH_SAFE(var, head, field, tvar) \
- for ((var) = SLIST_FIRST(head); \
- (var) && ((tvar) = SLIST_NEXT(var, field), 1); \
+#define TOR_SLIST_FIRST(head) ((head)->slh_first)
+#define TOR_SLIST_END(head) NULL
+#define TOR_SLIST_EMPTY(head) (SLIST_FIRST(head) == TOR_SLIST_END(head))
+#define TOR_SLIST_NEXT(elm, field) ((elm)->field.sle_next)
+
+#define TOR_SLIST_FOREACH(var, head, field) \
+ for((var) = TOR_SLIST_FIRST(head); \
+ (var) != TOR_SLIST_END(head); \
+ (var) = TOR_SLIST_NEXT(var, field))
+
+#define TOR_SLIST_FOREACH_SAFE(var, head, field, tvar) \
+ for ((var) = TOR_SLIST_FIRST(head); \
+ (var) && ((tvar) = TOR_SLIST_NEXT(var, field), 1); \
(var) = (tvar))
/*
* Singly-linked List functions.
*/
-#define SLIST_INIT(head) { \
- SLIST_FIRST(head) = SLIST_END(head); \
+#define TOR_SLIST_INIT(head) { \
+ TOR_SLIST_FIRST(head) = TOR_SLIST_END(head); \
}
-#define SLIST_INSERT_AFTER(slistelm, elm, field) do { \
+#define TOR_SLIST_INSERT_AFTER(slistelm, elm, field) do { \
(elm)->field.sle_next = (slistelm)->field.sle_next; \
(slistelm)->field.sle_next = (elm); \
} while (0)
-#define SLIST_INSERT_HEAD(head, elm, field) do { \
+#define TOR_SLIST_INSERT_HEAD(head, elm, field) do { \
(elm)->field.sle_next = (head)->slh_first; \
(head)->slh_first = (elm); \
} while (0)
-#define SLIST_REMOVE_AFTER(elm, field) do { \
+#define TOR_SLIST_REMOVE_AFTER(elm, field) do { \
(elm)->field.sle_next = (elm)->field.sle_next->field.sle_next; \
} while (0)
-#define SLIST_REMOVE_HEAD(head, field) do { \
+#define TOR_SLIST_REMOVE_HEAD(head, field) do { \
(head)->slh_first = (head)->slh_first->field.sle_next; \
} while (0)
-#define SLIST_REMOVE(head, elm, type, field) do { \
+#define TOR_SLIST_REMOVE(head, elm, type, field) do { \
if ((head)->slh_first == (elm)) { \
- SLIST_REMOVE_HEAD((head), field); \
+ TOR_SLIST_REMOVE_HEAD((head), field); \
} else { \
struct type *curelm = (head)->slh_first; \
\
@@ -162,22 +157,22 @@ struct { \
curelm = curelm->field.sle_next; \
curelm->field.sle_next = \
curelm->field.sle_next->field.sle_next; \
- _Q_INVALIDATE((elm)->field.sle_next); \
+ TOR_Q_INVALIDATE_((elm)->field.sle_next); \
} \
} while (0)
/*
* List definitions.
*/
-#define LIST_HEAD(name, type) \
+#define TOR_LIST_HEAD(name, type) \
struct name { \
struct type *lh_first; /* first element */ \
}
-#define LIST_HEAD_INITIALIZER(head) \
+#define TOR_LIST_HEAD_INITIALIZER(head) \
{ NULL }
-#define LIST_ENTRY(type) \
+#define TOR_LIST_ENTRY(type) \
struct { \
struct type *le_next; /* next element */ \
struct type **le_prev; /* address of previous next element */ \
@@ -186,29 +181,29 @@ struct { \
/*
* List access methods
*/
-#define LIST_FIRST(head) ((head)->lh_first)
-#define LIST_END(head) NULL
-#define LIST_EMPTY(head) (LIST_FIRST(head) == LIST_END(head))
-#define LIST_NEXT(elm, field) ((elm)->field.le_next)
-
-#define LIST_FOREACH(var, head, field) \
- for((var) = LIST_FIRST(head); \
- (var)!= LIST_END(head); \
- (var) = LIST_NEXT(var, field))
-
-#define LIST_FOREACH_SAFE(var, head, field, tvar) \
- for ((var) = LIST_FIRST(head); \
- (var) && ((tvar) = LIST_NEXT(var, field), 1); \
+#define TOR_LIST_FIRST(head) ((head)->lh_first)
+#define TOR_LIST_END(head) NULL
+#define TOR_LIST_EMPTY(head) (TOR_LIST_FIRST(head) == TOR_LIST_END(head))
+#define TOR_LIST_NEXT(elm, field) ((elm)->field.le_next)
+
+#define TOR_LIST_FOREACH(var, head, field) \
+ for((var) = TOR_LIST_FIRST(head); \
+ (var)!= TOR_LIST_END(head); \
+ (var) = TOR_LIST_NEXT(var, field))
+
+#define TOR_LIST_FOREACH_SAFE(var, head, field, tvar) \
+ for ((var) = TOR_LIST_FIRST(head); \
+ (var) && ((tvar) = TOR_LIST_NEXT(var, field), 1); \
(var) = (tvar))
/*
* List functions.
*/
-#define LIST_INIT(head) do { \
- LIST_FIRST(head) = LIST_END(head); \
+#define TOR_LIST_INIT(head) do { \
+ TOR_LIST_FIRST(head) = TOR_LIST_END(head); \
} while (0)
-#define LIST_INSERT_AFTER(listelm, elm, field) do { \
+#define TOR_LIST_INSERT_AFTER(listelm, elm, field) do { \
if (((elm)->field.le_next = (listelm)->field.le_next) != NULL) \
(listelm)->field.le_next->field.le_prev = \
&(elm)->field.le_next; \
@@ -216,52 +211,52 @@ struct { \
(elm)->field.le_prev = &(listelm)->field.le_next; \
} while (0)
-#define LIST_INSERT_BEFORE(listelm, elm, field) do { \
+#define TOR_LIST_INSERT_BEFORE(listelm, elm, field) do { \
(elm)->field.le_prev = (listelm)->field.le_prev; \
(elm)->field.le_next = (listelm); \
*(listelm)->field.le_prev = (elm); \
(listelm)->field.le_prev = &(elm)->field.le_next; \
} while (0)
-#define LIST_INSERT_HEAD(head, elm, field) do { \
+#define TOR_LIST_INSERT_HEAD(head, elm, field) do { \
if (((elm)->field.le_next = (head)->lh_first) != NULL) \
(head)->lh_first->field.le_prev = &(elm)->field.le_next;\
(head)->lh_first = (elm); \
(elm)->field.le_prev = &(head)->lh_first; \
} while (0)
-#define LIST_REMOVE(elm, field) do { \
+#define TOR_LIST_REMOVE(elm, field) do { \
if ((elm)->field.le_next != NULL) \
(elm)->field.le_next->field.le_prev = \
(elm)->field.le_prev; \
*(elm)->field.le_prev = (elm)->field.le_next; \
- _Q_INVALIDATE((elm)->field.le_prev); \
- _Q_INVALIDATE((elm)->field.le_next); \
+ TOR_Q_INVALIDATE_((elm)->field.le_prev); \
+ TOR_Q_INVALIDATE_((elm)->field.le_next); \
} while (0)
-#define LIST_REPLACE(elm, elm2, field) do { \
+#define TOR_LIST_REPLACE(elm, elm2, field) do { \
if (((elm2)->field.le_next = (elm)->field.le_next) != NULL) \
(elm2)->field.le_next->field.le_prev = \
&(elm2)->field.le_next; \
(elm2)->field.le_prev = (elm)->field.le_prev; \
*(elm2)->field.le_prev = (elm2); \
- _Q_INVALIDATE((elm)->field.le_prev); \
- _Q_INVALIDATE((elm)->field.le_next); \
+ TOR_Q_INVALIDATE_((elm)->field.le_prev); \
+ TOR_Q_INVALIDATE_((elm)->field.le_next); \
} while (0)
/*
* Simple queue definitions.
*/
-#define SIMPLEQ_HEAD(name, type) \
+#define TOR_SIMPLEQ_HEAD(name, type) \
struct name { \
struct type *sqh_first; /* first element */ \
struct type **sqh_last; /* addr of last next element */ \
}
-#define SIMPLEQ_HEAD_INITIALIZER(head) \
+#define TOR_SIMPLEQ_HEAD_INITIALIZER(head) \
{ NULL, &(head).sqh_first }
-#define SIMPLEQ_ENTRY(type) \
+#define TOR_SIMPLEQ_ENTRY(type) \
struct { \
struct type *sqe_next; /* next element */ \
}
@@ -269,53 +264,53 @@ struct { \
/*
* Simple queue access methods.
*/
-#define SIMPLEQ_FIRST(head) ((head)->sqh_first)
-#define SIMPLEQ_END(head) NULL
-#define SIMPLEQ_EMPTY(head) (SIMPLEQ_FIRST(head) == SIMPLEQ_END(head))
-#define SIMPLEQ_NEXT(elm, field) ((elm)->field.sqe_next)
-
-#define SIMPLEQ_FOREACH(var, head, field) \
- for((var) = SIMPLEQ_FIRST(head); \
- (var) != SIMPLEQ_END(head); \
- (var) = SIMPLEQ_NEXT(var, field))
-
-#define SIMPLEQ_FOREACH_SAFE(var, head, field, tvar) \
- for ((var) = SIMPLEQ_FIRST(head); \
- (var) && ((tvar) = SIMPLEQ_NEXT(var, field), 1); \
+#define TOR_SIMPLEQ_FIRST(head) ((head)->sqh_first)
+#define TOR_SIMPLEQ_END(head) NULL
+#define TOR_SIMPLEQ_EMPTY(head) (TOR_SIMPLEQ_FIRST(head) == TOR_SIMPLEQ_END(head))
+#define TOR_SIMPLEQ_NEXT(elm, field) ((elm)->field.sqe_next)
+
+#define TOR_SIMPLEQ_FOREACH(var, head, field) \
+ for((var) = TOR_SIMPLEQ_FIRST(head); \
+ (var) != TOR_SIMPLEQ_END(head); \
+ (var) = TOR_SIMPLEQ_NEXT(var, field))
+
+#define TOR_SIMPLEQ_FOREACH_SAFE(var, head, field, tvar) \
+ for ((var) = TOR_SIMPLEQ_FIRST(head); \
+ (var) && ((tvar) = TOR_SIMPLEQ_NEXT(var, field), 1); \
(var) = (tvar))
/*
* Simple queue functions.
*/
-#define SIMPLEQ_INIT(head) do { \
+#define TOR_SIMPLEQ_INIT(head) do { \
(head)->sqh_first = NULL; \
(head)->sqh_last = &(head)->sqh_first; \
} while (0)
-#define SIMPLEQ_INSERT_HEAD(head, elm, field) do { \
+#define TOR_SIMPLEQ_INSERT_HEAD(head, elm, field) do { \
if (((elm)->field.sqe_next = (head)->sqh_first) == NULL) \
(head)->sqh_last = &(elm)->field.sqe_next; \
(head)->sqh_first = (elm); \
} while (0)
-#define SIMPLEQ_INSERT_TAIL(head, elm, field) do { \
+#define TOR_SIMPLEQ_INSERT_TAIL(head, elm, field) do { \
(elm)->field.sqe_next = NULL; \
*(head)->sqh_last = (elm); \
(head)->sqh_last = &(elm)->field.sqe_next; \
} while (0)
-#define SIMPLEQ_INSERT_AFTER(head, listelm, elm, field) do { \
+#define TOR_SIMPLEQ_INSERT_AFTER(head, listelm, elm, field) do { \
if (((elm)->field.sqe_next = (listelm)->field.sqe_next) == NULL)\
(head)->sqh_last = &(elm)->field.sqe_next; \
(listelm)->field.sqe_next = (elm); \
} while (0)
-#define SIMPLEQ_REMOVE_HEAD(head, field) do { \
+#define TOR_SIMPLEQ_REMOVE_HEAD(head, field) do { \
if (((head)->sqh_first = (head)->sqh_first->field.sqe_next) == NULL) \
(head)->sqh_last = &(head)->sqh_first; \
} while (0)
-#define SIMPLEQ_REMOVE_AFTER(head, elm, field) do { \
+#define TOR_SIMPLEQ_REMOVE_AFTER(head, elm, field) do { \
if (((elm)->field.sqe_next = (elm)->field.sqe_next->field.sqe_next) \
== NULL) \
(head)->sqh_last = &(elm)->field.sqe_next; \
@@ -324,16 +319,16 @@ struct { \
/*
* Tail queue definitions.
*/
-#define TAILQ_HEAD(name, type) \
+#define TOR_TAILQ_HEAD(name, type) \
struct name { \
struct type *tqh_first; /* first element */ \
struct type **tqh_last; /* addr of last next element */ \
}
-#define TAILQ_HEAD_INITIALIZER(head) \
+#define TOR_TAILQ_HEAD_INITIALIZER(head) \
{ NULL, &(head).tqh_first }
-#define TAILQ_ENTRY(type) \
+#define TOR_TAILQ_ENTRY(type) \
struct { \
struct type *tqe_next; /* next element */ \
struct type **tqe_prev; /* address of previous next element */ \
@@ -342,49 +337,49 @@ struct { \
/*
* tail queue access methods
*/
-#define TAILQ_FIRST(head) ((head)->tqh_first)
-#define TAILQ_END(head) NULL
-#define TAILQ_NEXT(elm, field) ((elm)->field.tqe_next)
-#define TAILQ_LAST(head, headname) \
+#define TOR_TAILQ_FIRST(head) ((head)->tqh_first)
+#define TOR_TAILQ_END(head) NULL
+#define TOR_TAILQ_NEXT(elm, field) ((elm)->field.tqe_next)
+#define TOR_TAILQ_LAST(head, headname) \
(*(((struct headname *)((head)->tqh_last))->tqh_last))
/* XXX */
-#define TAILQ_PREV(elm, headname, field) \
+#define TOR_TAILQ_PREV(elm, headname, field) \
(*(((struct headname *)((elm)->field.tqe_prev))->tqh_last))
-#define TAILQ_EMPTY(head) \
- (TAILQ_FIRST(head) == TAILQ_END(head))
-
-#define TAILQ_FOREACH(var, head, field) \
- for((var) = TAILQ_FIRST(head); \
- (var) != TAILQ_END(head); \
- (var) = TAILQ_NEXT(var, field))
-
-#define TAILQ_FOREACH_SAFE(var, head, field, tvar) \
- for ((var) = TAILQ_FIRST(head); \
- (var) != TAILQ_END(head) && \
- ((tvar) = TAILQ_NEXT(var, field), 1); \
+#define TOR_TAILQ_EMPTY(head) \
+ (TOR_TAILQ_FIRST(head) == TOR_TAILQ_END(head))
+
+#define TOR_TAILQ_FOREACH(var, head, field) \
+ for((var) = TOR_TAILQ_FIRST(head); \
+ (var) != TOR_TAILQ_END(head); \
+ (var) = TOR_TAILQ_NEXT(var, field))
+
+#define TOR_TAILQ_FOREACH_SAFE(var, head, field, tvar) \
+ for ((var) = TOR_TAILQ_FIRST(head); \
+ (var) != TOR_TAILQ_END(head) && \
+ ((tvar) = TOR_TAILQ_NEXT(var, field), 1); \
(var) = (tvar))
-#define TAILQ_FOREACH_REVERSE(var, head, headname, field) \
- for((var) = TAILQ_LAST(head, headname); \
- (var) != TAILQ_END(head); \
- (var) = TAILQ_PREV(var, headname, field))
+#define TOR_TAILQ_FOREACH_REVERSE(var, head, headname, field) \
+ for((var) = TOR_TAILQ_LAST(head, headname); \
+ (var) != TOR_TAILQ_END(head); \
+ (var) = TOR_TAILQ_PREV(var, headname, field))
-#define TAILQ_FOREACH_REVERSE_SAFE(var, head, headname, field, tvar) \
- for ((var) = TAILQ_LAST(head, headname); \
- (var) != TAILQ_END(head) && \
- ((tvar) = TAILQ_PREV(var, headname, field), 1); \
+#define TOR_TAILQ_FOREACH_REVERSE_SAFE(var, head, headname, field, tvar) \
+ for ((var) = TOR_TAILQ_LAST(head, headname); \
+ (var) != TOR_TAILQ_END(head) && \
+ ((tvar) = TOR_TAILQ_PREV(var, headname, field), 1); \
(var) = (tvar))
/*
* Tail queue functions.
*/
-#define TAILQ_INIT(head) do { \
+#define TOR_TAILQ_INIT(head) do { \
(head)->tqh_first = NULL; \
(head)->tqh_last = &(head)->tqh_first; \
} while (0)
-#define TAILQ_INSERT_HEAD(head, elm, field) do { \
+#define TOR_TAILQ_INSERT_HEAD(head, elm, field) do { \
if (((elm)->field.tqe_next = (head)->tqh_first) != NULL) \
(head)->tqh_first->field.tqe_prev = \
&(elm)->field.tqe_next; \
@@ -394,14 +389,14 @@ struct { \
(elm)->field.tqe_prev = &(head)->tqh_first; \
} while (0)
-#define TAILQ_INSERT_TAIL(head, elm, field) do { \
+#define TOR_TAILQ_INSERT_TAIL(head, elm, field) do { \
(elm)->field.tqe_next = NULL; \
(elm)->field.tqe_prev = (head)->tqh_last; \
*(head)->tqh_last = (elm); \
(head)->tqh_last = &(elm)->field.tqe_next; \
} while (0)
-#define TAILQ_INSERT_AFTER(head, listelm, elm, field) do { \
+#define TOR_TAILQ_INSERT_AFTER(head, listelm, elm, field) do { \
if (((elm)->field.tqe_next = (listelm)->field.tqe_next) != NULL)\
(elm)->field.tqe_next->field.tqe_prev = \
&(elm)->field.tqe_next; \
@@ -411,25 +406,25 @@ struct { \
(elm)->field.tqe_prev = &(listelm)->field.tqe_next; \
} while (0)
-#define TAILQ_INSERT_BEFORE(listelm, elm, field) do { \
+#define TOR_TAILQ_INSERT_BEFORE(listelm, elm, field) do { \
(elm)->field.tqe_prev = (listelm)->field.tqe_prev; \
(elm)->field.tqe_next = (listelm); \
*(listelm)->field.tqe_prev = (elm); \
(listelm)->field.tqe_prev = &(elm)->field.tqe_next; \
} while (0)
-#define TAILQ_REMOVE(head, elm, field) do { \
+#define TOR_TAILQ_REMOVE(head, elm, field) do { \
if (((elm)->field.tqe_next) != NULL) \
(elm)->field.tqe_next->field.tqe_prev = \
(elm)->field.tqe_prev; \
else \
(head)->tqh_last = (elm)->field.tqe_prev; \
*(elm)->field.tqe_prev = (elm)->field.tqe_next; \
- _Q_INVALIDATE((elm)->field.tqe_prev); \
- _Q_INVALIDATE((elm)->field.tqe_next); \
+ TOR_Q_INVALIDATE_((elm)->field.tqe_prev); \
+ TOR_Q_INVALIDATE_((elm)->field.tqe_next); \
} while (0)
-#define TAILQ_REPLACE(head, elm, elm2, field) do { \
+#define TOR_TAILQ_REPLACE(head, elm, elm2, field) do { \
if (((elm2)->field.tqe_next = (elm)->field.tqe_next) != NULL) \
(elm2)->field.tqe_next->field.tqe_prev = \
&(elm2)->field.tqe_next; \
@@ -437,23 +432,23 @@ struct { \
(head)->tqh_last = &(elm2)->field.tqe_next; \
(elm2)->field.tqe_prev = (elm)->field.tqe_prev; \
*(elm2)->field.tqe_prev = (elm2); \
- _Q_INVALIDATE((elm)->field.tqe_prev); \
- _Q_INVALIDATE((elm)->field.tqe_next); \
+ TOR_Q_INVALIDATE_((elm)->field.tqe_prev); \
+ TOR_Q_INVALIDATE_((elm)->field.tqe_next); \
} while (0)
/*
* Circular queue definitions.
*/
-#define CIRCLEQ_HEAD(name, type) \
+#define TOR_CIRCLEQ_HEAD(name, type) \
struct name { \
struct type *cqh_first; /* first element */ \
struct type *cqh_last; /* last element */ \
}
-#define CIRCLEQ_HEAD_INITIALIZER(head) \
- { CIRCLEQ_END(&head), CIRCLEQ_END(&head) }
+#define TOR_CIRCLEQ_HEAD_INITIALIZER(head) \
+ { TOR_CIRCLEQ_END(&head), TOR_CIRCLEQ_END(&head) }
-#define CIRCLEQ_ENTRY(type) \
+#define TOR_CIRCLEQ_ENTRY(type) \
struct { \
struct type *cqe_next; /* next element */ \
struct type *cqe_prev; /* previous element */ \
@@ -462,112 +457,112 @@ struct { \
/*
* Circular queue access methods
*/
-#define CIRCLEQ_FIRST(head) ((head)->cqh_first)
-#define CIRCLEQ_LAST(head) ((head)->cqh_last)
-#define CIRCLEQ_END(head) ((void *)(head))
-#define CIRCLEQ_NEXT(elm, field) ((elm)->field.cqe_next)
-#define CIRCLEQ_PREV(elm, field) ((elm)->field.cqe_prev)
-#define CIRCLEQ_EMPTY(head) \
- (CIRCLEQ_FIRST(head) == CIRCLEQ_END(head))
-
-#define CIRCLEQ_FOREACH(var, head, field) \
- for((var) = CIRCLEQ_FIRST(head); \
- (var) != CIRCLEQ_END(head); \
- (var) = CIRCLEQ_NEXT(var, field))
-
-#define CIRCLEQ_FOREACH_SAFE(var, head, field, tvar) \
- for ((var) = CIRCLEQ_FIRST(head); \
- (var) != CIRCLEQ_END(head) && \
- ((tvar) = CIRCLEQ_NEXT(var, field), 1); \
+#define TOR_CIRCLEQ_FIRST(head) ((head)->cqh_first)
+#define TOR_CIRCLEQ_LAST(head) ((head)->cqh_last)
+#define TOR_CIRCLEQ_END(head) ((void *)(head))
+#define TOR_CIRCLEQ_NEXT(elm, field) ((elm)->field.cqe_next)
+#define TOR_CIRCLEQ_PREV(elm, field) ((elm)->field.cqe_prev)
+#define TOR_CIRCLEQ_EMPTY(head) \
+ (TOR_CIRCLEQ_FIRST(head) == TOR_CIRCLEQ_END(head))
+
+#define TOR_CIRCLEQ_FOREACH(var, head, field) \
+ for((var) = TOR_CIRCLEQ_FIRST(head); \
+ (var) != TOR_CIRCLEQ_END(head); \
+ (var) = TOR_CIRCLEQ_NEXT(var, field))
+
+#define TOR_CIRCLEQ_FOREACH_SAFE(var, head, field, tvar) \
+ for ((var) = TOR_CIRCLEQ_FIRST(head); \
+ (var) != TOR_CIRCLEQ_END(head) && \
+ ((tvar) = TOR_CIRCLEQ_NEXT(var, field), 1); \
(var) = (tvar))
-#define CIRCLEQ_FOREACH_REVERSE(var, head, field) \
- for((var) = CIRCLEQ_LAST(head); \
- (var) != CIRCLEQ_END(head); \
- (var) = CIRCLEQ_PREV(var, field))
+#define TOR_CIRCLEQ_FOREACH_REVERSE(var, head, field) \
+ for((var) = TOR_CIRCLEQ_LAST(head); \
+ (var) != TOR_CIRCLEQ_END(head); \
+ (var) = TOR_CIRCLEQ_PREV(var, field))
-#define CIRCLEQ_FOREACH_REVERSE_SAFE(var, head, headname, field, tvar) \
- for ((var) = CIRCLEQ_LAST(head, headname); \
- (var) != CIRCLEQ_END(head) && \
- ((tvar) = CIRCLEQ_PREV(var, headname, field), 1); \
+#define TOR_CIRCLEQ_FOREACH_REVERSE_SAFE(var, head, headname, field, tvar) \
+ for ((var) = TOR_CIRCLEQ_LAST(head, headname); \
+ (var) != TOR_CIRCLEQ_END(head) && \
+ ((tvar) = TOR_CIRCLEQ_PREV(var, headname, field), 1); \
(var) = (tvar))
/*
* Circular queue functions.
*/
-#define CIRCLEQ_INIT(head) do { \
- (head)->cqh_first = CIRCLEQ_END(head); \
- (head)->cqh_last = CIRCLEQ_END(head); \
+#define TOR_CIRCLEQ_INIT(head) do { \
+ (head)->cqh_first = TOR_CIRCLEQ_END(head); \
+ (head)->cqh_last = TOR_CIRCLEQ_END(head); \
} while (0)
-#define CIRCLEQ_INSERT_AFTER(head, listelm, elm, field) do { \
+#define TOR_CIRCLEQ_INSERT_AFTER(head, listelm, elm, field) do { \
(elm)->field.cqe_next = (listelm)->field.cqe_next; \
(elm)->field.cqe_prev = (listelm); \
- if ((listelm)->field.cqe_next == CIRCLEQ_END(head)) \
+ if ((listelm)->field.cqe_next == TOR_CIRCLEQ_END(head)) \
(head)->cqh_last = (elm); \
else \
(listelm)->field.cqe_next->field.cqe_prev = (elm); \
(listelm)->field.cqe_next = (elm); \
} while (0)
-#define CIRCLEQ_INSERT_BEFORE(head, listelm, elm, field) do { \
+#define TOR_CIRCLEQ_INSERT_BEFORE(head, listelm, elm, field) do { \
(elm)->field.cqe_next = (listelm); \
(elm)->field.cqe_prev = (listelm)->field.cqe_prev; \
- if ((listelm)->field.cqe_prev == CIRCLEQ_END(head)) \
+ if ((listelm)->field.cqe_prev == TOR_CIRCLEQ_END(head)) \
(head)->cqh_first = (elm); \
else \
(listelm)->field.cqe_prev->field.cqe_next = (elm); \
(listelm)->field.cqe_prev = (elm); \
} while (0)
-#define CIRCLEQ_INSERT_HEAD(head, elm, field) do { \
+#define TOR_CIRCLEQ_INSERT_HEAD(head, elm, field) do { \
(elm)->field.cqe_next = (head)->cqh_first; \
- (elm)->field.cqe_prev = CIRCLEQ_END(head); \
- if ((head)->cqh_last == CIRCLEQ_END(head)) \
+ (elm)->field.cqe_prev = TOR_CIRCLEQ_END(head); \
+ if ((head)->cqh_last == TOR_CIRCLEQ_END(head)) \
(head)->cqh_last = (elm); \
else \
(head)->cqh_first->field.cqe_prev = (elm); \
(head)->cqh_first = (elm); \
} while (0)
-#define CIRCLEQ_INSERT_TAIL(head, elm, field) do { \
- (elm)->field.cqe_next = CIRCLEQ_END(head); \
+#define TOR_CIRCLEQ_INSERT_TAIL(head, elm, field) do { \
+ (elm)->field.cqe_next = TOR_CIRCLEQ_END(head); \
(elm)->field.cqe_prev = (head)->cqh_last; \
- if ((head)->cqh_first == CIRCLEQ_END(head)) \
+ if ((head)->cqh_first == TOR_CIRCLEQ_END(head)) \
(head)->cqh_first = (elm); \
else \
(head)->cqh_last->field.cqe_next = (elm); \
(head)->cqh_last = (elm); \
} while (0)
-#define CIRCLEQ_REMOVE(head, elm, field) do { \
- if ((elm)->field.cqe_next == CIRCLEQ_END(head)) \
+#define TOR_CIRCLEQ_REMOVE(head, elm, field) do { \
+ if ((elm)->field.cqe_next == TOR_CIRCLEQ_END(head)) \
(head)->cqh_last = (elm)->field.cqe_prev; \
else \
(elm)->field.cqe_next->field.cqe_prev = \
(elm)->field.cqe_prev; \
- if ((elm)->field.cqe_prev == CIRCLEQ_END(head)) \
+ if ((elm)->field.cqe_prev == TOR_CIRCLEQ_END(head)) \
(head)->cqh_first = (elm)->field.cqe_next; \
else \
(elm)->field.cqe_prev->field.cqe_next = \
(elm)->field.cqe_next; \
- _Q_INVALIDATE((elm)->field.cqe_prev); \
- _Q_INVALIDATE((elm)->field.cqe_next); \
+ TOR_Q_INVALIDATE_((elm)->field.cqe_prev); \
+ TOR_Q_INVALIDATE_((elm)->field.cqe_next); \
} while (0)
-#define CIRCLEQ_REPLACE(head, elm, elm2, field) do { \
+#define TOR_CIRCLEQ_REPLACE(head, elm, elm2, field) do { \
if (((elm2)->field.cqe_next = (elm)->field.cqe_next) == \
- CIRCLEQ_END(head)) \
+ TOR_CIRCLEQ_END(head)) \
(head).cqh_last = (elm2); \
else \
(elm2)->field.cqe_next->field.cqe_prev = (elm2); \
if (((elm2)->field.cqe_prev = (elm)->field.cqe_prev) == \
- CIRCLEQ_END(head)) \
+ TOR_CIRCLEQ_END(head)) \
(head).cqh_first = (elm2); \
else \
(elm2)->field.cqe_prev->field.cqe_next = (elm2); \
- _Q_INVALIDATE((elm)->field.cqe_prev); \
- _Q_INVALIDATE((elm)->field.cqe_next); \
+ TOR_Q_INVALIDATE_((elm)->field.cqe_prev); \
+ TOR_Q_INVALIDATE_((elm)->field.cqe_next); \
} while (0)
#endif /* !_SYS_QUEUE_H_ */
diff --git a/src/or/buffers.c b/src/or/buffers.c
index 7868a45488..e5fac9172d 100644
--- a/src/or/buffers.c
+++ b/src/or/buffers.c
@@ -335,11 +335,11 @@ buf_dump_freelist_sizes(int severity)
{
#ifdef ENABLE_BUF_FREELISTS
int i;
- log(severity, LD_MM, "====== Buffer freelists:");
+ tor_log(severity, LD_MM, "====== Buffer freelists:");
for (i = 0; freelists[i].alloc_size; ++i) {
uint64_t total = ((uint64_t)freelists[i].cur_length) *
freelists[i].alloc_size;
- log(severity, LD_MM,
+ tor_log(severity, LD_MM,
U64_FORMAT" bytes in %d %d-byte chunks ["U64_FORMAT
" misses; "U64_FORMAT" frees; "U64_FORMAT" hits]",
U64_PRINTF_ARG(total),
@@ -348,7 +348,7 @@ buf_dump_freelist_sizes(int severity)
U64_PRINTF_ARG(freelists[i].n_free),
U64_PRINTF_ARG(freelists[i].n_hit));
}
- log(severity, LD_MM, U64_FORMAT" allocations in non-freelist sizes",
+ tor_log(severity, LD_MM, U64_FORMAT" allocations in non-freelist sizes",
U64_PRINTF_ARG(n_freelist_miss));
#else
(void)severity;
diff --git a/src/or/channel.c b/src/or/channel.c
index 7781622977..104b018cf4 100644
--- a/src/or/channel.c
+++ b/src/or/channel.c
@@ -33,7 +33,7 @@
typedef struct cell_queue_entry_s cell_queue_entry_t;
struct cell_queue_entry_s {
- SIMPLEQ_ENTRY(cell_queue_entry_s) next;
+ TOR_SIMPLEQ_ENTRY(cell_queue_entry_s) next;
enum {
CELL_QUEUE_FIXED,
CELL_QUEUE_VAR,
@@ -89,7 +89,7 @@ HT_HEAD(channel_idmap, channel_idmap_entry_s) channel_identity_map =
typedef struct channel_idmap_entry_s {
HT_ENTRY(channel_idmap_entry_s) node;
uint8_t digest[DIGEST_LEN];
- LIST_HEAD(channel_list_s, channel_s) channel_list;
+ TOR_LIST_HEAD(channel_list_s, channel_s) channel_list;
} channel_idmap_entry_t;
static INLINE unsigned
@@ -554,10 +554,10 @@ channel_add_to_digest_map(channel_t *chan)
if (! ent) {
ent = tor_malloc(sizeof(channel_idmap_entry_t));
memcpy(ent->digest, chan->identity_digest, DIGEST_LEN);
- LIST_INIT(&ent->channel_list);
+ TOR_LIST_INIT(&ent->channel_list);
HT_INSERT(channel_idmap, &channel_identity_map, ent);
}
- LIST_INSERT_HEAD(&ent->channel_list, chan, next_with_same_id);
+ TOR_LIST_INSERT_HEAD(&ent->channel_list, chan, next_with_same_id);
log_debug(LD_CHANNEL,
"Added channel %p (global ID " U64_FORMAT ") "
@@ -612,7 +612,7 @@ channel_remove_from_digest_map(channel_t *chan)
#endif
/* Pull it out of its list, wherever that list is */
- LIST_REMOVE(chan, next_with_same_id);
+ TOR_LIST_REMOVE(chan, next_with_same_id);
memcpy(search.digest, chan->identity_digest, DIGEST_LEN);
ent = HT_FIND(channel_idmap, &channel_identity_map, &search);
@@ -621,7 +621,7 @@ channel_remove_from_digest_map(channel_t *chan)
if (ent) {
/* Okay, it's here */
- if (LIST_EMPTY(&ent->channel_list)) {
+ if (TOR_LIST_EMPTY(&ent->channel_list)) {
HT_REMOVE(channel_idmap, &channel_identity_map, ent);
tor_free(ent);
}
@@ -691,7 +691,7 @@ channel_find_by_remote_digest(const char *identity_digest)
memcpy(search.digest, identity_digest, DIGEST_LEN);
ent = HT_FIND(channel_idmap, &channel_identity_map, &search);
if (ent) {
- rv = LIST_FIRST(&ent->channel_list);
+ rv = TOR_LIST_FIRST(&ent->channel_list);
}
return rv;
@@ -709,7 +709,7 @@ channel_next_with_digest(channel_t *chan)
{
tor_assert(chan);
- return LIST_NEXT(chan, next_with_same_id);
+ return TOR_LIST_NEXT(chan, next_with_same_id);
}
/**
@@ -735,8 +735,8 @@ channel_init(channel_t *chan)
chan->next_circ_id = crypto_rand_int(1 << 15);
/* Initialize queues. */
- SIMPLEQ_INIT(&chan->incoming_queue);
- SIMPLEQ_INIT(&chan->outgoing_queue);
+ TOR_SIMPLEQ_INIT(&chan->incoming_queue);
+ TOR_SIMPLEQ_INIT(&chan->outgoing_queue);
/* Initialize list entries. */
memset(&chan->next_with_same_id, 0, sizeof(chan->next_with_same_id));
@@ -879,16 +879,16 @@ channel_force_free(channel_t *chan)
}
/* We might still have a cell queue; kill it */
- SIMPLEQ_FOREACH_SAFE(cell, &chan->incoming_queue, next, cell_tmp) {
+ TOR_SIMPLEQ_FOREACH_SAFE(cell, &chan->incoming_queue, next, cell_tmp) {
cell_queue_entry_free(cell, 0);
}
- SIMPLEQ_INIT(&chan->incoming_queue);
+ TOR_SIMPLEQ_INIT(&chan->incoming_queue);
/* Outgoing cell queue is similar, but we can have to free packed cells */
- SIMPLEQ_FOREACH_SAFE(cell, &chan->outgoing_queue, next, cell_tmp) {
+ TOR_SIMPLEQ_FOREACH_SAFE(cell, &chan->outgoing_queue, next, cell_tmp) {
cell_queue_entry_free(cell, 0);
}
- SIMPLEQ_INIT(&chan->outgoing_queue);
+ TOR_SIMPLEQ_INIT(&chan->outgoing_queue);
tor_free(chan);
}
@@ -1051,7 +1051,7 @@ channel_set_cell_handlers(channel_t *chan,
chan->var_cell_handler = var_cell_handler;
/* Re-run the queue if we have one and there's any reason to */
- if (! SIMPLEQ_EMPTY(&chan->incoming_queue) &&
+ if (! TOR_SIMPLEQ_EMPTY(&chan->incoming_queue) &&
try_again &&
(chan->cell_handler ||
chan->var_cell_handler)) channel_process_cells(chan);
@@ -1686,7 +1686,7 @@ channel_write_cell_queue_entry(channel_t *chan, cell_queue_entry_t *q)
}
/* Can we send it right out? If so, try */
- if (SIMPLEQ_EMPTY(&chan->outgoing_queue) &&
+ if (TOR_SIMPLEQ_EMPTY(&chan->outgoing_queue) &&
chan->state == CHANNEL_STATE_OPEN) {
/* Pick the right write function for this cell type and save the result */
switch (q->type) {
@@ -1728,7 +1728,7 @@ channel_write_cell_queue_entry(channel_t *chan, cell_queue_entry_t *q)
* used the stack.
*/
tmp = cell_queue_entry_dup(q);
- SIMPLEQ_INSERT_TAIL(&chan->outgoing_queue, tmp, next);
+ TOR_SIMPLEQ_INSERT_TAIL(&chan->outgoing_queue, tmp, next);
/* Try to process the queue? */
if (chan->state == CHANNEL_STATE_OPEN) channel_flush_cells(chan);
}
@@ -1914,15 +1914,15 @@ channel_change_state(channel_t *chan, channel_state_t to_state)
channel_do_open_actions(chan);
/* Check for queued cells to process */
- if (! SIMPLEQ_EMPTY(&chan->incoming_queue))
+ if (! TOR_SIMPLEQ_EMPTY(&chan->incoming_queue))
channel_process_cells(chan);
- if (! SIMPLEQ_EMPTY(&chan->outgoing_queue))
+ if (! TOR_SIMPLEQ_EMPTY(&chan->outgoing_queue))
channel_flush_cells(chan);
} else if (to_state == CHANNEL_STATE_CLOSED ||
to_state == CHANNEL_STATE_ERROR) {
/* Assert that all queues are empty */
- tor_assert(SIMPLEQ_EMPTY(&chan->incoming_queue));
- tor_assert(SIMPLEQ_EMPTY(&chan->outgoing_queue));
+ tor_assert(TOR_SIMPLEQ_EMPTY(&chan->incoming_queue));
+ tor_assert(TOR_SIMPLEQ_EMPTY(&chan->outgoing_queue));
}
}
@@ -2096,7 +2096,7 @@ channel_flush_some_cells_from_outgoing_queue(channel_t *chan,
/* If we aren't in CHANNEL_STATE_OPEN, nothing goes through */
if (chan->state == CHANNEL_STATE_OPEN) {
while ((unlimited || num_cells > flushed) &&
- NULL != (q = SIMPLEQ_FIRST(&chan->outgoing_queue))) {
+ NULL != (q = TOR_SIMPLEQ_FIRST(&chan->outgoing_queue))) {
if (1) {
/*
@@ -2185,7 +2185,7 @@ channel_flush_some_cells_from_outgoing_queue(channel_t *chan,
}
/* if q got NULLed out, we used it and should remove the queue entry */
- if (!q) SIMPLEQ_REMOVE_HEAD(&chan->outgoing_queue, next);
+ if (!q) TOR_SIMPLEQ_REMOVE_HEAD(&chan->outgoing_queue, next);
/* No cell removed from list, so we can't go on any further */
else break;
}
@@ -2193,7 +2193,7 @@ channel_flush_some_cells_from_outgoing_queue(channel_t *chan,
}
/* Did we drain the queue? */
- if (SIMPLEQ_EMPTY(&chan->outgoing_queue)) {
+ if (TOR_SIMPLEQ_EMPTY(&chan->outgoing_queue)) {
channel_timestamp_drained(chan);
}
@@ -2227,7 +2227,7 @@ channel_more_to_flush(channel_t *chan)
tor_assert(chan);
/* Check if we have any queued */
- if (! SIMPLEQ_EMPTY(&chan->incoming_queue))
+ if (! TOR_SIMPLEQ_EMPTY(&chan->incoming_queue))
return 1;
/* Check if any circuits would like to queue some */
@@ -2435,13 +2435,13 @@ channel_process_cells(channel_t *chan)
if (!(chan->cell_handler ||
chan->var_cell_handler)) return;
/* Nothing we can do if we have no cells */
- if (SIMPLEQ_EMPTY(&chan->incoming_queue)) return;
+ if (TOR_SIMPLEQ_EMPTY(&chan->incoming_queue)) return;
/*
* Process cells until we're done or find one we have no current handler
* for.
*/
- while (NULL != (q = SIMPLEQ_FIRST(&chan->incoming_queue))) {
+ while (NULL != (q = TOR_SIMPLEQ_FIRST(&chan->incoming_queue))) {
tor_assert(q);
tor_assert(q->type == CELL_QUEUE_FIXED ||
q->type == CELL_QUEUE_VAR);
@@ -2449,7 +2449,7 @@ channel_process_cells(channel_t *chan)
if (q->type == CELL_QUEUE_FIXED &&
chan->cell_handler) {
/* Handle a fixed-length cell */
- SIMPLEQ_REMOVE_HEAD(&chan->incoming_queue, next);
+ TOR_SIMPLEQ_REMOVE_HEAD(&chan->incoming_queue, next);
tor_assert(q->u.fixed.cell);
log_debug(LD_CHANNEL,
"Processing incoming cell_t %p for channel %p (global ID "
@@ -2461,7 +2461,7 @@ channel_process_cells(channel_t *chan)
} else if (q->type == CELL_QUEUE_VAR &&
chan->var_cell_handler) {
/* Handle a variable-length cell */
- SIMPLEQ_REMOVE_HEAD(&chan->incoming_queue, next);
+ TOR_SIMPLEQ_REMOVE_HEAD(&chan->incoming_queue, next);
tor_assert(q->u.var.var_cell);
log_debug(LD_CHANNEL,
"Processing incoming var_cell_t %p for channel %p (global ID "
@@ -2496,7 +2496,7 @@ channel_queue_cell(channel_t *chan, cell_t *cell)
/* Do we need to queue it, or can we just call the handler right away? */
if (!(chan->cell_handler)) need_to_queue = 1;
- if (! SIMPLEQ_EMPTY(&chan->incoming_queue))
+ if (! TOR_SIMPLEQ_EMPTY(&chan->incoming_queue))
need_to_queue = 1;
/* Timestamp for receiving */
@@ -2522,7 +2522,7 @@ channel_queue_cell(channel_t *chan, cell_t *cell)
"(global ID " U64_FORMAT ")",
cell, chan,
U64_PRINTF_ARG(chan->global_identifier));
- SIMPLEQ_INSERT_TAIL(&chan->incoming_queue, q, next);
+ TOR_SIMPLEQ_INSERT_TAIL(&chan->incoming_queue, q, next);
if (chan->cell_handler ||
chan->var_cell_handler) {
channel_process_cells(chan);
@@ -2549,7 +2549,7 @@ channel_queue_var_cell(channel_t *chan, var_cell_t *var_cell)
/* Do we need to queue it, or can we just call the handler right away? */
if (!(chan->var_cell_handler)) need_to_queue = 1;
- if (! SIMPLEQ_EMPTY(&chan->incoming_queue))
+ if (! TOR_SIMPLEQ_EMPTY(&chan->incoming_queue))
need_to_queue = 1;
/* Timestamp for receiving */
@@ -2575,7 +2575,7 @@ channel_queue_var_cell(channel_t *chan, var_cell_t *var_cell)
"(global ID " U64_FORMAT ")",
var_cell, chan,
U64_PRINTF_ARG(chan->global_identifier));
- SIMPLEQ_INSERT_TAIL(&chan->incoming_queue, q, next);
+ TOR_SIMPLEQ_INSERT_TAIL(&chan->incoming_queue, q, next);
if (chan->cell_handler ||
chan->var_cell_handler) {
channel_process_cells(chan);
@@ -2636,10 +2636,10 @@ void
channel_dumpstats(int severity)
{
if (all_channels && smartlist_len(all_channels) > 0) {
- log(severity, LD_GENERAL,
+ tor_log(severity, LD_GENERAL,
"Dumping statistics about %d channels:",
smartlist_len(all_channels));
- log(severity, LD_GENERAL,
+ tor_log(severity, LD_GENERAL,
"%d are active, and %d are done and waiting for cleanup",
(active_channels != NULL) ?
smartlist_len(active_channels) : 0,
@@ -2649,10 +2649,10 @@ channel_dumpstats(int severity)
SMARTLIST_FOREACH(all_channels, channel_t *, chan,
channel_dump_statistics(chan, severity));
- log(severity, LD_GENERAL,
+ tor_log(severity, LD_GENERAL,
"Done spamming about channels now");
} else {
- log(severity, LD_GENERAL,
+ tor_log(severity, LD_GENERAL,
"No channels to dump");
}
}
@@ -2668,10 +2668,10 @@ void
channel_listener_dumpstats(int severity)
{
if (all_listeners && smartlist_len(all_listeners) > 0) {
- log(severity, LD_GENERAL,
+ tor_log(severity, LD_GENERAL,
"Dumping statistics about %d channel listeners:",
smartlist_len(all_listeners));
- log(severity, LD_GENERAL,
+ tor_log(severity, LD_GENERAL,
"%d are active and %d are done and waiting for cleanup",
(active_listeners != NULL) ?
smartlist_len(active_listeners) : 0,
@@ -2681,10 +2681,10 @@ channel_listener_dumpstats(int severity)
SMARTLIST_FOREACH(all_listeners, channel_listener_t *, chan_l,
channel_listener_dump_statistics(chan_l, severity));
- log(severity, LD_GENERAL,
+ tor_log(severity, LD_GENERAL,
"Done spamming about channel listeners now");
} else {
- log(severity, LD_GENERAL,
+ tor_log(severity, LD_GENERAL,
"No channel listeners to dump");
}
}
@@ -3115,7 +3115,7 @@ chan_cell_queue_len(const chan_cell_queue_t *queue)
{
int r = 0;
cell_queue_entry_t *cell;
- SIMPLEQ_FOREACH(cell, queue, next)
+ TOR_SIMPLEQ_FOREACH(cell, queue, next)
++r;
return r;
}
@@ -3139,13 +3139,13 @@ channel_dump_statistics(channel_t *chan, int severity)
age = (double)(now - chan->timestamp_created);
- log(severity, LD_GENERAL,
+ tor_log(severity, LD_GENERAL,
"Channel " U64_FORMAT " (at %p) with transport %s is in state "
"%s (%d)",
U64_PRINTF_ARG(chan->global_identifier), chan,
channel_describe_transport(chan),
channel_state_to_string(chan->state), chan->state);
- log(severity, LD_GENERAL,
+ tor_log(severity, LD_GENERAL,
" * Channel " U64_FORMAT " was created at " U64_FORMAT
" (" U64_FORMAT " seconds ago) "
"and last active at " U64_FORMAT " (" U64_FORMAT " seconds ago)",
@@ -3158,14 +3158,14 @@ channel_dump_statistics(channel_t *chan, int severity)
/* Handle digest and nickname */
if (!tor_digest_is_zero(chan->identity_digest)) {
if (chan->nickname) {
- log(severity, LD_GENERAL,
+ tor_log(severity, LD_GENERAL,
" * Channel " U64_FORMAT " says it is connected "
"to an OR with digest %s and nickname %s",
U64_PRINTF_ARG(chan->global_identifier),
hex_str(chan->identity_digest, DIGEST_LEN),
chan->nickname);
} else {
- log(severity, LD_GENERAL,
+ tor_log(severity, LD_GENERAL,
" * Channel " U64_FORMAT " says it is connected "
"to an OR with digest %s and no known nickname",
U64_PRINTF_ARG(chan->global_identifier),
@@ -3173,13 +3173,13 @@ channel_dump_statistics(channel_t *chan, int severity)
}
} else {
if (chan->nickname) {
- log(severity, LD_GENERAL,
+ tor_log(severity, LD_GENERAL,
" * Channel " U64_FORMAT " does not know the digest"
" of the OR it is connected to, but reports its nickname is %s",
U64_PRINTF_ARG(chan->global_identifier),
chan->nickname);
} else {
- log(severity, LD_GENERAL,
+ tor_log(severity, LD_GENERAL,
" * Channel " U64_FORMAT " does not know the digest"
" or the nickname of the OR it is connected to",
U64_PRINTF_ARG(chan->global_identifier));
@@ -3191,7 +3191,7 @@ channel_dump_statistics(channel_t *chan, int severity)
if (have_remote_addr) {
char *actual = tor_strdup(channel_get_actual_remote_descr(chan));
remote_addr_str = tor_dup_addr(&remote_addr);
- log(severity, LD_GENERAL,
+ tor_log(severity, LD_GENERAL,
" * Channel " U64_FORMAT " says its remote address"
" is %s, and gives a canonical description of \"%s\" and an "
"actual description of \"%s\"",
@@ -3203,7 +3203,7 @@ channel_dump_statistics(channel_t *chan, int severity)
tor_free(actual);
} else {
char *actual = tor_strdup(channel_get_actual_remote_descr(chan));
- log(severity, LD_GENERAL,
+ tor_log(severity, LD_GENERAL,
" * Channel " U64_FORMAT " does not know its remote "
"address, but gives a canonical description of \"%s\" and an "
"actual description of \"%s\"",
@@ -3214,7 +3214,7 @@ channel_dump_statistics(channel_t *chan, int severity)
}
/* Handle marks */
- log(severity, LD_GENERAL,
+ tor_log(severity, LD_GENERAL,
" * Channel " U64_FORMAT " has these marks: %s %s %s "
"%s %s %s",
U64_PRINTF_ARG(chan->global_identifier),
@@ -3233,7 +3233,7 @@ channel_dump_statistics(channel_t *chan, int severity)
"incoming" : "outgoing");
/* Describe queues */
- log(severity, LD_GENERAL,
+ tor_log(severity, LD_GENERAL,
" * Channel " U64_FORMAT " has %d queued incoming cells"
" and %d queued outgoing cells",
U64_PRINTF_ARG(chan->global_identifier),
@@ -3241,7 +3241,7 @@ channel_dump_statistics(channel_t *chan, int severity)
chan_cell_queue_len(&chan->outgoing_queue));
/* Describe circuits */
- log(severity, LD_GENERAL,
+ tor_log(severity, LD_GENERAL,
" * Channel " U64_FORMAT " has %d active circuits out of"
" %d in total",
U64_PRINTF_ARG(chan->global_identifier),
@@ -3251,25 +3251,25 @@ channel_dump_statistics(channel_t *chan, int severity)
circuitmux_num_circuits(chan->cmux) : 0);
/* Describe timestamps */
- log(severity, LD_GENERAL,
+ tor_log(severity, LD_GENERAL,
" * Channel " U64_FORMAT " was last used by a "
"client at " U64_FORMAT " (" U64_FORMAT " seconds ago)",
U64_PRINTF_ARG(chan->global_identifier),
U64_PRINTF_ARG(chan->timestamp_client),
U64_PRINTF_ARG(now - chan->timestamp_client));
- log(severity, LD_GENERAL,
+ tor_log(severity, LD_GENERAL,
" * Channel " U64_FORMAT " was last drained at "
U64_FORMAT " (" U64_FORMAT " seconds ago)",
U64_PRINTF_ARG(chan->global_identifier),
U64_PRINTF_ARG(chan->timestamp_drained),
U64_PRINTF_ARG(now - chan->timestamp_drained));
- log(severity, LD_GENERAL,
+ tor_log(severity, LD_GENERAL,
" * Channel " U64_FORMAT " last received a cell "
"at " U64_FORMAT " (" U64_FORMAT " seconds ago)",
U64_PRINTF_ARG(chan->global_identifier),
U64_PRINTF_ARG(chan->timestamp_recv),
U64_PRINTF_ARG(now - chan->timestamp_recv));
- log(severity, LD_GENERAL,
+ tor_log(severity, LD_GENERAL,
" * Channel " U64_FORMAT " last trasmitted a cell "
"at " U64_FORMAT " (" U64_FORMAT " seconds ago)",
U64_PRINTF_ARG(chan->global_identifier),
@@ -3277,7 +3277,7 @@ channel_dump_statistics(channel_t *chan, int severity)
U64_PRINTF_ARG(now - chan->timestamp_xmit));
/* Describe counters and rates */
- log(severity, LD_GENERAL,
+ tor_log(severity, LD_GENERAL,
" * Channel " U64_FORMAT " has received "
U64_FORMAT " cells and transmitted " U64_FORMAT,
U64_PRINTF_ARG(chan->global_identifier),
@@ -3288,13 +3288,13 @@ channel_dump_statistics(channel_t *chan, int severity)
if (chan->n_cells_recved > 0) {
avg = (double)(chan->n_cells_recved) / age;
if (avg >= 1.0) {
- log(severity, LD_GENERAL,
+ tor_log(severity, LD_GENERAL,
" * Channel " U64_FORMAT " has averaged %f "
"cells received per second",
U64_PRINTF_ARG(chan->global_identifier), avg);
} else if (avg >= 0.0) {
interval = 1.0 / avg;
- log(severity, LD_GENERAL,
+ tor_log(severity, LD_GENERAL,
" * Channel " U64_FORMAT " has averaged %f "
"seconds between received cells",
U64_PRINTF_ARG(chan->global_identifier), interval);
@@ -3303,13 +3303,13 @@ channel_dump_statistics(channel_t *chan, int severity)
if (chan->n_cells_xmitted > 0) {
avg = (double)(chan->n_cells_xmitted) / age;
if (avg >= 1.0) {
- log(severity, LD_GENERAL,
+ tor_log(severity, LD_GENERAL,
" * Channel " U64_FORMAT " has averaged %f "
"cells transmitted per second",
U64_PRINTF_ARG(chan->global_identifier), avg);
} else if (avg >= 0.0) {
interval = 1.0 / avg;
- log(severity, LD_GENERAL,
+ tor_log(severity, LD_GENERAL,
" * Channel " U64_FORMAT " has averaged %f "
"seconds between transmitted cells",
U64_PRINTF_ARG(chan->global_identifier), interval);
@@ -3337,13 +3337,13 @@ channel_listener_dump_statistics(channel_listener_t *chan_l, int severity)
age = (double)(now - chan_l->timestamp_created);
- log(severity, LD_GENERAL,
+ tor_log(severity, LD_GENERAL,
"Channel listener " U64_FORMAT " (at %p) with transport %s is in "
"state %s (%d)",
U64_PRINTF_ARG(chan_l->global_identifier), chan_l,
channel_listener_describe_transport(chan_l),
channel_listener_state_to_string(chan_l->state), chan_l->state);
- log(severity, LD_GENERAL,
+ tor_log(severity, LD_GENERAL,
" * Channel listener " U64_FORMAT " was created at " U64_FORMAT
" (" U64_FORMAT " seconds ago) "
"and last active at " U64_FORMAT " (" U64_FORMAT " seconds ago)",
@@ -3353,7 +3353,7 @@ channel_listener_dump_statistics(channel_listener_t *chan_l, int severity)
U64_PRINTF_ARG(chan_l->timestamp_active),
U64_PRINTF_ARG(now - chan_l->timestamp_active));
- log(severity, LD_GENERAL,
+ tor_log(severity, LD_GENERAL,
" * Channel listener " U64_FORMAT " last accepted an incoming "
"channel at " U64_FORMAT " (" U64_FORMAT " seconds ago) "
"and has accepted " U64_FORMAT " channels in total",
@@ -3371,13 +3371,13 @@ channel_listener_dump_statistics(channel_listener_t *chan_l, int severity)
chan_l->n_accepted > 0) {
avg = (double)(chan_l->n_accepted) / age;
if (avg >= 1.0) {
- log(severity, LD_GENERAL,
+ tor_log(severity, LD_GENERAL,
" * Channel listener " U64_FORMAT " has averaged %f incoming "
"channels per second",
U64_PRINTF_ARG(chan_l->global_identifier), avg);
} else if (avg >= 0.0) {
interval = 1.0 / avg;
- log(severity, LD_GENERAL,
+ tor_log(severity, LD_GENERAL,
" * Channel listener " U64_FORMAT " has averaged %f seconds "
"between incoming channels",
U64_PRINTF_ARG(chan_l->global_identifier), interval);
@@ -3504,7 +3504,7 @@ channel_has_queued_writes(channel_t *chan)
tor_assert(chan);
tor_assert(chan->has_queued_writes);
- if (! SIMPLEQ_EMPTY(&chan->outgoing_queue)) {
+ if (! TOR_SIMPLEQ_EMPTY(&chan->outgoing_queue)) {
has_writes = 1;
} else {
/* Check with the lower layer */
diff --git a/src/or/channel.h b/src/or/channel.h
index 31bd519474..ec79888063 100644
--- a/src/or/channel.h
+++ b/src/or/channel.h
@@ -19,7 +19,7 @@ typedef void (*channel_cell_handler_fn_ptr)(channel_t *, cell_t *);
typedef void (*channel_var_cell_handler_fn_ptr)(channel_t *, var_cell_t *);
struct cell_queue_entry_s;
-SIMPLEQ_HEAD(chan_cell_queue, cell_queue_entry_s) incoming_queue;
+TOR_SIMPLEQ_HEAD(chan_cell_queue, cell_queue_entry_s) incoming_queue;
typedef struct chan_cell_queue chan_cell_queue_t;
/*
@@ -125,7 +125,7 @@ struct channel_s {
* Linked list of channels with the same identity digest, for the
* digest->channel map
*/
- LIST_ENTRY(channel_s) next_with_same_id;
+ TOR_LIST_ENTRY(channel_s) next_with_same_id;
/* List of incoming cells to handle */
chan_cell_queue_t incoming_queue;
diff --git a/src/or/circuitbuild.c b/src/or/circuitbuild.c
index b986243867..5a5a3afea7 100644
--- a/src/or/circuitbuild.c
+++ b/src/or/circuitbuild.c
@@ -67,7 +67,10 @@ static int entry_guard_inc_circ_attempt_count(entry_guard_t *guard);
static void pathbias_count_build_success(origin_circuit_t *circ);
static void pathbias_count_successful_close(origin_circuit_t *circ);
static void pathbias_count_collapse(origin_circuit_t *circ);
-static void pathbias_count_unusable(origin_circuit_t *circ);
+static void pathbias_count_use_failed(origin_circuit_t *circ);
+static void pathbias_measure_use_rate(entry_guard_t *guard);
+static void pathbias_measure_close_rate(entry_guard_t *guard);
+static void pathbias_scale_use_rates(entry_guard_t *guard);
/** This function tries to get a channel to the specified endpoint,
* and then calls command_setup_channel() to give it the right
@@ -821,9 +824,6 @@ circuit_send_next_onion_skin(origin_circuit_t *circ)
/* We're done with measurement circuits here. Just close them */
if (circ->base_.purpose == CIRCUIT_PURPOSE_C_MEASURE_TIMEOUT) {
- /* If a measurement circ ever gets back to us, consider it
- * succeeded for path bias */
- circ->path_state = PATH_STATE_USE_SUCCEEDED;
circuit_mark_for_close(TO_CIRCUIT(circ), END_CIRC_REASON_FINISHED);
}
return 0;
@@ -1176,53 +1176,93 @@ pathbias_get_scale_threshold(const or_options_t *options)
}
/**
- * The scale factor is the denominator for our scaling
- * of circuit counts for our path bias window.
+ * Compute the path bias scaling ratio from the consensus
+ * parameters pb_multfactor/pb_scalefactor.
*
- * Note that our use of doubles for the path bias state
- * file means that powers of 2 work best here.
+ * Returns a value in (0, 1.0] which we multiply our pathbias
+ * counts with to scale them down.
*/
+static double
+pathbias_get_scale_ratio(const or_options_t *options)
+{
+ /*
+ * The scale factor is the denominator for our scaling
+ * of circuit counts for our path bias window.
+ *
+ * Note that our use of doubles for the path bias state
+ * file means that powers of 2 work best here.
+ */
+ int denominator = networkstatus_get_param(NULL, "pb_scalefactor",
+ 2, 2, INT32_MAX);
+ (void) options;
+ /**
+ * The mult factor is the numerator for our scaling
+ * of circuit counts for our path bias window. It
+ * allows us to scale by fractions.
+ */
+ return networkstatus_get_param(NULL, "pb_multfactor",
+ 1, 1, denominator)/((double)denominator);
+}
+
+/** The minimum number of circuit usage attempts before we start
+ * thinking about warning about path use bias and dropping guards */
static int
-pathbias_get_scale_factor(const or_options_t *options)
+pathbias_get_min_use(const or_options_t *options)
+{
+#define DFLT_PATH_BIAS_MIN_USE 20
+ if (options->PathBiasUseThreshold >= 3)
+ return options->PathBiasUseThreshold;
+ else
+ return networkstatus_get_param(NULL, "pb_minuse",
+ DFLT_PATH_BIAS_MIN_USE,
+ 3, INT32_MAX);
+}
+
+/** The circuit use success rate below which we issue a notice */
+static double
+pathbias_get_notice_use_rate(const or_options_t *options)
{
-#define DFLT_PATH_BIAS_SCALE_FACTOR 2
- if (options->PathBiasScaleFactor >= 1)
- return options->PathBiasScaleFactor;
+#define DFLT_PATH_BIAS_NOTICE_USE_PCT 90
+ if (options->PathBiasNoticeUseRate >= 0.0)
+ return options->PathBiasNoticeUseRate;
else
- return networkstatus_get_param(NULL, "pb_scalefactor",
- DFLT_PATH_BIAS_SCALE_FACTOR, 1, INT32_MAX);
+ return networkstatus_get_param(NULL, "pb_noticeusepct",
+ DFLT_PATH_BIAS_NOTICE_USE_PCT,
+ 0, 100)/100.0;
}
/**
- * The mult factor is the numerator for our scaling
- * of circuit counts for our path bias window. It
- * allows us to scale by fractions.
+ * The extreme use rate is the rate at which we would drop the guard,
+ * if pb_dropguard is also set. Otherwise we just warn.
*/
-static int
-pathbias_get_mult_factor(const or_options_t *options)
+double
+pathbias_get_extreme_use_rate(const or_options_t *options)
{
-#define DFLT_PATH_BIAS_MULT_FACTOR 1
- if (options->PathBiasMultFactor >= 1)
- return options->PathBiasMultFactor;
+#define DFLT_PATH_BIAS_EXTREME_USE_PCT 70
+ if (options->PathBiasExtremeUseRate >= 0.0)
+ return options->PathBiasExtremeUseRate;
else
- return networkstatus_get_param(NULL, "pb_multfactor",
- DFLT_PATH_BIAS_MULT_FACTOR, 1,
- pathbias_get_scale_factor(options));
+ return networkstatus_get_param(NULL, "pb_extremeusepct",
+ DFLT_PATH_BIAS_EXTREME_USE_PCT,
+ 0, 100)/100.0;
}
/**
- * If this parameter is set to a true value (default), we use the
- * successful_circuits_closed. Otherwise, we use the success_count.
+ * This is the number of circuits at which we scale our
+ * use counts by mult_factor/scale_factor. Note, this count is
+ * not exact, as we only perform the scaling in the event
+ * of no integer truncation.
*/
static int
-pathbias_use_close_counts(const or_options_t *options)
+pathbias_get_scale_use_threshold(const or_options_t *options)
{
-#define DFLT_PATH_BIAS_USE_CLOSE_COUNTS 1
- if (options->PathBiasUseCloseCounts >= 0)
- return options->PathBiasUseCloseCounts;
+#define DFLT_PATH_BIAS_SCALE_USE_THRESHOLD 100
+ if (options->PathBiasScaleUseThreshold >= 10)
+ return options->PathBiasScaleUseThreshold;
else
- return networkstatus_get_param(NULL, "pb_useclosecounts",
- DFLT_PATH_BIAS_USE_CLOSE_COUNTS, 0, 1);
+ return networkstatus_get_param(NULL, "pb_scaleuse",
+ DFLT_PATH_BIAS_SCALE_USE_THRESHOLD,
+ 10, INT32_MAX);
}
/**
@@ -1238,10 +1278,14 @@ pathbias_state_to_string(path_state_t state)
return "build attempted";
case PATH_STATE_BUILD_SUCCEEDED:
return "build succeeded";
+ case PATH_STATE_USE_ATTEMPTED:
+ return "use attempted";
case PATH_STATE_USE_SUCCEEDED:
return "use succeeded";
case PATH_STATE_USE_FAILED:
return "use failed";
+ case PATH_STATE_ALREADY_COUNTED:
+ return "already counted";
}
return "unknown";
@@ -1303,6 +1347,24 @@ pathbias_should_count(origin_circuit_t *circ)
circ->base_.purpose == CIRCUIT_PURPOSE_S_REND_JOINED ||
(circ->base_.purpose >= CIRCUIT_PURPOSE_C_INTRODUCING &&
circ->base_.purpose <= CIRCUIT_PURPOSE_C_INTRODUCE_ACKED)) {
+
+ /* Check to see if the shouldcount result has changed due to a
+ * unexpected purpose change that would affect our results.
+ *
+ * The reason we check the path state too here is because for the
+ * cannibalized versions of these purposes, we count them as successful
+ * before their purpose change.
+ */
+ if (circ->pathbias_shouldcount == PATHBIAS_SHOULDCOUNT_COUNTED
+ && circ->path_state != PATH_STATE_ALREADY_COUNTED) {
+ log_info(LD_BUG,
+ "Circuit %d is now being ignored despite being counted "
+ "in the past. Purpose is %s, path state is %s",
+ circ->global_identifier,
+ circuit_purpose_to_string(circ->base_.purpose),
+ pathbias_state_to_string(circ->path_state));
+ }
+ circ->pathbias_shouldcount = PATHBIAS_SHOULDCOUNT_IGNORED;
return 0;
}
@@ -1325,9 +1387,33 @@ pathbias_should_count(origin_circuit_t *circ)
}
tor_fragile_assert();
}
+
+ /* Check to see if the shouldcount result has changed due to a
+ * unexpected change that would affect our results */
+ if (circ->pathbias_shouldcount == PATHBIAS_SHOULDCOUNT_COUNTED) {
+ log_info(LD_BUG,
+ "One-hop circuit %d is now being ignored despite being counted "
+ "in the past. Purpose is %s, path state is %s",
+ circ->global_identifier,
+ circuit_purpose_to_string(circ->base_.purpose),
+ pathbias_state_to_string(circ->path_state));
+ }
+ circ->pathbias_shouldcount = PATHBIAS_SHOULDCOUNT_IGNORED;
return 0;
}
+ /* Check to see if the shouldcount result has changed due to a
+ * unexpected purpose change that would affect our results */
+ if (circ->pathbias_shouldcount == PATHBIAS_SHOULDCOUNT_IGNORED) {
+ log_info(LD_BUG,
+ "Circuit %d is now being counted despite being ignored "
+ "in the past. Purpose is %s, path state is %s",
+ circ->global_identifier,
+ circuit_purpose_to_string(circ->base_.purpose),
+ pathbias_state_to_string(circ->path_state));
+ }
+ circ->pathbias_shouldcount = PATHBIAS_SHOULDCOUNT_COUNTED;
+
return 1;
}
@@ -1338,7 +1424,7 @@ pathbias_should_count(origin_circuit_t *circ)
* Also check for several potential error cases for bug #6475.
*/
static int
-pathbias_count_circ_attempt(origin_circuit_t *circ)
+pathbias_count_build_attempt(origin_circuit_t *circ)
{
#define CIRC_ATTEMPT_NOTICE_INTERVAL (600)
static ratelim_t circ_attempt_notice_limit =
@@ -1448,6 +1534,7 @@ pathbias_count_build_success(origin_circuit_t *circ)
if (circ->path_state == PATH_STATE_BUILD_ATTEMPTED) {
circ->path_state = PATH_STATE_BUILD_SUCCEEDED;
guard->circ_successes++;
+ entry_guards_changed();
log_info(LD_CIRC, "Got success count %f/%f for guard %s=%s",
guard->circ_successes, guard->circ_attempts,
@@ -1505,6 +1592,158 @@ pathbias_count_build_success(origin_circuit_t *circ)
}
/**
+ * Record an attempt to use a circuit. Changes the circuit's
+ * path state and update its guard's usage counter.
+ *
+ * Used for path bias usage accounting.
+ */
+void
+pathbias_count_use_attempt(origin_circuit_t *circ)
+{
+ entry_guard_t *guard;
+
+ if (!pathbias_should_count(circ)) {
+ return;
+ }
+
+ if (circ->path_state < PATH_STATE_BUILD_SUCCEEDED) {
+ log_notice(LD_BUG,
+ "Used circuit is in strange path state %s. "
+ "Circuit is a %s currently %s.",
+ pathbias_state_to_string(circ->path_state),
+ circuit_purpose_to_string(circ->base_.purpose),
+ circuit_state_to_string(circ->base_.state));
+ } else if (circ->path_state < PATH_STATE_USE_ATTEMPTED) {
+ guard = entry_guard_get_by_id_digest(
+ circ->cpath->extend_info->identity_digest);
+ if (guard) {
+ pathbias_measure_use_rate(guard);
+ pathbias_scale_use_rates(guard);
+ guard->use_attempts++;
+ entry_guards_changed();
+
+ log_debug(LD_CIRC,
+ "Marked circuit %d (%f/%f) as used for guard %s=%s.",
+ circ->global_identifier,
+ guard->use_successes, guard->use_attempts,
+ guard->nickname, hex_str(guard->identity, DIGEST_LEN));
+ }
+
+ circ->path_state = PATH_STATE_USE_ATTEMPTED;
+ } else {
+ /* Harmless but educational log message */
+ log_info(LD_CIRC,
+ "Used circuit %d is already in path state %s. "
+ "Circuit is a %s currently %s.",
+ circ->global_identifier,
+ pathbias_state_to_string(circ->path_state),
+ circuit_purpose_to_string(circ->base_.purpose),
+ circuit_state_to_string(circ->base_.state));
+ }
+
+ return;
+}
+
+/**
+ * Check the circuit's path state is appropriate and mark it as
+ * successfully used. Used for path bias usage accounting.
+ *
+ * We don't actually increment the guard's counters until
+ * pathbias_check_close(), because the circuit can still transition
+ * back to PATH_STATE_USE_ATTEMPTED if a stream fails later (this
+ * is done so we can probe the circuit for liveness at close).
+ */
+void
+pathbias_mark_use_success(origin_circuit_t *circ)
+{
+ if (!pathbias_should_count(circ)) {
+ return;
+ }
+
+ if (circ->path_state < PATH_STATE_USE_ATTEMPTED) {
+ log_notice(LD_BUG,
+ "Used circuit %d is in strange path state %s. "
+ "Circuit is a %s currently %s.",
+ circ->global_identifier,
+ pathbias_state_to_string(circ->path_state),
+ circuit_purpose_to_string(circ->base_.purpose),
+ circuit_state_to_string(circ->base_.state));
+
+ pathbias_count_use_attempt(circ);
+ }
+
+ /* We don't do any accounting at the guard until actual circuit close */
+ circ->path_state = PATH_STATE_USE_SUCCEEDED;
+
+ return;
+}
+
+/**
+ * If a stream ever detatches from a circuit in a retriable way,
+ * we need to mark this circuit as still needing either another
+ * successful stream, or in need of a probe.
+ *
+ * An adversary could let the first stream request succeed (ie the
+ * resolve), but then tag and timeout the remainder (via cell
+ * dropping), forcing them on new circuits.
+ *
+ * Rolling back the state will cause us to probe such circuits, which
+ * should lead to probe failures in the event of such tagging due to
+ * either unrecognized cells coming in while we wait for the probe,
+ * or the cipher state getting out of sync in the case of dropped cells.
+ */
+void
+pathbias_mark_use_rollback(origin_circuit_t *circ)
+{
+ if (circ->path_state == PATH_STATE_USE_SUCCEEDED) {
+ log_info(LD_CIRC,
+ "Rolling back pathbias use state to 'attempted' for detached "
+ "circuit %d", circ->global_identifier);
+ circ->path_state = PATH_STATE_USE_ATTEMPTED;
+ }
+}
+
+/**
+ * Actually count a circuit success towards a guard's usage counters
+ * if the path state is appropriate.
+ */
+static void
+pathbias_count_use_success(origin_circuit_t *circ)
+{
+ entry_guard_t *guard;
+
+ if (!pathbias_should_count(circ)) {
+ return;
+ }
+
+ if (circ->path_state != PATH_STATE_USE_SUCCEEDED) {
+ log_notice(LD_BUG,
+ "Successfully used circuit %d is in strange path state %s. "
+ "Circuit is a %s currently %s.",
+ circ->global_identifier,
+ pathbias_state_to_string(circ->path_state),
+ circuit_purpose_to_string(circ->base_.purpose),
+ circuit_state_to_string(circ->base_.state));
+ } else {
+ guard = entry_guard_get_by_id_digest(
+ circ->cpath->extend_info->identity_digest);
+ if (guard) {
+ guard->use_successes++;
+ entry_guards_changed();
+
+ log_debug(LD_CIRC,
+ "Marked circuit %d (%f/%f) as used successfully for guard "
+ "%s=%s.",
+ circ->global_identifier, guard->use_successes,
+ guard->use_attempts, guard->nickname,
+ hex_str(guard->identity, DIGEST_LEN));
+ }
+ }
+
+ return;
+}
+
+/**
* Send a probe down a circuit that the client attempted to use,
* but for which the stream timed out/failed. The probe is a
* RELAY_BEGIN cell with a 0.a.b.c destination address, which
@@ -1554,6 +1793,16 @@ pathbias_send_usable_probe(circuit_t *circ)
return -1;
}
+ /* Can't probe if the channel isn't open */
+ if (circ->n_chan == NULL ||
+ (circ->n_chan->state != CHANNEL_STATE_OPEN
+ && circ->n_chan->state != CHANNEL_STATE_MAINT)) {
+ log_info(LD_CIRC,
+ "Skipping pathbias probe for circuit %d: Channel is not open.",
+ ocirc->global_identifier);
+ return -1;
+ }
+
circuit_change_purpose(circ, CIRCUIT_PURPOSE_PATH_BIAS_TESTING);
/* Update timestamp for when circuit_expire_building() should kill us */
@@ -1648,7 +1897,7 @@ pathbias_check_probe_response(circuit_t *circ, const cell_t *cell)
/* Check nonce */
if (ipv4_host == ocirc->pathbias_probe_nonce) {
- ocirc->path_state = PATH_STATE_USE_SUCCEEDED;
+ pathbias_mark_use_success(ocirc);
circuit_mark_for_close(circ, END_CIRC_REASON_FINISHED);
log_info(LD_CIRC,
"Got valid path bias probe back for circ %d, stream %d.",
@@ -1691,24 +1940,11 @@ pathbias_check_close(origin_circuit_t *ocirc, int reason)
return 0;
}
- if (ocirc->path_state == PATH_STATE_BUILD_SUCCEEDED) {
- if (circ->timestamp_dirty) {
- if (pathbias_send_usable_probe(circ) == 0)
- return -1;
- else
- pathbias_count_unusable(ocirc);
-
- /* Any circuit where there were attempted streams but no successful
- * streams could be bias */
- log_info(LD_CIRC,
- "Circuit %d closed without successful use for reason %d. "
- "Circuit purpose %d currently %d,%s. Len %d.",
- ocirc->global_identifier,
- reason, circ->purpose, ocirc->has_opened,
- circuit_state_to_string(circ->state),
- ocirc->build_state->desired_path_len);
-
- } else {
+ switch (ocirc->path_state) {
+ /* If the circuit was closed after building, but before use, we need
+ * to ensure we were the ones who tried to close it (and not a remote
+ * actor). */
+ case PATH_STATE_BUILD_SUCCEEDED:
if (reason & END_CIRC_REASON_FLAG_REMOTE) {
/* Remote circ close reasons on an unused circuit all could be bias */
log_info(LD_CIRC,
@@ -1739,11 +1975,45 @@ pathbias_check_close(origin_circuit_t *ocirc, int reason)
} else {
pathbias_count_successful_close(ocirc);
}
- }
- } else if (ocirc->path_state == PATH_STATE_USE_SUCCEEDED) {
- pathbias_count_successful_close(ocirc);
+ break;
+
+ /* If we tried to use a circuit but failed, we should probe it to ensure
+ * it has not been tampered with. */
+ case PATH_STATE_USE_ATTEMPTED:
+ /* XXX: Only probe and/or count failure if the network is live?
+ * What about clock jumps/suspends? */
+ if (pathbias_send_usable_probe(circ) == 0)
+ return -1;
+ else
+ pathbias_count_use_failed(ocirc);
+
+ /* Any circuit where there were attempted streams but no successful
+ * streams could be bias */
+ log_info(LD_CIRC,
+ "Circuit %d closed without successful use for reason %d. "
+ "Circuit purpose %d currently %d,%s. Len %d.",
+ ocirc->global_identifier,
+ reason, circ->purpose, ocirc->has_opened,
+ circuit_state_to_string(circ->state),
+ ocirc->build_state->desired_path_len);
+ break;
+
+ case PATH_STATE_USE_SUCCEEDED:
+ pathbias_count_successful_close(ocirc);
+ pathbias_count_use_success(ocirc);
+ break;
+
+ case PATH_STATE_USE_FAILED:
+ pathbias_count_use_failed(ocirc);
+ break;
+
+ default:
+ // Other states are uninteresting. No stats to count.
+ break;
}
+ ocirc->path_state = PATH_STATE_ALREADY_COUNTED;
+
return 0;
}
@@ -1792,6 +2062,7 @@ static void
pathbias_count_collapse(origin_circuit_t *circ)
{
entry_guard_t *guard = NULL;
+
if (!pathbias_should_count(circ)) {
return;
}
@@ -1816,8 +2087,13 @@ pathbias_count_collapse(origin_circuit_t *circ)
}
}
+/**
+ * Count a known failed circuit (because we could not probe it).
+ *
+ * This counter is informational.
+ */
static void
-pathbias_count_unusable(origin_circuit_t *circ)
+pathbias_count_use_failed(origin_circuit_t *circ)
{
entry_guard_t *guard = NULL;
if (!pathbias_should_count(circ)) {
@@ -1879,20 +2155,20 @@ pathbias_count_timeout(origin_circuit_t *circ)
}
/**
- * Return the number of circuits counted as successfully closed for
- * this guard.
- *
- * Also add in the currently open circuits to give them the benefit
- * of the doubt.
+ * Helper function to count all of the currently opened circuits
+ * for a guard that are in a given path state range. The state
+ * range is inclusive on both ends.
*/
-double
-pathbias_get_closed_count(entry_guard_t *guard)
+static int
+pathbias_count_circs_in_states(entry_guard_t *guard,
+ path_state_t from,
+ path_state_t to)
{
- circuit_t *circ;
+ circuit_t *circ = global_circuitlist;
int open_circuits = 0;
- /* Count currently open circuits. Give them the benefit of the doubt. */
- for (circ = global_circuitlist; circ; circ = circ->next) {
+ /* Count currently open circuits. Give them the benefit of the doubt */
+ for ( ; circ; circ = circ->next) {
origin_circuit_t *ocirc = NULL;
if (!CIRCUIT_IS_ORIGIN(circ) || /* didn't originate here */
circ->marked_for_close) /* already counted */
@@ -1903,63 +2179,193 @@ pathbias_get_closed_count(entry_guard_t *guard)
if (!ocirc->cpath || !ocirc->cpath->extend_info)
continue;
- if (ocirc->path_state >= PATH_STATE_BUILD_SUCCEEDED &&
+ if (ocirc->path_state >= from &&
+ ocirc->path_state <= to &&
+ pathbias_should_count(ocirc) &&
fast_memeq(guard->identity,
- ocirc->cpath->extend_info->identity_digest,
- DIGEST_LEN)) {
+ ocirc->cpath->extend_info->identity_digest,
+ DIGEST_LEN)) {
+ log_debug(LD_CIRC, "Found opened circuit %d in path_state %s",
+ ocirc->global_identifier,
+ pathbias_state_to_string(ocirc->path_state));
open_circuits++;
}
}
- return guard->successful_circuits_closed + open_circuits;
+ return open_circuits;
}
/**
- * This function checks the consensus parameters to decide
- * if it should return guard->circ_successes or
- * guard->successful_circuits_closed.
+ * Return the number of circuits counted as successfully closed for
+ * this guard.
+ *
+ * Also add in the currently open circuits to give them the benefit
+ * of the doubt.
*/
double
-pathbias_get_success_count(entry_guard_t *guard)
+pathbias_get_close_success_count(entry_guard_t *guard)
{
- if (pathbias_use_close_counts(get_options())) {
- return pathbias_get_closed_count(guard);
- } else {
- return guard->circ_successes;
- }
+ return guard->successful_circuits_closed +
+ pathbias_count_circs_in_states(guard,
+ PATH_STATE_BUILD_SUCCEEDED,
+ PATH_STATE_USE_SUCCEEDED);
}
-/** Increment the number of times we successfully extended a circuit to
- * <b>guard</b>, first checking if the failure rate is high enough that
- * we should eliminate the guard. Return -1 if the guard looks no good;
- * return 0 if the guard looks fine.
+/**
+ * Return the number of circuits counted as successfully used
+ * this guard.
+ *
+ * Also add in the currently open circuits that we are attempting
+ * to use to give them the benefit of the doubt.
*/
-static int
-entry_guard_inc_circ_attempt_count(entry_guard_t *guard)
+double
+pathbias_get_use_success_count(entry_guard_t *guard)
+{
+ return guard->use_successes +
+ pathbias_count_circs_in_states(guard,
+ PATH_STATE_USE_ATTEMPTED,
+ PATH_STATE_USE_SUCCEEDED);
+}
+
+/**
+ * Check the path bias use rate against our consensus parameter limits.
+ *
+ * Emits a log message if the use success rates are too low.
+ *
+ * If pathbias_get_dropguards() is set, we also disable the use of
+ * very failure prone guards.
+ */
+static void
+pathbias_measure_use_rate(entry_guard_t *guard)
{
const or_options_t *options = get_options();
- entry_guards_changed();
+ if (guard->use_attempts > pathbias_get_min_use(options)) {
+ /* Note: We rely on the < comparison here to allow us to set a 0
+ * rate and disable the feature entirely. If refactoring, don't
+ * change to <= */
+ if (pathbias_get_use_success_count(guard)/guard->use_attempts
+ < pathbias_get_extreme_use_rate(options)) {
+ /* Dropping is currently disabled by default. */
+ if (pathbias_get_dropguards(options)) {
+ if (!guard->path_bias_disabled) {
+ log_warn(LD_CIRC,
+ "Your Guard %s=%s is failing to carry an extremely large "
+ "amount of stream on its circuits. "
+ "To avoid potential route manipluation attacks, Tor has "
+ "disabled use of this guard. "
+ "Use counts are %ld/%ld. Success counts are %ld/%ld. "
+ "%ld circuits completed, %ld were unusable, %ld collapsed, "
+ "and %ld timed out. "
+ "For reference, your timeout cutoff is %ld seconds.",
+ guard->nickname, hex_str(guard->identity, DIGEST_LEN),
+ tor_lround(pathbias_get_use_success_count(guard)),
+ tor_lround(guard->use_attempts),
+ tor_lround(pathbias_get_close_success_count(guard)),
+ tor_lround(guard->circ_attempts),
+ tor_lround(guard->circ_successes),
+ tor_lround(guard->unusable_circuits),
+ tor_lround(guard->collapsed_circuits),
+ tor_lround(guard->timeouts),
+ tor_lround(circ_times.close_ms/1000));
+ guard->path_bias_disabled = 1;
+ guard->bad_since = approx_time();
+ entry_guards_changed();
+ return;
+ }
+ } else if (!guard->path_bias_extreme) {
+ guard->path_bias_extreme = 1;
+ log_warn(LD_CIRC,
+ "Your Guard %s=%s is failing to carry an extremely large "
+ "amount of streams on its circuits. "
+ "This could indicate a route manipulation attack, network "
+ "overload, bad local network connectivity, or a bug. "
+ "Use counts are %ld/%ld. Success counts are %ld/%ld. "
+ "%ld circuits completed, %ld were unusable, %ld collapsed, "
+ "and %ld timed out. "
+ "For reference, your timeout cutoff is %ld seconds.",
+ guard->nickname, hex_str(guard->identity, DIGEST_LEN),
+ tor_lround(pathbias_get_use_success_count(guard)),
+ tor_lround(guard->use_attempts),
+ tor_lround(pathbias_get_close_success_count(guard)),
+ tor_lround(guard->circ_attempts),
+ tor_lround(guard->circ_successes),
+ tor_lround(guard->unusable_circuits),
+ tor_lround(guard->collapsed_circuits),
+ tor_lround(guard->timeouts),
+ tor_lround(circ_times.close_ms/1000));
+ }
+ } else if (pathbias_get_use_success_count(guard)/guard->use_attempts
+ < pathbias_get_notice_use_rate(options)) {
+ if (!guard->path_bias_noticed) {
+ guard->path_bias_noticed = 1;
+ log_notice(LD_CIRC,
+ "Your Guard %s=%s is failing to carry more streams on its "
+ "circuits than usual. "
+ "Most likely this means the Tor network is overloaded "
+ "or your network connection is poor. "
+ "Use counts are %ld/%ld. Success counts are %ld/%ld. "
+ "%ld circuits completed, %ld were unusable, %ld collapsed, "
+ "and %ld timed out. "
+ "For reference, your timeout cutoff is %ld seconds.",
+ guard->nickname, hex_str(guard->identity, DIGEST_LEN),
+ tor_lround(pathbias_get_use_success_count(guard)),
+ tor_lround(guard->use_attempts),
+ tor_lround(pathbias_get_close_success_count(guard)),
+ tor_lround(guard->circ_attempts),
+ tor_lround(guard->circ_successes),
+ tor_lround(guard->unusable_circuits),
+ tor_lround(guard->collapsed_circuits),
+ tor_lround(guard->timeouts),
+ tor_lround(circ_times.close_ms/1000));
+ }
+ }
+ }
+}
+
+/**
+ * Check the path bias circuit close status rates against our consensus
+ * parameter limits.
+ *
+ * Emits a log message if the use success rates are too low.
+ *
+ * If pathbias_get_dropguards() is set, we also disable the use of
+ * very failure prone guards.
+ *
+ * XXX: This function shares similar log messages and checks to
+ * pathbias_measure_use_rate(). It may be possible to combine them
+ * eventually, especially if we can ever remove the need for 3
+ * levels of closure warns (if the overall circuit failure rate
+ * goes down with ntor).
+ */
+static void
+pathbias_measure_close_rate(entry_guard_t *guard)
+{
+ const or_options_t *options = get_options();
if (guard->circ_attempts > pathbias_get_min_circs(options)) {
/* Note: We rely on the < comparison here to allow us to set a 0
* rate and disable the feature entirely. If refactoring, don't
* change to <= */
- if (pathbias_get_success_count(guard)/guard->circ_attempts
+ if (pathbias_get_close_success_count(guard)/guard->circ_attempts
< pathbias_get_extreme_rate(options)) {
/* Dropping is currently disabled by default. */
if (pathbias_get_dropguards(options)) {
if (!guard->path_bias_disabled) {
log_warn(LD_CIRC,
- "Your Guard %s=%s is failing an extremely large amount of "
- "circuits. To avoid potential route manipulation attacks, "
- "Tor has disabled use of this guard. "
- "Success counts are %ld/%ld. %ld circuits completed, %ld "
- "were unusable, %ld collapsed, and %ld timed out. For "
- "reference, your timeout cutoff is %ld seconds.",
+ "Your Guard %s=%s is failing an extremely large "
+ "amount of circuits. "
+ "To avoid potential route manipluation attacks, Tor has "
+ "disabled use of this guard. "
+ "Success counts are %ld/%ld. Use counts are %ld/%ld. "
+ "%ld circuits completed, %ld were unusable, %ld collapsed, "
+ "and %ld timed out. "
+ "For reference, your timeout cutoff is %ld seconds.",
guard->nickname, hex_str(guard->identity, DIGEST_LEN),
- tor_lround(pathbias_get_closed_count(guard)),
+ tor_lround(pathbias_get_close_success_count(guard)),
tor_lround(guard->circ_attempts),
+ tor_lround(pathbias_get_use_success_count(guard)),
+ tor_lround(guard->use_attempts),
tor_lround(guard->circ_successes),
tor_lround(guard->unusable_circuits),
tor_lround(guard->collapsed_circuits),
@@ -1967,94 +2373,180 @@ entry_guard_inc_circ_attempt_count(entry_guard_t *guard)
tor_lround(circ_times.close_ms/1000));
guard->path_bias_disabled = 1;
guard->bad_since = approx_time();
- return -1;
+ entry_guards_changed();
+ return;
}
} else if (!guard->path_bias_extreme) {
guard->path_bias_extreme = 1;
log_warn(LD_CIRC,
- "Your Guard %s=%s is failing an extremely large amount of "
- "circuits. This could indicate a route manipulation attack, "
+ "Your Guard %s=%s is failing an extremely large "
+ "amount of circuits. "
+ "This could indicate a route manipulation attack, "
"extreme network overload, or a bug. "
- "Success counts are %ld/%ld. %ld circuits completed, %ld "
- "were unusable, %ld collapsed, and %ld timed out. For "
- "reference, your timeout cutoff is %ld seconds.",
+ "Success counts are %ld/%ld. Use counts are %ld/%ld. "
+ "%ld circuits completed, %ld were unusable, %ld collapsed, "
+ "and %ld timed out. "
+ "For reference, your timeout cutoff is %ld seconds.",
guard->nickname, hex_str(guard->identity, DIGEST_LEN),
- tor_lround(pathbias_get_closed_count(guard)),
+ tor_lround(pathbias_get_close_success_count(guard)),
tor_lround(guard->circ_attempts),
+ tor_lround(pathbias_get_use_success_count(guard)),
+ tor_lround(guard->use_attempts),
tor_lround(guard->circ_successes),
tor_lround(guard->unusable_circuits),
tor_lround(guard->collapsed_circuits),
tor_lround(guard->timeouts),
tor_lround(circ_times.close_ms/1000));
}
- } else if (pathbias_get_success_count(guard)/((double)guard->circ_attempts)
- < pathbias_get_warn_rate(options)) {
+ } else if (pathbias_get_close_success_count(guard)/guard->circ_attempts
+ < pathbias_get_warn_rate(options)) {
if (!guard->path_bias_warned) {
guard->path_bias_warned = 1;
log_warn(LD_CIRC,
- "Your Guard %s=%s is failing a very large amount of "
- "circuits. Most likely this means the Tor network is "
+ "Your Guard %s=%s is failing a very large "
+ "amount of circuits. "
+ "Most likely this means the Tor network is "
"overloaded, but it could also mean an attack against "
"you or potentially the guard itself. "
- "Success counts are %ld/%ld. %ld circuits completed, %ld "
- "were unusable, %ld collapsed, and %ld timed out. For "
- "reference, your timeout cutoff is %ld seconds.",
+ "Success counts are %ld/%ld. Use counts are %ld/%ld. "
+ "%ld circuits completed, %ld were unusable, %ld collapsed, "
+ "and %ld timed out. "
+ "For reference, your timeout cutoff is %ld seconds.",
guard->nickname, hex_str(guard->identity, DIGEST_LEN),
- tor_lround(pathbias_get_closed_count(guard)),
+ tor_lround(pathbias_get_close_success_count(guard)),
tor_lround(guard->circ_attempts),
+ tor_lround(pathbias_get_use_success_count(guard)),
+ tor_lround(guard->use_attempts),
tor_lround(guard->circ_successes),
tor_lround(guard->unusable_circuits),
tor_lround(guard->collapsed_circuits),
tor_lround(guard->timeouts),
tor_lround(circ_times.close_ms/1000));
}
- } else if (pathbias_get_success_count(guard)/((double)guard->circ_attempts)
+ } else if (pathbias_get_close_success_count(guard)/guard->circ_attempts
< pathbias_get_notice_rate(options)) {
if (!guard->path_bias_noticed) {
guard->path_bias_noticed = 1;
log_notice(LD_CIRC,
- "Your Guard %s=%s is failing more circuits than usual. "
- "Most likely this means the Tor network is overloaded. "
- "Success counts are %ld/%ld. %ld circuits completed, %ld "
- "were unusable, %ld collapsed, and %ld timed out. For "
- "reference, your timeout cutoff is %ld seconds.",
- guard->nickname, hex_str(guard->identity, DIGEST_LEN),
- tor_lround(pathbias_get_closed_count(guard)),
- tor_lround(guard->circ_attempts),
- tor_lround(guard->circ_successes),
- tor_lround(guard->unusable_circuits),
- tor_lround(guard->collapsed_circuits),
- tor_lround(guard->timeouts),
- tor_lround(circ_times.close_ms/1000));
+ "Your Guard %s=%s is failing more circuits than "
+ "usual. "
+ "Most likely this means the Tor network is overloaded. "
+ "Success counts are %ld/%ld. Use counts are %ld/%ld. "
+ "%ld circuits completed, %ld were unusable, %ld collapsed, "
+ "and %ld timed out. "
+ "For reference, your timeout cutoff is %ld seconds.",
+ guard->nickname, hex_str(guard->identity, DIGEST_LEN),
+ tor_lround(pathbias_get_close_success_count(guard)),
+ tor_lround(guard->circ_attempts),
+ tor_lround(pathbias_get_use_success_count(guard)),
+ tor_lround(guard->use_attempts),
+ tor_lround(guard->circ_successes),
+ tor_lround(guard->unusable_circuits),
+ tor_lround(guard->collapsed_circuits),
+ tor_lround(guard->timeouts),
+ tor_lround(circ_times.close_ms/1000));
}
}
}
+}
+
+/**
+ * This function scales the path bias use rates if we have
+ * more data than the scaling threshold. This allows us to
+ * be more sensitive to recent measurements.
+ *
+ * XXX: The attempt count transfer stuff here might be done
+ * better by keeping separate pending counters that get
+ * transfered at circuit close.
+ */
+static void
+pathbias_scale_close_rates(entry_guard_t *guard)
+{
+ const or_options_t *options = get_options();
/* If we get a ton of circuits, just scale everything down */
if (guard->circ_attempts > pathbias_get_scale_threshold(options)) {
- const int scale_factor = pathbias_get_scale_factor(options);
- const int mult_factor = pathbias_get_mult_factor(options);
+ double scale_ratio = pathbias_get_scale_ratio(options);
+ int opened_attempts = pathbias_count_circs_in_states(guard,
+ PATH_STATE_BUILD_ATTEMPTED, PATH_STATE_BUILD_ATTEMPTED);
+ int opened_built = pathbias_count_circs_in_states(guard,
+ PATH_STATE_BUILD_SUCCEEDED,
+ PATH_STATE_USE_FAILED);
+ guard->circ_attempts -= opened_attempts;
+ guard->circ_successes -= opened_built;
+
+ guard->circ_attempts *= scale_ratio;
+ guard->circ_successes *= scale_ratio;
+ guard->timeouts *= scale_ratio;
+ guard->successful_circuits_closed *= scale_ratio;
+ guard->collapsed_circuits *= scale_ratio;
+ guard->unusable_circuits *= scale_ratio;
+
+ guard->circ_attempts += opened_attempts;
+ guard->circ_successes += opened_built;
+
+ entry_guards_changed();
+
log_info(LD_CIRC,
- "Scaling pathbias counts to (%f/%f)*(%d/%d) for guard %s=%s",
- guard->circ_successes, guard->circ_attempts,
- mult_factor, scale_factor, guard->nickname,
- hex_str(guard->identity, DIGEST_LEN));
-
- guard->circ_attempts *= mult_factor;
- guard->circ_successes *= mult_factor;
- guard->timeouts *= mult_factor;
- guard->successful_circuits_closed *= mult_factor;
- guard->collapsed_circuits *= mult_factor;
- guard->unusable_circuits *= mult_factor;
-
- guard->circ_attempts /= scale_factor;
- guard->circ_successes /= scale_factor;
- guard->timeouts /= scale_factor;
- guard->successful_circuits_closed /= scale_factor;
- guard->collapsed_circuits /= scale_factor;
- guard->unusable_circuits /= scale_factor;
+ "Scaled pathbias counts to (%f,%f)/%f (%d/%d open) for guard "
+ "%s=%s",
+ guard->circ_successes, guard->successful_circuits_closed,
+ guard->circ_attempts, opened_built, opened_attempts,
+ guard->nickname, hex_str(guard->identity, DIGEST_LEN));
}
+}
+
+/**
+ * This function scales the path bias circuit close rates if we have
+ * more data than the scaling threshold. This allows us to be more
+ * sensitive to recent measurements.
+ *
+ * XXX: The attempt count transfer stuff here might be done
+ * better by keeping separate pending counters that get
+ * transfered at circuit close.
+ */
+void
+pathbias_scale_use_rates(entry_guard_t *guard)
+{
+ const or_options_t *options = get_options();
+
+ /* If we get a ton of circuits, just scale everything down */
+ if (guard->use_attempts > pathbias_get_scale_use_threshold(options)) {
+ double scale_ratio = pathbias_get_scale_ratio(options);
+ int opened_attempts = pathbias_count_circs_in_states(guard,
+ PATH_STATE_USE_ATTEMPTED, PATH_STATE_USE_SUCCEEDED);
+ guard->use_attempts -= opened_attempts;
+
+ guard->use_attempts *= scale_ratio;
+ guard->use_successes *= scale_ratio;
+
+ guard->use_attempts += opened_attempts;
+
+ log_info(LD_CIRC,
+ "Scaled pathbias use counts to %f/%f (%d open) for guard %s=%s",
+ guard->use_successes, guard->use_attempts, opened_attempts,
+ guard->nickname, hex_str(guard->identity, DIGEST_LEN));
+ entry_guards_changed();
+ }
+}
+
+/** Increment the number of times we successfully extended a circuit to
+ * 'guard', first checking if the failure rate is high enough that we should
+ * eliminate the guard. Return -1 if the guard looks no good; return 0 if the
+ * guard looks fine. */
+static int
+entry_guard_inc_circ_attempt_count(entry_guard_t *guard)
+{
+ entry_guards_changed();
+
+ pathbias_measure_close_rate(guard);
+
+ if (guard->path_bias_disabled)
+ return -1;
+
+ pathbias_scale_close_rates(guard);
guard->circ_attempts++;
+
log_info(LD_CIRC, "Got success count %f/%f for guard %s=%s",
guard->circ_successes, guard->circ_attempts, guard->nickname,
hex_str(guard->identity, DIGEST_LEN));
@@ -2078,7 +2570,7 @@ circuit_finish_handshake(origin_circuit_t *circ,
crypt_path_t *hop;
int rv;
- if ((rv = pathbias_count_circ_attempt(circ)) < 0)
+ if ((rv = pathbias_count_build_attempt(circ)) < 0)
return rv;
if (circ->cpath->state == CPATH_STATE_AWAITING_KEYS) {
@@ -2761,9 +3253,7 @@ circuit_extend_to_new_exit(origin_circuit_t *circ, extend_info_t *exit)
return -1;
}
- /* Set timestamp_dirty, so we can check it for path use bias */
- if (!circ->base_.timestamp_dirty)
- circ->base_.timestamp_dirty = time(NULL);
+ // XXX: Should cannibalized circuits be dirty or not? Not easy to say..
return 0;
}
diff --git a/src/or/circuitbuild.h b/src/or/circuitbuild.h
index e6cf802f2b..3ca8d1531d 100644
--- a/src/or/circuitbuild.h
+++ b/src/or/circuitbuild.h
@@ -58,10 +58,14 @@ const char *build_state_get_exit_nickname(cpath_build_state_t *state);
const node_t *choose_good_entry_server(uint8_t purpose,
cpath_build_state_t *state);
double pathbias_get_extreme_rate(const or_options_t *options);
+double pathbias_get_extreme_use_rate(const or_options_t *options);
int pathbias_get_dropguards(const or_options_t *options);
void pathbias_count_timeout(origin_circuit_t *circ);
int pathbias_check_close(origin_circuit_t *circ, int reason);
int pathbias_check_probe_response(circuit_t *circ, const cell_t *cell);
+void pathbias_count_use_attempt(origin_circuit_t *circ);
+void pathbias_mark_use_success(origin_circuit_t *circ);
+void pathbias_mark_use_rollback(origin_circuit_t *circ);
#endif
diff --git a/src/or/circuitlist.c b/src/or/circuitlist.c
index b8f71bd342..6987dc42fd 100644
--- a/src/or/circuitlist.c
+++ b/src/or/circuitlist.c
@@ -783,8 +783,8 @@ circuit_dump_conn_details(int severity,
int this_circid,
int other_circid)
{
- log(severity, LD_CIRC, "Conn %d has %s circuit: circID %d (other side %d), "
- "state %d (%s), born %ld:",
+ tor_log(severity, LD_CIRC, "Conn %d has %s circuit: circID %d "
+ "(other side %d), state %d (%s), born %ld:",
conn_array_index, type, this_circid, other_circid, circ->state,
circuit_state_to_string(circ->state),
(long)circ->timestamp_began.tv_sec);
@@ -846,8 +846,8 @@ circuit_dump_chan_details(int severity,
int this_circid,
int other_circid)
{
- log(severity, LD_CIRC, "Conn %p has %s circuit: circID %d (other side %d), "
- "state %d (%s), born %ld:",
+ tor_log(severity, LD_CIRC, "Conn %p has %s circuit: circID %d "
+ "(other side %d), state %d (%s), born %ld:",
chan, type, this_circid, other_circid, circ->state,
circuit_state_to_string(circ->state),
(long)circ->timestamp_began.tv_sec);
@@ -1343,7 +1343,7 @@ circuit_mark_for_close_(circuit_t *circ, int reason, int line,
tor_assert(file);
if (circ->marked_for_close) {
- log(LOG_WARN,LD_BUG,
+ log_warn(LD_BUG,
"Duplicate call to circuit_mark_for_close at %s:%d"
" (first at %s:%d)", file, line,
circ->marked_for_close_file, circ->marked_for_close);
diff --git a/src/or/circuitstats.c b/src/or/circuitstats.c
index 625083c9b8..73e34d9ed7 100644
--- a/src/or/circuitstats.c
+++ b/src/or/circuitstats.c
@@ -183,16 +183,6 @@ circuit_build_times_quantile_cutoff(void)
return num/100.0;
}
-/* DOCDOC circuit_build_times_get_bw_scale */
-int
-circuit_build_times_get_bw_scale(networkstatus_t *ns)
-{
- return networkstatus_get_param(ns, "bwweightscale",
- BW_WEIGHT_SCALE,
- BW_MIN_WEIGHT_SCALE,
- BW_MAX_WEIGHT_SCALE);
-}
-
/**
* Retrieve and bounds-check the cbtclosequantile consensus paramter.
*
diff --git a/src/or/circuituse.c b/src/or/circuituse.c
index 83734c9d6d..cfd41be792 100644
--- a/src/or/circuituse.c
+++ b/src/or/circuituse.c
@@ -668,18 +668,6 @@ circuit_expire_building(void)
circuit_build_times_set_timeout(&circ_times);
}
}
-
- if (TO_ORIGIN_CIRCUIT(victim)->has_opened &&
- victim->purpose != CIRCUIT_PURPOSE_PATH_BIAS_TESTING) {
- /* For path bias: we want to let these guys live for a while
- * so we get a chance to test them. */
- log_info(LD_CIRC,
- "Allowing cannibalized circuit %d time to finish building "
- "as a pathbias testing circ.",
- TO_ORIGIN_CIRCUIT(victim)->global_identifier);
- circuit_change_purpose(victim, CIRCUIT_PURPOSE_PATH_BIAS_TESTING);
- continue; /* It now should have a longer timeout next time */
- }
}
/* If this is a hidden service client circuit which is far enough
@@ -1090,7 +1078,10 @@ circuit_expire_old_circuits_clientside(void)
"purpose %d)",
circ->n_circ_id, (long)(now.tv_sec - circ->timestamp_dirty),
circ->purpose);
- circuit_mark_for_close(circ, END_CIRC_REASON_FINISHED);
+ /* Don't do this magic for testing circuits. Their death is governed
+ * by circuit_expire_building */
+ if (circ->purpose != CIRCUIT_PURPOSE_PATH_BIAS_TESTING)
+ circuit_mark_for_close(circ, END_CIRC_REASON_FINISHED);
} else if (!circ->timestamp_dirty && circ->state == CIRCUIT_STATE_OPEN) {
if (timercmp(&circ->timestamp_began, &cutoff, <)) {
if (circ->purpose == CIRCUIT_PURPOSE_C_GENERAL ||
@@ -1507,17 +1498,19 @@ circuit_launch_by_extend_info(uint8_t purpose,
purpose == CIRCUIT_PURPOSE_C_INTRODUCING) &&
circ->path_state == PATH_STATE_BUILD_SUCCEEDED) {
/* Path bias: Cannibalized rends pre-emptively count as a
- * successfully used circ. We don't wait until the extend,
- * because the rend point could be malicious.
+ * successfully built but unused closed circuit. We don't
+ * wait until the extend (or the close) because the rend
+ * point could be malicious.
*
* Same deal goes for client side introductions. Clients
* can be manipulated to connect repeatedly to them
* (especially web clients).
*
* If we decide to probe the initial portion of these circs,
- * (up to the adversaries final hop), we need to remove this.
+ * (up to the adversary's final hop), we need to remove this,
+ * or somehow mark the circuit with a special path state.
*/
- circ->path_state = PATH_STATE_USE_SUCCEEDED;
+
/* This must be called before the purpose change */
pathbias_check_close(circ, END_CIRC_REASON_FINISHED);
}
@@ -2037,6 +2030,8 @@ connection_ap_handshake_attach_chosen_circuit(entry_connection_t *conn,
if (!circ->base_.timestamp_dirty)
circ->base_.timestamp_dirty = time(NULL);
+ pathbias_count_use_attempt(circ);
+
link_apconn_to_circ(conn, circ, cpath);
tor_assert(conn->socks_request);
if (conn->socks_request->command == SOCKS_COMMAND_CONNECT) {
@@ -2163,6 +2158,11 @@ connection_ap_handshake_attach_circuit(entry_connection_t *conn)
* feasibility, at this point.
*/
rendcirc->base_.timestamp_dirty = time(NULL);
+
+ /* We've also attempted to use them. If they fail, we need to
+ * probe them for path bias */
+ pathbias_count_use_attempt(rendcirc);
+
link_apconn_to_circ(conn, rendcirc, NULL);
if (connection_ap_handshake_send_begin(conn) < 0)
return 0; /* already marked, let them fade away */
@@ -2214,6 +2214,10 @@ connection_ap_handshake_attach_circuit(entry_connection_t *conn)
case 0: /* success */
rendcirc->base_.timestamp_dirty = time(NULL);
introcirc->base_.timestamp_dirty = time(NULL);
+
+ pathbias_count_use_attempt(introcirc);
+ pathbias_count_use_attempt(rendcirc);
+
assert_circuit_ok(TO_CIRCUIT(rendcirc));
assert_circuit_ok(TO_CIRCUIT(introcirc));
return 0;
diff --git a/src/or/config.c b/src/or/config.c
index ce751122ff..31695baa73 100644
--- a/src/or/config.c
+++ b/src/or/config.c
@@ -297,7 +297,8 @@ static config_var_t option_vars_[] = {
V(MaxAdvertisedBandwidth, MEMUNIT, "1 GB"),
V(MaxCircuitDirtiness, INTERVAL, "10 minutes"),
V(MaxClientCircuitsPending, UINT, "32"),
- V(MaxOnionsPending, UINT, "100"),
+ OBSOLETE("MaxOnionsPending"),
+ V(MaxOnionQueueDelay, MSEC_INTERVAL, "1750 msec"),
OBSOLETE("MonthlyAccountingStart"),
V(MyFamily, STRING, NULL),
V(NewCircuitPeriod, INTERVAL, "30 seconds"),
@@ -321,11 +322,17 @@ static config_var_t option_vars_[] = {
V(PathBiasWarnRate, DOUBLE, "-1"),
V(PathBiasExtremeRate, DOUBLE, "-1"),
V(PathBiasScaleThreshold, INT, "-1"),
- V(PathBiasScaleFactor, INT, "-1"),
- V(PathBiasMultFactor, INT, "-1"),
+ OBSOLETE("PathBiasScaleFactor"),
+ OBSOLETE("PathBiasMultFactor"),
V(PathBiasDropGuards, AUTOBOOL, "0"),
- V(PathBiasUseCloseCounts, AUTOBOOL, "1"),
+ OBSOLETE("PathBiasUseCloseCounts"),
+ V(PathBiasUseThreshold, INT, "-1"),
+ V(PathBiasNoticeUseRate, DOUBLE, "-1"),
+ V(PathBiasExtremeUseRate, DOUBLE, "-1"),
+ V(PathBiasScaleUseThreshold, INT, "-1"),
+
+ V(PathsNeededToBuildCircuits, DOUBLE, "-1"),
OBSOLETE("PathlenCoinWeight"),
V(PerConnBWBurst, MEMUNIT, "0"),
V(PerConnBWRate, MEMUNIT, "0"),
@@ -1086,7 +1093,7 @@ options_act_reversible(const or_options_t *old_options, char **msg)
mark_logs_temp(); /* Close current logs once new logs are open. */
logs_marked = 1;
- if (options_init_logs(options, 0)<0) { /* Configure the log(s) */
+ if (options_init_logs(options, 0)<0) { /* Configure the tor_log(s) */
*msg = tor_strdup("Failed to init Log options. See logs for details.");
goto rollback;
}
@@ -1262,7 +1269,7 @@ options_act(const or_options_t *old_options)
return -1;
#ifdef NON_ANONYMOUS_MODE_ENABLED
- log(LOG_WARN, LD_GENERAL, "This copy of Tor was compiled to run in a "
+ log_warn(LD_GENERAL, "This copy of Tor was compiled to run in a "
"non-anonymous mode. It will provide NO ANONYMITY.");
#endif
@@ -1776,7 +1783,7 @@ config_get_commandlines(int argc, char **argv, config_line_t **result)
(*new)->value = want_arg ? tor_strdup(argv[i+1]) : tor_strdup("");
(*new)->command = command;
(*new)->next = NULL;
- log(LOG_DEBUG, LD_CONFIG, "command line: parsed keyword '%s', value '%s'",
+ log_debug(LD_CONFIG, "command line: parsed keyword '%s', value '%s'",
(*new)->key, (*new)->value);
new = &((*new)->next);
@@ -2224,7 +2231,7 @@ options_validate(or_options_t *old_options, or_options_t *options,
int n_ports=0;
#define REJECT(arg) \
STMT_BEGIN *msg = tor_strdup(arg); return -1; STMT_END
-#define COMPLAIN(arg) STMT_BEGIN log(LOG_WARN, LD_CONFIG, arg); STMT_END
+#define COMPLAIN(arg) STMT_BEGIN log_warn(LD_CONFIG, arg); STMT_END
tor_assert(msg);
*msg = NULL;
@@ -2233,7 +2240,7 @@ options_validate(or_options_t *old_options, or_options_t *options,
(!strcmpstart(uname, "Windows 95") ||
!strcmpstart(uname, "Windows 98") ||
!strcmpstart(uname, "Windows Me"))) {
- log(LOG_WARN, LD_CONFIG, "Tor is running as a server, but you are "
+ log_warn(LD_CONFIG, "Tor is running as a server, but you are "
"running %s; this probably won't work. See "
"https://wiki.torproject.org/TheOnionRouter/TorFAQ#ServerOS "
"for details.", uname);
@@ -2262,7 +2269,7 @@ options_validate(or_options_t *old_options, or_options_t *options,
}
if (server_mode(options) && !options->ContactInfo)
- log(LOG_NOTICE, LD_CONFIG, "Your ContactInfo config option is not set. "
+ log_notice(LD_CONFIG, "Your ContactInfo config option is not set. "
"Please consider setting it, so we can contact you if your server is "
"misconfigured or something else goes wrong.");
@@ -2274,7 +2281,7 @@ options_validate(or_options_t *old_options, or_options_t *options,
config_line_append(&options->Logs, "Log", "warn stdout");
}
- if (options_init_logs(options, 1)<0) /* Validate the log(s) */
+ if (options_init_logs(options, 1)<0) /* Validate the tor_log(s) */
REJECT("Failed to validate Log options. See logs for details.");
if (authdir_mode(options)) {
@@ -2292,7 +2299,7 @@ options_validate(or_options_t *old_options, or_options_t *options,
/* XXXX require that the only port not be DirPort? */
/* XXXX require that at least one port be listened-upon. */
if (n_ports == 0 && !options->RendConfigLines)
- log(LOG_WARN, LD_CONFIG,
+ log_warn(LD_CONFIG,
"SocksPort, TransPort, NATDPort, DNSPort, and ORPort are all "
"undefined, and there aren't any hidden services configured. "
"Tor will still run, but probably won't do anything.");
@@ -2399,6 +2406,18 @@ options_validate(or_options_t *old_options, or_options_t *options,
return -1;
}
+ if (options->PathsNeededToBuildCircuits >= 0.0) {
+ if (options->PathsNeededToBuildCircuits < 0.25) {
+ log_warn(LD_CONFIG, "PathsNeededToBuildCircuits is too low. Increasing "
+ "to 0.25");
+ options->PathsNeededToBuildCircuits = 0.25;
+ } else if (options->PathsNeededToBuildCircuits < 0.95) {
+ log_warn(LD_CONFIG, "PathsNeededToBuildCircuits is too high. Decreasing "
+ "to 0.95");
+ options->PathsNeededToBuildCircuits = 0.95;
+ }
+ }
+
if (options->MaxClientCircuitsPending <= 0 ||
options->MaxClientCircuitsPending > MAX_MAX_CLIENT_CIRCUITS_PENDING) {
tor_asprintf(msg,
@@ -2440,7 +2459,7 @@ options_validate(or_options_t *old_options, or_options_t *options,
});
new_line->value = smartlist_join_strings(instead,",",0,NULL);
/* These have been deprecated since 0.1.1.5-alpha-cvs */
- log(LOG_NOTICE, LD_CONFIG,
+ log_notice(LD_CONFIG,
"Converting FascistFirewall and FirewallPorts "
"config options to new format: \"ReachableAddresses %s\"",
new_line->value);
@@ -2455,7 +2474,7 @@ options_validate(or_options_t *old_options, or_options_t *options,
new_line->key = tor_strdup("ReachableDirAddresses");
new_line->value = tor_strdup("*:80");
options->ReachableDirAddresses = new_line;
- log(LOG_NOTICE, LD_CONFIG, "Converting FascistFirewall config option "
+ log_notice(LD_CONFIG, "Converting FascistFirewall config option "
"to new format: \"ReachableDirAddresses *:80\"");
}
if (!options->ReachableORAddresses) {
@@ -2463,7 +2482,7 @@ options_validate(or_options_t *old_options, or_options_t *options,
new_line->key = tor_strdup("ReachableORAddresses");
new_line->value = tor_strdup("*:443");
options->ReachableORAddresses = new_line;
- log(LOG_NOTICE, LD_CONFIG, "Converting FascistFirewall config option "
+ log_notice(LD_CONFIG, "Converting FascistFirewall config option "
"to new format: \"ReachableORAddresses *:443\"");
}
}
@@ -2643,6 +2662,37 @@ options_validate(or_options_t *old_options, or_options_t *options,
RECOMMENDED_MIN_CIRCUIT_BUILD_TIMEOUT );
}
+ if (options->PathBiasNoticeRate > 1.0) {
+ tor_asprintf(msg,
+ "PathBiasNoticeRate is too high. "
+ "It must be between 0 and 1.0");
+ return -1;
+ }
+ if (options->PathBiasWarnRate > 1.0) {
+ tor_asprintf(msg,
+ "PathBiasWarnRate is too high. "
+ "It must be between 0 and 1.0");
+ return -1;
+ }
+ if (options->PathBiasExtremeRate > 1.0) {
+ tor_asprintf(msg,
+ "PathBiasExtremeRate is too high. "
+ "It must be between 0 and 1.0");
+ return -1;
+ }
+ if (options->PathBiasNoticeUseRate > 1.0) {
+ tor_asprintf(msg,
+ "PathBiasNoticeUseRate is too high. "
+ "It must be between 0 and 1.0");
+ return -1;
+ }
+ if (options->PathBiasExtremeUseRate > 1.0) {
+ tor_asprintf(msg,
+ "PathBiasExtremeUseRate is too high. "
+ "It must be between 0 and 1.0");
+ return -1;
+ }
+
if (options->MaxCircuitDirtiness < MIN_MAX_CIRCUIT_DIRTINESS) {
log_warn(LD_CONFIG, "MaxCircuitDirtiness option is too short; "
"raising to %d seconds.", MIN_MAX_CIRCUIT_DIRTINESS);
@@ -3417,7 +3467,7 @@ find_torrc_filename(int argc, char **argv,
for (i = 1; i < argc; ++i) {
if (i < argc-1 && !strcmp(argv[i],fname_opt)) {
if (fname) {
- log(LOG_WARN, LD_CONFIG, "Duplicate %s options on command line.",
+ log_warn(LD_CONFIG, "Duplicate %s options on command line.",
fname_opt);
tor_free(fname);
}
@@ -3480,7 +3530,7 @@ load_torrc_from_disk(int argc, char **argv, int defaults_file)
fname = find_torrc_filename(argc, argv, defaults_file,
&using_default_torrc, &ignore_missing_torrc);
tor_assert(fname);
- log(LOG_DEBUG, LD_CONFIG, "Opening config file \"%s\"", fname);
+ log_debug(LD_CONFIG, "Opening config file \"%s\"", fname);
tor_free(*fname_var);
*fname_var = fname;
@@ -3490,18 +3540,18 @@ load_torrc_from_disk(int argc, char **argv, int defaults_file)
!(cf = read_file_to_str(fname,0,NULL))) {
if (using_default_torrc == 1 || ignore_missing_torrc) {
if (!defaults_file)
- log(LOG_NOTICE, LD_CONFIG, "Configuration file \"%s\" not present, "
+ log_notice(LD_CONFIG, "Configuration file \"%s\" not present, "
"using reasonable defaults.", fname);
tor_free(fname); /* sets fname to NULL */
*fname_var = NULL;
cf = tor_strdup("");
} else {
- log(LOG_WARN, LD_CONFIG,
+ log_warn(LD_CONFIG,
"Unable to open configuration file \"%s\".", fname);
goto err;
}
} else {
- log(LOG_NOTICE, LD_CONFIG, "Read configuration file \"%s\".", fname);
+ log_notice(LD_CONFIG, "Read configuration file \"%s\".", fname);
}
return cf;
@@ -3593,7 +3643,7 @@ options_init_from_torrc(int argc, char **argv)
tor_free(cf);
tor_free(cf_defaults);
if (errmsg) {
- log(LOG_WARN,LD_CONFIG,"%s", errmsg);
+ log_warn(LD_CONFIG,"%s", errmsg);
tor_free(errmsg);
}
return retval < 0 ? -1 : 0;
@@ -5377,7 +5427,7 @@ check_server_ports(const smartlist_t *ports,
}
if (n_low_port && options->AccountingMax) {
- log(LOG_WARN, LD_CONFIG,
+ log_warn(LD_CONFIG,
"You have set AccountingMax to use hibernation. You have also "
"chosen a low DirPort or OrPort. This combination can make Tor stop "
"working when it tries to re-attach the port after a period of "
diff --git a/src/or/connection.c b/src/or/connection.c
index b3719151f0..0d8242a54e 100644
--- a/src/or/connection.c
+++ b/src/or/connection.c
@@ -731,7 +731,7 @@ connection_mark_for_close_internal_(connection_t *conn,
tor_assert(file);
if (conn->marked_for_close) {
- log(LOG_WARN,LD_BUG,"Duplicate call to connection_mark_for_close at %s:%d"
+ log_warn(LD_BUG,"Duplicate call to connection_mark_for_close at %s:%d"
" (first at %s:%d)", file, line, conn->marked_for_close_file,
conn->marked_for_close);
tor_fragile_assert();
@@ -2530,7 +2530,7 @@ connection_bucket_refill_helper(int *bucket, int rate, int burst,
*bucket = burst;
}
}
- log(LOG_DEBUG, LD_NET,"%s now %d.", name, *bucket);
+ log_debug(LD_NET,"%s now %d.", name, *bucket);
}
}
@@ -3276,6 +3276,7 @@ connection_handle_write_impl(connection_t *conn, int force)
ssize_t max_to_write;
time_t now = approx_time();
size_t n_read = 0, n_written = 0;
+ int dont_stop_writing = 0;
tor_assert(!connection_is_listener(conn));
@@ -3332,6 +3333,7 @@ connection_handle_write_impl(connection_t *conn, int force)
if (connection_speaks_cells(conn) &&
conn->state > OR_CONN_STATE_PROXY_HANDSHAKING) {
or_connection_t *or_conn = TO_OR_CONN(conn);
+ size_t initial_size;
if (conn->state == OR_CONN_STATE_TLS_HANDSHAKING ||
conn->state == OR_CONN_STATE_TLS_CLIENT_RENEGOTIATING) {
connection_stop_writing(conn);
@@ -3355,6 +3357,7 @@ connection_handle_write_impl(connection_t *conn, int force)
}
/* else open, or closing */
+ initial_size = buf_datalen(conn->outbuf);
result = flush_buf_tls(or_conn->tls, conn->outbuf,
max_to_write, &conn->outbuf_flushlen);
@@ -3385,7 +3388,8 @@ connection_handle_write_impl(connection_t *conn, int force)
case TOR_TLS_WANTWRITE:
log_debug(LD_NET,"wanted write.");
/* we're already writing */
- return 0;
+ dont_stop_writing = 1;
+ break;
case TOR_TLS_WANTREAD:
/* Make sure to avoid a loop if the receive buckets are empty. */
log_debug(LD_NET,"wanted read.");
@@ -3407,6 +3411,12 @@ connection_handle_write_impl(connection_t *conn, int force)
tor_tls_get_n_raw_bytes(or_conn->tls, &n_read, &n_written);
log_debug(LD_GENERAL, "After TLS write of %d: %ld read, %ld written",
result, (long)n_read, (long)n_written);
+ /* So we notice bytes were written even on error */
+ /* XXXX024 This cast is safe since we can never write INT_MAX bytes in a
+ * single set of TLS operations. But it looks kinda ugly. If we refactor
+ * the *_buf_tls functions, we should make them return ssize_t or size_t
+ * or something. */
+ result = (int)(initial_size-buf_datalen(conn->outbuf));
} else {
CONN_LOG_PROTECT(conn,
result = flush_buf(conn->s, conn->outbuf,
@@ -3453,7 +3463,8 @@ connection_handle_write_impl(connection_t *conn, int force)
}
}
- if (!connection_wants_to_flush(conn)) { /* it's done flushing */
+ if (!connection_wants_to_flush(conn) &&
+ !dont_stop_writing) { /* it's done flushing */
if (connection_finished_flushing(conn) < 0) {
/* already marked */
return -1;
@@ -3897,7 +3908,7 @@ client_check_address_changed(tor_socket_t sock)
} else {
/* The interface changed. We're a client, so we need to regenerate our
* keys. First, reset the state. */
- log(LOG_NOTICE, LD_NET, "Our IP address has changed. Rotating keys...");
+ log_notice(LD_NET, "Our IP address has changed. Rotating keys...");
tor_addr_copy(*last_interface_ip_ptr, &iface_addr);
SMARTLIST_FOREACH(outgoing_addrs, tor_addr_t*, a_ptr, tor_free(a_ptr));
smartlist_clear(outgoing_addrs);
@@ -3981,8 +3992,9 @@ connection_flushed_some(connection_t *conn)
return r;
}
-/** We just finished flushing bytes from conn-\>outbuf, and there
- * are no more bytes remaining.
+/** We just finished flushing bytes to the appropriately low network layer,
+ * and there are no more bytes remaining in conn-\>outbuf, conn-\>bev, or
+ * conn-\>tls to be flushed.
*
* This function just passes conn to the connection-specific
* connection_*_finished_flushing() function.
@@ -4109,14 +4121,14 @@ connection_dump_buffer_mem_stats(int severity)
total_alloc += alloc_by_type[i];
}
- log(severity, LD_GENERAL,
+ tor_log(severity, LD_GENERAL,
"In buffers for %d connections: "U64_FORMAT" used/"U64_FORMAT" allocated",
smartlist_len(conns),
U64_PRINTF_ARG(total_used), U64_PRINTF_ARG(total_alloc));
for (i=CONN_TYPE_MIN_; i <= CONN_TYPE_MAX_; ++i) {
if (!n_conns_by_type[i])
continue;
- log(severity, LD_GENERAL,
+ tor_log(severity, LD_GENERAL,
" For %d %s connections: "U64_FORMAT" used/"U64_FORMAT" allocated",
n_conns_by_type[i], conn_type_to_string(i),
U64_PRINTF_ARG(used_by_type[i]), U64_PRINTF_ARG(alloc_by_type[i]));
diff --git a/src/or/connection_edge.c b/src/or/connection_edge.c
index 870ded98c9..b4fa3e6fe2 100644
--- a/src/or/connection_edge.c
+++ b/src/or/connection_edge.c
@@ -37,6 +37,7 @@
#include "router.h"
#include "routerlist.h"
#include "routerset.h"
+#include "circuitbuild.h"
#ifdef HAVE_LINUX_TYPES_H
#include <linux/types.h>
@@ -641,6 +642,10 @@ connection_ap_expire_beginning(void)
" '%s.onion'.",
seconds_idle,
safe_str_client(entry_conn->socks_request->address));
+ /* Roll back path bias use state so that we probe the circuit
+ * if nothing else succeeds on it */
+ pathbias_mark_use_rollback(TO_ORIGIN_CIRCUIT(circ));
+
connection_edge_end(conn, END_STREAM_REASON_TIMEOUT);
connection_mark_unattached_ap(entry_conn, END_STREAM_REASON_TIMEOUT);
}
@@ -805,6 +810,10 @@ connection_ap_detach_retriable(entry_connection_t *conn,
control_event_stream_status(conn, STREAM_EVENT_FAILED_RETRIABLE, reason);
ENTRY_TO_CONN(conn)->timestamp_lastread = time(NULL);
+ /* Roll back path bias use state so that we probe the circuit
+ * if nothing else succeeds on it */
+ pathbias_mark_use_rollback(circ);
+
if (conn->pending_optimistic_data) {
generic_buffer_set_to_copy(&conn->sending_optimistic_data,
conn->pending_optimistic_data);
@@ -2205,8 +2214,10 @@ connection_ap_handshake_socks_reply(entry_connection_t *conn, char *reply,
U64_PRINTF_ARG(ENTRY_TO_CONN(conn)->global_identifier),
endreason);
} else {
- TO_ORIGIN_CIRCUIT(conn->edge_.on_circuit)->path_state
- = PATH_STATE_USE_SUCCEEDED;
+ // XXX: Hrmm. It looks like optimistic data can't go through this
+ // codepath, but someone should probably test it and make sure.
+ // We don't want to mark optimistically opened streams as successful.
+ pathbias_mark_use_success(TO_ORIGIN_CIRCUIT(conn->edge_.on_circuit));
}
}
@@ -2480,7 +2491,7 @@ connection_exit_begin_conn(cell_t *cell, circuit_t *circ)
connection_exit_connect(n_stream);
/* For path bias: This circuit was used successfully */
- origin_circ->path_state = PATH_STATE_USE_SUCCEEDED;
+ pathbias_mark_use_success(origin_circ);
tor_free(address);
return 0;
diff --git a/src/or/connection_or.c b/src/or/connection_or.c
index 872decba11..5ec32d6324 100644
--- a/src/or/connection_or.c
+++ b/src/or/connection_or.c
@@ -295,13 +295,13 @@ connection_or_report_broken_states(int severity, int domain)
smartlist_sort(items, broken_state_count_compare);
- log(severity, domain, "%d connections have failed%s", total,
+ tor_log(severity, domain, "%d connections have failed%s", total,
smartlist_len(items) > MAX_REASONS_TO_REPORT ? ". Top reasons:" : ":");
SMARTLIST_FOREACH_BEGIN(items, const broken_state_count_t *, c) {
if (c_sl_idx > MAX_REASONS_TO_REPORT)
break;
- log(severity, domain,
+ tor_log(severity, domain,
" %d connections died in state %s", (int)c->count, c->state);
} SMARTLIST_FOREACH_END(c);
diff --git a/src/or/control.c b/src/or/control.c
index 54e5c597a1..9ab0dafb7b 100644
--- a/src/or/control.c
+++ b/src/or/control.c
@@ -4663,7 +4663,7 @@ control_event_bootstrap(bootstrap_status_t status, int progress)
if (status > bootstrap_percent ||
(progress && progress > bootstrap_percent)) {
bootstrap_status_to_string(status, &tag, &summary);
- log(status ? LOG_NOTICE : LOG_INFO, LD_CONTROL,
+ tor_log(status ? LOG_NOTICE : LOG_INFO, LD_CONTROL,
"Bootstrapped %d%%: %s.", progress ? progress : status, summary);
tor_snprintf(buf, sizeof(buf),
"BOOTSTRAP PROGRESS=%d TAG=%s SUMMARY=\"%s\"",
diff --git a/src/or/cpuworker.c b/src/or/cpuworker.c
index 465f15516d..b5740f091d 100644
--- a/src/or/cpuworker.c
+++ b/src/or/cpuworker.c
@@ -98,6 +98,11 @@ typedef struct cpuworker_request_t {
/** Task code. Must be one of CPUWORKER_TASK_* */
uint8_t task;
+ /** Flag: Are we timing this request? */
+ unsigned timed : 1;
+ /** If we're timing this request, when was it sent to the cpuworker? */
+ struct timeval started_at;
+
/** A create cell for the cpuworker to process. */
create_cell_t create_cell;
@@ -113,6 +118,17 @@ typedef struct cpuworker_reply_t {
/** True iff we got a successful request. */
uint8_t success;
+ /** Are we timing this request? */
+ unsigned int timed : 1;
+ /** What handshake type was the request? (Used for timing) */
+ uint16_t handshake_type;
+ /** When did we send the request to the cpuworker? */
+ struct timeval started_at;
+ /** Once the cpuworker received the request, how many microseconds did it
+ * take? (This shouldn't overflow; 4 billion micoseconds is over an hour,
+ * and we'll never have an onion handshake that takes so long.) */
+ uint32_t n_usec;
+
/** Output of processing a create cell
*
* @{
@@ -163,6 +179,110 @@ connection_cpu_reached_eof(connection_t *conn)
return 0;
}
+/** Indexed by handshake type: how many onionskins have we processed and
+ * counted of that type? */
+static uint64_t onionskins_n_processed[MAX_ONION_HANDSHAKE_TYPE+1];
+/** Indexed by handshake type, corresponding to the onionskins counted in
+ * onionskins_n_processed: how many microseconds have we spent in cpuworkers
+ * processing that kind of onionskin? */
+static uint64_t onionskins_usec_internal[MAX_ONION_HANDSHAKE_TYPE+1];
+/** Indexed by handshake type, corresponding to onionskins counted in
+ * onionskins_n_processed: how many microseconds have we spent waiting for
+ * cpuworkers to give us answers for that kind of onionskin?
+ */
+static uint64_t onionskins_usec_roundtrip[MAX_ONION_HANDSHAKE_TYPE+1];
+
+/** If any onionskin takes longer than this, we clip them to this
+ * time. (microseconds) */
+#define MAX_BELIEVABLE_ONIONSKIN_DELAY (2*1000*1000)
+
+/** Return true iff we'd like to measure a handshake of type
+ * <b>onionskin_type</b>. */
+static int
+should_time_request(uint16_t onionskin_type)
+{
+ /* If we've never heard of this type, we shouldn't even be here. */
+ if (onionskin_type > MAX_ONION_HANDSHAKE_TYPE)
+ return 0;
+ /* Measure the first N handshakes of each type, to ensure we have a
+ * sample */
+ if (onionskins_n_processed[onionskin_type] < 4096)
+ return 1;
+ /** Otherwise, measure with P=1/128. We avoid doing this for every
+ * handshake, since the measurement itself can take a little time. */
+ return tor_weak_random() < (TOR_RAND_MAX/128);
+}
+
+/** Return an estimate of how many microseconds we will need for a single
+ * cpuworker to to process <b>n_requests</b> onionskins of type
+ * <b>onionskin_type</b>. */
+uint64_t
+estimated_usec_for_onionskins(uint32_t n_requests, uint16_t onionskin_type)
+{
+ if (onionskin_type > MAX_ONION_HANDSHAKE_TYPE) /* should be impossible */
+ return 1000 * n_requests;
+ if (PREDICT_UNLIKELY(onionskins_n_processed[onionskin_type] < 100)) {
+ /* Until we have 100 data points, just asssume everything takes 1 msec. */
+ return 1000 * n_requests;
+ } else {
+ /* This can't overflow: we'll never have more than 500000 onionskins
+ * measured in onionskin_usec_internal, and they won't take anything near
+ * 1 sec each, and we won't have anything like 1 million queued
+ * onionskins. But that's 5e5 * 1e6 * 1e6, which is still less than
+ * UINT64_MAX. */
+ return (onionskins_usec_internal[onionskin_type] * n_requests) /
+ onionskins_n_processed[onionskin_type];
+ }
+}
+
+/** Compute the absolute and relative overhead of using the cpuworker
+ * framework for onionskins of type <b>onionskin_type</b>.*/
+static int
+get_overhead_for_onionskins(uint32_t *usec_out, double *frac_out,
+ uint16_t onionskin_type)
+{
+ uint64_t overhead;
+
+ *usec_out = 0;
+ *frac_out = 0.0;
+
+ if (onionskin_type > MAX_ONION_HANDSHAKE_TYPE) /* should be impossible */
+ return -1;
+ if (onionskins_n_processed[onionskin_type] == 0 ||
+ onionskins_usec_internal[onionskin_type] == 0 ||
+ onionskins_usec_roundtrip[onionskin_type] == 0)
+ return -1;
+
+ overhead = onionskins_usec_roundtrip[onionskin_type] -
+ onionskins_usec_internal[onionskin_type];
+
+ *usec_out = (uint32_t)(overhead / onionskins_n_processed[onionskin_type]);
+ *frac_out = U64_TO_DBL(overhead) / onionskins_usec_internal[onionskin_type];
+
+ return 0;
+}
+
+/** If we've measured overhead for onionskins of type <b>onionskin_type</b>,
+ * log it. */
+void
+cpuworker_log_onionskin_overhead(int severity, int onionskin_type,
+ const char *onionskin_type_name)
+{
+ uint32_t overhead;
+ double relative_overhead;
+ int r;
+
+ r = get_overhead_for_onionskins(&overhead, &relative_overhead,
+ onionskin_type);
+ if (!overhead || r<0)
+ return;
+
+ log_fn(severity, LD_OR,
+ "%s onionskins have averaged %u usec overhead (%.2f%%) in "
+ "cpuworker code ",
+ onionskin_type_name, (unsigned)overhead, relative_overhead*100);
+}
+
/** Called when we get data from a cpuworker. If the answer is not complete,
* wait for a complete answer. If the answer is complete,
* process it as appropriate.
@@ -190,6 +310,30 @@ connection_cpu_process_inbuf(connection_t *conn)
connection_fetch_from_buf((void*)&rpl,sizeof(cpuworker_reply_t),conn);
tor_assert(rpl.magic == CPUWORKER_REPLY_MAGIC);
+
+ if (rpl.timed && rpl.success &&
+ rpl.handshake_type <= MAX_ONION_HANDSHAKE_TYPE) {
+ /* Time how long this request took. The handshake_type check should be
+ needless, but let's leave it in to be safe. */
+ struct timeval tv_end, tv_diff;
+ int64_t usec_roundtrip;
+ tor_gettimeofday(&tv_end);
+ timersub(&tv_end, &rpl.started_at, &tv_diff);
+ usec_roundtrip = ((int64_t)tv_diff.tv_sec)*1000000 + tv_diff.tv_usec;
+ if (usec_roundtrip >= 0 &&
+ usec_roundtrip < MAX_BELIEVABLE_ONIONSKIN_DELAY) {
+ ++onionskins_n_processed[rpl.handshake_type];
+ onionskins_usec_internal[rpl.handshake_type] += rpl.n_usec;
+ onionskins_usec_roundtrip[rpl.handshake_type] += usec_roundtrip;
+ if (onionskins_n_processed[rpl.handshake_type] >= 500000) {
+ /* Scale down every 500000 handshakes. On a busy server, that's
+ * less impressive than it sounds. */
+ onionskins_n_processed[rpl.handshake_type] /= 2;
+ onionskins_usec_internal[rpl.handshake_type] /= 2;
+ onionskins_usec_roundtrip[rpl.handshake_type] /= 2;
+ }
+ }
+ }
/* parse out the circ it was talking about */
tag_unpack(rpl.tag, &chan_id, &circ_id);
circ = NULL;
@@ -289,7 +433,13 @@ cpuworker_main(void *data)
if (req.task == CPUWORKER_TASK_ONION) {
const create_cell_t *cc = &req.create_cell;
created_cell_t *cell_out = &rpl.created_cell;
+ struct timeval tv_start, tv_end;
int n;
+ rpl.timed = req.timed;
+ rpl.started_at = req.started_at;
+ rpl.handshake_type = cc->handshake_type;
+ if (req.timed)
+ tor_gettimeofday(&tv_start);
n = onion_skin_server_handshake(cc->handshake_type,
cc->onionskin, cc->handshake_len,
&onion_keys,
@@ -321,6 +471,17 @@ cpuworker_main(void *data)
rpl.success = 1;
}
rpl.magic = CPUWORKER_REPLY_MAGIC;
+ if (req.timed) {
+ struct timeval tv_diff;
+ int64_t usec;
+ tor_gettimeofday(&tv_end);
+ timersub(&tv_end, &tv_start, &tv_diff);
+ usec = ((int64_t)tv_diff.tv_sec)*1000000 + tv_diff.tv_usec;
+ if (usec < 0 || usec > MAX_BELIEVABLE_ONIONSKIN_DELAY)
+ rpl.n_usec = MAX_BELIEVABLE_ONIONSKIN_DELAY;
+ else
+ rpl.n_usec = (uint32_t) usec;
+ }
if (write_all(fd, (void*)&rpl, sizeof(rpl), 1) != sizeof(rpl)) {
log_err(LD_BUG,"writing response buf failed. Exiting.");
goto end;
@@ -478,6 +639,7 @@ assign_onionskin_to_cpuworker(connection_t *cpuworker,
cpuworker_request_t req;
time_t now = approx_time();
static time_t last_culled_cpuworkers = 0;
+ int should_time;
/* Checking for wedged cpuworkers requires a linear search over all
* connections, so let's do it only once a minute.
@@ -512,16 +674,18 @@ assign_onionskin_to_cpuworker(connection_t *cpuworker,
return -1;
}
+ should_time = should_time_request(onionskin->handshake_type);
memset(&req, 0, sizeof(req));
req.magic = CPUWORKER_REQUEST_MAGIC;
tag_pack(req.tag, circ->p_chan->global_identifier,
circ->p_circ_id);
+ req.timed = should_time;
cpuworker->state = CPUWORKER_STATE_BUSY_ONION;
/* touch the lastwritten timestamp, since that's how we check to
* see how long it's been since we asked the question, and sometimes
* we check before the first call to connection_handle_write(). */
- cpuworker->timestamp_lastwritten = time(NULL);
+ cpuworker->timestamp_lastwritten = now;
num_cpuworkers_busy++;
req.task = CPUWORKER_TASK_ONION;
@@ -529,6 +693,9 @@ assign_onionskin_to_cpuworker(connection_t *cpuworker,
tor_free(onionskin);
+ if (should_time)
+ tor_gettimeofday(&req.started_at);
+
connection_write_to_buf((void*)&req, sizeof(req), cpuworker);
memwipe(&req, 0, sizeof(req));
}
diff --git a/src/or/cpuworker.h b/src/or/cpuworker.h
index 18d45153c7..317cef43ba 100644
--- a/src/or/cpuworker.h
+++ b/src/or/cpuworker.h
@@ -22,5 +22,10 @@ int assign_onionskin_to_cpuworker(connection_t *cpuworker,
or_circuit_t *circ,
struct create_cell_t *onionskin);
+uint64_t estimated_usec_for_onionskins(uint32_t n_requests,
+ uint16_t onionskin_type);
+void cpuworker_log_onionskin_overhead(int severity, int onionskin_type,
+ const char *onionskin_type_name);
+
#endif
diff --git a/src/or/directory.c b/src/or/directory.c
index 692a6d6b2c..c101418446 100644
--- a/src/or/directory.c
+++ b/src/or/directory.c
@@ -1860,7 +1860,7 @@ connection_dir_client_reached_eof(dir_connection_t *conn)
const char *flavname = conn->requested_resource;
if (status_code != 200) {
int severity = (status_code == 304) ? LOG_INFO : LOG_WARN;
- log(severity, LD_DIR,
+ tor_log(severity, LD_DIR,
"Received http status code %d (%s) from server "
"'%s:%d' while fetching consensus directory.",
status_code, escaped(reason), conn->base_.address,
@@ -2800,8 +2800,6 @@ directory_handle_command_get(dir_connection_t *conn, const char *headers,
/* v2 or v3 network status fetch. */
smartlist_t *dir_fps = smartlist_new();
int is_v3 = !strcmpstart(url, "/tor/status-vote");
- geoip_client_action_t act =
- is_v3 ? GEOIP_CLIENT_NETWORKSTATUS : GEOIP_CLIENT_NETWORKSTATUS_V2;
const char *request_type = NULL;
const char *key = url + strlen("/tor/status/");
long lifetime = NETWORKSTATUS_CACHE_LIFETIME;
@@ -2851,7 +2849,7 @@ directory_handle_command_get(dir_connection_t *conn, const char *headers,
write_http_status_line(conn, 404, "Consensus not signed by sufficient "
"number of requested authorities");
smartlist_free(dir_fps);
- geoip_note_ns_response(act, GEOIP_REJECT_NOT_ENOUGH_SIGS);
+ geoip_note_ns_response(GEOIP_REJECT_NOT_ENOUGH_SIGS);
tor_free(flavor);
goto done;
}
@@ -2870,7 +2868,8 @@ directory_handle_command_get(dir_connection_t *conn, const char *headers,
if (!smartlist_len(dir_fps)) { /* we failed to create/cache cp */
write_http_status_line(conn, 503, "Network status object unavailable");
smartlist_free(dir_fps);
- geoip_note_ns_response(act, GEOIP_REJECT_UNAVAILABLE);
+ if (is_v3)
+ geoip_note_ns_response(GEOIP_REJECT_UNAVAILABLE);
goto done;
}
@@ -2878,13 +2877,15 @@ directory_handle_command_get(dir_connection_t *conn, const char *headers,
write_http_status_line(conn, 404, "Not found");
SMARTLIST_FOREACH(dir_fps, char *, cp, tor_free(cp));
smartlist_free(dir_fps);
- geoip_note_ns_response(act, GEOIP_REJECT_NOT_FOUND);
+ if (is_v3)
+ geoip_note_ns_response(GEOIP_REJECT_NOT_FOUND);
goto done;
} else if (!smartlist_len(dir_fps)) {
write_http_status_line(conn, 304, "Not modified");
SMARTLIST_FOREACH(dir_fps, char *, cp, tor_free(cp));
smartlist_free(dir_fps);
- geoip_note_ns_response(act, GEOIP_REJECT_NOT_MODIFIED);
+ if (is_v3)
+ geoip_note_ns_response(GEOIP_REJECT_NOT_MODIFIED);
goto done;
}
@@ -2896,24 +2897,24 @@ directory_handle_command_get(dir_connection_t *conn, const char *headers,
write_http_status_line(conn, 503, "Directory busy, try again later");
SMARTLIST_FOREACH(dir_fps, char *, fp, tor_free(fp));
smartlist_free(dir_fps);
- geoip_note_ns_response(act, GEOIP_REJECT_BUSY);
+ if (is_v3)
+ geoip_note_ns_response(GEOIP_REJECT_BUSY);
goto done;
}
- {
+ if (is_v3) {
struct in_addr in;
tor_addr_t addr;
if (tor_inet_aton((TO_CONN(conn))->address, &in)) {
tor_addr_from_ipv4h(&addr, ntohl(in.s_addr));
- geoip_note_client_seen(act, &addr, time(NULL));
- geoip_note_ns_response(act, GEOIP_SUCCESS);
+ geoip_note_client_seen(GEOIP_CLIENT_NETWORKSTATUS, &addr, time(NULL));
+ geoip_note_ns_response(GEOIP_SUCCESS);
/* Note that a request for a network status has started, so that we
* can measure the download time later on. */
if (conn->dirreq_id)
- geoip_start_dirreq(conn->dirreq_id, dlen, act,
- DIRREQ_TUNNELED);
+ geoip_start_dirreq(conn->dirreq_id, dlen, DIRREQ_TUNNELED);
else
- geoip_start_dirreq(TO_CONN(conn)->global_identifier, dlen, act,
+ geoip_start_dirreq(TO_CONN(conn)->global_identifier, dlen,
DIRREQ_DIRECT);
}
}
diff --git a/src/or/dirserv.c b/src/or/dirserv.c
index 8af848ca02..e2cd7cfd26 100644
--- a/src/or/dirserv.c
+++ b/src/or/dirserv.c
@@ -2017,7 +2017,7 @@ dirserv_compute_performance_thresholds(routerlist_t *rl)
median_uint32(bandwidths_excluding_exits, n_active_nonexit);
}
- log(LOG_INFO, LD_DIRSERV,
+ log_info(LD_DIRSERV,
"Cutoffs: For Stable, %lu sec uptime, %lu sec MTBF. "
"For Fast: %lu bytes/sec. "
"For Guard: WFU %.03f%%, time-known %lu sec, "
diff --git a/src/or/dirvote.c b/src/or/dirvote.c
index 0731426d97..aee9a6edfe 100644
--- a/src/or/dirvote.c
+++ b/src/or/dirvote.c
@@ -2288,7 +2288,7 @@ networkstatus_add_detached_signatures(networkstatus_t *target,
if (sig->good_signature || !old_sig || old_sig->bad_signature) {
log_info(LD_DIR, "Adding signature from %s with %s", voter_identity,
algorithm);
- log(severity, LD_DIR, "Added a signature for %s from %s.",
+ tor_log(severity, LD_DIR, "Added a signature for %s from %s.",
target_voter->nickname, source);
++r;
if (old_sig) {
diff --git a/src/or/dns.c b/src/or/dns.c
index 68309a80df..edcf92e5b3 100644
--- a/src/or/dns.c
+++ b/src/or/dns.c
@@ -262,7 +262,7 @@ evdns_log_cb(int warn, const char *msg)
int severity = warn ? LOG_WARN : LOG_INFO;
if (!strcmpstart(msg, "Resolve requested for") &&
get_options()->SafeLogging) {
- log(LOG_INFO, LD_EXIT, "eventdns: Resolve requested.");
+ log_info(LD_EXIT, "eventdns: Resolve requested.");
return;
} else if (!strcmpstart(msg, "Search: ")) {
return;
@@ -291,7 +291,7 @@ evdns_log_cb(int warn, const char *msg)
control_event_server_status(LOG_WARN, "NAMESERVER_ALL_DOWN");
all_down = 1;
}
- log(severity, LD_EXIT, "eventdns: %s", msg);
+ tor_log(severity, LD_EXIT, "eventdns: %s", msg);
}
/** Helper: passed to eventdns.c as a callback so it can generate random
@@ -835,7 +835,7 @@ dns_resolve_impl(edge_connection_t *exitconn, int is_resolve,
return -1;
if (address_is_invalid_destination(exitconn->base_.address, 0)) {
- log(LOG_PROTOCOL_WARN, LD_EXIT,
+ tor_log(LOG_PROTOCOL_WARN, LD_EXIT,
"Rejecting invalid destination address %s",
escaped_safe_str(exitconn->base_.address));
return -1;
@@ -1844,7 +1844,7 @@ wildcard_increment_answer(const char *id)
if (*ip > 5 && n_wildcard_requests > 10) {
if (!dns_wildcard_list) dns_wildcard_list = smartlist_new();
if (!smartlist_contains_string(dns_wildcard_list, id)) {
- log(dns_wildcard_notice_given ? LOG_INFO : LOG_NOTICE, LD_EXIT,
+ tor_log(dns_wildcard_notice_given ? LOG_INFO : LOG_NOTICE, LD_EXIT,
"Your DNS provider has given \"%s\" as an answer for %d different "
"invalid addresses. Apparently they are hijacking DNS failures. "
"I'll try to correct for this by treating future occurrences of "
@@ -1876,7 +1876,7 @@ add_wildcarded_test_address(const char *address)
smartlist_add(dns_wildcarded_test_address_list, tor_strdup(address));
n = smartlist_len(dns_wildcarded_test_address_list);
if (n > n_test_addrs/2) {
- log(dns_wildcarded_test_address_notice_given ? LOG_INFO : LOG_NOTICE,
+ tor_log(dns_wildcarded_test_address_notice_given ? LOG_INFO : LOG_NOTICE,
LD_EXIT, "Your DNS provider tried to redirect \"%s\" to a junk "
"address. It has done this with %d test addresses so far. I'm "
"going to stop being an exit node for now, since our DNS seems so "
@@ -1920,7 +1920,7 @@ evdns_wildcard_check_callback(int result, char type, int count, int ttl,
}
}
- log(dns_wildcard_one_notice_given ? LOG_INFO : LOG_NOTICE, LD_EXIT,
+ tor_log(dns_wildcard_one_notice_given ? LOG_INFO : LOG_NOTICE, LD_EXIT,
"Your DNS provider gave an answer for \"%s\", which "
"is not supposed to exist. Apparently they are hijacking "
"DNS failures. Trying to correct for this. We've noticed %d "
@@ -2151,8 +2151,8 @@ dump_dns_mem_usage(int severity)
/* Print out the count and estimated size of our &cache_root. It undercounts
hostnames in cached reverse resolves.
*/
- log(severity, LD_MM, "Our DNS cache has %d entries.", hash_count);
- log(severity, LD_MM, "Our DNS cache size is approximately %u bytes.",
+ tor_log(severity, LD_MM, "Our DNS cache has %d entries.", hash_count);
+ tor_log(severity, LD_MM, "Our DNS cache size is approximately %u bytes.",
(unsigned)hash_mem);
}
diff --git a/src/or/entrynodes.c b/src/or/entrynodes.c
index 3e58371643..4ca56cbacf 100644
--- a/src/or/entrynodes.c
+++ b/src/or/entrynodes.c
@@ -1098,6 +1098,40 @@ entry_guards_parse_state(or_state_t *state, int set, char **msg)
continue;
}
digestmap_set(added_by, d, tor_strdup(line->value+HEX_DIGEST_LEN+1));
+ } else if (!strcasecmp(line->key, "EntryGuardPathUseBias")) {
+ const or_options_t *options = get_options();
+ double use_cnt, success_cnt;
+
+ if (!node) {
+ *msg = tor_strdup("Unable to parse entry nodes: "
+ "EntryGuardPathUseBias without EntryGuard");
+ break;
+ }
+
+ if (tor_sscanf(line->value, "%lf %lf",
+ &use_cnt, &success_cnt) != 2) {
+ log_info(LD_GENERAL, "Malformed path use bias line for node %s",
+ node->nickname);
+ continue;
+ }
+
+ node->use_attempts = use_cnt;
+ node->use_successes = success_cnt;
+
+ log_info(LD_GENERAL, "Read %f/%f path use bias for node %s",
+ node->use_successes, node->use_attempts, node->nickname);
+
+ /* Note: We rely on the < comparison here to allow us to set a 0
+ * rate and disable the feature entirely. If refactoring, don't
+ * change to <= */
+ if (pathbias_get_use_success_count(node)/node->use_attempts
+ < pathbias_get_extreme_use_rate(options) &&
+ pathbias_get_dropguards(options)) {
+ node->path_bias_disabled = 1;
+ log_info(LD_GENERAL,
+ "Path use bias is too high (%f/%f); disabling node %s",
+ node->circ_successes, node->circ_attempts, node->nickname);
+ }
} else if (!strcasecmp(line->key, "EntryGuardPathBias")) {
const or_options_t *options = get_options();
double hop_cnt, success_cnt, timeouts, collapsed, successful_closed,
@@ -1144,7 +1178,7 @@ entry_guards_parse_state(or_state_t *state, int set, char **msg)
/* Note: We rely on the < comparison here to allow us to set a 0
* rate and disable the feature entirely. If refactoring, don't
* change to <= */
- if (pathbias_get_success_count(node)/node->circ_attempts
+ if (pathbias_get_close_success_count(node)/node->circ_attempts
< pathbias_get_extreme_rate(options) &&
pathbias_get_dropguards(options)) {
node->path_bias_disabled = 1;
@@ -1282,10 +1316,20 @@ entry_guards_update_state(or_state_t *state)
* unusable_circuits */
tor_asprintf(&line->value, "%f %f %f %f %f %f",
e->circ_attempts, e->circ_successes,
- pathbias_get_closed_count(e), e->collapsed_circuits,
+ pathbias_get_close_success_count(e),
+ e->collapsed_circuits,
e->unusable_circuits, e->timeouts);
next = &(line->next);
}
+ if (e->use_attempts > 0) {
+ *next = line = tor_malloc_zero(sizeof(config_line_t));
+ line->key = tor_strdup("EntryGuardPathUseBias");
+
+ tor_asprintf(&line->value, "%f %f",
+ e->use_attempts,
+ pathbias_get_use_success_count(e));
+ next = &(line->next);
+ }
} SMARTLIST_FOREACH_END(e);
if (!get_options()->AvoidDiskWrites)
diff --git a/src/or/entrynodes.h b/src/or/entrynodes.h
index 1e52ba28ea..e6c973c95a 100644
--- a/src/or/entrynodes.h
+++ b/src/or/entrynodes.h
@@ -61,6 +61,9 @@ typedef struct entry_guard_t {
* attempted, but none succeeded. */
double timeouts; /**< Number of 'right-censored' circuit timeouts for this
* guard. */
+ double use_attempts; /**< Number of circuits we tried to use with streams */
+ double use_successes; /**< Number of successfully used circuits using
+ * this guard as first hop. */
} entry_guard_t;
entry_guard_t *entry_guard_get_by_id_digest(const char *digest);
@@ -113,8 +116,8 @@ int find_transport_by_bridge_addrport(const tor_addr_t *addr, uint16_t port,
int validate_pluggable_transports_config(void);
-double pathbias_get_closed_count(entry_guard_t *gaurd);
-double pathbias_get_success_count(entry_guard_t *guard);
+double pathbias_get_close_success_count(entry_guard_t *guard);
+double pathbias_get_use_success_count(entry_guard_t *guard);
#endif
diff --git a/src/or/geoip.c b/src/or/geoip.c
index f9d036e07e..9ba1e31b8b 100644
--- a/src/or/geoip.c
+++ b/src/or/geoip.c
@@ -38,7 +38,6 @@ typedef struct geoip_ipv6_entry_t {
/** A per-country record for GeoIP request history. */
typedef struct geoip_country_t {
char countrycode[3];
- uint32_t n_v2_ns_requests;
uint32_t n_v3_ns_requests;
} geoip_country_t;
@@ -515,67 +514,6 @@ client_history_clear(void)
}
}
-/** How often do we update our estimate which share of v2 and v3 directory
- * requests is sent to us? We could as well trigger updates of shares from
- * network status updates, but that means adding a lot of calls into code
- * that is independent from geoip stats (and keeping them up-to-date). We
- * are perfectly fine with an approximation of 15-minute granularity. */
-#define REQUEST_SHARE_INTERVAL (15 * 60)
-
-/** When did we last determine which share of v2 and v3 directory requests
- * is sent to us? */
-static time_t last_time_determined_shares = 0;
-
-/** Sum of products of v2 shares times the number of seconds for which we
- * consider these shares as valid. */
-static double v2_share_times_seconds;
-
-/** Sum of products of v3 shares times the number of seconds for which we
- * consider these shares as valid. */
-static double v3_share_times_seconds;
-
-/** Number of seconds we are determining v2 and v3 shares. */
-static int share_seconds;
-
-/** Try to determine which fraction of v2 and v3 directory requests aimed at
- * caches will be sent to us at time <b>now</b> and store that value in
- * order to take a mean value later on. */
-static void
-geoip_determine_shares(time_t now)
-{
- double v2_share = 0.0, v3_share = 0.0;
- if (router_get_my_share_of_directory_requests(&v2_share, &v3_share) < 0)
- return;
- if (last_time_determined_shares) {
- v2_share_times_seconds += v2_share *
- ((double) (now - last_time_determined_shares));
- v3_share_times_seconds += v3_share *
- ((double) (now - last_time_determined_shares));
- share_seconds += (int)(now - last_time_determined_shares);
- }
- last_time_determined_shares = now;
-}
-
-/** Calculate which fraction of v2 and v3 directory requests aimed at caches
- * have been sent to us since the last call of this function up to time
- * <b>now</b>. Set *<b>v2_share_out</b> and *<b>v3_share_out</b> to the
- * fractions of v2 and v3 protocol shares we expect to have seen. Reset
- * counters afterwards. Return 0 on success, -1 on failure (e.g. when zero
- * seconds have passed since the last call).*/
-static int
-geoip_get_mean_shares(time_t now, double *v2_share_out,
- double *v3_share_out)
-{
- geoip_determine_shares(now);
- if (!share_seconds)
- return -1;
- *v2_share_out = v2_share_times_seconds / ((double) share_seconds);
- *v3_share_out = v3_share_times_seconds / ((double) share_seconds);
- v2_share_times_seconds = v3_share_times_seconds = 0.0;
- share_seconds = 0;
- return 0;
-}
-
/** Note that we've seen a client connect from the IP <b>addr</b>
* at time <b>now</b>. Ignored by all but bridges and directories if
* configured accordingly. */
@@ -610,22 +548,14 @@ geoip_note_client_seen(geoip_client_action_t action,
else
ent->last_seen_in_minutes = 0;
- if (action == GEOIP_CLIENT_NETWORKSTATUS ||
- action == GEOIP_CLIENT_NETWORKSTATUS_V2) {
+ if (action == GEOIP_CLIENT_NETWORKSTATUS) {
int country_idx = geoip_get_country_by_addr(addr);
if (country_idx < 0)
country_idx = 0; /** unresolved requests are stored at index 0. */
if (country_idx >= 0 && country_idx < smartlist_len(geoip_countries)) {
geoip_country_t *country = smartlist_get(geoip_countries, country_idx);
- if (action == GEOIP_CLIENT_NETWORKSTATUS)
- ++country->n_v3_ns_requests;
- else
- ++country->n_v2_ns_requests;
+ ++country->n_v3_ns_requests;
}
-
- /* Periodically determine share of requests that we should see */
- if (last_time_determined_shares + REQUEST_SHARE_INTERVAL < now)
- geoip_determine_shares(now);
}
}
@@ -652,36 +582,24 @@ geoip_remove_old_clients(time_t cutoff)
&cutoff);
}
-/** How many responses are we giving to clients requesting v2 network
- * statuses? */
-static uint32_t ns_v2_responses[GEOIP_NS_RESPONSE_NUM];
-
/** How many responses are we giving to clients requesting v3 network
* statuses? */
static uint32_t ns_v3_responses[GEOIP_NS_RESPONSE_NUM];
-/** Note that we've rejected a client's request for a v2 or v3 network
- * status, encoded in <b>action</b> for reason <b>reason</b> at time
- * <b>now</b>. */
+/** Note that we've rejected a client's request for a v3 network status
+ * for reason <b>reason</b> at time <b>now</b>. */
void
-geoip_note_ns_response(geoip_client_action_t action,
- geoip_ns_response_t response)
+geoip_note_ns_response(geoip_ns_response_t response)
{
static int arrays_initialized = 0;
if (!get_options()->DirReqStatistics)
return;
if (!arrays_initialized) {
- memset(ns_v2_responses, 0, sizeof(ns_v2_responses));
memset(ns_v3_responses, 0, sizeof(ns_v3_responses));
arrays_initialized = 1;
}
- tor_assert(action == GEOIP_CLIENT_NETWORKSTATUS ||
- action == GEOIP_CLIENT_NETWORKSTATUS_V2);
tor_assert(response < GEOIP_NS_RESPONSE_NUM);
- if (action == GEOIP_CLIENT_NETWORKSTATUS)
- ns_v3_responses[response]++;
- else
- ns_v2_responses[response]++;
+ ns_v3_responses[response]++;
}
/** Do not mention any country from which fewer than this number of IPs have
@@ -736,7 +654,6 @@ typedef struct dirreq_map_entry_t {
unsigned int state:3; /**< State of this directory request. */
unsigned int type:1; /**< Is this a direct or a tunneled request? */
unsigned int completed:1; /**< Is this request complete? */
- unsigned int action:2; /**< Is this a v2 or v3 request? */
/** When did we receive the request and started sending the response? */
struct timeval request_time;
size_t response_size; /**< What is the size of the response in bytes? */
@@ -805,12 +722,11 @@ dirreq_map_get_(dirreq_type_t type, uint64_t dirreq_id)
}
/** Note that an either direct or tunneled (see <b>type</b>) directory
- * request for a network status with unique ID <b>dirreq_id</b> of size
- * <b>response_size</b> and action <b>action</b> (either v2 or v3) has
- * started. */
+ * request for a v3 network status with unique ID <b>dirreq_id</b> of size
+ * <b>response_size</b> has started. */
void
geoip_start_dirreq(uint64_t dirreq_id, size_t response_size,
- geoip_client_action_t action, dirreq_type_t type)
+ dirreq_type_t type)
{
dirreq_map_entry_t *ent;
if (!get_options()->DirReqStatistics)
@@ -819,7 +735,6 @@ geoip_start_dirreq(uint64_t dirreq_id, size_t response_size,
ent->dirreq_id = dirreq_id;
tor_gettimeofday(&ent->request_time);
ent->response_size = response_size;
- ent->action = action;
ent->type = type;
dirreq_map_put_(ent, type, dirreq_id);
}
@@ -860,8 +775,7 @@ geoip_change_dirreq_state(uint64_t dirreq_id, dirreq_type_t type,
* times by deciles and quartiles. Return NULL if we have not observed
* requests for long enough. */
static char *
-geoip_get_dirreq_history(geoip_client_action_t action,
- dirreq_type_t type)
+geoip_get_dirreq_history(dirreq_type_t type)
{
char *result = NULL;
smartlist_t *dirreq_completed = NULL;
@@ -871,13 +785,10 @@ geoip_get_dirreq_history(geoip_client_action_t action,
struct timeval now;
tor_gettimeofday(&now);
- if (action != GEOIP_CLIENT_NETWORKSTATUS &&
- action != GEOIP_CLIENT_NETWORKSTATUS_V2)
- return NULL;
dirreq_completed = smartlist_new();
for (ptr = HT_START(dirreqmap, &dirreq_map); ptr; ptr = next) {
ent = *ptr;
- if (ent->action != action || ent->type != type) {
+ if (ent->type != type) {
next = HT_NEXT(dirreqmap, &dirreq_map, ptr);
continue;
} else {
@@ -1063,18 +974,15 @@ geoip_get_client_history(geoip_client_action_t action,
}
/** Return a newly allocated string holding the per-country request history
- * for <b>action</b> in a format suitable for an extra-info document, or NULL
- * on failure. */
+ * for v3 network statuses in a format suitable for an extra-info document,
+ * or NULL on failure. */
char *
-geoip_get_request_history(geoip_client_action_t action)
+geoip_get_request_history(void)
{
smartlist_t *entries, *strings;
char *result;
unsigned granularity = IP_GRANULARITY;
- if (action != GEOIP_CLIENT_NETWORKSTATUS &&
- action != GEOIP_CLIENT_NETWORKSTATUS_V2)
- return NULL;
if (!geoip_countries)
return NULL;
@@ -1082,8 +990,7 @@ geoip_get_request_history(geoip_client_action_t action)
SMARTLIST_FOREACH_BEGIN(geoip_countries, geoip_country_t *, c) {
uint32_t tot = 0;
c_hist_t *ent;
- tot = (action == GEOIP_CLIENT_NETWORKSTATUS) ?
- c->n_v3_ns_requests : c->n_v2_ns_requests;
+ tot = c->n_v3_ns_requests;
if (!tot)
continue;
ent = tor_malloc_zero(sizeof(c_hist_t));
@@ -1121,14 +1028,13 @@ void
geoip_reset_dirreq_stats(time_t now)
{
SMARTLIST_FOREACH(geoip_countries, geoip_country_t *, c, {
- c->n_v2_ns_requests = c->n_v3_ns_requests = 0;
+ c->n_v3_ns_requests = 0;
});
{
clientmap_entry_t **ent, **next, *this;
for (ent = HT_START(clientmap, &client_history); ent != NULL;
ent = next) {
- if ((*ent)->action == GEOIP_CLIENT_NETWORKSTATUS ||
- (*ent)->action == GEOIP_CLIENT_NETWORKSTATUS_V2) {
+ if ((*ent)->action == GEOIP_CLIENT_NETWORKSTATUS) {
this = *ent;
next = HT_NEXT_RMV(clientmap, &client_history, ent);
tor_free(this);
@@ -1137,10 +1043,6 @@ geoip_reset_dirreq_stats(time_t now)
}
}
}
- v2_share_times_seconds = v3_share_times_seconds = 0.0;
- last_time_determined_shares = 0;
- share_seconds = 0;
- memset(ns_v2_responses, 0, sizeof(ns_v2_responses));
memset(ns_v3_responses, 0, sizeof(ns_v3_responses));
{
dirreq_map_entry_t **ent, **next, *this;
@@ -1168,12 +1070,9 @@ char *
geoip_format_dirreq_stats(time_t now)
{
char t[ISO_TIME_LEN+1];
- double v2_share = 0.0, v3_share = 0.0;
int i;
- char *v3_ips_string, *v2_ips_string, *v3_reqs_string, *v2_reqs_string,
- *v2_share_string = NULL, *v3_share_string = NULL,
- *v3_direct_dl_string, *v2_direct_dl_string,
- *v3_tunneled_dl_string, *v2_tunneled_dl_string;
+ char *v3_ips_string, *v3_reqs_string, *v3_direct_dl_string,
+ *v3_tunneled_dl_string;
char *result;
if (!start_of_dirreq_stats_interval)
@@ -1182,90 +1081,45 @@ geoip_format_dirreq_stats(time_t now)
tor_assert(now >= start_of_dirreq_stats_interval);
format_iso_time(t, now);
- geoip_get_client_history(GEOIP_CLIENT_NETWORKSTATUS_V2, &v2_ips_string,
- NULL);
geoip_get_client_history(GEOIP_CLIENT_NETWORKSTATUS, &v3_ips_string, NULL);
- v2_reqs_string = geoip_get_request_history(
- GEOIP_CLIENT_NETWORKSTATUS_V2);
- v3_reqs_string = geoip_get_request_history(GEOIP_CLIENT_NETWORKSTATUS);
+ v3_reqs_string = geoip_get_request_history();
#define RESPONSE_GRANULARITY 8
for (i = 0; i < GEOIP_NS_RESPONSE_NUM; i++) {
- ns_v2_responses[i] = round_uint32_to_next_multiple_of(
- ns_v2_responses[i], RESPONSE_GRANULARITY);
ns_v3_responses[i] = round_uint32_to_next_multiple_of(
ns_v3_responses[i], RESPONSE_GRANULARITY);
}
#undef RESPONSE_GRANULARITY
- if (!geoip_get_mean_shares(now, &v2_share, &v3_share)) {
- tor_asprintf(&v2_share_string, "dirreq-v2-share %0.2f%%\n",
- v2_share*100);
- tor_asprintf(&v3_share_string, "dirreq-v3-share %0.2f%%\n",
- v3_share*100);
- }
-
- v2_direct_dl_string = geoip_get_dirreq_history(
- GEOIP_CLIENT_NETWORKSTATUS_V2, DIRREQ_DIRECT);
- v3_direct_dl_string = geoip_get_dirreq_history(
- GEOIP_CLIENT_NETWORKSTATUS, DIRREQ_DIRECT);
-
- v2_tunneled_dl_string = geoip_get_dirreq_history(
- GEOIP_CLIENT_NETWORKSTATUS_V2, DIRREQ_TUNNELED);
- v3_tunneled_dl_string = geoip_get_dirreq_history(
- GEOIP_CLIENT_NETWORKSTATUS, DIRREQ_TUNNELED);
+ v3_direct_dl_string = geoip_get_dirreq_history(DIRREQ_DIRECT);
+ v3_tunneled_dl_string = geoip_get_dirreq_history(DIRREQ_TUNNELED);
/* Put everything together into a single string. */
tor_asprintf(&result, "dirreq-stats-end %s (%d s)\n"
"dirreq-v3-ips %s\n"
- "dirreq-v2-ips %s\n"
"dirreq-v3-reqs %s\n"
- "dirreq-v2-reqs %s\n"
"dirreq-v3-resp ok=%u,not-enough-sigs=%u,unavailable=%u,"
"not-found=%u,not-modified=%u,busy=%u\n"
- "dirreq-v2-resp ok=%u,unavailable=%u,"
- "not-found=%u,not-modified=%u,busy=%u\n"
- "%s"
- "%s"
"dirreq-v3-direct-dl %s\n"
- "dirreq-v2-direct-dl %s\n"
- "dirreq-v3-tunneled-dl %s\n"
- "dirreq-v2-tunneled-dl %s\n",
+ "dirreq-v3-tunneled-dl %s\n",
t,
(unsigned) (now - start_of_dirreq_stats_interval),
v3_ips_string ? v3_ips_string : "",
- v2_ips_string ? v2_ips_string : "",
v3_reqs_string ? v3_reqs_string : "",
- v2_reqs_string ? v2_reqs_string : "",
ns_v3_responses[GEOIP_SUCCESS],
ns_v3_responses[GEOIP_REJECT_NOT_ENOUGH_SIGS],
ns_v3_responses[GEOIP_REJECT_UNAVAILABLE],
ns_v3_responses[GEOIP_REJECT_NOT_FOUND],
ns_v3_responses[GEOIP_REJECT_NOT_MODIFIED],
ns_v3_responses[GEOIP_REJECT_BUSY],
- ns_v2_responses[GEOIP_SUCCESS],
- ns_v2_responses[GEOIP_REJECT_UNAVAILABLE],
- ns_v2_responses[GEOIP_REJECT_NOT_FOUND],
- ns_v2_responses[GEOIP_REJECT_NOT_MODIFIED],
- ns_v2_responses[GEOIP_REJECT_BUSY],
- v2_share_string ? v2_share_string : "",
- v3_share_string ? v3_share_string : "",
v3_direct_dl_string ? v3_direct_dl_string : "",
- v2_direct_dl_string ? v2_direct_dl_string : "",
- v3_tunneled_dl_string ? v3_tunneled_dl_string : "",
- v2_tunneled_dl_string ? v2_tunneled_dl_string : "");
+ v3_tunneled_dl_string ? v3_tunneled_dl_string : "");
/* Free partial strings. */
tor_free(v3_ips_string);
- tor_free(v2_ips_string);
tor_free(v3_reqs_string);
- tor_free(v2_reqs_string);
- tor_free(v2_share_string);
- tor_free(v3_share_string);
tor_free(v3_direct_dl_string);
- tor_free(v2_direct_dl_string);
tor_free(v3_tunneled_dl_string);
- tor_free(v2_tunneled_dl_string);
return result;
}
diff --git a/src/or/geoip.h b/src/or/geoip.h
index 60d44a5536..ebefee5f4e 100644
--- a/src/or/geoip.h
+++ b/src/or/geoip.h
@@ -30,18 +30,17 @@ void geoip_note_client_seen(geoip_client_action_t action,
const tor_addr_t *addr, time_t now);
void geoip_remove_old_clients(time_t cutoff);
-void geoip_note_ns_response(geoip_client_action_t action,
- geoip_ns_response_t response);
+void geoip_note_ns_response(geoip_ns_response_t response);
int geoip_get_client_history(geoip_client_action_t action,
char **country_str, char **ipver_str);
-char *geoip_get_request_history(geoip_client_action_t action);
+char *geoip_get_request_history(void);
int getinfo_helper_geoip(control_connection_t *control_conn,
const char *question, char **answer,
const char **errmsg);
void geoip_free_all(void);
void geoip_start_dirreq(uint64_t dirreq_id, size_t response_size,
- geoip_client_action_t action, dirreq_type_t type);
+ dirreq_type_t type);
void geoip_change_dirreq_state(uint64_t dirreq_id, dirreq_type_t type,
dirreq_state_t new_state);
diff --git a/src/or/main.c b/src/or/main.c
index 1dd207a753..79b0f25778 100644
--- a/src/or/main.c
+++ b/src/or/main.c
@@ -973,7 +973,7 @@ directory_info_has_arrived(time_t now, int from_cache)
if (!router_have_minimum_dir_info()) {
int quiet = from_cache ||
directory_too_idle_to_fetch_descriptors(options, now);
- log(quiet ? LOG_INFO : LOG_NOTICE, LD_DIR,
+ tor_log(quiet ? LOG_INFO : LOG_NOTICE, LD_DIR,
"I learned some more directory information, but not enough to "
"build a circuit: %s", get_dir_info_status_string());
update_all_descriptor_downloads(now);
@@ -1201,7 +1201,7 @@ run_scheduled_events(time_t now)
* eventually. */
if (signewnym_is_pending &&
time_of_last_signewnym + MAX_SIGNEWNYM_RATE <= now) {
- log(LOG_INFO, LD_CONTROL, "Honoring delayed NEWNYM request");
+ log_info(LD_CONTROL, "Honoring delayed NEWNYM request");
signewnym_impl(now);
}
@@ -2083,7 +2083,7 @@ process_signal(uintptr_t sig)
time_t now = time(NULL);
if (time_of_last_signewnym + MAX_SIGNEWNYM_RATE > now) {
signewnym_is_pending = 1;
- log(LOG_NOTICE, LD_CONTROL,
+ log_notice(LD_CONTROL,
"Rate limiting NEWNYM request: delaying by %d second(s)",
(int)(MAX_SIGNEWNYM_RATE+time_of_last_signewnym-now));
} else {
@@ -2115,7 +2115,7 @@ static void
dumpmemusage(int severity)
{
connection_dump_buffer_mem_stats(severity);
- log(severity, LD_GENERAL, "In rephist: "U64_FORMAT" used by %d Tors.",
+ tor_log(severity, LD_GENERAL, "In rephist: "U64_FORMAT" used by %d Tors.",
U64_PRINTF_ARG(rephist_total_alloc), rephist_total_num);
dump_routerlist_mem_usage(severity);
dump_cell_pool_usage(severity);
@@ -2133,27 +2133,27 @@ dumpstats(int severity)
time_t elapsed;
size_t rbuf_cap, wbuf_cap, rbuf_len, wbuf_len;
- log(severity, LD_GENERAL, "Dumping stats:");
+ tor_log(severity, LD_GENERAL, "Dumping stats:");
SMARTLIST_FOREACH_BEGIN(connection_array, connection_t *, conn) {
int i = conn_sl_idx;
- log(severity, LD_GENERAL,
+ tor_log(severity, LD_GENERAL,
"Conn %d (socket %d) type %d (%s), state %d (%s), created %d secs ago",
i, (int)conn->s, conn->type, conn_type_to_string(conn->type),
conn->state, conn_state_to_string(conn->type, conn->state),
(int)(now - conn->timestamp_created));
if (!connection_is_listener(conn)) {
- log(severity,LD_GENERAL,
+ tor_log(severity,LD_GENERAL,
"Conn %d is to %s:%d.", i,
safe_str_client(conn->address),
conn->port);
- log(severity,LD_GENERAL,
+ tor_log(severity,LD_GENERAL,
"Conn %d: %d bytes waiting on inbuf (len %d, last read %d secs ago)",
i,
(int)connection_get_inbuf_len(conn),
(int)buf_allocation(conn->inbuf),
(int)(now - conn->timestamp_lastread));
- log(severity,LD_GENERAL,
+ tor_log(severity,LD_GENERAL,
"Conn %d: %d bytes waiting on outbuf "
"(len %d, last written %d secs ago)",i,
(int)connection_get_outbuf_len(conn),
@@ -2164,7 +2164,7 @@ dumpstats(int severity)
if (or_conn->tls) {
tor_tls_get_buffer_sizes(or_conn->tls, &rbuf_cap, &rbuf_len,
&wbuf_cap, &wbuf_len);
- log(severity, LD_GENERAL,
+ tor_log(severity, LD_GENERAL,
"Conn %d: %d/%d bytes used on OpenSSL read buffer; "
"%d/%d bytes used on write buffer.",
i, (int)rbuf_len, (int)rbuf_cap, (int)wbuf_len, (int)wbuf_cap);
@@ -2178,7 +2178,7 @@ dumpstats(int severity)
channel_dumpstats(severity);
channel_listener_dumpstats(severity);
- log(severity, LD_NET,
+ tor_log(severity, LD_NET,
"Cells processed: "U64_FORMAT" padding\n"
" "U64_FORMAT" create\n"
" "U64_FORMAT" created\n"
@@ -2194,33 +2194,36 @@ dumpstats(int severity)
U64_PRINTF_ARG(stats_n_relay_cells_delivered),
U64_PRINTF_ARG(stats_n_destroy_cells_processed));
if (stats_n_data_cells_packaged)
- log(severity,LD_NET,"Average packaged cell fullness: %2.3f%%",
+ tor_log(severity,LD_NET,"Average packaged cell fullness: %2.3f%%",
100*(U64_TO_DBL(stats_n_data_bytes_packaged) /
U64_TO_DBL(stats_n_data_cells_packaged*RELAY_PAYLOAD_SIZE)) );
if (stats_n_data_cells_received)
- log(severity,LD_NET,"Average delivered cell fullness: %2.3f%%",
+ tor_log(severity,LD_NET,"Average delivered cell fullness: %2.3f%%",
100*(U64_TO_DBL(stats_n_data_bytes_received) /
U64_TO_DBL(stats_n_data_cells_received*RELAY_PAYLOAD_SIZE)) );
+ cpuworker_log_onionskin_overhead(severity, ONION_HANDSHAKE_TYPE_TAP, "TAP");
+ cpuworker_log_onionskin_overhead(severity, ONION_HANDSHAKE_TYPE_NTOR,"ntor");
+
if (now - time_of_process_start >= 0)
elapsed = now - time_of_process_start;
else
elapsed = 0;
if (elapsed) {
- log(severity, LD_NET,
+ tor_log(severity, LD_NET,
"Average bandwidth: "U64_FORMAT"/%d = %d bytes/sec reading",
U64_PRINTF_ARG(stats_n_bytes_read),
(int)elapsed,
(int) (stats_n_bytes_read/elapsed));
- log(severity, LD_NET,
+ tor_log(severity, LD_NET,
"Average bandwidth: "U64_FORMAT"/%d = %d bytes/sec writing",
U64_PRINTF_ARG(stats_n_bytes_written),
(int)elapsed,
(int) (stats_n_bytes_written/elapsed));
}
- log(severity, LD_NET, "--------------- Dumping memory information:");
+ tor_log(severity, LD_NET, "--------------- Dumping memory information:");
dumpmemusage(severity);
rep_hist_dump_stats(now,severity);
@@ -2361,7 +2364,7 @@ tor_init(int argc, char *argv[])
}
#ifdef NON_ANONYMOUS_MODE_ENABLED
- log(LOG_WARN, LD_GENERAL, "This copy of Tor was compiled to run in a "
+ log_warn(LD_GENERAL, "This copy of Tor was compiled to run in a "
"non-anonymous mode. It will provide NO ANONYMITY.");
#endif
diff --git a/src/or/networkstatus.c b/src/or/networkstatus.c
index 79dd706c47..71ac054f88 100644
--- a/src/or/networkstatus.c
+++ b/src/or/networkstatus.c
@@ -561,7 +561,7 @@ networkstatus_check_consensus_signature(networkstatus_t *consensus,
if (warn >= 0) {
SMARTLIST_FOREACH(unrecognized, networkstatus_voter_info_t *, voter,
{
- log(severity, LD_DIR, "Consensus includes unrecognized authority "
+ tor_log(severity, LD_DIR, "Consensus includes unrecognized authority "
"'%s' at %s:%d (contact %s; identity %s)",
voter->nickname, voter->address, (int)voter->dir_port,
voter->contact?voter->contact:"n/a",
@@ -569,7 +569,7 @@ networkstatus_check_consensus_signature(networkstatus_t *consensus,
});
SMARTLIST_FOREACH(need_certs_from, networkstatus_voter_info_t *, voter,
{
- log(severity, LD_DIR, "Looks like we need to download a new "
+ tor_log(severity, LD_DIR, "Looks like we need to download a new "
"certificate from authority '%s' at %s:%d (contact %s; "
"identity %s)",
voter->nickname, voter->address, (int)voter->dir_port,
@@ -578,7 +578,7 @@ networkstatus_check_consensus_signature(networkstatus_t *consensus,
});
SMARTLIST_FOREACH(missing_authorities, dir_server_t *, ds,
{
- log(severity, LD_DIR, "Consensus does not include configured "
+ tor_log(severity, LD_DIR, "Consensus does not include configured "
"authority '%s' at %s:%d (identity %s)",
ds->nickname, ds->address, (int)ds->dir_port,
hex_str(ds->v3_identity_digest, DIGEST_LEN));
@@ -614,7 +614,7 @@ networkstatus_check_consensus_signature(networkstatus_t *consensus,
"because we were missing the keys.", n_missing_key);
}
joined = smartlist_join_strings(sl, " ", 0, NULL);
- log(severity, LD_DIR, "%s", joined);
+ tor_log(severity, LD_DIR, "%s", joined);
tor_free(joined);
SMARTLIST_FOREACH(sl, char *, c, tor_free(c));
smartlist_free(sl);
@@ -2239,6 +2239,21 @@ networkstatus_get_param(const networkstatus_t *ns, const char *param_name,
default_val, min_val, max_val);
}
+/**
+ * Retrieve the consensus parameter that governs the
+ * fixed-point precision of our network balancing 'bandwidth-weights'
+ * (which are themselves integer consensus values). We divide them
+ * by this value and ensure they never exceed this value.
+ */
+int
+networkstatus_get_weight_scale_param(networkstatus_t *ns)
+{
+ return networkstatus_get_param(ns, "bwweightscale",
+ BW_WEIGHT_SCALE,
+ BW_MIN_WEIGHT_SCALE,
+ BW_MAX_WEIGHT_SCALE);
+}
+
/** Return the value of a integer bw weight parameter from the networkstatus
* <b>ns</b> whose name is <b>weight_name</b>. If <b>ns</b> is NULL, try
* loading the latest consensus ourselves. Return <b>default_val</b> if no
@@ -2255,7 +2270,7 @@ networkstatus_get_bw_weight(networkstatus_t *ns, const char *weight_name,
if (!ns || !ns->weight_params)
return default_val;
- max = circuit_build_times_get_bw_scale(ns);
+ max = networkstatus_get_weight_scale_param(ns);
param = get_net_param_from_list(ns->weight_params, weight_name,
default_val, -1,
BW_MAX_WEIGHT_SCALE);
diff --git a/src/or/networkstatus.h b/src/or/networkstatus.h
index d6d6a036cd..b437c5ec2f 100644
--- a/src/or/networkstatus.h
+++ b/src/or/networkstatus.h
@@ -112,6 +112,7 @@ int networkstatus_parse_flavor_name(const char *flavname);
void document_signature_free(document_signature_t *sig);
document_signature_t *document_signature_dup(const document_signature_t *sig);
void networkstatus_free_all(void);
+int networkstatus_get_weight_scale_param(networkstatus_t *ns);
#endif
diff --git a/src/or/nodelist.c b/src/or/nodelist.c
index e444c73247..9f77dcafed 100644
--- a/src/or/nodelist.c
+++ b/src/or/nodelist.c
@@ -1213,7 +1213,7 @@ static int have_min_dir_info = 0;
static int need_to_update_have_min_dir_info = 1;
/** String describing what we're missing before we have enough directory
* info. */
-static char dir_info_status[128] = "";
+static char dir_info_status[256] = "";
/** Return true iff we have enough networkstatus and router information to
* start building circuits. Right now, this means "more than half the
@@ -1253,10 +1253,12 @@ get_dir_info_status_string(void)
* descriptors for. Store the former in *<b>num_usable</b> and the latter in
* *<b>num_present</b>. If <b>in_set</b> is non-NULL, only consider those
* routers in <b>in_set</b>. If <b>exit_only</b> is true, only consider nodes
- * with the Exit flag.
+ * with the Exit flag. If *descs_out is present, add a node_t for each
+ * usable descriptor to it.
*/
static void
count_usable_descriptors(int *num_present, int *num_usable,
+ smartlist_t *descs_out,
const networkstatus_t *consensus,
const or_options_t *options, time_t now,
routerset_t *in_set, int exit_only)
@@ -1266,6 +1268,10 @@ count_usable_descriptors(int *num_present, int *num_usable,
SMARTLIST_FOREACH_BEGIN(consensus->routerstatus_list, routerstatus_t *, rs)
{
+ const node_t *node = node_get_by_id(rs->identity_digest);
+ if (!node)
+ continue; /* This would be a bug: every entry in the consensus is
+ * supposed to have a node. */
if (exit_only && ! rs->is_exit)
continue;
if (in_set && ! routerset_contains_routerstatus(in_set, rs, -1))
@@ -1282,6 +1288,8 @@ count_usable_descriptors(int *num_present, int *num_usable,
/* we have the descriptor listed in the consensus. */
++*num_present;
}
+ if (descs_out)
+ smartlist_add(descs_out, (node_t*)node);
}
}
SMARTLIST_FOREACH_END(rs);
@@ -1291,6 +1299,66 @@ count_usable_descriptors(int *num_present, int *num_usable,
md ? "microdesc" : "desc", exit_only ? " exits" : "s");
}
+/** Return an extimate of which fraction of usable paths through the Tor
+ * network we have available for use. */
+static double
+compute_frac_paths_available(const networkstatus_t *consensus,
+ const or_options_t *options, time_t now,
+ int *num_present_out, int *num_usable_out,
+ char **status_out)
+{
+ smartlist_t *guards = smartlist_new();
+ smartlist_t *mid = smartlist_new();
+ smartlist_t *exits = smartlist_new();
+ smartlist_t *myexits= smartlist_new();
+ double f_guard, f_mid, f_exit, f_myexit;
+ int np, nu; /* Ignored */
+
+ count_usable_descriptors(num_present_out, num_usable_out,
+ mid, consensus, options, now, NULL, 0);
+ if (options->EntryNodes) {
+ count_usable_descriptors(&np, &nu, guards, consensus, options, now,
+ options->EntryNodes, 0);
+ } else {
+ SMARTLIST_FOREACH(mid, const node_t *, node, {
+ if (node->is_possible_guard)
+ smartlist_add(guards, (node_t*)node);
+ });
+ }
+
+ count_usable_descriptors(&np, &nu, exits, consensus, options, now,
+ NULL, 1);
+ count_usable_descriptors(&np, &nu, myexits, consensus, options, now,
+ options->ExitNodes, 1);
+
+ f_guard = frac_nodes_with_descriptors(guards, WEIGHT_FOR_GUARD);
+ f_mid = frac_nodes_with_descriptors(mid, WEIGHT_FOR_MID);
+ f_exit = frac_nodes_with_descriptors(exits, WEIGHT_FOR_EXIT);
+ f_myexit= frac_nodes_with_descriptors(myexits,WEIGHT_FOR_EXIT);
+
+ smartlist_free(guards);
+ smartlist_free(mid);
+ smartlist_free(exits);
+ smartlist_free(myexits);
+
+ /* This is a tricky point here: we don't want to make it easy for a
+ * directory to trickle exits to us until it learns which exits we have
+ * configured, so require that we have a threshold both of total exits
+ * and usable exits. */
+ if (f_myexit < f_exit)
+ f_exit = f_myexit;
+
+ tor_asprintf(status_out,
+ "%d%% of guards bw, "
+ "%d%% of midpoint bw, and "
+ "%d%% of exit bw",
+ (int)(f_guard*100),
+ (int)(f_mid*100),
+ (int)(f_exit*100));
+
+ return f_guard * f_mid * f_exit;
+}
+
/** We just fetched a new set of descriptors. Compute how far through
* the "loading descriptors" bootstrapping phase we are, so we can inform
* the controller of our progress. */
@@ -1306,7 +1374,7 @@ count_loading_descriptors_progress(void)
if (!consensus)
return 0; /* can't count descriptors if we have no list of them */
- count_usable_descriptors(&num_present, &num_usable,
+ count_usable_descriptors(&num_present, &num_usable, NULL,
consensus, get_options(), now, NULL, 0);
if (num_usable == 0)
@@ -1319,14 +1387,28 @@ count_loading_descriptors_progress(void)
BOOTSTRAP_STATUS_LOADING_DESCRIPTORS));
}
+/** Return the fraction of paths needed before we're willing to build
+ * circuits, as configured in <b>options</b>, or in the consensus <b>ns</b>. */
+static double
+get_frac_paths_needed_for_circs(const or_options_t *options,
+ const networkstatus_t *ns)
+{
+#define DFLT_PCT_USABLE_NEEDED 60
+ if (options->PathsNeededToBuildCircuits >= 1.0) {
+ return options->PathsNeededToBuildCircuits;
+ } else {
+ return networkstatus_get_param(ns, "min_paths_for_circs_pct",
+ DFLT_PCT_USABLE_NEEDED,
+ 25, 95)/100.0;
+ }
+}
+
/** Change the value of have_min_dir_info, setting it true iff we have enough
* network and router information to build circuits. Clear the value of
* need_to_update_have_min_dir_info. */
static void
update_router_have_minimum_dir_info(void)
{
- int num_present = 0, num_usable=0;
- int num_exit_present = 0, num_exit_usable = 0;
time_t now = time(NULL);
int res;
const or_options_t *options = get_options();
@@ -1355,66 +1437,40 @@ update_router_have_minimum_dir_info(void)
using_md = consensus->flavor == FLAV_MICRODESC;
- count_usable_descriptors(&num_present, &num_usable, consensus, options, now,
- NULL, 0);
- count_usable_descriptors(&num_exit_present, &num_exit_usable,
- consensus, options, now, options->ExitNodes, 1);
-
-/* What fraction of desired server descriptors do we need before we will
- * build circuits? */
-#define FRAC_USABLE_NEEDED .75
-/* What fraction of desired _exit_ server descriptors do we need before we
- * will build circuits? */
-#define FRAC_EXIT_USABLE_NEEDED .5
-
- if (num_present < num_usable * FRAC_USABLE_NEEDED) {
- tor_snprintf(dir_info_status, sizeof(dir_info_status),
- "We have only %d/%d usable %sdescriptors.",
- num_present, num_usable, using_md ? "micro" : "");
- res = 0;
- control_event_bootstrap(BOOTSTRAP_STATUS_REQUESTING_DESCRIPTORS, 0);
- goto done;
- } else if (num_present < 2) {
- tor_snprintf(dir_info_status, sizeof(dir_info_status),
- "Only %d %sdescriptor%s here and believed reachable!",
- num_present, using_md ? "micro" : "", num_present ? "" : "s");
- res = 0;
- goto done;
- } else if (num_exit_present < num_exit_usable * FRAC_EXIT_USABLE_NEEDED) {
- tor_snprintf(dir_info_status, sizeof(dir_info_status),
- "We have only %d/%d usable exit node descriptors.",
- num_exit_present, num_exit_usable);
- res = 0;
- control_event_bootstrap(BOOTSTRAP_STATUS_REQUESTING_DESCRIPTORS, 0);
- goto done;
- }
-
- /* Check for entry nodes. */
- if (options->EntryNodes) {
- count_usable_descriptors(&num_present, &num_usable, consensus, options,
- now, options->EntryNodes, 0);
+ {
+ char *status = NULL;
+ int num_present=0, num_usable=0;
+ double paths = compute_frac_paths_available(consensus, options, now,
+ &num_present, &num_usable,
+ &status);
- if (!num_usable || !num_present) {
+ if (paths < get_frac_paths_needed_for_circs(options,consensus)) {
tor_snprintf(dir_info_status, sizeof(dir_info_status),
- "We have only %d/%d usable entry node %sdescriptors.",
- num_present, num_usable, using_md?"micro":"");
+ "We need more %sdescriptors: we have %d/%d, and "
+ "can only build %d%% of likely paths. (We have %s.)",
+ using_md?"micro":"", num_present, num_usable,
+ (int)(paths*100), status);
+ /* log_notice(LD_NET, "%s", dir_info_status); */
+ tor_free(status);
res = 0;
+ control_event_bootstrap(BOOTSTRAP_STATUS_REQUESTING_DESCRIPTORS, 0);
goto done;
}
- }
- res = 1;
+ tor_free(status);
+ res = 1;
+ }
done:
if (res && !have_min_dir_info) {
- log(LOG_NOTICE, LD_DIR,
+ log_notice(LD_DIR,
"We now have enough directory information to build circuits.");
control_event_client_status(LOG_NOTICE, "ENOUGH_DIR_INFO");
control_event_bootstrap(BOOTSTRAP_STATUS_CONN_OR, 0);
}
if (!res && have_min_dir_info) {
int quiet = directory_too_idle_to_fetch_descriptors(options, now);
- log(quiet ? LOG_INFO : LOG_NOTICE, LD_DIR,
+ tor_log(quiet ? LOG_INFO : LOG_NOTICE, LD_DIR,
"Our directory information is no longer up-to-date "
"enough to build circuits: %s", dir_info_status);
diff --git a/src/or/onion.c b/src/or/onion.c
index 4625346f25..b9f5aa6c7d 100644
--- a/src/or/onion.c
+++ b/src/or/onion.c
@@ -13,6 +13,7 @@
#include "or.h"
#include "circuitlist.h"
#include "config.h"
+#include "cpuworker.h"
#include "onion.h"
#include "onion_fast.h"
#include "onion_ntor.h"
@@ -20,29 +21,71 @@
#include "relay.h"
#include "rephist.h"
#include "router.h"
+#include "tor_queue.h"
/** Type for a linked list of circuits that are waiting for a free CPU worker
* to process a waiting onion handshake. */
typedef struct onion_queue_t {
+ TOR_TAILQ_ENTRY(onion_queue_t) next;
or_circuit_t *circ;
create_cell_t *onionskin;
time_t when_added;
- struct onion_queue_t *next;
} onion_queue_t;
/** 5 seconds on the onion queue til we just send back a destroy */
#define ONIONQUEUE_WAIT_CUTOFF 5
-/** First and last elements in the linked list of circuits waiting for CPU
- * workers, or NULL if the list is empty.
- * @{ */
-static onion_queue_t *ol_list=NULL;
-static onion_queue_t *ol_tail=NULL;
-/**@}*/
-/** Length of ol_list */
-static int ol_length=0;
+/** Queue of circuits waiting for CPU workers, or NULL if the list is empty.*/
+TOR_TAILQ_HEAD(onion_queue_head_t, onion_queue_t) ol_list =
+ TOR_TAILQ_HEAD_INITIALIZER(ol_list);
-/* XXXX Check lengths vs MAX_ONIONSKIN_{CHALLENGE,REPLY}_LEN */
+/** Number of entries of each type currently in ol_list. */
+static int ol_entries[MAX_ONION_HANDSHAKE_TYPE+1];
+
+static void onion_queue_entry_remove(onion_queue_t *victim);
+
+/* XXXX024 Check lengths vs MAX_ONIONSKIN_{CHALLENGE,REPLY}_LEN.
+ *
+ * (By which I think I meant, "make sure that no
+ * X_ONIONSKIN_CHALLENGE/REPLY_LEN is greater than
+ * MAX_ONIONSKIN_CHALLENGE/REPLY_LEN." Also, make sure that we can pass
+ * over-large values via EXTEND2/EXTENDED2, for future-compatibility.*/
+
+/** Return true iff we have room to queue another oninoskin of type
+ * <b>type</b>. */
+static int
+have_room_for_onionskin(uint16_t type)
+{
+ const or_options_t *options = get_options();
+ int num_cpus;
+ uint64_t tap_usec, ntor_usec;
+ /* If we've got fewer than 50 entries, we always have room for one more. */
+ if (ol_entries[ONION_HANDSHAKE_TYPE_TAP] +
+ ol_entries[ONION_HANDSHAKE_TYPE_NTOR] < 50)
+ return 1;
+ num_cpus = get_num_cpus(options);
+ /* Compute how many microseconds we'd expect to need to clear all
+ * onionskins in the current queue. */
+ tap_usec = estimated_usec_for_onionskins(
+ ol_entries[ONION_HANDSHAKE_TYPE_TAP],
+ ONION_HANDSHAKE_TYPE_TAP) / num_cpus;
+ ntor_usec = estimated_usec_for_onionskins(
+ ol_entries[ONION_HANDSHAKE_TYPE_NTOR],
+ ONION_HANDSHAKE_TYPE_NTOR) / num_cpus;
+ /* See whether that exceeds MaxOnionQueueDelay. If so, we can't queue
+ * this. */
+ if ((tap_usec + ntor_usec) / 1000 > (uint64_t)options->MaxOnionQueueDelay)
+ return 0;
+#ifdef CURVE25519_ENABLED
+ /* If we support the ntor handshake, then don't let TAP handshakes use
+ * more than 2/3 of the space on the queue. */
+ if (type == ONION_HANDSHAKE_TYPE_TAP &&
+ tap_usec / 1000 > (uint64_t)options->MaxOnionQueueDelay * 2 / 3)
+ return 0;
+#endif
+
+ return 1;
+}
/** Add <b>circ</b> to the end of ol_list and return 0, except
* if ol_list is too long, in which case do nothing and return -1.
@@ -58,19 +101,7 @@ onion_pending_add(or_circuit_t *circ, create_cell_t *onionskin)
tmp->onionskin = onionskin;
tmp->when_added = now;
- if (!ol_tail) {
- tor_assert(!ol_list);
- tor_assert(!ol_length);
- ol_list = tmp;
- ol_tail = tmp;
- ol_length++;
- return 0;
- }
-
- tor_assert(ol_list);
- tor_assert(!ol_tail->next);
-
- if (ol_length >= get_options()->MaxOnionsPending) {
+ if (!have_room_for_onionskin(onionskin->handshake_type)) {
#define WARN_TOO_MANY_CIRC_CREATIONS_INTERVAL (60)
static ratelim_t last_warned =
RATELIM_INIT(WARN_TOO_MANY_CIRC_CREATIONS_INTERVAL);
@@ -87,13 +118,19 @@ onion_pending_add(or_circuit_t *circ, create_cell_t *onionskin)
return -1;
}
- ol_length++;
- ol_tail->next = tmp;
- ol_tail = tmp;
- while ((int)(now - ol_list->when_added) >= ONIONQUEUE_WAIT_CUTOFF) {
- /* cull elderly requests. */
- circ = ol_list->circ;
- onion_pending_remove(ol_list->circ);
+ ++ol_entries[onionskin->handshake_type];
+ circ->onionqueue_entry = tmp;
+ TOR_TAILQ_INSERT_TAIL(&ol_list, tmp, next);
+
+ /* cull elderly requests. */
+ while (1) {
+ onion_queue_t *head = TOR_TAILQ_FIRST(&ol_list);
+ if (now - head->when_added < (time_t)ONIONQUEUE_WAIT_CUTOFF)
+ break;
+
+ circ = head->circ;
+ circ->onionqueue_entry = NULL;
+ onion_queue_entry_remove(head);
log_info(LD_CIRC,
"Circuit create request is too old; canceling due to overload.");
circuit_mark_for_close(TO_CIRCUIT(circ), END_CIRC_REASON_RESOURCELIMIT);
@@ -108,17 +145,21 @@ or_circuit_t *
onion_next_task(create_cell_t **onionskin_out)
{
or_circuit_t *circ;
+ onion_queue_t *head = TOR_TAILQ_FIRST(&ol_list);
- if (!ol_list)
+ if (!head)
return NULL; /* no onions pending, we're done */
- tor_assert(ol_list->circ);
- tor_assert(ol_list->circ->p_chan); /* make sure it's still valid */
- tor_assert(ol_length > 0);
- circ = ol_list->circ;
- *onionskin_out = ol_list->onionskin;
- ol_list->onionskin = NULL; /* prevent free. */
- onion_pending_remove(ol_list->circ);
+ tor_assert(head->circ);
+ tor_assert(head->circ->p_chan); /* make sure it's still valid */
+ circ = head->circ;
+ if (head->onionskin &&
+ head->onionskin->handshake_type <= MAX_ONION_HANDSHAKE_TYPE)
+ --ol_entries[head->onionskin->handshake_type];
+ *onionskin_out = head->onionskin;
+ head->onionskin = NULL; /* prevent free. */
+ circ->onionqueue_entry = NULL;
+ onion_queue_entry_remove(head);
return circ;
}
@@ -128,37 +169,29 @@ onion_next_task(create_cell_t **onionskin_out)
void
onion_pending_remove(or_circuit_t *circ)
{
- onion_queue_t *tmpo, *victim;
-
- if (!ol_list)
- return; /* nothing here. */
-
- /* first check to see if it's the first entry */
- tmpo = ol_list;
- if (tmpo->circ == circ) {
- /* it's the first one. remove it from the list. */
- ol_list = tmpo->next;
- if (!ol_list)
- ol_tail = NULL;
- ol_length--;
- victim = tmpo;
- } else { /* we need to hunt through the rest of the list */
- for ( ;tmpo->next && tmpo->next->circ != circ; tmpo=tmpo->next) ;
- if (!tmpo->next) {
- log_debug(LD_GENERAL,
- "circ (p_circ_id %d) not in list, probably at cpuworker.",
- circ->p_circ_id);
- return;
- }
- /* now we know tmpo->next->circ == circ */
- victim = tmpo->next;
- tmpo->next = victim->next;
- if (ol_tail == victim)
- ol_tail = tmpo;
- ol_length--;
- }
+ onion_queue_t *victim;
+
+ if (!circ)
+ return;
+
+ victim = circ->onionqueue_entry;
+ if (victim)
+ onion_queue_entry_remove(victim);
+}
+
+/** Remove a queue entry <b>victim</b> from the queue, unlinking it from
+ * its circuit and freeing it and any structures it owns.*/
+static void
+onion_queue_entry_remove(onion_queue_t *victim)
+{
+ TOR_TAILQ_REMOVE(&ol_list, victim, next);
+
+ if (victim->circ)
+ victim->circ->onionqueue_entry = NULL;
- /* now victim points to the element that needs to be removed */
+ if (victim->onionskin &&
+ victim->onionskin->handshake_type <= MAX_ONION_HANDSHAKE_TYPE)
+ --ol_entries[victim->onionskin->handshake_type];
tor_free(victim->onionskin);
tor_free(victim);
@@ -168,14 +201,11 @@ onion_pending_remove(or_circuit_t *circ)
void
clear_pending_onions(void)
{
- while (ol_list) {
- onion_queue_t *victim = ol_list;
- ol_list = victim->next;
- tor_free(victim->onionskin);
- tor_free(victim);
+ onion_queue_t *victim;
+ while ((victim = TOR_TAILQ_FIRST(&ol_list))) {
+ onion_queue_entry_remove(victim);
}
- ol_list = ol_tail = NULL;
- ol_length = 0;
+ memset(ol_entries, 0, sizeof(ol_entries));
}
/* ============================================================ */
diff --git a/src/or/or.h b/src/or/or.h
index 328e8dfa7f..a0a921a9f4 100644
--- a/src/or/or.h
+++ b/src/or/or.h
@@ -2584,6 +2584,7 @@ struct ntor_handshake_state_t;
#define ONION_HANDSHAKE_TYPE_TAP 0x0000
#define ONION_HANDSHAKE_TYPE_FAST 0x0001
#define ONION_HANDSHAKE_TYPE_NTOR 0x0002
+#define MAX_ONION_HANDSHAKE_TYPE 0x0002
typedef struct {
uint16_t tag;
union {
@@ -2826,8 +2827,18 @@ typedef struct circuit_t {
/**
* Describes the circuit building process in simplified terms based
- * on the path bias accounting state for a circuit. Created to prevent
- * overcounting due to unknown cases of circuit reuse. See Bug #6475.
+ * on the path bias accounting state for a circuit.
+ *
+ * NOTE: These state values are enumerated in the order for which we
+ * expect circuits to transition through them. If you add states,
+ * you need to preserve this overall ordering. The various pathbias
+ * state transition and accounting functions (pathbias_mark_* and
+ * pathbias_count_*) contain ordinal comparisons to enforce proper
+ * state transitions for corrections.
+ *
+ * This state machine and the associated logic was created to prevent
+ * miscounting due to unknown cases of circuit reuse. See also tickets
+ * #6475 and #7802.
*/
typedef enum {
/** This circuit is "new". It has not yet completed a first hop
@@ -2838,7 +2849,7 @@ typedef enum {
PATH_STATE_BUILD_ATTEMPTED = 1,
/** This circuit has been completely built */
PATH_STATE_BUILD_SUCCEEDED = 2,
- /** Did any SOCKS streams or hidserv introductions actually succeed on
+ /** Did we try to attach any SOCKS streams or hidserv introductions to
* this circuit?
*
* Note: If we ever implement end-to-end stream timing through test
@@ -2846,13 +2857,28 @@ typedef enum {
* (or any other automatic streams) because the adversary could
* just tag at a later point.
*/
- PATH_STATE_USE_SUCCEEDED = 3,
+ PATH_STATE_USE_ATTEMPTED = 3,
+ /** Did any SOCKS streams or hidserv introductions actually succeed on
+ * this circuit?
+ *
+ * If any streams detatch/fail from this circuit, the code transitions
+ * the circuit back to PATH_STATE_USE_ATTEMPTED to ensure we probe. See
+ * pathbias_mark_use_rollback() for that.
+ */
+ PATH_STATE_USE_SUCCEEDED = 4,
/**
* This is a special state to indicate that we got a corrupted
* relay cell on a circuit and we don't intend to probe it.
*/
- PATH_STATE_USE_FAILED = 4,
+ PATH_STATE_USE_FAILED = 5,
+
+ /**
+ * This is a special state to indicate that we already counted
+ * the circuit. Used to guard against potential state machine
+ * violations.
+ */
+ PATH_STATE_ALREADY_COUNTED = 6,
} path_state_t;
/** An origin_circuit_t holds data necessary to build and use a circuit.
@@ -2888,10 +2914,25 @@ typedef struct origin_circuit_t {
* cannibalized circuits. */
unsigned int has_opened : 1;
- /** Kludge to help us prevent the warn in bug #6475 and eventually
- * debug why we are not seeing first hops in some cases. */
+ /**
+ * Path bias state machine. Used to ensure integrity of our
+ * circuit building and usage accounting. See path_state_t
+ * for more details.
+ */
ENUM_BF(path_state_t) path_state : 3;
+ /**
+ * Tristate variable to guard against pathbias miscounting
+ * due to circuit purpose transitions changing the decision
+ * of pathbias_should_count(). This variable is informational
+ * only. The current results of pathbias_should_count() are
+ * the official decision for pathbias accounting.
+ */
+ uint8_t pathbias_shouldcount;
+#define PATHBIAS_SHOULDCOUNT_UNDECIDED 0
+#define PATHBIAS_SHOULDCOUNT_IGNORED 1
+#define PATHBIAS_SHOULDCOUNT_COUNTED 2
+
/** For path probing. Store the temporary probe stream ID
* for response comparison */
streamid_t pathbias_probe_id;
@@ -2997,9 +3038,10 @@ typedef struct origin_circuit_t {
* ISO_STREAM. */
uint64_t associated_isolated_stream_global_id;
/**@}*/
-
} origin_circuit_t;
+struct onion_queue_t;
+
/** An or_circuit_t holds information needed to implement a circuit at an
* OR. */
typedef struct or_circuit_t {
@@ -3013,6 +3055,9 @@ typedef struct or_circuit_t {
* cells to p_chan. NULL if we have no cells pending, or if we're not
* linked to an OR connection. */
struct circuit_t *prev_active_on_p_chan;
+ /** Pointer to an entry on the onion queue, if this circuit is waiting for a
+ * chance to give an onionskin to a cpuworker. Used only in onion.c */
+ struct onion_queue_t *onionqueue_entry;
/** The circuit_id used in the previous (backward) hop of this circuit. */
circid_t p_circ_id;
@@ -3496,9 +3541,7 @@ typedef struct {
* and try a new circuit if the stream has been
* waiting for this many seconds. If zero, use
* our default internal timeout schedule. */
- int MaxOnionsPending; /**< How many circuit CREATE requests do we allow
- * to wait simultaneously before we start dropping
- * them? */
+ int MaxOnionQueueDelay; /**<DOCDOC*/
int NewCircuitPeriod; /**< How long do we use a circuit before building
* a new one? */
int MaxCircuitDirtiness; /**< Never use circs that were first used more than
@@ -3912,9 +3955,16 @@ typedef struct {
double PathBiasExtremeRate;
int PathBiasDropGuards;
int PathBiasScaleThreshold;
- int PathBiasScaleFactor;
- int PathBiasMultFactor;
- int PathBiasUseCloseCounts;
+ /** @} */
+
+ /**
+ * Parameters for path-bias use detection
+ * @{
+ */
+ int PathBiasUseThreshold;
+ double PathBiasNoticeUseRate;
+ double PathBiasExtremeUseRate;
+ int PathBiasScaleUseThreshold;
/** @} */
int IPv6Exit; /**< Do we support exiting to IPv6 addresses? */
@@ -3923,6 +3973,9 @@ typedef struct {
/** Autobool: should we use the ntor handshake if we can? */
int UseNTorHandshake;
+
+ /** Fraction: */
+ double PathsNeededToBuildCircuits;
} or_options_t;
/** Persistent state for an onion router, as saved to disk. */
diff --git a/src/or/policies.c b/src/or/policies.c
index f9a03aef2c..9696b8123b 100644
--- a/src/or/policies.c
+++ b/src/or/policies.c
@@ -881,7 +881,7 @@ exit_policy_remove_redundancies(smartlist_t *dest)
char p1[POLICY_BUF_LEN], p2[POLICY_BUF_LEN];
policy_write_item(p1, sizeof(p1), tmp, 0);
policy_write_item(p2, sizeof(p2), ap, 0);
- log(LOG_DEBUG, LD_CONFIG, "Removing exit policy %s (%d). It is made "
+ log_debug(LD_CONFIG, "Removing exit policy %s (%d). It is made "
"redundant by %s (%d).", p1, j, p2, i);
smartlist_del_keeporder(dest, j--);
addr_policy_free(tmp);
@@ -910,7 +910,7 @@ exit_policy_remove_redundancies(smartlist_t *dest)
char p1[POLICY_BUF_LEN], p2[POLICY_BUF_LEN];
policy_write_item(p1, sizeof(p1), ap, 0);
policy_write_item(p2, sizeof(p2), tmp, 0);
- log(LOG_DEBUG, LD_CONFIG, "Removing exit policy %s. It is already "
+ log_debug(LD_CONFIG, "Removing exit policy %s. It is already "
"covered by %s.", p1, p2);
smartlist_del_keeporder(dest, i--);
addr_policy_free(ap);
diff --git a/src/or/relay.c b/src/or/relay.c
index bb3a835442..3ae5b47ba5 100644
--- a/src/or/relay.c
+++ b/src/or/relay.c
@@ -730,7 +730,7 @@ connection_ap_process_end_not_open(
* We rely on recognized+digest being strong enough to make
* tags unlikely to allow us to get tagged, yet 'recognized'
* reason codes here. */
- circ->path_state = PATH_STATE_USE_SUCCEEDED;
+ pathbias_mark_use_success(circ);
}
}
@@ -1443,7 +1443,8 @@ connection_edge_process_relay_cell(cell_t *cell, circuit_t *circ,
/*XXXX024: Downgrade this back to LOG_PROTOCOL_WARN after a while*/
log_fn(LOG_WARN, LD_PROTOCOL,
"Bug/attack: unexpected sendme cell from client. "
- "Closing circ.");
+ "Closing circ (window %d).",
+ circ->package_window);
return -END_CIRC_REASON_TORPROTOCOL;
}
circ->package_window += CIRCWINDOW_INCREMENT;
@@ -2023,8 +2024,9 @@ dump_cell_pool_usage(int severity)
n_cells += TO_OR_CIRCUIT(c)->p_chan_cells.n;
++n_circs;
}
- log(severity, LD_MM, "%d cells allocated on %d circuits. %d cells leaked.",
- n_cells, n_circs, total_cells_allocated - n_cells);
+ tor_log(severity, LD_MM,
+ "%d cells allocated on %d circuits. %d cells leaked.",
+ n_cells, n_circs, total_cells_allocated - n_cells);
mp_pool_log_status(cell_pool, severity);
}
diff --git a/src/or/rendclient.c b/src/or/rendclient.c
index 32623c3f40..61e3b917e3 100644
--- a/src/or/rendclient.c
+++ b/src/or/rendclient.c
@@ -71,6 +71,9 @@ rend_client_send_establish_rendezvous(origin_circuit_t *circ)
* and the rend cookie also means we've used the circ. */
circ->base_.timestamp_dirty = time(NULL);
+ /* We've attempted to use this circuit. Probe it if we fail */
+ pathbias_count_use_attempt(circ);
+
if (relay_send_command_from_edge(0, TO_CIRCUIT(circ),
RELAY_COMMAND_ESTABLISH_RENDEZVOUS,
circ->rend_data->rend_cookie,
@@ -316,6 +319,8 @@ rend_client_send_introduction(origin_circuit_t *introcirc,
* state. */
introcirc->base_.timestamp_dirty = time(NULL);
+ pathbias_count_use_attempt(introcirc);
+
goto cleanup;
perm_err:
@@ -395,7 +400,7 @@ rend_client_introduction_acked(origin_circuit_t *circ,
/* For path bias: This circuit was used successfully. Valid
* nacks and acks count. */
- circ->path_state = PATH_STATE_USE_SUCCEEDED;
+ pathbias_mark_use_success(circ);
if (request_len == 0) {
/* It's an ACK; the introduction point relayed our introduction request. */
@@ -902,7 +907,7 @@ rend_client_rendezvous_acked(origin_circuit_t *circ, const uint8_t *request,
* Waiting any longer opens us up to attacks from Bob. He could induce
* Alice to attempt to connect to his hidden service and never reply
* to her rend requests */
- circ->path_state = PATH_STATE_USE_SUCCEEDED;
+ pathbias_mark_use_success(circ);
/* XXXX This is a pretty brute-force approach. It'd be better to
* attach only the connections that are waiting on this circuit, rather
diff --git a/src/or/rendservice.c b/src/or/rendservice.c
index 6ffa4f8f95..f85ac2c03b 100644
--- a/src/or/rendservice.c
+++ b/src/or/rendservice.c
@@ -1384,9 +1384,6 @@ rend_service_introduce(origin_circuit_t *circuit, const uint8_t *request,
goto err;
memcpy(cpath->rend_circ_nonce, keys, DIGEST_LEN);
- /* For path bias: This intro circuit was used successfully */
- circuit->path_state = PATH_STATE_USE_SUCCEEDED;
-
goto done;
log_error:
@@ -2511,6 +2508,9 @@ rend_service_intro_has_opened(origin_circuit_t *circuit)
goto err;
}
+ /* We've attempted to use this circuit */
+ pathbias_count_use_attempt(circuit);
+
goto done;
err:
@@ -2558,6 +2558,10 @@ rend_service_intro_established(origin_circuit_t *circuit,
"Received INTRO_ESTABLISHED cell on circuit %d for service %s",
circuit->base_.n_circ_id, serviceid);
+ /* Getting a valid INTRODUCE_ESTABLISHED means we've successfully
+ * used the circ */
+ pathbias_mark_use_success(circuit);
+
return 0;
err:
circuit_mark_for_close(TO_CIRCUIT(circuit), END_CIRC_REASON_TORPROTOCOL);
@@ -2589,6 +2593,9 @@ rend_service_rendezvous_has_opened(origin_circuit_t *circuit)
if (!circuit->base_.timestamp_dirty)
circuit->base_.timestamp_dirty = time(NULL);
+ /* This may be redundant */
+ pathbias_count_use_attempt(circuit);
+
hop = circuit->build_state->service_pending_final_cpath_ref->cpath;
base16_encode(hexcookie,9,circuit->rend_data->rend_cookie,4);
@@ -3061,7 +3068,8 @@ rend_services_introduce(void)
if (intro->time_expiring + INTRO_POINT_EXPIRATION_GRACE_PERIOD > now) {
/* This intro point has completely expired. Remove it, and
* mark the circuit for close if it's still alive. */
- if (intro_circ != NULL) {
+ if (intro_circ != NULL &&
+ intro_circ->base_.purpose != CIRCUIT_PURPOSE_PATH_BIAS_TESTING) {
circuit_mark_for_close(TO_CIRCUIT(intro_circ),
END_CIRC_REASON_FINISHED);
}
@@ -3296,7 +3304,7 @@ rend_service_dump_stats(int severity)
for (i=0; i < smartlist_len(rend_service_list); ++i) {
service = smartlist_get(rend_service_list, i);
- log(severity, LD_GENERAL, "Service configured in \"%s\":",
+ tor_log(severity, LD_GENERAL, "Service configured in \"%s\":",
service->directory);
for (j=0; j < smartlist_len(service->intro_nodes); ++j) {
intro = smartlist_get(service->intro_nodes, j);
@@ -3304,11 +3312,11 @@ rend_service_dump_stats(int severity)
circ = find_intro_circuit(intro, service->pk_digest);
if (!circ) {
- log(severity, LD_GENERAL, " Intro point %d at %s: no circuit",
+ tor_log(severity, LD_GENERAL, " Intro point %d at %s: no circuit",
j, safe_name);
continue;
}
- log(severity, LD_GENERAL, " Intro point %d at %s: circuit is %s",
+ tor_log(severity, LD_GENERAL, " Intro point %d at %s: circuit is %s",
j, safe_name, circuit_state_to_string(circ->base_.state));
}
}
diff --git a/src/or/rephist.c b/src/or/rephist.c
index 74d459f8a3..925ca88153 100644
--- a/src/or/rephist.c
+++ b/src/or/rephist.c
@@ -648,7 +648,7 @@ rep_hist_dump_stats(time_t now, int severity)
rep_history_clean(now - get_options()->RephistTrackTime);
- log(severity, LD_HIST, "--------------- Dumping history information:");
+ tor_log(severity, LD_HIST, "--------------- Dumping history information:");
for (orhist_it = digestmap_iter_init(history_map);
!digestmap_iter_done(orhist_it);
@@ -673,7 +673,7 @@ rep_hist_dump_stats(time_t now, int severity)
} else {
uptime=1.0;
}
- log(severity, LD_HIST,
+ tor_log(severity, LD_HIST,
"OR %s [%s]: %ld/%ld good connections; uptime %ld/%ld sec (%.2f%%); "
"wmtbf %lu:%02lu:%02lu",
name1, hexdigest1,
@@ -707,7 +707,7 @@ rep_hist_dump_stats(time_t now, int severity)
else
len += ret;
}
- log(severity, LD_HIST, "%s", buffer);
+ tor_log(severity, LD_HIST, "%s", buffer);
}
}
}
@@ -2042,7 +2042,7 @@ note_crypto_pk_op(pk_op_t operation)
void
dump_pk_ops(int severity)
{
- log(severity, LD_HIST,
+ tor_log(severity, LD_HIST,
"PK operations: %lu directory objects signed, "
"%lu directory objects verified, "
"%lu routerdescs signed, "
diff --git a/src/or/router.c b/src/or/router.c
index c584d6277f..db396f0d56 100644
--- a/src/or/router.c
+++ b/src/or/router.c
@@ -391,14 +391,14 @@ init_key_from_file(const char *fname, int generate, int severity)
crypto_pk_t *prkey = NULL;
if (!(prkey = crypto_pk_new())) {
- log(severity, LD_GENERAL,"Error constructing key");
+ tor_log(severity, LD_GENERAL,"Error constructing key");
goto error;
}
switch (file_status(fname)) {
case FN_DIR:
case FN_ERROR:
- log(severity, LD_FS,"Can't read key from \"%s\"", fname);
+ tor_log(severity, LD_FS,"Can't read key from \"%s\"", fname);
goto error;
case FN_NOENT:
if (generate) {
@@ -406,8 +406,8 @@ init_key_from_file(const char *fname, int generate, int severity)
if (try_locking(get_options(), 0)<0) {
/* Make sure that --list-fingerprint only creates new keys
* if there is no possibility for a deadlock. */
- log(severity, LD_FS, "Another Tor process has locked \"%s\". Not "
- "writing any new keys.", fname);
+ tor_log(severity, LD_FS, "Another Tor process has locked \"%s\". "
+ "Not writing any new keys.", fname);
/*XXXX The 'other process' might make a key in a second or two;
* maybe we should wait for it. */
goto error;
@@ -416,16 +416,16 @@ init_key_from_file(const char *fname, int generate, int severity)
log_info(LD_GENERAL, "No key found in \"%s\"; generating fresh key.",
fname);
if (crypto_pk_generate_key(prkey)) {
- log(severity, LD_GENERAL,"Error generating onion key");
+ tor_log(severity, LD_GENERAL,"Error generating onion key");
goto error;
}
if (crypto_pk_check_key(prkey) <= 0) {
- log(severity, LD_GENERAL,"Generated key seems invalid");
+ tor_log(severity, LD_GENERAL,"Generated key seems invalid");
goto error;
}
log_info(LD_GENERAL, "Generated key seems valid");
if (crypto_pk_write_private_key_to_filename(prkey, fname)) {
- log(severity, LD_FS,
+ tor_log(severity, LD_FS,
"Couldn't write generated key to \"%s\".", fname);
goto error;
}
@@ -435,7 +435,7 @@ init_key_from_file(const char *fname, int generate, int severity)
return prkey;
case FN_FILE:
if (crypto_pk_read_private_key_from_filename(prkey, fname)) {
- log(severity, LD_GENERAL,"Error loading private key.");
+ tor_log(severity, LD_GENERAL,"Error loading private key.");
goto error;
}
return prkey;
@@ -465,7 +465,7 @@ init_curve25519_keypair_from_file(curve25519_keypair_t *keys_out,
switch (file_status(fname)) {
case FN_DIR:
case FN_ERROR:
- log(severity, LD_FS,"Can't read key from \"%s\"", fname);
+ tor_log(severity, LD_FS,"Can't read key from \"%s\"", fname);
goto error;
case FN_NOENT:
if (generate) {
@@ -473,8 +473,8 @@ init_curve25519_keypair_from_file(curve25519_keypair_t *keys_out,
if (try_locking(get_options(), 0)<0) {
/* Make sure that --list-fingerprint only creates new keys
* if there is no possibility for a deadlock. */
- log(severity, LD_FS, "Another Tor process has locked \"%s\". Not "
- "writing any new keys.", fname);
+ tor_log(severity, LD_FS, "Another Tor process has locked \"%s\". "
+ "Not writing any new keys.", fname);
/*XXXX The 'other process' might make a key in a second or two;
* maybe we should wait for it. */
goto error;
@@ -485,7 +485,7 @@ init_curve25519_keypair_from_file(curve25519_keypair_t *keys_out,
if (curve25519_keypair_generate(keys_out, 1) < 0)
goto error;
if (curve25519_keypair_write_to_file(keys_out, fname, tag)<0) {
- log(severity, LD_FS,
+ tor_log(severity, LD_FS,
"Couldn't write generated key to \"%s\".", fname);
memset(keys_out, 0, sizeof(*keys_out));
goto error;
@@ -498,12 +498,12 @@ init_curve25519_keypair_from_file(curve25519_keypair_t *keys_out,
{
char *tag_in=NULL;
if (curve25519_keypair_read_from_file(keys_out, &tag_in, fname) < 0) {
- log(severity, LD_GENERAL,"Error loading private key.");
+ tor_log(severity, LD_GENERAL,"Error loading private key.");
tor_free(tag_in);
goto error;
}
if (!tag_in || strcmp(tag_in, tag)) {
- log(severity, LD_GENERAL,"Unexpected tag %s on private key.",
+ tor_log(severity, LD_GENERAL,"Unexpected tag %s on private key.",
escaped(tag_in));
tor_free(tag_in);
goto error;
@@ -631,14 +631,14 @@ v3_authority_check_key_expiry(void)
return;
if (time_left <= 0) {
- log(badness, LD_DIR, "Your v3 authority certificate has expired."
- " Generate a new one NOW.");
+ tor_log(badness, LD_DIR, "Your v3 authority certificate has expired."
+ " Generate a new one NOW.");
} else if (time_left <= 24*60*60) {
- log(badness, LD_DIR, "Your v3 authority certificate expires in %d hours;"
- " Generate a new one NOW.", time_left/(60*60));
+ tor_log(badness, LD_DIR, "Your v3 authority certificate expires in %d "
+ "hours; Generate a new one NOW.", time_left/(60*60));
} else {
- log(badness, LD_DIR, "Your v3 authority certificate expires in %d days;"
- " Generate a new one soon.", time_left/(24*60*60));
+ tor_log(badness, LD_DIR, "Your v3 authority certificate expires in %d "
+ "days; Generate a new one soon.", time_left/(24*60*60));
}
last_warned = now;
}
@@ -902,7 +902,7 @@ init_keys(void)
tor_free(cp);
tor_free(keydir);
- log(LOG_NOTICE, LD_GENERAL,
+ log_notice(LD_GENERAL,
"Your Tor server's identity key fingerprint is '%s %s'",
options->Nickname, fingerprint);
if (!authdir_mode(options))
@@ -1062,10 +1062,10 @@ decide_to_advertise_dirport(const or_options_t *options, uint16_t dir_port)
if (advertising != new_choice) {
if (new_choice == 1) {
- log(LOG_NOTICE, LD_DIR, "Advertising DirPort as %d", dir_port);
+ log_notice(LD_DIR, "Advertising DirPort as %d", dir_port);
} else {
tor_assert(reason);
- log(LOG_NOTICE, LD_DIR, "Not advertising DirPort (Reason: %s)", reason);
+ log_notice(LD_DIR, "Not advertising DirPort (Reason: %s)", reason);
}
advertising = new_choice;
}
diff --git a/src/or/routerlist.c b/src/or/routerlist.c
index b294bfa080..8f19947600 100644
--- a/src/or/routerlist.c
+++ b/src/or/routerlist.c
@@ -42,6 +42,9 @@
/****************************************************************************/
/* static function prototypes */
+static int compute_weighted_bandwidths(const smartlist_t *sl,
+ bandwidth_weight_rule_t rule,
+ u64_dbl_t **bandwidths_out);
static const routerstatus_t *router_pick_directory_server_impl(
dirinfo_type_t auth, int flags);
static const routerstatus_t *router_pick_trusteddirserver_impl(
@@ -1681,9 +1684,35 @@ kb_to_bytes(uint32_t bw)
* guards proportionally less.
*/
static const node_t *
-smartlist_choose_node_by_bandwidth_weights(smartlist_t *sl,
+smartlist_choose_node_by_bandwidth_weights(const smartlist_t *sl,
bandwidth_weight_rule_t rule)
{
+ u64_dbl_t *bandwidths=NULL;
+
+ if (compute_weighted_bandwidths(sl, rule, &bandwidths) < 0)
+ return NULL;
+
+ scale_array_elements_to_u64(bandwidths, smartlist_len(sl),
+ &sl_last_total_weighted_bw);
+
+ {
+ int idx = choose_array_element_by_weight(bandwidths,
+ smartlist_len(sl));
+ tor_free(bandwidths);
+ return idx < 0 ? NULL : smartlist_get(sl, idx);
+ }
+}
+
+/** Given a list of routers and a weighting rule as in
+ * smartlist_choose_node_by_bandwidth_weights, compute weighted bandwidth
+ * values for each node and store them in a freshly allocated
+ * *<b>bandwidths_out</b> of the same length as <b>sl</b>, and holding results
+ * as doubles. Return 0 on success, -1 on failure. */
+static int
+compute_weighted_bandwidths(const smartlist_t *sl,
+ bandwidth_weight_rule_t rule,
+ u64_dbl_t **bandwidths_out)
+{
int64_t weight_scale;
double Wg = -1, Wm = -1, We = -1, Wd = -1;
double Wgb = -1, Wmb = -1, Web = -1, Wdb = -1;
@@ -1702,10 +1731,10 @@ smartlist_choose_node_by_bandwidth_weights(smartlist_t *sl,
"Empty routerlist passed in to consensus weight node "
"selection for rule %s",
bandwidth_weight_rule_to_string(rule));
- return NULL;
+ return -1;
}
- weight_scale = circuit_build_times_get_bw_scale(NULL);
+ weight_scale = networkstatus_get_weight_scale_param(NULL);
if (rule == WEIGHT_FOR_GUARD) {
Wg = networkstatus_get_bw_weight(NULL, "Wgg", -1);
@@ -1756,7 +1785,7 @@ smartlist_choose_node_by_bandwidth_weights(smartlist_t *sl,
log_debug(LD_CIRC,
"Got negative bandwidth weights. Defaulting to old selection"
" algorithm.");
- return NULL; // Use old algorithm.
+ return -1; // Use old algorithm.
}
Wg /= weight_scale;
@@ -1786,7 +1815,7 @@ smartlist_choose_node_by_bandwidth_weights(smartlist_t *sl,
log_warn(LD_BUG,
"Consensus is not listing bandwidths. Defaulting back to "
"old router selection algorithm.");
- return NULL;
+ return -1;
}
this_bw = kb_to_bytes(node->rs->bandwidth);
} else if (node->ri) {
@@ -1819,20 +1848,53 @@ smartlist_choose_node_by_bandwidth_weights(smartlist_t *sl,
sl_last_weighted_bw_of_me = (uint64_t) bandwidths[node_sl_idx].dbl;
} SMARTLIST_FOREACH_END(node);
- log_debug(LD_CIRC, "Choosing node for rule %s based on weights "
+ log_debug(LD_CIRC, "Generated weighted bandwidths for rule %s based "
+ "on weights "
"Wg=%f Wm=%f We=%f Wd=%f with total bw "U64_FORMAT,
bandwidth_weight_rule_to_string(rule),
Wg, Wm, We, Wd, U64_PRINTF_ARG(weighted_bw));
- scale_array_elements_to_u64(bandwidths, smartlist_len(sl),
- &sl_last_total_weighted_bw);
+ *bandwidths_out = bandwidths;
- {
- int idx = choose_array_element_by_weight(bandwidths,
- smartlist_len(sl));
- tor_free(bandwidths);
- return idx < 0 ? NULL : smartlist_get(sl, idx);
+ return 0;
+}
+
+/** For all nodes in <b>sl</b>, return the fraction of those nodes, weighted
+ * by their weighted bandwidths with rule <b>rule</b>, for which we have
+ * descriptors. */
+double
+frac_nodes_with_descriptors(const smartlist_t *sl,
+ bandwidth_weight_rule_t rule)
+{
+ u64_dbl_t *bandwidths = NULL;
+ double total, present;
+
+ if (smartlist_len(sl) == 0)
+ return 0.0;
+
+ if (compute_weighted_bandwidths(sl, rule, &bandwidths) < 0) {
+ int n_with_descs = 0;
+ SMARTLIST_FOREACH(sl, const node_t *, node, {
+ if (node_has_descriptor(node))
+ n_with_descs++;
+ });
+ return ((double)n_with_descs) / (double)smartlist_len(sl);
}
+
+ total = present = 0.0;
+ SMARTLIST_FOREACH_BEGIN(sl, const node_t *, node) {
+ const double bw = bandwidths[node_sl_idx].dbl;
+ total += bw;
+ if (node_has_descriptor(node))
+ present += bw;
+ } SMARTLIST_FOREACH_END(node);
+
+ tor_free(bandwidths);
+
+ if (total < 1.0)
+ return 0;
+
+ return present / total;
}
/** Helper function:
@@ -1849,7 +1911,7 @@ smartlist_choose_node_by_bandwidth_weights(smartlist_t *sl,
* guards proportionally less.
*/
static const node_t *
-smartlist_choose_node_by_bandwidth(smartlist_t *sl,
+smartlist_choose_node_by_bandwidth(const smartlist_t *sl,
bandwidth_weight_rule_t rule)
{
unsigned int i;
@@ -2055,7 +2117,7 @@ smartlist_choose_node_by_bandwidth(smartlist_t *sl,
/** Choose a random element of status list <b>sl</b>, weighted by
* the advertised bandwidth of each node */
const node_t *
-node_sl_choose_by_bandwidth(smartlist_t *sl,
+node_sl_choose_by_bandwidth(const smartlist_t *sl,
bandwidth_weight_rule_t rule)
{ /*XXXX MOVE */
const node_t *ret;
@@ -2585,7 +2647,7 @@ dump_routerlist_mem_usage(int severity)
SMARTLIST_FOREACH(routerlist->old_routers, signed_descriptor_t *, sd,
olddescs += sd->signed_descriptor_len);
- log(severity, LD_DIR,
+ tor_log(severity, LD_DIR,
"In %d live descriptors: "U64_FORMAT" bytes. "
"In %d old descriptors: "U64_FORMAT" bytes.",
smartlist_len(routerlist->routers), U64_PRINTF_ARG(livedescs),
diff --git a/src/or/routerlist.h b/src/or/routerlist.h
index 798cebc58e..1849fff31c 100644
--- a/src/or/routerlist.h
+++ b/src/or/routerlist.h
@@ -47,8 +47,10 @@ const routerinfo_t *routerlist_find_my_routerinfo(void);
uint32_t router_get_advertised_bandwidth(const routerinfo_t *router);
uint32_t router_get_advertised_bandwidth_capped(const routerinfo_t *router);
-const node_t *node_sl_choose_by_bandwidth(smartlist_t *sl,
+const node_t *node_sl_choose_by_bandwidth(const smartlist_t *sl,
bandwidth_weight_rule_t rule);
+double frac_nodes_with_descriptors(const smartlist_t *sl,
+ bandwidth_weight_rule_t rule);
const node_t *router_choose_random_node(smartlist_t *excludedsmartlist,
struct routerset_t *excludedset,
diff --git a/src/or/routerparse.c b/src/or/routerparse.c
index b945ea6aa6..2a3de12c35 100644
--- a/src/or/routerparse.c
+++ b/src/or/routerparse.c
@@ -1029,7 +1029,7 @@ dump_distinct_digest_count(int severity)
#ifdef COUNT_DISTINCT_DIGESTS
if (!verified_digests)
verified_digests = digestmap_new();
- log(severity, LD_GENERAL, "%d *distinct* router digests verified",
+ tor_log(severity, LD_GENERAL, "%d *distinct* router digests verified",
digestmap_size(verified_digests));
#else
(void)severity; /* suppress "unused parameter" warning */
@@ -2255,7 +2255,7 @@ networkstatus_verify_bw_weights(networkstatus_t *ns)
const char *casename = NULL;
int valid = 1;
- weight_scale = circuit_build_times_get_bw_scale(ns);
+ weight_scale = networkstatus_get_weight_scale_param(ns);
Wgg = networkstatus_get_bw_weight(ns, "Wgg", -1);
Wgm = networkstatus_get_bw_weight(ns, "Wgm", -1);
Wgd = networkstatus_get_bw_weight(ns, "Wgd", -1);
diff --git a/src/or/routerset.c b/src/or/routerset.c
index 4b519034d3..e45516bb6c 100644
--- a/src/or/routerset.c
+++ b/src/or/routerset.c
@@ -95,7 +95,7 @@ routerset_refresh_countries(routerset_t *target)
tor_assert(cc < target->n_countries);
bitarray_set(target->countries, cc);
} else {
- log(LOG_WARN, LD_CONFIG, "Country code '%s' is not recognized.",
+ log_warn(LD_CONFIG, "Country code '%s' is not recognized.",
country);
}
} SMARTLIST_FOREACH_END(country);
diff --git a/src/or/statefile.c b/src/or/statefile.c
index 53b6817ef7..bcb7b07417 100644
--- a/src/or/statefile.c
+++ b/src/or/statefile.c
@@ -52,6 +52,7 @@ static config_var_t state_vars_[] = {
VAR("EntryGuardUnlistedSince", LINELIST_S, EntryGuards, NULL),
VAR("EntryGuardAddedBy", LINELIST_S, EntryGuards, NULL),
VAR("EntryGuardPathBias", LINELIST_S, EntryGuards, NULL),
+ VAR("EntryGuardPathUseBias", LINELIST_S, EntryGuards, NULL),
V(EntryGuards, LINELIST_V, NULL),
VAR("TransportProxy", LINELIST_S, TransportProxies, NULL),
diff --git a/src/or/status.c b/src/or/status.c
index 97d0e49e01..126167dcb9 100644
--- a/src/or/status.c
+++ b/src/or/status.c
@@ -108,7 +108,7 @@ log_heartbeat(time_t now)
uptime, count_circuits(),bw_sent,bw_rcvd);
if (stats_n_data_cells_packaged)
- log(LOG_NOTICE, LD_HEARTBEAT, "Average packaged cell fullness: %2.3f%%",
+ log_notice(LD_HEARTBEAT, "Average packaged cell fullness: %2.3f%%",
100*(U64_TO_DBL(stats_n_data_bytes_packaged) /
U64_TO_DBL(stats_n_data_cells_packaged*RELAY_PAYLOAD_SIZE)) );
diff --git a/src/test/test.c b/src/test/test.c
index e3e989b0c1..b838172d5a 100644
--- a/src/test/test.c
+++ b/src/test/test.c
@@ -1529,59 +1529,35 @@ test_geoip(void)
*dirreq_stats_1 =
"dirreq-stats-end 2010-08-12 13:27:30 (86400 s)\n"
"dirreq-v3-ips ab=8\n"
- "dirreq-v2-ips \n"
"dirreq-v3-reqs ab=8\n"
- "dirreq-v2-reqs \n"
"dirreq-v3-resp ok=0,not-enough-sigs=0,unavailable=0,not-found=0,"
"not-modified=0,busy=0\n"
- "dirreq-v2-resp ok=0,unavailable=0,not-found=0,not-modified=0,"
- "busy=0\n"
"dirreq-v3-direct-dl complete=0,timeout=0,running=0\n"
- "dirreq-v2-direct-dl complete=0,timeout=0,running=0\n"
- "dirreq-v3-tunneled-dl complete=0,timeout=0,running=0\n"
- "dirreq-v2-tunneled-dl complete=0,timeout=0,running=0\n",
+ "dirreq-v3-tunneled-dl complete=0,timeout=0,running=0\n",
*dirreq_stats_2 =
"dirreq-stats-end 2010-08-12 13:27:30 (86400 s)\n"
"dirreq-v3-ips \n"
- "dirreq-v2-ips \n"
"dirreq-v3-reqs \n"
- "dirreq-v2-reqs \n"
"dirreq-v3-resp ok=0,not-enough-sigs=0,unavailable=0,not-found=0,"
"not-modified=0,busy=0\n"
- "dirreq-v2-resp ok=0,unavailable=0,not-found=0,not-modified=0,"
- "busy=0\n"
"dirreq-v3-direct-dl complete=0,timeout=0,running=0\n"
- "dirreq-v2-direct-dl complete=0,timeout=0,running=0\n"
- "dirreq-v3-tunneled-dl complete=0,timeout=0,running=0\n"
- "dirreq-v2-tunneled-dl complete=0,timeout=0,running=0\n",
+ "dirreq-v3-tunneled-dl complete=0,timeout=0,running=0\n",
*dirreq_stats_3 =
"dirreq-stats-end 2010-08-12 13:27:30 (86400 s)\n"
"dirreq-v3-ips \n"
- "dirreq-v2-ips \n"
"dirreq-v3-reqs \n"
- "dirreq-v2-reqs \n"
"dirreq-v3-resp ok=8,not-enough-sigs=0,unavailable=0,not-found=0,"
"not-modified=0,busy=0\n"
- "dirreq-v2-resp ok=0,unavailable=0,not-found=0,not-modified=0,"
- "busy=0\n"
"dirreq-v3-direct-dl complete=0,timeout=0,running=0\n"
- "dirreq-v2-direct-dl complete=0,timeout=0,running=0\n"
- "dirreq-v3-tunneled-dl complete=0,timeout=0,running=0\n"
- "dirreq-v2-tunneled-dl complete=0,timeout=0,running=0\n",
+ "dirreq-v3-tunneled-dl complete=0,timeout=0,running=0\n",
*dirreq_stats_4 =
"dirreq-stats-end 2010-08-12 13:27:30 (86400 s)\n"
"dirreq-v3-ips \n"
- "dirreq-v2-ips \n"
"dirreq-v3-reqs \n"
- "dirreq-v2-reqs \n"
"dirreq-v3-resp ok=8,not-enough-sigs=0,unavailable=0,not-found=0,"
"not-modified=0,busy=0\n"
- "dirreq-v2-resp ok=0,unavailable=0,not-found=0,not-modified=0,"
- "busy=0\n"
"dirreq-v3-direct-dl complete=0,timeout=0,running=0\n"
- "dirreq-v2-direct-dl complete=0,timeout=0,running=0\n"
- "dirreq-v3-tunneled-dl complete=0,timeout=0,running=4\n"
- "dirreq-v2-tunneled-dl complete=0,timeout=0,running=0\n",
+ "dirreq-v3-tunneled-dl complete=0,timeout=0,running=4\n",
*entry_stats_1 =
"entry-stats-end 2010-08-12 13:27:30 (86400 s)\n"
"entry-ips ab=8\n",
@@ -1754,14 +1730,13 @@ test_geoip(void)
/* Note a successful network status response and make sure that it
* appears in the history string. */
- geoip_note_ns_response(GEOIP_CLIENT_NETWORKSTATUS, GEOIP_SUCCESS);
+ geoip_note_ns_response(GEOIP_SUCCESS);
s = geoip_format_dirreq_stats(now + 86400);
test_streq(dirreq_stats_3, s);
tor_free(s);
/* Start a tunneled directory request. */
- geoip_start_dirreq((uint64_t) 1, 1024, GEOIP_CLIENT_NETWORKSTATUS,
- DIRREQ_TUNNELED);
+ geoip_start_dirreq((uint64_t) 1, 1024, DIRREQ_TUNNELED);
s = geoip_format_dirreq_stats(now + 86400);
test_streq(dirreq_stats_4, s);
diff --git a/src/test/test_util.c b/src/test/test_util.c
index ad214b9e67..bed33fac25 100644
--- a/src/test/test_util.c
+++ b/src/test/test_util.c
@@ -17,6 +17,7 @@
#ifdef _WIN32
#include <tchar.h>
#endif
+#include <math.h>
/* XXXX this is a minimal wrapper to make the unit tests compile with the
* changed tor_timegm interface. */
@@ -3240,6 +3241,20 @@ test_util_set_env_var_in_sl(void *ptr)
smartlist_free(expected_resulting_env_vars);
}
+static void
+test_util_mathlog(void *arg)
+{
+ double d;
+ (void) arg;
+
+ d = tor_mathlog(2.718281828);
+ tt_double_op(fabs(d - 1.0), <, .000001);
+ d = tor_mathlog(10);
+ tt_double_op(fabs(d - 2.30258509), <, .000001);
+ done:
+ ;
+}
+
#define UTIL_LEGACY(name) \
{ #name, legacy_test_helper, 0, &legacy_setup, test_util_ ## name }
@@ -3296,6 +3311,7 @@ struct testcase_t util_tests[] = {
UTIL_TEST(read_file_eof_tiny_limit, 0),
UTIL_TEST(read_file_eof_two_loops, 0),
UTIL_TEST(read_file_eof_zero_bytes, 0),
+ UTIL_TEST(mathlog, 0),
END_OF_TESTCASES
};
diff --git a/src/tools/tor-gencert.c b/src/tools/tor-gencert.c
index c68aaa747c..3809b22d43 100644
--- a/src/tools/tor-gencert.c
+++ b/src/tools/tor-gencert.c
@@ -82,10 +82,11 @@ crypto_log_errors(int severity, const char *doing)
if (!lib) lib = "(null)";
if (!func) func = "(null)";
if (doing) {
- log(severity, LD_CRYPTO, "crypto error while %s: %s (in %s:%s)",
- doing, msg, lib, func);
+ tor_log(severity, LD_CRYPTO, "crypto error while %s: %s (in %s:%s)",
+ doing, msg, lib, func);
} else {
- log(severity, LD_CRYPTO, "crypto error: %s (in %s:%s)", msg, lib, func);
+ tor_log(severity, LD_CRYPTO, "crypto error: %s (in %s:%s)",
+ msg, lib, func);
}
}
}
diff --git a/src/win32/orconfig.h b/src/win32/orconfig.h
index 6e45a2928b..ef08fdb2be 100644
--- a/src/win32/orconfig.h
+++ b/src/win32/orconfig.h
@@ -151,6 +151,9 @@
/* Define to 1 iff NULL is represented by a 0 in memory. */
#define NULL_REP_IS_ZERO_BYTES 1
+/* Define to 1 iff memset(0) sets doubles to 0.0 */
+#define DOUBLE_0_REP_IS_ZERO_BYTES 1
+
/* Name of package */
#define PACKAGE "tor"