Skip to content

Commit f643b80

Browse files
authored
DNS: Retry with EDNS0 when response is truncated
1 parent 2cba2c4 commit f643b80

File tree

2 files changed

+28
-3
lines changed

2 files changed

+28
-3
lines changed

app/dns/dnscommon.go

+8-3
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,9 @@ type IPRecord struct {
3535
IP []net.Address
3636
Expire time.Time
3737
RCode dnsmessage.RCode
38+
39+
// Truncated is for udp dns to indicates if the response is truncated and needs to be retried
40+
Truncated bool
3841
}
3942

4043
func (r *IPRecord) getIPs() ([]net.Address, error) {
@@ -65,6 +68,7 @@ type dnsRequest struct {
6568
start time.Time
6669
expire time.Time
6770
msg *dnsmessage.Message
71+
ctx context.Context
6872
}
6973

7074
func genEDNS0Options(clientIP net.IP) *dnsmessage.Resource {
@@ -179,9 +183,10 @@ func parseResponse(payload []byte) (*IPRecord, error) {
179183

180184
now := time.Now()
181185
ipRecord := &IPRecord{
182-
ReqID: h.ID,
183-
RCode: h.RCode,
184-
Expire: now.Add(time.Second * 600),
186+
ReqID: h.ID,
187+
RCode: h.RCode,
188+
Expire: now.Add(time.Second * 600),
189+
Truncated: h.Truncated,
185190
}
186191

187192
L:

app/dns/nameserver_udp.go

+20
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,26 @@ func (s *ClassicNameServer) HandleResponse(ctx context.Context, packet *udp_prot
128128
return
129129
}
130130

131+
// if truncated, retry with EDNS0 option(udp payload size: 1350)
132+
if ipRec.Truncated {
133+
// if already has EDNS0 option, no need to retry
134+
if ok && len(req.msg.Additionals) == 0 {
135+
// copy necessary meta data from original request
136+
// and add EDNS0 option
137+
opt := new(dnsmessage.Resource)
138+
common.Must(opt.Header.SetEDNS0(1350, 0xfe00, true))
139+
newMsg := *req.msg
140+
newReq := *req
141+
newMsg.Additionals = append(newMsg.Additionals, *opt)
142+
newMsg.ID = s.newReqID()
143+
newReq.msg = &newMsg
144+
s.addPendingRequest(&newReq)
145+
b, _ := dns.PackMessage(req.msg)
146+
s.udpServer.Dispatch(toDnsContext(newReq.ctx, s.address.String()), *s.address, b)
147+
return
148+
}
149+
}
150+
131151
var rec record
132152
switch req.reqType {
133153
case dnsmessage.TypeA:

0 commit comments

Comments
 (0)