Account for PTR answers in mdns_client

En passant, ResponseA -> the more versatile Response.
This commit is contained in:
Michael Bridgen committed 2015-01-08 18:30:30 +00:00
1 parent e9b84c968d
commit 89fa52818c
3 files changed
+72 -45

No files matched your search

+26 -16
View File
@@ -26,7 +26,7 @@ var (
}
)
type ResponseA struct {
type Response struct {
Name string
Addr net.IP
Err error
@@ -34,7 +34,7 @@ type ResponseA struct {
type responseInfo struct {
timeout time.Time // if no answer by this time, give up
ch chan<- *ResponseA
ch chan<- *Response
}
// Represents one query that we have sent for one name.
@@ -60,7 +60,7 @@ type MDNSClient struct {
type mDNSQueryInfo struct {
name string
querytype uint16
responseCh chan<- *ResponseA
responseCh chan<- *Response
}
func NewMDNSClient() (*MDNSClient, error) {
@@ -121,7 +121,7 @@ func (c *MDNSClient) Shutdown() {
}
// Async
func (c *MDNSClient) SendQuery(name string, querytype uint16, responseCh chan<- *ResponseA) {
func (c *MDNSClient) SendQuery(name string, querytype uint16, responseCh chan<- *Response) {
c.queryChan <- &MDNSInteraction{
code: CSendQuery,
payload: mDNSQueryInfo{name, querytype, responseCh},
@@ -209,7 +209,7 @@ func (c *MDNSClient) handleSendQuery(q mDNSQueryInfo) {
m.RecursionDesired = false
buf, err := m.Pack()
if err != nil {
q.responseCh <- &ResponseA{Err: err}
q.responseCh <- &Response{Err: err}
close(q.responseCh)
return
}
@@ -218,7 +218,7 @@ func (c *MDNSClient) handleSendQuery(q mDNSQueryInfo) {
id: m.Id,
}
if _, err = c.conn.WriteTo(buf, c.addr); err != nil {
q.responseCh <- &ResponseA{Err: err}
q.responseCh <- &Response{Err: err}
close(q.responseCh)
return
}
@@ -235,19 +235,29 @@ func (c *MDNSClient) handleSendQuery(q mDNSQueryInfo) {
func (c *MDNSClient) handleResponse(r *dns.Msg) {
for _, answer := range r.Answer {
var name string
var res *Response
switch rr := answer.(type) {
case *dns.A:
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?
name = rr.Hdr.Name
res = &Response{Addr: rr.A}
case *dns.PTR:
name = rr.Hdr.Name
res = &Response{Name: rr.Ptr}
default:
return
}
if query, found := c.inflight[name]; found {
for _, resp := range query.responseInfos {
resp.ch <- res
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?
}
}
}
+44 -27
View File
@@ -13,9 +13,27 @@ var (
successTestName = "test1.weave."
failTestName = "test2.weave."
testAddr = net.ParseIP("9.8.7.6")
testInAddr = "6.7.8.9.in-addr.arpa."
)
func minimalServer(w dns.ResponseWriter, req *dns.Msg) {
sendAnswer := func(m *dns.Msg) {
buf, err := m.Pack()
checkFatal(err)
if buf == nil {
log.Fatal("Nil buffer")
}
//log.Println("minimalServer sending:", buf)
// This is a bit of a kludge - per the RFC we should send responses from 5353, but that doesn't seem to work
sendconn, err := net.DialUDP("udp", nil, ipv4Addr)
checkFatal(err)
_, err = sendconn.Write(buf)
sendconn.Close()
checkFatal(err)
}
//log.Println("minimalServer received:", req)
if len(req.Answer) > 0 {
return // Only interested in questions.
@@ -23,31 +41,24 @@ func minimalServer(w dns.ResponseWriter, req *dns.Msg) {
if len(req.Question) != 1 {
return // We only handle single-question messages
}
if req.Question[0].Name != successTestName {
return // This is not the DNS record you are looking for
if req.Question[0].Qtype == dns.TypeA && req.Question[0].Name == successTestName {
m := new(dns.Msg)
m.SetReply(req)
hdr := dns.RR_Header{Name: m.Question[0].Name, Rrtype: dns.TypeA,
Class: dns.ClassINET, Ttl: 3600}
a := &dns.A{hdr, testAddr}
m.Answer = append(m.Answer, a)
sendAnswer(m)
} else if req.Question[0].Qtype == dns.TypePTR && req.Question[0].Name == testInAddr {
m := new(dns.Msg)
m.SetReply(req)
hdr := dns.RR_Header{Name: m.Question[0].Name, Rrtype: dns.TypePTR,
Class: dns.ClassINET, Ttl: 3600}
a := &dns.PTR{hdr, successTestName}
m.Answer = append(m.Answer, a)
sendAnswer(m)
}
m := new(dns.Msg)
m.SetReply(req)
hdr := dns.RR_Header{Name: m.Question[0].Name, Rrtype: dns.TypeA,
Class: dns.ClassINET, Ttl: 3600}
a := &dns.A{hdr, testAddr}
m.Answer = append(m.Answer, a)
buf, err := m.Pack()
checkFatal(err)
if buf == nil {
log.Fatal("Nil buffer")
}
//log.Println("minimalServer sending:", buf)
// This is a bit of a kludge - per the RFC we should send responses from 5353, but that doesn't seem to work
sendconn, err := net.DialUDP("udp", nil, ipv4Addr)
checkFatal(err)
_, err = sendconn.Write(buf)
sendconn.Close()
checkFatal(err)
}
func RunLocalMulticastServer() (*dns.Server, error) {
@@ -76,14 +87,14 @@ func setup(t *testing.T) (*MDNSClient, *dns.Server, error) {
type testContext struct {
receivedAddr net.IP
receivedCount int
channel chan *ResponseA
channel chan *Response
}
func newTestContext() *testContext {
return &testContext{channel: make(chan *ResponseA, 4)}
return &testContext{channel: make(chan *Response, 4)}
}
func (c *testContext) checkResponse(t *testing.T, channelOk bool, resp *ResponseA) {
func (c *testContext) checkResponse(t *testing.T, channelOk bool, resp *Response) {
if !channelOk {
c.channel = nil
return
@@ -166,4 +177,10 @@ func TestAsLookup(t *testing.T) {
ip, err = mdnsClient.LookupLocal("foo.example.com.")
wt.AssertErrorType(t, err, (*LookupError)(nil), "unknown hostname")
name, err := mdnsClient.ReverseLookupLocal(testInAddr)
wt.AssertNoErr(t, err)
if !(successTestName == name) {
t.Fatalf("Expected name %s, got %s", successTestName, name)
}
}
+2 -2
View File
@@ -6,8 +6,8 @@ import (
"net"
)
func mdnsLookup(client *MDNSClient, name string, qtype uint16) (*ResponseA, error) {
channel := make(chan *ResponseA)
func mdnsLookup(client *MDNSClient, name string, qtype uint16) (*Response, error) {
channel := make(chan *Response)
client.SendQuery(name, qtype, channel)
for resp := range channel {
Debug.Printf("Got response name %s addr %s", resp.Name, resp.Addr)