diff options
author | Brian May <brian@linuxpenguins.xyz> | 2015-11-24 12:23:17 +1100 |
---|---|---|
committer | Brian May <brian@linuxpenguins.xyz> | 2015-11-24 12:23:17 +1100 |
commit | c0748c23880c19c80c61d8d2b9177c1cbb3de4f0 (patch) | |
tree | a9e5302227c0b4b9065c39527bf0043d9c5cd092 | |
parent | 71d46d77bf2fd94a8351b9944feff9275687043b (diff) |
Support IPV6 DNS servers.
Closes #28.
-rw-r--r-- | sshuttle/server.py | 39 |
1 files changed, 23 insertions, 16 deletions
diff --git a/sshuttle/server.py b/sshuttle/server.py index 2529765..5021997 100644 --- a/sshuttle/server.py +++ b/sshuttle/server.py @@ -120,55 +120,62 @@ class Hostwatch: class DnsProxy(Handler): def __init__(self, mux, chan, request): - # FIXME! IPv4 specific - sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) - Handler.__init__(self, [sock]) + Handler.__init__(self, []) self.timeout = time.time() + 30 self.mux = mux self.chan = chan self.tries = 0 - self.peer = None self.request = request - self.sock = sock - # FIXME! IPv4 specific - self.sock.setsockopt(socket.SOL_IP, socket.IP_TTL, 42) + self.peers = {} self.try_send() def try_send(self): if self.tries >= 3: return self.tries += 1 - # FIXME! Support IPv6 nameservers - self.peer = resolvconf_random_nameserver()[1] - self.sock.connect((self.peer, 53)) - debug2('DNS: sending to %r\n' % self.peer) + + family, peer = resolvconf_random_nameserver() + + sock = socket.socket(family, socket.SOCK_DGRAM) + sock.setsockopt(socket.SOL_IP, socket.IP_TTL, 42) + sock.connect((peer, 53)) + + self.peers[sock] = peer + + debug2('DNS: sending to %r (try %d)\n' % (peer, self.tries)) try: - self.sock.send(self.request) + sock.send(self.request) + self.socks.append(sock) except socket.error as e: if e.args[0] in ssnet.NET_ERRS: # might have been spurious; try again. # Note: these errors sometimes are reported by recv(), # and sometimes by send(). We have to catch both. - debug2('DNS send to %r: %s\n' % (self.peer, e)) + debug2('DNS send to %r: %s\n' % (peer, e)) self.try_send() return else: - log('DNS send to %r: %s\n' % (self.peer, e)) + log('DNS send to %r: %s\n' % (peer, e)) return def callback(self, sock): + peer = self.peers[sock] + try: data = sock.recv(4096) except socket.error as e: + self.socks.remove(sock) + del self.peers[sock] + if e.args[0] in ssnet.NET_ERRS: # might have been spurious; try again. # Note: these errors sometimes are reported by recv(), # and sometimes by send(). We have to catch both. - debug2('DNS recv from %r: %s\n' % (self.peer, e)) + debug2('DNS recv from %r: %s\n' % (peer, e)) self.try_send() return else: - log('DNS recv from %r: %s\n' % (self.peer, e)) + log('DNS recv from %r: %s\n' % (peer, e)) return debug2('DNS response: %d bytes\n' % len(data)) self.mux.send(self.chan, ssnet.CMD_DNS_RESPONSE, data) |