dnssd 0.6.0 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/ext/Makefile +149 -0
- data/ext/extconf.rb +19 -3
- data/ext/mkmf.log +266 -0
- data/ext/rdnssd.bundle +0 -0
- data/ext/rdnssd.c +12 -13
- data/ext/rdnssd.h +28 -3
- data/ext/rdnssd.o +0 -0
- data/ext/rdnssd_service.c +420 -223
- data/ext/rdnssd_service.o +0 -0
- data/ext/rdnssd_structs.c +368 -246
- data/ext/rdnssd_structs.o +0 -0
- data/ext/rdnssd_tr.c +16 -11
- data/ext/rdnssd_tr.o +0 -0
- data/ext/run_rdoc +0 -0
- metadata +62 -38
data/ext/rdnssd.bundle
ADDED
Binary file
|
data/ext/rdnssd.c
CHANGED
@@ -20,13 +20,6 @@ static VALUE eDNSSDUnknownError;
|
|
20
20
|
|
21
21
|
static VALUE dnssd_errors[DNSSD_ERROR_END - DNSSD_ERROR_START];
|
22
22
|
|
23
|
-
/*void
|
24
|
-
dnssd_check_class(VALUE obj, VALUE cClass)
|
25
|
-
{
|
26
|
-
if (rb_obj_is_kind_of(obj, cClass) != Qtrue)
|
27
|
-
rb_raise(rb_eRuntimeError, "need %s or a subclass", rb_class2name(cClass));
|
28
|
-
}*/
|
29
|
-
|
30
23
|
static void
|
31
24
|
dnssd_errors_store(VALUE error, int num)
|
32
25
|
{
|
@@ -40,9 +33,11 @@ dnssd_check_error_code(DNSServiceErrorType e)
|
|
40
33
|
int num = (int)e;
|
41
34
|
if (num) {
|
42
35
|
if(DNSSD_ERROR_START <= num && num < DNSSD_ERROR_END) {
|
43
|
-
rb_raise(dnssd_errors[num - DNSSD_ERROR_START],
|
36
|
+
rb_raise(dnssd_errors[num - DNSSD_ERROR_START],
|
37
|
+
"DNSSD operation failed with error code: %d", num);
|
44
38
|
} else {
|
45
|
-
rb_raise(eDNSSDUnknownError,
|
39
|
+
rb_raise(eDNSSDUnknownError,
|
40
|
+
"DNSSD operation failed with unrecognized error code: %d", num);
|
46
41
|
}
|
47
42
|
}
|
48
43
|
}
|
@@ -50,15 +45,19 @@ dnssd_check_error_code(DNSServiceErrorType e)
|
|
50
45
|
void
|
51
46
|
dnssd_instantiation_error(const char *what)
|
52
47
|
{
|
53
|
-
rb_raise(rb_eRuntimeError,
|
48
|
+
rb_raise(rb_eRuntimeError,
|
49
|
+
"cannot instantiate %s, use DNSSD "
|
50
|
+
"enumerate_domains(), browse(), resolve() or register() instead",
|
51
|
+
what);
|
54
52
|
}
|
55
53
|
|
56
54
|
/*
|
57
55
|
* Document-module: DNSSD
|
58
56
|
* DNSSD is a wrapper for Apple's DNS Service Discovery library.
|
59
|
-
* The methods DNSSD.
|
60
|
-
* provide the basic API
|
61
|
-
* Discovery aware.
|
57
|
+
* The methods DNSSD.enumerate_domains, DNSSD.browse(),
|
58
|
+
* DNSSD.register(), and DNSSD.resolve() provide the basic API
|
59
|
+
* for making your applications DNS Service Discovery aware.
|
60
|
+
*
|
62
61
|
*/
|
63
62
|
|
64
63
|
static void
|
data/ext/rdnssd.h
CHANGED
@@ -7,14 +7,36 @@
|
|
7
7
|
#define RDNSSD_INCLUDED
|
8
8
|
|
9
9
|
#include <ruby.h>
|
10
|
+
#include <intern.h>
|
10
11
|
#include <dns_sd.h>
|
11
12
|
|
13
|
+
/* for if_indextoname() and other unix networking functions */
|
14
|
+
#ifdef HAVE_UNISTD_H
|
15
|
+
#include <unistd.h>
|
16
|
+
#endif
|
17
|
+
#ifdef HAVE_SYS_TYPES_H
|
18
|
+
#include <sys/types.h>
|
19
|
+
#endif
|
20
|
+
#ifdef HAVE_SYS_SOCKET_H
|
21
|
+
#include <sys/socket.h>
|
22
|
+
#endif
|
23
|
+
#ifdef HAVE_SYS_PARAM_H
|
24
|
+
#include <sys/param.h>
|
25
|
+
#endif
|
26
|
+
#ifdef HAVE_NET_IF_H
|
27
|
+
#include <net/if.h>
|
28
|
+
#endif
|
29
|
+
#ifdef HAVE_SYS_IF_H
|
30
|
+
#include <sys/if.h>
|
31
|
+
#endif
|
32
|
+
|
12
33
|
extern VALUE mDNSSD;
|
13
34
|
|
14
35
|
void dnssd_check_error_code(DNSServiceErrorType e);
|
15
36
|
void dnssd_instantiation_error(const char *what);
|
16
37
|
|
17
|
-
VALUE dnssd_create_fullname(
|
38
|
+
VALUE dnssd_create_fullname(const char *name, const char *regtype, const char *domain, int err_flag);
|
39
|
+
VALUE dnssd_split_fullname(VALUE fullname);
|
18
40
|
|
19
41
|
/* decodes a buffer, creating a new text record */
|
20
42
|
VALUE dnssd_tr_new(long len, const char *buf);
|
@@ -24,12 +46,15 @@ VALUE dnssd_tr_to_encoded_str(VALUE v);
|
|
24
46
|
/* Get DNSServiceFlags from self */
|
25
47
|
DNSServiceFlags dnssd_to_flags(VALUE obj);
|
26
48
|
|
27
|
-
VALUE
|
28
|
-
|
49
|
+
VALUE dnssd_domain_enum_new(VALUE service, DNSServiceFlags flags,
|
50
|
+
uint32_t interface, const char *domain);
|
29
51
|
|
30
52
|
VALUE dnssd_browse_new(VALUE service, DNSServiceFlags flags, uint32_t interface,
|
31
53
|
const char *name, const char *regtype, const char *domain);
|
32
54
|
|
55
|
+
VALUE dnssd_register_new(VALUE service, DNSServiceFlags flags, const char *name,
|
56
|
+
const char *regtype, const char *domain);
|
57
|
+
|
33
58
|
VALUE dnssd_resolve_new(VALUE service, DNSServiceFlags flags, uint32_t interface,
|
34
59
|
const char *fullname, const char *host_target,
|
35
60
|
uint16_t opaqueport, uint16_t txt_len, const char *txt_rec);
|
data/ext/rdnssd.o
ADDED
Binary file
|
data/ext/rdnssd_service.c
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
/*
|
2
2
|
* Ruby Rendezvous Binding
|
3
|
-
* $Id: rdnssd_service.c,v 1.
|
3
|
+
* $Id: rdnssd_service.c,v 1.24 2005/03/22 00:19:37 cmills Exp $
|
4
4
|
*
|
5
5
|
* Copyright (c) 2004 Chad Fowler, Charles Mills, Rich Kilmer
|
6
6
|
* Licenced under the same terms as Ruby.
|
@@ -8,15 +8,10 @@
|
|
8
8
|
*/
|
9
9
|
|
10
10
|
#include "rdnssd.h"
|
11
|
-
#include <
|
12
|
-
|
13
|
-
/* for if_nametoindex() */
|
14
|
-
#include <sys/types.h>
|
15
|
-
#include <sys/socket.h>
|
16
|
-
#include <net/if.h>
|
11
|
+
#include <assert.h>
|
17
12
|
|
18
13
|
#ifndef DNSSD_API
|
19
|
-
/* define as nothing if not defined in "dns_sd.h" header */
|
14
|
+
/* define as nothing if not defined in Apple's "dns_sd.h" header */
|
20
15
|
#define DNSSD_API
|
21
16
|
#endif
|
22
17
|
|
@@ -25,19 +20,19 @@ static ID dnssd_id_call;
|
|
25
20
|
static ID dnssd_id_to_str;
|
26
21
|
static ID dnssd_iv_block;
|
27
22
|
static ID dnssd_iv_thread;
|
23
|
+
static ID dnssd_iv_result;
|
28
24
|
static ID dnssd_iv_service;
|
29
25
|
|
30
26
|
#define IsDNSSDService(obj) (rb_obj_is_kind_of(obj,cDNSSDService)==Qtrue)
|
31
|
-
#define GetDNSSDService(obj, var)
|
32
|
-
|
33
|
-
static VALUE dnssd_process(VALUE service);
|
27
|
+
#define GetDNSSDService(obj, var) \
|
28
|
+
do { assert(IsDNSSDService(obj)); Data_Get_Struct(obj, DNSServiceRef, var); } while (0)
|
34
29
|
|
35
|
-
|
36
|
-
|
30
|
+
void
|
31
|
+
dnssd_callback(VALUE service, VALUE reply)
|
37
32
|
{
|
38
|
-
|
39
|
-
|
40
|
-
|
33
|
+
VALUE result = rb_funcall2( rb_ivar_get(service, dnssd_iv_block),
|
34
|
+
dnssd_id_call, 1, &reply );
|
35
|
+
rb_ivar_set(service, dnssd_iv_result, result);
|
41
36
|
}
|
42
37
|
|
43
38
|
static const char *
|
@@ -45,7 +40,7 @@ dnssd_get_domain(VALUE service_domain)
|
|
45
40
|
{
|
46
41
|
const char *domain = StringValueCStr(service_domain);
|
47
42
|
/* max len including the null terminator and trailing '.' */
|
48
|
-
if (
|
43
|
+
if (RSTRING(service_domain)->len >= kDNSServiceMaxDomainName - 1)
|
49
44
|
rb_raise(rb_eArgError, "domain name string too large");
|
50
45
|
return domain;
|
51
46
|
}
|
@@ -63,7 +58,7 @@ dnssd_get_interface_index(VALUE interface)
|
|
63
58
|
|
64
59
|
/*
|
65
60
|
* call-seq:
|
66
|
-
* DNSSD::
|
61
|
+
* DNSSD::Service.fullname(name, type, domain) => string
|
67
62
|
*
|
68
63
|
* Concatenate a three-part domain name (as seen in DNSSD::Reply#fullname())
|
69
64
|
* into a properly-escaped full domain name.
|
@@ -79,20 +74,36 @@ dnssd_get_interface_index(VALUE interface)
|
|
79
74
|
* Raises a <code>ArgumentError</code> if the full service name cannot be constructed from
|
80
75
|
* the arguments.
|
81
76
|
*/
|
82
|
-
|
83
77
|
static VALUE
|
84
|
-
|
78
|
+
dnssd_service_s_fullname(VALUE klass, VALUE name, VALUE type, VALUE domain)
|
85
79
|
{
|
86
|
-
return dnssd_create_fullname(name, type,
|
80
|
+
return dnssd_create_fullname( StringValueCStr(name), StringValueCStr(type),
|
81
|
+
StringValueCStr(domain), 1 );
|
87
82
|
}
|
88
83
|
|
89
84
|
/*
|
90
85
|
* call-seq:
|
91
|
-
* DNSSD::
|
86
|
+
* DNSSD::Service.split(fullname) => array
|
87
|
+
* DNSSD::Service.split_fullname(fullname) => array
|
92
88
|
*
|
93
|
-
*
|
89
|
+
* Split a properly escaped multi-part domain name (as seen in DNSSD::Reply#fullname())
|
90
|
+
* into an array of names.
|
91
|
+
*
|
92
|
+
* DNSSD::Service.split('_http._tcp.local.') #=> ["_http.", "_tcp.", "local."]
|
94
93
|
*/
|
94
|
+
static VALUE
|
95
|
+
dnssd_service_s_split(VALUE klass, VALUE fullname)
|
96
|
+
{
|
97
|
+
return dnssd_split_fullname(fullname);
|
98
|
+
}
|
95
99
|
|
100
|
+
/*
|
101
|
+
* call-seq:
|
102
|
+
* DNSSD::Service.new() => raises a RuntimeError
|
103
|
+
*
|
104
|
+
* Services can only be instantiated using DNSSD.enumerate_domains(),
|
105
|
+
* DNSSD.browse(), DNSSD.register(), and DNSSD.resolve().
|
106
|
+
*/
|
96
107
|
static VALUE
|
97
108
|
dnssd_service_new(int argc, VALUE *argv, VALUE klass)
|
98
109
|
{
|
@@ -101,11 +112,8 @@ dnssd_service_new(int argc, VALUE *argv, VALUE klass)
|
|
101
112
|
}
|
102
113
|
|
103
114
|
static void
|
104
|
-
|
115
|
+
dnssd_service_free_client(DNSServiceRef *client)
|
105
116
|
{
|
106
|
-
DNSServiceRef *client = (DNSServiceRef*)RDATA(service)->data;
|
107
|
-
/* set to null right away for a bit more thread safety */
|
108
|
-
RDATA(service)->data = NULL;
|
109
117
|
DNSServiceRefDeallocate(*client);
|
110
118
|
free(client); /* free the pointer */
|
111
119
|
}
|
@@ -115,10 +123,8 @@ dnssd_service_free(void *ptr)
|
|
115
123
|
{
|
116
124
|
DNSServiceRef *client = (DNSServiceRef*)ptr;
|
117
125
|
if (client) {
|
118
|
-
/* client will be non-null only if client has not been deallocated
|
119
|
-
|
120
|
-
DNSServiceRefDeallocate(*client);
|
121
|
-
free(client); /* free the pointer, see dnssd_service_alloc() below */
|
126
|
+
/* client will be non-null only if client has not been deallocated */
|
127
|
+
dnssd_service_free_client(client);
|
122
128
|
}
|
123
129
|
}
|
124
130
|
|
@@ -129,71 +135,131 @@ dnssd_service_alloc(VALUE block)
|
|
129
135
|
VALUE service = Data_Wrap_Struct(cDNSSDService, 0, dnssd_service_free, client);
|
130
136
|
rb_ivar_set(service, dnssd_iv_block, block);
|
131
137
|
rb_ivar_set(service, dnssd_iv_thread, Qnil);
|
138
|
+
rb_ivar_set(service, dnssd_iv_result, Qnil);
|
132
139
|
return service;
|
133
140
|
}
|
134
141
|
|
135
|
-
static void
|
136
|
-
dnssd_service_start(VALUE service)
|
137
|
-
{
|
138
|
-
VALUE thread = rb_thread_create(dnssd_process, (void *)service);
|
139
|
-
rb_ivar_set(service, dnssd_iv_thread, thread);
|
140
|
-
/* !! IMPORTANT: prevents premature garbage collection of the service,
|
141
|
-
* this way the thread holds a reference to the service and
|
142
|
-
* the service gets marked as long as the thread is running.
|
143
|
-
* Running threads are always marked by Ruby. !! */
|
144
|
-
rb_ivar_set(thread, dnssd_iv_service, service);
|
145
|
-
}
|
146
|
-
|
147
142
|
/*
|
148
143
|
* call-seq:
|
149
144
|
* service.stopped? => true or false
|
150
145
|
*
|
151
146
|
* Returns <code>true</code> if _service_ has been stopped, <code>false</code> otherwise.
|
152
147
|
*/
|
153
|
-
|
154
148
|
static VALUE
|
155
149
|
dnssd_service_is_stopped(VALUE service)
|
156
150
|
{
|
157
|
-
|
151
|
+
DNSServiceRef *client = (DNSServiceRef*)RDATA(service)->data;
|
152
|
+
return client == NULL ? Qtrue : Qfalse;
|
158
153
|
}
|
159
154
|
|
160
155
|
/*
|
161
156
|
* call-seq:
|
162
157
|
* service.stop => service
|
163
158
|
*
|
164
|
-
* Stops
|
159
|
+
* Stops _service_ closing the underlying socket and killing
|
165
160
|
* the underlying thread.
|
161
|
+
*
|
162
|
+
* It is good practice to all stop running services before exit.
|
163
|
+
*
|
164
|
+
* service = DNSSD.browse('_http._tcp') do |r|
|
165
|
+
* # found a service ...
|
166
|
+
* end
|
167
|
+
* sleep(2)
|
168
|
+
* service.stop
|
169
|
+
*
|
166
170
|
*/
|
167
|
-
|
168
171
|
static VALUE
|
169
172
|
dnssd_service_stop(VALUE service)
|
170
173
|
{
|
171
|
-
VALUE thread
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
/* once thread is killed we don't need to reference the block any more */
|
174
|
+
VALUE thread;
|
175
|
+
DNSServiceRef *client = (DNSServiceRef*)RDATA(service)->data;
|
176
|
+
/* set to null right away for a bit more thread safety */
|
177
|
+
RDATA(service)->data = NULL;
|
178
|
+
if (client == NULL) rb_raise(rb_eRuntimeError, "service is already stopped");
|
179
|
+
dnssd_service_free_client(client);
|
180
|
+
thread = rb_ivar_get(service, dnssd_iv_thread);
|
180
181
|
rb_ivar_set(service, dnssd_iv_block, Qnil);
|
181
|
-
|
182
|
-
|
183
|
-
|
182
|
+
rb_ivar_set(service, dnssd_iv_thread, Qnil);
|
183
|
+
|
184
|
+
if (!NIL_P(thread)) {
|
185
|
+
/* will raise error if thread is not a Ruby Thread */
|
186
|
+
rb_thread_kill(thread);
|
187
|
+
}
|
184
188
|
return service;
|
185
189
|
}
|
186
190
|
|
191
|
+
static VALUE
|
192
|
+
dnssd_service_process(VALUE service)
|
193
|
+
{
|
194
|
+
int dns_sd_fd, nfds, result;
|
195
|
+
fd_set readfds;
|
196
|
+
|
197
|
+
DNSServiceRef *client;
|
198
|
+
GetDNSSDService(service, client);
|
199
|
+
|
200
|
+
dns_sd_fd = DNSServiceRefSockFD(*client);
|
201
|
+
nfds = dns_sd_fd + 1;
|
202
|
+
for ( ;; ) {
|
203
|
+
FD_ZERO(&readfds);
|
204
|
+
FD_SET(dns_sd_fd, &readfds);
|
205
|
+
result = rb_thread_select(nfds, &readfds,
|
206
|
+
(fd_set *) NULL,
|
207
|
+
(fd_set *) NULL,
|
208
|
+
(struct timeval *) NULL);
|
209
|
+
if (result > 0) {
|
210
|
+
if ( FD_ISSET(dns_sd_fd, &readfds) ) {
|
211
|
+
DNSServiceErrorType e = DNSServiceProcessResult(*client);
|
212
|
+
dnssd_check_error_code(e);
|
213
|
+
}
|
214
|
+
} else {
|
215
|
+
break;
|
216
|
+
}
|
217
|
+
}
|
218
|
+
/* return the result from the processing */
|
219
|
+
return rb_ivar_get(service, dnssd_iv_result);
|
220
|
+
}
|
221
|
+
|
222
|
+
/* stop the service only if it is still running */
|
223
|
+
static VALUE
|
224
|
+
dnssd_service_stop2(VALUE service)
|
225
|
+
{
|
226
|
+
if (dnssd_service_is_stopped(service)) {
|
227
|
+
return service;
|
228
|
+
}
|
229
|
+
return dnssd_service_stop(service);
|
230
|
+
}
|
231
|
+
|
232
|
+
static VALUE
|
233
|
+
dnssd_service_start(VALUE service)
|
234
|
+
{
|
235
|
+
return rb_ensure(dnssd_service_process, service, dnssd_service_stop2, service);
|
236
|
+
}
|
237
|
+
|
238
|
+
static VALUE
|
239
|
+
dnssd_service_start_in_thread(VALUE service)
|
240
|
+
{
|
241
|
+
/* race condition - service.@block could be called before the service.@thread
|
242
|
+
* is set and if the block calls service.stop() will raise an error, even though
|
243
|
+
* the service has been started and is running. */
|
244
|
+
VALUE thread = rb_thread_create(dnssd_service_process, (void *)service);
|
245
|
+
rb_ivar_set(service, dnssd_iv_thread, thread);
|
246
|
+
/* !! IMPORTANT: prevents premature garbage collection of the service,
|
247
|
+
* this way the thread holds a reference to the service and
|
248
|
+
* the service gets marked as long as the thread is running.
|
249
|
+
* Running threads are always marked by Ruby. !! */
|
250
|
+
rb_ivar_set(thread, dnssd_iv_service, service);
|
251
|
+
return service;
|
252
|
+
}
|
253
|
+
|
187
254
|
/*
|
188
255
|
* call-seq:
|
189
256
|
* service.inspect => string
|
190
257
|
*
|
191
258
|
*/
|
192
|
-
|
193
259
|
static VALUE
|
194
260
|
dnssd_service_inspect(VALUE self)
|
195
261
|
{
|
196
|
-
VALUE buf = rb_str_buf_new(
|
262
|
+
VALUE buf = rb_str_buf_new(32);
|
197
263
|
rb_str_buf_cat2(buf, "<#");
|
198
264
|
rb_str_buf_cat2(buf, rb_obj_classname(self));
|
199
265
|
if (dnssd_service_is_stopped(self)) {
|
@@ -203,74 +269,116 @@ dnssd_service_inspect(VALUE self)
|
|
203
269
|
return buf;
|
204
270
|
}
|
205
271
|
|
206
|
-
static
|
207
|
-
|
272
|
+
static void DNSSD_API
|
273
|
+
dnssd_domain_enum_reply(DNSServiceRef sdRef, DNSServiceFlags flags,
|
274
|
+
uint32_t interface_index, DNSServiceErrorType e,
|
275
|
+
const char *domain, void *context)
|
208
276
|
{
|
209
|
-
|
277
|
+
VALUE service;
|
278
|
+
/* other parameters are undefined if errorCode != 0 */
|
279
|
+
dnssd_check_error_code(e);
|
280
|
+
service = (VALUE)context;
|
281
|
+
dnssd_callback(service, dnssd_domain_enum_new(service, flags, interface_index, domain));
|
210
282
|
}
|
211
283
|
|
212
284
|
static VALUE
|
213
|
-
|
285
|
+
sd_enumerate_domains(int argc, VALUE *argv, VALUE service)
|
214
286
|
{
|
215
|
-
|
216
|
-
|
287
|
+
VALUE tmp_flags, interface;
|
288
|
+
|
289
|
+
DNSServiceFlags flags = 0;
|
290
|
+
uint32_t interface_index = 0;
|
217
291
|
|
218
|
-
|
219
|
-
|
292
|
+
DNSServiceErrorType e;
|
293
|
+
DNSServiceRef *client;
|
220
294
|
|
221
|
-
|
222
|
-
nfds = dns_sd_fd + 1;
|
223
|
-
while (1) {
|
224
|
-
FD_ZERO (&readfds);
|
225
|
-
FD_SET (dns_sd_fd, &readfds);
|
226
|
-
result = rb_thread_select (nfds, &readfds, (fd_set *) NULL, (fd_set *) NULL, (struct timeval *) NULL);
|
227
|
-
if (result > 0) {
|
228
|
-
if (FD_ISSET (dns_sd_fd, &readfds)) {
|
229
|
-
DNSServiceProcessResult(*client);
|
230
|
-
}
|
231
|
-
} else {
|
232
|
-
break;
|
233
|
-
}
|
234
|
-
}
|
235
|
-
return Qnil;
|
236
|
-
}
|
295
|
+
rb_scan_args (argc, argv, "02", &tmp_flags, &interface);
|
237
296
|
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
{
|
244
|
-
VALUE service, block, browse_reply;
|
245
|
-
/* other parameters are undefined if errorCode != 0 */
|
246
|
-
dnssd_check_error_code(errorCode);
|
297
|
+
/* optional parameters */
|
298
|
+
if (!NIL_P(tmp_flags))
|
299
|
+
flags = dnssd_to_flags(tmp_flags);
|
300
|
+
if (!NIL_P(interface))
|
301
|
+
interface_index = dnssd_get_interface_index(interface);
|
247
302
|
|
248
|
-
service
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
/* client is wrapped by service */
|
254
|
-
rb_funcall2(block, dnssd_id_call, 1, &browse_reply);
|
303
|
+
GetDNSSDService(service, client);
|
304
|
+
e = DNSServiceEnumerateDomains (client, flags, interface_index,
|
305
|
+
dnssd_domain_enum_reply, (void *)service);
|
306
|
+
dnssd_check_error_code(e);
|
307
|
+
return service;
|
255
308
|
}
|
256
309
|
|
257
310
|
/*
|
258
311
|
* call-seq:
|
259
|
-
* DNSSD.
|
260
|
-
*
|
261
|
-
*
|
312
|
+
* DNSSD.enumerate_domains!(flags=0, interface=DNSSD::InterfaceAny) {|reply| block } => obj
|
313
|
+
*
|
314
|
+
* Synchronously enumerate domains available for browsing and registration.
|
315
|
+
* For each domain found a DNSSD::Reply object is passed to block with #domain
|
316
|
+
* set to the enumerated domain.
|
317
|
+
*
|
318
|
+
* available_domains = []
|
319
|
+
* timeout(2) do
|
320
|
+
* DNSSD.enumerate_domains! do |r|
|
321
|
+
* available_domains << r.domain
|
322
|
+
* end
|
323
|
+
* rescue TimeoutError
|
324
|
+
* end
|
325
|
+
* puts available_domains.inspect
|
262
326
|
*
|
263
|
-
|
264
|
-
|
327
|
+
*/
|
328
|
+
|
329
|
+
static VALUE
|
330
|
+
dnssd_enumerate_domains_bang (int argc, VALUE * argv, VALUE self)
|
331
|
+
{
|
332
|
+
return dnssd_service_start(
|
333
|
+
sd_enumerate_domains(argc, argv, dnssd_service_alloc(rb_block_proc()))
|
334
|
+
);
|
335
|
+
}
|
336
|
+
/*
|
337
|
+
* call-seq:
|
338
|
+
* DNSSD.enumerate_domains(flags=0, interface=DNSSD::InterfaceAny) {|reply| bloc } => serivce_handle
|
339
|
+
*
|
340
|
+
* Asynchronously enumerate domains available for browsing and registration.
|
341
|
+
* For each domain found a DNSSD::DomainEnumReply object is passed to block.
|
265
342
|
* The returned _service_handle_ can be used to control when to
|
266
|
-
* stop
|
343
|
+
* stop enumerating domains (see DNSSD::Service#stop).
|
344
|
+
*
|
345
|
+
* available_domains = []
|
346
|
+
* s = DNSSD.enumerate_domains do |d|
|
347
|
+
* available_domains << d.domain
|
348
|
+
* end
|
349
|
+
* sleep(0.2)
|
350
|
+
* s.stop
|
351
|
+
* puts available_domains.inspect
|
267
352
|
*
|
268
353
|
*/
|
269
354
|
|
270
355
|
static VALUE
|
271
|
-
|
356
|
+
dnssd_enumerate_domains(int argc, VALUE * argv, VALUE self)
|
357
|
+
{
|
358
|
+
return dnssd_service_start_in_thread(
|
359
|
+
sd_enumerate_domains(argc, argv, dnssd_service_alloc(rb_block_proc()))
|
360
|
+
);
|
361
|
+
}
|
362
|
+
|
363
|
+
static void DNSSD_API
|
364
|
+
dnssd_browse_reply (DNSServiceRef client, DNSServiceFlags flags,
|
365
|
+
uint32_t interface_index, DNSServiceErrorType e,
|
366
|
+
const char *name, const char *type,
|
367
|
+
const char *domain, void *context)
|
272
368
|
{
|
273
|
-
|
369
|
+
VALUE service;
|
370
|
+
/* other parameters are undefined if errorCode != 0 */
|
371
|
+
dnssd_check_error_code(e);
|
372
|
+
service = (VALUE)context;
|
373
|
+
dnssd_callback(service,
|
374
|
+
dnssd_browse_new (service, flags, interface_index, name, type, domain)
|
375
|
+
);
|
376
|
+
}
|
377
|
+
|
378
|
+
static VALUE
|
379
|
+
sd_browse(int argc, VALUE *argv, VALUE service)
|
380
|
+
{
|
381
|
+
VALUE type, domain, tmp_flags, interface;
|
274
382
|
|
275
383
|
const char *type_str;
|
276
384
|
const char *domain_str = NULL;
|
@@ -279,72 +387,91 @@ dnssd_browse (int argc, VALUE * argv, VALUE self)
|
|
279
387
|
|
280
388
|
DNSServiceErrorType e;
|
281
389
|
DNSServiceRef *client;
|
282
|
-
VALUE service;
|
283
|
-
|
284
|
-
rb_scan_args (argc, argv, "13&", &service_type, &domain,
|
285
|
-
&tmp_flags, &interface, &block);
|
286
390
|
|
287
|
-
|
288
|
-
|
289
|
-
type_str = StringValueCStr(
|
391
|
+
rb_scan_args (argc, argv, "13", &type,
|
392
|
+
&domain, &tmp_flags, &interface);
|
393
|
+
type_str = StringValueCStr(type);
|
290
394
|
|
291
395
|
/* optional parameters */
|
292
|
-
if (domain
|
396
|
+
if (!NIL_P(domain))
|
293
397
|
domain_str = dnssd_get_domain(domain);
|
294
|
-
if (tmp_flags
|
398
|
+
if (!NIL_P(tmp_flags))
|
295
399
|
flags = dnssd_to_flags(tmp_flags);
|
296
|
-
if (interface
|
400
|
+
if (!NIL_P(interface))
|
297
401
|
interface_index = dnssd_get_interface_index(interface);
|
298
402
|
|
299
|
-
/* allocate this last since all other parameters are on the stack (thanks to & unary operator) */
|
300
|
-
service = dnssd_service_alloc(block);
|
301
403
|
GetDNSSDService(service, client);
|
302
|
-
|
303
404
|
e = DNSServiceBrowse (client, flags, interface_index,
|
304
405
|
type_str, domain_str,
|
305
406
|
dnssd_browse_reply, (void *)service);
|
306
407
|
dnssd_check_error_code(e);
|
307
|
-
|
308
|
-
return service;
|
408
|
+
return service;
|
309
409
|
}
|
310
410
|
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
411
|
+
/*
|
412
|
+
* call-seq:
|
413
|
+
* DNSSD.browse!(type, domain=nil, flags=0, interface=DNSSD::InterfaceAny) {|reply| block } => obj
|
414
|
+
*
|
415
|
+
* Synchronously browse for services.
|
416
|
+
* For each service found a DNSSD::Reply object is passed to block.
|
417
|
+
*
|
418
|
+
* timeout(6) do
|
419
|
+
* DNSSD.browse!('_http._tcp') do |r|
|
420
|
+
* puts "found: #{r.inspect}"
|
421
|
+
* end
|
422
|
+
* rescue TimeoutError
|
423
|
+
* end
|
424
|
+
*
|
425
|
+
*/
|
426
|
+
static VALUE
|
427
|
+
dnssd_browse_bang(int argc, VALUE * argv, VALUE self)
|
316
428
|
{
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
service = (VALUE)context;
|
322
|
-
block = dnssd_service_get_block(service);
|
323
|
-
register_reply = dnssd_register_new(service, flags, name, regtype, domain);
|
324
|
-
|
325
|
-
rb_funcall2(block, dnssd_id_call, 1, ®ister_reply);
|
429
|
+
return dnssd_service_start(
|
430
|
+
sd_browse(argc, argv, dnssd_service_alloc(rb_block_proc()))
|
431
|
+
);
|
326
432
|
}
|
433
|
+
|
327
434
|
|
328
435
|
/*
|
329
436
|
* call-seq:
|
330
|
-
* DNSSD.
|
331
|
-
*
|
332
|
-
*
|
333
|
-
*
|
334
|
-
* Register a service.
|
335
|
-
* If a block is provided a DNSSD::RegisterReply object will passed to the block
|
336
|
-
* when the registration completes or asynchronously fails.
|
337
|
-
* If no block is passed the client will not be notified of the default values picked
|
338
|
-
* on its behalf or of any error that occur.
|
437
|
+
* DNSSD.browse(type, domain=nil, flags=0, interface=DNSSD::InterfaceAny) {|reply| block } => service_handle
|
438
|
+
*
|
439
|
+
* Asynchronously browse for services.
|
440
|
+
* For each service found a DNSSD::BrowseReply object is passed to block.
|
339
441
|
* The returned _service_handle_ can be used to control when to
|
340
|
-
* stop
|
442
|
+
* stop browsing for services (see DNSSD::Service#stop).
|
443
|
+
*
|
444
|
+
* s = DNSSD.browse('_http._tcp') do |b|
|
445
|
+
* puts "found: #{b.inspect}"
|
446
|
+
* end
|
447
|
+
*
|
341
448
|
*/
|
449
|
+
static VALUE
|
450
|
+
dnssd_browse(int argc, VALUE * argv, VALUE self)
|
451
|
+
{
|
452
|
+
return dnssd_service_start_in_thread(
|
453
|
+
sd_browse(argc, argv, dnssd_service_alloc(rb_block_proc()))
|
454
|
+
);
|
455
|
+
}
|
456
|
+
|
457
|
+
static void DNSSD_API
|
458
|
+
dnssd_register_reply (DNSServiceRef client, DNSServiceFlags flags,
|
459
|
+
DNSServiceErrorType e,
|
460
|
+
const char *name, const char *regtype,
|
461
|
+
const char *domain, void *context)
|
462
|
+
{
|
463
|
+
VALUE service;
|
464
|
+
/* other parameters are undefined if errorCode != 0 */
|
465
|
+
dnssd_check_error_code(e);
|
466
|
+
service = (VALUE)context;
|
467
|
+
dnssd_callback(service, dnssd_register_new(service, flags, name, regtype, domain));
|
468
|
+
}
|
342
469
|
|
343
470
|
static VALUE
|
344
|
-
|
471
|
+
sd_register(int argc, VALUE *argv, VALUE service)
|
345
472
|
{
|
346
|
-
VALUE
|
347
|
-
text_record, tmp_flags, interface
|
473
|
+
VALUE name, type, domain, port,
|
474
|
+
text_record, tmp_flags, interface;
|
348
475
|
|
349
476
|
const char *name_str, *type_str, *domain_str = NULL;
|
350
477
|
uint16_t opaqueport;
|
@@ -355,100 +482,117 @@ dnssd_register (int argc, VALUE * argv, VALUE self)
|
|
355
482
|
|
356
483
|
DNSServiceErrorType e;
|
357
484
|
DNSServiceRef *client;
|
358
|
-
VALUE service;
|
359
485
|
|
360
|
-
rb_scan_args (argc, argv, "43
|
361
|
-
&
|
362
|
-
&
|
363
|
-
&text_record, &tmp_flags,
|
364
|
-
&interface, &block);
|
486
|
+
rb_scan_args (argc, argv, "43",
|
487
|
+
&name, &type, &domain, &port,
|
488
|
+
&text_record, &tmp_flags, &interface);
|
365
489
|
|
366
490
|
/* required parameters */
|
367
|
-
|
368
|
-
|
369
|
-
type_str = StringValueCStr(service_type);
|
491
|
+
name_str = StringValueCStr(name);
|
492
|
+
type_str = StringValueCStr(type);
|
370
493
|
|
371
|
-
if (
|
372
|
-
domain_str = dnssd_get_domain(
|
494
|
+
if (!NIL_P(domain))
|
495
|
+
domain_str = dnssd_get_domain(domain);
|
373
496
|
/* convert from host to net byte order */
|
374
|
-
opaqueport = htons((uint16_t)NUM2UINT(
|
497
|
+
opaqueport = htons((uint16_t)NUM2UINT(port));
|
375
498
|
|
376
499
|
/* optional parameters */
|
377
|
-
if (text_record
|
500
|
+
if (!NIL_P(text_record)) {
|
378
501
|
text_record = dnssd_tr_to_encoded_str(text_record);
|
379
502
|
txt_rec = RSTRING(text_record)->ptr;
|
380
503
|
txt_len = RSTRING(text_record)->len;
|
381
504
|
}
|
382
|
-
if (tmp_flags
|
505
|
+
if (!NIL_P(tmp_flags))
|
383
506
|
flags = dnssd_to_flags(tmp_flags);
|
384
|
-
if(interface
|
507
|
+
if(!NIL_P(interface))
|
385
508
|
interface_index = dnssd_get_interface_index(interface);
|
386
509
|
|
387
|
-
/* allocate this last since all other parameters are on the stack (thanks to & unary operator) */
|
388
|
-
service = dnssd_service_alloc(block);
|
389
510
|
GetDNSSDService(service, client);
|
390
511
|
|
391
|
-
|
512
|
+
/* HACK */
|
513
|
+
rb_iv_set(service, "@interface", interface);
|
514
|
+
rb_iv_set(service, "@port", port);
|
515
|
+
rb_iv_set(service, "@text_record", text_record);
|
516
|
+
/********/
|
517
|
+
e = DNSServiceRegister (client, flags, interface_index,
|
392
518
|
name_str, type_str, domain_str,
|
393
519
|
NULL, opaqueport, txt_len, txt_rec,
|
394
|
-
/*block == Qnil ? NULL : dnssd_register_reply,*/
|
395
520
|
dnssd_register_reply, (void*)service );
|
396
521
|
dnssd_check_error_code(e);
|
397
|
-
dnssd_service_start(service);
|
398
522
|
return service;
|
399
523
|
}
|
400
524
|
|
401
525
|
/*
|
402
|
-
|
526
|
+
* call-seq:
|
527
|
+
* DNSSD.register!(name, type, domain, port, text_record=nil, flags=0, interface=DNSSD::InterfaceAny) {|reply| block } => obj
|
528
|
+
*
|
529
|
+
* Synchronously register a service. A DNSSD::Reply object is passed
|
530
|
+
* to the block when the registration completes.
|
531
|
+
*
|
532
|
+
* DNSSD.register!("My Files", "_http._tcp", nil, 8080) do |r|
|
533
|
+
* warn("successfully registered: #{r.inspect}")
|
534
|
+
* end
|
535
|
+
*
|
536
|
+
*/
|
403
537
|
static VALUE
|
404
|
-
|
538
|
+
dnssd_register_bang(int argc, VALUE * argv, VALUE self)
|
405
539
|
{
|
406
|
-
|
407
|
-
|
408
|
-
|
409
|
-
|
410
|
-
|
540
|
+
return dnssd_service_start(
|
541
|
+
sd_register(argc, argv, dnssd_service_alloc(rb_block_proc()))
|
542
|
+
);
|
543
|
+
}
|
544
|
+
|
545
|
+
/*
|
546
|
+
* call-seq:
|
547
|
+
* DNSSD.register(name, type, domain, port, text_record=nil, flags=0, interface=DNSSD::InterfaceAny) {|reply| block } => service_handle
|
548
|
+
*
|
549
|
+
* Asynchronously register a service. A DNSSD::Reply object is
|
550
|
+
* passed to the block when the registration completes.
|
551
|
+
* The returned _service_handle_ can be used to control when to
|
552
|
+
* stop the service (see DNSSD::Service#stop).
|
553
|
+
*
|
554
|
+
* # Start a webserver and register it using DNS Service Discovery
|
555
|
+
* require 'dnssd'
|
556
|
+
* require 'webrick'
|
557
|
+
*
|
558
|
+
* web_s = WEBrick::HTTPServer.new(:Port=>8080, :DocumentRoot=>Dir::pwd)
|
559
|
+
* dns_s = DNSSD.register("My Files", "_http._tcp", nil, 8080) do |r|
|
560
|
+
* warn("successfully registered: #{r.inspect}")
|
561
|
+
* end
|
562
|
+
*
|
563
|
+
* trap("INT"){ dns_s.stop; web_s.shutdown }
|
564
|
+
* web_s.start
|
565
|
+
*
|
566
|
+
*/
|
567
|
+
static VALUE
|
568
|
+
dnssd_register(int argc, VALUE * argv, VALUE self)
|
569
|
+
{
|
570
|
+
return dnssd_service_start_in_thread(
|
571
|
+
sd_register(argc, argv, dnssd_service_alloc(rb_block_proc()))
|
572
|
+
);
|
411
573
|
}
|
412
|
-
*/
|
413
574
|
|
414
575
|
static void DNSSD_API
|
415
576
|
dnssd_resolve_reply (DNSServiceRef client, DNSServiceFlags flags,
|
416
|
-
uint32_t interface_index, DNSServiceErrorType
|
577
|
+
uint32_t interface_index, DNSServiceErrorType e,
|
417
578
|
const char *fullname, const char *host_target,
|
418
579
|
uint16_t opaqueport, uint16_t txt_len,
|
419
580
|
const char *txt_rec, void *context)
|
420
581
|
{
|
582
|
+
VALUE service;
|
421
583
|
/* other parameters are undefined if errorCode != 0 */
|
422
|
-
dnssd_check_error_code(
|
423
|
-
VALUE service, block, resolve_reply;
|
424
|
-
|
584
|
+
dnssd_check_error_code(e);
|
425
585
|
service = (VALUE)context;
|
426
|
-
|
427
|
-
|
428
|
-
|
429
|
-
|
430
|
-
|
431
|
-
rb_funcall2(block, dnssd_id_call, 1, &resolve_reply);
|
586
|
+
dnssd_callback(service,
|
587
|
+
dnssd_resolve_new(service, flags, interface_index, fullname,
|
588
|
+
host_target, opaqueport, txt_len, txt_rec)
|
589
|
+
);
|
432
590
|
}
|
433
591
|
|
434
|
-
/*
|
435
|
-
* call-seq:
|
436
|
-
* DNSSD.resolve(service_name, service_type, service_domain, flags=0, interface=DNSSD::InterfaceAny) do |resolve_reply|
|
437
|
-
* block
|
438
|
-
* end => service_handle
|
439
|
-
*
|
440
|
-
* Resolve a service discovered via DNSSD.browse().
|
441
|
-
* The service is resolved to a target host name, port number, and text record - all contained
|
442
|
-
* in the DNSSD::ResolveReply object passed to the required block.
|
443
|
-
* The returned _service_handle_ can be used to control when to
|
444
|
-
* stop resolving the service (see DNSSD::Service#stop).
|
445
|
-
*/
|
446
|
-
|
447
592
|
static VALUE
|
448
|
-
|
593
|
+
sd_resolve(int argc, VALUE *argv, VALUE service)
|
449
594
|
{
|
450
|
-
VALUE
|
451
|
-
tmp_flags, interface, block;
|
595
|
+
VALUE name, type, domain, tmp_flags, interface;
|
452
596
|
|
453
597
|
const char *name_str, *type_str, *domain_str;
|
454
598
|
DNSServiceFlags flags = 0;
|
@@ -456,34 +600,76 @@ dnssd_resolve(int argc, VALUE * argv, VALUE self)
|
|
456
600
|
|
457
601
|
DNSServiceErrorType err;
|
458
602
|
DNSServiceRef *client;
|
459
|
-
VALUE service;
|
460
603
|
|
461
|
-
rb_scan_args
|
462
|
-
&service_name, &service_type, &service_domain,
|
463
|
-
&tmp_flags, &interface, &block);
|
604
|
+
rb_scan_args(argc, argv, "32", &name, &type, &domain, &tmp_flags, &interface);
|
464
605
|
|
465
606
|
/* required parameters */
|
466
|
-
|
467
|
-
|
468
|
-
|
469
|
-
domain_str = dnssd_get_domain(service_domain);
|
607
|
+
name_str = StringValueCStr(name),
|
608
|
+
type_str = StringValueCStr(type),
|
609
|
+
domain_str = dnssd_get_domain(domain);
|
470
610
|
|
471
611
|
/* optional parameters */
|
472
|
-
if (tmp_flags
|
612
|
+
if (!NIL_P(tmp_flags))
|
473
613
|
flags = dnssd_to_flags(tmp_flags);
|
474
|
-
if (interface
|
614
|
+
if (!NIL_P(interface))
|
475
615
|
interface_index = dnssd_get_interface_index(interface);
|
476
|
-
}
|
477
616
|
|
478
|
-
/* allocate this last since all other parameters are on the stack (thanks to unary & operator) */
|
479
|
-
service = dnssd_service_alloc(block);
|
480
617
|
GetDNSSDService(service, client);
|
481
|
-
|
482
618
|
err = DNSServiceResolve (client, flags, interface_index, name_str, type_str,
|
483
|
-
domain_str, dnssd_resolve_reply, (void *)
|
619
|
+
domain_str, dnssd_resolve_reply, (void *)service);
|
484
620
|
dnssd_check_error_code(err);
|
485
|
-
|
486
|
-
|
621
|
+
return service;
|
622
|
+
}
|
623
|
+
|
624
|
+
/*
|
625
|
+
* call-seq:
|
626
|
+
* DNSSD.resolve!(name, type, domain, flags=0, interface=DNSSD::InterfaceAny) {|reply| block } => obj
|
627
|
+
*
|
628
|
+
* Synchronously resolve a service discovered via DNSSD.browse().
|
629
|
+
* The service is resolved to a target host name, port number, and
|
630
|
+
* text record - all contained in the DNSSD::Reply object
|
631
|
+
* passed to the required block.
|
632
|
+
*
|
633
|
+
* timeout(2) do
|
634
|
+
* DNSSD.resolve!("foo bar", "_http._tcp", "local") do |r|
|
635
|
+
* puts r.inspect
|
636
|
+
* end
|
637
|
+
* rescue TimeoutError
|
638
|
+
* end
|
639
|
+
*
|
640
|
+
*/
|
641
|
+
static VALUE
|
642
|
+
dnssd_resolve_bang(int argc, VALUE * argv, VALUE self)
|
643
|
+
{
|
644
|
+
return dnssd_service_start(
|
645
|
+
sd_resolve(argc, argv, dnssd_service_alloc(rb_block_proc()))
|
646
|
+
);
|
647
|
+
}
|
648
|
+
|
649
|
+
/*
|
650
|
+
* call-seq:
|
651
|
+
* DNSSD.resolve(name, type, domain, flags=0, interface=DNSSD::InterfaceAny) {|reply| block } => service_handle
|
652
|
+
*
|
653
|
+
* Asynchronously resolve a service discovered via DNSSD.browse().
|
654
|
+
* The service is resolved to a target host name, port number, and
|
655
|
+
* text record - all contained in the DNSSD::Reply object
|
656
|
+
* passed to the required block.
|
657
|
+
* The returned _service_handle_ can be used to control when to
|
658
|
+
* stop resolving the service (see DNSSD::Service#stop).
|
659
|
+
*
|
660
|
+
* s = DNSSD.resolve("foo bar", "_http._tcp", "local") do |r|
|
661
|
+
* puts r.inspect
|
662
|
+
* end
|
663
|
+
* sleep(2)
|
664
|
+
* s.stop
|
665
|
+
*
|
666
|
+
*/
|
667
|
+
static VALUE
|
668
|
+
dnssd_resolve(int argc, VALUE * argv, VALUE self)
|
669
|
+
{
|
670
|
+
return dnssd_service_start_in_thread(
|
671
|
+
sd_resolve(argc, argv, dnssd_service_alloc(rb_block_proc()))
|
672
|
+
);
|
487
673
|
}
|
488
674
|
|
489
675
|
void
|
@@ -497,19 +683,30 @@ Init_DNSSD_Service(void)
|
|
497
683
|
dnssd_id_to_str = rb_intern("to_str");
|
498
684
|
dnssd_iv_block = rb_intern("@block");
|
499
685
|
dnssd_iv_thread = rb_intern("@thread");
|
686
|
+
dnssd_iv_result = rb_intern("@result");
|
500
687
|
dnssd_iv_service = rb_intern("@service");
|
501
688
|
|
502
689
|
cDNSSDService = rb_define_class_under(mDNSSD, "Service", rb_cObject);
|
503
690
|
|
504
691
|
rb_define_singleton_method(cDNSSDService, "new", dnssd_service_new, -1);
|
505
|
-
rb_define_singleton_method(cDNSSDService, "fullname",
|
692
|
+
rb_define_singleton_method(cDNSSDService, "fullname", dnssd_service_s_fullname, 3);
|
693
|
+
rb_define_singleton_method(cDNSSDService, "split_fullname", dnssd_service_s_split, 1);
|
694
|
+
rb_define_singleton_method(cDNSSDService, "split", dnssd_service_s_split, 1);
|
695
|
+
|
696
|
+
/* Access the services underlying thread. Returns nil if the service is synchronous. */
|
697
|
+
rb_define_attr(cDNSSDService, "thread", 1, 0);
|
506
698
|
|
507
699
|
rb_define_method(cDNSSDService, "stop", dnssd_service_stop, 0);
|
508
700
|
rb_define_method(cDNSSDService, "stopped?", dnssd_service_is_stopped, 0);
|
509
701
|
rb_define_method(cDNSSDService, "inspect", dnssd_service_inspect, 0);
|
510
702
|
|
703
|
+
rb_define_module_function(mDNSSD, "enumerate_domains", dnssd_enumerate_domains, -1);
|
704
|
+
rb_define_module_function(mDNSSD, "enumerate_domains!", dnssd_enumerate_domains_bang, -1);
|
511
705
|
rb_define_module_function(mDNSSD, "browse", dnssd_browse, -1);
|
706
|
+
rb_define_module_function(mDNSSD, "browse!", dnssd_browse_bang, -1);
|
512
707
|
rb_define_module_function(mDNSSD, "resolve", dnssd_resolve, -1);
|
708
|
+
rb_define_module_function(mDNSSD, "resolve!", dnssd_resolve_bang, -1);
|
513
709
|
rb_define_module_function(mDNSSD, "register", dnssd_register, -1);
|
710
|
+
rb_define_module_function(mDNSSD, "register!", dnssd_register_bang, -1);
|
514
711
|
}
|
515
712
|
|