Browse Source

Merge remote-tracking branch 'public/feature4516'

Nick Mathewson 12 years ago
parent
commit
f634228a07
4 changed files with 41 additions and 0 deletions
  1. 7 0
      changes/UserspaceIOCPBuffers
  2. 1 0
      src/or/config.c
  3. 28 0
      src/or/main.c
  4. 5 0
      src/or/or.h

+ 7 - 0
changes/UserspaceIOCPBuffers

@@ -0,0 +1,7 @@
+  o Minor features:
+    - Experimental support for running on Windows with IOCP and no
+      kernel-space socket buffers. This feature is controlled by a new
+      UserspaceIOCPBuffers feature (off by default), which has no
+      effect unless Tor has been built with support for bufferevents,
+      is running on Windows, and has enabled IOCP.  This may, in the
+      long run, help solve or mitigate bug 98.

+ 1 - 0
src/or/config.c

@@ -405,6 +405,7 @@ static config_var_t _option_vars[] = {
   V(UseEntryGuards,              BOOL,     "1"),
   V(UseMicrodescriptors,         AUTOBOOL, "auto"),
   V(User,                        STRING,   NULL),
+  V(UserspaceIOCPBuffers,        BOOL,     "0"),
   VAR("V1AuthoritativeDirectory",BOOL, V1AuthoritativeDir,   "0"),
   VAR("V2AuthoritativeDirectory",BOOL, V2AuthoritativeDir,   "0"),
   VAR("V3AuthoritativeDirectory",BOOL, V3AuthoritativeDir,   "0"),

+ 28 - 0
src/or/main.c

@@ -196,6 +196,26 @@ free_old_inbuf(connection_t *conn)
 }
 #endif
 
+#ifdef MS_WINDOWS
+/** Remove the kernel-space send and receive buffers for <b>s</b>. For use
+ * with IOCP only. */
+static int
+set_buffer_lengths_to_zero(tor_socket_t s)
+{
+  int zero = 0;
+  int r = 0;
+  if (setsockopt(s, SOL_SOCKET, SO_SNDBUF, (void*)&zero, sizeof(zero))) {
+    log_warn(LD_NET, "Unable to clear SO_SNDBUF");
+    r = -1;
+  }
+  if (setsockopt(s, SOL_SOCKET, SO_RCVBUF, (void*)&zero, sizeof(zero))) {
+    log_warn(LD_NET, "Unable to clear SO_RCVBUF");
+    r = -1;
+  }
+  return r;
+}
+#endif
+
 /** Add <b>conn</b> to the array of connections that we can poll on.  The
  * connection's socket must be set; the connection starts out
  * non-reading and non-writing.
@@ -216,6 +236,14 @@ connection_add_impl(connection_t *conn, int is_connecting)
 #ifdef USE_BUFFEREVENTS
   if (connection_type_uses_bufferevent(conn)) {
     if (SOCKET_OK(conn->s) && !conn->linked) {
+
+#ifdef MS_WINDOWS
+      if (tor_libevent_using_iocp_bufferevents() &&
+          get_options()->UserspaceIOCPBuffers) {
+        set_buffer_lengths_to_zero(conn->s);
+      }
+#endif
+
       conn->bufev = bufferevent_socket_new(
                          tor_libevent_get_base(),
                          conn->s,

+ 5 - 0
src/or/or.h

@@ -3432,6 +3432,11 @@ typedef struct {
    * never use it.  If -1, we do what the consensus says. */
   int OptimisticData;
 
+  /** If 1, and we are using IOCP, we set the kernel socket SNDBUF and RCVBUF
+   * to 0 to try to save kernel memory and avoid the dread "Out of buffers"
+   * issue. */
+  int UserspaceIOCPBuffers;
+
 } or_options_t;
 
 /** Persistent state for an onion router, as saved to disk. */