[tor-commits] [ooni-probe/master] Make important refactoring to various parts.

art at torproject.org art at torproject.org
Tue Nov 6 14:54:15 UTC 2012


commit 46133a4a1cdc03e741f00c57f2d53fe20095827f
Author: Arturo Filastò <arturo at filasto.net>
Date:   Tue Nov 6 15:53:45 2012 +0100

    Make important refactoring to various parts.
    * Fix bug in captive portal test
---
 nettests/core/captiveportal.py |    5 +-
 nettests/echo.py               |    4 +-
 ooni/__init__.py               |    4 +-
 ooni/config.py                 |    7 ---
 ooni/lib/txscapy.py            |   50 ++++++++++---------
 ooni/oconfig.py                |    1 +
 ooni/runner.py                 |    2 +-
 ooni/templates/scapyt.py       |  108 +++++++++++++++++++++++++++++++++++----
 8 files changed, 132 insertions(+), 49 deletions(-)

diff --git a/nettests/core/captiveportal.py b/nettests/core/captiveportal.py
index fdc37a0..6641985 100644
--- a/nettests/core/captiveportal.py
+++ b/nettests/core/captiveportal.py
@@ -65,7 +65,8 @@ class CaptivePortal(nettest.NetTestCase):
 
     name = "captivep"
     description = "Captive Portal Test"
-    requirements = None
+    version = '0.1'
+    author = "Isis LoveCruft <isis at torproject.org>"
 
     def http_fetch(self, url, headers={}):
         """
@@ -636,5 +637,3 @@ class CaptivePortal(nettest.NetTestCase):
         log.msg("")
         log.msg("Captive portal test finished!")
 
-        self.control(self.report)
-
diff --git a/nettests/echo.py b/nettests/echo.py
index bc47519..611970e 100644
--- a/nettests/echo.py
+++ b/nettests/echo.py
@@ -70,9 +70,9 @@ class EchoTest(ScapyTest):
             form (*ifa_name, AF_FAMILY, *ifa_addr)
         '''
 
-        if self.local_options:
+        if self.localOptions:
             log.debug("%s: local_options found" % self.name)
-            for key, value in self.local_options:
+            for key, value in self.localOptions.items():
                 log.debug("%s: setting self.%s = %s" % (key, value))
                 setattr(self, key, value)
 
diff --git a/ooni/__init__.py b/ooni/__init__.py
index f025d30..659d4af 100644
--- a/ooni/__init__.py
+++ b/ooni/__init__.py
@@ -1,4 +1,4 @@
-from . import config
+from . import oconfig
 from . import inputunit
 from . import kit
 from . import lib
@@ -14,7 +14,7 @@ from . import utils
 #from . import plugoo
 #from . import plugins
 
-__all__ = ['config', 'inputunit', 'kit',
+__all__ = ['oconfig', 'inputunit', 'kit',
            'lib', 'nettest', 'oonicli', 'reporter',
            'runner', 'templates', 'utils']
            # XXX below are legacy related modules
diff --git a/ooni/config.py b/ooni/config.py
deleted file mode 100644
index 96a1ee0..0000000
--- a/ooni/config.py
+++ /dev/null
@@ -1,7 +0,0 @@
-from ooni.utils import Storage
-
-# XXX move this to an actual configuration file
-basic = Storage()
-advanced = Storage()
-
-advanced.debug = True
diff --git a/ooni/lib/txscapy.py b/ooni/lib/txscapy.py
index 4446be0..dffda36 100644
--- a/ooni/lib/txscapy.py
+++ b/ooni/lib/txscapy.py
@@ -18,7 +18,6 @@ import time
 
 from twisted.internet import protocol, base, fdesc, error, defer
 from twisted.internet import reactor, threads
-from twisted.python import log
 from zope.interface import implements
 
 from scapy.all import Gen
@@ -77,7 +76,7 @@ class ScapySocket(object):
         else:
             return self.ssocket.recv(self.MTU)
 
-class Scapy(object):
+class TXScapy(object):
     """
     A twisted based wrapper for scapy send and receive functionality.
 
@@ -90,12 +89,12 @@ class Scapy(object):
     write_only_answers = False
     pcapwriter = None
     recv = False
+    timeout_call = None
+    answers = []
+    questions = []
 
     def __init__(self, pkts=None, maxPacketSize=8192, reactor=None, filter=None,
             iface=None, nofilter=None, pcapfile=None, timeout=None, *arg, **kw):
