[tor-commits] [ooni-probe/master] s/b0wser/daphn3/i

art at torproject.org art at torproject.org
Fri Jul 20 23:29:14 UTC 2012


commit 29dccd1f44b895d674079d085207e4e71b43beac
Author: Arturo Filastò <art at torproject.org>
Date:   Sat Jul 21 01:30:03 2012 +0200

    s/b0wser/daphn3/i
    because greek mythology is cooler than video games!
---
 ooni/plugins/b0wser.py   |  100 ----------------
 ooni/plugins/daphn3.py   |  100 ++++++++++++++++
 ooni/protocols/b0wser.py |  284 ----------------------------------------------
 ooni/protocols/daphn3.py |  284 ++++++++++++++++++++++++++++++++++++++++++++++
 oonib/b0wser.py          |   33 ------
 oonib/daphn3.py          |   33 ++++++
 oonib/oonibackend.py     |    6 +-
 7 files changed, 420 insertions(+), 420 deletions(-)

diff --git a/ooni/plugins/b0wser.py b/ooni/plugins/b0wser.py
deleted file mode 100644
index 3121378..0000000
--- a/ooni/plugins/b0wser.py
+++ /dev/null
@@ -1,100 +0,0 @@
-"""
-This is a self genrated test created by scaffolding.py.
-you will need to fill it up with all your necessities.
-Safe hacking :).
-"""
-from zope.interface import implements
-from twisted.python import usage
-from twisted.plugin import IPlugin
-from twisted.internet import protocol, endpoints
-
-from ooni.plugoo.tests import ITest, OONITest
-from ooni.plugoo.assets import Asset
-from ooni.protocols import b0wser
-from ooni.utils import log
-
-class B0wserClientProtocol(b0wser.B0wserProtocol):
-    def connectionMade(self):
-        self.next_state()
-
-    def connectionLost(self, reason):
-        print "LOST!"
-
-class B0wserClientFactory(protocol.ClientFactory):
-    protocol = B0wserClientProtocol
-    mutator = None
-    steps = None
-
-    def buildProtocol(self, addr):
-        p = self.protocol()
-        p.factory = self
-        if self.steps:
-            p.steps = self.steps
-
-        if not self.mutator:
-            self.mutator = b0wser.Mutator(p.steps)
-            p.mutator = self.mutator
-        else:
-            print "Moving on to next mutation"
-            self.mutator.next_mutation()
-        return p
-
-    def clientConnectionFailed(self, reason):
-        print "We failed connecting the the OONIB"
-        print "Cannot perform test. Perhaps it got blocked?"
-        print "Please report this to tor-assistants at torproject.org"
-
-    def clientConnectionLost(self, reason):
-        print "Connection Lost."
-
-class b0wserArgs(usage.Options):
-    optParameters = [['pcap', 'f', None, 'PCAP file to take as input'],
-                     ['host', 'h', None, 'Target Hostname'],
-                     ['port', 'p', None, 'Target port number'],
-                     ['resume', 'r', 0, 'Resume at this index']]
-
-class b0wserTest(OONITest):
-    implements(IPlugin, ITest)
-
-    shortName = "b0wser"
-    description = "b0wser"
-    requirements = None
-    options = b0wserArgs
-    blocking = False
-
-    local_options = None
-
-    steps = None
-    def initialize(self):
-        if not self.local_options:
-            return
-        #pass
-        self.factory = B0wserClientFactory()
-        self.steps = b0wser.get_b0wser_dictionary_from_pcap(self.local_options['pcap'])
-
-    def control(self, exp_res, args):
-        mutation = self.factory.mutator.get_mutation(0)
-        return {'mutation_number': args['mutation'], 'value': mutation}
-
-    def experiment(self, args):
-        log.msg("Doing mutation %s" % args['mutation'])
-        self.factory.steps = self.steps
-        host = self.local_options['host']
-        port = int(self.local_options['port'])
-        log.msg("Connecting to %s:%s" % (host, port))
-        endpoint = endpoints.TCP4ClientEndpoint(self.reactor, host, port)
-        return endpoint.connect(self.factory)
-        #return endpoint.connect(B0wserClientFactory)
-
-    def load_assets(self):
-        if not self.steps:
-            print "No asset!"
-            return {}
-        mutations = 0
-        for x in self.steps:
-            mutations += len(x['data'])
-        return {'mutation': range(mutations)}
-
-# We need to instantiate it otherwise getPlugins does not detect it
-# XXX Find a way to load plugins without instantiating them.
-b0wsertest = b0wserTest(None, None, None)
diff --git a/ooni/plugins/daphn3.py b/ooni/plugins/daphn3.py
new file mode 100644
index 0000000..6dd9da2
--- /dev/null
+++ b/ooni/plugins/daphn3.py
@@ -0,0 +1,100 @@
+"""
+This is a self genrated test created by scaffolding.py.
+you will need to fill it up with all your necessities.
+Safe hacking :).
+"""
+from zope.interface import implements
+from twisted.python import usage
+from twisted.plugin import IPlugin
+from twisted.internet import protocol, endpoints
+
+from ooni.plugoo.tests import ITest, OONITest
+from ooni.plugoo.assets import Asset
+from ooni.protocols import daphn3
+from ooni.utils import log
+
+class Daphn3ClientProtocol(daphn3.Daphn3Protocol):
+    def connectionMade(self):
+        self.next_state()
+
+    def connectionLost(self, reason):
+        print "LOST!"
+
+class Daphn3ClientFactory(protocol.ClientFactory):
+    protocol = Daphn3ClientProtocol
+    mutator = None
+    steps = None
+
+    def buildProtocol(self, addr):
+        p = self.protocol()
+        p.factory = self
+        if self.steps:
+            p.steps = self.steps
+
+        if not self.mutator:
+            self.mutator = daphn3.Mutator(p.steps)
+            p.mutator = self.mutator
+        else:
+            print "Moving on to next mutation"
+            self.mutator.next_mutation()
+        return p
+
+    def clientConnectionFailed(self, reason):
+        print "We failed connecting the the OONIB"
+        print "Cannot perform test. Perhaps it got blocked?"
+        print "Please report this to tor-assistants at torproject.org"
+
+    def clientConnectionLost(self, reason):
+        print "Connection Lost."
+
+class daphn3Args(usage.Options):
+    optParameters = [['pcap', 'f', None, 'PCAP file to take as input'],
+                     ['host', 'h', None, 'Target Hostname'],
+                     ['port', 'p', None, 'Target port number'],
+                     ['resume', 'r', 0, 'Resume at this index']]
+
+class daphn3Test(OONITest):
+    implements(IPlugin, ITest)
+
+    shortName = "daphn3"
+    description = "daphn3"
+    requirements = None
+    options = daphn3Args
+    blocking = False
+
+    local_options = None
+
+    steps = None
+    def initialize(self):
+        if not self.local_options:
+            return
+        #pass
+        self.factory = Daphn3ClientFactory()
+        self.steps = daphn3.get_daphn3_dictionary_from_pcap(self.local_options['pcap'])
+
+    def control(self, exp_res, args):
+        mutation = self.factory.mutator.get_mutation(0)
+        return {'mutation_number': args['mutation'], 'value': mutation}
+
+    def experiment(self, args):
+        log.msg("Doing mutation %s" % args['mutation'])
+        self.factory.steps = self.steps
+        host = self.local_options['host']
+        port = int(self.local_options['port'])
+        log.msg("Connecting to %s:%s" % (host, port))
+        endpoint = endpoints.TCP4ClientEndpoint(self.reactor, host, port)
+        return endpoint.connect(self.factory)
+        #return endpoint.connect(Daphn3ClientFactory)
+
+    def load_assets(self):
+        if not self.steps:
+            print "No asset!"
+            return {}
+        mutations = 0
+        for x in self.steps:
+            mutations += len(x['data'])
+        return {'mutation': range(mutations)}
+
+# We need to instantiate it otherwise getPlugins does not detect it
+# XXX Find a way to load plugins without instantiating them.
+daphn3test = daphn3Test(None, None, None)
diff --git a/ooni/protocols/b0wser.py b/ooni/protocols/b0wser.py
deleted file mode 100644
index 5d55c94..0000000
--- a/ooni/protocols/b0wser.py
+++ /dev/null
@@ -1,284 +0,0 @@
-from twisted.internet import protocol, defer
-from twisted.internet.error import ConnectionDone
-
-from ooni.utils import log
-from ooni.plugoo import reports
-
-import sys
-from scapy.all import *
-import yaml
-
-def get_b0wser_dictionary_from_pcap(filename):
-    """
-    @param filename: Filesystem path to the pcap.
-
-    Returns:
-      [{"sender": "client", "data": "\x17\x52\x15"}, {"sender": "server", "data": "\x17\x15\x13"}]
-    """
-    packets = rdpcap(filename)
-
-    checking_first_packet = True
-    client_ip_addr = None
-    server_ip_addr = None
-
-    ssl_packets = []
-    messages = []
-
-    """
-    pcap assumptions:
-
-    pcap only contains packets exchanged between a Tor client and a Tor server.
-    (This assumption makes sure that there are only two IP addresses in the
-    pcap file)
-
-    The first packet of the pcap is sent from the client to the server. (This
-    assumption is used to get the IP address of the client.)
-
-    All captured packets are TLS packets: that is TCP session
-    establishment/teardown packets should be filtered out (no SYN/SYN+ACK)
-    """
-
-    """Minimally validate the pcap and also find out what's the client
-    and server IP addresses."""
-    for packet in packets:
-        if checking_first_packet:
-            client_ip_addr = packet[IP].src
-            checking_first_packet = False
-        else:
-            if packet[IP].src != client_ip_addr:
-                server_ip_addr = packet[IP].src
-
-        try:
-            if (packet[Raw]):
-                ssl_packets.append(packet)
-        except IndexError:
-            pass
-
-    """Form our list."""
-    for packet in ssl_packets:
-        if packet[IP].src == client_ip_addr:
-            messages.append({"sender": "client", "data": str(packet[Raw])})
-        elif packet[IP].src == server_ip_addr:
-            messages.append({"sender": "server", "data": str(packet[Raw])})
-        else:
-            raise("Detected third IP address! pcap is corrupted.")
-
-    return messages
-
-class Mutator:
-    idx = 0
-    step = 0
-
-    waiting = False
-    waiting_step = 0
-
-    def __init__(self, steps):
-        """
-        @param steps: array of dicts containing as keys data and wait. Data is
-                      the content of the ith packet to be sent and wait is how
-                      much we should wait before mutating the packet of the
-                      next step.
-        """
-        self.steps = steps
-
-    def _mutate(self, data, idx):
-        """
-        Mutate the idx bytes by increasing it's value by one
-
-        @param data: the data to be mutated.
-
-        @param idx: what byte should be mutated.
-        """
-        print "idx: %s, data: %s" % (idx, data)
-        ret = data[:idx]
-        ret += chr(ord(data[idx]) + 1)
-        ret += data[idx+1:]
-        return ret
-
-    def state(self):
-        """
-        Return the current mutation state. As in what bytes are being mutated.
-
-        Returns a dict containg the packet index and the step number.
-        """
-        print "[Mutator.state()] Giving out my internal state."
-        current_state =  {'idx': self.idx, 'step': self.step}
-        return current_state
-
-    def next_mutation(self):
-        """
-        Increases by one the mutation state.
-
-        ex. (* is the mutation state, i.e. the byte to be mutated)
-        before [___*] [____]
-               step1   step2
-        after  [____] [*___]
-
-        Should be called every time you need to proceed onto the next mutation.
-        It changes the internal state of the mutator to that of the next
-        mutatation.
-
-        returns True if another mutation is available.
-        returns False if all the possible mutations have been done.
-        """
-        if (self.step + 1) > len(self.steps):
-            # Hack to stop once we have gone through all the steps
-            print "[Mutator.next_mutation()] I believe I have gone over all steps"
-            print "                          Stopping!"
-            self.waiting = True
-            return False
-
-        self.idx += 1
-        current_idx = self.idx
-        current_step = self.step
-        current_data = self.steps[current_step]['data']
-        try:
-            data_to_receive = len(self.steps[current_step +1 ]['data'])
-            print "[Mutator.next_mutation()] Managed to receive some data."
-        except:
-            print "[Mutator.next_mutation()] No more data to receive."
-
-        if self.waiting and self.waiting_step == data_to_receive:
-            print "[Mutator.next_mutation()] I am no longer waiting"
-            log.debug("I am no longer waiting.")
-            self.waiting = False
-            self.waiting_step = 0
-            self.idx = 0
-
-        elif self.waiting:
-            print "[Mutator.next_mutation()] Waiting some more."
-            log.debug("Waiting some more.")
-            self.waiting_step += 1
-
-        elif current_idx >= len(current_data):
-            print "[Mutator.next_mutation()] Entering waiting mode."
-            log.debug("Entering waiting mode.")
-            self.step += 1
-            self.idx = 0
-            self.waiting = True
-        log.debug("current index %s" % current_idx)
-        log.debug("current data %s" % len(current_data))
-        return True
-
-    def get_mutation(self, step):
-        """
-        Returns the current packet to be sent to the wire.
-        If no mutation is necessary it will return the plain data.
-        Should be called when you are interested in obtaining the data to be
-        sent for the selected state.
-
-        @param step: the current step you want the mutation for
-
-        returns the mutated packet for the specified step.
-        """
-        if step != self.step or self.waiting:
-            log.debug("[Mutator.get_mutation()] I am not going to do anything :)")
-            return self.steps[step]['data']
-
-        data = self.steps[step]['data']
-        print "Mutating %s with idx %s" % (data, self.idx)
-        return self._mutate(data, self.idx)
-
-class B0wserProtocol(protocol.Protocol):
-    """
-    This implements the B0wser protocol for the server side.
-    It gets instanced once for every client that connects to the oonib.
-    For every instance of protocol there is only 1 mutation.
-    Once the last step is reached the connection is closed on the serverside.
-    """
-    steps = []
-    mutator = None
-
-    role = 'client'
-    state = 0
-    total_states = len(steps) - 1
-    received_data = 0
-    to_receive_data = 0
-    report = reports.Report('b0wser', 'b0wser.yamlooni')
-
-    def next_state(self):
-        """
-        This is called once I have completed one step of the protocol and need
-        to proceed to the next step.
-        """
-        if not self.mutator:
-            print "[B0wserProtocol.next_state] No mutator. There is no point to stay on this earth."
-            self.transport.loseConnection()
-            return
-        if self.role is self.steps[self.state]['sender']:
-            print "[B0wserProtocol.next_state] I am a sender"
-            data = self.mutator.get_mutation(self.state)
-            self.transport.write(data)
-            self.to_receive_data = 0
-        else:
-            print "[B0wserProtocol.next_state] I am a receiver"
-            self.to_receive_data = len(self.steps[self.state]['data'])
-
-        self.state += 1
-        self.received_data = 0
-
-    def dataReceived(self, data):
-        """
-        This is called every time some data is received. I transition to the
-        next step once the amount of data that I expect to receive is received.
-
-        @param data: the data that has been sent by the client.
-        """
-        if not self.mutator:
-            print "I don't have a mutator. My life means nothing."
-            self.transport.loseConnection()
-            return
-        if len(self.steps) <= self.state:
-            print "I have reached the end of the state machine"
-            print "Censorship fingerprint bruteforced!"
-            report = {'mutator_state': self.mutator.state()}
-            self.report(report)
-            self.transport.loseConnection()
-            return
-
-        self.received_data += len(data)
-        if self.received_data >= self.to_receive_data:
-            print "Moving to next state %s" % self.state
-            self.next_state()
-
-    def censorship_detected(self, report):
-        """
-        I have detected the possible presence of censorship we need to write a
-        report on it.
-
-        @param report: a dict containing the report to be written. Must contain
-                       the keys 'reason', 'proto_state' and 'mutator_state'.
-                       The reason is the reason for which the connection was
-                       closed. The proto_state is the current state of the
-                       protocol instance and mutator_state is what was being
-                       mutated.
-        """
-        print "The connection was closed because of %s" % report['reason']
-        print "State %s, Mutator %s" % (report['proto_state'],
-                                        report['mutator_state'])
-        self.mutator.next_mutation()
-
-
-
-    def connectionLost(self, reason):
-        """
-        The connection was closed. This may be because of a legittimate reason
-        or it may be because of a censorship event.
-        """
-        if not self.mutator:
-            print "Terminated because of little interest in life."
-            return
-        report = {'reason': reason, 'proto_state': self.state,
-                'trigger': None, 'mutator_state': self.mutator.state()}
-
-        if self.state < self.total_states:
-            report['trigger'] = 'did not finish state walk'
-            self.censorship_detected(report)
-
-        if reason.check(ConnectionDone):
-            print "Connection closed cleanly"
-        else:
-            report['trigger'] = 'unclean connection closure'
-            self.censorship_detected(report)
-
-
diff --git a/ooni/protocols/daphn3.py b/ooni/protocols/daphn3.py
new file mode 100644
index 0000000..d8290e6
--- /dev/null
+++ b/ooni/protocols/daphn3.py
@@ -0,0 +1,284 @@
+from twisted.internet import protocol, defer
+from twisted.internet.error import ConnectionDone
+
+from ooni.utils import log
+from ooni.plugoo import reports
+
+import sys
+from scapy.all import *
+import yaml
+
+def get_daphn3_dictionary_from_pcap(filename):
+    """
+    @param filename: Filesystem path to the pcap.
+
+    Returns:
+      [{"sender": "client", "data": "\x17\x52\x15"}, {"sender": "server", "data": "\x17\x15\x13"}]
+    """
+    packets = rdpcap(filename)
+
+    checking_first_packet = True
+    client_ip_addr = None
+    server_ip_addr = None
+
+    ssl_packets = []
+    messages = []
+
+    """
+    pcap assumptions:
+
+    pcap only contains packets exchanged between a Tor client and a Tor server.
+    (This assumption makes sure that there are only two IP addresses in the
+    pcap file)
+
+    The first packet of the pcap is sent from the client to the server. (This
+    assumption is used to get the IP address of the client.)
+
+    All captured packets are TLS packets: that is TCP session
+    establishment/teardown packets should be filtered out (no SYN/SYN+ACK)
+    """
+
+    """Minimally validate the pcap and also find out what's the client
+    and server IP addresses."""
+    for packet in packets:
+        if checking_first_packet:
+            client_ip_addr = packet[IP].src
+            checking_first_packet = False
+        else:
+            if packet[IP].src != client_ip_addr:
+                server_ip_addr = packet[IP].src
+
+        try:
+            if (packet[Raw]):
+                ssl_packets.append(packet)
+        except IndexError:
+            pass
+
+    """Form our list."""
+    for packet in ssl_packets:
+        if packet[IP].src == client_ip_addr:
+            messages.append({"sender": "client", "data": str(packet[Raw])})
+        elif packet[IP].src == server_ip_addr:
+            messages.append({"sender": "server", "data": str(packet[Raw])})
+        else:
+            raise("Detected third IP address! pcap is corrupted.")
+
+    return messages
+
+class Mutator:
+    idx = 0
+    step = 0
+
+    waiting = False
+    waiting_step = 0
+
+    def __init__(self, steps):
+        """
+        @param steps: array of dicts containing as keys data and wait. Data is
+                      the content of the ith packet to be sent and wait is how
+                      much we should wait before mutating the packet of the
+                      next step.
+        """
+        self.steps = steps
+
+    def _mutate(self, data, idx):
+        """
+        Mutate the idx bytes by increasing it's value by one
+
+        @param data: the data to be mutated.
+
+        @param idx: what byte should be mutated.
+        """
+        print "idx: %s, data: %s" % (idx, data)
+        ret = data[:idx]
+        ret += chr(ord(data[idx]) + 1)
+        ret += data[idx+1:]
+        return ret
+
+    def state(self):
+        """
+        Return the current mutation state. As in what bytes are being mutated.
+
+        Returns a dict containg the packet index and the step number.
+        """
+        print "[Mutator.state()] Giving out my internal state."
+        current_state =  {'idx': self.idx, 'step': self.step}
+        return current_state
+
+    def next_mutation(self):
+        """
+        Increases by one the mutation state.
+
+        ex. (* is the mutation state, i.e. the byte to be mutated)
+        before [___*] [____]
+               step1   step2
+        after  [____] [*___]
+
+        Should be called every time you need to proceed onto the next mutation.
+        It changes the internal state of the mutator to that of the next
+        mutatation.
+
+        returns True if another mutation is available.
+        returns False if all the possible mutations have been done.
+        """
+        if (self.step + 1) > len(self.steps):
+            # Hack to stop once we have gone through all the steps
+            print "[Mutator.next_mutation()] I believe I have gone over all steps"
+            print "                          Stopping!"
+            self.waiting = True
+            return False
+
+        self.idx += 1
+        current_idx = self.idx
+        current_step = self.step
+        current_data = self.steps[current_step]['data']
+        try:
+            data_to_receive = len(self.steps[current_step +1 ]['data'])
+            print "[Mutator.next_mutation()] Managed to receive some data."
+        except:
+            print "[Mutator.next_mutation()] No more data to receive."
+
+        if self.waiting and self.waiting_step == data_to_receive:
+            print "[Mutator.next_mutation()] I am no longer waiting"
+            log.debug("I am no longer waiting.")
+            self.waiting = False
+            self.waiting_step = 0
+            self.idx = 0
+
+        elif self.waiting:
+            print "[Mutator.next_mutation()] Waiting some more."
+            log.debug("Waiting some more.")
+            self.waiting_step += 1
+
+        elif current_idx >= len(current_data):
+            print "[Mutator.next_mutation()] Entering waiting mode."
+            log.debug("Entering waiting mode.")
+            self.step += 1
+            self.idx = 0
+            self.waiting = True
+        log.debug("current index %s" % current_idx)
+        log.debug("current data %s" % len(current_data))
+        return True
+
+    def get_mutation(self, step):
+        """
+        Returns the current packet to be sent to the wire.
+        If no mutation is necessary it will return the plain data.
+        Should be called when you are interested in obtaining the data to be
+        sent for the selected state.
+
+        @param step: the current step you want the mutation for
+
+        returns the mutated packet for the specified step.
+        """
+        if step != self.step or self.waiting:
+            log.debug("[Mutator.get_mutation()] I am not going to do anything :)")
+            return self.steps[step]['data']
+
+        data = self.steps[step]['data']
+        print "Mutating %s with idx %s" % (data, self.idx)
+        return self._mutate(data, self.idx)
+
+class Daphn3Protocol(protocol.Protocol):
+    """
+    This implements the Daphn3 protocol for the server side.
+    It gets instanced once for every client that connects to the oonib.
+    For every instance of protocol there is only 1 mutation.
+    Once the last step is reached the connection is closed on the serverside.
+    """
+    steps = []
+    mutator = None
+
+    role = 'client'
+    state = 0
+    total_states = len(steps) - 1
+    received_data = 0
+    to_receive_data = 0
+    report = reports.Report('daphn3', 'daphn3.yamlooni')
+
+    def next_state(self):
+        """
+        This is called once I have completed one step of the protocol and need
+        to proceed to the next step.
+        """
+        if not self.mutator:
+            print "[Daphn3Protocol.next_state] No mutator. There is no point to stay on this earth."
+            self.transport.loseConnection()
+            return
+        if self.role is self.steps[self.state]['sender']:
+            print "[Daphn3Protocol.next_state] I am a sender"
+            data = self.mutator.get_mutation(self.state)
+            self.transport.write(data)
+            self.to_receive_data = 0
+        else:
+            print "[Daphn3Protocol.next_state] I am a receiver"
+            self.to_receive_data = len(self.steps[self.state]['data'])
+
+        self.state += 1
+        self.received_data = 0
+
+    def dataReceived(self, data):
+        """
+        This is called every time some data is received. I transition to the
+        next step once the amount of data that I expect to receive is received.
+
+        @param data: the data that has been sent by the client.
+        """
+        if not self.mutator:
+            print "I don't have a mutator. My life means nothing."
+            self.transport.loseConnection()
+            return
+        if len(self.steps) <= self.state:
+            print "I have reached the end of the state machine"
+            print "Censorship fingerprint bruteforced!"
+            report = {'mutator_state': self.mutator.state()}
+            self.report(report)
+            self.transport.loseConnection()
+            return
+
+        self.received_data += len(data)
+        if self.received_data >= self.to_receive_data:
+            print "Moving to next state %s" % self.state
+            self.next_state()
+
+    def censorship_detected(self, report):
+        """
+        I have detected the possible presence of censorship we need to write a
+        report on it.
+
+        @param report: a dict containing the report to be written. Must contain
+                       the keys 'reason', 'proto_state' and 'mutator_state'.
+                       The reason is the reason for which the connection was
+                       closed. The proto_state is the current state of the
+                       protocol instance and mutator_state is what was being
+                       mutated.
+        """
+        print "The connection was closed because of %s" % report['reason']
+        print "State %s, Mutator %s" % (report['proto_state'],
+                                        report['mutator_state'])
+        self.mutator.next_mutation()
+
+
+
+    def connectionLost(self, reason):
+        """
+        The connection was closed. This may be because of a legittimate reason
+        or it may be because of a censorship event.
+        """
+        if not self.mutator:
+            print "Terminated because of little interest in life."
+            return
+        report = {'reason': reason, 'proto_state': self.state,
+                'trigger': None, 'mutator_state': self.mutator.state()}
+
+        if self.state < self.total_states:
+            report['trigger'] = 'did not finish state walk'
+            self.censorship_detected(report)
+
+        if reason.check(ConnectionDone):
+            print "Connection closed cleanly"
+        else:
+            report['trigger'] = 'unclean connection closure'
+            self.censorship_detected(report)
+
+
diff --git a/oonib/b0wser.py b/oonib/b0wser.py
deleted file mode 100644
index 4500075..0000000
--- a/oonib/b0wser.py
+++ /dev/null
@@ -1,33 +0,0 @@
-from twisted.internet import protocol
-from twisted.internet.error import ConnectionDone
-
-from ooni.plugoo import reports
-from ooni.protocols.b0wser import Mutator, B0wserProtocol
-
-class B0wserServer(protocol.ServerFactory):
-    """
-    This is the main class that deals with the b0wser server side component.
-    We keep track of global state of every client here.
-    Every client is identified by their IP address and the state of mutation is
-    stored by using their IP address as a key. This may lead to some bugs if
-    two different clients are sharing the same IP, but hopefully the
-    probability of such thing is not that likely.
-    """
-    protocol = B0wserProtocol
-    mutations = {}
-    def buildProtocol(self, addr):
-        p = self.protocol()
-        p.factory = self
-
-        if addr.host not in self.mutations:
-            self.mutations[addr.host] = Mutator(p.steps)
-        else:
-            print "Moving on to next mutation"
-            if not self.mutations[addr.host].next_mutation():
-                self.mutations.pop(addr.host)
-        try:
-            p.mutator = self.mutations[addr.host]
-        except:
-            pass
-        return p
-
diff --git a/oonib/daphn3.py b/oonib/daphn3.py
new file mode 100644
index 0000000..22aef49
--- /dev/null
+++ b/oonib/daphn3.py
@@ -0,0 +1,33 @@
+from twisted.internet import protocol
+from twisted.internet.error import ConnectionDone
+
+from ooni.plugoo import reports
+from ooni.protocols.daphn3 import Mutator, daphn3Protocol
+
+class daphn3Server(protocol.ServerFactory):
+    """
+    This is the main class that deals with the daphn3 server side component.
+    We keep track of global state of every client here.
+    Every client is identified by their IP address and the state of mutation is
+    stored by using their IP address as a key. This may lead to some bugs if
+    two different clients are sharing the same IP, but hopefully the
+    probability of such thing is not that likely.
+    """
+    protocol = daphn3Protocol
+    mutations = {}
+    def buildProtocol(self, addr):
+        p = self.protocol()
+        p.factory = self
+
+        if addr.host not in self.mutations:
+            self.mutations[addr.host] = Mutator(p.steps)
+        else:
+            print "Moving on to next mutation"
+            if not self.mutations[addr.host].next_mutation():
+                self.mutations.pop(addr.host)
+        try:
+            p.mutator = self.mutations[addr.host]
+        except:
+            pass
+        return p
+
diff --git a/oonib/oonibackend.py b/oonib/oonibackend.py
index 4ae275e..22a8728 100755
--- a/oonib/oonibackend.py
+++ b/oonib/oonibackend.py
@@ -18,7 +18,7 @@ from twisted.names import dns
 
 from oonib.httpbackend import HTTPBackend
 from oonib.dnsbackend import ProxyDNSServer
-from oonib.b0wser import B0wserServer
+from oonib.daphn3 import Daphn3Server
 
 # This tells twisted to set the
 server.version = "Apache"
@@ -34,5 +34,5 @@ UDPFactory = dns.DNSDatagramProtocol(TCPDNSServer)
 internet.UDPServer(5354, UDPFactory).setServiceParent(serviceCollection)
 
 # Start the ooni backend thing
-b0wser = B0wserServer()
-internet.TCPServer(9666, b0wser).setServiceParent(serviceCollection)
+daphn3 = Daphn3Server()
+internet.TCPServer(9666, daphn3).setServiceParent(serviceCollection)



More information about the tor-commits mailing list