|
|
|
|
@ -386,7 +386,6 @@ func (ns *Impl) handleLocalPackets(p *packet.Parsed, t *tstun.Wrapper) filter.Re |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var pn tcpip.NetworkProtocolNumber |
|
|
|
|
switch p.IPVersion { |
|
|
|
|
case 4: |
|
|
|
|
@ -900,20 +899,36 @@ func (ns *Impl) handleMagicDNSUDP(srcAddr netaddr.IPPort, c *gonet.UDPConn) { |
|
|
|
|
// In practice, implementations are advised not to exceed 512 bytes
|
|
|
|
|
// due to fragmenting. Just to be sure, we bump all the way to the MTU.
|
|
|
|
|
const maxUDPReqSize = mtu |
|
|
|
|
// Packets are being generated by the local host, so there should be
|
|
|
|
|
// very, very little latency. 150ms was chosen as something of an upper
|
|
|
|
|
// bound on resource usage, while hopefully still being long enough for
|
|
|
|
|
// a heavily loaded system.
|
|
|
|
|
const readDeadline = 150 * time.Millisecond |
|
|
|
|
|
|
|
|
|
defer c.Close() |
|
|
|
|
q := make([]byte, maxUDPReqSize) |
|
|
|
|
n, err := c.Read(q) |
|
|
|
|
if err != nil { |
|
|
|
|
ns.logf("dns udp read: %v", err) |
|
|
|
|
return |
|
|
|
|
} |
|
|
|
|
resp, err := ns.dns.Query(context.Background(), q[:n], srcAddr) |
|
|
|
|
if err != nil { |
|
|
|
|
ns.logf("dns udp query: %v", err) |
|
|
|
|
return |
|
|
|
|
|
|
|
|
|
// libresolv from glibc is quite adamant that transmitting multiple DNS
|
|
|
|
|
// requests down the same UDP socket is valid. To support this, we read
|
|
|
|
|
// in a loop (with a tight deadline so we don't chew too many resources).
|
|
|
|
|
//
|
|
|
|
|
// See: https://github.com/bminor/glibc/blob/f7fbb99652eceb1b6b55e4be931649df5946497c/resolv/res_send.c#L995
|
|
|
|
|
for { |
|
|
|
|
c.SetReadDeadline(time.Now().Add(readDeadline)) |
|
|
|
|
n, _, err := c.ReadFrom(q) |
|
|
|
|
if err != nil { |
|
|
|
|
if oe, ok := err.(*net.OpError); !(ok && oe.Timeout()) { |
|
|
|
|
ns.logf("dns udp read: %v", err) // log non-timeout errors
|
|
|
|
|
} |
|
|
|
|
return |
|
|
|
|
} |
|
|
|
|
resp, err := ns.dns.Query(context.Background(), q[:n], srcAddr) |
|
|
|
|
if err != nil { |
|
|
|
|
ns.logf("dns udp query: %v", err) |
|
|
|
|
return |
|
|
|
|
} |
|
|
|
|
c.Write(resp) |
|
|
|
|
} |
|
|
|
|
c.Write(resp) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// forwardUDP proxies between client (with addr clientAddr) and dstAddr.
|
|
|
|
|
|