]> git.saurik.com Git - apple/libresolv.git/blob - dns_plugin.c
libresolv-41.tar.gz
[apple/libresolv.git] / dns_plugin.c
1 /*
2 * Copyright (c) 2008 Apple, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
11 * file.
12 *
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #include <netdb.h>
28 #include <dns.h>
29 #include <dns_util.h>
30 #include <resolv.h>
31 #include <nameser.h>
32 #include <pthread.h>
33 #include <si_module.h>
34 #include <ils.h>
35 #include <dns_private.h>
36
37 /* from dns_util.c */
38 #define DNS_MAX_RECEIVE_SIZE 65536
39
40 #define MDNS_HANDLE_NAME "*MDNS*"
41
42 #define DNS_HANDLE_BUSY 0x00000001
43 #define MDNS_HANDLE_BUSY 0x00000002
44
45 #define MODULE_DNS 0
46 #define MODULE_MDNS 1
47
48 static pthread_mutex_t dns_plugin_lock = PTHREAD_MUTEX_INITIALIZER;
49
50 typedef struct
51 {
52 struct hostent host;
53 int alias_count;
54 int addr_count;
55 uint64_t ttl;
56 } dns_build_hostent_t;
57
58 typedef struct
59 {
60 dns_handle_t dns;
61 dns_handle_t mdns;
62 uint32_t flags;
63 } dns_plugin_private_t;
64
65 #define DNS_FLAGS_RCODE_MASK 0x000f
66 static const char hexchar[] = "0123456789abcdef";
67
68 static dns_handle_t
69 dns_checkout_handle(si_mod_t *si)
70 {
71 dns_plugin_private_t *pp;
72 dns_handle_t dns;
73
74 if (si == NULL) return NULL;
75
76 pthread_mutex_lock(&dns_plugin_lock);
77 if (si->private == NULL)
78 {
79 pp = (dns_plugin_private_t *)calloc(1, sizeof(dns_plugin_private_t));
80 si->private = pp;
81 }
82
83 dns = NULL;
84 pp = (dns_plugin_private_t *)si->private;
85
86 if (pp == NULL)
87 {
88 /* shouldn't happen */
89 dns = dns_open(NULL);
90 pthread_mutex_unlock(&dns_plugin_lock);
91 return dns;
92 }
93
94 if ((pp->flags & DNS_HANDLE_BUSY) == 0)
95 {
96 if (pp->dns == NULL) pp->dns = dns_open(NULL);
97 pp->flags |= DNS_HANDLE_BUSY;
98 pthread_mutex_unlock(&dns_plugin_lock);
99 return pp->dns;
100 }
101
102 /* main dns handle is busy - create a temporary one */
103 dns = dns_open(NULL);
104 pthread_mutex_unlock(&dns_plugin_lock);
105 return dns;
106 }
107
108 static dns_handle_t
109 mdns_checkout_handle(si_mod_t *si)
110 {
111 dns_plugin_private_t *pp;
112 dns_handle_t dns;
113
114 if (si == NULL) return NULL;
115
116 pthread_mutex_lock(&dns_plugin_lock);
117 if (si->private == NULL)
118 {
119 pp = (dns_plugin_private_t *)calloc(1, sizeof(dns_plugin_private_t));
120 si->private = pp;
121 }
122
123 dns = NULL;
124 pp = (dns_plugin_private_t *)si->private;
125
126 if (pp == NULL)
127 {
128 /* shouldn't happen */
129 dns = dns_open(MDNS_HANDLE_NAME);
130 pthread_mutex_unlock(&dns_plugin_lock);
131 return dns;
132 }
133
134 if ((pp->flags & MDNS_HANDLE_BUSY) == 0)
135 {
136 if (pp->mdns == NULL) pp->mdns = dns_open(MDNS_HANDLE_NAME);
137 pp->flags |= MDNS_HANDLE_BUSY;
138 pthread_mutex_unlock(&dns_plugin_lock);
139 return pp->mdns;
140 }
141
142 /* main mdns handle is busy - create a temporary one */
143 dns = dns_open(MDNS_HANDLE_NAME);
144 pthread_mutex_unlock(&dns_plugin_lock);
145 return dns;
146 }
147
148 static void
149 dns_checkin_handle(si_mod_t *si, dns_handle_t dns)
150 {
151 dns_plugin_private_t *pp;
152
153 if (si == NULL) return;
154 if (dns == NULL) return;
155
156 pthread_mutex_lock(&dns_plugin_lock);
157 if (si->private == NULL)
158 {
159 /* shouldn't happen */
160 pp = (dns_plugin_private_t *)calloc(1, sizeof(dns_plugin_private_t));
161 si->private = pp;
162 }
163
164 pp = (dns_plugin_private_t *)si->private;
165
166 if (pp == NULL)
167 {
168 /* shouldn't happen */
169 dns_free(dns);
170 pthread_mutex_unlock(&dns_plugin_lock);
171 return;
172 }
173
174 if (pp->dns == dns)
175 {
176 pp->flags &= ~DNS_HANDLE_BUSY;
177 pthread_mutex_unlock(&dns_plugin_lock);
178 return;
179 }
180 else if (pp->mdns == dns)
181 {
182 pp->flags &= ~MDNS_HANDLE_BUSY;
183 pthread_mutex_unlock(&dns_plugin_lock);
184 return;
185 }
186
187 dns_free(dns);
188 pthread_mutex_unlock(&dns_plugin_lock);
189 }
190
191 static char *
192 dns_reverse_ipv4(const char *addr)
193 {
194 union
195 {
196 uint32_t a;
197 unsigned char b[4];
198 } ab;
199 char *p;
200
201 if (addr == NULL) return NULL;
202
203 memcpy(&(ab.a), addr, 4);
204
205 asprintf(&p, "%u.%u.%u.%u.in-addr.arpa.", ab.b[3], ab.b[2], ab.b[1], ab.b[0]);
206 return p;
207 }
208
209 static char *
210 dns_reverse_ipv6(const char *addr)
211 {
212 char x[65], *p;
213 int i, j;
214 u_int8_t d, hi, lo;
215
216 if (addr == NULL) return NULL;
217
218 x[64] = '\0';
219 j = 63;
220 for (i = 0; i < 16; i++)
221 {
222 d = addr[i];
223 lo = d & 0x0f;
224 hi = d >> 4;
225 x[j--] = '.';
226 x[j--] = hexchar[hi];
227 x[j--] = '.';
228 x[j--] = hexchar[lo];
229 }
230
231 p = calloc(1, 75);
232 if (p == NULL) return NULL;
233
234 memmove(p, x, 64);
235 strcat(p, "ip6.arpa.");
236
237 return p;
238 }
239
240 static char *
241 dns_lower_case(const char *s)
242 {
243 int i;
244 char *t;
245
246 if (s == NULL) return NULL;
247 t = malloc(strlen(s) + 1);
248
249 for (i = 0; s[i] != '\0'; i++)
250 {
251 if ((s[i] >= 'A') && (s[i] <= 'Z')) t[i] = s[i] + 32;
252 else t[i] = s[i];
253 }
254 t[i] = '\0';
255 return t;
256 }
257
258 static int
259 dns_host_merge_alias(const char *name, dns_build_hostent_t *h)
260 {
261 int i;
262
263 if (name == NULL) return 0;
264 if (h == NULL) return 0;
265
266 if ((h->host.h_name != NULL) && (!strcmp(name, h->host.h_name))) return 0;
267 for (i = 0; i < h->alias_count; i++) if (!strcmp(name, h->host.h_aliases[i])) return 0;
268
269 h->host.h_aliases = (char **)reallocf(h->host.h_aliases, (h->alias_count + 2) * sizeof(char *));
270 if (h->host.h_aliases == NULL)
271 {
272 h->alias_count = 0;
273 return -1;
274 }
275
276 h->host.h_aliases[h->alias_count] = dns_lower_case(name);
277 h->alias_count++;
278 h->host.h_aliases[h->alias_count] = NULL;
279
280 return 0;
281 }
282
283 static int
284 dns_host_append_addr(const char *addr, uint32_t len, dns_build_hostent_t *h)
285 {
286 if (addr == NULL) return 0;
287 if (h == NULL) return 0;
288
289 if (h->addr_count == 0) h->host.h_addr_list = (char **)calloc(2, sizeof(char *));
290 else h->host.h_addr_list = (char **)reallocf(h->host.h_addr_list, (h->addr_count + 2) * sizeof(char *));
291
292 if (h->host.h_addr_list == NULL)
293 {
294 h->addr_count = 0;
295 return -1;
296 }
297
298 h->host.h_addr_list[h->addr_count] = malloc(len);
299 if (h->host.h_addr_list[h->addr_count] == NULL) return -1;
300
301 memcpy(h->host.h_addr_list[h->addr_count], addr, len);
302 h->addr_count++;
303 h->host.h_addr_list[h->addr_count] = NULL;
304
305 return 0;
306 }
307
308 static void
309 dns_plugin_clear_host(dns_build_hostent_t *h)
310 {
311 uint32_t i;
312 char **aliases;
313
314 if (h == NULL) return;
315
316 if (h->host.h_name != NULL) free(h->host.h_name);
317 h->host.h_name = NULL;
318
319 aliases = h->host.h_aliases;
320 if (aliases != NULL)
321 {
322 while (*aliases != NULL) free(*aliases++);
323 free(h->host.h_aliases);
324 }
325
326 h->host.h_aliases = NULL;
327
328 if (h->host.h_addr_list != NULL)
329 {
330 for (i = 0; h->host.h_addr_list[i] != NULL; i++) free(h->host.h_addr_list[i]);
331 free(h->host.h_addr_list);
332 }
333
334 h->host.h_addr_list = NULL;
335 }
336
337 static int
338 dns_reply_to_hostent(dns_reply_t *r, int af, const char *addr, dns_build_hostent_t *h)
339 {
340 int i, got_data, got_addr;
341 int ptrx, cnamex;
342
343 if (r == NULL) return -1;
344 if (r->status != DNS_STATUS_OK) return -1;
345 if ((r->header->flags & DNS_FLAGS_RCODE_MASK) != ns_r_noerror) return -1;
346
347 if (r == NULL) return -1;
348 if (r->header == NULL) return -1;
349 if (r->header->ancount == 0) return -1;
350
351 got_data = 0;
352 got_addr = 0;
353 ptrx = -1;
354 cnamex = -1;
355
356 for (i = 0; i < r->header->ancount; i++)
357 {
358 if ((af == AF_INET) && (r->answer[i]->dnstype == ns_t_a))
359 {
360 got_data++;
361 got_addr++;
362 dns_host_append_addr((const char *)&(r->answer[i]->data.A->addr), 4, h);
363 if (h->ttl == 0) h->ttl = r->answer[i]->ttl;
364 else if (r->answer[i]->ttl < h->ttl) h->ttl = r->answer[i]->ttl;
365 }
366
367 else if ((af == AF_INET6) && (r->answer[i]->dnstype == ns_t_aaaa))
368 {
369 got_data++;
370 got_addr++;
371 dns_host_append_addr((const char *)&(r->answer[i]->data.AAAA->addr), 16, h);
372 if (h->ttl == 0) h->ttl = r->answer[i]->ttl;
373 else if (r->answer[i]->ttl < h->ttl) h->ttl = r->answer[i]->ttl;
374 }
375
376 else if (r->answer[i]->dnstype == ns_t_cname)
377 {
378 got_data++;
379 if (cnamex == -1) cnamex = i;
380 if (h->ttl == 0) h->ttl = r->answer[i]->ttl;
381 else if (r->answer[i]->ttl < h->ttl) h->ttl = r->answer[i]->ttl;
382 }
383
384 else if (r->answer[i]->dnstype == ns_t_ptr)
385 {
386 got_data++;
387 if (ptrx == -1) ptrx = i;
388 if (h->ttl == 0) h->ttl = r->answer[i]->ttl;
389 else if (r->answer[i]->ttl < h->ttl) h->ttl = r->answer[i]->ttl;
390 }
391 }
392
393 if (addr != NULL)
394 {
395 if (af == AF_INET)
396 {
397 got_addr++;
398 dns_host_append_addr(addr, 4, h);
399 }
400 else if (af == AF_INET6)
401 {
402 got_addr++;
403 dns_host_append_addr(addr, 16, h);
404 }
405 }
406
407 if (got_data == 0) return -1;
408 if (got_addr == 0) return -1;
409
410 h->host.h_addrtype = af;
411 if (af == AF_INET) h->host.h_length = 4;
412 else h->host.h_length = 16;
413
414 if (ptrx != -1)
415 {
416 /* use name from PTR record */
417 h->host.h_name = dns_lower_case(r->answer[ptrx]->data.PTR->name);
418 }
419 else if (cnamex != -1)
420 {
421 /* use name from CNAME record */
422 h->host.h_name = dns_lower_case(r->answer[cnamex]->data.CNAME->name);
423 }
424 else
425 {
426 /* use name in first answer */
427 h->host.h_name = dns_lower_case(r->answer[0]->name);
428 }
429
430 for (i = 0; i < r->header->ancount; i++)
431 {
432 if (r->answer[i]->dnstype == ns_t_cname)
433 {
434 dns_host_merge_alias(r->answer[cnamex]->data.CNAME->name, h);
435 dns_host_merge_alias(r->answer[cnamex]->name, h);
436 }
437 }
438
439 if (h->alias_count == 0) h->host.h_aliases = (char **)calloc(1, sizeof(char *));
440
441 return 0;
442 }
443
444 static si_item_t *
445 _internal_host_byname(si_mod_t *si, const char *name, int af, const char *ignored, uint32_t *err, int which)
446 {
447 uint32_t type;
448 dns_reply_t *r;
449 dns_build_hostent_t h;
450 si_item_t *out;
451 dns_handle_t dns;
452 uint64_t bb;
453 int status;
454
455 if (err != NULL) *err = SI_STATUS_NO_ERROR;
456
457 if (name == NULL)
458 {
459 if (err != NULL) *err = SI_STATUS_H_ERRNO_NO_RECOVERY;
460 return NULL;
461 }
462
463 if (af == AF_INET) type = ns_t_a;
464 else if (af == AF_INET6) type = ns_t_aaaa;
465 else
466 {
467 if (err != NULL) *err = SI_STATUS_H_ERRNO_NO_RECOVERY;
468 return NULL;
469 }
470
471 r = NULL;
472 dns = NULL;
473
474 if (which == MODULE_DNS) dns = dns_checkout_handle(si);
475 else if (which == MODULE_MDNS) dns = mdns_checkout_handle(si);
476
477 if (dns == NULL)
478 {
479 if (err != NULL) *err = SI_STATUS_H_ERRNO_NO_RECOVERY;
480 return NULL;
481 }
482
483 r = dns_lookup(dns, name, ns_c_in, type);
484 dns_checkin_handle(si, dns);
485
486 if (r == NULL)
487 {
488 if (err != NULL) *err = SI_STATUS_H_ERRNO_HOST_NOT_FOUND;
489 return NULL;
490 }
491
492 memset(&h, 0, sizeof(dns_build_hostent_t));
493
494 status = dns_reply_to_hostent(r, af, NULL, &h);
495 dns_free_reply(r);
496
497 if (status < 0)
498 {
499 dns_plugin_clear_host(&h);
500 if (err != NULL) *err = SI_STATUS_H_ERRNO_NO_RECOVERY;
501 return NULL;
502 }
503
504 bb = h.ttl + time(NULL);
505
506 if (af == AF_INET)
507 {
508 out = (si_item_t *)LI_ils_create("L4488s*44a", (unsigned long)si, CATEGORY_HOST_IPV4, 1, bb, 0LL, h.host.h_name, h.host.h_aliases, af, h.host.h_length, h.host.h_addr_list);
509 }
510 else
511 {
512 out = (si_item_t *)LI_ils_create("L4488s*44c", (unsigned long)si, CATEGORY_HOST_IPV6, 1, bb, 0LL, h.host.h_name, h.host.h_aliases, af, h.host.h_length, h.host.h_addr_list);
513 }
514
515 dns_plugin_clear_host(&h);
516
517 if ((out == NULL) && (err != NULL)) *err = SI_STATUS_H_ERRNO_NO_RECOVERY;
518
519 return out;
520 }
521
522 si_item_t *
523 dns_host_byname(si_mod_t *si, const char *name, int af, const char *ignored, uint32_t *err)
524 {
525 return _internal_host_byname(si, name, af, NULL, err, MODULE_DNS);
526 }
527
528 si_item_t *
529 mdns_host_byname(si_mod_t *si, const char *name, int af, const char *ignored, uint32_t *err)
530 {
531 return _internal_host_byname(si, name, af, NULL, err, MODULE_MDNS);
532 }
533
534 static si_item_t *
535 _internal_host_byaddr(si_mod_t *si, const void *addr, int af, const char *ignored, uint32_t *err, int which)
536 {
537 uint32_t type;
538 dns_reply_t *r;
539 dns_build_hostent_t h;
540 char *name;
541 si_item_t *out;
542 dns_handle_t dns;
543 socklen_t len;
544 uint64_t bb;
545 int cat;
546 struct sockaddr_storage from;
547 uint32_t fromlen;
548
549 if (err != NULL) *err = SI_STATUS_NO_ERROR;
550
551 if (addr == NULL)
552 {
553 if (err != NULL) *err = SI_STATUS_H_ERRNO_NO_RECOVERY;
554 return NULL;
555 }
556
557 if (si == NULL)
558 {
559 if (err != NULL) *err = SI_STATUS_H_ERRNO_NO_RECOVERY;
560 return NULL;
561 }
562
563 fromlen = sizeof(struct sockaddr_storage);
564 memset(&from, 0, fromlen);
565
566 name = NULL;
567 type = ns_t_ptr;
568
569 len = 0;
570 cat = -1;
571
572 if (af == AF_INET)
573 {
574 len = 4;
575 name = dns_reverse_ipv4(addr);
576 cat = CATEGORY_HOST_IPV4;
577 }
578 else if (af == AF_INET6)
579 {
580 len = 16;
581 name = dns_reverse_ipv6(addr);
582 cat = CATEGORY_HOST_IPV6;
583 }
584 else
585 {
586 if (err != NULL) *err = SI_STATUS_H_ERRNO_NO_RECOVERY;
587 return NULL;
588 }
589
590 r = NULL;
591 dns = NULL;
592
593 if (which == MODULE_DNS) dns = dns_checkout_handle(si);
594 else if (which == MODULE_MDNS) dns = mdns_checkout_handle(si);
595
596 if (dns == NULL)
597 {
598 if (err != NULL) *err = SI_STATUS_H_ERRNO_NO_RECOVERY;
599 return NULL;
600 }
601
602 r = dns_lookup(dns, name, ns_c_in, type);
603 dns_checkin_handle(si, dns);
604
605 free(name);
606 if (r == NULL)
607 {
608 if (err != NULL) *err = SI_STATUS_H_ERRNO_HOST_NOT_FOUND;
609 return NULL;
610 }
611
612 memset(&h, 0, sizeof(dns_build_hostent_t));
613
614 if (dns_reply_to_hostent(r, af, addr, &h) < 0)
615 {
616 dns_plugin_clear_host(&h);
617 if (err != NULL) *err = SI_STATUS_H_ERRNO_NO_RECOVERY;
618 return NULL;
619 }
620
621 bb = h.ttl + time(NULL);
622 out = (si_item_t *)LI_ils_create("L4488s*44a", (unsigned long)si, cat, 1, bb, 0LL, h.host.h_name, h.host.h_aliases, af, h.host.h_length, h.host.h_addr_list);
623
624 dns_plugin_clear_host(&h);
625
626 if ((out == NULL) && (err != NULL)) *err = SI_STATUS_H_ERRNO_NO_RECOVERY;
627
628 return out;
629 }
630
631 si_item_t *
632 dns_host_byaddr(si_mod_t *si, const void *addr, int af, const char *ignored, uint32_t *err)
633 {
634 return _internal_host_byaddr(si, addr, af, NULL, err, MODULE_DNS);
635 }
636
637 si_item_t *
638 mdns_host_byaddr(si_mod_t *si, const void *addr, int af, const char *ignored, uint32_t *err)
639 {
640 return _internal_host_byaddr(si, addr, af, NULL, err, MODULE_MDNS);
641 }
642
643 /*
644 * We support dns_async_start / cancel / handle_reply using dns_item_call
645 */
646 static si_item_t *
647 _internal_item_call(si_mod_t *si, int call, const char *name, const char *ignored1, const char *ignored2, uint32_t class, uint32_t type, uint32_t *err, int which)
648 {
649 dns_handle_t dns;
650 char buf[DNS_MAX_RECEIVE_SIZE];
651 int len;
652 struct sockaddr_storage from;
653 uint32_t fromlen;
654 si_item_t *out;
655
656 if (err != NULL) *err = SI_STATUS_NO_ERROR;
657 if ((call != SI_CALL_DNS_QUERY) && (call != SI_CALL_DNS_SEARCH))
658 {
659 if (err != NULL) *err = SI_STATUS_H_ERRNO_NO_RECOVERY;
660 return NULL;
661 }
662
663 if (name == NULL)
664 {
665 if (err != NULL) *err = SI_STATUS_H_ERRNO_NO_RECOVERY;
666 return NULL;
667 }
668
669 dns = NULL;
670
671 if (which == MODULE_DNS) dns = dns_checkout_handle(si);
672 else if (which == MODULE_MDNS) dns = mdns_checkout_handle(si);
673
674 if (dns == NULL)
675 {
676 if (err != NULL) *err = SI_STATUS_H_ERRNO_NO_RECOVERY;
677 return NULL;
678 }
679
680 fromlen = sizeof(struct sockaddr_storage);
681 memset(&from, 0, fromlen);
682
683 len = 0;
684 if (call == SI_CALL_DNS_QUERY) len = dns_query(dns, name, class, type, buf, sizeof(buf), (struct sockaddr *)&from, &fromlen);
685 else if (call == SI_CALL_DNS_SEARCH) len = dns_search(dns, name, class, type, buf, sizeof(buf), (struct sockaddr *)&from, &fromlen);
686
687 dns_checkin_handle(si, dns);
688
689 if ((len <= 0) || (len > DNS_MAX_RECEIVE_SIZE))
690 {
691 if (err != NULL) *err = SI_STATUS_H_ERRNO_HOST_NOT_FOUND;
692 return NULL;
693 }
694
695 out = (si_item_t *)LI_ils_create("L4488@@", (unsigned long)si, CATEGORY_DNSPACKET, 1, 0LL, 0LL, len, buf, fromlen, &from);
696 if ((out == NULL) && (err != NULL)) *err = SI_STATUS_H_ERRNO_NO_RECOVERY;
697
698 return out;
699 }
700
701 si_item_t *
702 dns_item_call(si_mod_t *si, int call, const char *name, const char *ignored1, const char *ignored2, uint32_t class, uint32_t type, uint32_t *err)
703 {
704 return _internal_item_call(si, call, name, ignored1, ignored2, class, type, err, MODULE_DNS);
705 }
706
707 si_item_t *
708 mdns_item_call(si_mod_t *si, int call, const char *name, const char *ignored1, const char *ignored2, uint32_t class, uint32_t type, uint32_t *err)
709 {
710 return _internal_item_call(si, call, name, ignored1, ignored2, class, type, err, MODULE_MDNS);
711 }
712
713 int
714 dns_is_valid(si_mod_t *si, si_item_t *item)
715 {
716 uint64_t now;
717 si_mod_t *src;
718
719 if (si == NULL) return 0;
720 if (item == NULL) return 0;
721 if (si->name == NULL) return 0;
722 if (item->src == NULL) return 0;
723
724 src = (si_mod_t *)item->src;
725
726 if (src->name == NULL) return 0;
727 if (string_not_equal(si->name, src->name)) return 0;
728
729 now = time(NULL);
730 if (item->validation_a < now) return 0;
731 return 1;
732 }
733
734 int
735 mdns_is_valid(si_mod_t *si, si_item_t *item)
736 {
737 return 0;
738 }
739
740 void
741 dns_close(si_mod_t *si)
742 {
743 dns_plugin_private_t *pp;
744
745 if (si == NULL) return;
746
747 pp = (dns_plugin_private_t *)si->private;
748 if (pp == NULL) return;
749
750 if (pp->dns != NULL) dns_free(pp->dns);
751 free(si->private);
752 }
753
754 int
755 dns_init(si_mod_t *si)
756 {
757 if (si == NULL) return 1;
758
759 si->vers = 1;
760
761 si->sim_close = dns_close;
762 si->sim_is_valid = dns_is_valid;
763 si->sim_host_byname = dns_host_byname;
764 si->sim_host_byaddr = dns_host_byaddr;
765 si->sim_item_call = dns_item_call;
766
767 return 0;
768 }
769
770 void
771 mdns_close(si_mod_t *si)
772 {
773 dns_close(si);
774 }
775
776 int
777 mdns_init(si_mod_t *si)
778 {
779 if (si == NULL) return 1;
780
781 si->vers = 1;
782
783 si->sim_close = dns_close;
784 si->sim_is_valid = mdns_is_valid;
785 si->sim_host_byname = mdns_host_byname;
786 si->sim_host_byaddr = mdns_host_byaddr;
787 si->sim_item_call = mdns_item_call;
788
789 return 0;
790 }