xref: /openbsd-src/lib/libc/asr/asr_private.h (revision 1ed934d0d08bf9c3f460e8740d169e7606f8702f)
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