Module: Net::DNS::MDNS
- Defined in:
- lib/net/dns/mdns.rb
Overview
:main:Net::DNS::MDNS :title:net-mdns - multicast DNS and DNS service discovery
- Author
-
Sam Roberts <[email protected]>
- Copyright
-
Copyright © 2005 Sam Roberts
- License
-
May be distributed under the same terms as Ruby
- Version
-
0.4
- Homepage
- Download
Summary
An implementation of a multicast DNS (mDNS) responder. mDNS is an extension of hierarchical, unicast DNS to link-local multicast, used to do service discovery and address lookups over local networks. It is most widely known because it is part of Apple’s OS X.
net-mdns consists of:
-
Net::DNS::MDNSSD: a high-level API for browsing, resolving, and advertising services using DNS-SD over mDNS that aims to be compatible with DNSSD, see below for more information.
-
Resolv::MDNS: an extension to the ‘resolv’ resolver library that adds support for multicast DNS.
-
Net::DNS::MDNS: the low-level APIs and mDNS responder at the core of Resolv::MDNS and Net::DNS::MDNSSD.
net-mdns can be used for:
-
name to address lookups on local networks
-
address to name lookups on local networks
-
discovery of services on local networks
-
advertisement of services on local networks
Client Example
This is an example of finding all _http._tcp services, connecting to them, and printing the ‘Server’ field of the HTTP headers using Net::HTTP (from exhttp.txt):
require 'net/http'
require 'thread'
require 'pp'
# For MDNSSD
require 'net/dns/mdns-sd'
# To make Resolv aware of mDNS
require 'net/dns/resolv-mdns'
# To make TCPSocket use Resolv, not the C library resolver.
require 'net/dns/resolv-replace'
# Use a short name.
DNSSD = Net::DNS::MDNSSD
# Sync stdout, and don't write to console from multiple threads.
$stdout.sync
$lock = Mutex.new
# Be quiet.
debug = false
DNSSD.browse('_http._tcp') do |b|
$lock.synchronize { pp b } if debug
DNSSD.resolve(b.name, b.type) do |r|
$lock.synchronize { pp r } if debug
begin
http = Net::HTTP.new(r.target, r.port)
path = r.text_record['path'] || '/'
headers = http.head(path)
$lock.synchronize do
puts "#{r.name.inspect} on #{r.target}:#{r.port}#{path} was last-modified #{headers['server']}"
end
rescue
$lock.synchronize { puts $!; puts $!.backtrace }
end
end
end
# Hit enter when you think that's all.
STDIN.gets
Server Example
This is an example of advertising a webrick server using DNS-SD (from exwebrick.txt).
require 'webrick'
require 'net/dns/mdns-sd'
DNSSD = Net::DNS::MDNSSD
class HelloServlet < WEBrick::HTTPServlet::AbstractServlet
def do_GET(req, resp)
resp.body = "hello, world\n"
resp['content-type'] = 'text/plain'
raise WEBrick::HTTPStatus::OK
end
end
server = WEBrick::HTTPServer.new( :Port => 8080 )
server.mount( '/hello/', HelloServlet )
handle = DNSSD.register("hello", '_http._tcp', 'local', 8080, 'path' => '/hello/')
['INT', 'TERM'].each { |signal|
trap(signal) { server.shutdown; handle.stop; }
}
server.start
Samples
There are a few command line utilities in the samples/ directory:
-
mdns.txt, mdns.rb is a command line interface for to Net::DNS::MDNSSD (or to DNSSD)
-
v1demo.txt, v1demo.rb is a sample provided by Ben Giddings showing the call sequences to use with Resolv::MDNS for service resolution. This predates Net::DNS::MDNSSD, so while its a great sample, you might want to look at mdns.rb instead.
-
v1mdns.txt, v1mdns.rb is a low-level utility for exercising Resolv::MDNS.
-
mdns-watch.txt, mdns-watch.rb is a utility that dumps all mDNS traffic, useful for debugging.
Comparison to the DNS-SD Extension
The DNS-SD project at dnssd.rubyforge.org is another approach to mDNS and service discovery.
DNS-SD is a compiled ruby extension implemented on top of the dns_sd.h APIs published by Apple. These APIs work by contacting a local mDNS daemon (through unix domain sockets) and should be more efficient since they use a daemon written in C by a dedicated team at Apple.
Currently, the only thing I’m aware of net-mdns doing that DNS-SD doesn’t is integrate into the standard library so that link-local domain names can be used throughout the standard networking classes, and allow querying of arbitrary DNS record types. There is no reason DNS-SD can’t do this, it just needs to wrap DNSServiceQueryRecord() and expose it, and that will happen sometime soon.
Since net-mdns doesn’t do significantly more than DNSSD, why would you be interested in it?
The DNS-SD extension requires the dns_sd.h C language APIs for the Apple mDNS daemon. Installing the Apple responder can be quite difficult, and requires a running daemon. It also requires compiling the extension. If you need a pure ruby implementation, or if building DNS-SD turns out to be difficult for you, net-mdns may be useful to you.
For More Information
See the following:
-
draft-cheshire-dnsext-multicastdns-04.txt for a description of mDNS
-
RFC 2782 for a description of DNS SRV records
-
draft-cheshire-dnsext-dns-sd-02.txt for a description of how to use SRV, PTR, and TXT records for service discovery
-
www.dns-sd.org (a list of services is at www.dns-sd.org/ServiceTypes.html).
-
dnssd.rubyforge.org - for DNSSD, a C extension for communicating with Apple’s mDNSResponder daemon.
TODO
See TODO.
Thanks
-
to Tanaka Akira for resolv.rb, I learned a lot about meta-programming and ruby idioms from it, as well as getting an almost-complete implementation of the DNS message format and a resolver framework I could plug mDNS support into.
-
to Charles Mills for letting me add net-mdns to DNS-SD’s Rubyforge project when he hardly knew me, and hadn’t even seen any code yet.
-
to Ben Giddings for promising to use this if I wrote it, which was the catalyst for resuming a year-old prototype.
Author
Any feedback, questions, problems, etc., please contact me, Sam Roberts, via [email protected], or directly.
Defined Under Namespace
Modules: QueryImp Classes: Answer, BackgroundQuery, Cache, Query, Question, Responder, Service