[tor-commits] [ooni-probe/master] Implement parts of OONI Backend.

art at torproject.org art at torproject.org
Thu May 31 03:01:42 UTC 2012


commit c0423382890576b92bb55121bfbc394ad941cf98
Author: Arturo Filastò <hellais at torproject.org>
Date:   Mon May 28 23:40:13 2012 +0200

    Implement parts of OONI Backend.
    * Write an HTTP server that replies with the headers sent by the browser
    * Write a Proxy DNS server that proxies requests and writes to log
---
 backend/dnsbackend.py  |   16 ++++++++++
 backend/httpbackend.py |   74 ++++++++++++++++++++++++++++++++++++++++++++++++
 backend/oonibackend.py |   34 ++++++++++++++++++++++
 plugoo/tests.py        |   16 ++--------
 4 files changed, 128 insertions(+), 12 deletions(-)

diff --git a/backend/__init__.py b/backend/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/backend/dnsbackend.py b/backend/dnsbackend.py
new file mode 100644
index 0000000..689d1a4
--- /dev/null
+++ b/backend/dnsbackend.py
@@ -0,0 +1,16 @@
+from twisted.internet.protocol import Factory, Protocol
+from twisted.internet import reactor
+from twisted.names import dns
+from twisted.names import client, server
+
+class ProxyDNSServer(server.DNSServerFactory):
+    def __init__(self, authorities = None,
+                 caches = None, clients = None,
+                 verbose = 0):
+        resolver = client.Resolver(servers=[('8.8.8.8', 53)])
+        server.DNSServerFactory.__init__(self, authorities = authorities,
+                                         caches = caches, clients = [resolver],
+                                         verbose = verbose)
+    def handleQuery(self, message, protocol, address):
+        print message, protocol, address
+        server.DNSServerFactory.handleQuery(self, message, protocol, address)
diff --git a/backend/httpbackend.py b/backend/httpbackend.py
new file mode 100644
index 0000000..79a487b
--- /dev/null
+++ b/backend/httpbackend.py
@@ -0,0 +1,74 @@
+import json
+import random
+import string
+
+from twisted.application import internet, service
+from twisted.internet import protocol, reactor, defer
+from twisted.protocols import basic
+from twisted.web import resource, server, static
+from twisted.web.microdom import escape
+
+server.version = "Apache"
+
+class HTTPRandomPage(resource.Resource):
+    """
+    This generates a random page of arbitrary length and containing the string
+    selected by the user.
+    The format is the following:
+    /random/<length>/<keyword>
+    """
+    isLeaf = True
+    def _gen_random_string(self, length):
+        return ''.join(random.choice(string.letters) for x in range(length))
+
+    def genRandomPage(self, length=100, keyword=None):
+        data = self._gen_random_string(length/2)
+        if keyword:
+            data += keyword
+        data += self._gen_random_string(length - length/2)
+        data += '\n'
+        return data
+
+    def render(self, request):
+        length = 100
+        keyword = None
+        path_parts = request.path.split('/')
+        if len(path_parts) > 2:
+            length = int(path_parts[2])
+            if length > 100000:
+                length = 100000
+
+        if len(path_parts) > 3:
+            keyword = escape(path_parts[3])
+
+        return self.genRandomPage(length, keyword)
+
+class HTTPReturnHeaders(resource.Resource):
+    """
+    This returns the headers being sent by the client in JSON format.
+    """
+    isLeaf = True
+    def render(self, request):
+        req_headers = request.getAllHeaders()
+        return json.dumps(req_headers)
+
+class HTTPSendHeaders(resource.Resource):
+    """
+    This sends to the client the headers that they send inside of the POST
+    request encoded in json.
+    """
+    isLeaf = True
+    def render_POST(self, request):
+        headers = json.loads(request.content.read())
+        for header, value in headers.items():
+            request.setHeader(str(header), str(value))
+        return ''
+
+class HTTPBackend(resource.Resource):
+    def __init__(self):
+        resource.Resource.__init__(self)
+        self.putChild('random', HTTPRandomPage())
+        self.putChild('returnheaders', HTTPReturnHeaders())
+        self.putChild('sendheaders', HTTPSendHeaders())
+
+
diff --git a/backend/oonibackend.py b/backend/oonibackend.py
new file mode 100644
index 0000000..774a9c5
--- /dev/null
+++ b/backend/oonibackend.py
@@ -0,0 +1,34 @@
+"""
+    ooni backend
+    ************
+
+    This is the backend system responsible for running certain services that
+    are useful for censorship detection.
+"""
+import json
+import random
+import string
+
+from twisted.application import internet, service
+from twisted.internet import protocol, reactor, defer
+from twisted.protocols import basic
+from twisted.web import resource, server, static
+from twisted.web.microdom import escape
+from twisted.names import dns
+
+from backend.httpbackend import HTTPBackend
+from backend.dnsbackend import ProxyDNSServer
+
+# This tells twisted to set the
+server.version = "Apache"
+
+application = service.Application('oonibackend')
+serviceCollection = service.IServiceCollection(application)
+internet.TCPServer(8000, server.Site(HTTPBackend())).setServiceParent(serviceCollection)
+
+# Start the DNS Server related services
+TCPDNSServer = ProxyDNSServer()
+internet.TCPServer(8002, TCPDNSServer).setServiceParent(serviceCollection)
+UDPFactory = dns.DNSDatagramProtocol(TCPDNSServer)
+internet.UDPServer(5353, UDPFactory).setServiceParent(serviceCollection)
+
diff --git a/plugoo/tests.py b/plugoo/tests.py
index 39adfa2..09363a2 100644
--- a/plugoo/tests.py
+++ b/plugoo/tests.py
@@ -186,20 +186,16 @@ class TwistedTest(object):
         result['start_time'] = self.start_time
         result['end_time'] = self.end_time
         result['run_time'] = self.end_time - self.start_time
-        return self.d.callback(result)
 
     def _do_experiment(self):
-        self.d_experiment = defer.Deferred()
-        self.d_experiment.addCallback(self._do_control)
-        self.experiment()
+        self.d = defer.maybeDeferred(self.experiment)
+        self.d.addCallback(self.control)
+        self.d.addCallback(self.finished)
         return self.d
 
-    def _do_control(self, exp):
-        self.control(exp)
-        self.finished(dict())
-
     def control(self, exp):
         print "Doing control..."
+        self.d.callback(result)
 
     def experiment(self):
         print "Doing experiment"
@@ -207,10 +203,6 @@ class TwistedTest(object):
 
     def startTest(self):
         print "Starting test %s" % repr(self)
-        self.d = defer.Deferred()
-        result = {}
-        #reactor.callLater(2.0, self.finished, result)
-        # Start experiment
         return self._do_experiment()
 
 class TwistedTestFactory(object):





More information about the tor-commits mailing list