feature/conn25: preserve TTL on DNS rewrites

We were accidentally hardcoding TTL 0 before.

Fixes tailscale/corp#45025

Signed-off-by: Michael Ben-Ami <mzb@tailscale.com>
This commit is contained in:
Michael Ben-Ami
2026-07-17 10:27:14 -04:00
committed by mzbenami
parent cfd101f9d7
commit 7ec9b7ffa3
2 changed files with 102 additions and 7 deletions
+7 -7
View File
@@ -1069,9 +1069,9 @@ func (e *extension) sendAddressAssignment(ctx context.Context, as addrs) (tailcf
}
type dnsResponseRewrite struct {
domain dnsname.FQDN
dst netip.Addr
ttl time.Duration
domain dnsname.FQDN
dst netip.Addr
ttlSeconds uint32
}
func makeServFail(logf logger.Logf, h dnsmessage.Header, q dnsmessage.Question) []byte {
@@ -1263,7 +1263,7 @@ func (c *Conn25) mapDNSResponse(buf []byte) []byte {
}
dstAddr = netip.AddrFrom16(r.AAAA)
}
answers = append(answers, dnsResponseRewrite{domain: queriedDomain, dst: dstAddr, ttl: time.Second * time.Duration(h.TTL)})
answers = append(answers, dnsResponseRewrite{domain: queriedDomain, dst: dstAddr, ttlSeconds: h.TTL})
default:
// we already checked the question was for a supported type, this answer is unexpected
if err := p.SkipAnswer(); err != nil {
@@ -1297,7 +1297,7 @@ func (c *client) rewriteDNSResponse(appName string, hdr dnsmessage.Header, quest
// make an answer for each rewrite
for _, rw := range answers {
as, err := c.reserveAddresses(appName, rw.domain, rw.dst, rw.ttl)
as, err := c.reserveAddresses(appName, rw.domain, rw.dst, time.Duration(rw.ttlSeconds)*time.Second)
if err != nil {
return nil, err
}
@@ -1309,12 +1309,12 @@ func (c *client) rewriteDNSResponse(appName string, hdr dnsmessage.Header, quest
return nil, err
}
if rw.dst.Is4() {
rhdr := dnsmessage.ResourceHeader{Name: name, Type: dnsmessage.TypeA, Class: dnsmessage.ClassINET, TTL: 0}
rhdr := dnsmessage.ResourceHeader{Name: name, Type: dnsmessage.TypeA, Class: dnsmessage.ClassINET, TTL: rw.ttlSeconds}
if err := b.AResource(rhdr, dnsmessage.AResource{A: as.magic.As4()}); err != nil {
return nil, err
}
} else if rw.dst.Is6() {
rhdr := dnsmessage.ResourceHeader{Name: name, Type: dnsmessage.TypeAAAA, Class: dnsmessage.ClassINET, TTL: 0}
rhdr := dnsmessage.ResourceHeader{Name: name, Type: dnsmessage.TypeAAAA, Class: dnsmessage.ClassINET, TTL: rw.ttlSeconds}
if err := b.AAAAResource(rhdr, dnsmessage.AAAAResource{AAAA: as.magic.As16()}); err != nil {
return nil, err
}