Module: DNSSD

Defined in:
lib/dnssd.rb,
lib/dnssd.rb,
ext/dnssd/dnssd.c,
ext/dnssd/flags.c,
ext/dnssd/errors.c,
ext/dnssd/record.c,
ext/dnssd/service.c

Overview

DNSSD is a wrapper for the DNS Service Discovery library.

DNSSD.announce and DNSSD::Reply.connect provide an easy-to-use way to announce and connect to services.

The methods DNSSD.enumerate_domains, DNSSD.browse, DNSSD.register, and DNSSD.resolve provide the basic API for making your applications DNS Service Discovery aware.

Defined Under Namespace

Classes: AlreadyRegisteredError, BadFlagsError, BadInterfaceIndexError, BadKeyError, BadParamError, BadReferenceError, BadSigError, BadStateError, BadTimeError, ClientIncompatibleError, DoubleNATError, Error, FirewallError, Flags, InvalidError, NATPortMappingDisabled, NATPortMappingUnsupported, NATTraversalError, NameConflictError, NoAuthenticationError, NoMemoryError, NoSuchKeyError, NoSuchNameError, NoSuchRecordError, NotInitializedError, Record, RefusedError, Reply, Service, ServiceNotRunningError, TextRecord, TransientError, UnknownError, UnsupportedError

Constant Summary collapse

VERSION =

The version of DNSSD you’re using.

'3.0.2'
InterfaceUnicast =

Unicast interfaces

ULONG2NUM(kDNSServiceInterfaceIndexUnicast)
InterfaceAny =

All interfaces

ULONG2NUM(kDNSServiceInterfaceIndexAny)
InterfaceLocalOnly =

Local interfaces, for services running only on the same machine

ULONG2NUM(kDNSServiceInterfaceIndexLocalOnly)

Class Method Summary collapse

Class Method Details

.announce(socket, name, service = nil, text_record = nil, flags = 0, interface = DNSSD::InterfaceAny, &block) ⇒ Object

Registers socket with DNSSD as name. If service is omitted it is looked up using #getservbyport and the ports address. text_record, flags and interface are used as in #register.

Returns the Service created by registering the socket. The Service will automatically be shut down when #close or #close_read is called on the socket.

Only for bound TCP and UDP sockets.

Raises:

  • (ArgumentError)


29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
# File 'lib/dnssd.rb', line 29

def self.announce(socket, name, service = nil, text_record = nil, flags = 0,
                  interface = DNSSD::InterfaceAny, &block)
  _, port, = socket.addr

  raise ArgumentError, 'socket not bound' if port == 0

  service ||= Socket.getservbyport port

  proto = case socket
          when TCPSocket then 'tcp'
          when UDPSocket then 'udp'
          else raise ArgumentError, 'tcp or udp sockets only'
          end

  type = "_#{service}._#{proto}"

  registrar = register(name, type, nil, port, text_record, flags, interface,
                       &block)

  socket.instance_variable_set :@registrar, registrar

  def socket.close
    result = super
    @registrar.stop
    return result
  end

  def socket.close_read
    result = super
    @registrar.stop
    return result
  end

  registrar
end

.browse(type, domain = nil, flags = 0, interface = DNSSD::InterfaceAny) ⇒ Object

Asynchronous version of DNSSD::Service#browse



68
69
70
71
72
# File 'lib/dnssd.rb', line 68

def self.browse type, domain = nil, flags = 0, interface = DNSSD::InterfaceAny
  service = DNSSD::Service.browse type, domain, flags, interface
  service.async_each { |r| yield r }
  service
end

.browse!(type, domain = nil, flags = 0, interface = DNSSD::InterfaceAny) ⇒ Object

Synchronous version of DNSSD::Service#browse



77
78
79
80
81
82
# File 'lib/dnssd.rb', line 77

def self.browse! type, domain = nil, flags = 0, interface = DNSSD::InterfaceAny
  service = DNSSD::Service.browse type, domain, flags, interface
  service.each { |r| yield r }
