[tor-commits] [obfsproxy/master] Fix a problem when receiving test files in tester.py.

nickm at torproject.org nickm at torproject.org
Fri Sep 9 17:08:58 UTC 2011


commit fb876074f1c040a6bdcf0e7489ca5e07d5ce428f
Author: George Kadianakis <desnacked at gmail.com>
Date:   Fri Aug 19 05:29:09 2011 +0200

    Fix a problem when receiving test files in tester.py.
    
    The workers of tester.py used to socket.recv() till they got
    zero-length data. That's usually caused by "EOF" or by the other side
    of the socket closing.
    
    A python string (TEST_FILE) don't cause an "EOF" and obfsproxy doesn't
    close its sockets since it's supposed to stream data continuously. So,
    how did the integration tests work?
    tester.py used to socket.shutdown(socket.SHUT_WR) the upstream part of
    the connection right after sending the test file, which resulted in
    obfsproxy conn_free'ing the whole 'circuit'; including the downstream
    side. That used to return zero-length data to recv() and that's how it
    was getting out of the ReadWorker:work().
    
    In the case of handshake-less protocols (like 'dummy') that was okay,
    since the data were ultimately transferred to the server's destination
    by conn_flush_and_free()s.
    The thing is that in protocols like obfs2, the handshake couldn't be
    completed since the whole 'circuit' was torn down. And that's why
    obfs2 tests did not work.
    
    This patch uses socket.timeout instead of zero-length data to get out
    of the recv() loop.
    
    Conflicts:
    
    	src/test/tester.py.in
---
 src/test/tester.py.in |   45 ++++++++++++++++++++++++++-------------------
 1 files changed, 26 insertions(+), 19 deletions(-)

diff --git a/src/test/tester.py.in b/src/test/tester.py.in
index 55d9477..4b93784 100644
--- a/src/test/tester.py.in
+++ b/src/test/tester.py.in
@@ -102,6 +102,8 @@ def connect_with_retry(addr):
             retry += 1
             time.sleep(0.05)
 
+SOCKET_TIMEOUT = 1.0
+
 # Helper: In a separate process (to avoid deadlock), listen on a
 # specified socket.  The first time something connects to that socket,
 # read all available data, stick it in a string, and post the string
@@ -116,13 +118,15 @@ class ReadWorker(object):
         listener.listen(1)
         (conn, remote) = listener.accept()
         listener.close()
-        conn.settimeout(1.0)
+        conn.settimeout(SOCKET_TIMEOUT)
         data = ""
         try:
             while True:
                 chunk = conn.recv(4096)
                 if chunk == "": break
                 data += chunk
+        except socket.timeout:
+            pass
         except Exception, e:
             data += "|RECV ERROR: " + e
         conn.close()
@@ -135,7 +139,7 @@ class ReadWorker(object):
         self.worker.start()
 
     def get(self):
-        rv = self.oq.get(timeout=1)
+        rv = self.oq.get(timeout=SOCKET_TIMEOUT+0.1)
         self.worker.join()
         return rv
 
@@ -162,7 +166,7 @@ class DirectTest(object):
         self.output_reader = ReadWorker(("127.0.0.1", EXIT_PORT))
         self.obfs = Obfsproxy(self.obfs_args)
         self.input_chan = connect_with_retry(("127.0.0.1", ENTRY_PORT))
-        self.input_chan.settimeout(1.0)
+        self.input_chan.settimeout(SOCKET_TIMEOUT)
 
     def tearDown(self):
         self.obfs.stop()
@@ -174,12 +178,13 @@ class DirectTest(object):
         # transfer a file.  Then check whether the output is the same
         # as the input.
         self.input_chan.sendall(TEST_FILE)
-        self.input_chan.shutdown(socket.SHUT_WR)
         try:
             output = self.output_reader.get()
         except Queue.Empty:
             output = ""
 
+        self.input_chan.close()
+
         report = diff("errors in transfer:", TEST_FILE, output)
 
         report += self.obfs.check_completion("obfsproxy", report!="")
@@ -243,20 +248,22 @@ class SocksTest(object):
                     if e.errno != errno.ECONNRESET: raise
                 self.assertEqual(got, exp)
             sending = not sending
+
         if good:
             input_chan.sendall(TEST_FILE)
-            input_chan.shutdown(socket.SHUT_WR)
             try:
                 output = self.output_reader.get()
             except Queue.Empty:
                 output = ""
 
+            input_chan.close()
+
         if good: return output
         else: return None
 
     def socksTest(self, sequence):
         input_chan = connect_with_retry(("127.0.0.1", ENTRY_PORT))
-        input_chan.settimeout(1.0)
+        input_chan.settimeout(SOCKET_TIMEOUT)
 
         try:
             output = self.socksTestInner(sequence, input_chan)
@@ -352,13 +359,13 @@ class SocksBad(SocksTest, unittest.TestCase):
 #
 
 # fails, disabled
-#class DirectObfs2(DirectTest, unittest.TestCase):
-#    obfs_args = ("obfs2",
-#                 "--dest=127.0.0.1:%d" % EXIT_PORT,
-#                 "server", "127.0.0.1:%d" % SERVER_PORT,
-#                 "obfs2",
-#                 "--dest=127.0.0.1:%d" % SERVER_PORT,
-#                 "client", "127.0.0.1:%d" % ENTRY_PORT)
+class DirectObfs2(DirectTest, unittest.TestCase):
+   obfs_args = ("obfs2",
+                "--dest=127.0.0.1:%d" % EXIT_PORT,
+                "server", "127.0.0.1:%d" % SERVER_PORT,
+                "obfs2",
+                "--dest=127.0.0.1:%d" % SERVER_PORT,
+                "client", "127.0.0.1:%d" % ENTRY_PORT)
 
 class DirectDummy(DirectTest, unittest.TestCase):
     obfs_args = ("dummy", "server",
@@ -369,12 +376,12 @@ class DirectDummy(DirectTest, unittest.TestCase):
                  "127.0.0.1:%d" % SERVER_PORT)
 
 # fails, disabled
-#class SocksObfs2(GoodSocksTest, unittest.TestCase):
-#    server_args = ("obfs2",
-#                   "--dest=127.0.0.1:%d" % EXIT_PORT,
-#                   "server", "127.0.0.1:%d" % SERVER_PORT)
-#    client_args = ("obfs2",
-#                   "socks", "127.0.0.1:%d" % ENTRY_PORT)
+class SocksObfs2(GoodSocksTest, unittest.TestCase):
+   server_args = ("obfs2",
+                  "--dest=127.0.0.1:%d" % EXIT_PORT,
+                  "server", "127.0.0.1:%d" % SERVER_PORT)
+   client_args = ("obfs2",
+                  "socks", "127.0.0.1:%d" % ENTRY_PORT)
 
 class SocksDummy(GoodSocksTest, unittest.TestCase):
     server_args = ("dummy", "server",





More information about the tor-commits mailing list