1*1ed934d0Seric /* $OpenBSD: asr_private.h,v 1.18 2013/05/27 17:31:01 eric Exp $ */ 2b44da627Seric /* 3b44da627Seric * Copyright (c) 2012 Eric Faurot <eric@openbsd.org> 4b44da627Seric * 5b44da627Seric * Permission to use, copy, modify, and distribute this software for any 6b44da627Seric * purpose with or without fee is hereby granted, provided that the above 7b44da627Seric * copyright notice and this permission notice appear in all copies. 8b44da627Seric * 9b44da627Seric * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10b44da627Seric * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11b44da627Seric * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12b44da627Seric * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13b44da627Seric * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14b44da627Seric * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15b44da627Seric * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16b44da627Seric */ 1780f48568Seric 18b44da627Seric #include <stdio.h> 19b44da627Seric 20788d36d7Seric #ifndef ASRNODEBUG 218d9b2fa8Seric #define DEBUG 22788d36d7Seric #endif 238d9b2fa8Seric 24b44da627Seric #define QR_MASK (0x1 << 15) 25b44da627Seric #define OPCODE_MASK (0xf << 11) 26b44da627Seric #define AA_MASK (0x1 << 10) 27b44da627Seric #define TC_MASK (0x1 << 9) 28b44da627Seric #define RD_MASK (0x1 << 8) 29b44da627Seric #define RA_MASK (0x1 << 7) 30b44da627Seric #define Z_MASK (0x7 << 4) 31b44da627Seric #define RCODE_MASK (0xf) 32b44da627Seric 33b44da627Seric #define OPCODE(v) ((v) & OPCODE_MASK) 34b44da627Seric #define RCODE(v) ((v) & RCODE_MASK) 35b44da627Seric 36b44da627Seric 37975956b6Seric struct pack { 38975956b6Seric char *buf; 39975956b6Seric size_t len; 40975956b6Seric size_t offset; 41975956b6Seric const char *err; 42975956b6Seric }; 43975956b6Seric 44975956b6Seric struct unpack { 45975956b6Seric const char *buf; 46b44da627Seric size_t len; 47b44da627Seric size_t offset; 48b44da627Seric const char *err; 49b44da627Seric }; 50b44da627Seric 51b44da627Seric struct header { 52b44da627Seric uint16_t id; 53b44da627Seric uint16_t flags; 54b44da627Seric uint16_t qdcount; 55b44da627Seric uint16_t ancount; 56b44da627Seric uint16_t nscount; 57b44da627Seric uint16_t arcount; 58b44da627Seric }; 59b44da627Seric 60b44da627Seric struct query { 61b44da627Seric char q_dname[MAXDNAME]; 62b44da627Seric uint16_t q_type; 63b44da627Seric uint16_t q_class; 64b44da627Seric }; 65b44da627Seric 66b44da627Seric struct rr { 67b44da627Seric char rr_dname[MAXDNAME]; 68b44da627Seric uint16_t rr_type; 69b44da627Seric uint16_t rr_class; 70b44da627Seric uint32_t rr_ttl; 71b44da627Seric union { 72b44da627Seric struct { 73b44da627Seric char cname[MAXDNAME]; 74b44da627Seric } cname; 75b44da627Seric struct { 76b44da627Seric uint16_t preference; 77b44da627Seric char exchange[MAXDNAME]; 78b44da627Seric } mx; 79b44da627Seric struct { 80b44da627Seric char nsname[MAXDNAME]; 81b44da627Seric } ns; 82b44da627Seric struct { 83b44da627Seric char ptrname[MAXDNAME]; 84b44da627Seric } ptr; 85b44da627Seric struct { 86b44da627Seric char mname[MAXDNAME]; 87b44da627Seric char rname[MAXDNAME]; 88b44da627Seric uint32_t serial; 89b44da627Seric uint32_t refresh; 90b44da627Seric uint32_t retry; 91b44da627Seric uint32_t expire; 92b44da627Seric uint32_t minimum; 93b44da627Seric } soa; 94b44da627Seric struct { 95b44da627Seric struct in_addr addr; 96b44da627Seric } in_a; 97b44da627Seric struct { 98b44da627Seric struct in6_addr addr6; 99b44da627Seric } in_aaaa; 100b44da627Seric struct { 101b44da627Seric uint16_t rdlen; 102b44da627Seric const void *rdata; 103b44da627Seric } other; 104b44da627Seric } rr; 105b44da627Seric }; 106b44da627Seric 107b44da627Seric 108b44da627Seric #define ASR_MAXNS 5 109b44da627Seric #define ASR_MAXDB 3 110b44da627Seric #define ASR_MAXDOM 10 111b44da627Seric 112b44da627Seric enum async_type { 113b44da627Seric ASR_SEND, 114b44da627Seric ASR_SEARCH, 115b44da627Seric ASR_GETRRSETBYNAME, 116b44da627Seric ASR_GETHOSTBYNAME, 117b44da627Seric ASR_GETHOSTBYADDR, 118b44da627Seric ASR_GETNETBYNAME, 119b44da627Seric ASR_GETNETBYADDR, 120b44da627Seric ASR_GETADDRINFO, 121b44da627Seric ASR_GETNAMEINFO, 122b44da627Seric }; 123b44da627Seric 124*1ed934d0Seric #define ASR_DB_FILE 'f' 125*1ed934d0Seric #define ASR_DB_DNS 'b' 126*1ed934d0Seric #define ASR_DB_YP 'y' 127b44da627Seric 128b44da627Seric struct asr_ctx { 129b44da627Seric int ac_refcount; 130b44da627Seric int ac_options; 131b44da627Seric int ac_ndots; 132b44da627Seric char *ac_domain; 133b44da627Seric int ac_domcount; 134b44da627Seric char *ac_dom[ASR_MAXDOM]; 135b44da627Seric int ac_dbcount; 136*1ed934d0Seric char ac_db[ASR_MAXDB + 1]; 137b44da627Seric int ac_family[3]; 138b44da627Seric 139b44da627Seric char *ac_hostfile; 140b44da627Seric 141b44da627Seric int ac_nscount; 142b44da627Seric int ac_nstimeout; 143b44da627Seric int ac_nsretries; 144b44da627Seric struct sockaddr *ac_ns[ASR_MAXNS]; 145b44da627Seric 146b44da627Seric }; 147b44da627Seric 148b44da627Seric struct asr { 149b44da627Seric char *a_path; 150b44da627Seric time_t a_mtime; 151b44da627Seric time_t a_rtime; 152b44da627Seric struct asr_ctx *a_ctx; 153b44da627Seric }; 154b44da627Seric 155b44da627Seric 156b44da627Seric #define ASYNC_DOM_FQDN 0x00000001 157b44da627Seric #define ASYNC_DOM_NDOTS 0x00000002 158b44da627Seric #define ASYNC_DOM_HOSTALIAS 0x00000004 159b44da627Seric #define ASYNC_DOM_DOMAIN 0x00000008 160b44da627Seric #define ASYNC_DOM_ASIS 0x00000010 161b44da627Seric 162b44da627Seric #define ASYNC_NODATA 0x00000100 163b44da627Seric #define ASYNC_AGAIN 0x00000200 164b44da627Seric 165b44da627Seric #define ASYNC_EXTOBUF 0x00002000 166b44da627Seric 167b44da627Seric 168b44da627Seric struct async { 169b44da627Seric int (*as_run)(struct async *, struct async_res *); 170b44da627Seric struct asr_ctx *as_ctx; 171b44da627Seric int as_type; 172b44da627Seric int as_state; 173b44da627Seric 174b44da627Seric /* cond */ 175b44da627Seric int as_timeout; 176b44da627Seric int as_fd; 177b44da627Seric 178b44da627Seric /* loop indices in ctx */ 179b44da627Seric int as_dom_step; 180b44da627Seric int as_dom_idx; 181b44da627Seric int as_dom_flags; 182b44da627Seric int as_family_idx; 183b44da627Seric int as_db_idx; 184b44da627Seric int as_ns_idx; 185b44da627Seric int as_ns_cycles; 186b44da627Seric 187b44da627Seric int as_count; 188b44da627Seric 189b44da627Seric union { 190b44da627Seric struct { 191b44da627Seric int flags; 192b44da627Seric uint16_t reqid; 193b44da627Seric int class; 194b44da627Seric int type; 195b44da627Seric char *dname; /* not fqdn! */ 196b44da627Seric int rcode; /* response code */ 197b44da627Seric int ancount; /* answer count */ 198b44da627Seric 199b44da627Seric /* io buffers for query/response */ 200b44da627Seric unsigned char *obuf; 201b44da627Seric size_t obuflen; 202b44da627Seric size_t obufsize; 203b44da627Seric unsigned char *ibuf; 204b44da627Seric size_t ibuflen; 205b44da627Seric size_t ibufsize; 206b44da627Seric size_t datalen; /* for tcp io */ 2077856d263Seric uint16_t pktlen; 208b44da627Seric } dns; 209b44da627Seric 210b44da627Seric struct { 211b44da627Seric int flags; 212b44da627Seric int class; 213b44da627Seric int type; 214b44da627Seric char *name; 215b44da627Seric struct async *subq; 216b44da627Seric int saved_h_errno; 217b44da627Seric } search; 218b44da627Seric 219b44da627Seric struct { 220b44da627Seric int flags; 221b44da627Seric int class; 222b44da627Seric int type; 223b44da627Seric char *name; 224b44da627Seric struct async *subq; 225b44da627Seric } rrset; 226b44da627Seric 227b44da627Seric struct { 228b44da627Seric char *name; 229b44da627Seric int family; 230b44da627Seric struct async *subq; 231b44da627Seric char addr[16]; 232b44da627Seric int addrlen; 2337ffb6b35Seric int subq_h_errno; 234b44da627Seric } hostnamadr; 235b44da627Seric 236b44da627Seric struct { 237b44da627Seric char *name; 238b44da627Seric int family; 239b44da627Seric struct async *subq; 240b44da627Seric in_addr_t addr; 241b44da627Seric } netnamadr; 242b44da627Seric 243b44da627Seric struct { 244b44da627Seric char *hostname; 245b44da627Seric char *servname; 246b44da627Seric int port_tcp; 247b44da627Seric int port_udp; 248b44da627Seric union { 249b44da627Seric struct sockaddr sa; 250b44da627Seric struct sockaddr_in sain; 251b44da627Seric struct sockaddr_in6 sain6; 252b44da627Seric } sa; 253b44da627Seric 254b44da627Seric struct addrinfo hints; 255c5c8c49bSeric char *fqdn; 256b44da627Seric struct addrinfo *aifirst; 257b44da627Seric struct addrinfo *ailast; 258b44da627Seric struct async *subq; 259b44da627Seric int flags; 260b44da627Seric } ai; 261b44da627Seric 262b44da627Seric struct { 263b44da627Seric char *hostname; 264b44da627Seric char *servname; 265b44da627Seric size_t hostnamelen; 266b44da627Seric size_t servnamelen; 267b44da627Seric union { 268b44da627Seric struct sockaddr sa; 269b44da627Seric struct sockaddr_in sain; 270b44da627Seric struct sockaddr_in6 sain6; 271b44da627Seric } sa; 272b44da627Seric int flags; 273b44da627Seric struct async *subq; 274b44da627Seric } ni; 275b44da627Seric #define MAXTOKEN 10 276b44da627Seric } as; 277b44da627Seric 278b44da627Seric }; 279b44da627Seric 280b44da627Seric #define AS_DB(p) ((p)->as_ctx->ac_db[(p)->as_db_idx - 1]) 281b44da627Seric #define AS_FAMILY(p) ((p)->as_ctx->ac_family[(p)->as_family_idx]) 282b44da627Seric 283b44da627Seric enum asr_state { 284b44da627Seric ASR_STATE_INIT, 285b44da627Seric ASR_STATE_NEXT_DOMAIN, 286b44da627Seric ASR_STATE_NEXT_DB, 287b44da627Seric ASR_STATE_SAME_DB, 288b44da627Seric ASR_STATE_NEXT_FAMILY, 289b44da627Seric ASR_STATE_NEXT_NS, 290b44da627Seric ASR_STATE_UDP_SEND, 291b44da627Seric ASR_STATE_UDP_RECV, 292b44da627Seric ASR_STATE_TCP_WRITE, 293b44da627Seric ASR_STATE_TCP_READ, 294b44da627Seric ASR_STATE_PACKET, 295b44da627Seric ASR_STATE_SUBQUERY, 296b44da627Seric ASR_STATE_NOT_FOUND, 297b44da627Seric ASR_STATE_HALT, 298b44da627Seric }; 299b44da627Seric 300b44da627Seric 301b44da627Seric /* asr_utils.c */ 302975956b6Seric void pack_init(struct pack *, char *, size_t); 303975956b6Seric int pack_header(struct pack *, const struct header *); 304975956b6Seric int pack_query(struct pack *, uint16_t, uint16_t, const char *); 305975956b6Seric 306975956b6Seric void unpack_init(struct unpack *, const char *, size_t); 307975956b6Seric int unpack_header(struct unpack *, struct header *); 308975956b6Seric int unpack_query(struct unpack *, struct query *); 309975956b6Seric int unpack_rr(struct unpack *, struct rr *); 310b44da627Seric int sockaddr_from_str(struct sockaddr *, int, const char *); 311b44da627Seric ssize_t dname_from_fqdn(const char *, char *, size_t); 312b44da627Seric 313b44da627Seric /* asr.c */ 314b44da627Seric struct asr_ctx *asr_use_resolver(struct asr *); 315b44da627Seric void asr_ctx_unref(struct asr_ctx *); 316b44da627Seric struct async *async_new(struct asr_ctx *, int); 317b44da627Seric void async_free(struct async *); 318b44da627Seric size_t asr_make_fqdn(const char *, const char *, char *, size_t); 319b44da627Seric size_t asr_domcat(const char *, const char *, char *, size_t); 320b44da627Seric char *asr_strdname(const char *, char *, size_t); 321b44da627Seric int asr_iter_db(struct async *); 322b44da627Seric int asr_iter_ns(struct async *); 323b44da627Seric int asr_iter_domain(struct async *, const char *, char *, size_t); 324b44da627Seric int asr_parse_namedb_line(FILE *, char **, int); 325b44da627Seric 326b44da627Seric /* <*>_async.h */ 327c5221d45Seric struct async *res_query_async_ctx(const char *, int, int, struct asr_ctx *); 328c5221d45Seric struct async *res_search_async_ctx(const char *, int, int, struct asr_ctx *); 329b44da627Seric struct async *gethostbyaddr_async_ctx(const void *, socklen_t, int, 330b44da627Seric struct asr_ctx *); 331b44da627Seric 332b44da627Seric #ifdef DEBUG 333b44da627Seric 33446ab4803Seric #define DPRINT(...) do { if(asr_debug) { \ 33546ab4803Seric fprintf(asr_debug, __VA_ARGS__); \ 33646ab4803Seric } } while (0) 33746ab4803Seric #define DPRINT_PACKET(n, p, s) do { if(asr_debug) { \ 33846ab4803Seric fprintf(asr_debug, "----- %s -----\n", n); \ 339d4cf23afSeric asr_dump_packet(asr_debug, (p), (s)); \ 34046ab4803Seric fprintf(asr_debug, "--------------\n"); \ 34146ab4803Seric } } while (0) 342b44da627Seric 343b44da627Seric const char *asr_querystr(int); 344d4cf23afSeric const char *asr_statestr(int); 345b44da627Seric const char *asr_transitionstr(int); 346d4cf23afSeric const char *print_sockaddr(const struct sockaddr *, char *, size_t); 347d4cf23afSeric void asr_dump_config(FILE *, struct asr *); 348d4cf23afSeric void asr_dump_packet(FILE *, const void *, size_t); 349d4cf23afSeric 350d4cf23afSeric extern FILE * asr_debug; 351b44da627Seric 352b44da627Seric #else /* DEBUG */ 353b44da627Seric 35446ab4803Seric #define DPRINT(...) 35546ab4803Seric #define DPRINT_PACKET(...) 35646ab4803Seric 357b44da627Seric #endif /* DEBUG */ 358d4cf23afSeric 359d4cf23afSeric #define async_set_state(a, s) do { \ 360d4cf23afSeric DPRINT("asr: [%s@%p] %s -> %s\n", \ 361d4cf23afSeric asr_querystr((a)->as_type), \ 362d4cf23afSeric as, \ 363d4cf23afSeric asr_statestr((a)->as_state), \ 364d4cf23afSeric asr_statestr((s))); \ 365d4cf23afSeric (a)->as_state = (s); } while (0) 366