From: Lyndon Samson Date: 2005-02-04T07:33:24+09:00 Subject: Re: ANN: net-mdns, multicast DNS and service discovery (aka "Rendezvous") Rendezvous is a ( good ) Tibco messaging product, don't get their lawyers fired up again ;-) On Thu, 3 Feb 2005 13:00:24 +0900, Sam Roberts wrote: > Hi, > > net-mdns is an extension to the standard 'resolv' resolver library that > adds support for multicast DNS. mDNS is an extension of hierarchical, > unicast DNS to link-local unicast. It is most widely known because it is > part of Apple's OS X "Rendezvous" system, where it is used to do service > discovery over local networks. > > I've been planning to do this awhile, but a post by Ben Giddings made me > think that I should do it sooner rather than later. Thanks! > > It's beta, but it works (for me and my Alpha tester, Ben, anyhow). > > RAA - http://raa.ruby-lang.org/project/net-mdns/ > > The rdoc overview is below, to get an idea what its about. > > Cheers, > Sam > > main:Resolv::MDNS > title:mDNS - multicast DNS and service discovery (aka "Rendezvous") > > Author:: Sam Roberts > Copyright:: Copyright (C) 2005 Sam Roberts > License:: May be distributed under the same terms as Ruby > Version:: 0.0 > Homepage:: http://vpim.rubyforge.org/mdns > Download:: http://vpim.rubyforge.org/mdns/mdns.tgz > > == Summary > An extension to the standard 'resolv' resolver library that adds support > for multicast DNS. mDNS is an extension of hierarchical, unicast DNS to > link-local multicast. It is most widely known because it is part of Apple's > OS X "Rendezvous" system, where it is used to do service discovery over > local networks. > > MDNS can be used for: > - name to address lookups on local networks > - address to name lookups on local networks (only for link-local addresses) > - discovery of services on local networks > > = Example > require 'net/http' > require 'net/dns/mdns-resolv' > require 'resolv-replace' > > # Address lookup > > begin > puts Resolv.getaddress('example.local') > rescue Resolv::ResolvError > puts "no such address!" > end > > # Service discovery > > mdns = Resolv::MDNS.new > > mdns.each_resource('_http._tcp.local', Resolv::DNS::Resource::IN::PTR) do |rrhttp| > service = rrhttp.name > host = nil > port = nil > path = '/' > > rrsrv = mdns.getresource(rrhttp.name, Resolv::DNS::Resource::IN::SRV) > host, port = rrsrv.target.to_s, rrsrv.port > rrtxt = mdns.getresource(rrhttp.name, Resolv::DNS::Resource::IN::TXT) > if rrtxt.data =~ /path=(.*)/ > path = $1 > end > > http = Net::HTTP.new(host, port) > > headers = http.head(path) > > puts "#{service[0]} on #{host}:#{port}#{path} was last-modified #{headers['last-modified']}" > end > > == Address Lookups > When used for name lookups, it is most useful to add MDNS to the default > set of resolvers queried when using the 'resolv' module methods. This is > done by doing: > require 'net/dns/mdns-resolv' > Resolv.getaddress('localhost') # resolved using Resolv::Hosts("/etc/hosts") > Resolv.getaddress('www.example.com') # resolved using Resolv::DNS > Resolv.getaddress('example.local') # resolved using Resolv::MDNS > Using this approach means that both global DNS names and local names can be > resolved. When doing this, you may also consider doing: > require 'resolv-replace' > This has the effect of replacing the default ruby implementation of address > lookup in IPSocket, TCPSocket, UDPSocket, and SOCKSocket with > Resolv.getaddress, so (if 'net/dns/mdns-resolv' has been required) the > standard libraries TCP/IP classes will use mDNS for name lookups in the .local domain. > > == Service Discovery > > Service discovery consists of 2 stages: > - enumerating the names of the instances of the service > - resolving the instance names > > = Service Enumeration > > To do this query the pointer records (Resolv::DNS::Resource::IN::PTR) for > names of the form _svc._prot.local. The values of svc and prot for common > services can be found at http://www.dns-sd.org/ServiceTypes.html. > The first label of the name returned is suitable for display to peoplem, and > should be unique in the network. > > = Service Resolution > > In order to resolve a service name query the service record > (Resolv::DNS::Resource::IN::SRV) for the name. The service record contains > a host and port to connect to. The host name will have to be resolved to > an address. This can be done explicitly using mDNS or, if resolv-replace > and mdns-default have been required, it will be done by the standard library. > In addition, some services put "extra" information about the service in a > text (Resolv::DNS::Resource::IN::TXT) record associated with the service name. > The format of the text record is service-specific. > > == 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 > - http://www.dns-sd.org > > == Comparison to the DNS-SD Extension > > The DNS-SD project at http://dnssd.rubyforge.org/wiki/wiki.pl 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 (they can > take advantage of the daemon's cache) and likely a better way of doing > mDNS queries than using pure ruby. Also, the mDNS daemon is capable of > advertising services over the network, and Resolv::MDNS can't do that, > though I'm working on it. There's some technical obstacles. > > Currently, the only thing I'm aware of Resolv::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. There is no > reason DNS-SD can't do this, and I'll try and add that capability as soon as I > find a way to install and use DNS-SD, which leads to why you might be > interested in Resolv::MDNS. > > 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, Resolv::MDNS may be useful to you. > > == Samples > > There are a few samples in the samples/ directory: > - mdns.rb is useful for finding out as much as possible about services on .local > - mdns_demo.rb is a sample provided by Ben Giddings, with better docs, showing > the call sequence he uses when resolving services. Thanks, Ben! > > == TODO > > - Implement a Resolv:: object that uses the DNS-SD project, so the standard > library will use it for .local name lookups. > - Implement response cacheing and service advertising in Resolv::MDNS. > - Implement a higher level service discovery API that will work with either > DNS-SD or Resolv::MDNS, so either can be used (as available) without code > changes. > - Various API improvements, testing, ... > > == Author > > Any feedback, questions, problems, etc., please contact me, Sam Roberts, > via dnssd-developers@rubyforge.org, or directly. > > -- Into RFID? www.rfidnewsupdate.com Simple, fast, news.