-        if self.debug:
-            log.startLogging(sys.stdout)
-
         self.maxPacketSize = maxPacketSize
         if not reactor:
             from twisted.internet import reactor
@@ -173,13 +172,15 @@ class Scapy(object):
         @param question: the sent packet that matches that response.
 
         """
-
         if self.pcapwriter and self.write_only_answers:
             self.pcapwriter.write(question)
             self.pcapwriter.write(answer)
+            self.answers.append(answers)
+            self.questions.append(question)
         self.answer_count += 1
-        if self.answer_count >= self.total_count:
-            print "Got all the answers I need"
+        if self.answer_count >= self.total_count and self.running:
+            log.debug("Got all the answers I need")
+            self.finalClose()
             self.deferred.callback(None)
 
     def processAnswer(self, pkt, hlst):
@@ -211,7 +212,6 @@ class Scapy(object):
         """
         pkt.show()
 
-
     def doRead(self):
         """
         There is something to be read on the wire. Do all the processing on the
@@ -262,10 +262,13 @@ class Scapy(object):
         self.socket.send(pkt)
 
     def timeout(self, *arg, **kw):
-        log.debug("Caught a timeout with %s %s" % (arg, kw))
         if not self.done:
-            self._reactor.callLater(self.timeoutSeconds, self.timeout, None)
-        else:
+            log.debug("I have not finished. Setting to call in %s" %
+                    self.timeoutSeconds)
+            self.timeout_call = self._reactor.callLater(self.timeoutSeconds, self.timeout, None)
+        elif self.running:
+            log.debug("Cancelling timeout call")
+            self.finalClose()
             self.deferred.callback(None)
 
     def sr(self, pkts, filter=None, iface=None, nofilter=0, timeout=None, *args, **kw):
@@ -287,11 +290,11 @@ class Scapy(object):
         @param filter:   provide a BPF filter
         @param iface:    listen answers only on the given interface
         """
-        log.debug("Calling with %s" % pkts)
+        log.debug("TXScapy sending and receiving packets")
         self.recv = True
         if timeout:
             self.timeoutSeconds = timeout
-            self._reactor.callLater(timeout, self.timeout, None)
+            self.timeout_call = self._reactor.callLater(timeout, self.timeout, None)
         self._sendrcv(pkts, filter=filter, iface=iface, nofilter=nofilter)
 
     def send(self, pkts, filter=None, iface=None, nofilter=0, *args, **kw):
@@ -327,7 +330,8 @@ class Scapy(object):
                     pkt = self.outqueue.pop()
                 except:
                     self.done = True
