MCPcopy Index your code
hub / github.com/tailscale/tailscale / handleMagicDNSUDP

Method handleMagicDNSUDP

wgengine/netstack/netstack.go:1976–2010  ·  view source on GitHub ↗
(srcAddr netip.AddrPort, c *gonet.UDPConn)

Source from the content-addressed store, hash-verified

1974}
1975
1976func (ns *Impl) handleMagicDNSUDP(srcAddr netip.AddrPort, c *gonet.UDPConn) {
1977 // Packets are being generated by the local host, so there should be
1978 // very, very little latency. 150ms was chosen as something of an upper
1979 // bound on resource usage, while hopefully still being long enough for
1980 // a heavily loaded system.
1981 const readDeadline = 150 * time.Millisecond
1982
1983 defer c.Close()
1984
1985 bufp := udpBufPool.Get().(*[]byte)
1986 defer udpBufPool.Put(bufp)
1987 q := *bufp
1988
1989 // libresolv from glibc is quite adamant that transmitting multiple DNS
1990 // requests down the same UDP socket is valid. To support this, we read
1991 // in a loop (with a tight deadline so we don't chew too many resources).
1992 //
1993 // See: https://github.com/bminor/glibc/blob/f7fbb99652eceb1b6b55e4be931649df5946497c/resolv/res_send.c#L995
1994 for {
1995 c.SetReadDeadline(time.Now().Add(readDeadline))
1996 n, _, err := c.ReadFrom(q)
1997 if err != nil {
1998 if oe, ok := err.(*net.OpError); !(ok && oe.Timeout()) {
1999 ns.logf("dns udp read: %v", err) // log non-timeout errors
2000 }
2001 return
2002 }
2003 resp, err := ns.dns.Query(context.Background(), q[:n], "udp", srcAddr)
2004 if err != nil {
2005 ns.logf("dns udp query: %v", err)
2006 return
2007 }
2008 c.Write(resp)
2009 }
2010}
2011
2012// forwardUDP proxies between client (with addr clientAddr) and dstAddr.
2013//

Callers 1

acceptUDPMethod · 0.95

Calls 11

PutMethod · 0.80
CloseMethod · 0.65
GetMethod · 0.65
SetReadDeadlineMethod · 0.65
AddMethod · 0.65
NowMethod · 0.65
WriteMethod · 0.65
ReadFromMethod · 0.45
TimeoutMethod · 0.45
logfMethod · 0.45
QueryMethod · 0.45

Tested by

no test coverage detected