dnssd 0.6.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.
@@ -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
+