commit d9be6f4e8fe86c216f85f31d2ff3461d34d16a10 Author: Arlo Breault arlolra@gmail.com Date: Fri Jun 7 11:41:56 2013 -0700
Add a --nat-traversal flag to flashproxy-client.
Uses the tor-fw-helper. --- flashproxy-client | 38 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 36 insertions(+), 2 deletions(-)
diff --git a/flashproxy-client b/flashproxy-client index 7feaefe..2e1ce45 100755 --- a/flashproxy-client +++ b/flashproxy-client @@ -60,6 +60,7 @@ class options(object): register_commands = [] pid_filename = None safe_logging = True + nat_traversal = False address_family = socket.AF_UNSPEC
# We accept up to this many bytes from a socket not yet matched with a partner @@ -112,6 +113,7 @@ omitted, it uses a public default. methods. Implies --register. Possible methods are appspot email http Default is "%(reg_methods)s". + --nat-traversal attempt to traverse NAT with tor-fw-helper. --unsafe-logging don't scrub IP addresses from logs.\ """ % { "progname": sys.argv[0], @@ -127,6 +129,29 @@ def safe_str(s): else: return s
+def traverse_nat(): + if not options.nat_traversal: + return False + port = options.remote_addrs[0][1] + script_path = os.path.join(get_script_dir(), "tor-fw-helper") + command = [script_path, "-p", ":%s" % port] + try: + log(u"Attempting NAT traversal for port: %d" % port) + p = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + stdout, stderr = p.communicate() + except OSError, e: + log(u"Error opening tor-fw-helper.") + return False + if p.returncode != 0: + log("tor-fw-helper exited with status %d." % p.returncode) + return False + line = stdout.split() + if len(line) >= 5 and line[4] == "SUCCESS": + log(u"NAT traversal succeeded.") + return True + log(u"NAT traversal failed.") + return False + log_lock = threading.Lock() def log(msg): log_lock.acquire() @@ -948,7 +973,7 @@ def proxy_loop(): websocket_pending.pop(0) report_pending()
-def build_register_command(method): +def get_script_dir(): # sys.path[0] usually contains the directory the script is located in. # py2exe overwrites this for bundled executables. if getattr(sys, "frozen", False): @@ -958,6 +983,10 @@ def build_register_command(method): if not script_dir: # Maybe the script was read from stdin; in any case don't guess at the directory. raise ValueError("Can't find executable directory for registration helpers") + return script_dir + +def build_register_command(method): + script_dir = get_script_dir() af = [] if options.address_family == socket.AF_INET: af = ["-4"] @@ -1056,7 +1085,7 @@ def main(): register_addr_spec = None register_methods = []
- opts, args = getopt.gnu_getopt(sys.argv[1:], "46f:hl:r", ["daemon", "external", "facilitator=", "facilitator-pubkey=", "help", "log=", "pidfile=", "register", "register-addr=", "register-methods=", "unsafe-logging"]) + opts, args = getopt.gnu_getopt(sys.argv[1:], "46f:hl:r", ["daemon", "external", "facilitator=", "facilitator-pubkey=", "help", "log=", "pidfile=", "register", "register-addr=", "register-methods=", "nat-traversal", "unsafe-logging"]) for o, a in opts: if o == "-4": options.address_family = socket.AF_INET @@ -1088,6 +1117,8 @@ def main(): elif o == "--register-methods": options.register = True register_methods.extend(a.split(",")) + elif o == "--nat-traversal": + options.nat_traversal = True elif o == "--unsafe-logging": options.safe_logging = False
@@ -1143,6 +1174,9 @@ def main(): for method in register_methods: options.register_commands.append(build_register_command(method))
+ # Attempt to traverse NAT if enabled + traverse_nat() + # Remote sockets, accepting remote WebSocket connections from proxies. remote_listen = [] for addr in options.remote_addrs: