mirror of
https://github.com/soypat/lneto.git
synced 2026-08-21 23:19:03 +00:00
mdns: avoid dropping large answers that could not be decoded completely
This commit is contained in:
+2
-2
@@ -174,8 +174,8 @@ func (c *Client) Demux(carrierData []byte, frameOffset int) error {
|
|||||||
// Incoming query — match against our services.
|
// Incoming query — match against our services.
|
||||||
var query dns.Message
|
var query dns.Message
|
||||||
query.LimitResourceDecoding(f.QDCount(), 0, 0, 0)
|
query.LimitResourceDecoding(f.QDCount(), 0, 0, 0)
|
||||||
_, _, err = query.Decode(frame)
|
_, incomplete, err := query.Decode(frame)
|
||||||
if err != nil {
|
if err != nil && !incomplete {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
for i := range query.Questions {
|
for i := range query.Questions {
|
||||||
|
|||||||
@@ -420,6 +420,49 @@ func TestClientResponderSendsOnce(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestClientResponderHandlesQueryWithKnownAnswers(t *testing.T) {
|
||||||
|
// RFC 6762 §7.1: mDNS queries may include known-answer records.
|
||||||
|
// The responder must not return an error when decoding such queries.
|
||||||
|
svc := testService()
|
||||||
|
responder := newResponder(t, []Service{svc})
|
||||||
|
|
||||||
|
// Build an mDNS query with a known-answer record (QDCount=1, ANCount=1).
|
||||||
|
ptrName := mustNewName("Other Device._http._tcp.local")
|
||||||
|
ptrData, perr := ptrName.AppendTo(nil)
|
||||||
|
if perr != nil {
|
||||||
|
t.Fatal("encode PTR name:", perr)
|
||||||
|
}
|
||||||
|
var msg dns.Message
|
||||||
|
msg.Questions = []dns.Question{{
|
||||||
|
Name: mustNewName("_http._tcp.local"),
|
||||||
|
Type: dns.TypePTR,
|
||||||
|
Class: dns.ClassINET,
|
||||||
|
}}
|
||||||
|
msg.Answers = []dns.Resource{
|
||||||
|
dns.NewResource(mustNewName("_http._tcp.local"), dns.TypePTR, dns.ClassINET, 120, ptrData),
|
||||||
|
}
|
||||||
|
var buf [1024]byte
|
||||||
|
data, err := msg.AppendTo(buf[:0], 0, 0) // txid=0, flags=0 (query).
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal("build query with known-answer:", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Demux must not return an error.
|
||||||
|
err = responder.Demux(data, 0)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("responder demux returned error on query with known-answers: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Responder should still generate a response for its service.
|
||||||
|
n, err := responder.Encapsulate(buf[:], -1, 0)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal("responder encapsulate:", err)
|
||||||
|
}
|
||||||
|
if n == 0 {
|
||||||
|
t.Fatal("responder should respond to query even when known-answers are present")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestClientAbort(t *testing.T) {
|
func TestClientAbort(t *testing.T) {
|
||||||
svc := testService()
|
svc := testService()
|
||||||
responder := newResponder(t, []Service{svc})
|
responder := newResponder(t, []Service{svc})
|
||||||
|
|||||||
Reference in New Issue
Block a user