[or-cvs] r18696: {} Add code for testing clogging attack: sending and receiving (in projects/relay-protection: . src)

sjm217 at seul.org sjm217 at seul.org
Thu Feb 26 14:33:43 UTC 2009


Author: sjm217
Date: 2009-02-26 09:33:41 -0500 (Thu, 26 Feb 2009)
New Revision: 18696

Added:
   projects/relay-protection/src/
   projects/relay-protection/src/bulk-downloader.py
   projects/relay-protection/src/bulk-sender.py
   projects/relay-protection/src/controller.py
Log:
Add code for testing clogging attack: sending and receiving data

Added: projects/relay-protection/src/bulk-downloader.py
===================================================================
--- projects/relay-protection/src/bulk-downloader.py	                        (rev 0)
+++ projects/relay-protection/src/bulk-downloader.py	2009-02-26 14:33:41 UTC (rev 18696)
@@ -0,0 +1,77 @@
+#!/usr/bin/python
+
+import sys
+import threading
+import socket
+import time
+import random
+from controller import DownloadController
+from socksipy import socks
+
+NUM_THREADS = 5
+INTERVAL_SEC = 1
+SOCKET_ADDR = ('localhost', 9003)
+USE_SOCKS = True
+THREAD_LIFETIME = 60
+
+class DownloaderThread(threading.Thread):
+
+    def __init__(self, controller, thread_id):
+        threading.Thread.__init__(self)
+        self.thread_id = thread_id
+        self.controller = controller
+        self.sock = None
+        self.thread_data = 0
+        self.thread_end_time = None
+
+    def run(self):
+        while True:
+            try:
+                if self.sock == None:
+                    if USE_SOCKS:
+                        self.sock = socks.socksocket()
+                        self.sock.setproxy(socks.PROXY_TYPE_SOCKS5, "localhost", 9050)
+                    else:
+                        self.sock = socket.socket()
+
+                    self.thread_data = 0
+                    self.thread_end_time = time.time() + THREAD_LIFETIME + random.randint(-10, 10)
+                    self.sock.connect(SOCKET_ADDR)
+
+                data = self.sock.recv(498)
+                self.thread_data += len(data)
+                self.controller.got_data(len(data), self.thread_id)
+
+                if len(data) == 0 or time.time() >= self.thread_end_time:
+                    self.sock.close()
+                    self.sock = None
+            except (socket.error, socks.ProxyError), e:
+                print >>sys.stderr, "Socket error %s"%repr(e)
+                try:
+                    self.sock.close()
+                except Exception:
+                    pass
+                self.sock = None
+                time.sleep(1)
+        
+def download_data(controller):
+    while True:
+        print controller.stats()
+        time.sleep(INTERVAL_SEC)
+        
+def main():
+    controller = DownloadController()
+    for i in range(NUM_THREADS):
+        t = DownloaderThread(controller, i)
+        t.start()
+
+    try:
+        download_data(controller)
+    except KeyboardInterrupt, e:
+        pass
+    
+    sys.exit()
+
+if __name__=="__main__":
+    main()
+    


Property changes on: projects/relay-protection/src/bulk-downloader.py
___________________________________________________________________
Added: svn:executable
   + *

Added: projects/relay-protection/src/bulk-sender.py
===================================================================
--- projects/relay-protection/src/bulk-sender.py	                        (rev 0)
+++ projects/relay-protection/src/bulk-sender.py	2009-02-26 14:33:41 UTC (rev 18696)
@@ -0,0 +1,70 @@
+#!/usr/bin/python
+
+import socket
+import threading
+import SocketServer
+import sys
+import time
+from controller import DownloadController
+
+DATA_LEN = 498
+INTERVAL_SEC = 1
+
+class ThreadedTCPRequestHandler(SocketServer.BaseRequestHandler):
+    def handle(self):
+        print >>sys.stderr, "Incoming connection from %s"%repr(self.client_address)
+        controller = self.server.download_controller
+        while True:
+            while controller.keep_running():
+                try:
+                    data = self.request.send("0" * DATA_LEN)
+                except socket.error:
+                    return
+
+                controller.got_data(DATA_LEN, threading.currentThread().getName())
+            controller.wait()
+
+class ThreadedTCPServer(SocketServer.ThreadingMixIn, SocketServer.TCPServer):
+    def __init__(self, sa, handler, controller):
+        self.download_controller = controller
+        SocketServer.TCPServer.__init__(self, sa, handler)
+
+def simulate_load(controller):
+    controller.go()
+
+    is_on = True
+    trigger = time.time() + 20
+    while True:
+        t = time.time()
+        if t >= trigger:
+            if is_on:
+                print "stopping"
+                controller.stop()
+                is_on = False
+            else:
+                print "starting"
+                controller.go()
+                is_on = True
+            trigger = t + 20
+            
+        print controller.stats()
+        time.sleep(INTERVAL_SEC)
+
+def main():
+    HOST, PORT = "0.0.0.0", 9003
+
+    controller = DownloadController()
+    server = ThreadedTCPServer((HOST, PORT), ThreadedTCPRequestHandler, controller)
+    ip, port = server.server_address
+
+    server_thread = threading.Thread(target=server.serve_forever)
+    server_thread.start()
+
+    try:
+        simulate_load(controller)
+    except KeyboardInterrupt, e:
+        pass
+    sys.exit()
+
+if __name__ == "__main__":
+    main()


Property changes on: projects/relay-protection/src/bulk-sender.py
___________________________________________________________________
Added: svn:executable
   + *

Added: projects/relay-protection/src/controller.py
===================================================================
--- projects/relay-protection/src/controller.py	                        (rev 0)
+++ projects/relay-protection/src/controller.py	2009-02-26 14:33:41 UTC (rev 18696)
@@ -0,0 +1,66 @@
+import threading
+import time
+
+class DownloadController:
+
+    def __init__(self):
+        self.condition = threading.Condition()
+        self.running = False
+        
+        self.last_time = None
+        self.last_data = None
+        self.total_data = 0
+
+        self.lock = threading.Lock()
+
+    def go(self):
+        self.condition.acquire()
+        self.running = True
+        self.condition.notifyAll()
+        self.condition.release()
+
+    def wait(self):
+        self.condition.acquire()
+        self.condition.wait()
+        self.condition.release()
+
+    def stop(self):
+        self.condition.acquire()
+        self.running = False
+        self.condition.release()
+
+    def keep_running(self):
+        return self.running
+
+    def got_data(self, amount, thread_id):
+        self.lock.acquire()
+        self.total_data += amount
+        self.lock.release()
+            
+        #print "Thread %s got %s bytes"%(thread_id, amount)
+
+    def format_number(self, number, factor=1024):
+        if number != None:
+            return "%2.2f"%(float(number)/factor)
+        else:
+            return "N/A"
+            
+    def stats(self):
+        t = time.time()
+        self.lock.acquire()
+        if self.last_time == None:
+            delta_t = delta_b = rate = None
+        else:
+            delta_t = t - self.last_time
+            delta_b = self.total_data - self.last_data
+            rate = delta_b / delta_t
+            
+        self.last_time = t
+        self.last_data = self.total_data
+        self.lock.release()
+
+        period = self.format_number(delta_t, 1)
+        rate = self.format_number(rate)
+        total = self.format_number(self.last_data)
+            
+        return "Data rate in last %s seconds: %s kB/s. Total data %s kB"%(period, rate, total)



More information about the tor-commits mailing list