go-micro.dev/v5@v5.12.0/util/mdns/dns_sd.go (about) 1 package mdns 2 3 import "github.com/miekg/dns" 4 5 // DNSSDService is a service that complies with the DNS-SD (RFC 6762) and MDNS 6 // (RFC 6762) specs for local, multicast-DNS-based discovery. 7 // 8 // DNSSDService implements the Zone interface and wraps an MDNSService instance. 9 // To deploy an mDNS service that is compliant with DNS-SD, it's recommended to 10 // register only the wrapped instance with the server. 11 // 12 // Example usage: 13 // 14 // service := &mdns.DNSSDService{ 15 // MDNSService: &mdns.MDNSService{ 16 // Instance: "My Foobar Service", 17 // Service: "_foobar._tcp", 18 // Port: 8000, 19 // } 20 // } 21 // server, err := mdns.NewServer(&mdns.Config{Zone: service}) 22 // if err != nil { 23 // log.Fatalf("Error creating server: %v", err) 24 // } 25 // defer server.Shutdown() 26 type DNSSDService struct { 27 MDNSService *MDNSService 28 } 29 30 // Records returns DNS records in response to a DNS question. 31 // 32 // This function returns the DNS response of the underlying MDNSService 33 // instance. It also returns a PTR record for a request for " 34 // _services._dns-sd._udp.<Domain>", as described in section 9 of RFC 6763 35 // ("Service Type Enumeration"), to allow browsing of the underlying MDNSService 36 // instance. 37 func (s *DNSSDService) Records(q dns.Question) []dns.RR { 38 var recs []dns.RR 39 if q.Name == "_services._dns-sd._udp."+s.MDNSService.Domain+"." { 40 recs = s.dnssdMetaQueryRecords(q) 41 } 42 return append(recs, s.MDNSService.Records(q)...) 43 } 44 45 // dnssdMetaQueryRecords returns the DNS records in response to a "meta-query" 46 // issued to browse for DNS-SD services, as per section 9. of RFC6763. 47 // 48 // A meta-query has a name of the form "_services._dns-sd._udp.<Domain>" where 49 // Domain is a fully-qualified domain, such as "local.". 50 func (s *DNSSDService) dnssdMetaQueryRecords(q dns.Question) []dns.RR { 51 // Intended behavior, as described in the RFC: 52 // ...it may be useful for network administrators to find the list of 53 // advertised service types on the network, even if those Service Names 54 // are just opaque identifiers and not particularly informative in 55 // isolation. 56 // 57 // For this purpose, a special meta-query is defined. A DNS query for PTR 58 // records with the name "_services._dns-sd._udp.<Domain>" yields a set of 59 // PTR records, where the rdata of each PTR record is the two-abel 60 // <Service> name, plus the same domain, e.g., "_http._tcp.<Domain>". 61 // Including the domain in the PTR rdata allows for slightly better name 62 // compression in Unicast DNS responses, but only the first two labels are 63 // relevant for the purposes of service type enumeration. These two-label 64 // service types can then be used to construct subsequent Service Instance 65 // Enumeration PTR queries, in this <Domain> or others, to discover 66 // instances of that service type. 67 return []dns.RR{ 68 &dns.PTR{ 69 Hdr: dns.RR_Header{ 70 Name: q.Name, 71 Rrtype: dns.TypePTR, 72 Class: dns.ClassINET, 73 Ttl: defaultTTL, 74 }, 75 Ptr: s.MDNSService.serviceAddr, 76 }, 77 } 78 } 79 80 // Announcement returns DNS records that should be broadcast during the initial 81 // availability of the service, as described in section 8.3 of RFC 6762. 82 // TODO(reddaly): Add this when Announcement is added to the mdns.Zone interface. 83 // func (s *DNSSDService) Announcement() []dns.RR { 84 // return s.MDNSService.Announcement() 85 //}