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:
Michael Bridgen committed 2014-10-22 13:35:40 +01:00
1 parent e21069f3ab
commit 156314a802
2 files changed
+9 -7

No files matched your search

+8 -5
View File
@@ -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
View File
@@ -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)