[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

constrained socket buffers patch



hi Andrew, all,

attached is the constrained sockets patch.  apologies for the delay;
still have DSL problems at home.

to enable this feature set:

ConstrainedSockets 1

in your configuration.  this will limit the recv and xmit buffers
associated with TCP sockets to the default 4096 bytes.  you can also
alter the default explicitly via:

ConstrainedSockSize 2048

the value must be between 2048 and 262144 in 1024 byte increments.
attempting to set an invalid value should produce an error at start.
see the (patched) man page for additional details.

to patch:
cd tor-0.1.2.14
patch -p1 < ../tor-constrained-sockets.patch

then build as usual (vary per your reqs):
./configure --prefix=/usr --sysconfdir=/etc && make && make install

let me know if this appears to work!  you may try adjusting the
buffers down as low as 2048 if you still get problems at 4096,
however, i don't think this is likely.

best regards,
diff -Naur orig-tor-0.1.2.14/doc/tor.1.in mod-tor-0.1.2.14/doc/tor.1.in
--- orig-tor-0.1.2.14/doc/tor.1.in	2007-05-25 00:51:42.000000000 +0000
+++ mod-tor-0.1.2.14/doc/tor.1.in	2007-07-11 21:20:33.000000000 +0000
@@ -88,6 +88,21 @@
 Windows since that platform lacks getrlimit(). (Default: 1000)
 .LP
 .TP
+\fBConstrainedSockets \fR\fB0\fR|\fB1\fR\fP
+If set, Tor will attempt to shrink the recv and xmit buffers for all
+sockets to the size specified in \fBConstrainedSockSize\fP.  This is useful
+for virtual servers and other environments where system level TCP
+buffers may be limited.  The preferred solution is to have the admin
+increase the buffer pool via /proc/sys/net/ipv4/tcp_mem or equivalent
+facility.  Note that this will not work on Windows platforms.
+.LP
+.TP
+\fBConstrainedSockSize \fR\fINUM\fP
+When \fBConstrainedSockets\fP is enabled the recv and xmit buffers for
+all sockets will be set to this limit.  Must be a value between 2048
+and 262144 in 1024 byte increments.  Default of 4096 is recommended.
+.LP
+.TP
 \fBControlPort \fR\fIPort\fP
 If set, Tor will accept connections on this port and allow those
 connections to control the Tor process using the Tor Control Protocol
diff -Naur orig-tor-0.1.2.14/src/or/config.c mod-tor-0.1.2.14/src/or/config.c
--- orig-tor-0.1.2.14/src/or/config.c	2007-05-25 00:51:40.000000000 +0000
+++ mod-tor-0.1.2.14/src/or/config.c	2007-07-11 21:14:18.000000000 +0000
@@ -139,6 +139,8 @@
   VAR("CircuitIdleTimeout",  INTERVAL, CircuitIdleTimeout,   "1 hour"),
   VAR("ClientOnly",          BOOL,     ClientOnly,           "0"),
   VAR("ConnLimit",           UINT,     ConnLimit,            "1000"),
+  VAR("ConstrainedSockets",  BOOL,     ConstrainedSockets,   "0"),
+  VAR("ConstrainedSockSize", UINT,     ConstrainedSockSize,  "4096"),
   VAR("ContactInfo",         STRING,   ContactInfo,          NULL),
   VAR("ControlListenAddress",LINELIST, ControlListenAddress, NULL),
   VAR("ControlPort",         UINT,     ControlPort,          "0"),
@@ -309,6 +311,10 @@
   { "BandwidthBurst", "Limit the maximum token buffer size (also known as "
     "burst) to the given number of bytes." },
   { "ConnLimit", "Maximum number of simultaneous sockets allowed." },
+  { "ConstrainedSockets", "Shrink tx and rx buffers for sockets to avoid "
+    "system limits on vservers and related environments." },
+  { "ConstrainedSockSize", "Limit socket buffers to this size when "
+    "ConstrainedSockets is set.  Must be at least 2048 bytes." },
   /*  ControlListenAddress */
   { "ControlPort", "If set, Tor will accept connections from the same machine "
     "(localhost only) on this port, and allow those connections to control "
@@ -2765,6 +2771,24 @@
     }
   }
 
+#ifndef MS_WINDOWS
+  if (options->ConstrainedSockets) {
+    /** If the user wants to constrain socket buffer use, make sure the desired
+     * limit is between 2k and 256k in k increments. */
+    const int minsocksz = 2*1024;
+    const int maxsocksz = 256*1024;
+    if (options->ConstrainedSockSize < minsocksz ||
+        options->ConstrainedSockSize > maxsocksz ||
+        options->ConstrainedSockSize % 1024 ) {
+      r = tor_snprintf(buf, sizeof(buf),
+          "ConstrainedSockSize is invalid.  Must be a value between %d and %d in 1024 byte increments.",
+          minsocksz, maxsocksz);
+      *msg = tor_strdup(r >= 0 ? buf : "internal error");
+      return -1;
+    }
+  }
+#endif
+
   if (rend_config_services(options, 1) < 0)
     REJECT("Failed to configure rendezvous options. See logs for details.");
 
