[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