1 /* $OpenBSD: asr_private.h,v 1.24 2014/03/14 11:07:33 eric 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 #ifndef ASRNODEBUG 21 #define DEBUG 22 #endif 23 24 #define QR_MASK (0x1 << 15) 25 #define OPCODE_MASK (0xf << 11) 26 #define AA_MASK (0x1 << 10) 27 #define TC_MASK (0x1 << 9) 28 #define RD_MASK (0x1 << 8) 29 #define RA_MASK (0x1 << 7) 30 #define Z_MASK (0x7 << 4) 31 #define RCODE_MASK (0xf) 32 33 #define OPCODE(v) ((v) & OPCODE_MASK) 34 #define RCODE(v) ((v) & RCODE_MASK) 35 36 37 struct asr_pack { 38 char *buf; 39 size_t len; 40 size_t offset; 41 const char *err; 42 }; 43 44 struct asr_unpack { 45 const char *buf; 46 size_t len; 47 size_t offset; 48 const char *err; 49 }; 50 51 struct asr_dns_header { 52 uint16_t id; 53 uint16_t flags; 54 uint16_t qdcount; 55 uint16_t ancount; 56 uint16_t nscount; 57 uint16_t arcount; 58 }; 59 60 struct asr_dns_query { 61 char q_dname[MAXDNAME]; 62 uint16_t q_type; 63 uint16_t q_class; 64 }; 65 66 struct asr_dns_rr { 67 char rr_dname[MAXDNAME]; 68 uint16_t rr_type; 69 uint16_t rr_class; 70 uint32_t rr_ttl; 71 union { 72 struct { 73 char cname[MAXDNAME]; 74 } cname; 75 struct { 76 uint16_t preference; 77 char exchange[MAXDNAME]; 78 } mx; 79 struct { 80 char nsname[MAXDNAME]; 81 } ns; 82 struct { 83 char ptrname[MAXDNAME]; 84 } ptr; 85 struct { 86 char mname[MAXDNAME]; 87 char rname[MAXDNAME]; 88 uint32_t serial; 89 uint32_t refresh; 90 uint32_t retry; 91 uint32_t expire; 92 uint32_t minimum; 93 } soa; 94 struct { 95 struct in_addr addr; 96 } in_a; 97 struct { 98 struct in6_addr addr6; 99 } in_aaaa; 100 struct { 101 uint16_t rdlen; 102 const void *rdata; 103 } other; 104 } rr; 105 }; 106 107 108 #define ASR_MAXNS 5 109 #define ASR_MAXDB 3 110 #define ASR_MAXDOM 10 111 112 enum async_type { 113 ASR_SEND, 114 ASR_SEARCH, 115 ASR_GETRRSETBYNAME, 116 ASR_GETHOSTBYNAME, 117 ASR_GETHOSTBYADDR, 118 ASR_GETNETBYNAME, 119 ASR_GETNETBYADDR, 120 ASR_GETADDRINFO, 121 ASR_GETNAMEINFO, 122 }; 123 124 #define ASR_DB_FILE 'f' 125 #define ASR_DB_DNS 'b' 126 #define ASR_DB_YP 'y' 127 128 struct asr_ctx { 129 int ac_refcount; 130 int ac_options; 131 int ac_ndots; 132 char *ac_domain; 133 int ac_domcount; 134 char *ac_dom[ASR_MAXDOM]; 135 int ac_dbcount; 136 char ac_db[ASR_MAXDB + 1]; 137 int ac_family[3]; 138 139 char *ac_hostfile; 140 141 int ac_nscount; 142 int ac_nstimeout; 143 int ac_nsretries; 144 struct sockaddr *ac_ns[ASR_MAXNS]; 145 146 }; 147 148 struct asr { 149 char *a_path; 150 time_t a_mtime; 151 time_t a_rtime; 152 struct asr_ctx *a_ctx; 153 }; 154 155 156 #define ASYNC_DOM_FQDN 0x00000001 157 #define ASYNC_DOM_NDOTS 0x00000002 158 #define ASYNC_DOM_DOMAIN 0x00000004 159 #define ASYNC_DOM_ASIS 0x00000008 160 161 #define ASYNC_NODATA 0x00000100 162 #define ASYNC_AGAIN 0x00000200 163 164 #define ASYNC_EXTOBUF 0x00002000 165 166 167 struct async { 168 int (*as_run)(struct async *, struct async_res *); 169 struct asr_ctx *as_ctx; 170 int as_type; 171 int as_state; 172 173 /* cond */ 174 int as_timeout; 175 int as_fd; 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 int flags; 189 uint16_t reqid; 190 int class; 191 int type; 192 char *dname; /* not fqdn! */ 193 int rcode; /* response code */ 194 int ancount; /* answer count */ 195 196 int nsidx; 197 int nsloop; 198 199 /* io buffers for query/response */ 200 unsigned char *obuf; 201 size_t obuflen; 202 size_t obufsize; 203 unsigned char *ibuf; 204 size_t ibuflen; 205 size_t ibufsize; 206 size_t datalen; /* for tcp io */ 207 uint16_t pktlen; 208 } dns; 209 210 struct { 211 int flags; 212 int class; 213 int type; 214 char *name; 215 struct async *subq; 216 int saved_h_errno; 217 } search; 218 219 struct { 220 int flags; 221 int class; 222 int type; 223 char *name; 224 struct async *subq; 225 } rrset; 226 227 struct { 228 char *name; 229 int family; 230 struct async *subq; 231 char addr[16]; 232 int addrlen; 233 int subq_h_errno; 234 } hostnamadr; 235 236 struct { 237 char *name; 238 int family; 239 struct async *subq; 240 in_addr_t addr; 241 } netnamadr; 242 243 struct { 244 char *hostname; 245 char *servname; 246 int port_tcp; 247 int port_udp; 248 union { 249 struct sockaddr sa; 250 struct sockaddr_in sain; 251 struct sockaddr_in6 sain6; 252 } sa; 253 254 struct addrinfo hints; 255 char *fqdn; 256 struct addrinfo *aifirst; 257 struct addrinfo *ailast; 258 struct async *subq; 259 int flags; 260 } ai; 261 262 struct { 263 char *hostname; 264 char *servname; 265 size_t hostnamelen; 266 size_t servnamelen; 267 union { 268 struct sockaddr sa; 269 struct sockaddr_in sain; 270 struct sockaddr_in6 sain6; 271 } sa; 272 int flags; 273 struct async *subq; 274 } ni; 275 #define MAXTOKEN 10 276 } as; 277 278 }; 279 280 #define AS_DB(p) ((p)->as_ctx->ac_db[(p)->as_db_idx - 1]) 281 #define AS_FAMILY(p) ((p)->as_ctx->ac_family[(p)->as_family_idx]) 282 283 enum asr_state { 284 ASR_STATE_INIT, 285 ASR_STATE_NEXT_DOMAIN, 286 ASR_STATE_NEXT_DB, 287 ASR_STATE_SAME_DB, 288 ASR_STATE_NEXT_FAMILY, 289 ASR_STATE_NEXT_NS, 290 ASR_STATE_UDP_SEND, 291 ASR_STATE_UDP_RECV, 292 ASR_STATE_TCP_WRITE, 293 ASR_STATE_TCP_READ, 294 ASR_STATE_PACKET, 295 ASR_STATE_SUBQUERY, 296 ASR_STATE_NOT_FOUND, 297 ASR_STATE_HALT, 298 }; 299 300 301 /* asr_utils.c */ 302 void asr_pack_init(struct asr_pack *, char *, size_t); 303 int asr_pack_header(struct asr_pack *, const struct asr_dns_header *); 304 int asr_pack_query(struct asr_pack *, uint16_t, uint16_t, const char *); 305 void asr_unpack_init(struct asr_unpack *, const char *, size_t); 306 int asr_unpack_header(struct asr_unpack *, struct asr_dns_header *); 307 int asr_unpack_query(struct asr_unpack *, struct asr_dns_query *); 308 int asr_unpack_rr(struct asr_unpack *, struct asr_dns_rr *); 309 int asr_sockaddr_from_str(struct sockaddr *, int, const char *); 310 ssize_t asr_dname_from_fqdn(const char *, char *, size_t); 311 ssize_t asr_addr_as_fqdn(const char *, int, char *, size_t); 312 313 /* asr.c */ 314 struct asr_ctx *asr_use_resolver(struct asr *); 315 void asr_ctx_unref(struct asr_ctx *); 316 struct async *asr_async_new(struct asr_ctx *, int); 317 void asr_async_free(struct async *); 318 size_t asr_make_fqdn(const char *, const char *, char *, size_t); 319 char *asr_strdname(const char *, char *, size_t); 320 int asr_iter_db(struct async *); 321 int asr_parse_namedb_line(FILE *, char **, int); 322 char *asr_hostalias(struct asr_ctx *, const char *, char *, size_t); 323 324 /* *_async.c */ 325 struct async *res_query_async_ctx(const char *, int, int, struct asr_ctx *); 326 struct async *res_search_async_ctx(const char *, int, int, struct asr_ctx *); 327 struct async *gethostbyaddr_async_ctx(const void *, socklen_t, int, 328 struct asr_ctx *); 329 330 #ifdef DEBUG 331 332 #define DPRINT(...) do { if(asr_debug) { \ 333 fprintf(asr_debug, __VA_ARGS__); \ 334 } } while (0) 335 #define DPRINT_PACKET(n, p, s) do { if(asr_debug) { \ 336 fprintf(asr_debug, "----- %s -----\n", n); \ 337 asr_dump_packet(asr_debug, (p), (s)); \ 338 fprintf(asr_debug, "--------------\n"); \ 339 } } while (0) 340 341 const char *asr_querystr(int); 342 const char *asr_statestr(int); 343 const char *asr_transitionstr(int); 344 const char *print_sockaddr(const struct sockaddr *, char *, size_t); 345 void asr_dump_config(FILE *, struct asr *); 346 void asr_dump_packet(FILE *, const void *, size_t); 347 348 extern FILE * asr_debug; 349 350 #else /* DEBUG */ 351 352 #define DPRINT(...) 353 #define DPRINT_PACKET(...) 354 355 #endif /* DEBUG */ 356 357 #define async_set_state(a, s) do { \ 358 DPRINT("asr: [%s@%p] %s -> %s\n", \ 359 asr_querystr((a)->as_type), \ 360 as, \ 361 asr_statestr((a)->as_state), \ 362 asr_statestr((s))); \ 363 (a)->as_state = (s); } while (0) 364