From d3653063d30ee8174f6ec330124553c6717fbe9c Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Thu, 18 Aug 2011 15:08:49 -0400 Subject: [PATCH 1/7] Automatically use filtering bufferevents with IOCP. --- changes/bug3752 | 5 +++++ src/common/compat_libevent.c | 11 +++++++++++ src/common/compat_libevent.h | 1 + src/common/tortls.c | 2 +- 4 files changed, 18 insertions(+), 1 deletion(-) create mode 100644 changes/bug3752 diff --git a/changes/bug3752 b/changes/bug3752 new file mode 100644 index 0000000000..270f1559cf --- /dev/null +++ b/changes/bug3752 @@ -0,0 +1,5 @@ + o Major bugfixes: + - The IOCP backend now works even when the user has not specified + the (internal, debbuging-only) _UseFilteringSSLBufferevents option. + Fixes part of bug 3752; bugfix on 0.2.3.1-alpha. + diff --git a/src/common/compat_libevent.c b/src/common/compat_libevent.c index 8752de7492..595742f961 100644 --- a/src/common/compat_libevent.c +++ b/src/common/compat_libevent.c @@ -164,6 +164,16 @@ struct event_base *the_event_base = NULL; #endif #endif +#ifdef USE_BUFFEREVENTS +static int using_iocp_bufferevents = 0; + +int +tor_libevent_using_iocp_bufferevents(void) +{ + return using_iocp_bufferevents; +} +#endif + /** Initialize the Libevent library and set up the event base. */ void tor_libevent_initialize(tor_libevent_cfg *torcfg) @@ -187,6 +197,7 @@ tor_libevent_initialize(tor_libevent_cfg *torcfg) if (! torcfg->disable_iocp) { evthread_use_windows_threads(); event_config_set_flag(cfg, EVENT_BASE_FLAG_STARTUP_IOCP); + using_iocp_bufferevents = 1; } #endif diff --git a/src/common/compat_libevent.h b/src/common/compat_libevent.h index 8669fd4e0b..bbe105bf40 100644 --- a/src/common/compat_libevent.h +++ b/src/common/compat_libevent.h @@ -73,6 +73,7 @@ const char *tor_libevent_get_version_str(void); #ifdef USE_BUFFEREVENTS #define TOR_LIBEVENT_TICKS_PER_SECOND 3 const struct timeval *tor_libevent_get_one_tick_timeout(void); +int tor_libevent_using_iocp_bufferevents(void); #endif #endif diff --git a/src/common/tortls.c b/src/common/tortls.c index 455603030f..2aaa2c49b5 100644 --- a/src/common/tortls.c +++ b/src/common/tortls.c @@ -1892,7 +1892,7 @@ tor_tls_init_bufferevent(tor_tls_t *tls, struct bufferevent *bufev_in, const enum bufferevent_ssl_state state = receiving ? BUFFEREVENT_SSL_ACCEPTING : BUFFEREVENT_SSL_CONNECTING; - if (filter) { + if (filter || tor_libevent_using_iocp_bufferevents()) { /* Grab an extra reference to the SSL, since BEV_OPT_CLOSE_ON_FREE means that the SSL will get freed too. From 263d68aa82e77026e2a34c07152435b0c31feb0e Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Thu, 18 Aug 2011 15:17:37 -0400 Subject: [PATCH 2/7] Appease "make check-spaces" --- src/or/buffers.c | 8 ++++---- src/or/connection.c | 1 + 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/or/buffers.c b/src/or/buffers.c index c9c8e43082..ffc15141ab 100644 --- a/src/or/buffers.c +++ b/src/or/buffers.c @@ -1054,14 +1054,14 @@ fetch_var_cell_from_buf(buf_t *buf, var_cell_t **out, int linkproto) #ifdef USE_BUFFEREVENTS /** Try to read n bytes from buf at pos (which may be * NULL for the start of the buffer), copying the data only if necessary. Set - * *data_out to a pointer to the desired bytes. Set free_out to 1 - * if we needed to malloc *data because the original bytes were + * *data_out to a pointer to the desired bytes. Set free_out + * to 1 if we needed to malloc *data because the original bytes were * noncontiguous; 0 otherwise. Return the number of bytes actually available * at *data_out. */ static ssize_t -inspect_evbuffer(struct evbuffer *buf, char **data_out, size_t n, int *free_out, - struct evbuffer_ptr *pos) +inspect_evbuffer(struct evbuffer *buf, char **data_out, size_t n, + int *free_out, struct evbuffer_ptr *pos) { int n_vecs, i; diff --git a/src/or/connection.c b/src/or/connection.c index 4e691e17fe..f8f82a30dd 100644 --- a/src/or/connection.c +++ b/src/or/connection.c @@ -4166,3 +4166,4 @@ connection_free_all(void) bufferevent_rate_limit_group_free(global_rate_limit); #endif } + From df96aed14f67c9ffc2c4908add7079a0424d7cbb Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Thu, 18 Aug 2011 16:15:03 -0400 Subject: [PATCH 3/7] Remove warning about a loop parsing evbuffer socks This behavior is normal when we want more data than the evbuffer actually has for us. We'll ask for (say) 7 bytes, get only 5 (because that's all there is), try to parse the 5 bytes, and get told "no, I want 7". One option would be to bail out early whenever want_length is > buflen, but sometimes we use an over-large want_length. So instead, let's just remove the warning here: it's not a bug after all. --- src/or/buffers.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/or/buffers.c b/src/or/buffers.c index ffc15141ab..85d58e8986 100644 --- a/src/or/buffers.c +++ b/src/or/buffers.c @@ -1657,9 +1657,9 @@ fetch_from_evbuffer_socks(struct evbuffer *buf, socks_request_t *req, if (res == 0 && n_drain == 0 && want_length <= last_wanted) { /* If we drained nothing, and we didn't ask for more than last time, - * we're stuck in a loop. That's bad. It shouldn't be possible, but - * let's make sure. */ - log_warn(LD_BUG, "We seem to be caught in a parse loop; breaking out"); + * then we probably wanted more data than the buffer actually had, + * and we're finding out that we're not satisified with it. It's + * time to break until we have more data. */ break; } From 2ad336f999781db211d92332e657398829c8799c Mon Sep 17 00:00:00 2001 From: Steven Murdoch Date: Fri, 19 Aug 2011 14:47:44 +0100 Subject: [PATCH 4/7] Link and build tor-fw-helper on Windows - Update configure script to test for libminiupnpc along with the libws2_32 and libiphlpapi libraries required by libminiupnpc - When building tor-fw-helper, link in libiphlpapi - Link in libminiupnpc statically becasue I could not get the DLL to link properly - Call WSAStartup before doing network operations - Fix up a compiler warning about uninitialized backend_state N.B. The changes to configure.in and Makefile.am will break on non- Windows platforms. --- configure.in | 2 +- src/tools/tor-fw-helper/Makefile.am | 2 +- src/tools/tor-fw-helper/tor-fw-helper-upnp.c | 3 ++ src/tools/tor-fw-helper/tor-fw-helper.c | 34 +++++++++++++++++++- 4 files changed, 38 insertions(+), 3 deletions(-) diff --git a/configure.in b/configure.in index 4a89df6e04..1c45f186d5 100644 --- a/configure.in +++ b/configure.in @@ -559,7 +559,7 @@ dnl There are no packages for Debian or Redhat as of this patch if test "$upnp" = "true"; then AC_DEFINE(MINIUPNPC, 1, [Define to 1 if we are building with UPnP.]) - TOR_SEARCH_LIBRARY(libminiupnpc, $trylibminiupnpcdir, [-lminiupnpc], + TOR_SEARCH_LIBRARY(libminiupnpc, $trylibminiupnpcdir, [-lminiupnpc -lws2_32 -liphlpapi], [#include #include #include ], diff --git a/src/tools/tor-fw-helper/Makefile.am b/src/tools/tor-fw-helper/Makefile.am index 77ff63fc36..39aabc7b20 100644 --- a/src/tools/tor-fw-helper/Makefile.am +++ b/src/tools/tor-fw-helper/Makefile.am @@ -25,7 +25,7 @@ endif if MINIUPNPC miniupnpc_ldflags = @TOR_LDFLAGS_libminiupnpc@ -miniupnpc_ldadd = -lminiupnpc -lm +miniupnpc_ldadd = -lminiupnpc -lm -liphlpapi miniupnpc_cppflags = @TOR_CPPFLAGS_libminiupnpc@ else miniupnpc_ldflags = diff --git a/src/tools/tor-fw-helper/tor-fw-helper-upnp.c b/src/tools/tor-fw-helper/tor-fw-helper-upnp.c index 18ca56394f..c4b14a84e2 100644 --- a/src/tools/tor-fw-helper/tor-fw-helper-upnp.c +++ b/src/tools/tor-fw-helper/tor-fw-helper-upnp.c @@ -9,6 +9,9 @@ #include "orconfig.h" #ifdef MINIUPNPC +#ifdef MS_WINDOWS +#define STATICLIB +#endif #include #include #include diff --git a/src/tools/tor-fw-helper/tor-fw-helper.c b/src/tools/tor-fw-helper/tor-fw-helper.c index 20d60d7ba6..cb8e0cd9eb 100644 --- a/src/tools/tor-fw-helper/tor-fw-helper.c +++ b/src/tools/tor-fw-helper/tor-fw-helper.c @@ -13,6 +13,7 @@ * later date. */ +#include "orconfig.h" #include #include #include @@ -20,7 +21,10 @@ #include #include -#include "orconfig.h" +#ifdef MS_WINDOWS +#include +#endif + #include "tor-fw-helper.h" #ifdef NAT_PMP #include "tor-fw-helper-natpmp.h" @@ -219,6 +223,29 @@ tor_fw_add_dir_port(tor_fw_options_t *tor_fw_options, } } +/** Called before we make any calls to network-related functions. + * (Some operating systems require their network libraries to be + * initialized.) (from common/compat.c) */ +static int +network_init(void) +{ +#ifdef MS_WINDOWS + /* This silly exercise is necessary before windows will allow + * gethostbyname to work. */ + WSADATA WSAData; + int r; + r = WSAStartup(0x101, &WSAData); + if (r) { + fprintf(stderr, "E: Error initializing Windows network layer - code was %d", r); + return -1; + } + /* WSAData.iMaxSockets might show the max sockets we're allowed to use. + * We might use it to complain if we're trying to be a server but have + * too few sockets available. */ +#endif + return 0; +} + int main(int argc, char **argv) { @@ -229,6 +256,7 @@ main(int argc, char **argv) backends_t backend_state; memset(&tor_fw_options, 0, sizeof(tor_fw_options)); + memset(&backend_state, 0, sizeof(backend_state)); while (1) { int option_index = 0; @@ -329,6 +357,10 @@ main(int argc, char **argv) tor_fw_options.public_dir_port); } + // Initialize networking + if (network_init()) + exit(1); + // Initalize the various fw-helper backend helpers r = init_backends(&tor_fw_options, &backend_state); if (r) From 269c0b4633a5b41b2d37cf9c877fe37c4ea4a1f9 Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Fri, 19 Aug 2011 13:20:15 -0400 Subject: [PATCH 5/7] Only link ws2_32 and iphlapi on windows. This is a tweak for the tor-fw-helper port to windows. --- configure.in | 4 +++- src/tools/tor-fw-helper/Makefile.am | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/configure.in b/configure.in index 1c45f186d5..f9e98f0256 100644 --- a/configure.in +++ b/configure.in @@ -325,6 +325,7 @@ dnl Where do you live, libevent? And how do we call you? if test "$bwin32" = true; then TOR_LIB_WS32=-lws2_32 + TOR_LIB_IPHLAPI=-liphlapi # Some of the cargo-cults recommend -lwsock32 as well, but I don't # think it's actually necessary. TOR_LIB_GDI=-lgdi32 @@ -334,6 +335,7 @@ else fi AC_SUBST(TOR_LIB_WS32) AC_SUBST(TOR_LIB_GDI) +AC_SUBST(TOR_LIB_IPHLAPI) dnl We need to do this before we try our disgusting hack below. AC_CHECK_HEADERS([sys/types.h]) @@ -559,7 +561,7 @@ dnl There are no packages for Debian or Redhat as of this patch if test "$upnp" = "true"; then AC_DEFINE(MINIUPNPC, 1, [Define to 1 if we are building with UPnP.]) - TOR_SEARCH_LIBRARY(libminiupnpc, $trylibminiupnpcdir, [-lminiupnpc -lws2_32 -liphlpapi], + TOR_SEARCH_LIBRARY(libminiupnpc, $trylibminiupnpcdir, [-lminiupnpc $TOR_LIB_WS32 $TOR_LIB_IPHLAPI], [#include #include #include ], diff --git a/src/tools/tor-fw-helper/Makefile.am b/src/tools/tor-fw-helper/Makefile.am index 39aabc7b20..127a000020 100644 --- a/src/tools/tor-fw-helper/Makefile.am +++ b/src/tools/tor-fw-helper/Makefile.am @@ -25,7 +25,7 @@ endif if MINIUPNPC miniupnpc_ldflags = @TOR_LDFLAGS_libminiupnpc@ -miniupnpc_ldadd = -lminiupnpc -lm -liphlpapi +miniupnpc_ldadd = -lminiupnpc -lm @TOR_LIB_IPHLAPI@ miniupnpc_cppflags = @TOR_CPPFLAGS_libminiupnpc@ else miniupnpc_ldflags = From c5e74fc60db2b0c763d55f5bca8a32dc4bc05fe5 Mon Sep 17 00:00:00 2001 From: Steven Murdoch Date: Mon, 22 Aug 2011 16:31:30 +0100 Subject: [PATCH 6/7] Appease "make check spaces" --- src/tools/tor-fw-helper/tor-fw-helper.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/tools/tor-fw-helper/tor-fw-helper.c b/src/tools/tor-fw-helper/tor-fw-helper.c index cb8e0cd9eb..002239745a 100644 --- a/src/tools/tor-fw-helper/tor-fw-helper.c +++ b/src/tools/tor-fw-helper/tor-fw-helper.c @@ -236,7 +236,8 @@ network_init(void) int r; r = WSAStartup(0x101, &WSAData); if (r) { - fprintf(stderr, "E: Error initializing Windows network layer - code was %d", r); + fprintf(stderr, "E: Error initializing Windows network layer " + "- code was %d", r); return -1; } /* WSAData.iMaxSockets might show the max sockets we're allowed to use. From 850d8c9eb8a847d3d35d4e39acf2d84afe8dffa4 Mon Sep 17 00:00:00 2001 From: Steven Murdoch Date: Mon, 22 Aug 2011 17:38:22 +0100 Subject: [PATCH 7/7] Correct reference to libiphlpapi from libiphlapi --- configure.in | 6 +++--- src/tools/tor-fw-helper/Makefile.am | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/configure.in b/configure.in index f9e98f0256..26792a6677 100644 --- a/configure.in +++ b/configure.in @@ -325,7 +325,7 @@ dnl Where do you live, libevent? And how do we call you? if test "$bwin32" = true; then TOR_LIB_WS32=-lws2_32 - TOR_LIB_IPHLAPI=-liphlapi + TOR_LIB_IPHLPAPI=-liphlpapi # Some of the cargo-cults recommend -lwsock32 as well, but I don't # think it's actually necessary. TOR_LIB_GDI=-lgdi32 @@ -335,7 +335,7 @@ else fi AC_SUBST(TOR_LIB_WS32) AC_SUBST(TOR_LIB_GDI) -AC_SUBST(TOR_LIB_IPHLAPI) +AC_SUBST(TOR_LIB_IPHLPAPI) dnl We need to do this before we try our disgusting hack below. AC_CHECK_HEADERS([sys/types.h]) @@ -561,7 +561,7 @@ dnl There are no packages for Debian or Redhat as of this patch if test "$upnp" = "true"; then AC_DEFINE(MINIUPNPC, 1, [Define to 1 if we are building with UPnP.]) - TOR_SEARCH_LIBRARY(libminiupnpc, $trylibminiupnpcdir, [-lminiupnpc $TOR_LIB_WS32 $TOR_LIB_IPHLAPI], + TOR_SEARCH_LIBRARY(libminiupnpc, $trylibminiupnpcdir, [-lminiupnpc $TOR_LIB_WS32 $TOR_LIB_IPHLPAPI], [#include #include #include ], diff --git a/src/tools/tor-fw-helper/Makefile.am b/src/tools/tor-fw-helper/Makefile.am index 127a000020..8f64ad2ba3 100644 --- a/src/tools/tor-fw-helper/Makefile.am +++ b/src/tools/tor-fw-helper/Makefile.am @@ -25,7 +25,7 @@ endif if MINIUPNPC miniupnpc_ldflags = @TOR_LDFLAGS_libminiupnpc@ -miniupnpc_ldadd = -lminiupnpc -lm @TOR_LIB_IPHLAPI@ +miniupnpc_ldadd = -lminiupnpc -lm @TOR_LIB_IPHLPAPI@ miniupnpc_cppflags = @TOR_CPPFLAGS_libminiupnpc@ else miniupnpc_ldflags =