dnssd 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,588 @@
1
+ /*
2
+ * Copyright (c) 2004 Chad Fowler, Charles Mills, Rich Kilmer
3
+ * Licensed under the same terms as Ruby.
4
+ * This software has absolutely no warranty.
5
+ */
6
+ #include "rdnssd.h"
7
+
8
+ /* for if_indextoname() */
9
+ #include <sys/types.h>
10
+ #include <sys/socket.h>
11
+ #include <net/if.h>
12
+
13
+ static VALUE cDNSSDFlags;
14
+ static VALUE cDNSSDReply;
15
+ static VALUE cDNSSDBrowseReply;
16
+ static VALUE cDNSSDResolveReply;
17
+ static VALUE cDNSSDRegisterReply;
18
+
19
+ static ID dnssd_iv_flags;
20
+ static ID dnssd_iv_interface;
21
+ static ID dnssd_iv_fullname;
22
+ static ID dnssd_iv_target;
23
+ static ID dnssd_iv_port;
24
+ static ID dnssd_iv_text_record;
25
+ static ID dnssd_iv_name;
26
+ static ID dnssd_iv_type;
27
+ static ID dnssd_iv_domain;
28
+ static ID dnssd_iv_service;
29
+
30
+ #define IsDNSSDFlags(obj) (rb_obj_is_kind_of(obj,cDNSSDFlags)==Qtrue)
31
+
32
+ /* dns sd flags, flag ID's, flag names */
33
+ #define DNSSD_MAX_FLAGS 9
34
+
35
+ static const DNSServiceFlags dnssd_flag[DNSSD_MAX_FLAGS] = {
36
+ kDNSServiceFlagsMoreComing,
37
+
38
+ kDNSServiceFlagsAdd,
39
+ kDNSServiceFlagsDefault,
40
+
41
+ kDNSServiceFlagsNoAutoRename,
42
+
43
+ kDNSServiceFlagsShared,
44
+ kDNSServiceFlagsUnique,
45
+
46
+ kDNSServiceFlagsBrowseDomains,
47
+ kDNSServiceFlagsRegistrationDomains,
48
+
49
+ kDNSServiceFlagsLongLivedQuery
50
+ };
51
+
52
+ static ID dnssd_flag_iv[DNSSD_MAX_FLAGS];
53
+
54
+ static const char *dnssd_flag_name[DNSSD_MAX_FLAGS] = {
55
+ "more_coming",
56
+ "add",
57
+ "default",
58
+ "no_auto_rename",
59
+ "shared",
60
+ "unique",
61
+ "browse_domains",
62
+ "registration_domains",
63
+ "long_lived_query"
64
+ };
65
+
66
+ static VALUE
67
+ dnssd_struct_inspect(VALUE self, volatile VALUE data)
68
+ {
69
+ VALUE buf = rb_str_buf_new(0);
70
+ rb_str_buf_cat2(buf, "#<");
71
+ rb_str_buf_cat2(buf, rb_obj_classname(self));
72
+ if (RSTRING(data)->len > 0) {
73
+ rb_str_buf_cat2(buf, " ");
74
+ rb_str_buf_append(buf, data);
75
+ }
76
+ rb_str_buf_cat2(buf, ">");
77
+ return buf;
78
+ }
79
+
80
+ VALUE
81
+ dnssd_create_fullname(VALUE name, VALUE regtype, VALUE domain, int err_flag)
82
+ {
83
+ char buffer[kDNSServiceMaxDomainName];
84
+ int ret_val = DNSServiceConstructFullName(buffer,
85
+ NIL_P(name) ? NULL : StringValueCStr(name),
86
+ StringValueCStr(regtype),
87
+ StringValueCStr(domain) );
88
+ if (ret_val) {
89
+ static const char msg[] = "could not construct full service name";
90
+ if (err_flag) rb_raise(rb_eArgError, msg);
91
+ /* else */
92
+ rb_warn(msg);
93
+ return name;
94
+ }
95
+ buffer[kDNSServiceMaxDomainName - 1] = '\000'; /* just in case */
96
+ return rb_str_new2(buffer);
97
+ }
98
+
99
+ static VALUE
100
+ dnssd_get_fullname(VALUE self, int flag)
101
+ {
102
+ return dnssd_create_fullname( rb_ivar_get(self, dnssd_iv_name),
103
+ rb_ivar_get(self, dnssd_iv_type),
104
+ rb_ivar_get(self, dnssd_iv_domain), flag );
105
+ }
106
+
107
+ /*
108
+ * call-seq:
109
+ * reply.fullname => string
110
+ *
111
+ * The fullname of the resource the reply is associated with.
112
+ * See DNSSD::Service.fullname() for more information.
113
+ */
114
+
115
+ static VALUE
116
+ dnssd_reply_fullname(VALUE self)
117
+ {
118
+ return dnssd_get_fullname(self, 1);
119
+ }
120
+
121
+ static void
122
+ dnssd_add_names(volatile VALUE self, const char *name,
123
+ const char *regtype, const char *domain)
124
+ {
125
+ rb_ivar_set(self, dnssd_iv_name, rb_str_new2(name));
126
+ rb_ivar_set(self, dnssd_iv_type, rb_str_new2(regtype));
127
+ rb_ivar_set(self, dnssd_iv_domain, rb_str_new2(domain));
128
+ }
129
+
130
+ static void
131
+ dnssd_init_flag_iv(void)
132
+ {
133
+ /* initialize flag instance variable ids. */
134
+ char buffer[32];
135
+ int i;
136
+ for (i=0; i<DNSSD_MAX_FLAGS; i++) {
137
+ snprintf(buffer, sizeof(buffer), "@%s", dnssd_flag_name[i]);
138
+ dnssd_flag_iv[i] = rb_intern(buffer);
139
+ }
140
+ }
141
+
142
+ static void
143
+ dnssd_init_flags_methods(VALUE class)
144
+ {
145
+ char buffer[128];
146
+ int i;
147
+ for (i=0; i<DNSSD_MAX_FLAGS; i++) {
148
+ volatile VALUE str;
149
+ size_t len = snprintf(buffer, sizeof(buffer),
150
+ "def %s?; @%s end",
151
+ dnssd_flag_name[i],
152
+ dnssd_flag_name[i]);
153
+ str = rb_str_new(buffer, (long)len);
154
+ rb_mod_module_eval(1, (VALUE *)&str, class);
155
+ /* attr_writer method for each flag */
156
+ rb_define_attr(class, dnssd_flag_name[i], 0, 1);
157
+ }
158
+ }
159
+
160
+ static VALUE
161
+ dnssd_flags_init(VALUE self, DNSServiceFlags flags)
162
+ {
163
+ int i;
164
+ for (i=0; i<DNSSD_MAX_FLAGS; i++) {
165
+ /* check each flag using binary and, set to Qtrue of exists */
166
+ if (flags & dnssd_flag[i]) {
167
+ rb_ivar_set(self, dnssd_flag_iv[i], Qtrue);
168
+ } else {
169
+ rb_ivar_set(self, dnssd_flag_iv[i], Qfalse);
170
+ }
171
+ }
172
+ return self;
173
+ }
174
+
175
+ static DNSServiceFlags
176
+ dnssd_get_flags(VALUE self)
177
+ {
178
+ DNSServiceFlags flags = 0;
179
+ int i;
180
+ for (i=0; i<DNSSD_MAX_FLAGS; i++) {
181
+ if (RTEST(rb_ivar_get(self, dnssd_flag_iv[i]))) {
182
+ flags |= dnssd_flag[i];
183
+ }
184
+ }
185
+ return flags;
186
+ }
187
+
188
+ DNSServiceFlags
189
+ dnssd_to_flags(VALUE obj)
190
+ {
191
+ DNSServiceFlags flags = 0;
192
+ if (IsDNSSDFlags(obj)) {
193
+ flags = dnssd_get_flags(obj);
194
+ } else {
195
+ flags = NUM2ULONG(obj);
196
+ }
197
+ return flags;
198
+ }
199
+
200
+ /*
201
+ * call-seq:
202
+ * DNSSD::Flags.new() => flags
203
+ * DNSSD::Flags.new(integer) => flags
204
+ * DNSSD::Flags.new(flags) => dup_of_flags
205
+ *
206
+ * Returns a new group of flags. In the first form,
207
+ * none of the new flags are set.
208
+ * In the second the flags corresponding to the bits of _integer_ are set.
209
+ * In the third the flags set in _flags_ are set.
210
+ *
211
+ * flags = Flags.new()
212
+ * flags.more_coming = true
213
+ * flags.to_i #=> DNSSD::Flags::MoreComing
214
+ * f.shared = true
215
+ * flags.to_i #=> Flags::MoreComing | Flags::Shared
216
+ * same_flags = Flags.new(Flags::MoreComing | Flags::Shared)
217
+ * flags == same_flags #=> true
218
+ *
219
+ */
220
+
221
+ static VALUE
222
+ dnssd_flags_initialize(int argc, VALUE *argv, VALUE self)
223
+ {
224
+ VALUE def_val = Qnil;
225
+ DNSServiceFlags flags = 0;
226
+
227
+ rb_scan_args(argc, argv, "01", &def_val);
228
+ if (def_val != Qnil) {
229
+ flags = dnssd_to_flags(def_val);
230
+ }
231
+ return dnssd_flags_init(self, flags);
232
+ }
233
+
234
+ static VALUE
235
+ dnssd_flags_new(DNSServiceFlags flags)
236
+ {
237
+ return dnssd_flags_init(rb_obj_alloc(cDNSSDFlags), flags);
238
+ }
239
+
240
+ /*
241
+ * call-seq:
242
+ * flags.to_i => an_integer
243
+ *
244
+ * Get the integer representation of _flags_ by bitwise or'ing
245
+ * each of the set flags.
246
+ */
247
+
248
+ static VALUE
249
+ dnssd_flags_to_i(VALUE self)
250
+ {
251
+ return ULONG2NUM(dnssd_get_flags(self));
252
+ }
253
+
254
+ static VALUE
255
+ dnssd_flags_list(VALUE self)
256
+ {
257
+ VALUE buf = rb_str_buf_new(0);
258
+ int i;
259
+ for (i=0; i<DNSSD_MAX_FLAGS; i++) {
260
+ if (rb_ivar_get(self, dnssd_flag_iv[i])) {
261
+ rb_str_buf_cat2(buf, dnssd_flag_name[i]);
262
+ rb_str_buf_cat2(buf, ",");
263
+ }
264
+ }
265
+ /* get rid of trailing comma */
266
+ if (RSTRING(buf)->len > 0) {
267
+ RSTRING(buf)->len--;
268
+ }
269
+ return buf;
270
+ }
271
+
272
+ /*
273
+ * call-seq:
274
+ * flags.inspect => string
275
+ *
276
+ * Create a printable version of _flags_.
277
+ *
278
+ * flags = DNSSD::Flags.new
279
+ * flags.add = true
280
+ * flags.default = true
281
+ * flags.inspect # => "#<DNSSD::Flags add,default>"
282
+ */
283
+
284
+ static VALUE
285
+ dnssd_flags_inspect(VALUE self)
286
+ {
287
+ volatile VALUE data = dnssd_flags_list(self);
288
+ return dnssd_struct_inspect(self, data);
289
+ }
290
+
291
+ /*
292
+ * call-seq:
293
+ * flags == obj => true or false
294
+ *
295
+ * Equality--Two groups of flags are equal if the flags underlying integers
296
+ * are equal.
297
+ *
298
+ * flags = Flags.new()
299
+ * flags.more_coming = true
300
+ * flags.shared = true
301
+ * flags == Flags::MoreComing | Flags::Shared #=> true
302
+ * flags == Flags.new(Flags::MoreComing | Flags::Shared) #=> true
303
+ */
304
+
305
+ static VALUE
306
+ dnssd_flags_equal(VALUE self, VALUE obj)
307
+ {
308
+ DNSServiceFlags flags = dnssd_get_flags(self);
309
+ DNSServiceFlags obj_flags = dnssd_to_flags(obj);
310
+
311
+ return flags == obj_flags ? Qtrue : Qfalse;
312
+ }
313
+
314
+ static VALUE
315
+ dnssd_interface_name(uint32_t interface)
316
+ {
317
+ char buffer[IF_NAMESIZE];
318
+ if (if_indextoname(interface, buffer)) {
319
+ return rb_str_new2(buffer);
320
+ } else {
321
+ return ULONG2NUM(interface);
322
+ }
323
+ }
324
+
325
+ static VALUE
326
+ dnssd_get_interface(VALUE self)
327
+ {
328
+ return rb_String(rb_ivar_get(self, dnssd_iv_interface));
329
+ }
330
+
331
+ /*
332
+ * call-seq:
333
+ * register_reply.inspect => string
334
+ *
335
+ */
336
+
337
+ static VALUE
338
+ dnssd_register_inspect(VALUE self)
339
+ {
340
+ volatile VALUE data = dnssd_get_fullname(self, 0);
341
+ return dnssd_struct_inspect(self, data);
342
+ }
343
+
344
+ VALUE
345
+ dnssd_register_new(VALUE service, DNSServiceFlags flags, const char *name,
346
+ const char *regtype, const char *domain )
347
+ {
348
+ volatile VALUE self = rb_obj_alloc(cDNSSDRegisterReply);
349
+ rb_ivar_set(self, dnssd_iv_flags, dnssd_flags_new(flags));
350
+ rb_ivar_set(self, dnssd_iv_service, service);
351
+ dnssd_add_names(self, name, regtype, domain);
352
+ return self;
353
+ }
354
+
355
+ /*
356
+ * call-seq:
357
+ * browse_reply.inspect => string
358
+ *
359
+ */
360
+
361
+ static VALUE
362
+ dnssd_browse_inspect(VALUE self)
363
+ {
364
+ volatile VALUE data = rb_str_buf_new(0);
365
+ rb_str_buf_append(data, dnssd_get_fullname(self, 0));
366
+ rb_str_buf_cat2(data, " interface:");
367
+ rb_str_buf_append(data, dnssd_get_interface(self));
368
+ return dnssd_struct_inspect(self, data);
369
+ }
370
+
371
+ VALUE
372
+ dnssd_browse_new(VALUE service, DNSServiceFlags flags, uint32_t interface,
373
+ const char *name, const char *regtype, const char *domain)
374
+ {
375
+ volatile VALUE self = rb_obj_alloc(cDNSSDBrowseReply);
376
+ rb_ivar_set(self, dnssd_iv_flags, dnssd_flags_new(flags));
377
+ rb_ivar_set(self, dnssd_iv_interface, dnssd_interface_name(interface));
378
+ rb_ivar_set(self, dnssd_iv_service, service);
379
+ dnssd_add_names(self, name, regtype, domain);
380
+ return self;
381
+ }
382
+
383
+ /*
384
+ * call-seq:
385
+ * resolve_reply.inspect => string
386
+ *
387
+ */
388
+
389
+ static VALUE
390
+ dnssd_resolve_inspect(VALUE self)
391
+ {
392
+ volatile VALUE data = rb_str_buf_new(0);
393
+ rb_str_buf_append(data, rb_ivar_get(self, dnssd_iv_fullname));
394
+ rb_str_buf_cat2(data, " interface:");
395
+ rb_str_buf_append(data, dnssd_get_interface(self));
396
+ rb_str_buf_cat2(data, " target:");
397
+ rb_str_buf_append(data, rb_ivar_get(self, dnssd_iv_target));
398
+ rb_str_buf_cat2(data, ":");
399
+ rb_str_buf_append(data, rb_inspect(rb_ivar_get(self, dnssd_iv_port)));
400
+ rb_str_buf_cat2(data, " ");
401
+ rb_str_buf_append(data, rb_inspect(rb_ivar_get(self, dnssd_iv_text_record)));
402
+ return dnssd_struct_inspect(self, data);
403
+ }
404
+
405
+ VALUE
406
+ dnssd_resolve_new(VALUE service, DNSServiceFlags flags, uint32_t interface,
407
+ const char *fullname, const char *host_target,
408
+ uint16_t opaqueport, uint16_t txt_len, const char *txt_rec)
409
+ {
410
+ uint16_t port = ntohs(opaqueport);
411
+ volatile VALUE self = rb_obj_alloc(cDNSSDResolveReply);
412
+ rb_ivar_set(self, dnssd_iv_flags, dnssd_flags_new(flags));
413
+ rb_ivar_set(self, dnssd_iv_interface, dnssd_interface_name(interface));
414
+ rb_ivar_set(self, dnssd_iv_fullname, rb_str_new2(fullname));
415
+ rb_ivar_set(self, dnssd_iv_target, rb_str_new2(host_target));
416
+ rb_ivar_set(self, dnssd_iv_port, UINT2NUM(port));
417
+ rb_ivar_set(self, dnssd_iv_text_record, dnssd_tr_new((long)txt_len, txt_rec));
418
+ rb_ivar_set(self, dnssd_iv_service, service);
419
+ return self;
420
+ }
421
+
422
+ /*
423
+ * call-seq:
424
+ * DNSSD::Reply.new() => raises a RuntimeError
425
+ *
426
+ */
427
+ static VALUE
428
+ dnssd_reply_initialize(int argc, VALUE *argv, VALUE reply)
429
+ {
430
+ dnssd_instantiation_error(rb_obj_classname(reply));
431
+ return Qnil;
432
+ }
433
+
434
+ void
435
+ Init_DNSSD_Replies(void)
436
+ {
437
+ /* hack so rdoc documents the project correctly */
438
+ #ifdef mDNSSD_RDOC_HACK
439
+ mDNSSD = rb_define_module("DNSSD");
440
+ #endif
441
+
442
+ dnssd_iv_flags = rb_intern("@flags");
443
+ dnssd_iv_interface = rb_intern("@interface");
444
+ dnssd_iv_fullname = rb_intern("@fullname");
445
+ dnssd_iv_target = rb_intern("@target");
446
+ dnssd_iv_port = rb_intern("@port");
447
+ dnssd_iv_text_record = rb_intern("@text_record");
448
+ dnssd_iv_name = rb_intern("@name");
449
+ dnssd_iv_type = rb_intern("@type");
450
+ dnssd_iv_domain = rb_intern("@domain");
451
+ dnssd_iv_service = rb_intern("@service");
452
+
453
+ dnssd_init_flag_iv();
454
+
455
+ cDNSSDFlags = rb_define_class_under(mDNSSD, "Flags", rb_cObject);
456
+ rb_define_method(cDNSSDFlags, "initialize", dnssd_flags_initialize, -1);
457
+ /* this creates all the attr_accessor and flag? methods */
458
+ dnssd_init_flags_methods(cDNSSDFlags);
459
+ rb_define_method(cDNSSDFlags, "inspect", dnssd_flags_inspect, 0);
460
+ rb_define_method(cDNSSDFlags, "to_i", dnssd_flags_to_i, 0);
461
+ rb_define_method(cDNSSDFlags, "==", dnssd_flags_equal, 1);
462
+
463
+ /* prototype: rb_define_attr(class, name, read, write) */
464
+ cDNSSDReply = rb_define_class_under(mDNSSD, "Reply", rb_cObject);
465
+ /* DNSSD::Reply objects can only be instantiated by DNSSD.browse(), DNSSD.register(), DNSSD.resolve(). */
466
+ rb_define_method(cDNSSDReply, "initialize", dnssd_reply_initialize, -1);
467
+ /* Flags describing the reply. See DNSSD::Flags for more information. */
468
+ rb_define_attr(cDNSSDReply, "flags", 1, 0);
469
+ /* The service associated with the reply. See DNSSD::Service for more information. */
470
+ rb_define_attr(cDNSSDReply, "service", 1, 0);
471
+ rb_define_method(cDNSSDReply, "fullname", dnssd_reply_fullname, 0);
472
+
473
+ cDNSSDBrowseReply = rb_define_class_under(mDNSSD, "BrowseReply", cDNSSDReply);
474
+ /* The interface on which the service is advertised.
475
+ * The interface should be passed to DNSSD.resolve() when resolving the service. */
476
+ rb_define_attr(cDNSSDBrowseReply, "interface", 1, 0);
477
+ /* The service name discovered. */
478
+ rb_define_attr(cDNSSDBrowseReply, "name", 1, 0);
479
+ /* The service type, as passed in to DNSSD.browse(). */
480
+ rb_define_attr(cDNSSDBrowseReply, "type", 1, 0);
481
+ /* The domain on which the service was discovered.
482
+ * (If the application did not specify a domain in DNSSD.browse(),
483
+ * this indicates the domain on which the service was discovered.) */
484
+ rb_define_attr(cDNSSDBrowseReply, "domain", 1, 0);
485
+ rb_define_method(cDNSSDBrowseReply, "inspect", dnssd_browse_inspect, 0);
486
+
487
+ cDNSSDResolveReply = rb_define_class_under(mDNSSD, "ResolveReply", cDNSSDReply);
488
+ /* The interface on which the service was resolved. */
489
+ rb_define_attr(cDNSSDResolveReply, "interface", 1, 0);
490
+ /* The full service domain name, in the form "<servicename>.<protocol>.<domain>.".
491
+ * (Any literal dots (".") are escaped with a backslash ("\."), and literal
492
+ * backslashes are escaped with a second backslash ("\\"), e.g. a web server
493
+ * named "Dr. Pepper" would have the fullname "Dr\.\032Pepper._http._tcp.local.".)
494
+ * See DNSSD::Service.fullname() for more information. */
495
+ rb_define_attr(cDNSSDResolveReply, "fullname", 1, 0);
496
+ /* The target hostname of the machine providing the service.
497
+ * This name can be passed to functions like Socket.gethostbyname()
498
+ * to identify the host's IP address. */
499
+ rb_define_attr(cDNSSDResolveReply, "target", 1, 0);
500
+ /* The port on which connections are accepted for this service. */
501
+ rb_define_attr(cDNSSDResolveReply, "port", 1, 0);
502
+ /* The service's primary text record, see DNSSD::TextRecord for more information. */
503
+ rb_define_attr(cDNSSDResolveReply, "text_record", 1, 0);
504
+ rb_define_method(cDNSSDResolveReply, "inspect", dnssd_resolve_inspect, 0);
505
+
506
+ cDNSSDRegisterReply = rb_define_class_under(mDNSSD, "RegisterReply", cDNSSDReply);
507
+ /* The service name registered.
508
+ * (If the application did not specify a name in DNSSD.register(),
509
+ * this indicates what name was automatically chosen.) */
510
+ rb_define_attr(cDNSSDRegisterReply, "name", 1, 0);
511
+ /* The type of service registered as it was passed to DNSSD.register(). */
512
+ rb_define_attr(cDNSSDRegisterReply, "type", 1, 0);
513
+ /* The domain on which the service was registered.
514
+ * (If the application did not specify a domain in DNSSD.register(),
515
+ * this indicates the default domain on which the service was registered.) */
516
+ rb_define_attr(cDNSSDRegisterReply, "domain", 1, 0);
517
+ rb_define_method(cDNSSDRegisterReply, "inspect", dnssd_register_inspect, 0);
518
+
519
+ /* flag constants */
520
+ #if DNSSD_MAX_FLAGS != 9
521
+ #error The code below needs to be updated.
522
+ #endif
523
+ /* MoreComing indicates that at least one more result is queued and will be delivered following immediately after this one.
524
+ * Applications should not update their UI to display browse
525
+ * results when the MoreComing flag is set, because this would
526
+ * result in a great deal of ugly flickering on the screen.
527
+ * Applications should instead wait until until MoreComing is not set,
528
+ * and then update their UI.
529
+ * When MoreComing is not set, that doesn't mean there will be no more
530
+ * answers EVER, just that there are no more answers immediately
531
+ * available right now at this instant. If more answers become available
532
+ * in the future they will be delivered as usual.
533
+ */
534
+ rb_define_const(cDNSSDFlags, "MoreComing", ULONG2NUM(kDNSServiceFlagsMoreComing));
535
+
536
+
537
+ /* Flags for domain enumeration and DNSSD.browse() reply callbacks.
538
+ * DNSSD::Flags::Default applies only to enumeration and is only valid in
539
+ * conjuction with DNSSD::Flags::Add. An enumeration callback with the DNSSD::Flags::Add
540
+ * flag NOT set indicates a DNSSD::Flags::Remove, i.e. the domain is no longer valid.
541
+ */
542
+ rb_define_const(cDNSSDFlags, "Add", ULONG2NUM(kDNSServiceFlagsAdd));
543
+ rb_define_const(cDNSSDFlags, "Default", ULONG2NUM(kDNSServiceFlagsDefault));
544
+
545
+ /* Flag for specifying renaming behavior on name conflict when registering non-shared records.
546
+ * By default, name conflicts are automatically handled by renaming the service.
547
+ * DNSSD::Flags::NoAutoRename overrides this behavior - with this
548
+ * flag set, name conflicts will result in a callback. The NoAutoRename flag
549
+ * is only valid if a name is explicitly specified when registering a service
550
+ * (ie the default name is not used.)
551
+ */
552
+ rb_define_const(cDNSSDFlags, "NoAutoRename", ULONG2NUM(kDNSServiceFlagsNoAutoRename));
553
+
554
+ /* Flag for registering individual records on a connected DNSServiceRef.
555
+ * DNSSD::Flags::Shared indicates that there may be multiple records
556
+ * with this name on the network (e.g. PTR records). DNSSD::Flags::Unique indicates that the
557
+ * record's name is to be unique on the network (e.g. SRV records).
558
+ * (DNSSD::Flags::Shared and DNSSD::Flags::Unique are currently not used by the Ruby API.)
559
+ */
560
+ rb_define_const(cDNSSDFlags, "Shared", ULONG2NUM(kDNSServiceFlagsShared));
561
+ rb_define_const(cDNSSDFlags, "Unique", ULONG2NUM(kDNSServiceFlagsUnique));
562
+
563
+ /* Flags for specifying domain enumeration type in DNSSD.enumerate_domains()
564
+ * (currently not part of the Ruby API).
565
+ * DNSSD::Flags::BrowseDomains enumerates domains recommended for browsing,
566
+ * DNSSD::Flags::RegistrationDomains enumerates domains recommended for registration.
567
+ */
568
+ rb_define_const(cDNSSDFlags, "BrowseDomains", ULONG2NUM(kDNSServiceFlagsBrowseDomains));
569
+ rb_define_const(cDNSSDFlags, "RegistrationDomains", ULONG2NUM(kDNSServiceFlagsRegistrationDomains));
570
+
571
+ /* Flag for creating a long-lived unicast query for the DNSDS.query_record()
572
+ * (currently not part of the Ruby API). */
573
+ rb_define_const(cDNSSDFlags, "LongLivedQuery", ULONG2NUM(kDNSServiceFlagsLongLivedQuery));
574
+ }
575
+
576
+ /* Document-class: DNSSD::Reply
577
+ *
578
+ * DNSSD::Reply is the parent class of DNSSD::BrowseReply, DNSSD::RegisterReply, and DNSSD::ResolveReply.
579
+ * It simply contains the behavior that is common to those classes, otherwise it is not
580
+ * used by the DNSSD Ruby API.
581
+ *
582
+ */
583
+
584
+ /* Document-class: DNSSD::Flags
585
+ *
586
+ * Flags used in DNSSD Ruby API.
587
+ */
588
+