mirror of
https://github.com/sshuttle/sshuttle.git
synced 2025-04-23 02:38:30 +02:00
TProxy IPv6 support.
This commit is contained in:
parent
f41c6b62e5
commit
20254bab57
51
client.py
51
client.py
@ -99,41 +99,55 @@ def original_dst(sock):
|
|||||||
class MultiListener:
|
class MultiListener:
|
||||||
|
|
||||||
def __init__(self, type=socket.SOCK_STREAM, proto=0):
|
def __init__(self, type=socket.SOCK_STREAM, proto=0):
|
||||||
|
self.v6 = socket.socket(socket.AF_INET6, type, proto)
|
||||||
self.v4 = socket.socket(socket.AF_INET, type, proto)
|
self.v4 = socket.socket(socket.AF_INET, type, proto)
|
||||||
|
|
||||||
def setsockopt(self, level, optname, value):
|
def setsockopt(self, level, optname, value):
|
||||||
|
if self.v6:
|
||||||
|
self.v6.setsockopt(level, optname, value)
|
||||||
if self.v4:
|
if self.v4:
|
||||||
self.v4.setsockopt(level, optname, value)
|
self.v4.setsockopt(level, optname, value)
|
||||||
|
|
||||||
def add_handler(self, handlers, callback, method, mux):
|
def add_handler(self, handlers, callback, method, mux):
|
||||||
|
if self.v6:
|
||||||
|
handlers.append(Handler([self.v6], lambda: callback(self.v6, method, mux, handlers)))
|
||||||
if self.v4:
|
if self.v4:
|
||||||
handlers.append(Handler([self.v4], lambda: callback(self.v4, method, mux, handlers)))
|
handlers.append(Handler([self.v4], lambda: callback(self.v4, method, mux, handlers)))
|
||||||
|
|
||||||
def listen(self, backlog):
|
def listen(self, backlog):
|
||||||
|
if self.v6:
|
||||||
|
self.v6.listen(backlog)
|
||||||
if self.v4:
|
if self.v4:
|
||||||
self.v4.listen(backlog)
|
self.v4.listen(backlog)
|
||||||
|
|
||||||
def bind(self, address_v4):
|
def bind(self, address_v6, address_v4):
|
||||||
|
if address_v6 and self.v6:
|
||||||
|
self.v6.bind(address_v6)
|
||||||
|
else:
|
||||||
|
self.v6 = None
|
||||||
if address_v4 and self.v4:
|
if address_v4 and self.v4:
|
||||||
self.v4.bind(address_v4)
|
self.v4.bind(address_v4)
|
||||||
else:
|
else:
|
||||||
self.v4 = None
|
self.v4 = None
|
||||||
|
|
||||||
def print_listening(self, what):
|
def print_listening(self, what):
|
||||||
|
if self.v6:
|
||||||
|
listenip = self.v6.getsockname()
|
||||||
|
debug1('%s listening on %r.\n' % (what, listenip))
|
||||||
if self.v4:
|
if self.v4:
|
||||||
listenip = self.v4.getsockname()
|
listenip = self.v4.getsockname()
|
||||||
debug1('%s listening on %r.\n' % (what, listenip))
|
debug1('%s listening on %r.\n' % (what, listenip))
|
||||||
|
|
||||||
|
|
||||||
class FirewallClient:
|
class FirewallClient:
|
||||||
def __init__(self, port_v4, subnets_include, subnets_exclude, dnsport_v4, method):
|
def __init__(self, port_v6, port_v4, subnets_include, subnets_exclude, dnsport_v6, dnsport_v4, method):
|
||||||
self.auto_nets = []
|
self.auto_nets = []
|
||||||
self.subnets_include = subnets_include
|
self.subnets_include = subnets_include
|
||||||
self.subnets_exclude = subnets_exclude
|
self.subnets_exclude = subnets_exclude
|
||||||
argvbase = ([sys.argv[1], sys.argv[0], sys.argv[1]] +
|
argvbase = ([sys.argv[1], sys.argv[0], sys.argv[1]] +
|
||||||
['-v'] * (helpers.verbose or 0) +
|
['-v'] * (helpers.verbose or 0) +
|
||||||
['--firewall', str(port_v4),
|
['--firewall', str(port_v6), str(port_v4),
|
||||||
str(dnsport_v4),
|
str(dnsport_v6), str(dnsport_v4),
|
||||||
method])
|
method])
|
||||||
if ssyslog._p:
|
if ssyslog._p:
|
||||||
argvbase += ['--syslog']
|
argvbase += ['--syslog']
|
||||||
@ -376,7 +390,7 @@ def _main(tcp_listener, fw, ssh_cmd, remotename, python, latency_control,
|
|||||||
mux.callback()
|
mux.callback()
|
||||||
|
|
||||||
|
|
||||||
def main(listenip_v4,
|
def main(listenip_v6, listenip_v4,
|
||||||
ssh_cmd, remotename, python, latency_control, dns,
|
ssh_cmd, remotename, python, latency_control, dns,
|
||||||
method, seed_hosts, auto_nets,
|
method, seed_hosts, auto_nets,
|
||||||
subnets_include, subnets_exclude, syslog, daemon, pidfile):
|
subnets_include, subnets_exclude, syslog, daemon, pidfile):
|
||||||
@ -390,7 +404,7 @@ def main(listenip_v4,
|
|||||||
return 5
|
return 5
|
||||||
debug1('Starting sshuttle proxy.\n')
|
debug1('Starting sshuttle proxy.\n')
|
||||||
|
|
||||||
if listenip_v4 and listenip_v4[1]:
|
if listenip_v6 and listenip_v6[1] and listenip_v4 and listenip_v4[1]:
|
||||||
# if both ports given, no need to search for a spare port
|
# if both ports given, no need to search for a spare port
|
||||||
ports = [ 0, ]
|
ports = [ 0, ]
|
||||||
else:
|
else:
|
||||||
@ -399,6 +413,7 @@ def main(listenip_v4,
|
|||||||
|
|
||||||
# search for free ports and try to bind
|
# search for free ports and try to bind
|
||||||
last_e = None
|
last_e = None
|
||||||
|
redirectport_v6 = 0
|
||||||
redirectport_v4 = 0
|
redirectport_v4 = 0
|
||||||
bound = False
|
bound = False
|
||||||
debug2('Binding redirector:')
|
debug2('Binding redirector:')
|
||||||
@ -407,6 +422,16 @@ def main(listenip_v4,
|
|||||||
tcp_listener = MultiListener()
|
tcp_listener = MultiListener()
|
||||||
tcp_listener.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
|
tcp_listener.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
|
||||||
|
|
||||||
|
if listenip_v6 and listenip_v6[1]:
|
||||||
|
lv6 = listenip_v6
|
||||||
|
redirectport_v6 = lv6[1]
|
||||||
|
elif listenip_v6:
|
||||||
|
lv6 = (listenip_v6[0],port)
|
||||||
|
redirectport_v6 = port
|
||||||
|
else:
|
||||||
|
lv6 = None
|
||||||
|
redirectport_v6 = 0
|
||||||
|
|
||||||
if listenip_v4 and listenip_v4[1]:
|
if listenip_v4 and listenip_v4[1]:
|
||||||
lv4 = listenip_v4
|
lv4 = listenip_v4
|
||||||
redirectport_v4 = lv4[1]
|
redirectport_v4 = lv4[1]
|
||||||
@ -418,7 +443,7 @@ def main(listenip_v4,
|
|||||||
redirectport_v4 = 0
|
redirectport_v4 = 0
|
||||||
|
|
||||||
try:
|
try:
|
||||||
tcp_listener.bind(lv4)
|
tcp_listener.bind(lv6, lv4)
|
||||||
bound = True
|
bound = True
|
||||||
break
|
break
|
||||||
except socket.error, e:
|
except socket.error, e:
|
||||||
@ -443,6 +468,13 @@ def main(listenip_v4,
|
|||||||
dns_listener = MultiListener(socket.SOCK_DGRAM)
|
dns_listener = MultiListener(socket.SOCK_DGRAM)
|
||||||
dns_listener.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
|
dns_listener.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
|
||||||
|
|
||||||
|
if listenip_v6:
|
||||||
|
lv6 = (listenip_v6[0],port)
|
||||||
|
dnsport_v6 = port
|
||||||
|
else:
|
||||||
|
lv6 = None
|
||||||
|
dnsport_v6 = 0
|
||||||
|
|
||||||
if listenip_v4:
|
if listenip_v4:
|
||||||
lv4 = (listenip_v4[0],port)
|
lv4 = (listenip_v4[0],port)
|
||||||
dnsport_v4 = port
|
dnsport_v4 = port
|
||||||
@ -451,7 +483,7 @@ def main(listenip_v4,
|
|||||||
dnsport_v4 = 0
|
dnsport_v4 = 0
|
||||||
|
|
||||||
try:
|
try:
|
||||||
dns_listener.bind(lv4)
|
dns_listener.bind(lv6, lv4)
|
||||||
bound = True
|
bound = True
|
||||||
break
|
break
|
||||||
except socket.error, e:
|
except socket.error, e:
|
||||||
@ -465,10 +497,11 @@ def main(listenip_v4,
|
|||||||
assert(last_e)
|
assert(last_e)
|
||||||
raise last_e
|
raise last_e
|
||||||
else:
|
else:
|
||||||
|
dnsport_v6 = 0
|
||||||
dnsport_v4 = 0
|
dnsport_v4 = 0
|
||||||
dns_listener = None
|
dns_listener = None
|
||||||
|
|
||||||
fw = FirewallClient(redirectport_v4, subnets_include, subnets_exclude, dnsport_v4, method)
|
fw = FirewallClient(redirectport_v6, redirectport_v4, subnets_include, subnets_exclude, dnsport_v6, dnsport_v4, method)
|
||||||
|
|
||||||
if fw.method == "tproxy":
|
if fw.method == "tproxy":
|
||||||
tcp_listener.setsockopt(socket.SOL_IP, IP_TRANSPARENT, 1)
|
tcp_listener.setsockopt(socket.SOL_IP, IP_TRANSPARENT, 1)
|
||||||
|
32
firewall.py
32
firewall.py
@ -15,7 +15,9 @@ def nonfatal(func, *args):
|
|||||||
|
|
||||||
|
|
||||||
def ipt_chain_exists(family, table, name):
|
def ipt_chain_exists(family, table, name):
|
||||||
if family == socket.AF_INET:
|
if family == socket.AF_INET6:
|
||||||
|
cmd = 'ip6tables'
|
||||||
|
elif family == socket.AF_INET:
|
||||||
cmd = 'iptables'
|
cmd = 'iptables'
|
||||||
else:
|
else:
|
||||||
raise Exception('Unsupported family "%s"'%family_to_string(family))
|
raise Exception('Unsupported family "%s"'%family_to_string(family))
|
||||||
@ -30,7 +32,9 @@ def ipt_chain_exists(family, table, name):
|
|||||||
|
|
||||||
|
|
||||||
def _ipt(family, table, *args):
|
def _ipt(family, table, *args):
|
||||||
if family == socket.AF_INET:
|
if family == socket.AF_INET6:
|
||||||
|
argv = ['ip6tables', '-t', table] + list(args)
|
||||||
|
elif family == socket.AF_INET:
|
||||||
argv = ['iptables', '-t', table] + list(args)
|
argv = ['iptables', '-t', table] + list(args)
|
||||||
else:
|
else:
|
||||||
raise Exception('Unsupported family "%s"'%family_to_string(family))
|
raise Exception('Unsupported family "%s"'%family_to_string(family))
|
||||||
@ -110,7 +114,7 @@ def do_iptables_nat(port, dnsport, family, subnets):
|
|||||||
|
|
||||||
if dnsport:
|
if dnsport:
|
||||||
nslist = resolvconf_nameservers()
|
nslist = resolvconf_nameservers()
|
||||||
for ip in nslist:
|
for f,ip in filter(lambda i: i[0]==family, nslist):
|
||||||
ipt_ttl('-A', chain, '-j', 'REDIRECT',
|
ipt_ttl('-A', chain, '-j', 'REDIRECT',
|
||||||
'--dest', '%s/32' % ip,
|
'--dest', '%s/32' % ip,
|
||||||
'-p', 'udp',
|
'-p', 'udp',
|
||||||
@ -119,7 +123,7 @@ def do_iptables_nat(port, dnsport, family, subnets):
|
|||||||
|
|
||||||
|
|
||||||
def do_iptables_tproxy(port, dnsport, family, subnets):
|
def do_iptables_tproxy(port, dnsport, family, subnets):
|
||||||
if family not in [socket.AF_INET]:
|
if family not in [socket.AF_INET, socket.AF_INET6]:
|
||||||
raise Exception('Address family "%s" unsupported by tproxy method'%family_to_string(family))
|
raise Exception('Address family "%s" unsupported by tproxy method'%family_to_string(family))
|
||||||
|
|
||||||
table = "mangle"
|
table = "mangle"
|
||||||
@ -367,7 +371,7 @@ def do_ipfw(port, dnsport, family, subnets):
|
|||||||
divertsock.bind(('0.0.0.0', port)) # IP field is ignored
|
divertsock.bind(('0.0.0.0', port)) # IP field is ignored
|
||||||
|
|
||||||
nslist = resolvconf_nameservers()
|
nslist = resolvconf_nameservers()
|
||||||
for ip in nslist:
|
for f,ip in filter(lambda i: i[0]==family, nslist):
|
||||||
# relabel and then catch outgoing DNS requests
|
# relabel and then catch outgoing DNS requests
|
||||||
ipfw('add', sport, 'divert', sport,
|
ipfw('add', sport, 'divert', sport,
|
||||||
'log', 'udp',
|
'log', 'udp',
|
||||||
@ -450,9 +454,13 @@ def restore_etc_hosts(port):
|
|||||||
# exit. In case that fails, it's not the end of the world; future runs will
|
# exit. In case that fails, it's not the end of the world; future runs will
|
||||||
# supercede it in the transproxy list, at least, so the leftover rules
|
# supercede it in the transproxy list, at least, so the leftover rules
|
||||||
# are hopefully harmless.
|
# are hopefully harmless.
|
||||||
def main(port_v4, dnsport_v4, method, syslog):
|
def main(port_v6, port_v4, dnsport_v6, dnsport_v4, method, syslog):
|
||||||
assert(port_v4 > 0)
|
assert(port_v6 >= 0)
|
||||||
|
assert(port_v6 <= 65535)
|
||||||
|
assert(port_v4 >= 0)
|
||||||
assert(port_v4 <= 65535)
|
assert(port_v4 <= 65535)
|
||||||
|
assert(dnsport_v6 >= 0)
|
||||||
|
assert(dnsport_v6 <= 65535)
|
||||||
assert(dnsport_v4 >= 0)
|
assert(dnsport_v4 >= 0)
|
||||||
assert(dnsport_v4 <= 65535)
|
assert(dnsport_v4 <= 65535)
|
||||||
|
|
||||||
@ -519,6 +527,12 @@ def main(port_v4, dnsport_v4, method, syslog):
|
|||||||
if line:
|
if line:
|
||||||
debug1('firewall manager: starting transproxy.\n')
|
debug1('firewall manager: starting transproxy.\n')
|
||||||
|
|
||||||
|
subnets_v6 = filter(lambda i: i[0]==socket.AF_INET6, subnets)
|
||||||
|
if port_v6:
|
||||||
|
do_wait = do_it(port_v6, dnsport_v6, socket.AF_INET6, subnets_v6)
|
||||||
|
elif len(subnets_v6) > 0:
|
||||||
|
debug1("IPv6 subnets defined but IPv6 disabled\n")
|
||||||
|
|
||||||
subnets_v4 = filter(lambda i: i[0]==socket.AF_INET, subnets)
|
subnets_v4 = filter(lambda i: i[0]==socket.AF_INET, subnets)
|
||||||
if port_v4:
|
if port_v4:
|
||||||
do_wait = do_it(port_v4, dnsport_v4, socket.AF_INET, subnets_v4)
|
do_wait = do_it(port_v4, dnsport_v4, socket.AF_INET, subnets_v4)
|
||||||
@ -543,7 +557,7 @@ def main(port_v4, dnsport_v4, method, syslog):
|
|||||||
if line.startswith('HOST '):
|
if line.startswith('HOST '):
|
||||||
(name,ip) = line[5:].strip().split(',', 1)
|
(name,ip) = line[5:].strip().split(',', 1)
|
||||||
hostmap[name] = ip
|
hostmap[name] = ip
|
||||||
rewrite_etc_hosts(port_v4)
|
rewrite_etc_hosts(port_v6 or port_v4)
|
||||||
elif line:
|
elif line:
|
||||||
raise Fatal('expected EOF, got %r' % line)
|
raise Fatal('expected EOF, got %r' % line)
|
||||||
else:
|
else:
|
||||||
@ -555,4 +569,4 @@ def main(port_v4, dnsport_v4, method, syslog):
|
|||||||
pass
|
pass
|
||||||
if port_v4:
|
if port_v4:
|
||||||
do_it(port_v4, 0, socket.AF_INET, [])
|
do_it(port_v4, 0, socket.AF_INET, [])
|
||||||
restore_etc_hosts(port_v4)
|
restore_etc_hosts(port_v6 or port_v4)
|
||||||
|
@ -42,7 +42,10 @@ def resolvconf_nameservers():
|
|||||||
for line in open('/etc/resolv.conf'):
|
for line in open('/etc/resolv.conf'):
|
||||||
words = line.lower().split()
|
words = line.lower().split()
|
||||||
if len(words) >= 2 and words[0] == 'nameserver':
|
if len(words) >= 2 and words[0] == 'nameserver':
|
||||||
l.append(words[1])
|
if ':' in words[1]:
|
||||||
|
l.append((socket.AF_INET6,words[1]))
|
||||||
|
else:
|
||||||
|
l.append((socket.AF_INET,words[1]))
|
||||||
return l
|
return l
|
||||||
|
|
||||||
|
|
||||||
@ -55,7 +58,7 @@ def resolvconf_random_nameserver():
|
|||||||
random.shuffle(l)
|
random.shuffle(l)
|
||||||
return l[0]
|
return l[0]
|
||||||
else:
|
else:
|
||||||
return '127.0.0.1'
|
return (socket.AF_INET,'127.0.0.1')
|
||||||
|
|
||||||
|
|
||||||
def islocal(ip,family):
|
def islocal(ip,family):
|
||||||
|
59
main.py
59
main.py
@ -22,12 +22,31 @@ def parse_subnet4(s):
|
|||||||
return(socket.AF_INET, '%d.%d.%d.%d' % (a,b,c,d), width)
|
return(socket.AF_INET, '%d.%d.%d.%d' % (a,b,c,d), width)
|
||||||
|
|
||||||
|
|
||||||
|
# 1:2::3/64 or just 1:2::3
|
||||||
|
def parse_subnet6(s):
|
||||||
|
m = re.match(r'(?:([a-fA-F\d:]+))?(?:/(\d+))?$', s)
|
||||||
|
if not m:
|
||||||
|
raise Fatal('%r is not a valid IP subnet format' % s)
|
||||||
|
(net,width) = m.groups()
|
||||||
|
if width == None:
|
||||||
|
width = 128
|
||||||
|
else:
|
||||||
|
width = int(width)
|
||||||
|
if width > 128:
|
||||||
|
raise Fatal('*/%d is greater than the maximum of 128' % width)
|
||||||
|
return(socket.AF_INET6, net, width)
|
||||||
|
|
||||||
|
|
||||||
# list of:
|
# list of:
|
||||||
# 1.2.3.4/5 or just 1.2.3.4
|
# 1.2.3.4/5 or just 1.2.3.4
|
||||||
|
# 1:2::3/64 or just 1:2::3
|
||||||
def parse_subnets(subnets_str):
|
def parse_subnets(subnets_str):
|
||||||
subnets = []
|
subnets = []
|
||||||
for s in subnets_str:
|
for s in subnets_str:
|
||||||
subnet = parse_subnet4(s)
|
if ':' in s:
|
||||||
|
subnet = parse_subnet6(s)
|
||||||
|
else:
|
||||||
|
subnet = parse_subnet4(s)
|
||||||
subnets.append(subnet)
|
subnets.append(subnet)
|
||||||
return subnets
|
return subnets
|
||||||
|
|
||||||
@ -50,13 +69,24 @@ def parse_ipport4(s):
|
|||||||
return ('%d.%d.%d.%d' % (a,b,c,d), port)
|
return ('%d.%d.%d.%d' % (a,b,c,d), port)
|
||||||
|
|
||||||
|
|
||||||
|
# [1:2::3]:456 or [1:2::3] or 456
|
||||||
|
def parse_ipport6(s):
|
||||||
|
s = str(s)
|
||||||
|
m = re.match(r'(?:\[([^]]*)])?(?::)?(?:(\d+))?$', s)
|
||||||
|
if not m:
|
||||||
|
raise Fatal('%s is not a valid IP:port format' % s)
|
||||||
|
(ip,port) = m.groups()
|
||||||
|
(ip,port) = (ip or '::', int(port or 0))
|
||||||
|
return (ip, port)
|
||||||
|
|
||||||
|
|
||||||
optspec = """
|
optspec = """
|
||||||
sshuttle [-l [ip:]port] [-r [username@]sshserver[:port]] <subnets...>
|
sshuttle [-l [ip:]port] [-r [username@]sshserver[:port]] <subnets...>
|
||||||
sshuttle --server
|
sshuttle --server
|
||||||
sshuttle --firewall <port> <subnets...>
|
sshuttle --firewall <port> <subnets...>
|
||||||
sshuttle --hostwatch
|
sshuttle --hostwatch
|
||||||
--
|
--
|
||||||
l,listen= transproxy to this ip address and port number [127.0.0.1:0]
|
l,listen= transproxy to this ip address and port number
|
||||||
H,auto-hosts scan for remote hostnames and update local /etc/hosts
|
H,auto-hosts scan for remote hostnames and update local /etc/hosts
|
||||||
N,auto-nets automatically determine subnets to route
|
N,auto-nets automatically determine subnets to route
|
||||||
dns capture local DNS requests and forward to the remote DNS server
|
dns capture local DNS requests and forward to the remote DNS server
|
||||||
@ -93,10 +123,11 @@ try:
|
|||||||
server.latency_control = opt.latency_control
|
server.latency_control = opt.latency_control
|
||||||
sys.exit(server.main())
|
sys.exit(server.main())
|
||||||
elif opt.firewall:
|
elif opt.firewall:
|
||||||
if len(extra) != 3:
|
if len(extra) != 5:
|
||||||
o.fatal('exactly three arguments expected')
|
o.fatal('exactly five arguments expected')
|
||||||
sys.exit(firewall.main(int(extra[0]), int(extra[1]),
|
sys.exit(firewall.main(int(extra[0]), int(extra[1]),
|
||||||
extra[2], opt.syslog))
|
int(extra[2]), int(extra[3]),
|
||||||
|
extra[4], opt.syslog))
|
||||||
elif opt.hostwatch:
|
elif opt.hostwatch:
|
||||||
sys.exit(hostwatch.hw_main(extra))
|
sys.exit(hostwatch.hw_main(extra))
|
||||||
else:
|
else:
|
||||||
@ -124,8 +155,22 @@ try:
|
|||||||
method = opt.method
|
method = opt.method
|
||||||
else:
|
else:
|
||||||
o.fatal("method %s not supported"%opt.method)
|
o.fatal("method %s not supported"%opt.method)
|
||||||
ipport_v4 = parse_ipport4(opt.listen or '0.0.0.0:0')
|
if not opt.listen:
|
||||||
sys.exit(client.main(ipport_v4,
|
if opt.method == "tproxy":
|
||||||
|
ipport_v6 = parse_ipport6('[::1]:0')
|
||||||
|
else:
|
||||||
|
ipport_v6 = None
|
||||||
|
ipport_v4 = parse_ipport4('127.0.0.1:0')
|
||||||
|
else:
|
||||||
|
ipport_v6 = None
|
||||||
|
ipport_v4 = None
|
||||||
|
list = opt.listen.split(",")
|
||||||
|
for ip in list:
|
||||||
|
if '[' in ip and ']' in ip and opt.method == "tproxy":
|
||||||
|
ipport_v6 = parse_ipport6(ip)
|
||||||
|
else:
|
||||||
|
ipport_v4 = parse_ipport4(ip)
|
||||||
|
sys.exit(client.main(ipport_v6, ipport_v4,
|
||||||
opt.ssh_cmd,
|
opt.ssh_cmd,
|
||||||
remotename,
|
remotename,
|
||||||
opt.python,
|
opt.python,
|
||||||
|
@ -108,6 +108,7 @@ class Hostwatch:
|
|||||||
|
|
||||||
class DnsProxy(Handler):
|
class DnsProxy(Handler):
|
||||||
def __init__(self, mux, chan, request):
|
def __init__(self, mux, chan, request):
|
||||||
|
# FIXME! IPv4 specific
|
||||||
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
||||||
Handler.__init__(self, [sock])
|
Handler.__init__(self, [sock])
|
||||||
self.timeout = time.time()+30
|
self.timeout = time.time()+30
|
||||||
@ -117,6 +118,7 @@ class DnsProxy(Handler):
|
|||||||
self.peer = None
|
self.peer = None
|
||||||
self.request = request
|
self.request = request
|
||||||
self.sock = sock
|
self.sock = sock
|
||||||
|
# FIXME! IPv4 specific
|
||||||
self.sock.setsockopt(socket.SOL_IP, socket.IP_TTL, 42)
|
self.sock.setsockopt(socket.SOL_IP, socket.IP_TTL, 42)
|
||||||
self.try_send()
|
self.try_send()
|
||||||
|
|
||||||
@ -124,7 +126,8 @@ class DnsProxy(Handler):
|
|||||||
if self.tries >= 3:
|
if self.tries >= 3:
|
||||||
return
|
return
|
||||||
self.tries += 1
|
self.tries += 1
|
||||||
self.peer = resolvconf_random_nameserver()
|
# FIXME! Support IPv6 nameservers
|
||||||
|
self.peer = resolvconf_random_nameserver()[1]
|
||||||
self.sock.connect((self.peer, 53))
|
self.sock.connect((self.peer, 53))
|
||||||
debug2('DNS: sending to %r\n' % self.peer)
|
debug2('DNS: sending to %r\n' % self.peer)
|
||||||
try:
|
try:
|
||||||
|
Loading…
Reference in New Issue
Block a user