diff -Naur orig-tor-0.1.2.14/src/or/connection.c mod-tor-0.1.2.14/src/or/connection.c
--- orig-tor-0.1.2.14/src/or/connection.c	2007-05-25 00:51:40.000000000 +0000
+++ mod-tor-0.1.2.14/src/or/connection.c	2007-07-11 21:47:00.000000000 +0000
@@ -27,6 +27,7 @@
 static int connection_read_to_buf(connection_t *conn, int *max_to_read);
 static int connection_process_inbuf(connection_t *conn, int package_partial);
 static void client_check_address_changed(int sock);
+static void set_constrained_socket_buffers(int sock, int size);
 
 static uint32_t last_interface_ip = 0;
 static smartlist_t *outgoing_addrs = NULL;
@@ -741,6 +742,8 @@
   /* length of the remote address. Must be whatever accept() needs. */
   socklen_t remotelen = 256;
   char tmpbuf[INET_NTOA_BUF_LEN];
+  or_options_t *options = get_options();
+
   tor_assert((size_t)remotelen >= sizeof(struct sockaddr_in));
   memset(addrbuf, 0, sizeof(addrbuf));
 
@@ -766,6 +769,12 @@
 
   set_socket_nonblocking(news);
 
+#ifndef MS_WINDOWS
+  if (options->ConstrainedSockets) {
+    set_constrained_socket_buffers (news, options->ConstrainedSockSize);
+  }
+#endif
+
   if (check_sockaddr_in((struct sockaddr*)addrbuf, remotelen, LOG_INFO)<0) {
     log_info(LD_NET,
              "accept() returned a strange address; trying getsockname().");
@@ -910,6 +919,12 @@
 
   set_socket_nonblocking(s);
 
+#ifndef MS_WINDOWS
+  if (options->ConstrainedSockets) {
+    set_constrained_socket_buffers (s, options->ConstrainedSockSize);
+  }
+#endif
+
   memset(&dest_addr,0,sizeof(dest_addr));
   dest_addr.sin_family = AF_INET;
   dest_addr.sin_port = htons(port);
@@ -2226,6 +2241,29 @@
   }
 }
 
+/** Some systems have limited system buffers for recv and xmit on
+ * sockets allocated in a virtual server or similar environment.  This
+ * method will attempt to constrain the buffers allocated to the socket
+ * to the desired size.  This should be a value between 2k and 256k.
+ * The preferred solution is to have the administrator set increased
+ * limits in /proc/sys/net/ipv4/tcp_mem or equivalent.
+ */
+static void
+set_constrained_socket_buffers(int sock, int size)
+{
+  if (setsockopt(sock, SOL_SOCKET, SO_SNDBUF, &size, sizeof(size)) < 0) {
+    int e = tor_socket_errno(sock);
+    log_warn(LD_NET, "setsockopt() to constrain send buffer to %d bytes failed: %s",
+             size, tor_socket_strerror(e));
+  }
+  if (setsockopt(sock, SOL_SOCKET, SO_RCVBUF, &size, sizeof(size)) < 0) {
+    int e = tor_socket_errno(sock);
+    log_warn(LD_NET, "setsockopt() to constrain recv buffer to %d bytes failed: %s",
+             size, tor_socket_strerror(e));
+  }
+  return;
+}
+
 /** Process new bytes that have arrived on conn-\>inbuf.
  *
  * This function just passes conn to the connection-specific
diff -Naur orig-tor-0.1.2.14/src/or/or.h mod-tor-0.1.2.14/src/or/or.h
--- orig-tor-0.1.2.14/src/or/or.h	2007-05-25 00:51:40.000000000 +0000
+++ mod-tor-0.1.2.14/src/or/or.h	2007-07-11 21:39:58.000000000 +0000
@@ -1678,6 +1678,9 @@
   config_line_t *ReachableORAddresses; /**< IP:ports for OR conns. */
   config_line_t *ReachableDirAddresses; /**< IP:ports for Dir conns. */
 
+  int ConstrainedSockets; /**< Shrink xmit and recv socket buffers. */
+  int ConstrainedSockSize; /**< Size of constrained buffers. */
+
   /** Application ports that require all nodes in circ to have sufficient
    * uptime. */
   smartlist_t *LongLivedPorts;