mirror of
https://github.com/sshuttle/sshuttle.git
synced 2025-05-09 10:34:33 +02:00
dns: trim DNS channel handlers after a response, or after a timeout.
This avoids memory/socket leaks.
This commit is contained in:
parent
4c5185dc55
commit
b570778894
21
client.py
21
client.py
@ -1,4 +1,4 @@
|
|||||||
import struct, socket, select, errno, re, signal
|
import struct, socket, select, errno, re, signal, time
|
||||||
import compat.ssubprocess as ssubprocess
|
import compat.ssubprocess as ssubprocess
|
||||||
import helpers, ssnet, ssh, ssyslog
|
import helpers, ssnet, ssh, ssyslog
|
||||||
from ssnet import SockWrapper, Handler, Proxy, Mux, MuxWrapper
|
from ssnet import SockWrapper, Handler, Proxy, Mux, MuxWrapper
|
||||||
@ -293,22 +293,27 @@ def _main(listener, fw, ssh_cmd, remotename, python, latency_control,
|
|||||||
handlers.append(Proxy(SockWrapper(sock, sock), outwrap))
|
handlers.append(Proxy(SockWrapper(sock, sock), outwrap))
|
||||||
handlers.append(Handler([listener], onaccept))
|
handlers.append(Handler([listener], onaccept))
|
||||||
|
|
||||||
dnspeers = {}
|
dnsreqs = {}
|
||||||
def dns_done(chan, data):
|
def dns_done(chan, data):
|
||||||
peer = dnspeers.get(chan)
|
peer,timeout = dnsreqs.get(chan)
|
||||||
debug1('dns_done: channel=%r peer=%r\n' % (chan, peer))
|
debug3('dns_done: channel=%r peer=%r\n' % (chan, peer))
|
||||||
if peer:
|
if peer:
|
||||||
del dnspeers[chan]
|
del dnsreqs[chan]
|
||||||
debug1('doing sendto %r\n' % (peer,))
|
debug3('doing sendto %r\n' % (peer,))
|
||||||
dnslistener.sendto(data, peer)
|
dnslistener.sendto(data, peer)
|
||||||
def ondns():
|
def ondns():
|
||||||
pkt,peer = dnslistener.recvfrom(4096)
|
pkt,peer = dnslistener.recvfrom(4096)
|
||||||
|
now = time.time()
|
||||||
if pkt:
|
if pkt:
|
||||||
debug1('Got DNS request from %r: %d bytes\n' % (peer, len(pkt)))
|
debug1('DNS request from %r: %d bytes\n' % (peer, len(pkt)))
|
||||||
chan = mux.next_channel()
|
chan = mux.next_channel()
|
||||||
dnspeers[chan] = peer
|
dnsreqs[chan] = peer,now+30
|
||||||
mux.send(chan, ssnet.CMD_DNS_REQ, pkt)
|
mux.send(chan, ssnet.CMD_DNS_REQ, pkt)
|
||||||
mux.channels[chan] = lambda cmd,data: dns_done(chan,data)
|
mux.channels[chan] = lambda cmd,data: dns_done(chan,data)
|
||||||
|
for chan,(peer,timeout) in dnsreqs.items():
|
||||||
|
if timeout < now:
|
||||||
|
del dnsreqs[chan]
|
||||||
|
debug3('Remaining DNS requests: %d\n' % len(dnsreqs))
|
||||||
if dnslistener:
|
if dnslistener:
|
||||||
handlers.append(Handler([dnslistener], ondns))
|
handlers.append(Handler([dnslistener], ondns))
|
||||||
|
|
||||||
|
15
server.py
15
server.py
@ -1,4 +1,4 @@
|
|||||||
import re, struct, socket, select, traceback
|
import re, struct, socket, select, traceback, time
|
||||||
if not globals().get('skip_imports'):
|
if not globals().get('skip_imports'):
|
||||||
import ssnet, helpers, hostwatch
|
import ssnet, helpers, hostwatch
|
||||||
import compat.ssubprocess as ssubprocess
|
import compat.ssubprocess as ssubprocess
|
||||||
@ -111,6 +111,7 @@ class DnsProxy(Handler):
|
|||||||
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.sock = sock
|
self.sock = sock
|
||||||
|
self.timeout = time.time()+30
|
||||||
self.mux = mux
|
self.mux = mux
|
||||||
self.chan = chan
|
self.chan = chan
|
||||||
self.sock.setsockopt(socket.SOL_IP, socket.IP_TTL, 42)
|
self.sock.setsockopt(socket.SOL_IP, socket.IP_TTL, 42)
|
||||||
@ -119,8 +120,9 @@ class DnsProxy(Handler):
|
|||||||
|
|
||||||
def callback(self):
|
def callback(self):
|
||||||
data = self.sock.recv(4096)
|
data = self.sock.recv(4096)
|
||||||
debug2('dns response: %d bytes\n' % len(data))
|
debug2('DNS response: %d bytes\n' % len(data))
|
||||||
self.mux.send(self.chan, ssnet.CMD_DNS_RESPONSE, data)
|
self.mux.send(self.chan, ssnet.CMD_DNS_RESPONSE, data)
|
||||||
|
self.ok = False
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
@ -184,7 +186,7 @@ def main():
|
|||||||
|
|
||||||
dnshandlers = {}
|
dnshandlers = {}
|
||||||
def dns_req(channel, data):
|
def dns_req(channel, data):
|
||||||
debug1('got dns request!\n')
|
debug2('Incoming DNS request.\n')
|
||||||
h = DnsProxy(mux, channel, data)
|
h = DnsProxy(mux, channel, data)
|
||||||
handlers.append(h)
|
handlers.append(h)
|
||||||
dnshandlers[channel] = h
|
dnshandlers[channel] = h
|
||||||
@ -201,3 +203,10 @@ def main():
|
|||||||
if latency_control:
|
if latency_control:
|
||||||
mux.check_fullness()
|
mux.check_fullness()
|
||||||
mux.callback()
|
mux.callback()
|
||||||
|
|
||||||
|
if dnshandlers:
|
||||||
|
now = time.time()
|
||||||
|
for channel,h in dnshandlers.items():
|
||||||
|
if h.timeout < now or not h.ok:
|
||||||
|
del dnshandlers[channel]
|
||||||
|
h.ok = False
|
||||||
|
Loading…
Reference in New Issue
Block a user