1/* $OpenBSD: asr_private.h,v 1.49 2023/11/20 12:15:16 florian Exp $ */ 2/* 3 * Copyright (c) 2012 Eric Faurot <eric@openbsd.org> 4 * 5 * Permission to use, copy, modify, and distribute this software for any 6 * purpose with or without fee is hereby granted, provided that the above 7 * copyright notice and this permission notice appear in all copies. 8 * 9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 */ 17 18#include <stdio.h> 19 20#define QR_MASK (0x1 << 15) 21#define OPCODE_MASK (0xf << 11) 22#define AA_MASK (0x1 << 10) 23#define TC_MASK (0x1 << 9) 24#define RD_MASK (0x1 << 8) 25#define RA_MASK (0x1 << 7) 26#define Z_MASK (0x1 << 6) 27#define AD_MASK (0x1 << 5) 28#define CD_MASK (0x1 << 4) 29#define RCODE_MASK (0xf) 30 31#define OPCODE(v) ((v) & OPCODE_MASK) 32#define RCODE(v) ((v) & RCODE_MASK) 33 34 35struct asr_pack { 36 char *buf; 37 size_t len; 38 size_t offset; 39 int err; 40}; 41 42struct asr_unpack { 43 const char *buf; 44 size_t len; 45 size_t offset; 46 int err; 47}; 48 49struct asr_dns_header { 50 uint16_t id; 51 uint16_t flags; 52 uint16_t qdcount; 53 uint16_t ancount; 54 uint16_t nscount; 55 uint16_t arcount; 56}; 57 58struct asr_dns_query { 59 char q_dname[MAXDNAME]; 60 uint16_t q_type; 61 uint16_t q_class; 62}; 63 64struct asr_dns_rr { 65 char rr_dname[MAXDNAME]; 66 uint16_t rr_type; 67 uint16_t rr_class; 68 uint32_t rr_ttl; 69 union { 70 struct { 71 char cname[MAXDNAME]; 72 } cname; 73 struct { 74 uint16_t preference; 75 char exchange[MAXDNAME]; 76 } mx; 77 struct { 78 char nsname[MAXDNAME]; 79 } ns; 80 struct { 81 char ptrname[MAXDNAME]; 82 } ptr; 83 struct { 84 char mname[MAXDNAME]; 85 char rname[MAXDNAME]; 86 uint32_t serial; 87 uint32_t refresh; 88 uint32_t retry; 89 uint32_t expire; 90 uint32_t minimum; 91 } soa; 92 struct { 93 struct in_addr addr; 94 } in_a; 95 struct { 96 struct in6_addr addr6; 97 } in_aaaa; 98 struct { 99 uint16_t rdlen; 100 const void *rdata; 101 } other; 102 } rr; 103}; 104 105 106#define ASR_MAXNS 5 107#define ASR_MAXDB 3 108#define ASR_MAXDOM 10 109 110enum async_type { 111 ASR_SEND, 112 ASR_SEARCH, 113 ASR_GETRRSETBYNAME, 114 ASR_GETHOSTBYNAME, 115 ASR_GETHOSTBYADDR, 116 ASR_GETADDRINFO, 117 ASR_GETNAMEINFO, 118}; 119 120#define ASR_DB_FILE 'f' 121#define ASR_DB_DNS 'b' 122 123struct asr_ctx { 124 int ac_refcount; 125 int ac_options; 126 int ac_ndots; 127 char *ac_domain; 128 int ac_domcount; 129 char *ac_dom[ASR_MAXDOM]; 130 int ac_dbcount; 131 char ac_db[ASR_MAXDB + 1]; 132 int ac_family[3]; 133 134 int ac_nscount; 135 int ac_nstimeout; 136 int ac_nsretries; 137 struct sockaddr *ac_ns[ASR_MAXNS]; 138 139}; 140 141struct asr { 142 pid_t a_pid; 143 time_t a_mtime; 144 time_t a_rtime; 145 struct asr_ctx *a_ctx; 146}; 147 148#define ASYNC_COND 0 149#define ASYNC_DONE 1 150 151#define ASYNC_DOM_FQDN 0x00000001 152#define ASYNC_DOM_NDOTS 0x00000002 153#define ASYNC_DOM_DOMAIN 0x00000004 154#define ASYNC_DOM_ASIS 0x00000008 155 156#define ASYNC_NODATA 0x00000100 157#define ASYNC_AGAIN 0x00000200 158 159#define ASYNC_GETNET 0x00001000 160#define ASYNC_EXTOBUF 0x00002000 161 162#define ASYNC_NO_INET 0x00010000 163#define ASYNC_NO_INET6 0x00020000 164 165struct asr_query { 166 int (*as_run)(struct asr_query *, struct asr_result *); 167 struct asr_ctx *as_ctx; 168 int as_type; 169 int as_flags; 170 int as_state; 171 172 /* cond */ 173 int as_timeout; 174 int as_fd; 175 struct asr_query *as_subq; 176 177 /* loop indices in ctx */ 178 int as_dom_step; 179 int as_dom_idx; 180 int as_dom_flags; 181 int as_family_idx; 182 int as_db_idx; 183 184 int as_count; 185 186 union { 187 struct { 188 uint16_t reqid; 189 int class; 190 int type; 191 char *dname; /* not fqdn! */ 192 int rcode; /* response code */ 193 int ancount; /* answer count */ 194 195 int nsidx; 196 int nsloop; 197 198 /* io buffers for query/response */ 199 unsigned char *obuf; 200 size_t obuflen; 201 size_t obufsize; 202 unsigned char *ibuf; 203 size_t ibuflen; 204 size_t ibufsize; 205 size_t datalen; /* for tcp io */ 206 uint16_t pktlen; 207 } dns; 208 209 struct { 210 int class; 211 int type; 212 char *name; 213 int saved_h_errno; 214 } search; 215 216 struct { 217 int flags; 218 int class; 219 int type; 220 char *name; 221 } rrset; 222 223 struct { 224 char *name; 225 int family; 226 char addr[16]; 227 int addrlen; 228 int subq_h_errno; 229 } hostnamadr; 230 231 struct { 232 char *hostname; 233 char *servname; 234 int port_tcp; 235 int port_udp; 236 union { 237 struct sockaddr sa; 238 struct sockaddr_in sain; 239 struct sockaddr_in6 sain6; 240 } sa; 241 242 struct addrinfo hints; 243 char *fqdn; 244 struct addrinfo *aifirst; 245 struct addrinfo *ailast; 246 } ai; 247 248 struct { 249 char *hostname; 250 char *servname; 251 size_t hostnamelen; 252 size_t servnamelen; 253 union { 254 struct sockaddr sa; 255 struct sockaddr_in sain; 256 struct sockaddr_in6 sain6; 257 } sa; 258 int flags; 259 } ni; 260#define MAXTOKEN 10 261 } as; 262 263}; 264 265#define AS_DB(p) ((p)->as_ctx->ac_db[(p)->as_db_idx - 1]) 266#define AS_FAMILY(p) ((p)->as_ctx->ac_family[(p)->as_family_idx]) 267 268enum asr_state { 269 ASR_STATE_INIT, 270 ASR_STATE_NEXT_DOMAIN, 271 ASR_STATE_NEXT_DB, 272 ASR_STATE_SAME_DB, 273 ASR_STATE_NEXT_FAMILY, 274 ASR_STATE_NEXT_NS, 275 ASR_STATE_UDP_SEND, 276 ASR_STATE_UDP_RECV, 277 ASR_STATE_TCP_WRITE, 278 ASR_STATE_TCP_READ, 279 ASR_STATE_PACKET, 280 ASR_STATE_SUBQUERY, 281 ASR_STATE_NOT_FOUND, 282 ASR_STATE_HALT, 283}; 284 285#define MAXPACKETSZ 4096 286 287__BEGIN_HIDDEN_DECLS 288 289/* asr_utils.c */ 290void _asr_pack_init(struct asr_pack *, char *, size_t); 291int _asr_pack_header(struct asr_pack *, const struct asr_dns_header *); 292int _asr_pack_query(struct asr_pack *, uint16_t, uint16_t, const char *); 293int _asr_pack_edns0(struct asr_pack *, uint16_t, int); 294void _asr_unpack_init(struct asr_unpack *, const char *, size_t); 295int _asr_unpack_header(struct asr_unpack *, struct asr_dns_header *); 296int _asr_unpack_query(struct asr_unpack *, struct asr_dns_query *); 297int _asr_unpack_rr(struct asr_unpack *, struct asr_dns_rr *); 298int _asr_sockaddr_from_str(struct sockaddr *, int, const char *); 299ssize_t _asr_dname_from_fqdn(const char *, char *, size_t); 300ssize_t _asr_addr_as_fqdn(const char *, int, char *, size_t); 301int hnok_lenient(const char *); 302int _asr_is_localhost(const char*); 303 304/* asr.c */ 305void _asr_resolver_done(void *); 306struct asr_ctx *_asr_use_resolver(void *); 307struct asr_ctx *_asr_no_resolver(void); 308void _asr_ctx_unref(struct asr_ctx *); 309struct asr_query *_asr_async_new(struct asr_ctx *, int); 310void _asr_async_free(struct asr_query *); 311size_t _asr_make_fqdn(const char *, const char *, char *, size_t); 312char *_asr_strdname(const char *, char *, size_t); 313int _asr_iter_db(struct asr_query *); 314int _asr_parse_namedb_line(FILE *, char **, int, char *, size_t); 315 316/* *_async.c */ 317struct asr_query *_res_query_async_ctx(const char *, int, int, struct asr_ctx *); 318struct asr_query *_res_search_async_ctx(const char *, int, int, struct asr_ctx *); 319struct asr_query *_gethostbyaddr_async_ctx(const void *, socklen_t, int, 320 struct asr_ctx *); 321 322int _asr_iter_domain(struct asr_query *, const char *, char *, size_t); 323 324#ifdef DEBUG 325 326#define DPRINT(...) do { if(_asr_debug) { \ 327 fprintf(_asr_debug, __VA_ARGS__); \ 328 } } while (0) 329#define DPRINT_PACKET(n, p, s) do { if(_asr_debug) { \ 330 fprintf(_asr_debug, "----- %s -----\n", n); \ 331 _asr_dump_packet(_asr_debug, (p), (s)); \ 332 fprintf(_asr_debug, "--------------\n"); \ 333 } } while (0) 334 335#else /* DEBUG */ 336 337#define DPRINT(...) 338#define DPRINT_PACKET(...) 339 340#endif /* DEBUG */ 341 342const char *_asr_querystr(int); 343const char *_asr_statestr(int); 344const char *_asr_transitionstr(int); 345const char *_asr_print_sockaddr(const struct sockaddr *, char *, size_t); 346void _asr_dump_config(FILE *, struct asr *); 347void _asr_dump_packet(FILE *, const void *, size_t); 348 349extern FILE *_asr_debug; 350 351#define async_set_state(a, s) do { \ 352 DPRINT("asr: [%s@%p] %s -> %s\n", \ 353 _asr_querystr((a)->as_type), \ 354 as, \ 355 _asr_statestr((a)->as_state), \ 356 _asr_statestr((s))); \ 357 (a)->as_state = (s); } while (0) 358 359__END_HIDDEN_DECLS 360