[tor-commits] [flashproxy/master] Parse relay file.
infinity0 at torproject.org
infinity0 at torproject.org
Mon Oct 28 14:47:40 UTC 2013
commit 36b615a7a95b292ac09741861512bce019e00d79
Author: George Kadianakis <desnacked at riseup.net>
Date: Fri Sep 6 17:23:26 2013 +0300
Parse relay file.
---
facilitator/facilitator | 84 ++++++++++++++++++++++++++++++++++++++++-------
1 file changed, 72 insertions(+), 12 deletions(-)
diff --git a/facilitator/facilitator b/facilitator/facilitator
index 869f62d..8d3f835 100755
--- a/facilitator/facilitator
+++ b/facilitator/facilitator
@@ -33,16 +33,33 @@ class options(object):
listen_port = DEFAULT_LISTEN_PORT
log_filename = DEFAULT_LOG_FILENAME
log_file = sys.stdout
- relay_spec = None
daemonize = True
pid_filename = None
privdrop_username = None
safe_logging = True
+ # Dictionary containing Tor relays that we can pass to
+ # flashproxies. It looks like this:
+ # {"websocket" : ["1.1.1.1:123"], "obfs3|websocket" : ["3.1.2.3:5555", "1.2.3.4:6666"], "obfs2|websocket" : ["1.2.4.4:5123"]}
+ relays = {}
+
+ @staticmethod
+ def num_relays():
+ """Return the number of registered relays."""
+
+ num_relays = 0
+ for relay_list in options.relays.values():
+ num_relays += len(relay_list)
+
+ return num_relays
+
@staticmethod
- def set_relay_spec(spec):
+ def add_relay(transport, spec):
spec = fac.parse_addr_spec(spec, defport = DEFAULT_RELAY_PORT, resolve = True)
- options.relay_spec = fac.format_addr(spec)
+ if transport not in options.relays:
+ options.relays[transport] = []
+
+ options.relays[transport].append(fac.format_addr(spec))
def usage(f = sys.stdout):
print >> f, """\
@@ -57,6 +74,7 @@ again. Listen on 127.0.0.1 and port PORT (by default %(port)d).
--pidfile FILENAME write PID to FILENAME after daemonizing.
--privdrop-user USER switch UID and GID to those of USER.
-r, --relay RELAY send RELAY (host:port) to proxies as the relay to use.
+ -f, --relay-file FILE learn relays from FILE
--unsafe-logging don't scrub IP addresses from logs.\
""" % {
"progname": sys.argv[0],
@@ -64,6 +82,14 @@ again. Listen on 127.0.0.1 and port PORT (by default %(port)d).
"log": DEFAULT_LOG_FILENAME,
}
+def get_outermost_transport(transport):
+ """
+ Given a combined transport name in 'transport', return the name of
+ the outermost transport.
+ e.g. if 'transport' == 'obfs3|websocket' this function returns 'websocket'
+ """
+ return transport.split("|")[-1]
+
def safe_str(s):
"""Return "[scrubbed]" if options.safe_logging is true, and s otherwise."""
if options.safe_logging:
@@ -243,9 +269,9 @@ class Handler(SocketServer.StreamRequestHandler):
return False
check_back_in = get_check_back_in_for_proxy(proxy_addr)
if reg:
- log(u"proxy gets %s, relay %s (now %d)" %
- (safe_str(unicode(reg)), options.relay_spec, num_regs()))
- print >> self.wfile, fac.render_transaction("OK", ("CLIENT", str(reg)), ("RELAY", options.relay_spec), ("CHECK-BACK-IN", str(check_back_in)))
+ log(u"proxy gets %s, num_relays %s (now %d)" %
+ (safe_str(unicode(reg)), options.num_relays(), num_regs()))
+ print >> self.wfile, fac.render_transaction("OK", ("CLIENT", str(reg)), ("RELAY", reg.relay), ("CHECK-BACK-IN", str(check_back_in)))
else:
log(u"proxy gets none")
print >> self.wfile, fac.render_transaction("NONE", ("CHECK-BACK-IN", str(check_back_in)))
@@ -354,9 +380,27 @@ def put_reg(reg):
REGS = get_regs(af, get_outermost_transport(reg.transport_chain))
return REGS.add(reg)
+def parse_relay_file(fname):
+ """
+ Parse a file containing Tor relays that we can point proxies to.
+ Throws ValueError if the file is not properly formatted.
+ """
+ # File format is:
+ # <transport> <addrport>
+ # Example:
+ # obfs2|websocket 1.4.6.1:4123
+ with open(fname) as input:
+ for line in input:
+ words_list = line.split()
+ if len(words_list) != 2:
+ raise ValueError("Wrong line format: %s" % line)
+
+ # XXX Maybe we should validate here
+ options.add_relay(words_list[0], words_list[1])
+
def main():
- opts, args = getopt.gnu_getopt(sys.argv[1:], "dhl:p:r:",
- ["debug", "help", "log=", "port=", "pidfile=", "privdrop-user=", "relay=", "unsafe-logging"])
+ opts, args = getopt.gnu_getopt(sys.argv[1:], "dhl:p:r:f:",
+ ["debug", "help", "log=", "port=", "pidfile=", "privdrop-user=", "relay=", "relay-file=", "unsafe-logging"])
for o, a in opts:
if o == "-d" or o == "--debug":
options.daemonize = False
@@ -374,20 +418,35 @@ def main():
options.privdrop_username = a
elif o == "-r" or o == "--relay":
try:
- options.set_relay_spec(a)
- except socket.gaierror, e:
+ options.add_relay("websocket", a)
+ except (ValueError, socket.gaierror) as e:
print >> sys.stderr, u"Can't resolve relay %s: %s" % (repr(a), str(e))
sys.exit(1)
+ elif o == "-f" or o == "--relay-file":
+ try:
+ parse_relay_file(a)
+ except ValueError as e:
+ print >> sys.stderr, u"Could not parse file '%s': %s" % (repr(a), str(e))
+ sys.exit(1)
elif o == "--unsafe-logging":
options.safe_logging = False
- if not options.relay_spec:
+ if not options.relays:
print >> sys.stderr, """\
The -r option is required. Give it the relay that will be sent to proxies.
-r HOST[:PORT]\
"""
sys.exit(1)
+
+ # Create RegSets for our supported transports
+ for transport in options.relays.keys():
+ outermost_transport = get_outermost_transport(transport)
+ if outermost_transport not in REGSETS_IPV4:
+ REGSETS_IPV4[outermost_transport] = RegSet()
+ REGSETS_IPV6[outermost_transport] = RegSet()
+
+ # Setup log file
if options.log_filename:
options.log_file = open(options.log_filename, "a")
# Send error tracebacks to the log.
@@ -400,7 +459,7 @@ The -r option is required. Give it the relay that will be sent to proxies.
server = Server(addrinfo[4], Handler)
log(u"start on %s" % fac.format_addr(addrinfo[4]))
- log(u"using relay address %s" % options.relay_spec)
+ log(u"using relays %s" % str(options.relays))
if options.daemonize:
log(u"daemonizing")
@@ -427,3 +486,4 @@ The -r option is required. Give it the relay that will be sent to proxies.
if __name__ == "__main__":
main()
+
More information about the tor-commits
mailing list