mirror of
https://github.com/tailscale/tailscale.git
synced 2025-10-20 06:32:01 +00:00
net/dns, net/dns/resolver, wgengine: refactor DNS request path (#4364)
* net/dns, net/dns/resolver, wgengine: refactor DNS request path Previously, method calls into the DNS manager/resolver types handled DNS requests rather than DNS packets. This is fine for UDP as one packet corresponds to one request or response, however will not suit an implementation that supports DNS over TCP. To support PRs implementing this in the future, wgengine delegates all handling/construction of packets to the magic DNS endpoint, to the DNS types themselves. Handling IP packets at this level enables future support for both UDP and TCP. Signed-off-by: Tom DNetto <tom@tailscale.com>
This commit is contained in:
@@ -487,23 +487,22 @@ func (e *userspaceEngine) handleLocalPackets(p *packet.Parsed, t *tstun.Wrapper)
|
||||
|
||||
// handleDNS is an outbound pre-filter resolving Tailscale domains.
|
||||
func (e *userspaceEngine) handleDNS(p *packet.Parsed, t *tstun.Wrapper) filter.Response {
|
||||
if p.Dst.Port() == magicDNSPort && p.IPProto == ipproto.UDP {
|
||||
switch p.Dst.IP() {
|
||||
case magicDNSIP, magicDNSIPv6:
|
||||
err := e.dns.EnqueueRequest(append([]byte(nil), p.Payload()...), p.Src)
|
||||
if err != nil {
|
||||
e.logf("dns: enqueue: %v", err)
|
||||
}
|
||||
return filter.Drop
|
||||
switch p.Dst.IP() {
|
||||
case magicDNSIP, magicDNSIPv6:
|
||||
err := e.dns.EnqueuePacket(append([]byte(nil), p.Payload()...), p.IPProto, p.Src, p.Dst)
|
||||
if err != nil {
|
||||
e.logf("dns: enqueue: %v", err)
|
||||
}
|
||||
return filter.Drop
|
||||
default:
|
||||
return filter.Accept
|
||||
}
|
||||
return filter.Accept
|
||||
}
|
||||
|
||||
// pollResolver reads responses from the DNS resolver and injects them inbound.
|
||||
// pollResolver reads packets from the DNS resolver and injects them inbound.
|
||||
func (e *userspaceEngine) pollResolver() {
|
||||
for {
|
||||
bs, to, err := e.dns.NextResponse()
|
||||
bs, err := e.dns.NextPacket()
|
||||
if err == resolver.ErrClosed {
|
||||
return
|
||||
}
|
||||
@@ -512,39 +511,9 @@ func (e *userspaceEngine) pollResolver() {
|
||||
continue
|
||||
}
|
||||
|
||||
var buf []byte
|
||||
const offset = tstun.PacketStartOffset
|
||||
switch {
|
||||
case to.IP().Is4():
|
||||
h := packet.UDP4Header{
|
||||
IP4Header: packet.IP4Header{
|
||||
Src: magicDNSIP,
|
||||
Dst: to.IP(),
|
||||
},
|
||||
SrcPort: magicDNSPort,
|
||||
DstPort: to.Port(),
|
||||
}
|
||||
hlen := h.Len()
|
||||
// TODO(dmytro): avoid this allocation without importing tstun quirks into dns.
|
||||
buf = make([]byte, offset+hlen+len(bs))
|
||||
copy(buf[offset+hlen:], bs)
|
||||
h.Marshal(buf[offset:])
|
||||
case to.IP().Is6():
|
||||
h := packet.UDP6Header{
|
||||
IP6Header: packet.IP6Header{
|
||||
Src: magicDNSIPv6,
|
||||
Dst: to.IP(),
|
||||
},
|
||||
SrcPort: magicDNSPort,
|
||||
DstPort: to.Port(),
|
||||
}
|
||||
hlen := h.Len()
|
||||
// TODO(dmytro): avoid this allocation without importing tstun quirks into dns.
|
||||
buf = make([]byte, offset+hlen+len(bs))
|
||||
copy(buf[offset+hlen:], bs)
|
||||
h.Marshal(buf[offset:])
|
||||
}
|
||||
e.tundev.InjectInboundDirect(buf, offset)
|
||||
// The leading empty space required by the semantics of
|
||||
// InjectInboundDirect is allocated in NextPacket().
|
||||
e.tundev.InjectInboundDirect(bs, tstun.PacketStartOffset)
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user