-                    if not self.recv:
+                    if not self.recv and self.running:
+                        log.debug("I am not in receiving state running callback")
                         self.deferred.callback(None)
                     return
                 d = threads.deferToThreadPool(reactor, self.threadpool,
@@ -353,25 +357,25 @@ class Scapy(object):
 
     def finalClose(self):
         """
-        Clean all the thread related stuff up.
+        Clean all the shutdown related functions.
         """
         self.shutdownID = None
         self.threadpool.stop()
+        if self.timeout_call:
+            self.timeout_call.cancel()
+            self.timeout_call = None
         self.running = False
 
 @defer.inlineCallbacks
-def txsr(*arg, **kw):
-    tr = Scapy(*arg, **kw)
-    log.debug("Calling sr with %s, %s" % (arg, kw))
-    tr.sr(*arg, **kw)
+def txsr(*args, **kw):
+    tr = TXScapy(*args, **kw)
+    tr.sr(*args, **kw)
     yield tr.deferred
     tr.finalClose()
 
 @defer.inlineCallbacks
 def txsend(*arg, **kw):
-    tr = Scapy(**kw)
-    log.debug("Calling send with %s, %s" % (arg, kw))
+    tr = TXScapy(*arg, **kw)
     tr.send(*arg, **kw)
     yield tr.deferred
     tr.finalClose()
-
diff --git a/ooni/oconfig.py b/ooni/oconfig.py
index 96a1ee0..202b569 100644
--- a/ooni/oconfig.py
+++ b/ooni/oconfig.py
@@ -2,6 +2,7 @@ from ooni.utils import Storage
 
 # XXX move this to an actual configuration file
 basic = Storage()
+basic.logfile = '/tmp/ooniprobe.log'
 advanced = Storage()
 
 advanced.debug = True
diff --git a/ooni/runner.py b/ooni/runner.py
index e1ecaac..97b4003 100644
--- a/ooni/runner.py
+++ b/ooni/runner.py
@@ -205,7 +205,7 @@ class ORunner(object):
 
         try:
             reportFile = open(config['reportfile'], 'a+')
-        except:
+        except TypeError:
             filename = 'report_'+date.timestamp()+'.yaml'
             reportFile = open(filename, 'a+')
         self.reporterFactory = ReporterFactory(reportFile,
diff --git a/ooni/templates/scapyt.py b/ooni/templates/scapyt.py
index 8751587..9e18fbd 100644
--- a/ooni/templates/scapyt.py
+++ b/ooni/templates/scapyt.py
@@ -7,14 +7,14 @@ import random
 from zope.interface import implements
 from twisted.python import usage
 from twisted.plugin import IPlugin
-from twisted.internet import protocol, defer
+from twisted.internet import protocol, defer, threads
 
-from scapy.all import IP, TCP
+from scapy.all import IP, TCP, send, sr
 
 from ooni.nettest import NetTestCase
 from ooni.utils import log
 
-from ooni.lib.txscapy import txsr, txsend
+from ooni.lib.txscapy import TXScapy
 
 class ScapyTest(NetTestCase):
     """
@@ -31,30 +31,116 @@ class ScapyTest(NetTestCase):
 
     receive = True
     timeout = 1
-    pcapfile = None
+    pcapfile = 'packet_capture.pcap'
     packet = IP()/TCP()
     reactor = None
+
+    answered = None
+    unanswered = None
+
+
     def setUp(self):
         if not self.reactor:
             from twisted.internet import reactor
             self.reactor = reactor
-        self.request = {}
-        self.response = {}
+        self.questions = []
+        self.answers = []
+        self.processInputs()
+
+    def processInputs(self):
+        """
+        Place here the logic for validating and processing of inputs and
+        command line arguments.
+        """
+        pass
 
     def tearDown(self):
-        self.reactor.stop()
+        log.debug("Tearing down reactor")
+
+    def finished(self, *arg):
+        log.debug("Calling final close")
+
+        self.questions = self.txscapy.questions
+        self.answers = self.txscapy.answers
+
+        log.debug("These are the questions: %s" % self.questions)
+        log.debug("These are the answers: %s" % self.answers)
+
+        self.txscapy.finalClose()
+
+    def sendReceivePackets(self):
+        packets = self.buildPackets()
 
-    def sendReceivePackets(self, *kw):
-        d = txsr(self.request, pcapfile=self.pcapfile,
+        log.debug("Sending and receiving %s" % packets)
+
+        self.txscapy = TXScapy(packets, pcapfile=self.pcapfile,
+                          timeout=self.timeout, reactor=self.reactor)
+
+        self.txscapy.sr(packets, pcapfile=self.pcapfile,
                  timeout=self.timeout, reactor=self.reactor)
+
+        d = self.txscapy.deferred
+        d.addCallback(self.finished)
+
+        return d
+
+    def sendPackets(self):
+        log.debug("Sending and receiving of packets %s" % packets)
+
+        packets = self.buildPackets()
+
+        self.txscapy = TXScapy(packets, pcapfile=self.pcapfile,
+                          timeout=self.timeout, reactor=self.reactor)
+
+        self.txscapy.send(packets, reactor=self.reactor).deferred
+
+        d = self.txscapy.deferred
+        d.addCallback(self.finished)
+
         return d
 
+    def buildPackets(self):
+        """
+        Override this method to build scapy packets.
+        """
+        pass
+
+class BlockingScapyTest(ScapyTest):
+    """
+    This is a very basic Scapy Test template that does not do all the
+    multithreading kung-fu of txscapy, but maintains the same API.
+
+    This will allow tests implemented using the BlockingScapyTest API to easily
+    migrate to the new API.
+    """
+    name = "Blocking Scapy Test"
+    version = 0.1
+
+    timeout = None
+
+    answered = None
+    unanswered = None
+
+    def sendReceivePackets(self):
+        packets = self.buildPackets()
+
+        log.debug("Sending and receiving %s" % packets)
+
+        self.answered, self.unanswered = sr(packets, timeout=self.timeout)
+
+        log.debug("%s %s" % (ans, unans))
+
     def sendPackets(self):
-        return txsend(self.buildPackets(), reactor=self.reactor)
+        packets = self.buildPackets()
+
+        log.debug("Sending packets %s" % packets)
+
+        send(packets)
+
 
     def buildPackets(self):
         """
         Override this method to build scapy packets.
         """
-        return self.packet
+        pass
 



More information about the tor-commits mailing list