ensure
  service.stop
end

.enumerate_domains(flags = DNSSD::Flags::BrowseDomains, interface = DNSSD::InterfaceAny) ⇒ Object

Asynchronous version of DNSSD::Service#enumerate_domains



87
88
89
90
91
92
# File 'lib/dnssd.rb', line 87

def self.enumerate_domains flags = DNSSD::Flags::BrowseDomains,
                           interface = DNSSD::InterfaceAny
  service = DNSSD::Service.enumerate_domains flags, interface
  service.async_each { |r| yield r }
  service
end

.enumerate_domains!(flags = DNSSD::Flags::BrowseDomains, interface = DNSSD::InterfaceAny, &block) ⇒ Object

Synchronous version of DNSSD::Service#enumerate_domains



97
98
99
100
101
102
103
# File 'lib/dnssd.rb', line 97

def self.enumerate_domains!(flags = DNSSD::Flags::BrowseDomains,
                            interface = DNSSD::InterfaceAny, &block)
  service = DNSSD::Service.enumerate_domains flags, interface
  service.each { |r| yield r }
ensure
  service.stop
end

.interface_name(interface_index) ⇒ Object

Returns the interface name for interface interface_index.

DNSSD.interface_name 1 # => 'lo0'


17
18
19
20
# File 'ext/dnssd/dnssd.c', line 17

static VALUE
dnssd_if_nametoindex(VALUE self, VALUE name) {
  return UINT2NUM(if_nametoindex(StringValueCStr(name)));
}

.interface_index(interface_name) ⇒ Object

Returns the interface index for interface interface_name.

DNSSD.interface_index 'lo0' # => 1


31
32
33
34
35
36
37
38
39
40
41
# File 'ext/dnssd/dnssd.c', line 31

static VALUE
dnssd_if_indextoname(VALUE self, VALUE index) {
  char buffer[IF_NAMESIZE];

  if (if_indextoname(NUM2UINT(index), buffer))
    return rb_str_new2(buffer);

  rb_raise(rb_eArgError, "invalid interface %d", NUM2UINT(index));

  return Qnil;
}

.register(name, type, domain, port, text_record = nil, flags = 0, interface = DNSSD::InterfaceAny) ⇒ Object

Asynchronous version of DNSSD::Service#register



108
109
110
111
112
113
114
115
116
# File 'lib/dnssd.rb', line 108

def self.register(name, type, domain, port, text_record = nil, flags = 0,
                  interface = DNSSD::InterfaceAny)
  service = DNSSD::Service.register name, type, domain, port, nil,
    text_record, flags, interface

  service.async_each { |r| yield r } if block_given?

  service
end

.register!(name, type, domain, port, text_record = nil, flags = 0, interface = DNSSD::InterfaceAny, &block) ⇒ Object

Synchronous version of DNSSD::Service#register



121
122
123
124
125
126
127
128
129
# File 'lib/dnssd.rb', line 121

def self.register!(name, type, domain, port, text_record = nil, flags = 0,
                   interface = DNSSD::InterfaceAny, &block)
  service = DNSSD::Service.register name, type, domain, port, nil,
    text_record, flags, interface

  service.each { |r| yield r } if block_given?
ensure
  service.stop
end

.resolve(*args) ⇒ Object

Asynchronous version of DNSSD::Service#resolve



134
135
136
137
138
# File 'lib/dnssd.rb', line 134

def self.resolve(*args)
  service = DNSSD::Service.resolve(*args)
  service.async_each { |r| yield r }
  service
end

.resolve!(*args) ⇒ Object

Synchronous version of DNSSD::Service#resolve



143
144
145
146
147
148
# File 'lib/dnssd.rb', line 143

def self.resolve!(*args)
  service = DNSSD::Service.resolve(*args)
  service.each { |r| yield r }
ensure
  service.stop if service
end