commit 945418905fd844913fed6328a2e3e664785ca398 Author: David Fifield david@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.