commit 3e92fc1e67ada8e50f7fc82710f7108d9faefedb Author: David Fifield david@bamsoftware.com Date: Thu Mar 29 14:55:47 2012 -0700
Get rid of registration in the connector.
Move it to an external program, connector-reg-http.py. --- README | 12 +++-- connector.py | 30 +------------- flashproxy-reg-http.py | 106 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 115 insertions(+), 33 deletions(-)
diff --git a/README b/README index 46776d5..c4f0f46 100644 --- a/README +++ b/README @@ -58,14 +58,16 @@ only communication your computer makes with a fixed IP address is registration with the facilitator: everything else happens over ephemeral proxies.
-1. Run the connector and instruct it to register with a public - facilitator. - $ python connector.py -f tor-facilitator.bamsoftware.com +1. Run the connector. + $ python connector.py + Register with a public facilitator. + $ python flashproxy-reg-http.py By default the connector listens on Internet-facing TCP port 9000. If you have to use a different port (to get through a firewall, for - example), give it on the command line like this (here using port + example), give it on the command lines like this (here using port 8888): - $ python connector.py -f tor-facilitator.bamsoftware.com :9001 :8888 + $ python connector.py 127.0.0.1:9001 :8888 + $ python flashproxy-reg-http.py -a :8888 2. Run Tor using the included torrc file. $ tor -f flashproxy/torrc
diff --git a/connector.py b/connector.py index 3268a64..571289e 100755 --- a/connector.py +++ b/connector.py @@ -4,7 +4,6 @@ import base64 import cStringIO import getopt import hashlib -import httplib import os import re import select @@ -21,14 +20,12 @@ DEFAULT_REMOTE_ADDRESS = "0.0.0.0" DEFAULT_REMOTE_PORT = 9000 DEFAULT_LOCAL_ADDRESS = "127.0.0.1" DEFAULT_LOCAL_PORT = 9001 -DEFAULT_FACILITATOR_PORT = 9002
LOG_DATE_FORMAT = "%Y-%m-%d %H:%M:%S"
class options(object): local_addr = None remote_addr = None - facilitator_addr = None
log_filename = None log_file = sys.stdout @@ -41,7 +38,7 @@ UNCONNECTED_BUFFER_LIMIT = 10240
def usage(f = sys.stdout): print >> f, """\ -Usage: %(progname)s -f FACILITATOR[:PORT] [LOCAL][:PORT] [REMOTE][:PORT] +Usage: %(progname)s [LOCAL][:PORT] [REMOTE][:PORT] Wait for connections on a local and a remote port. When any pair of connections exists, data is ferried between them until one side is closed. By default LOCAL is "%(local)s" and REMOTE is "%(remote)s". @@ -49,12 +46,7 @@ LOCAL is "%(local)s" and REMOTE is "%(remote)s". The local connection acts as a SOCKS4a proxy, but the host and port in the SOCKS request are ignored and the local connection is always linked to a remote connection. - -If the -f option is given, then the REMOTE address is advertised to the given -FACILITATOR. --daemon daemonize (Unix only). - -f, --facilitator=HOST[:PORT] advertise willingness to receive connections to - HOST:PORT. By default PORT is %(fac_port)d. -h, --help show this help. -l, --log FILENAME write log to FILENAME (default stdout). --pidfile FILENAME write PID to FILENAME after daemonizing.\ @@ -62,7 +54,6 @@ FACILITATOR. "progname": sys.argv[0], "local": format_addr((DEFAULT_LOCAL_ADDRESS, DEFAULT_LOCAL_PORT)), "remote": format_addr((DEFAULT_REMOTE_ADDRESS, DEFAULT_REMOTE_PORT)), - "fac_port": DEFAULT_FACILITATOR_PORT, }
def log(msg): @@ -556,22 +547,12 @@ def handle_remote_connection(fd):
def handle_local_connection(fd): log(u"handle_local_connection") - register() match_proxies()
def report_pending(): log(u"locals (%d): %s" % (len(locals), [format_peername(x) for x in locals])) log(u"remotes (%d): %s" % (len(remotes), [format_peername(x) for x in remotes]))
-def register(): - if options.facilitator_addr is None: - return False - spec = format_addr((None, options.remote_addr[1])) - log(u"Registering "%s" with %s." % (spec, format_addr(options.facilitator_addr))) - http = httplib.HTTPConnection(*options.facilitator_addr) - http.request("POST", "/", urllib.urlencode({"client": spec})) - http.close() - return True
def proxy_chunk(fd_r, fd_w, label): try: @@ -640,7 +621,6 @@ def main(): local_c, addr = fd.accept() log(u"Local connection from %s." % format_addr(addr)) socks_pending.append(local_c) - register() elif fd in websocket_pending: log(u"Data from WebSocket-pending %s." % format_addr(addr)) protocols = handle_websocket_request(fd) @@ -665,13 +645,11 @@ def main(): if not proxy_chunk(fd, local, "remote"): del local_for[fd] del remote_for[local] - register() elif fd in remote_for: remote = remote_for[fd] if not proxy_chunk(fd, remote, "local"): del remote_for[fd] del local_for[remote] - register() elif fd in locals: if not receive_unlinked(fd, "local"): locals.remove(fd) @@ -683,12 +661,10 @@ def main(): match_proxies()
if __name__ == "__main__": - opts, args = getopt.gnu_getopt(sys.argv[1:], "f:hl:", ["daemon", "facilitator=", "help", "log=", "pidfile="]) + opts, args = getopt.gnu_getopt(sys.argv[1:], "hl:", ["daemon", "help", "log=", "pidfile="]) for o, a in opts: if o == "--daemon": options.daemonize = True - elif o == "-f" or o == "--facilitator": - options.facilitator_addr = parse_addr_spec(a, None, DEFAULT_FACILITATOR_PORT) elif o == "-h" or o == "--help": usage() sys.exit() @@ -735,8 +711,6 @@ if __name__ == "__main__": local_for = {} remote_for = {}
- register() - if options.daemonize: log(u"Daemonizing.") pid = os.fork() diff --git a/flashproxy-reg-http.py b/flashproxy-reg-http.py new file mode 100755 index 0000000..032a0fb --- /dev/null +++ b/flashproxy-reg-http.py @@ -0,0 +1,106 @@ +#!/usr/bin/env python + +import getopt +import httplib +import socket +import sys +import urllib + +DEFAULT_REMOTE_ADDR = None +DEFAULT_REMOTE_PORT = 9000 +DEFAULT_FACILITATOR_HOST = "tor-facilitator.bamsoftware.com" +DEFAULT_FACILITATOR_PORT = 9002 + +class options(object): + facilitator_addr = None + remote_addr = None + +def usage(f = sys.stdout): + print >> f, """\ +Usage: %(progname)s [HOSTNAME][:PORT] +Register with a flash proxy facilitator using an HTTP POST. By default the +facilitator address is "%(fac_addr)s". + + -a, --address=ADDRESS register the given address instead of "%(remote_addr)s". + -h, --help show this help. \ +""" % { + "progname": sys.argv[0], + "fac_addr": format_addr((DEFAULT_FACILITATOR_HOST, DEFAULT_FACILITATOR_PORT)), + "remote_addr": format_addr((DEFAULT_REMOTE_ADDR, DEFAULT_REMOTE_PORT)), +} + +def parse_addr_spec(spec, defhost = None, defport = None): + host = None + port = None + m = None + # IPv6 syntax. + if not m: + m = re.match(ur'^[(.+)]:(\d+)$', spec) + if m: + host, port = m.groups() + af = socket.AF_INET6 + if not m: + m = re.match(ur'^[(.+)]:?$', spec) + if m: + host, = m.groups() + af = socket.AF_INET6 + # IPv4 syntax. + if not m: + m = re.match(ur'^(.+):(\d+)$', spec) + if m: + host, port = m.groups() + af = socket.AF_INET + if not m: + m = re.match(ur'^:?(\d+)$', spec) + if m: + port, = m.groups() + af = 0 + if not m: + host = spec + af = 0 + host = host or defhost + port = port or defport + if not (host and port): + raise ValueError("Bad address specification "%s"" % spec) + return host, int(port) + +def format_addr(addr): + host, port = addr + if not host: + return u":%d" % port + # Numeric IPv6 address? + try: + addrs = socket.getaddrinfo(host, port, 0, socket.SOCK_STREAM, socket.IPPROTO_TCP, socket.AI_NUMERICHOST) + af = addrs[0][0] + except socket.gaierror, e: + af = 0 + if af == socket.AF_INET6: + return u"[%s]:%d" % (host, port) + else: + return u"%s:%d" % (host, port) + +options.facilitator_addr = (DEFAULT_FACILITATOR_HOST, DEFAULT_FACILITATOR_PORT) +options.remote_addr = (DEFAULT_REMOTE_ADDR, DEFAULT_REMOTE_PORT) + +opts, args = getopt.gnu_getopt(sys.argv[1:], "a:h", ["address=", "help"]) +for o, a in opts: + if o == "-a" or o == "--address": + options.remote_addr = parse_addr_spec(a, DEFAULT_REMOTE_ADDR, DEFAULT_REMOTE_PORT) + elif o == "-h" or o == "--help": + usage() + sys.exit() + +if len(args) == 0: + pass +elif len(args) == 1: + options.facilitator_addr = parse_addr_spec(args[0], DEFAULT_FACILITATOR_HOST, DEFAULT_FACILITATOR_PORT) +else: + usage(sys.stderr) + sys.exit(1) + +spec = format_addr(options.remote_addr) +http = httplib.HTTPConnection(*options.facilitator_addr) +http.request("POST", "/", urllib.urlencode({"client": spec})) +http.close() + +print "Registered "%s" with %s." % (spec, format_addr(options.facilitator_addr))
tor-commits@lists.torproject.org