[tor-commits] [flashproxy/master] Listen on both IPv4 and IPv6 by default in flashproxy-client.
dcf at torproject.org
dcf at torproject.org
Sun Sep 23 18:22:05 UTC 2012
commit 54c3d895d51562adc3e5b54f44daf8a070fba439
Author: David Fifield <david at bamsoftware.com>
Date: Sun Sep 23 11:19:23 2012 -0700
Listen on both IPv4 and IPv6 by default in flashproxy-client.
If no host is given for the local address, listen on 127.0.0.1 and ::1.
If no host is given for the remote address, listen on 0.0.0.0 and ::.
This adds the ability to listen on more than one local or remote socket,
though this is not exposed in the command-line interface except in this
special case.
---
README | 2 +-
flashproxy-client | 85 +++++++++++++++++++++++++++++++++++------------------
2 files changed, 57 insertions(+), 30 deletions(-)
diff --git a/README b/README
index f5654cf..af19893 100644
--- a/README
+++ b/README
@@ -19,7 +19,7 @@ transport plugin" below to try out the system even behind NAT.
9000. If you have to use a different port (to get through a firewall,
for example), give it on the command lines like this (here using port
8888):
- $ flashproxy-client --register 127.0.0.1:9001 :8888
+ $ flashproxy-client --register :9001 :8888
2. Run Tor using the included torrc file.
$ tor -f torrc
diff --git a/flashproxy-client b/flashproxy-client
index 16c95ec..cf0c0b7 100755
--- a/flashproxy-client
+++ b/flashproxy-client
@@ -29,16 +29,15 @@ try:
except ImportError:
numpy = None
-DEFAULT_REMOTE_ADDRESS = None
-DEFAULT_REMOTE_PORT = 9000
-DEFAULT_LOCAL_ADDRESS = "127.0.0.1"
DEFAULT_LOCAL_PORT = 9001
+DEFAULT_REMOTE_PORT = 9000
LOG_DATE_FORMAT = "%Y-%m-%d %H:%M:%S"
class options(object):
- local_addr = None
- remote_addr = None
+ local_addrs = []
+ remote_addrs = []
+ register_addr = None
facilitator_url = None
log_filename = None
@@ -57,7 +56,8 @@ def usage(f = sys.stdout):
Usage: %(progname)s --register [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".
+LOCAL is localhost addresses on port %(local_port)d and REMOTE is all addresses
+on port %(remote_port)d.
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
@@ -76,8 +76,8 @@ facilitator is used; if omitted, it uses a public default.
--unsafe-logging don't scrub IP addresses from logs.\
""" % {
"progname": sys.argv[0],
- "local": format_addr((DEFAULT_LOCAL_ADDRESS, DEFAULT_LOCAL_PORT)),
- "remote": format_addr((DEFAULT_REMOTE_ADDRESS, DEFAULT_REMOTE_PORT)),
+ "local_port": DEFAULT_LOCAL_PORT,
+ "remote_port": DEFAULT_REMOTE_PORT,
}
def safe_str(s):
@@ -433,10 +433,16 @@ class WebSocketBinaryEncoder(object):
def listen_socket(addr):
"""Return a nonblocking socket listening on the given address."""
- addr = (addr[0] or "0.0.0.0", addr[1])
addrinfo = socket.getaddrinfo(addr[0], addr[1], 0, socket.SOCK_STREAM, socket.IPPROTO_TCP)[0]
s = socket.socket(addrinfo[0], addrinfo[1], addrinfo[2])
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
+ if addrinfo[0] == socket.AF_INET6 and socket.has_ipv6:
+ # Set the IPV6_V6ONLY socket option, otherwise some operating systems
+ # will listen on an IPv4 address as well as IPv6 by default. For
+ # example, "::" will listen on both "::" and "0.0.0.0", and "::1" will
+ # listen on both "::1" and "127.0.0.1". See
+ # https://trac.torproject.org/projects/tor/ticket/4760.
+ s.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_V6ONLY, 1)
s.bind(addr)
s.listen(10)
s.setblocking(0)
@@ -639,7 +645,7 @@ def register():
# Maybe the script was read from stdin; in any case don't guess at the directory.
return
command = [os.path.join(script_dir, "flashproxy-reg-http")]
- spec = format_addr(options.remote_addr)
+ spec = format_addr(options.register_addr)
if options.facilitator_url is None:
log(u"Registering \"%s\"." % spec)
else:
@@ -792,14 +798,14 @@ class LocalSocket(object):
def main():
while True:
- rset = [remote_s, local_s] + websocket_pending + socks_pending + locals + remotes
+ rset = remote_listen + local_listen + websocket_pending + socks_pending + locals + remotes
rset, _, _ = select.select(rset, [], [], WEBSOCKET_REQUEST_TIMEOUT)
for fd in rset:
- if fd == remote_s:
+ if fd in remote_listen:
remote_c, addr = fd.accept()
log(u"Remote connection from %s." % safe_format_sockaddr(addr))
websocket_pending.append(TimeoutSocket(remote_c))
- elif fd == local_s:
+ elif fd in local_listen:
local_c, addr = fd.accept()
log(u"Local connection from %s." % safe_format_sockaddr(addr))
socks_pending.append(local_c)
@@ -879,30 +885,51 @@ if __name__ == "__main__":
elif o == "--unsafe-logging":
options.safe_logging = False
+ if options.log_filename:
+ options.log_file = open(options.log_filename, "a")
+ # Send error tracebacks to the log.
+ sys.stderr = options.log_file
+ else:
+ options.log_file = sys.stdout
+
if len(args) == 0:
- options.local_addr = (DEFAULT_LOCAL_ADDRESS, DEFAULT_LOCAL_PORT)
- options.remote_addr = (DEFAULT_REMOTE_ADDRESS, DEFAULT_REMOTE_PORT)
+ local_addr = (None, DEFAULT_LOCAL_PORT)
+ remote_addr = (None, DEFAULT_REMOTE_PORT)
elif len(args) == 1:
- options.local_addr = parse_addr_spec(args[0], DEFAULT_LOCAL_ADDRESS, DEFAULT_LOCAL_PORT)
- options.remote_addr = (DEFAULT_REMOTE_ADDRESS, DEFAULT_REMOTE_PORT)
+ local_addr = parse_addr_spec(args[0], defport=DEFAULT_LOCAL_PORT)
+ remote_addr = (None, DEFAULT_REMOTE_PORT)
elif len(args) == 2:
- options.local_addr = parse_addr_spec(args[0], DEFAULT_LOCAL_ADDRESS, DEFAULT_LOCAL_PORT)
- options.remote_addr = parse_addr_spec(args[1], DEFAULT_REMOTE_ADDRESS, DEFAULT_REMOTE_PORT)
+ local_addr = parse_addr_spec(args[0], defport=DEFAULT_LOCAL_PORT)
+ remote_addr = parse_addr_spec(args[1], defport=DEFAULT_REMOTE_PORT)
else:
usage(sys.stderr)
sys.exit(1)
- if options.log_filename:
- options.log_file = open(options.log_filename, "a")
- # Send error tracebacks to the log.
- sys.stderr = options.log_file
+ # Listen on both IPv4 and IPv6 if no host is given.
+ if local_addr[0]:
+ options.local_addrs.append(local_addr)
else:
- options.log_file = sys.stdout
-
- # Local socket, accepting SOCKS requests from localhost
- local_s = listen_socket(options.local_addr)
- # Remote socket, accepting remote WebSocket connections from proxies.
- remote_s = listen_socket(options.remote_addr)
+ options.local_addrs.append(("127.0.0.1", local_addr[1]))
+ if socket.has_ipv6:
+ options.local_addrs.append(("::1", local_addr[1]))
+ if remote_addr[0]:
+ options.remote_addrs.append(remote_addr)
+ else:
+ options.remote_addrs.append(("0.0.0.0", remote_addr[1]))
+ if socket.has_ipv6:
+ options.remote_addrs.append(("::", remote_addr[1]))
+ options.register_addr = remote_addr
+
+ # Local sockets, accepting SOCKS requests from localhost
+ local_listen = []
+ for addr in options.local_addrs:
+ local_listen.append(listen_socket(addr))
+ log(u"Listening local on %s." % format_addr(addr))
+ # Remote sockets, accepting remote WebSocket connections from proxies.
+ remote_listen = []
+ for addr in options.remote_addrs:
+ remote_listen.append(listen_socket(addr))
+ log(u"Listening remote on %s." % format_addr(addr))
# New remote sockets waiting to finish their WebSocket negotiation.
websocket_pending = []
More information about the tor-commits
mailing list