ANN: net-mdns, multicast DNS and service discovery (aka "Rendezvous")

Discussion in 'Ruby' started by Sam Roberts, Feb 3, 2005.

  1. Sam Roberts

    Sam Roberts Guest

    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 , or directly.
    Sam Roberts, Feb 3, 2005
    #1
    1. Advertising

  2. Sam Roberts

    Ben Giddings Guest

    Hi Sam,

    Thanks for putting this up!

    Just to let you folks know, this may be alpha software, and may still
    have bugs, but it works for what I need, and works well. You may be
    interested to know that it is in much better shape than Python's
    zeroconf implementation.

    Ben
    Ben Giddings, Feb 3, 2005
    #2
    1. Advertising

  3. 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 , or directly.
    >
    >



    --
    Into RFID? www.rfidnewsupdate.com Simple, fast, news.
    Lyndon Samson, Feb 3, 2005
    #3
  4. Sam Roberts

    Ben Giddings Guest

    On Feb 3, 2005, at 17:33, Lyndon Samson wrote:
    > Rendezvous is a ( good ) Tibco messaging product, don't get their
    > lawyers fired up again ;-)


    Um, google sez Apple wins. Apple has called their implementation of
    zeroconf Rendezvous forever. If there's anybody's lawyers we have to
    worry about it's, Apple's. I think they trademarked "Rendezvous", the
    IETF name is "zeroconf". Meh, whatever. It's great software, we can
    figure out the names later. :)

    Ben
    Ben Giddings, Feb 4, 2005
    #4
  5. Ben Giddings wrote:
    > On Feb 3, 2005, at 17:33, Lyndon Samson wrote:
    >
    >> Rendezvous is a ( good ) Tibco messaging product, don't get their
    >> lawyers fired up again ;-)

    >
    >
    > Um, google sez Apple wins. Apple has called their implementation of
    > zeroconf Rendezvous forever. If there's anybody's lawyers we have to
    > worry about it's, Apple's. I think they trademarked "Rendezvous", the
    > IETF name is "zeroconf". Meh, whatever. It's great software, we can
    > figure out the names later. :)


    Actually, Apple is phasing out the name "Rendezvous" because of the
    Tibco lawsuit. Regardless, just call it MDNS (multicast DNS) or DNSSD
    (DNS service discovery), depending on what you're actually talking about
    and you're fine.

    -garrett
    Garrett Rooney, Feb 4, 2005
    #5
  6. Sam Roberts

    Sam Roberts Guest

    Wrote Garrett Rooney <>, on Sat, Feb 05, 2005 at 12:45:47AM +0900:
    > Actually, Apple is phasing out the name "Rendezvous" because of the
    > Tibco lawsuit. Regardless, just call it MDNS (multicast DNS) or DNSSD
    > (DNS service discovery), depending on what you're actually talking about
    > and you're fine.


    Note that the lib is called net-mdns, and the only mention of
    "Rendezous" is one note that Apple calls it that. Which they still do,
    its smeared across their web site, and the minds of their users.

    Cheers,
    Sam

    --
    Sam Roberts <>
    Sam Roberts, Feb 4, 2005
    #6
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. i_lk

    Rendezvous Peers In JXTA

    i_lk, Oct 17, 2005, in forum: Java
    Replies:
    0
    Views:
    622
  2. Richard Kilmer
    Replies:
    5
    Views:
    260
    Mikael Brockman
    Oct 9, 2004
  3. Sam Roberts
    Replies:
    0
    Views:
    241
    Sam Roberts
    Feb 6, 2005
  4. Sam Roberts
    Replies:
    0
    Views:
    206
    Sam Roberts
    Mar 20, 2005
  5. Doug Beaver
    Replies:
    0
    Views:
    119
    Doug Beaver
    Dec 17, 2005
Loading...

Share This Page