[tor-commits] [flashproxy/master] Support new client registrations.

infinity0 at torproject.org infinity0 at torproject.org
Mon Oct 28 14:47:40 UTC 2013


commit 7b3010e1d4338d173bd9aec35e2ed819842d080d
Author: George Kadianakis <desnacked at riseup.net>
Date:   Fri Sep 6 17:27:11 2013 +0300

    Support new client registrations.
---
 facilitator/fac.py          |    3 +-
 facilitator/facilitator     |   25 ++++++++++++++---
 facilitator/facilitator.cgi |   64 ++++++++++++++++++++++++++++++++++++-------
 3 files changed, 77 insertions(+), 15 deletions(-)

diff --git a/facilitator/fac.py b/facilitator/fac.py
index 70d482d..c79e415 100644
--- a/facilitator/fac.py
+++ b/facilitator/fac.py
@@ -239,11 +239,12 @@ def transact(f, command, *params):
         raise ValueError("No newline at end of string returned by facilitator")
     return parse_transaction(line[:-1])
 
-def put_reg(facilitator_addr, client_addr, registrant_addr=None):
+def put_reg(facilitator_addr, client_addr, transport_chain, registrant_addr=None):
     """Send a registration to the facilitator using a one-time socket. Returns
     true iff the command was successful."""
     f = fac_socket(facilitator_addr)
     params = [("CLIENT", format_addr(client_addr))]
+    params.append(("TRANSPORT_CHAIN", transport_chain))
     if registrant_addr is not None:
         params.append(("FROM", format_addr(registrant_addr)))
     try:
diff --git a/facilitator/facilitator b/facilitator/facilitator
index 7b1c51a..3b99346 100755
--- a/facilitator/facilitator
+++ b/facilitator/facilitator
@@ -299,18 +299,35 @@ class Handler(SocketServer.StreamRequestHandler):
             print >> self.wfile, fac.render_transaction("NONE", ("CHECK-BACK-IN", str(check_back_in)))
         return True
 
+    # Handle a PUT request (client made a registration request; register it.)
+    # Example: PUT CLIENT="1.1.1.1:5555" FROM="1.1.1.2:6666" TRANSPORT_CHAIN="obfs3|websocket"
     def do_PUT(self, params):
+        # Check out if we recognize the transport chain in this registration request
+        transport_chain = fac.param_first("TRANSPORT_CHAIN", params)
+        if transport_chain is None:
+            log(u"PUT missing TRANSPORT_CHAIN param")
+            self.send_error()
+            return False
+
+        # See if we have relays that support this transport chain
+        if transport_chain not in options.relays:
+            log(u"Unrecognized transport chain: %s" % transport_chain)
+            self.send_error() # XXX can we tell the flashproxy client of this error?
+            return False
+        # if we have relays that support this transport chain, we
+        # certainly have a regset for its outermost transport too.
+        assert(get_outermost_transport(transport_chain) in REGSETS_IPV4)
+
         client_spec = fac.param_first("CLIENT", params)
         if client_spec is None:
             log(u"PUT missing CLIENT param")
             self.send_error()
             return False
 
-        # FROM
-
         try:
-            reg = Reg.parse(client_spec)
-        except ValueError, e:
+            reg = Reg.parse(client_spec, transport_chain)
+        except (UnknownTransport, ValueError) as e:
+            # XXX should we throw a better error message to the client? Is it possible?
             log(u"syntax error in %s: %s" % (safe_str(repr(client_spec)), safe_str(repr(str(e)))))
             self.send_error()
             return False
diff --git a/facilitator/facilitator.cgi b/facilitator/facilitator.cgi
index 3adbc15..b20a9ed 100755
--- a/facilitator/facilitator.cgi
+++ b/facilitator/facilitator.cgi
@@ -79,18 +79,62 @@ Access-Control-Allow-Origin: *\r
         exit_error(400)
 
 def do_post():
+    """Parse client registration."""
+
+    # Old style client registration:
+    #   client=1.2.3.4:9000
+    # New style client registration:
+    #   client-websocket=1.2.3.4:9000&client-obfs3|websocket=1.2.3.4:10000
+
+    is_new_style = True
+
     if path_info != "/":
         exit_error(400)
-    client_specs = fs.getlist("client")
-    if len(client_specs) != 1:
-        exit_error(400)
-    client_spec = client_specs[0].strip()
-    try:
-        client_addr = fac.parse_addr_spec(client_spec, defhost=remote_addr[0])
-    except ValueError:
-        exit_error(400)
-    if not fac.put_reg(FACILITATOR_ADDR, client_addr, remote_addr):
-        exit_error(500)
+
+    if "client" in fs.keys():
+        is_new_style = False
+
+    if is_new_style:
+        # It's a new style registration. We iterate through the items
+        # in the POST body, and see if any of them look like
+        # "client-websocket=1.2.3.4:9000". We then split all those
+        # items and send them as separate registrations to the
+        # facilitator.
+        for key in fs.keys():
+            if not key.startswith("client-"):
+                continue
+
+            # Get the "webssocket" part of "client-webscoket".
+            transport_chain = key[len("client-"):]
+            # Get the "1.2.3.4:9000" part of "client-websocket=1.2.3.4:9000".
+            client_spec = fs[key].value.strip()
+            try:
+                client_addr = fac.parse_addr_spec(client_spec, defhost=remote_addr[0])
+            except ValueError:
+                exit_error(400)
+
+            # XXX what if previous registrations passed through
+            # successfully, but the last one failed and called
+            # exit_error()?
+
+            # XXX need to link these registrations together, so that
+            # when one is answerered the rest are invalidated.
+            if not fac.put_reg(FACILITATOR_ADDR, client_addr, transport_chain, remote_addr):
+                exit_error(500)
+
+    else: # old-stle registration:
+        client_specs = fs.getlist("client")
+        if len(client_specs) != 1:
+            exit_error(400)
+        client_spec = client_specs[0].strip()
+        try:
+            client_addr = fac.parse_addr_spec(client_spec, defhost=remote_addr[0])
+        except ValueError:
+            exit_error(400)
+
+        if not fac.put_reg(FACILITATOR_ADDR, client_addr, "websocket", remote_addr):
+            exit_error(500)
+
     print """\
 Status: 200\r
 \r"""





More information about the tor-commits mailing list