[tor-commits] [flashproxy/master] Give remote hosts 2 seconds to make their WebSocket request.

dcf at torproject.org dcf at torproject.org
Mon Apr 9 04:08:42 UTC 2012


commit d469ec913900395011245fb53b7a0a1bf139d1da
Author: David Fifield <david at bamsoftware.com>
Date:   Thu Mar 29 19:26:03 2012 -0700

    Give remote hosts 2 seconds to make their WebSocket request.
---
 connector.py |   26 ++++++++++++++++++++++++--
 1 files changed, 24 insertions(+), 2 deletions(-)

diff --git a/connector.py b/connector.py
index 07f0f3e..908f988 100755
--- a/connector.py
+++ b/connector.py
@@ -358,6 +358,9 @@ def format_peername(s):
     except socket.error, e:
         return "<unconnected>"
 
+# How long to wait for a WebSocket request on the remote socket. It is limited
+# to avoid Slowloris-like attacks.
+WEBSOCKET_REQUEST_TIMEOUT = 2.0
 
 class WebSocketRequestHandler(BaseHTTPServer.BaseHTTPRequestHandler):
     def __init__(self, request_text, fd):
@@ -601,6 +604,17 @@ def match_proxies():
         if remote.buf:
             local.send_chunk(remote.buf)
 
+class TimeoutSocket(object):
+    def __init__(self, fd):
+        self.fd = fd
+        self.birthday = time.time()
+
+    def age(self):
+        return time.time() - self.birthday
+
+    def __getattr__(self, name):
+        return getattr(self.fd, name)
+
 class RemoteSocket(object):
     def __init__(self, fd, protocols):
         self.fd = fd
@@ -635,12 +649,12 @@ class LocalSocket(object):
 def main():
     while True:
         rset = [remote_s, local_s] + websocket_pending + socks_pending + locals + remotes
-        rset, _, _ = select.select(rset, [], [])
+        rset, _, _ = select.select(rset, [], [], WEBSOCKET_REQUEST_TIMEOUT)
         for fd in rset:
             if fd == remote_s:
                 remote_c, addr = fd.accept()
                 log(u"Remote connection from %s." % format_addr(addr))
-                websocket_pending.append(remote_c)
+                websocket_pending.append(TimeoutSocket(remote_c))
             elif fd == local_s:
                 local_c, addr = fd.accept()
                 log(u"Local connection from %s." % format_addr(addr))
@@ -687,6 +701,14 @@ def main():
                         locals.remove(fd)
                     report_pending()
             match_proxies()
+        while websocket_pending:
+            pending = websocket_pending[0]
+            if pending.age() < WEBSOCKET_REQUEST_TIMEOUT:
+                break
+            log(u"Expired remote connection from %s." % format_peername(pending))
+            pending.close()
+            websocket_pending.pop(0)
+            report_pending()
 
 if __name__ == "__main__":
     opts, args = getopt.gnu_getopt(sys.argv[1:], "hl:", ["daemon", "help", "log=", "pidfile="])





More information about the tor-commits mailing list