[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
[tor-commits] [flashproxy/master] Isolate address family manipulation and name resolution within parse_addr_spec.
commit 23d3a7d9756c7bbb5ce6675102b3aefe97d28b32
Author: David Fifield <david@xxxxxxxxxxxxxxx>
Date: Sat Jul 28 12:25:23 2012 -0700
Isolate address family manipulation and name resolution within parse_addr_spec.
facilitator wants to resolve the name given to the --relay option; most
other places we want to insist on numeric address. The facilitator had a
special version of parse_addr_spec that also returned the address
family, in order to allow it to resolve the name itself. Now put all
this special handling inside parse_addr_spec, controlled by a boolean
parameter, and use one parse_addr_spec between facilitator and
facilitator.cgi.
---
fac.py | 46 +++++++++++++++++++++++++++++++++++++++++++---
facilitator | 24 ++++--------------------
2 files changed, 47 insertions(+), 23 deletions(-)
diff --git a/fac.py b/fac.py
index bace28c..b9ad435 100644
--- a/fac.py
+++ b/fac.py
@@ -1,7 +1,28 @@
import re
import socket
-def parse_addr_spec(spec, defhost = None, defport = None):
+def parse_addr_spec(spec, defhost = None, defport = None, resolve = False):
+ """Parse a host:port specification and return a 2-tuple ("host", port) as
+ understood by the Python socket functions.
+ >>> parse_addr_spec("192.168.0.1:9999")
+ ('192.168.0.1', 9999)
+
+ If defhost or defport are given, those parts of the specification may be
+ omitted; if so, they will be filled in with defaults.
+ >>> parse_addr_spec("192.168.0.2:8888", defhost="192.168.0.1", defport=9999)
+ ('192.168.0.2', 8888)
+ >>> parse_addr_spec(":8888", defhost="192.168.0.1", defport=9999)
+ ('192.168.0.1', 9999)
+ >>> parse_addr_spec("192.168.0.2:", defhost="192.168.0.1", defport=9999)
+ ('192.168.0.2', 9999)
+ >>> parse_addr_spec(":", defhost="192.168.0.1", defport=9999)
+ ('192.168.0.1', 9999)
+
+ If resolve is true, then the host in the specification or the defhost may be
+ a domain name, which will be resolved. If resolve is false, then the host
+ must be a numeric IPv4 or IPv6 address.
+
+ IPv6 addresses must be enclosed in square brackets."""
host = None
port = None
m = None
@@ -32,9 +53,28 @@ def parse_addr_spec(spec, defhost = None, defport = None):
af = 0
host = host or defhost
port = port or defport
- if not (host and port):
+ if host is None or port is None:
raise ValueError("Bad address specification \"%s\"" % spec)
- return af, host, int(port)
+
+ # Now we have split around the colon and have a guess at the address family.
+ # Forward-resolve the name into an addrinfo struct. Real DNS resolution is
+ # done only if resolve is true; otherwise the address must be numeric.
+ if resolve:
+ flags = 0
+ else:
+ flags = socket.AI_NUMERICHOST
+ try:
+ addrs = socket.getaddrinfo(host, port, af, socket.SOCK_STREAM, socket.IPPROTO_TCP, flags)
+ except socket.gaierror, e:
+ raise ValueError("Bad host or port: \"%s\" \"%s\": %s" % (host, port, str(e)))
+ if not addrs:
+ raise ValueError("Bad host or port: \"%s\" \"%s\"" % (host, port))
+
+ # Convert the result of socket.getaddrinfo (which is a 2-tuple for IPv4 and
+ # a 4-tuple for IPv6) into a (host, port) 2-tuple.
+ host, port = socket.getnameinfo(addrs[0][4], socket.NI_NUMERICHOST | socket.NI_NUMERICSERV)
+ port = int(port)
+ return host, port
def format_addr(addr):
host, port = addr
diff --git a/facilitator b/facilitator
index d1e25a4..99ef63d 100755
--- a/facilitator
+++ b/facilitator
@@ -33,10 +33,8 @@ class options(object):
@staticmethod
def set_relay_spec(spec):
- af, host, port = fac.parse_addr_spec(spec, defport = DEFAULT_RELAY_PORT)
- # Resolve to get an IP address.
- addrs = socket.getaddrinfo(host, port, af)
- options.relay_spec = fac.format_addr(addrs[0][4])
+ spec = fac.parse_addr_spec(spec, defport = DEFAULT_RELAY_PORT, resolve = True)
+ options.relay_spec = fac.format_addr(spec)
def usage(f = sys.stdout):
print >> f, """\
@@ -92,22 +90,8 @@ class TCPReg(object):
class Reg(object):
@staticmethod
def parse(spec, defhost = None, defport = None):
- try:
- af, host, port = fac.parse_addr_spec(spec, defhost, defport)
- except ValueError:
- pass
- else:
- try:
- addrs = socket.getaddrinfo(host, port, af, socket.SOCK_STREAM, socket.IPPROTO_TCP, socket.AI_NUMERICHOST)
- except socket.gaierror, e:
- raise ValueError("Bad host or port: \"%s\" \"%s\": %s" % (host, port, str(e)))
- if not addrs:
- raise ValueError("Bad host or port: \"%s\" \"%s\"" % (host, port))
-
- host, port = socket.getnameinfo(addrs[0][4], socket.NI_NUMERICHOST | socket.NI_NUMERICSERV)
- return TCPReg(host, int(port))
-
- raise ValueError("Bad spec format: %s" % repr(spec))
+ host, port = fac.parse_addr_spec(spec, defhost, defport)
+ return TCPReg(host, port)
class RegSet(object):
def __init__(self):
_______________________________________________
tor-commits mailing list
tor-commits@xxxxxxxxxxxxxxxxxxxx
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits