[tor-commits] [flashproxy/master] Use resolved listener addresses for port forwarding.

dcf at torproject.org dcf at torproject.org
Sun Feb 2 01:34:29 UTC 2014


commit 945418905fd844913fed6328a2e3e664785ca398
Author: David Fifield <david at bamsoftware.com>
Date:   Sat Feb 1 16:32:51 2014 -0800

    Use resolved listener addresses for port forwarding.
    
    Previously we used remote_addr, the actual address given on the command
    line. The difference is that after opening the listener, we know what
    port ":0" became, so this is now possible:
    	./flashproxy-client --external --port-forwarding :9001 :0
    The other thing we can do is skip IPv6 addresses, because it appears
    that UPnP and NAT-PMP are for TCP/IPv4 ports only.
    
    The above command will produce output like
    
    2014-02-01 17:07:01 Listening remote on 0.0.0.0:40138.
    2014-02-01 17:07:01 Listening remote on [::]:55179.
    2014-02-01 17:07:01 Listening local on 127.0.0.1:9001.
    2014-02-01 17:07:01 Listening local on [::1]:9001.
    2014-02-01 17:07:01 Not forwarding to [::]:55179 because it is not an IPv4 address.
    2014-02-01 17:07:01 Running port forwarding command: tor-fw-helper -p 40138:40138
---
 flashproxy-client |   36 ++++++++++++++++++++++++++----------
 1 file changed, 26 insertions(+), 10 deletions(-)

diff --git a/flashproxy-client b/flashproxy-client
index ee0b068..6a7667e 100755
--- a/flashproxy-client
+++ b/flashproxy-client
@@ -19,7 +19,7 @@ import threading
 import time
 import traceback
 
-from flashproxy.util import parse_addr_spec, format_addr
+from flashproxy.util import parse_addr_spec, addr_family, format_addr
 
 from hashlib import sha1
 
@@ -678,6 +678,27 @@ def forward_ports(pairs):
         return False
     return True
 
+def forward_listeners(listeners):
+    """Attempt to forward the ports belonging to the given listening sockets.
+    Non-IPv4 addresses are ignored. If options.port_forwarding_external is not
+    None, only the first IPv4 address in the list will be forwarded."""
+    forward_list = []
+    for listener in remote_listen:
+        host, port = socket.getnameinfo(listener.getsockname(), socket.NI_NUMERICHOST | socket.NI_NUMERICSERV)
+        port = int(port)
+        af = addr_family(host)
+        if af != socket.AF_INET:
+            # I guess tor-fw-helper can only handle IPv4.
+            log(u"Not forwarding to %s because it is not an IPv4 address." % format_addr((host, port)))
+            continue
+        if options.port_forwarding_external is not None:
+            forward_list.append((options.port_forwarding_external, port))
+            # A fixed external address means we can forward only one port.
+            break
+        else:
+            forward_list.append((port, port))
+    forward_ports(forward_list)
+
 register_condvar = threading.Condition()
 # register_flag true means registration_thread_func should register at its next
 # opportunity.
@@ -1165,15 +1186,6 @@ def main():
     for method in register_methods:
         options.register_commands.append(build_register_command(method))
 
-    # Attempt to forward ports if requested.
-    if options.port_forwarding:
-        internal = remote_addr[1]
-        if options.port_forwarding_external is not None:
-            external = options.port_forwarding_external
-        else:
-            external = internal
-        forward_ports(((external, internal),))
-
     # Remote sockets, accepting remote WebSocket connections from proxies.
     remote_listen = []
     for addr in options.remote_addrs:
@@ -1206,6 +1218,10 @@ def main():
     if options.managed:
         pt_cmethods_done()
 
+    # Attempt to forward ports if requested.
+    if options.port_forwarding:
+        forward_listeners(remote_listen)
+
     # New remote sockets waiting to finish their WebSocket negotiation.
     websocket_pending = []
     # Remote connection sockets.





More information about the tor-commits mailing list