2 * Copyright (c) 1999-2007 Apple Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
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
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.
21 * @APPLE_LICENSE_HEADER_END@
34 #include <sys/types.h>
35 #include <sys/socket.h>
39 #include <netinet/in.h>
40 #include <arpa/nameser.h>
44 #include "dns_private.h"
45 #include "res_private.h"
47 #define DNS_RESOLVER_DIR "/etc/resolver"
49 #define DNS_PRIVATE_HANDLE_TYPE_SUPER 0
50 #define DNS_PRIVATE_HANDLE_TYPE_PLAIN 1
51 #define DNS_DEFAULT_RECEIVE_SIZE 8192
52 #define DNS_MAX_RECEIVE_SIZE 65536
54 #define SDNS_DEFAULT_STAT_LATENCY 10
56 #define DNS_FLAGS_QR_MASK 0x8000
57 #define DNS_FLAGS_QR_QUERY 0x0000
59 #define DNS_FLAGS_OPCODE_MASK 0x7800
61 #define DNS_FLAGS_RCODE_MASK 0x000f
63 #define DNS_FLAGS_AA 0x0400
64 #define DNS_FLAGS_TC 0x0200
65 #define DNS_FLAGS_RD 0x0100
66 #define DNS_FLAGS_RA 0x0080
68 #define DNS_SOCK_UDP 0
69 #define DNS_SOCK_TCP_UNCONNECTED 1
70 #define DNS_SOCK_TCP_CONNECTED 2
72 #define INET_NTOP_AF_INET_OFFSET 4
73 #define INET_NTOP_AF_INET6_OFFSET 8
75 #define MAXPACKET 1024
77 extern void res_client_close(res_state res
);
78 extern int __res_nquery(res_state statp
, const char *name
, int class, int type
, u_char
*answer
, int anslen
);
79 extern int dns_res_send(res_state statp
, const u_char
*buf
, int buflen
, u_char
*ans
, int *anssiz
, struct sockaddr
*from
, int *fromlen
);
80 extern void _check_cache(sdns_handle_t
*sdns
);
81 extern int _sdns_search(sdns_handle_t
*sdns
, const char *name
, uint32_t class, uint32_t type
, uint32_t fqdn
, uint32_t recurse
, char *buf
, uint32_t len
, struct sockaddr
*from
, uint32_t *fromlen
, int *min
);
82 extern int _pdns_search(sdns_handle_t
*sdns
, pdns_handle_t
*pdns
, const char *name
, uint32_t class, uint32_t type
, char *buf
, uint32_t len
, struct sockaddr
*from
, uint32_t *fromlen
);
83 static pthread_mutex_t _dnsPrintLock
= PTHREAD_MUTEX_INITIALIZER
;
88 pthread_mutex_lock(&_dnsPrintLock
);
92 _dns_print_unlock(void)
94 pthread_mutex_unlock(&_dnsPrintLock
);
99 _dns_parse_uint8(char **p
)
109 _dns_parse_uint16(char **p
)
120 _dns_parse_uint32(char **p
)
131 _dns_cname_length(char *s
)
135 if (s
== NULL
) return 1;
137 while ((s
[l
- 1] == '.') && (l
> 1)) l
--;
142 _dns_insert_cname(char *s
, char *p
)
161 len
= _dns_cname_length(s
);
164 memmove(p
+ 1, s
, len
);
169 for (i
= len
+ 1; i
>= 0; i
--)
181 _dns_parse_string(const char *p
, char **x
, int32_t *remaining
)
186 if (*remaining
< 1) return NULL
;
192 if (*remaining
< len
) return NULL
;
195 str
= malloc(len
+ 1);
196 memmove(str
, *x
, len
);
204 _dns_parse_domain_name(const char *p
, char **x
, int32_t *remaining
)
208 uint16_t i
, j
, dlen
, len
;
209 int more
, compressed
;
210 char *name
, *start
, *y
, *z
;
212 if (*remaining
< 1) return NULL
;
235 if ((dlen
& 0xc0) == 0xc0)
243 v16
= (uint16_t *)*x
;
245 y
= (char *)p
+ (ntohs(*v16
) & 0x3fff);
246 if ((*x
== y
) || (y
> z
))
253 if (compressed
== 0) skip
+= 2;
269 name
= realloc(name
, len
);
278 for (i
= 0; i
< dlen
; i
++)
285 if (compressed
== 0) skip
+= (dlen
+ 1);
287 if (dlen
== 0) more
= 0;
300 name
= realloc(name
, len
);
307 if ((start
+ skip
) > z
)
319 dns_resource_record_t
*
320 _dns_parse_resource_record_internal(const char *p
, char **x
, int32_t *remaining
)
322 uint32_t size
, bx
, mi
;
325 dns_resource_record_t
*r
;
328 if (*remaining
< 1) return NULL
;
330 r
= (dns_resource_record_t
*)calloc(1, sizeof(dns_resource_record_t
));
332 r
->name
= _dns_parse_domain_name(p
, x
, remaining
);
345 r
->dnstype
= _dns_parse_uint16(x
);
346 r
->dnsclass
= _dns_parse_uint16(x
);
347 r
->ttl
= _dns_parse_uint32(x
);
348 rdlen
= _dns_parse_uint16(x
);
366 size
= sizeof(dns_address_record_t
);
367 r
->data
.A
= (dns_address_record_t
*)calloc(1, size
);
368 r
->data
.A
->addr
.s_addr
= htonl(_dns_parse_uint32(x
));
380 size
= sizeof(dns_in6_address_record_t
);
381 r
->data
.AAAA
= (dns_in6_address_record_t
*)calloc(1, size
);
382 r
->data
.AAAA
->addr
.__u6_addr
.__u6_addr32
[0] = htonl(_dns_parse_uint32(x
));
383 r
->data
.AAAA
->addr
.__u6_addr
.__u6_addr32
[1] = htonl(_dns_parse_uint32(x
));
384 r
->data
.AAAA
->addr
.__u6_addr
.__u6_addr32
[2] = htonl(_dns_parse_uint32(x
));
385 r
->data
.AAAA
->addr
.__u6_addr
.__u6_addr32
[3] = htonl(_dns_parse_uint32(x
));
396 size
= sizeof(dns_domain_name_record_t
);
397 r
->data
.CNAME
= (dns_domain_name_record_t
*)calloc(1,size
);
398 r
->data
.CNAME
->name
= _dns_parse_domain_name(p
, x
, remaining
);
399 if (r
->data
.CNAME
->name
== NULL
)
408 size
= sizeof(dns_SOA_record_t
);
409 r
->data
.SOA
= (dns_SOA_record_t
*)calloc(1, size
);
411 r
->data
.SOA
->mname
= _dns_parse_domain_name(p
, x
, remaining
);
412 if (r
->data
.SOA
->mname
== NULL
)
419 r
->data
.SOA
->rname
= _dns_parse_domain_name(p
, x
, remaining
);
420 if (r
->data
.SOA
->rname
== NULL
)
422 free(r
->data
.SOA
->mname
);
430 free(r
->data
.SOA
->mname
);
431 free(r
->data
.SOA
->rname
);
439 r
->data
.SOA
->serial
= _dns_parse_uint32(x
);
440 r
->data
.SOA
->refresh
= _dns_parse_uint32(x
);
441 r
->data
.SOA
->retry
= _dns_parse_uint32(x
);
442 r
->data
.SOA
->expire
= _dns_parse_uint32(x
);
443 r
->data
.SOA
->minimum
= _dns_parse_uint32(x
);
455 size
= sizeof(dns_WKS_record_t
);
456 r
->data
.WKS
= (dns_WKS_record_t
*)calloc(1, size
);
458 r
->data
.WKS
->addr
.s_addr
= htonl(_dns_parse_uint32(x
));
459 r
->data
.WKS
->protocol
= _dns_parse_uint8(x
);
461 r
->data
.WKS
->maplength
= size
* 8;
462 r
->data
.WKS
->map
= NULL
;
463 if (size
== 0) break;
465 r
->data
.WKS
->map
= (uint8_t *)calloc(1, r
->data
.WKS
->maplength
);
467 for (bx
= 0; bx
< size
; bx
++)
469 byte
= _dns_parse_uint8(x
);
470 for (i
= 128; i
>= 1; i
= i
/2)
472 if (byte
& i
) r
->data
.WKS
->map
[mi
] = 0xff;
473 else r
->data
.WKS
->map
[mi
] = 0;
480 size
= sizeof(dns_HINFO_record_t
);
481 r
->data
.HINFO
= (dns_HINFO_record_t
*)calloc(1, size
);
483 r
->data
.HINFO
->cpu
= _dns_parse_string(p
, x
, remaining
);
484 if (r
->data
.HINFO
->cpu
== NULL
)
491 r
->data
.HINFO
->os
= _dns_parse_string(p
, x
, remaining
);
492 if (r
->data
.HINFO
->os
== NULL
)
494 free(r
->data
.HINFO
->cpu
);
503 size
= sizeof(dns_MINFO_record_t
);
504 r
->data
.MINFO
= (dns_MINFO_record_t
*)calloc(1, size
);
506 r
->data
.MINFO
->rmailbx
= _dns_parse_domain_name(p
, x
, remaining
);
507 if (r
->data
.MINFO
->rmailbx
== NULL
)
514 r
->data
.MINFO
->emailbx
= _dns_parse_domain_name(p
, x
, remaining
);
515 if (r
->data
.MINFO
->emailbx
== NULL
)
517 free(r
->data
.MINFO
->rmailbx
);
534 size
= sizeof(dns_MX_record_t
);
535 r
->data
.MX
= (dns_MX_record_t
*)calloc(1, size
);
537 r
->data
.MX
->preference
= _dns_parse_uint16(x
);
538 r
->data
.MX
->name
= _dns_parse_domain_name(p
, x
, remaining
);
539 if (r
->data
.MX
->name
== NULL
)
549 size
= sizeof(dns_TXT_record_t
);
550 r
->data
.TXT
= (dns_TXT_record_t
*)malloc(size
);
551 r
->data
.TXT
->string_count
= 0;
552 r
->data
.TXT
->strings
= NULL
;
554 while (*x
< (eor
+ rdlen
))
556 if (r
->data
.TXT
->string_count
== 0)
558 r
->data
.TXT
->strings
= (char **)calloc(1, sizeof(char *));
562 r
->data
.TXT
->strings
= (char **)realloc(r
->data
.TXT
->strings
, (r
->data
.TXT
->string_count
+ 1) * sizeof(char *));
565 r
->data
.TXT
->strings
[r
->data
.TXT
->string_count
] = _dns_parse_string(p
, x
, remaining
);
566 if (r
->data
.TXT
->strings
[r
->data
.TXT
->string_count
] == NULL
)
568 free(r
->data
.TXT
->strings
);
573 r
->data
.TXT
->string_count
++;
579 size
= sizeof(dns_RP_record_t
);
580 r
->data
.RP
= (dns_RP_record_t
*)calloc(1, size
);
582 r
->data
.RP
->mailbox
= _dns_parse_domain_name(p
, x
, remaining
);
583 if (r
->data
.RP
->mailbox
== NULL
)
590 r
->data
.RP
->txtdname
= _dns_parse_domain_name(p
, x
, remaining
);
591 if (r
->data
.RP
->txtdname
== NULL
)
593 free(r
->data
.RP
->mailbox
);
609 size
= sizeof(dns_AFSDB_record_t
);
610 r
->data
.AFSDB
= (dns_AFSDB_record_t
*)calloc(1, size
);
612 r
->data
.AFSDB
->subtype
= _dns_parse_uint32(x
);
613 r
->data
.AFSDB
->hostname
= _dns_parse_domain_name(p
, x
, remaining
);
614 if (r
->data
.AFSDB
->hostname
== NULL
)
624 size
= sizeof(dns_X25_record_t
);
625 r
->data
.X25
= (dns_X25_record_t
*)calloc(1, size
);
627 r
->data
.X25
->psdn_address
= _dns_parse_string(p
, x
, remaining
);
628 if (r
->data
.X25
->psdn_address
== NULL
)
638 size
= sizeof(dns_ISDN_record_t
);
639 r
->data
.ISDN
= (dns_ISDN_record_t
*)calloc(1, size
);
641 r
->data
.ISDN
->isdn_address
= _dns_parse_string(p
, x
, remaining
);
642 if (r
->data
.ISDN
->isdn_address
== NULL
)
649 if (*x
< (eor
+ rdlen
))
651 r
->data
.ISDN
->subaddress
= _dns_parse_string(p
, x
, remaining
);
652 if (r
->data
.ISDN
->subaddress
== NULL
)
654 free(r
->data
.ISDN
->isdn_address
);
662 r
->data
.ISDN
->subaddress
= NULL
;
676 size
= sizeof(dns_RT_record_t
);
677 r
->data
.RT
= (dns_RT_record_t
*)calloc(1, size
);
679 r
->data
.RT
->preference
= _dns_parse_uint16(x
);
680 r
->data
.RT
->intermediate
= _dns_parse_domain_name(p
, x
, remaining
);
681 if (r
->data
.RT
->intermediate
== NULL
)
699 size
= sizeof(dns_LOC_record_t
);
700 r
->data
.LOC
= (dns_LOC_record_t
*)calloc(1, size
);
702 r
->data
.LOC
->version
= _dns_parse_uint8(x
);
703 r
->data
.LOC
->size
= _dns_parse_uint8(x
);
704 r
->data
.LOC
->horizontal_precision
= _dns_parse_uint8(x
);
705 r
->data
.LOC
->vertical_precision
= _dns_parse_uint8(x
);
706 r
->data
.LOC
->latitude
= _dns_parse_uint32(x
);
707 r
->data
.LOC
->longitude
= _dns_parse_uint32(x
);
708 r
->data
.LOC
->altitude
= _dns_parse_uint32(x
);
720 size
= sizeof(dns_SRV_record_t
);
721 r
->data
.SRV
= (dns_SRV_record_t
*)calloc(1, size
);
723 r
->data
.SRV
->priority
= _dns_parse_uint16(x
);
724 r
->data
.SRV
->weight
= _dns_parse_uint16(x
);
725 r
->data
.SRV
->port
= _dns_parse_uint16(x
);
726 r
->data
.SRV
->target
= _dns_parse_domain_name(p
, x
, remaining
);
727 if (r
->data
.SRV
->target
== NULL
)
738 if (*remaining
< rdlen
)
746 size
= sizeof(dns_raw_resource_record_t
);
747 r
->data
.DNSNULL
= (dns_raw_resource_record_t
*)calloc(1, size
);
749 r
->data
.DNSNULL
->length
= rdlen
;
750 r
->data
.DNSNULL
->data
= calloc(1, rdlen
);
751 memmove(r
->data
.DNSNULL
->data
, *x
, rdlen
);
760 dns_resource_record_t
*
761 dns_parse_resource_record(const char *buf
, uint32_t len
)
768 return _dns_parse_resource_record_internal(buf
, &x
, &remaining
);
772 _dns_parse_question_internal(const char *p
, char **x
, int32_t *remaining
)
776 if (x
== NULL
) return NULL
;
777 if (*x
== NULL
) return NULL
;
778 if (*remaining
< 1) return NULL
;
780 q
= (dns_question_t
*)calloc(1, sizeof(dns_question_t
));
782 q
->name
= _dns_parse_domain_name(p
, x
, remaining
);
796 *remaining
= *remaining
- 4;
798 q
->dnstype
= _dns_parse_uint16(x
);
799 q
->dnsclass
= _dns_parse_uint16(x
);
805 dns_parse_question(const char *buf
, uint32_t len
)
812 return _dns_parse_question_internal(buf
, &x
, &remaining
);
817 dns_parse_packet(const char *p
, uint32_t len
)
825 if (p
== NULL
) return NULL
;
826 if (len
< NS_HFIXEDSZ
) return NULL
;
830 r
= (dns_reply_t
*)calloc(1, sizeof(dns_reply_t
));
832 r
->header
= (dns_header_t
*)calloc(1, sizeof(dns_header_t
));
835 h
->xid
= _dns_parse_uint16(&x
);
836 h
->flags
= _dns_parse_uint16(&x
);
837 h
->qdcount
= _dns_parse_uint16(&x
);
838 h
->ancount
= _dns_parse_uint16(&x
);
839 h
->nscount
= _dns_parse_uint16(&x
);
840 h
->arcount
= _dns_parse_uint16(&x
);
842 remaining
= len
- NS_HFIXEDSZ
;
844 size
= sizeof(dns_question_t
*);
845 r
->question
= (dns_question_t
**)calloc(h
->qdcount
, size
);
846 for (i
= 0; i
< h
->qdcount
; i
++)
848 r
->question
[i
] = _dns_parse_question_internal(p
, &x
, &remaining
);
849 if (r
->question
[i
] ==NULL
)
852 if (i
> 0) h
->qdcount
= i
- 1;
861 size
= sizeof(dns_resource_record_t
*);
863 r
->answer
= (dns_resource_record_t
**)calloc(h
->ancount
, size
);
864 for (i
= 0; i
< h
->ancount
; i
++)
866 r
->answer
[i
] = _dns_parse_resource_record_internal(p
, &x
, &remaining
);
867 if (r
->answer
[i
] == NULL
)
870 if (i
> 0) h
->ancount
= i
- 1;
878 r
->authority
= (dns_resource_record_t
**)calloc(h
->nscount
, size
);
879 for (i
= 0; i
< h
->nscount
; i
++)
881 r
->authority
[i
] = _dns_parse_resource_record_internal(p
, &x
, &remaining
);
882 if (r
->authority
[i
] == NULL
)
885 if (i
> 0) h
->nscount
= i
- 1;
892 r
->additional
= (dns_resource_record_t
**)calloc(h
->arcount
, size
);
893 for (i
= 0; i
< h
->arcount
; i
++)
895 r
->additional
[i
] = _dns_parse_resource_record_internal(p
, &x
, &remaining
);
896 if (r
->additional
[i
] == NULL
)
899 if (i
> 0) h
->arcount
= i
- 1;
909 dns_free_resource_record(dns_resource_record_t
*r
)
933 free(r
->data
.CNAME
->name
);
938 free(r
->data
.SOA
->mname
);
939 free(r
->data
.SOA
->rname
);
944 free(r
->data
.WKS
->map
);
949 free(r
->data
.HINFO
->cpu
);
950 free(r
->data
.HINFO
->os
);
955 free(r
->data
.MINFO
->rmailbx
);
956 free(r
->data
.MINFO
->emailbx
);
961 free(r
->data
.MX
->name
);
967 for (i
=0; i
<r
->data
.TXT
->string_count
; i
++)
969 free(r
->data
.TXT
->strings
[i
]);
971 if (r
->data
.TXT
->strings
!= NULL
)
972 free(r
->data
.TXT
->strings
);
977 free(r
->data
.RP
->mailbox
);
978 free(r
->data
.RP
->txtdname
);
983 free(r
->data
.AFSDB
->hostname
);
988 free(r
->data
.X25
->psdn_address
);
993 free(r
->data
.ISDN
->isdn_address
);
994 if (r
->data
.ISDN
->subaddress
!= NULL
)
995 free(r
->data
.ISDN
->subaddress
);
1000 free(r
->data
.RT
->intermediate
);
1009 free(r
->data
.SRV
->target
);
1015 free(r
->data
.DNSNULL
->data
);
1016 free(r
->data
.DNSNULL
);
1024 dns_free_reply(dns_reply_t
*r
)
1028 if (r
== NULL
) return;
1029 if (r
->header
!= NULL
)
1031 for (i
= 0; i
< r
->header
->qdcount
; i
++)
1033 free(r
->question
[i
]->name
);
1034 free(r
->question
[i
]);
1037 for (i
= 0; i
< r
->header
->ancount
; i
++) dns_free_resource_record(r
->answer
[i
]);
1038 for (i
= 0; i
< r
->header
->nscount
; i
++) dns_free_resource_record(r
->authority
[i
]);
1039 for (i
= 0; i
< r
->header
->arcount
; i
++) dns_free_resource_record(r
->additional
[i
]);
1044 if (r
->question
!= NULL
) free(r
->question
);
1045 if (r
->answer
!= NULL
) free(r
->answer
);
1046 if (r
->authority
!= NULL
) free(r
->authority
);
1047 if (r
->additional
!= NULL
) free(r
->additional
);
1049 if (r
->server
!= NULL
) free(r
->server
);
1055 _dns_append_question(dns_question_t
*q
, char **s
, uint16_t *l
)
1060 if (q
== NULL
) return;
1062 len
= *l
+ _dns_cname_length(q
->name
) + 2 + 4;
1063 *s
= realloc(*s
, len
);
1065 _dns_insert_cname(q
->name
, (char *)*s
+ *l
);
1071 *p
= htons(q
->dnstype
);
1075 *p
= htons(q
->dnsclass
);
1080 _dns_append_resource_record(dns_resource_record_t
*r
, char **s
, uint16_t *l
)
1082 uint16_t clen
, len
, *p
, extra
, rdlen
;
1086 if (r
== NULL
) return;
1096 clen
= _dns_cname_length(r
->data
.PTR
->name
);
1102 len
= *l
+ _dns_cname_length(r
->name
) + 2 + extra
;
1103 *s
= realloc(*s
, len
);
1105 _dns_insert_cname(r
->name
, (char *)*s
+ *l
);
1108 x
= *s
+ (len
- extra
);
1111 *p
= htons(r
->dnstype
);
1115 *p
= htons(r
->dnsclass
);
1119 *p2
= htonl(r
->ttl
);
1131 *p2
= htons(r
->data
.A
->addr
.s_addr
);
1136 clen
= _dns_cname_length(r
->data
.PTR
->name
) + 2;
1140 _dns_insert_cname(r
->data
.PTR
->name
, x
);
1149 dns_build_reply(dns_reply_t
*dnsr
, uint16_t *rl
)
1155 if (dnsr
== NULL
) return NULL
;
1165 h
= (dns_header_t
*)s
;
1167 h
->xid
= htons(dnsr
->header
->xid
);
1168 h
->flags
= htons(dnsr
->header
->flags
);
1169 h
->qdcount
= htons(dnsr
->header
->qdcount
);
1170 h
->ancount
= htons(dnsr
->header
->ancount
);
1171 h
->nscount
= htons(dnsr
->header
->nscount
);
1172 h
->arcount
= htons(dnsr
->header
->arcount
);
1174 for (i
= 0; i
< dnsr
->header
->qdcount
; i
++)
1176 _dns_append_question(dnsr
->question
[i
], &s
, rl
);
1179 for (i
= 0; i
< dnsr
->header
->ancount
; i
++)
1181 _dns_append_resource_record(dnsr
->answer
[i
], &s
, rl
);
1184 for (i
= 0; i
< dnsr
->header
->nscount
; i
++)
1186 _dns_append_resource_record(dnsr
->authority
[i
], &s
, rl
);
1189 for (i
= 0; i
< dnsr
->header
->arcount
; i
++)
1191 _dns_append_resource_record(dnsr
->additional
[i
], &s
, rl
);
1198 dns_free_question(dns_question_t
*q
)
1200 if (q
== NULL
) return;
1201 if (q
->name
!= NULL
) free(q
->name
);
1206 dns_set_buffer_size(dns_handle_t d
, uint32_t len
)
1208 dns_private_handle_t
*dns
;
1209 if (d
== NULL
) return;
1211 dns
= (dns_private_handle_t
*)d
;
1212 if (dns
->recvsize
== len
) return;
1214 if (dns
->recvbuf
!= NULL
)
1217 dns
->recvbuf
= NULL
;
1220 dns
->recvsize
= len
;
1221 if (dns
->recvsize
> DNS_MAX_RECEIVE_SIZE
) dns
->recvsize
= DNS_MAX_RECEIVE_SIZE
;
1223 if (dns
->recvsize
> 0) dns
->recvbuf
= malloc(dns
->recvsize
);
1227 dns_get_buffer_size(dns_handle_t d
)
1229 dns_private_handle_t
*dns
;
1230 if (d
== NULL
) return 0;
1232 dns
= (dns_private_handle_t
*)d
;
1233 return dns
->recvsize
;
1237 dns_lookup_soa_min(dns_handle_t d
, const char *name
, uint32_t class, uint32_t type
, int *min
)
1239 dns_private_handle_t
*dns
;
1242 struct sockaddr_storage
*from
;
1245 if (d
== NULL
) return NULL
;
1246 if (name
== NULL
) return NULL
;
1248 dns
= (dns_private_handle_t
*)d
;
1249 if (min
!= NULL
) *min
= -1;
1251 if (dns
->recvbuf
== NULL
)
1253 if (dns
->recvsize
== 0) dns
->recvsize
= DNS_DEFAULT_RECEIVE_SIZE
;
1255 dns
->recvbuf
= malloc(dns
->recvsize
);
1256 if (dns
->recvbuf
== NULL
) return NULL
;
1259 fromlen
= sizeof(struct sockaddr_storage
);
1260 from
= (struct sockaddr_storage
*)calloc(1, sizeof(struct sockaddr_storage
));
1263 if (dns
->handle_type
== DNS_PRIVATE_HANDLE_TYPE_SUPER
)
1265 _check_cache(dns
->sdns
);
1266 len
= _sdns_search(dns
->sdns
, name
, class, type
, 0, 1, dns
->recvbuf
, dns
->recvsize
, (struct sockaddr
*)from
, &fromlen
, min
);
1270 /* NB. Minumium SOA TTL values are NOT provided when the caller passes a DNS_PRIVATE_HANDLE_TYPE_PLAIN handle */
1271 len
= _pdns_search(dns
->sdns
, dns
->pdns
, name
, class, type
, dns
->recvbuf
, dns
->recvsize
, (struct sockaddr
*)from
, &fromlen
);
1280 r
= dns_parse_packet(dns
->recvbuf
, len
);
1282 if (r
== NULL
) free(from
);
1283 else r
->server
= (struct sockaddr
*)from
;
1289 dns_lookup(dns_handle_t d
, const char *name
, uint32_t class, uint32_t type
)
1293 return dns_lookup_soa_min(d
, name
, class, type
, &unused
);
1297 * DNS printing utilities
1301 coord_ntoa(int32_t coord
, uint32_t islat
)
1303 int32_t deg
, min
, sec
, secfrac
;
1304 static char buf
[64];
1307 coord
= coord
- 0x80000000;
1310 if ((islat
== 1) && (coord
< 0))
1326 secfrac
= coord
% 1000;
1327 coord
= coord
/ 1000;
1334 sprintf(buf
, "%d %.2d %.2d.%.3d %c", deg
, min
, sec
, secfrac
, dir
);
1339 alt_ntoa(int32_t alt
)
1341 int32_t ref
, m
, frac
, sign
;
1342 static char buf
[128];
1358 m
= (alt
/ 100) * sign
;
1360 sprintf(buf
, "%d.%.2d", m
, frac
);
1379 precsize_ntoa(uint8_t prec
)
1381 static char buf
[19];
1383 int mantissa
, exponent
;
1385 mantissa
= (int)((prec
>> 4) & 0x0f) % 10;
1386 exponent
= (int)((prec
>> 0) & 0x0f) % 10;
1388 val
= mantissa
* poweroften
[exponent
];
1390 sprintf(buf
, "%ld.%.2ld", val
/100, val%100
);
1395 dns_type_string(uint16_t t
)
1399 case ns_t_a
: return "A ";
1400 case ns_t_ns
: return "NS ";
1401 case ns_t_md
: return "MD ";
1402 case ns_t_mf
: return "MF ";
1403 case ns_t_cname
: return "CNAME";
1404 case ns_t_soa
: return "SOA ";
1405 case ns_t_mb
: return "MB ";
1406 case ns_t_mg
: return "MG ";
1407 case ns_t_mr
: return "MR ";
1408 case ns_t_null
: return "NULL ";
1409 case ns_t_wks
: return "WKS ";
1410 case ns_t_ptr
: return "PTR ";
1411 case ns_t_hinfo
: return "HINFO";
1412 case ns_t_minfo
: return "MINFO";
1413 case ns_t_mx
: return "MX ";
1414 case ns_t_txt
: return "TXT ";
1415 case ns_t_rp
: return "PR ";
1416 case ns_t_afsdb
: return "AFSDB";
1417 case ns_t_x25
: return "X25 ";
1418 case ns_t_isdn
: return "ISDN ";
1419 case ns_t_rt
: return "RT ";
1420 case ns_t_nsap
: return "NSAP ";
1421 case ns_t_nsap_ptr
: return "NSPTR";
1422 case ns_t_sig
: return "SIG ";
1423 case ns_t_key
: return "KEY ";
1424 case ns_t_px
: return "PX ";
1425 case ns_t_gpos
: return "GPOS ";
1426 case ns_t_aaaa
: return "AAAA ";
1427 case ns_t_loc
: return "LOC ";
1428 case ns_t_nxt
: return "NXT ";
1429 case ns_t_eid
: return "EID ";
1430 case ns_t_nimloc
: return "NIMLC";
1431 case ns_t_srv
: return "SRV ";
1432 case ns_t_atma
: return "ATMA ";
1433 case ns_t_naptr
: return "NAPTR";
1434 case ns_t_kx
: return "KX ";
1435 case ns_t_cert
: return "CERT ";
1436 case ns_t_a6
: return "A6 ";
1437 case ns_t_dname
: return "DNAME";
1438 case ns_t_sink
: return "SINK ";
1439 case ns_t_opt
: return "OPT ";
1440 case ns_t_tkey
: return "TKEY ";
1441 case ns_t_tsig
: return "TSIG ";
1442 case ns_t_ixfr
: return "IXFR ";
1443 case ns_t_axfr
: return "AXFR ";
1444 case ns_t_mailb
: return "MAILB";
1445 case ns_t_maila
: return "MAILA";
1446 case ns_t_any
: return "ANY ";
1447 case ns_t_zxfr
: return "ZXFR ";
1448 default: return "?????";
1455 dns_type_number(const char *t
, uint16_t *n
)
1457 if (t
== NULL
) return -1;
1459 if (!strcasecmp(t
, "A")) { *n
= ns_t_a
; return 0; }
1460 if (!strcasecmp(t
, "NS")) { *n
= ns_t_ns
; return 0; }
1461 if (!strcasecmp(t
, "MD")) { *n
= ns_t_md
; return 0; }
1462 if (!strcasecmp(t
, "MF")) { *n
= ns_t_mf
; return 0; }
1463 if (!strcasecmp(t
, "CNAME")) { *n
= ns_t_cname
; return 0; }
1464 if (!strcasecmp(t
, "SOA")) { *n
= ns_t_soa
; return 0; }
1465 if (!strcasecmp(t
, "MB")) { *n
= ns_t_mb
; return 0; }
1466 if (!strcasecmp(t
, "MG")) { *n
= ns_t_mg
; return 0; }
1467 if (!strcasecmp(t
, "MR")) { *n
= ns_t_mr
; return 0; }
1468 if (!strcasecmp(t
, "NULL")) { *n
= ns_t_null
; return 0; }
1469 if (!strcasecmp(t
, "WKS")) { *n
= ns_t_wks
; return 0; }
1470 if (!strcasecmp(t
, "PTR")) { *n
= ns_t_ptr
; return 0; }
1471 if (!strcasecmp(t
, "HINFO")) { *n
= ns_t_hinfo
; return 0; }
1472 if (!strcasecmp(t
, "MINFO")) { *n
= ns_t_minfo
; return 0; }
1473 if (!strcasecmp(t
, "MX")) { *n
= ns_t_mx
; return 0; }
1474 if (!strcasecmp(t
, "TXT")) { *n
= ns_t_txt
; return 0; }
1475 if (!strcasecmp(t
, "RP")) { *n
= ns_t_rp
; return 0; }
1476 if (!strcasecmp(t
, "AFSDB")) { *n
= ns_t_afsdb
; return 0; }
1477 if (!strcasecmp(t
, "X25")) { *n
= ns_t_x25
; return 0; }
1478 if (!strcasecmp(t
, "ISDN")) { *n
= ns_t_isdn
; return 0; }
1479 if (!strcasecmp(t
, "RT")) { *n
= ns_t_rt
; return 0; }
1480 if (!strcasecmp(t
, "NSAP")) { *n
= ns_t_nsap
; return 0; }
1481 if (!strcasecmp(t
, "NSPTR")) { *n
= ns_t_nsap_ptr
; return 0; }
1482 if (!strcasecmp(t
, "NSAP_PTR")){ *n
= ns_t_nsap_ptr
; return 0; }
1483 if (!strcasecmp(t
, "SIG")) { *n
= ns_t_sig
; return 0; }
1484 if (!strcasecmp(t
, "KEY")) { *n
= ns_t_key
; return 0; }
1485 if (!strcasecmp(t
, "PX")) { *n
= ns_t_px
; return 0; }
1486 if (!strcasecmp(t
, "GPOS")) { *n
= ns_t_gpos
; return 0; }
1487 if (!strcasecmp(t
, "AAAA")) { *n
= ns_t_aaaa
; return 0; }
1488 if (!strcasecmp(t
, "LOC")) { *n
= ns_t_loc
; return 0; }
1489 if (!strcasecmp(t
, "NXT")) { *n
= ns_t_nxt
; return 0; }
1490 if (!strcasecmp(t
, "EID")) { *n
= ns_t_eid
; return 0; }
1491 if (!strcasecmp(t
, "NIMLOC")) { *n
= ns_t_nimloc
; return 0; }
1492 if (!strcasecmp(t
, "SRV")) { *n
= ns_t_srv
; return 0; }
1493 if (!strcasecmp(t
, "ATMA")) { *n
= ns_t_atma
; return 0; }
1494 if (!strcasecmp(t
, "NAPTR")) { *n
= ns_t_naptr
; return 0; }
1495 if (!strcasecmp(t
, "KX")) { *n
= ns_t_kx
; return 0; }
1496 if (!strcasecmp(t
, "CERT")) { *n
= ns_t_cert
; return 0; }
1497 if (!strcasecmp(t
, "A6")) { *n
= ns_t_a6
; return 0; }
1498 if (!strcasecmp(t
, "DNAME")) { *n
= ns_t_dname
; return 0; }
1499 if (!strcasecmp(t
, "SINK")) { *n
= ns_t_sink
; return 0; }
1500 if (!strcasecmp(t
, "OPT")) { *n
= ns_t_opt
; return 0; }
1501 if (!strcasecmp(t
, "TKEY")) { *n
= ns_t_tkey
; return 0; }
1502 if (!strcasecmp(t
, "TSIG")) { *n
= ns_t_tsig
; return 0; }
1503 if (!strcasecmp(t
, "IXFR")) { *n
= ns_t_ixfr
; return 0; }
1504 if (!strcasecmp(t
, "AXFR")) { *n
= ns_t_axfr
; return 0; }
1505 if (!strcasecmp(t
, "MAILB")) { *n
= ns_t_mailb
; return 0; }
1506 if (!strcasecmp(t
, "MAILA")) { *n
= ns_t_maila
; return 0; }
1507 if (!strcasecmp(t
, "ANY")) { *n
= ns_t_any
; return 0; }
1508 if (!strcasecmp(t
, "ZXFR")) { *n
= ns_t_zxfr
; return 0; }
1514 dns_class_string(uint16_t c
)
1518 case ns_c_in
: return "IN";
1519 case ns_c_2
: return "CS";
1520 case ns_c_chaos
: return "CH";
1521 case ns_c_hs
: return "HS";
1522 case ns_c_none
: return "NONE";
1523 case ns_c_any
: return "ANY";
1524 default: return "??";
1531 dns_class_number(const char *c
, uint16_t *n
)
1533 if (c
== NULL
) return -1;
1535 if (!strcasecmp(c
, "IN")) { *n
= ns_c_in
; return 0; }
1536 if (!strcasecmp(c
, "CS")) { *n
= ns_c_2
; return 0; }
1537 if (!strcasecmp(c
, "CH")) { *n
= ns_c_chaos
; return 0; }
1538 if (!strcasecmp(c
, "HS")) { *n
= ns_c_hs
; return 0; }
1539 if (!strcasecmp(c
, "NONE")) { *n
= ns_c_none
; return 0; }
1540 if (!strcasecmp(c
, "ANY")) { *n
= ns_c_any
; return 0; }
1546 _dns_print_question_lock(const dns_question_t
*q
, FILE *f
, int lockit
)
1548 if (lockit
!= 0) _dns_print_lock();
1549 fprintf(f
, "%s %s %s\n", q
->name
, dns_class_string(q
->dnsclass
), dns_type_string(q
->dnstype
));
1550 if (lockit
!= 0) _dns_print_unlock();
1554 dns_print_question(const dns_question_t
*q
, FILE *f
)
1556 _dns_print_question_lock(q
, f
, 1);
1560 _dns_print_resource_record_lock(const dns_resource_record_t
*r
, FILE *f
, int lockit
)
1566 struct sockaddr_in6 s6
;
1569 if (lockit
!= 0) _dns_print_lock();
1571 fprintf(f
, "%s %s %s ", r
->name
, dns_class_string(r
->dnsclass
), dns_type_string(r
->dnstype
));
1572 fprintf(f
, "%u", r
->ttl
);
1577 fprintf(f
, " %s", inet_ntoa(r
->data
.A
->addr
));
1581 memset(&s6
, 0, sizeof(struct sockaddr_in6
));
1582 s6
.sin6_len
= sizeof(struct sockaddr_in6
);
1583 s6
.sin6_family
= AF_INET6
;
1584 s6
.sin6_addr
= r
->data
.AAAA
->addr
;
1585 fprintf(f
, " %s", inet_ntop(AF_INET6
, (char *)(&s6
) + INET_NTOP_AF_INET6_OFFSET
, pbuf
, 64));
1596 fprintf(f
, " %s", r
->data
.CNAME
->name
);
1600 fprintf(f
, " %s %s %u %u %u %u %u",
1601 r
->data
.SOA
->mname
, r
->data
.SOA
->rname
,
1602 r
->data
.SOA
->serial
, r
->data
.SOA
->refresh
, r
->data
.SOA
->retry
,
1603 r
->data
.SOA
->expire
, r
->data
.SOA
->minimum
);
1607 fprintf(f
, " %s", inet_ntoa(r
->data
.WKS
->addr
));
1608 p
= getprotobynumber(r
->data
.WKS
->protocol
);
1611 fprintf(f
, " %s", p
->p_name
);
1613 for (i
= 0; i
< r
->data
.WKS
->maplength
; i
++)
1615 if (r
->data
.WKS
->map
[i
])
1617 s
= getservbyport(i
, p
->p_name
);
1618 if (s
== NULL
) fprintf(f
, " %u", i
);
1619 else fprintf(f
, " %s", s
->s_name
);
1623 else fprintf(f
, " UNKNOWN PROTOCOL %u", r
->data
.WKS
->protocol
);
1627 fprintf(f
, " %s %s", r
->data
.HINFO
->cpu
, r
->data
.HINFO
->os
);
1631 fprintf(f
, " %s %s", r
->data
.MINFO
->rmailbx
, r
->data
.MINFO
->emailbx
);
1635 fprintf(f
, " %u %s", r
->data
.MX
->preference
, r
->data
.MX
->name
);
1639 for (i
= 0; i
< r
->data
.TXT
->string_count
; i
++)
1641 fprintf(f
, " \"%s\"", r
->data
.TXT
->strings
[i
]);
1646 fprintf(f
, " %s %s", r
->data
.RP
->mailbox
, r
->data
.RP
->txtdname
);
1650 fprintf(f
, " %u %s", r
->data
.AFSDB
->subtype
,
1651 r
->data
.AFSDB
->hostname
);
1655 fprintf(f
, " %s", r
->data
.X25
->psdn_address
);
1659 fprintf(f
, " %s", r
->data
.ISDN
->isdn_address
);
1660 if (r
->data
.ISDN
->subaddress
!= NULL
)
1661 fprintf(f
, " %s", r
->data
.ISDN
->subaddress
);
1665 fprintf(f
, " %hu %s", r
->data
.RT
->preference
,
1666 r
->data
.RT
->intermediate
);
1670 fprintf(f
, " %s", coord_ntoa(r
->data
.LOC
->latitude
, 1));
1671 fprintf(f
, " %s", coord_ntoa(r
->data
.LOC
->longitude
, 0));
1672 fprintf(f
, " %sm", alt_ntoa(r
->data
.LOC
->altitude
));
1673 fprintf(f
, " %sm", precsize_ntoa(r
->data
.LOC
->size
));
1674 fprintf(f
, " %sm", precsize_ntoa(r
->data
.LOC
->horizontal_precision
));
1675 fprintf(f
, " %sm", precsize_ntoa(r
->data
.LOC
->vertical_precision
));
1679 fprintf(f
, " %hu %hu %hu %s",
1680 r
->data
.SRV
->priority
, r
->data
.SRV
->weight
,
1681 r
->data
.SRV
->port
, r
->data
.SRV
->target
);
1686 len
= r
->data
.DNSNULL
->length
;
1687 fprintf(f
, " %hu ", len
);
1688 for (i
= 0; i
< len
; i
++)
1690 x
= r
->data
.DNSNULL
->data
[i
];
1691 fprintf(f
, "%x", x
);
1696 len
= r
->data
.DNSNULL
->length
;
1697 for (i
= 0; i
< len
; i
++)
1699 x
= r
->data
.DNSNULL
->data
[i
];
1700 if (isascii(x
)) fprintf(f
, "%c", x
);
1701 else fprintf(f
, " ");
1709 if (lockit
!= 0) _dns_print_unlock();
1713 dns_print_resource_record(const dns_resource_record_t
*r
, FILE *f
)
1715 _dns_print_resource_record_lock(r
, f
, 1);
1719 dns_print_reply(const dns_reply_t
*r
, FILE *f
, uint16_t mask
)
1724 uint32_t offset
, iface
;
1730 fprintf(f
, "-nil-\n");
1731 _dns_print_unlock();
1735 if (r
->status
!= DNS_STATUS_OK
)
1737 if (r
->status
== DNS_STATUS_TIMEOUT
)
1738 fprintf(f
, "Timeout\n");
1739 else if (r
->status
== DNS_STATUS_SEND_FAILED
)
1740 fprintf(f
, "Send failed\n");
1741 else if (r
->status
== DNS_STATUS_RECEIVE_FAILED
)
1742 fprintf(f
, "Receive failed\n");
1743 else fprintf(f
, "status %u\n", r
->status
);
1745 _dns_print_unlock();
1751 if (mask
& DNS_PRINT_XID
)
1753 fprintf(f
, "Xid: %u\n", h
->xid
);
1756 if (mask
& DNS_PRINT_QR
)
1758 if ((h
->flags
& DNS_FLAGS_QR_MASK
) == DNS_FLAGS_QR_QUERY
)
1759 fprintf(f
, "QR: Query\n");
1761 fprintf(f
, "QR: Reply\n");
1764 if (mask
& DNS_PRINT_SERVER
)
1766 if (r
->server
== NULL
)
1768 fprintf(f
, "Server: -nil-\n");
1772 offset
= INET_NTOP_AF_INET_OFFSET
;
1773 if (r
->server
->sa_family
== AF_INET6
) offset
= INET_NTOP_AF_INET6_OFFSET
;
1775 fprintf(f
, "Server: %s", inet_ntop(r
->server
->sa_family
, (char *)(r
->server
) + offset
, scratch
, 1024));
1776 if (r
->server
->sa_family
== AF_INET
)
1778 memcpy(&iface
, (((struct sockaddr_in
*)(r
->server
))->sin_zero
), 4);
1779 if (iface
> 0) fprintf(f
, "%%%s", if_indextoname(iface
, scratch
));
1781 else if (r
->server
->sa_family
== AF_INET6
)
1783 iface
= ((struct sockaddr_in6
*)(r
->server
))->sin6_scope_id
;
1784 if (iface
> 0) fprintf(f
, "%%%s", if_indextoname(iface
, scratch
));
1790 if (mask
& DNS_PRINT_OPCODE
)
1792 fprintf(f
, "Opcode: ");
1793 switch (h
->flags
& DNS_FLAGS_OPCODE_MASK
)
1795 case ns_o_query
: fprintf(f
, "Standard\n"); break;
1796 case ns_o_iquery
: fprintf(f
, "Inverse\n"); break;
1797 case ns_o_status
: fprintf(f
, "Status\n"); break;
1798 case ns_o_notify
: fprintf(f
, "Notify\n"); break;
1799 case ns_o_update
: fprintf(f
, "Update\n"); break;
1801 fprintf(f
, "Reserved (%hu)\n",
1802 (h
->flags
& DNS_FLAGS_OPCODE_MASK
) >> 11);
1806 if (mask
& DNS_PRINT_AA
)
1808 if (h
->flags
& DNS_FLAGS_AA
) fprintf(f
, "AA: Authoritative\n");
1809 else fprintf(f
, "AA: Non-Authoritative\n");
1812 if (mask
& DNS_PRINT_TC
)
1814 if (h
->flags
& DNS_FLAGS_TC
) fprintf(f
, "TC: Truncated\n");
1815 else fprintf(f
, "TC: Non-Truncated\n");
1818 if (mask
& DNS_PRINT_RD
)
1820 if (h
->flags
& DNS_FLAGS_RD
) fprintf(f
, "RD: Recursion desired\n");
1821 else fprintf(f
, "RD: No recursion desired\n");
1824 if (mask
& DNS_PRINT_RA
)
1826 if (h
->flags
& DNS_FLAGS_RA
) fprintf(f
, "RA: Recursion available\n");
1827 else fprintf(f
, "RA: No recursion available \n");
1830 if (mask
& DNS_PRINT_RCODE
)
1832 fprintf(f
, "Rcode: ");
1833 switch (h
->flags
& DNS_FLAGS_RCODE_MASK
)
1836 fprintf(f
, "No error\n");
1839 fprintf(f
, "Format error \n");
1842 fprintf(f
, "Server failure\n");
1845 fprintf(f
, "Name error \n");
1848 fprintf(f
, "Not implemented\n");
1851 fprintf(f
, "Refused\n");
1854 fprintf(f
, "Name exists\n");
1857 fprintf(f
, "RR Set exists\n");
1860 fprintf(f
, "RR Set does not exist\n");
1863 fprintf(f
, "Not authoritative\n");
1866 fprintf(f
, "Record zone does not match section zone\n");
1869 fprintf(f
, "Invalid EDNS version or TSIG signature\n");
1872 fprintf(f
, "Invalid key\n");
1875 fprintf(f
, "Invalid time\n");
1878 fprintf(f
, "Reserved (%hu)\n",h
->flags
& DNS_FLAGS_RCODE_MASK
);
1882 if (mask
& DNS_PRINT_QUESTION
)
1884 fprintf(f
, "Question (%hu):\n", h
->qdcount
);
1885 for (i
= 0; i
< h
->qdcount
; i
++)
1886 _dns_print_question_lock(r
->question
[i
], f
, 0);
1889 if (mask
& DNS_PRINT_ANSWER
)
1891 fprintf(f
, "Answer (%hu):\n", h
->ancount
);
1892 for (i
= 0; i
< h
->ancount
; i
++)
1893 _dns_print_resource_record_lock(r
->answer
[i
], f
, 0);
1896 if (mask
& DNS_PRINT_AUTHORITY
)
1898 fprintf(f
, "Authority (%hu):\n", h
->nscount
);
1899 for (i
= 0; i
< h
->nscount
; i
++)
1900 _dns_print_resource_record_lock(r
->authority
[i
], f
, 0);
1903 if (mask
& DNS_PRINT_ADDITIONAL
)
1905 fprintf(f
, "Additional records (%hu):\n", h
->arcount
);
1906 for (i
= 0; i
< h
->arcount
; i
++)
1907 _dns_print_resource_record_lock(r
->additional
[i
], f
, 0);
1910 _dns_print_unlock();
1914 _pdns_print_handle(pdns_handle_t
*pdns
, FILE *f
)
1919 struct sockaddr
*sa
;
1924 fprintf(f
, "-nil-\n");
1928 if (pdns
->name
== NULL
) fprintf(f
, "Name: -nil-\n");
1929 else fprintf(f
, "Name: %s\n", pdns
->name
);
1931 fprintf(f
, "Flags:");
1932 if (pdns
->flags
== 0) fprintf(f
, " None\n");
1935 if (pdns
->flags
& DNS_FLAG_DEBUG
) fprintf(f
, " Debug");
1936 if (pdns
->flags
& DNS_FLAG_CHECK_RESOLVER_DIR
) fprintf(f
, " DirCheck");
1937 if (pdns
->flags
& DNS_FLAG_HAVE_IPV6_SERVER
) fprintf(f
, " IPv6");
1938 if (pdns
->flags
& DNS_FLAG_OK_TO_SKIP_AAAA
) fprintf(f
, " SkipAAAA");
1939 if (pdns
->flags
& DNS_FLAG_DEFAULT_RESOLVER
) fprintf(f
, " Default");
1944 if (r
== NULL
) return;
1946 if (r
->defdname
[0] != '\0') fprintf(f
, "Domain: %s\n", r
->defdname
);
1947 fprintf(f
, "Search Order: %d\n", pdns
->search_order
);
1948 fprintf(f
, "Total Timeout: %d\n", pdns
->total_timeout
);
1949 fprintf(f
, "Retry Timeout: %d\n", pdns
->res
->retrans
);
1950 fprintf(f
, "Retry Attempts: %d\n", pdns
->res
->retry
);
1952 fprintf(f
, "Server%s:\n", (r
->nscount
== 1) ? "" : "s");
1953 for (i
= 0; i
< r
->nscount
; i
++)
1955 sa
= get_nsaddr(r
, i
);
1956 offset
= INET_NTOP_AF_INET_OFFSET
;
1957 if (sa
->sa_family
== AF_INET6
) offset
= INET_NTOP_AF_INET6_OFFSET
;
1958 fprintf(f
, " %u: %s", i
, inet_ntop(sa
->sa_family
, (char *)sa
+ offset
, scratch
, 1024));
1962 if (pdns
->search_count
> 0)
1964 fprintf(f
, "Search List:\n");
1965 for (i
= 0; i
< pdns
->search_count
; i
++)
1966 fprintf(f
, " %u: %s\n", i
, pdns
->search_list
[i
]);
1969 if (r
->sort_list
[0].addr
.s_addr
!= 0)
1971 fprintf(f
, "Sortlist:\n");
1972 for (i
= 0; (r
->sort_list
[i
].addr
.s_addr
!= 0); i
++)
1974 fprintf(f
, " %u: ", i
);
1975 a
.s_addr
= r
->sort_list
[i
].addr
.s_addr
;
1976 fprintf(f
, "%s/", inet_ntoa(a
));
1977 a
.s_addr
= r
->sort_list
[i
].mask
;
1978 fprintf(f
, "%s\n", inet_ntoa(a
));
1984 _sdns_print_handle(sdns_handle_t
*sdns
, FILE *f
)
1990 fprintf(f
, "-nil-\n");
1994 for (i
= 0; i
< sdns
->client_count
; i
++)
1996 fprintf(f
, "DNS client %d\n", i
);
1997 _pdns_print_handle(sdns
->client
[i
], f
);
2001 fprintf(f
, "resolver dir mod time = %u\n", sdns
->modtime
);
2002 fprintf(f
, "resolver dir stat time = %u\n", sdns
->stattime
);
2003 fprintf(f
, "resolver dir stat latency = %u\n", sdns
->stat_latency
);
2007 dns_print_handle(dns_handle_t d
, FILE *f
)
2009 dns_private_handle_t
*dns
;
2015 fprintf(f
, "-nil-\n");
2016 _dns_print_unlock();
2020 dns
= (dns_private_handle_t
*)d
;
2022 if (dns
->handle_type
== DNS_PRIVATE_HANDLE_TYPE_SUPER
)
2024 _sdns_print_handle(dns
->sdns
, f
);
2028 _pdns_print_handle(dns
->pdns
, f
);
2031 _dns_print_unlock();
2035 dns_all_server_addrs(dns_handle_t d
, struct sockaddr
***addrs
, uint32_t *count
)
2037 int i
, j
, k
, n
, found
;
2038 dns_private_handle_t
*dns
;
2039 pdns_handle_t
*pdns
;
2040 struct sockaddr
*sa
;
2041 struct sockaddr_storage
**l
;
2049 if (d
== NULL
) return;
2051 dns
= (dns_private_handle_t
*)d
;
2053 if (dns
->handle_type
!= DNS_PRIVATE_HANDLE_TYPE_SUPER
) return;
2055 if (dns
->sdns
== NULL
) return;
2057 /* Just to initialize / validate clients */
2058 i
= dns_search_list_count(d
);
2060 for (i
= 0; i
< dns
->sdns
->client_count
; i
++)
2062 pdns
= dns
->sdns
->client
[i
];
2063 if (pdns
== NULL
) continue;
2066 if (r
== NULL
) continue;
2068 for (j
= 0; j
< r
->nscount
; j
++)
2070 sa
= get_nsaddr(r
, j
);
2072 for (k
= 0; (found
== 0) && (k
< n
); k
++)
2074 if (memcmp(l
[k
], sa
, sa
->sa_len
) == 0) found
= 1;
2076 if (found
== 1) continue;
2080 l
= (struct sockaddr_storage
**)calloc(1, sizeof(struct sockaddr_storage
*));
2084 l
= (struct sockaddr_storage
**)reallocf(l
, (n
+ 1) * sizeof(struct sockaddr_storage
*));
2087 if (l
== NULL
) return;
2089 l
[n
] = (struct sockaddr_storage
*)calloc(1, sizeof(struct sockaddr_storage
));
2090 if (l
[n
] == NULL
) return;
2092 memset(l
[n
], 0, sizeof(struct sockaddr_storage
));
2093 memcpy(l
[n
], sa
, sa
->sa_len
);
2098 *addrs
= (struct sockaddr
**)l
;
2103 dns_res_once(struct sockaddr
*server
, struct timeval
*timeout
, int options
, const char *name
, int class, int type
, u_char
*res
, int *reslen
)
2106 int n
, fromlen
, status
;
2107 struct sockaddr_storage from
;
2108 u_char buf
[MAXPACKET
];
2110 if (server
== NULL
) return DNS_RES_STATUS_INVALID_ARGUMENT
;
2111 if (name
== NULL
) return DNS_RES_STATUS_INVALID_ARGUMENT
;
2112 if (res
== NULL
) return DNS_RES_STATUS_INVALID_ARGUMENT
;
2113 if (reslen
== NULL
) return DNS_RES_STATUS_INVALID_ARGUMENT
;
2115 fromlen
= sizeof(struct sockaddr_storage
);
2117 statp
= res_state_new();
2119 statp
->options
= options
;
2120 statp
->id
= res_randomid();
2121 if (timeout
== NULL
) statp
->retrans
= 5;
2122 else statp
->retrans
= timeout
->tv_sec
;
2125 statp
->_vcsock
= -1;
2128 strcpy(statp
->_u
._ext
.ext
->nsuffix
, "ip6.arpa");
2129 strcpy(statp
->_u
._ext
.ext
->nsuffix2
, "ip6.int");
2130 strcpy(statp
->_u
._ext
.ext
->bsuffix
, "ip6.arpa");
2132 if (server
->sa_family
== AF_INET6
)
2134 memcpy(&(statp
->_u
._ext
.ext
->nsaddrs
[0]), server
, sizeof(struct sockaddr_in6
));
2135 statp
->nsaddr_list
[0].sin_family
= 0;
2139 memcpy(&(statp
->_u
._ext
.ext
->nsaddrs
[0]), server
, sizeof(struct sockaddr_in
));
2140 memcpy(&(statp
->nsaddr_list
[0]), server
, sizeof(struct sockaddr_in
));
2143 n
= res_nmkquery(statp
, ns_o_query
, name
, class, type
, NULL
, 0, NULL
, buf
, sizeof(buf
));
2145 status
= dns_res_send(statp
, buf
, n
, res
, reslen
, (struct sockaddr
*)&from
, &fromlen
);
2147 res_client_close(statp
);