mirror of git://git.gnupg.org/gnupg.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1321 lines
34 KiB
1321 lines
34 KiB
/* ========================================================================== |
|
* dns.h - Recursive, Reentrant DNS Resolver. |
|
* -------------------------------------------------------------------------- |
|
* Copyright (c) 2009, 2010, 2012-2015 William Ahern |
|
* |
|
* Permission is hereby granted, free of charge, to any person obtaining a |
|
* copy of this software and associated documentation files (the |
|
* "Software"), to deal in the Software without restriction, including |
|
* without limitation the rights to use, copy, modify, merge, publish, |
|
* distribute, sublicense, and/or sell copies of the Software, and to permit |
|
* persons to whom the Software is furnished to do so, subject to the |
|
* following conditions: |
|
* |
|
* The above copyright notice and this permission notice shall be included |
|
* in all copies or substantial portions of the Software. |
|
* |
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS |
|
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN |
|
* NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, |
|
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR |
|
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE |
|
* USE OR OTHER DEALINGS IN THE SOFTWARE. |
|
* ========================================================================== |
|
*/ |
|
#ifndef DNS_H |
|
#define DNS_H |
|
|
|
#include <stddef.h> /* size_t offsetof() */ |
|
#include <stdint.h> /* uint64_t */ |
|
#include <stdio.h> /* FILE */ |
|
#include <string.h> /* strlen(3) */ |
|
#include <time.h> /* struct timespec time_t */ |
|
|
|
#if _WIN32 |
|
#include <winsock2.h> |
|
#include <ws2tcpip.h> |
|
#else |
|
#include <sys/param.h> /* BYTE_ORDER BIG_ENDIAN _BIG_ENDIAN */ |
|
#include <sys/types.h> /* socklen_t */ |
|
#include <sys/socket.h> /* struct socket */ |
|
#include <poll.h> /* POLLIN POLLOUT */ |
|
#include <netinet/in.h> /* struct in_addr struct in6_addr */ |
|
#include <netdb.h> /* struct addrinfo */ |
|
#endif |
|
|
|
|
|
/* |
|
* V I S I B I L I T Y |
|
* |
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ |
|
|
|
#ifndef DNS_PUBLIC |
|
#define DNS_PUBLIC |
|
#endif |
|
|
|
|
|
/* |
|
* V E R S I O N |
|
* |
|
* Vendor: Entity for which versions numbers are relevant. (If forking |
|
* change DNS_VENDOR to avoid confusion.) |
|
* |
|
* Three versions: |
|
* |
|
* REL Official "release"--bug fixes, new features, etc. |
|
* ABI Changes to existing object sizes or parameter types |
|
* API Changes that might effect application source. |
|
* |
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ |
|
|
|
#define DNS_VENDOR "william@25thandClement.com" |
|
|
|
#define DNS_V_REL 0x20160809 |
|
#define DNS_V_ABI 0x20160608 |
|
#define DNS_V_API 0x20160809 |
|
|
|
|
|
DNS_PUBLIC const char *dns_vendor(void); |
|
|
|
DNS_PUBLIC int dns_v_rel(void); |
|
DNS_PUBLIC int dns_v_abi(void); |
|
DNS_PUBLIC int dns_v_api(void); |
|
|
|
|
|
/* |
|
* E R R O R S |
|
* |
|
* Errors and exceptions are always returned through an int. This should |
|
* hopefully make integration easier in the majority of circumstances, and |
|
* also cut down on useless compiler warnings. |
|
* |
|
* System and library errors are returned together. POSIX guarantees that |
|
* all system errors are positive integers. Library errors are always |
|
* negative integers in the range DNS_EBASE to DNS_ELAST, with the high bits |
|
* set to the three magic ASCII characters "dns". |
|
* |
|
* dns_strerror() returns static English string descriptions of all known |
|
* errors, and punts the remainder to strerror(3). |
|
* |
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ |
|
|
|
#define DNS_EBASE -(('d' << 24) | ('n' << 16) | ('s' << 8) | 64) |
|
|
|
#define dns_error_t int /* for documentation only */ |
|
|
|
enum dns_errno { |
|
DNS_ENOBUFS = DNS_EBASE, |
|
DNS_EILLEGAL, |
|
DNS_EORDER, |
|
DNS_ESECTION, |
|
DNS_EUNKNOWN, |
|
DNS_EADDRESS, |
|
DNS_ENOQUERY, |
|
DNS_ENOANSWER, |
|
DNS_EFETCHED, |
|
DNS_ESERVICE, /* EAI_SERVICE */ |
|
DNS_ENONAME, /* EAI_NONAME */ |
|
DNS_EFAIL, /* EAI_FAIL */ |
|
DNS_ECONNFIN, |
|
DNS_EVERIFY, |
|
DNS_ELAST, |
|
}; /* dns_errno */ |
|
|
|
DNS_PUBLIC const char *dns_strerror(dns_error_t); |
|
|
|
DNS_PUBLIC int *dns_debug_p(void); |
|
|
|
#define dns_debug (*dns_debug_p()) /* was extern int dns_debug before 20160523 API */ |
|
|
|
|
|
/* |
|
* C O M P I L E R A N N O T A T I O N S |
|
* |
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ |
|
|
|
#if defined __clang__ |
|
#define DNS_PRAGMA_PUSH _Pragma("clang diagnostic push") |
|
#define DNS_PRAGMA_QUIET _Pragma("clang diagnostic ignored \"-Winitializer-overrides\"") |
|
#define DNS_PRAGMA_POP _Pragma("clang diagnostic pop") |
|
|
|
#elif (__GNUC__ == 4 && __GNUC_MINOR__ >= 6) || __GNUC__ > 4 |
|
#define DNS_PRAGMA_PUSH _Pragma("GCC diagnostic push") |
|
#define DNS_PRAGMA_QUIET _Pragma("GCC diagnostic ignored \"-Woverride-init\"") |
|
#define DNS_PRAGMA_POP _Pragma("GCC diagnostic pop") |
|
|
|
#else |
|
#define DNS_PRAGMA_PUSH |
|
#define DNS_PRAGMA_QUIET |
|
#define DNS_PRAGMA_POP |
|
#endif |
|
|
|
#if defined __GNUC__ |
|
#define DNS_PRAGMA_EXTENSION __extension__ |
|
#else |
|
#define DNS_PRAGMA_EXTENSION |
|
#endif |
|
|
|
|
|
/* |
|
* E V E N T S I N T E R F A C E S |
|
* |
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ |
|
|
|
#if defined(POLLIN) |
|
#define DNS_POLLIN POLLIN |
|
#else |
|
#define DNS_POLLIN 1 |
|
#endif |
|
|
|
#if defined(POLLOUT) |
|
#define DNS_POLLOUT POLLOUT |
|
#else |
|
#define DNS_POLLOUT 2 |
|
#endif |
|
|
|
|
|
/* |
|
* See Application Interface below for configuring libevent bitmasks instead |
|
* of poll(2) bitmasks. |
|
*/ |
|
#define DNS_EVREAD 2 |
|
#define DNS_EVWRITE 4 |
|
|
|
|
|
#define DNS_POLL2EV(set) \ |
|
(((set) & DNS_POLLIN)? DNS_EVREAD : 0) | (((set) & DNS_POLLOUT)? DNS_EVWRITE : 0) |
|
|
|
#define DNS_EV2POLL(set) \ |
|
(((set) & DNS_EVREAD)? DNS_POLLIN : 0) | (((set) & DNS_EVWRITE)? DNS_POLLOUT : 0) |
|
|
|
|
|
/* |
|
* E N U M E R A T I O N I N T E R F A C E S |
|
* |
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ |
|
|
|
enum dns_section { |
|
DNS_S_QD = 0x01, |
|
#define DNS_S_QUESTION DNS_S_QD |
|
|
|
DNS_S_AN = 0x02, |
|
#define DNS_S_ANSWER DNS_S_AN |
|
|
|
DNS_S_NS = 0x04, |
|
#define DNS_S_AUTHORITY DNS_S_NS |
|
|
|
DNS_S_AR = 0x08, |
|
#define DNS_S_ADDITIONAL DNS_S_AR |
|
|
|
DNS_S_ALL = 0x0f |
|
}; /* enum dns_section */ |
|
|
|
|
|
enum dns_class { |
|
DNS_C_IN = 1, |
|
|
|
DNS_C_ANY = 255 |
|
}; /* enum dns_class */ |
|
|
|
|
|
enum dns_type { |
|
DNS_T_A = 1, |
|
DNS_T_NS = 2, |
|
DNS_T_CNAME = 5, |
|
DNS_T_SOA = 6, |
|
DNS_T_PTR = 12, |
|
DNS_T_MX = 15, |
|
DNS_T_TXT = 16, |
|
DNS_T_AAAA = 28, |
|
DNS_T_SRV = 33, |
|
DNS_T_OPT = 41, |
|
DNS_T_SSHFP = 44, |
|
DNS_T_SPF = 99, |
|
DNS_T_AXFR = 252, |
|
|
|
DNS_T_ALL = 255 |
|
}; /* enum dns_type */ |
|
|
|
|
|
enum dns_opcode { |
|
DNS_OP_QUERY = 0, |
|
DNS_OP_IQUERY = 1, |
|
DNS_OP_STATUS = 2, |
|
DNS_OP_NOTIFY = 4, |
|
DNS_OP_UPDATE = 5, |
|
}; /* dns_opcode */ |
|
|
|
|
|
enum dns_rcode { |
|
DNS_RC_NOERROR = 0, |
|
DNS_RC_FORMERR = 1, |
|
DNS_RC_SERVFAIL = 2, |
|
DNS_RC_NXDOMAIN = 3, |
|
DNS_RC_NOTIMP = 4, |
|
DNS_RC_REFUSED = 5, |
|
DNS_RC_YXDOMAIN = 6, |
|
DNS_RC_YXRRSET = 7, |
|
DNS_RC_NXRRSET = 8, |
|
DNS_RC_NOTAUTH = 9, |
|
DNS_RC_NOTZONE = 10, |
|
|
|
/* EDNS(0) extended RCODEs */ |
|
DNS_RC_BADVERS = 16, |
|
}; /* dns_rcode */ |
|
|
|
|
|
/* |
|
* NOTE: These string functions need a small buffer in case the literal |
|
* integer value needs to be printed and returned. UNLESS this buffer is |
|
* SPECIFIED, the returned string has ONLY BLOCK SCOPE. |
|
*/ |
|
#define DNS_STRMAXLEN 47 /* "QUESTION|ANSWER|AUTHORITY|ADDITIONAL" */ |
|
|
|
DNS_PUBLIC const char *dns_strsection(enum dns_section, char *); |
|
|
|
DNS_PUBLIC enum dns_section dns_isection(const char *); |
|
|
|
DNS_PUBLIC const char *dns_strclass(enum dns_class, char *); |
|
|
|
DNS_PUBLIC enum dns_class dns_iclass(const char *); |
|
|
|
DNS_PUBLIC const char *dns_strtype(enum dns_type, char *); |
|
|
|
DNS_PUBLIC enum dns_type dns_itype(const char *); |
|
|
|
DNS_PUBLIC const char *dns_stropcode(enum dns_opcode); |
|
|
|
DNS_PUBLIC enum dns_opcode dns_iopcode(const char *); |
|
|
|
DNS_PUBLIC const char *dns_strrcode(enum dns_rcode); |
|
|
|
DNS_PUBLIC enum dns_rcode dns_ircode(const char *); |
|
|
|
|
|
/* |
|
* A T O M I C I N T E R F A C E S |
|
* |
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ |
|
|
|
typedef unsigned long dns_atomic_t; |
|
|
|
typedef unsigned long dns_refcount_t; /* must be same value type as dns_atomic_t */ |
|
|
|
|
|
/* |
|
* C R Y P T O I N T E R F A C E S |
|
* |
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ |
|
|
|
typedef unsigned dns_random_f(void); |
|
|
|
DNS_PUBLIC dns_random_f **dns_random_p(void); |
|
|
|
#define dns_random (*dns_random_p()) /* was extern unsigned (*dns_random)(void) before 20160523 API */ |
|
|
|
|
|
/* |
|
* P A C K E T I N T E R F A C E |
|
* |
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ |
|
|
|
struct dns_header { |
|
unsigned qid:16; |
|
|
|
#if (defined BYTE_ORDER && BYTE_ORDER == BIG_ENDIAN) || (defined __sun && defined _BIG_ENDIAN) |
|
unsigned qr:1; |
|
unsigned opcode:4; |
|
unsigned aa:1; |
|
unsigned tc:1; |
|
unsigned rd:1; |
|
|
|
unsigned ra:1; |
|
unsigned unused:3; |
|
unsigned rcode:4; |
|
#else |
|
unsigned rd:1; |
|
unsigned tc:1; |
|
unsigned aa:1; |
|
unsigned opcode:4; |
|
unsigned qr:1; |
|
|
|
unsigned rcode:4; |
|
unsigned unused:3; |
|
unsigned ra:1; |
|
#endif |
|
|
|
unsigned qdcount:16; |
|
unsigned ancount:16; |
|
unsigned nscount:16; |
|
unsigned arcount:16; |
|
}; /* struct dns_header */ |
|
|
|
#define dns_header(p) (&(p)->header) |
|
|
|
|
|
#ifndef DNS_P_QBUFSIZ |
|
#define DNS_P_QBUFSIZ dns_p_calcsize(256 + 4) |
|
#endif |
|
|
|
#ifndef DNS_P_DICTSIZE |
|
#define DNS_P_DICTSIZE 16 |
|
#endif |
|
|
|
struct dns_packet { |
|
unsigned short dict[DNS_P_DICTSIZE]; |
|
|
|
struct dns_p_memo { |
|
struct dns_s_memo { |
|
unsigned short base, end; |
|
} qd, an, ns, ar; |
|
|
|
struct { |
|
unsigned short p; |
|
unsigned short maxudp; |
|
unsigned ttl; |
|
} opt; |
|
} memo; |
|
|
|
struct { struct dns_packet *cqe_next, *cqe_prev; } cqe; |
|
|
|
size_t size, end; |
|
|
|
int:16; /* tcp padding */ |
|
|
|
DNS_PRAGMA_EXTENSION union { |
|
struct dns_header header; |
|
unsigned char data[1]; |
|
}; |
|
}; /* struct dns_packet */ |
|
|
|
#define dns_p_calcsize(n) (offsetof(struct dns_packet, data) + DNS_PP_MAX(12, (n))) |
|
|
|
#define dns_p_sizeof(P) dns_p_calcsize((P)->end) |
|
|
|
/** takes size of entire packet structure as allocated */ |
|
DNS_PUBLIC struct dns_packet *dns_p_init(struct dns_packet *, size_t); |
|
|
|
/** takes size of maximum desired payload */ |
|
DNS_PUBLIC struct dns_packet *dns_p_make(size_t, int *); |
|
|
|
DNS_PUBLIC int dns_p_grow(struct dns_packet **); |
|
|
|
DNS_PUBLIC struct dns_packet *dns_p_copy(struct dns_packet *, const struct dns_packet *); |
|
|
|
#define dns_p_opcode(P) (dns_header(P)->opcode) |
|
|
|
DNS_PUBLIC enum dns_rcode dns_p_rcode(struct dns_packet *); |
|
|
|
DNS_PUBLIC unsigned dns_p_count(struct dns_packet *, enum dns_section); |
|
|
|
DNS_PUBLIC int dns_p_push(struct dns_packet *, enum dns_section, const void *, size_t, enum dns_type, enum dns_class, unsigned, const void *); |
|
|
|
DNS_PUBLIC void dns_p_dictadd(struct dns_packet *, unsigned short); |
|
|
|
DNS_PUBLIC struct dns_packet *dns_p_merge(struct dns_packet *, enum dns_section, struct dns_packet *, enum dns_section, int *); |
|
|
|
DNS_PUBLIC void dns_p_dump(struct dns_packet *, FILE *); |
|
|
|
DNS_PUBLIC int dns_p_study(struct dns_packet *); |
|
|
|
|
|
/* |
|
* D O M A I N N A M E I N T E R F A C E S |
|
* |
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ |
|
|
|
#define DNS_D_MAXLABEL 63 /* + 1 '\0' */ |
|
#define DNS_D_MAXNAME 255 /* + 1 '\0' */ |
|
|
|
#define DNS_D_ANCHOR 1 /* anchor domain w/ root "." */ |
|
#define DNS_D_CLEAVE 2 /* cleave sub-domain */ |
|
#define DNS_D_TRIM 4 /* remove superfluous dots */ |
|
|
|
DNS_PUBLIC char *dns_d_init(void *, size_t, const void *, size_t, int); |
|
|
|
DNS_PUBLIC size_t dns_d_anchor(void *, size_t, const void *, size_t); |
|
|
|
DNS_PUBLIC size_t dns_d_cleave(void *, size_t, const void *, size_t); |
|
|
|
DNS_PUBLIC size_t dns_d_comp(void *, size_t, const void *, size_t, struct dns_packet *, int *); |
|
|
|
DNS_PUBLIC size_t dns_d_expand(void *, size_t, unsigned short, struct dns_packet *, int *); |
|
|
|
DNS_PUBLIC unsigned short dns_d_skip(unsigned short, struct dns_packet *); |
|
|
|
DNS_PUBLIC int dns_d_push(struct dns_packet *, const void *, size_t); |
|
|
|
DNS_PUBLIC size_t dns_d_cname(void *, size_t, const void *, size_t, struct dns_packet *, int *error); |
|
|
|
|
|
/* |
|
* R E S O U R C E R E C O R D I N T E R F A C E S |
|
* |
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ |
|
|
|
struct dns_rr { |
|
enum dns_section section; |
|
|
|
struct { |
|
unsigned short p; |
|
unsigned short len; |
|
} dn; |
|
|
|
enum dns_type type; |
|
enum dns_class class; |
|
unsigned ttl; |
|
|
|
struct { |
|
unsigned short p; |
|
unsigned short len; |
|
} rd; |
|
}; /* struct dns_rr */ |
|
|
|
|
|
DNS_PUBLIC int dns_rr_copy(struct dns_packet *, struct dns_rr *, struct dns_packet *); |
|
|
|
DNS_PUBLIC int dns_rr_parse(struct dns_rr *, unsigned short, struct dns_packet *); |
|
|
|
DNS_PUBLIC unsigned short dns_rr_skip(unsigned short, struct dns_packet *); |
|
|
|
DNS_PUBLIC int dns_rr_cmp(struct dns_rr *, struct dns_packet *, struct dns_rr *, struct dns_packet *); |
|
|
|
DNS_PUBLIC size_t dns_rr_print(void *, size_t, struct dns_rr *, struct dns_packet *, int *); |
|
|
|
|
|
struct dns_rr_i { |
|
enum dns_section section; |
|
const void *name; |
|
enum dns_type type; |
|
enum dns_class class; |
|
const void *data; |
|
|
|
int follow; |
|
|
|
int (*sort)(struct dns_rr *, struct dns_rr *, struct dns_rr_i *, struct dns_packet *); |
|
unsigned args[2]; |
|
|
|
struct { |
|
unsigned short next; |
|
unsigned short count; |
|
|
|
unsigned exec; |
|
unsigned regs[2]; |
|
} state, saved; |
|
}; /* struct dns_rr_i */ |
|
|
|
DNS_PUBLIC int dns_rr_i_packet(struct dns_rr *, struct dns_rr *, struct dns_rr_i *, struct dns_packet *); |
|
|
|
DNS_PUBLIC int dns_rr_i_order(struct dns_rr *, struct dns_rr *, struct dns_rr_i *, struct dns_packet *); |
|
|
|
DNS_PUBLIC int dns_rr_i_shuffle(struct dns_rr *, struct dns_rr *, struct dns_rr_i *, struct dns_packet *); |
|
|
|
DNS_PUBLIC void dns_rr_i_init(struct dns_rr_i *); |
|
|
|
#define dns_rr_i_save(i) ((i)->saved = (i)->state) |
|
#define dns_rr_i_rewind(i) ((i)->state = (i)->saved) |
|
#define dns_rr_i_count(i) ((i)->state.count) |
|
|
|
DNS_PUBLIC unsigned dns_rr_grep(struct dns_rr *, unsigned, struct dns_rr_i *, struct dns_packet *, int *); |
|
|
|
#define dns_rr_foreach_(rr, P, ...) \ |
|
for (struct dns_rr_i DNS_PP_XPASTE(i, __LINE__) = { __VA_ARGS__ }; dns_rr_grep((rr), 1, &DNS_PP_XPASTE(i, __LINE__), (P), NULL); ) |
|
|
|
#define dns_rr_foreach(...) dns_rr_foreach_(__VA_ARGS__) |
|
|
|
|
|
/* |
|
* A R E S O U R C E R E C O R D |
|
*/ |
|
|
|
struct dns_a { |
|
struct in_addr addr; |
|
}; /* struct dns_a */ |
|
|
|
DNS_PUBLIC int dns_a_parse(struct dns_a *, struct dns_rr *, struct dns_packet *); |
|
|
|
DNS_PUBLIC int dns_a_push(struct dns_packet *, struct dns_a *); |
|
|
|
DNS_PUBLIC int dns_a_cmp(const struct dns_a *, const struct dns_a *); |
|
|
|
DNS_PUBLIC size_t dns_a_print(void *, size_t, struct dns_a *); |
|
|
|
DNS_PUBLIC size_t dns_a_arpa(void *, size_t, const struct dns_a *); |
|
|
|
|
|
/* |
|
* AAAA R E S O U R C E R E C O R D |
|
*/ |
|
|
|
struct dns_aaaa { |
|
struct in6_addr addr; |
|
}; /* struct dns_aaaa */ |
|
|
|
DNS_PUBLIC int dns_aaaa_parse(struct dns_aaaa *, struct dns_rr *, struct dns_packet *); |
|
|
|
DNS_PUBLIC int dns_aaaa_push(struct dns_packet *, struct dns_aaaa *); |
|
|
|
DNS_PUBLIC int dns_aaaa_cmp(const struct dns_aaaa *, const struct dns_aaaa *); |
|
|
|
DNS_PUBLIC size_t dns_aaaa_print(void *, size_t, struct dns_aaaa *); |
|
|
|
DNS_PUBLIC size_t dns_aaaa_arpa(void *, size_t, const struct dns_aaaa *); |
|
|
|
|
|
/* |
|
* MX R E S O U R C E R E C O R D |
|
*/ |
|
|
|
struct dns_mx { |
|
unsigned short preference; |
|
char host[DNS_D_MAXNAME + 1]; |
|
}; /* struct dns_mx */ |
|
|
|
DNS_PUBLIC int dns_mx_parse(struct dns_mx *, struct dns_rr *, struct dns_packet *); |
|
|
|
DNS_PUBLIC int dns_mx_push(struct dns_packet *, struct dns_mx *); |
|
|
|
DNS_PUBLIC int dns_mx_cmp(const struct dns_mx *, const struct dns_mx *); |
|
|
|
DNS_PUBLIC size_t dns_mx_print(void *, size_t, struct dns_mx *); |
|
|
|
DNS_PUBLIC size_t dns_mx_cname(void *, size_t, struct dns_mx *); |
|
|
|
|
|
/* |
|
* NS R E S O U R C E R E C O R D |
|
*/ |
|
|
|
struct dns_ns { |
|
char host[DNS_D_MAXNAME + 1]; |
|
}; /* struct dns_ns */ |
|
|
|
DNS_PUBLIC int dns_ns_parse(struct dns_ns *, struct dns_rr *, struct dns_packet *); |
|
|
|
DNS_PUBLIC int dns_ns_push(struct dns_packet *, struct dns_ns *); |
|
|
|
DNS_PUBLIC int dns_ns_cmp(const struct dns_ns *, const struct dns_ns *); |
|
|
|
DNS_PUBLIC size_t dns_ns_print(void *, size_t, struct dns_ns *); |
|
|
|
DNS_PUBLIC size_t dns_ns_cname(void *, size_t, struct dns_ns *); |
|
|
|
|
|
/* |
|
* CNAME R E S O U R C E R E C O R D |
|
*/ |
|
|
|
struct dns_cname { |
|
char host[DNS_D_MAXNAME + 1]; |
|
}; /* struct dns_cname */ |
|
|
|
DNS_PUBLIC int dns_cname_parse(struct dns_cname *, struct dns_rr *, struct dns_packet *); |
|
|
|
DNS_PUBLIC int dns_cname_push(struct dns_packet *, struct dns_cname *); |
|
|
|
DNS_PUBLIC int dns_cname_cmp(const struct dns_cname *, const struct dns_cname *); |
|
|
|
DNS_PUBLIC size_t dns_cname_print(void *, size_t, struct dns_cname *); |
|
|
|
DNS_PUBLIC size_t dns_cname_cname(void *, size_t, struct dns_cname *); |
|
|
|
|
|
/* |
|
* SOA R E S O U R C E R E C O R D |
|
*/ |
|
|
|
struct dns_soa { |
|
char mname[DNS_D_MAXNAME + 1]; |
|
char rname[DNS_D_MAXNAME + 1]; |
|
unsigned serial, refresh, retry, expire, minimum; |
|
}; /* struct dns_soa */ |
|
|
|
DNS_PUBLIC int dns_soa_parse(struct dns_soa *, struct dns_rr *, struct dns_packet *); |
|
|
|
DNS_PUBLIC int dns_soa_push(struct dns_packet *, struct dns_soa *); |
|
|
|
DNS_PUBLIC int dns_soa_cmp(const struct dns_soa *, const struct dns_soa *); |
|
|
|
DNS_PUBLIC size_t dns_soa_print(void *, size_t, struct dns_soa *); |
|
|
|
|
|
/* |
|
* PTR R E S O U R C E R E C O R D |
|
*/ |
|
|
|
struct dns_ptr { |
|
char host[DNS_D_MAXNAME + 1]; |
|
}; /* struct dns_ptr */ |
|
|
|
DNS_PUBLIC int dns_ptr_parse(struct dns_ptr *, struct dns_rr *, struct dns_packet *); |
|
|
|
DNS_PUBLIC int dns_ptr_push(struct dns_packet *, struct dns_ptr *); |
|
|
|
DNS_PUBLIC int dns_ptr_cmp(const struct dns_ptr *, const struct dns_ptr *); |
|
|
|
DNS_PUBLIC size_t dns_ptr_print(void *, size_t, struct dns_ptr *); |
|
|
|
DNS_PUBLIC size_t dns_ptr_cname(void *, size_t, struct dns_ptr *); |
|
|
|
DNS_PUBLIC size_t dns_ptr_qname(void *, size_t, int, void *); |
|
|
|
|
|
/* |
|
* SRV R E S O U R C E R E C O R D |
|
*/ |
|
|
|
struct dns_srv { |
|
unsigned short priority; |
|
unsigned short weight; |
|
unsigned short port; |
|
char target[DNS_D_MAXNAME + 1]; |
|
}; /* struct dns_srv */ |
|
|
|
DNS_PUBLIC int dns_srv_parse(struct dns_srv *, struct dns_rr *, struct dns_packet *); |
|
|
|
DNS_PUBLIC int dns_srv_push(struct dns_packet *, struct dns_srv *); |
|
|
|
DNS_PUBLIC int dns_srv_cmp(const struct dns_srv *, const struct dns_srv *); |
|
|
|
DNS_PUBLIC size_t dns_srv_print(void *, size_t, struct dns_srv *); |
|
|
|
DNS_PUBLIC size_t dns_srv_cname(void *, size_t, struct dns_srv *); |
|
|
|
|
|
/* |
|
* OPT R E S O U R C E R E C O R D |
|
*/ |
|
|
|
#ifndef DNS_OPT_MINDATA |
|
#define DNS_OPT_MINDATA 256 |
|
#endif |
|
|
|
#define DNS_OPT_DNSSEC 0x8000 |
|
|
|
struct dns_opt { |
|
enum dns_rcode rcode; |
|
unsigned char version; |
|
unsigned short flags; |
|
|
|
union { |
|
unsigned short maxsize; /* deprecated as confusing */ |
|
unsigned short maxudp; /* maximum UDP payload size */ |
|
}; |
|
|
|
size_t size, len; |
|
unsigned char data[DNS_OPT_MINDATA]; |
|
}; /* struct dns_opt */ |
|
|
|
#define DNS_OPT_INIT(opt) { .size = sizeof (*opt) - offsetof(struct dns_opt, data) } |
|
|
|
DNS_PUBLIC struct dns_opt *dns_opt_init(struct dns_opt *, size_t); |
|
|
|
DNS_PUBLIC int dns_opt_parse(struct dns_opt *, struct dns_rr *, struct dns_packet *); |
|
|
|
DNS_PUBLIC int dns_opt_push(struct dns_packet *, struct dns_opt *); |
|
|
|
DNS_PUBLIC int dns_opt_cmp(const struct dns_opt *, const struct dns_opt *); |
|
|
|
DNS_PUBLIC size_t dns_opt_print(void *, size_t, struct dns_opt *); |
|
|
|
DNS_PUBLIC unsigned int dns_opt_ttl(const struct dns_opt *); |
|
|
|
DNS_PUBLIC unsigned short dns_opt_class(const struct dns_opt *); |
|
|
|
DNS_PUBLIC dns_error_t dns_opt_data_push(struct dns_opt *, unsigned char, unsigned short, const void *); |
|
|
|
|
|
/* |
|
* SSHFP R E S O U R C E R E C O R D |
|
*/ |
|
|
|
struct dns_sshfp { |
|
enum dns_sshfp_key { |
|
DNS_SSHFP_RSA = 1, |
|
DNS_SSHFP_DSA = 2, |
|
} algo; |
|
|
|
enum dns_sshfp_digest { |
|
DNS_SSHFP_SHA1 = 1, |
|
} type; |
|
|
|
union { |
|
unsigned char sha1[20]; |
|
} digest; |
|
}; /* struct dns_sshfp */ |
|
|
|
DNS_PUBLIC int dns_sshfp_parse(struct dns_sshfp *, struct dns_rr *, struct dns_packet *); |
|
|
|
DNS_PUBLIC int dns_sshfp_push(struct dns_packet *, struct dns_sshfp *); |
|
|
|
DNS_PUBLIC int dns_sshfp_cmp(const struct dns_sshfp *, const struct dns_sshfp *); |
|
|
|
DNS_PUBLIC size_t dns_sshfp_print(void *, size_t, struct dns_sshfp *); |
|
|
|
|
|
/* |
|
* TXT R E S O U R C E R E C O R D |
|
*/ |
|
|
|
#ifndef DNS_TXT_MINDATA |
|
#define DNS_TXT_MINDATA 1024 |
|
#endif |
|
|
|
struct dns_txt { |
|
size_t size, len; |
|
unsigned char data[DNS_TXT_MINDATA]; |
|
}; /* struct dns_txt */ |
|
|
|
DNS_PUBLIC struct dns_txt *dns_txt_init(struct dns_txt *, size_t); |
|
|
|
DNS_PUBLIC int dns_txt_parse(struct dns_txt *, struct dns_rr *, struct dns_packet *); |
|
|
|
DNS_PUBLIC int dns_txt_push(struct dns_packet *, struct dns_txt *); |
|
|
|
DNS_PUBLIC int dns_txt_cmp(const struct dns_txt *, const struct dns_txt *); |
|
|
|
DNS_PUBLIC size_t dns_txt_print(void *, size_t, struct dns_txt *); |
|
|
|
|
|
/* |
|
* ANY R E S O U R C E R E C O R D |
|
*/ |
|
|
|
union dns_any { |
|
struct dns_a a; |
|
struct dns_aaaa aaaa; |
|
struct dns_mx mx; |
|
struct dns_ns ns; |
|
struct dns_cname cname; |
|
struct dns_soa soa; |
|
struct dns_ptr ptr; |
|
struct dns_srv srv; |
|
struct dns_opt opt; |
|
struct dns_sshfp sshfp; |
|
struct dns_txt txt, spf, rdata; |
|
}; /* union dns_any */ |
|
|
|
#define DNS_ANY_INIT(any) { .rdata = { .size = sizeof *(any) - offsetof(struct dns_txt, data) } } |
|
|
|
DNS_PUBLIC union dns_any *dns_any_init(union dns_any *, size_t); |
|
|
|
DNS_PUBLIC int dns_any_parse(union dns_any *, struct dns_rr *, struct dns_packet *); |
|
|
|
DNS_PUBLIC int dns_any_push(struct dns_packet *, union dns_any *, enum dns_type); |
|
|
|
DNS_PUBLIC int dns_any_cmp(const union dns_any *, enum dns_type, const union dns_any *, enum dns_type); |
|
|
|
DNS_PUBLIC size_t dns_any_print(void *, size_t, union dns_any *, enum dns_type); |
|
|
|
DNS_PUBLIC size_t dns_any_cname(void *, size_t, union dns_any *, enum dns_type); |
|
|
|
|
|
/* |
|
* H O S T S I N T E R F A C E |
|
* |
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ |
|
|
|
struct dns_hosts; |
|
|
|
DNS_PUBLIC struct dns_hosts *dns_hosts_open(int *); |
|
|
|
DNS_PUBLIC void dns_hosts_close(struct dns_hosts *); |
|
|
|
DNS_PUBLIC dns_refcount_t dns_hosts_acquire(struct dns_hosts *); |
|
|
|
DNS_PUBLIC dns_refcount_t dns_hosts_release(struct dns_hosts *); |
|
|
|
DNS_PUBLIC struct dns_hosts *dns_hosts_mortal(struct dns_hosts *); |
|
|
|
DNS_PUBLIC struct dns_hosts *dns_hosts_local(int *); |
|
|
|
DNS_PUBLIC int dns_hosts_loadfile(struct dns_hosts *, FILE *); |
|
|
|
DNS_PUBLIC int dns_hosts_loadpath(struct dns_hosts *, const char *); |
|
|
|
DNS_PUBLIC int dns_hosts_dump(struct dns_hosts *, FILE *); |
|
|
|
DNS_PUBLIC int dns_hosts_insert(struct dns_hosts *, int, const void *, const void *, _Bool); |
|
|
|
DNS_PUBLIC struct dns_packet *dns_hosts_query(struct dns_hosts *, struct dns_packet *, int *); |
|
|
|
|
|
/* |
|
* R E S O L V . C O N F I N T E R F A C E |
|
* |
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ |
|
|
|
struct dns_resolv_conf { |
|
struct sockaddr_storage nameserver[3]; |
|
|
|
char search[4][DNS_D_MAXNAME + 1]; |
|
|
|
/* (f)ile, (b)ind, (c)ache */ |
|
char lookup[4 * (1 + (4 * 2))]; |
|
|
|
/* getaddrinfo family by preference order ("inet4", "inet6") */ |
|
int family[3]; |
|
|
|
struct { |
|
_Bool edns0; |
|
|
|
unsigned ndots; |
|
|
|
unsigned timeout; |
|
|
|
unsigned attempts; |
|
|
|
_Bool rotate; |
|
|
|
_Bool recurse; |
|
|
|
_Bool smart; |
|
|
|
enum { |
|
DNS_RESCONF_TCP_ENABLE, |
|
DNS_RESCONF_TCP_ONLY, |
|
DNS_RESCONF_TCP_SOCKS, |
|
DNS_RESCONF_TCP_DISABLE, |
|
} tcp; |
|
} options; |
|
|
|
struct sockaddr_storage iface; |
|
|
|
struct { /* PRIVATE */ |
|
dns_atomic_t refcount; |
|
} _; |
|
}; /* struct dns_resolv_conf */ |
|
|
|
DNS_PUBLIC struct dns_resolv_conf *dns_resconf_open(int *); |
|
|
|
DNS_PUBLIC void dns_resconf_close(struct dns_resolv_conf *); |
|
|
|
DNS_PUBLIC dns_refcount_t dns_resconf_acquire(struct dns_resolv_conf *); |
|
|
|
DNS_PUBLIC dns_refcount_t dns_resconf_release(struct dns_resolv_conf *); |
|
|
|
DNS_PUBLIC struct dns_resolv_conf *dns_resconf_mortal(struct dns_resolv_conf *); |
|
|
|
DNS_PUBLIC struct dns_resolv_conf *dns_resconf_local(int *); |
|
|
|
DNS_PUBLIC struct dns_resolv_conf *dns_resconf_root(int *); |
|
|
|
DNS_PUBLIC int dns_resconf_pton(struct sockaddr_storage *, const char *); |
|
|
|
DNS_PUBLIC int dns_resconf_loadfile(struct dns_resolv_conf *, FILE *); |
|
|
|
DNS_PUBLIC int dns_resconf_loadpath(struct dns_resolv_conf *, const char *); |
|
|
|
DNS_PUBLIC int dns_nssconf_loadfile(struct dns_resolv_conf *, FILE *); |
|
|
|
DNS_PUBLIC int dns_nssconf_loadpath(struct dns_resolv_conf *, const char *); |
|
|
|
DNS_PUBLIC int dns_resconf_dump(struct dns_resolv_conf *, FILE *); |
|
|
|
DNS_PUBLIC int dns_nssconf_dump(struct dns_resolv_conf *, FILE *); |
|
|
|
DNS_PUBLIC int dns_resconf_setiface(struct dns_resolv_conf *, const char *, unsigned short); |
|
|
|
typedef unsigned long dns_resconf_i_t; |
|
|
|
DNS_PUBLIC size_t dns_resconf_search(void *, size_t, const void *, size_t, struct dns_resolv_conf *, dns_resconf_i_t *); |
|
|
|
|
|
/* |
|
* H I N T S E R V E R I N T E R F A C E |
|
* |
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ |
|
|
|
struct dns_hints; |
|
|
|
DNS_PUBLIC struct dns_hints *dns_hints_open(struct dns_resolv_conf *, int *); |
|
|
|
DNS_PUBLIC void dns_hints_close(struct dns_hints *); |
|
|
|
DNS_PUBLIC dns_refcount_t dns_hints_acquire(struct dns_hints *); |
|
|
|
DNS_PUBLIC dns_refcount_t dns_hints_release(struct dns_hints *); |
|
|
|
DNS_PUBLIC struct dns_hints *dns_hints_mortal(struct dns_hints *); |
|
|
|
DNS_PUBLIC int dns_hints_insert(struct dns_hints *, const char *, const struct sockaddr *, unsigned); |
|
|
|
DNS_PUBLIC unsigned dns_hints_insert_resconf(struct dns_hints *, const char *, const struct dns_resolv_conf *, int *); |
|
|
|
DNS_PUBLIC struct dns_hints *dns_hints_local(struct dns_resolv_conf *, int *); |
|
|
|
DNS_PUBLIC struct dns_hints *dns_hints_root(struct dns_resolv_conf *, int *); |
|
|
|
DNS_PUBLIC struct dns_packet *dns_hints_query(struct dns_hints *, struct dns_packet *, int *); |
|
|
|
DNS_PUBLIC int dns_hints_dump(struct dns_hints *, FILE *); |
|
|
|
|
|
struct dns_hints_i { |
|
const char *zone; |
|
|
|
struct { |
|
unsigned next; |
|
unsigned seed; |
|
} state; |
|
}; /* struct dns_hints_i */ |
|
|
|
|
|
DNS_PUBLIC unsigned dns_hints_grep(struct sockaddr **, socklen_t *, unsigned, struct dns_hints_i *, struct dns_hints *); |
|
|
|
|
|
/* |
|
* C A C H E I N T E R F A C E |
|
* |
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ |
|
|
|
struct dns_cache { |
|
void *state; |
|
|
|
dns_refcount_t (*acquire)(struct dns_cache *); |
|
dns_refcount_t (*release)(struct dns_cache *); |
|
|
|
struct dns_packet *(*query)(struct dns_packet *, struct dns_cache *, int *); |
|
|
|
int (*submit)(struct dns_packet *, struct dns_cache *); |
|
int (*check)(struct dns_cache *); |
|
struct dns_packet *(*fetch)(struct dns_cache *, int *); |
|
|
|
int (*pollfd)(struct dns_cache *); |
|
short (*events)(struct dns_cache *); |
|
void (*clear)(struct dns_cache *); |
|
|
|
union { |
|
long i; |
|
void *p; |
|
} arg[3]; |
|
|
|
struct { /* PRIVATE */ |
|
dns_atomic_t refcount; |
|
} _; |
|
}; /* struct dns_cache */ |
|
|
|
|
|
DNS_PUBLIC struct dns_cache *dns_cache_init(struct dns_cache *); |
|
|
|
DNS_PUBLIC void dns_cache_close(struct dns_cache *); |
|
|
|
|
|
/* |
|
* A P P L I C A T I O N I N T E R F A C E |
|
* |
|
* Options to change the behavior of the API. Applies across all the |
|
* different components. |
|
* |
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ |
|
|
|
#define DNS_OPTS_INITIALIZER_ { 0, 0 }, 0, 0 |
|
#define DNS_OPTS_INITIALIZER { DNS_OPTS_INITIALIZER_ } |
|
|
|
struct dns_options { |
|
/* |
|
* If the callback closes *fd, it must set it to -1. Otherwise, the |
|
* descriptor is queued and lazily closed at object destruction or |
|
* by an explicit call to _clear(). This allows safe use of |
|
* kqueue(2), epoll(2), et al -style persistent events. |
|
*/ |
|
struct { |
|
void *arg; |
|
int (*cb)(int *fd, void *arg); |
|
} closefd; |
|
|
|
/* bitmask for _events() routines */ |
|
enum dns_events { |
|
DNS_SYSPOLL, |
|
DNS_LIBEVENT, |
|
} events; |
|
|
|
/* Use this SOCKS server. */ |
|
const struct sockaddr_storage *socks_host; |
|
|
|
/* Credentials for the SOCKS server (optional). */ |
|
const char *socks_user; |
|
const char *socks_password; |
|
}; /* struct dns_options */ |
|
|
|
|
|
/* |
|
* S T A T S I N T E R F A C E S |
|
* |
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ |
|
|
|
struct dns_stat { |
|
size_t queries; |
|
|
|
struct { |
|
struct { |
|
size_t count, bytes; |
|
} sent, rcvd; |
|
} udp, tcp; |
|
}; /* struct dns_stat */ |
|
|
|
|
|
/* |
|
* S O C K E T I N T E R F A C E |
|
* |
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ |
|
|
|
struct dns_socket; |
|
|
|
DNS_PUBLIC struct dns_socket *dns_so_open(const struct sockaddr *, int, const struct dns_options *, int *error); |
|
|
|
DNS_PUBLIC void dns_so_close(struct dns_socket *); |
|
|
|
DNS_PUBLIC void dns_so_reset(struct dns_socket *); |
|
|
|
DNS_PUBLIC unsigned short dns_so_mkqid(struct dns_socket *so); |
|
|
|
DNS_PUBLIC struct dns_packet *dns_so_query(struct dns_socket *, struct dns_packet *, struct sockaddr *, int *); |
|
|
|
DNS_PUBLIC int dns_so_submit(struct dns_socket *, struct dns_packet *, struct sockaddr *); |
|
|
|
DNS_PUBLIC int dns_so_check(struct dns_socket *); |
|
|
|
DNS_PUBLIC struct dns_packet *dns_so_fetch(struct dns_socket *, int *); |
|
|
|
DNS_PUBLIC time_t dns_so_elapsed(struct dns_socket *); |
|
|
|
DNS_PUBLIC void dns_so_clear(struct dns_socket *); |
|
|
|
DNS_PUBLIC int dns_so_events(struct dns_socket *); |
|
|
|
DNS_PUBLIC int dns_so_pollfd(struct dns_socket *); |
|
|
|
DNS_PUBLIC int dns_so_poll(struct dns_socket *, int); |
|
|
|
DNS_PUBLIC const struct dns_stat *dns_so_stat(struct dns_socket *); |
|
|
|
DNS_PUBLIC struct dns_trace *dns_so_trace(struct dns_socket *); |
|
|
|
DNS_PUBLIC void dns_so_settrace(struct dns_socket *, struct dns_trace *); |
|
|
|
|
|
/* |
|
* R E S O L V E R I N T E R F A C E |
|
* |
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ |
|
|
|
struct dns_resolver; |
|
|
|
DNS_PUBLIC struct dns_resolver *dns_res_open(struct dns_resolv_conf *, struct dns_hosts *hosts, struct dns_hints *, struct dns_cache *, const struct dns_options *, int *); |
|
|
|
DNS_PUBLIC struct dns_resolver *dns_res_stub(const struct dns_options *, int *); |
|
|
|
DNS_PUBLIC void dns_res_reset(struct dns_resolver *); |
|
|
|
DNS_PUBLIC void dns_res_close(struct dns_resolver *); |
|
|
|
DNS_PUBLIC dns_refcount_t dns_res_acquire(struct dns_resolver *); |
|
|
|
DNS_PUBLIC dns_refcount_t dns_res_release(struct dns_resolver *); |
|
|
|
DNS_PUBLIC struct dns_resolver *dns_res_mortal(struct dns_resolver *); |
|
|
|
DNS_PUBLIC int dns_res_submit(struct dns_resolver *, const char *, enum dns_type, enum dns_class); |
|
|
|
DNS_PUBLIC int dns_res_submit2(struct dns_resolver *, const char *, size_t, enum dns_type, enum dns_class); |
|
|
|
DNS_PUBLIC int dns_res_check(struct dns_resolver *); |
|
|
|
DNS_PUBLIC struct dns_packet *dns_res_fetch(struct dns_resolver *, int *); |
|
|
|
DNS_PUBLIC time_t dns_res_elapsed(struct dns_resolver *); |
|
|
|
DNS_PUBLIC void dns_res_clear(struct dns_resolver *); |
|
|
|
DNS_PUBLIC int dns_res_events(struct dns_resolver *); |
|
|
|
DNS_PUBLIC int dns_res_pollfd(struct dns_resolver *); |
|
|
|
DNS_PUBLIC time_t dns_res_timeout(struct dns_resolver *); |
|
|
|
DNS_PUBLIC int dns_res_poll(struct dns_resolver *, int); |
|
|
|
DNS_PUBLIC struct dns_packet *dns_res_query(struct dns_resolver *, const char *, enum dns_type, enum dns_class, int, int *); |
|
|
|
DNS_PUBLIC const struct dns_stat *dns_res_stat(struct dns_resolver *); |
|
|
|
DNS_PUBLIC void dns_res_sethints(struct dns_resolver *, struct dns_hints *); |
|
|
|
DNS_PUBLIC struct dns_trace *dns_res_trace(struct dns_resolver *); |
|
|
|
DNS_PUBLIC void dns_res_settrace(struct dns_resolver *, struct dns_trace *); |
|
|
|
|
|
/* |
|
* A D D R I N F O I N T E R F A C E |
|
* |
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ |
|
|
|
struct dns_addrinfo; |
|
|
|
DNS_PUBLIC struct dns_addrinfo *dns_ai_open(const char *, const char *, enum dns_type, const struct addrinfo *, struct dns_resolver *, int *); |
|
|
|
DNS_PUBLIC void dns_ai_close(struct dns_addrinfo *); |
|
|
|
DNS_PUBLIC int dns_ai_nextent(struct addrinfo **, struct dns_addrinfo *); |
|
|
|
DNS_PUBLIC size_t dns_ai_print(void *, size_t, struct addrinfo *, struct dns_addrinfo *); |
|
|
|
DNS_PUBLIC time_t dns_ai_elapsed(struct dns_addrinfo *); |
|
|
|
DNS_PUBLIC void dns_ai_clear(struct dns_addrinfo *); |
|
|
|
DNS_PUBLIC int dns_ai_events(struct dns_addrinfo *); |
|
|
|
DNS_PUBLIC int dns_ai_pollfd(struct dns_addrinfo *); |
|
|
|
DNS_PUBLIC time_t dns_ai_timeout(struct dns_addrinfo *); |
|
|
|
DNS_PUBLIC int dns_ai_poll(struct dns_addrinfo *, int); |
|
|
|
DNS_PUBLIC const struct dns_stat *dns_ai_stat(struct dns_addrinfo *); |
|
|
|
DNS_PUBLIC struct dns_trace *dns_ai_trace(struct dns_addrinfo *); |
|
|
|
DNS_PUBLIC void dns_ai_settrace(struct dns_addrinfo *, struct dns_trace *); |
|
|
|
|
|
/* |
|
* Q U E R Y T R A C I N G I N T E R F A C E |
|
* |
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ |
|
|
|
#define DNS_TRACE_ID_C(n) UINT64_C(n) |
|
typedef uint64_t dns_trace_id_t; |
|
|
|
#define DNS_TRACE_ABI 0x20160803 |
|
|
|
struct dns_trace_event { |
|
enum { |
|
DNS_TE_RES_SUBMIT = 1, |
|
DNS_TE_RES_FETCH = 99, |
|
|
|
DNS_TE_SO_SUBMIT = 100, |
|
DNS_TE_SO_VERIFY, |
|
DNS_TE_SO_FETCH = 199, |
|
|
|
DNS_TE_SYS_CONNECT = 200, |
|
DNS_TE_SYS_SEND, |
|
DNS_TE_SYS_RECV, |
|
} type; |
|
|
|
size_t size; |
|
dns_trace_id_t id; |
|
struct timespec ts; |
|
int abi; |
|
|
|
union { |
|
struct { |
|
char qname[DNS_D_MAXNAME + 1]; |
|
enum dns_type qtype; |
|
enum dns_class qclass; |
|
int error; |
|
} res_submit; |
|
|
|
struct { |
|
int error; |
|
} res_fetch; |
|
|
|
struct { |
|
struct sockaddr_storage haddr; |
|
char hname[DNS_D_MAXNAME + 1]; |
|
int error; |
|
} so_submit; |
|
|
|
struct { |
|
int error; |
|
} so_verify; |
|
|
|
struct { |
|
int error; |
|
} so_fetch; |
|
|
|
struct { |
|
struct sockaddr_storage src, dst; |
|
int socktype; |
|
dns_error_t error; |
|
} sys_connect, sys_send, sys_recv; |
|
}; |
|
|
|
unsigned char data[]; |
|
}; |
|
|
|
static inline size_t dns_te_datasize(const struct dns_trace_event *te) { |
|
size_t n = offsetof(struct dns_trace_event, data); |
|
return (n <= te->size)? te->size - n : 0; |
|
} |
|
|
|
struct dns_trace; |
|
|
|
DNS_PUBLIC int dns_trace_abi(void); |
|
|
|
DNS_PUBLIC struct dns_trace *dns_trace_open(FILE *, dns_error_t *); |
|
|
|
DNS_PUBLIC void dns_trace_close(struct dns_trace *); |
|
|
|
DNS_PUBLIC dns_refcount_t dns_trace_acquire(struct dns_trace *); |
|
|
|
DNS_PUBLIC dns_refcount_t dns_trace_release(struct dns_trace *); |
|
|
|
DNS_PUBLIC dns_trace_id_t dns_trace_id(struct dns_trace *); |
|
|
|
DNS_PUBLIC dns_trace_id_t dns_trace_setid(struct dns_trace *, dns_trace_id_t); |
|
|
|
DNS_PUBLIC struct dns_trace_event *dns_trace_get(struct dns_trace *, struct dns_trace_event **, dns_error_t *); |
|
|
|
DNS_PUBLIC struct dns_trace_event *dns_trace_tag(struct dns_trace *, struct dns_trace_event *); |
|
|
|
DNS_PUBLIC dns_error_t dns_trace_put(struct dns_trace *, const struct dns_trace_event *, const void *, size_t); |
|
|
|
DNS_PUBLIC dns_error_t dns_trace_dump(struct dns_trace *, FILE *); |
|
|
|
DNS_PUBLIC struct dns_trace_event *dns_trace_fget(struct dns_trace_event **, FILE *, dns_error_t *); |
|
|
|
DNS_PUBLIC dns_error_t dns_trace_fput(const struct dns_trace_event *, const void *, size_t, FILE *); |
|
|
|
|
|
/* |
|
* U T I L I T Y I N T E R F A C E S |
|
* |
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ |
|
|
|
DNS_PUBLIC size_t dns_strlcpy(char *, const char *, size_t); |
|
|
|
DNS_PUBLIC size_t dns_strlcat(char *, const char *, size_t); |
|
|
|
|
|
/* |
|
* M A C R O M A G I C S |
|
* |
|
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ |
|
|
|
#define DNS_PP_MIN(a, b) (((a) < (b))? (a) : (b)) |
|
#define DNS_PP_MAX(a, b) (((a) > (b))? (a) : (b)) |
|
#define DNS_PP_NARG_(a, b, c, d, e, f, g, h, i, j, k, N,...) N |
|
#define DNS_PP_NARG(...) DNS_PP_NARG_(__VA_ARGS__, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0) |
|
#define DNS_PP_CALL(F, ...) F(__VA_ARGS__) |
|
#define DNS_PP_PASTE(x, y) x##y |
|
#define DNS_PP_XPASTE(x, y) DNS_PP_PASTE(x, y) |
|
#define DNS_PP_STRINGIFY_(s) #s |
|
#define DNS_PP_STRINGIFY(s) DNS_PP_STRINGIFY_(s) |
|
#define DNS_PP_D1 0 |
|
#define DNS_PP_D2 1 |
|
#define DNS_PP_D3 2 |
|
#define DNS_PP_D4 3 |
|
#define DNS_PP_D5 4 |
|
#define DNS_PP_D6 5 |
|
#define DNS_PP_D7 6 |
|
#define DNS_PP_D8 7 |
|
#define DNS_PP_D9 8 |
|
#define DNS_PP_D10 9 |
|
#define DNS_PP_D11 10 |
|
#define DNS_PP_DEC(N) DNS_PP_XPASTE(DNS_PP_D, N) |
|
|
|
#endif /* DNS_H */
|
|
|