Module: Net::DNS::MDNSSD
- Defined in:
- lib/net/dns/mdns-sd.rb
Overview
DNS-SD over mDNS
An implementation of DNS Service-Discovery (DNS-SD) using Net::DNS::MDNS.
DNS-SD is described in draft-cheshire-dnsext-dns-sd.txt, see www.dns-sd.org for more information. It is most often seen as part of Apple’s OS X, but is widely useful.
These APIs accept and return a set of arguments which are documented once, here, for convenience.
-
type: DNS-SD classifies services into types using a naming convention. That convention is <_service>.<_protocol>. The underscores (“_”) serve to differentiate from normal DNS names. Protocol is always one of “_tcp” or “_udp”. The service is a short name, see the list at www.dns-sd.org/ServiceTypes.html. A common service is “http”, the type of which would be “_http._tcp”.
-
domain: Services operate in a domain, theoretically. In current practice, that domain is always “local”.
-
name: Service lookup with #browse results in a name of a service of that type. That name is associated with a target (a host name), port, priority, and weight, as well as series of key to value mappings, specific to the service. In practice, priority and weight are widely ignored.
-
fullname: The concatention of the service name (optionally), type, and domain results in a single dot-seperated domain name - the “fullname”. See Util.parse_name for more information about the format.
-
text_record: Service information in the form of key/value pairs. See Util.parse_strings for more information about the format.
-
flags: should return flags, similar to DNSSD, but for now we just return the TTL of the DNS message. A TTL of zero means a deregistration of the record.
Services are advertised and resolved over specific network interfaces. Currently, Net::DNS::MDNS supports only a single default interface, and the interface will always be nil
.
Defined Under Namespace
Modules: Util Classes: BrowseReply, RegisterReply, ResolveReply
Class Method Summary collapse
-
.browse(type, domain = '.local', *ignored) ⇒ Object
Lookup a service by
type
anddomain
. -
.register(name, type, domain, port, txt = {}, *ignored) {|RegisterReply.new(name, type, domain)| ... } ⇒ Object
Register a service instance on the local host.
-
.resolve(name, type, domain = '.local', *ignored) ⇒ Object
Resolve a service instance by
name
,type
anddomain
.
Class Method Details
.browse(type, domain = '.local', *ignored) ⇒ Object
Lookup a service by type
and domain
.
Yields a BrowseReply as services are found, in a background thread, not the caller’s thread!
Returns a MDNS::BackgroundQuery, call MDNS::BackgroundQuery#stop when you have found all the replies you are interested in.
74 75 76 77 78 79 80 81 82 83 84 85 |
# File 'lib/net/dns/mdns-sd.rb', line 74 def self.browse(type, domain = '.local', *ignored) # :yield: BrowseReply dnsname = DNS::Name.create(type) dnsname << DNS::Name.create(domain) dnsname.absolute = true q = MDNS::BackgroundQuery.new(dnsname, IN::PTR) do |q, answers| answers.each do |an| yield BrowseReply.new( an ) end end q end |
.register(name, type, domain, port, txt = {}, *ignored) {|RegisterReply.new(name, type, domain)| ... } ⇒ Object
Register a service instance on the local host.
txt
is a Hash of String keys to String values.
Because the service name
may already be in use on the network, a different name may be registered than that requested. Because of this, if a block is supplied, a RegisterReply will be yielded so that the actual service name registered may be seen.
Returns a MDNS::Service, call MDNS::Service#stop when you no longer want to advertise the service.
NOTE - The service name
should be unique on the network, MDNSSD doesn’t currently attempt to ensure this. This will be fixed in an upcoming release.
168 169 170 171 172 173 174 175 176 177 178 179 180 181 |
# File 'lib/net/dns/mdns-sd.rb', line 168 def self.register(name, type, domain, port, txt = {}, *ignored) # :yields: RegisterReply dnsname = DNS::Name.create(name) dnsname << DNS::Name.create(type) dnsname << DNS::Name.create(domain) dnsname.absolute = true s = MDNS::Service.new(name, type, port, txt) do |s| s.domain = domain end yield RegisterReply.new(name, type, domain) if block_given? s end |
.resolve(name, type, domain = '.local', *ignored) ⇒ Object
Resolve a service instance by name
, type
and domain
.
Yields a ResolveReply as service instances are found, in a background thread, not the caller’s thread!
Returns a MDNS::BackgroundQuery, call MDNS::BackgroundQuery#stop when you have found all the replies you are interested in.
110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 |
# File 'lib/net/dns/mdns-sd.rb', line 110 def self.resolve(name, type, domain = '.local', *ignored) # :yield: ResolveReply dnsname = DNS::Name.create(name) dnsname << DNS::Name.create(type) dnsname << DNS::Name.create(domain) dnsname.absolute = true rrs = {} q = MDNS::BackgroundQuery.new(dnsname, IN::ANY) do |q, answers| _rrs = {} answers.each do |an| if an.name == dnsname _rrs[an.type] = an end end # We queried for ANY, but don't yield unless we got a SRV or TXT. if( _rrs[IN::SRV] || _rrs[IN::TXT] ) rrs.update _rrs ansrv, antxt = rrs[IN::SRV], rrs[IN::TXT] # puts "ansrv->#{ansrv}" # puts "antxt->#{antxt}" # Even though we got an SRV or TXT, we can't yield until we have both. if ansrv && antxt yield ResolveReply.new( ansrv, antxt ) end end end q end |