Complete multicast requests on first response
This is the simplest thing that works, is consistent with what happens if there's a local answer, and avoids having all multicast requests last 250ms or more. Since we're no longer waiting *at least* the timeout period, I've bumped the multicast response timeout up to half a second. There was also a bug whereby the query would be entered into the inflight map even if the socket write had failed (and the channel had been closed).
This commit is contained in:
1 parent
e21069f3ab
commit
156314a802
2 files changed
+9
-7
No files matched your search
@@ -14,9 +14,9 @@ const (
|
||||
mdnsPort = 5353 // mDNS assigned port
|
||||
// We wait this long to hear responses from other mDNS servers on the network.
|
||||
// TODO: introduce caching so we don't have to wait this long on every call.
|
||||
mDNSTimeout = 250 * time.Millisecond
|
||||
mDNSTimeout = 500 * time.Millisecond
|
||||
MaxDuration = time.Duration(math.MaxInt64)
|
||||
ChannelSize = 16
|
||||
MailboxSize = 16
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -88,7 +88,7 @@ func (c *MDNSClient) Start(ifi *net.Interface) error {
|
||||
c.server = &dns.Server{Listener: nil, PacketConn: multicast, Handler: dns.HandlerFunc(handleMDNS)}
|
||||
go c.server.ActivateAndServe()
|
||||
|
||||
queryChan := make(chan *MDNSInteraction, ChannelSize)
|
||||
queryChan := make(chan *MDNSInteraction, MailboxSize)
|
||||
c.queryChan = queryChan
|
||||
go c.queryLoop(queryChan)
|
||||
|
||||
@@ -216,13 +216,13 @@ func (c *MDNSClient) handleSendQuery(q mDNSQueryInfo) {
|
||||
name: q.name,
|
||||
id: m.Id,
|
||||
}
|
||||
c.inflight[q.name] = query
|
||||
_, err = c.conn.WriteTo(buf, c.addr)
|
||||
if err != nil {
|
||||
q.responseCh <- &ResponseA{Err: err}
|
||||
close(q.responseCh)
|
||||
return
|
||||
}
|
||||
c.inflight[q.name] = query
|
||||
}
|
||||
info := &responseInfo{
|
||||
ch: q.responseCh,
|
||||
@@ -237,10 +237,13 @@ func (c *MDNSClient) handleResponse(r *dns.Msg) {
|
||||
for _, answer := range r.Answer {
|
||||
switch rr := answer.(type) {
|
||||
case *dns.A:
|
||||
if query, found := c.inflight[rr.Hdr.Name]; found {
|
||||
name := rr.Hdr.Name
|
||||
if query, found := c.inflight[name]; found {
|
||||
for _, resp := range query.responseInfos {
|
||||
resp.ch <- &ResponseA{Name: rr.Hdr.Name, Addr: rr.A}
|
||||
close(resp.ch)
|
||||
}
|
||||
delete(c.inflight, name)
|
||||
} else {
|
||||
// We've received a response that didn't match a query
|
||||
// Do we want to cache it?
|
||||
|
||||
+1
-2
@@ -41,10 +41,9 @@ func queryHandler(zone Zone, mdnsClient *MDNSClient) dns.HandlerFunc {
|
||||
} else {
|
||||
Debug.Printf("Failed lookup for %s; sending mDNS query", q.Name)
|
||||
// We don't know the answer; see if someone else does
|
||||
channel := make(chan *ResponseA, ChannelSize)
|
||||
channel := make(chan *ResponseA)
|
||||
replies := make([]net.IP, 0)
|
||||
go func() {
|
||||
// Loop terminates when channel is closed by MDNSClient on timeout
|
||||
for resp := range channel {
|
||||
Debug.Printf("Got address response %s to query %s addr %s", resp.Name, q.Name, resp.Addr)
|
||||
replies = append(replies, resp.Addr)
|
||||
|
||||
Reference in new issue
Block a user