xref: /openbsd-src/lib/libc/asr/asr_private.h (revision 373da8abb60949de81b32d3c8eaecdaabf17bdaa)
1*373da8abSflorian /*	$OpenBSD: asr_private.h,v 1.49 2023/11/20 12:15:16 florian 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 
20b44da627Seric #define QR_MASK		(0x1 << 15)
21b44da627Seric #define OPCODE_MASK	(0xf << 11)
22b44da627Seric #define AA_MASK		(0x1 << 10)
23b44da627Seric #define TC_MASK		(0x1 <<  9)
24b44da627Seric #define RD_MASK		(0x1 <<  8)
25b44da627Seric #define RA_MASK		(0x1 <<  7)
263aff1a83Sjca #define Z_MASK		(0x1 <<  6)
273aff1a83Sjca #define AD_MASK		(0x1 <<  5)
283aff1a83Sjca #define CD_MASK		(0x1 <<  4)
29b44da627Seric #define RCODE_MASK	(0xf)
30b44da627Seric 
31b44da627Seric #define OPCODE(v)	((v) & OPCODE_MASK)
32b44da627Seric #define RCODE(v)	((v) & RCODE_MASK)
33b44da627Seric 
34b44da627Seric 
35f90bf415Seric struct asr_pack {
36975956b6Seric 	char		*buf;
37975956b6Seric 	size_t		 len;
38975956b6Seric 	size_t		 offset;
3992f75510Seric 	int		 err;
40975956b6Seric };
41975956b6Seric 
42f90bf415Seric struct asr_unpack {
43975956b6Seric 	const char	*buf;
44b44da627Seric 	size_t		 len;
45b44da627Seric 	size_t		 offset;
4692f75510Seric 	int		 err;
47b44da627Seric };
48b44da627Seric 
49f90bf415Seric struct asr_dns_header {
50b44da627Seric 	uint16_t	id;
51b44da627Seric 	uint16_t	flags;
52b44da627Seric 	uint16_t	qdcount;
53b44da627Seric 	uint16_t	ancount;
54b44da627Seric 	uint16_t	nscount;
55b44da627Seric 	uint16_t	arcount;
56b44da627Seric };
57b44da627Seric 
58f90bf415Seric struct asr_dns_query {
59b44da627Seric 	char		q_dname[MAXDNAME];
60b44da627Seric 	uint16_t	q_type;
61b44da627Seric 	uint16_t	q_class;
62b44da627Seric };
63b44da627Seric 
64f90bf415Seric struct asr_dns_rr {
65b44da627Seric 	char		rr_dname[MAXDNAME];
66b44da627Seric 	uint16_t	rr_type;
67b44da627Seric 	uint16_t	rr_class;
68b44da627Seric 	uint32_t	rr_ttl;
69b44da627Seric 	union {
70b44da627Seric 		struct {
71b44da627Seric 			char	cname[MAXDNAME];
72b44da627Seric 		} cname;
73b44da627Seric 		struct {
74b44da627Seric 			uint16_t	preference;
75b44da627Seric 			char		exchange[MAXDNAME];
76b44da627Seric 		} mx;
77b44da627Seric 		struct {
78b44da627Seric 			char	nsname[MAXDNAME];
79b44da627Seric 		} ns;
80b44da627Seric 		struct {
81b44da627Seric 			char	ptrname[MAXDNAME];
82b44da627Seric 		} ptr;
83b44da627Seric 		struct {
84b44da627Seric 			char		mname[MAXDNAME];
85b44da627Seric 			char		rname[MAXDNAME];
86b44da627Seric 			uint32_t	serial;
87b44da627Seric 			uint32_t	refresh;
88b44da627Seric 			uint32_t	retry;
89b44da627Seric 			uint32_t	expire;
90b44da627Seric 			uint32_t	minimum;
91b44da627Seric 		} soa;
92b44da627Seric 		struct {
93b44da627Seric 			struct in_addr	addr;
94b44da627Seric 		} in_a;
95b44da627Seric 		struct {
96b44da627Seric 			struct in6_addr	addr6;
97b44da627Seric 		} in_aaaa;
98b44da627Seric 		struct {
99b44da627Seric 			uint16_t	 rdlen;
100b44da627Seric 			const void	*rdata;
101b44da627Seric 		} other;
102b44da627Seric 	} rr;
103b44da627Seric };
104b44da627Seric 
105b44da627Seric 
106b44da627Seric #define ASR_MAXNS	5
107b44da627Seric #define ASR_MAXDB	3
108b44da627Seric #define ASR_MAXDOM	10
109b44da627Seric 
110b44da627Seric enum async_type {
111b44da627Seric 	ASR_SEND,
112b44da627Seric 	ASR_SEARCH,
113b44da627Seric 	ASR_GETRRSETBYNAME,
114b44da627Seric 	ASR_GETHOSTBYNAME,
115b44da627Seric 	ASR_GETHOSTBYADDR,
116b44da627Seric 	ASR_GETADDRINFO,
117b44da627Seric 	ASR_GETNAMEINFO,
118b44da627Seric };
119b44da627Seric 
1201ed934d0Seric #define	ASR_DB_FILE	'f'
1211ed934d0Seric #define	ASR_DB_DNS	'b'
122b44da627Seric 
123b44da627Seric struct asr_ctx {
124b44da627Seric 	int		 ac_refcount;
125b44da627Seric 	int		 ac_options;
126b44da627Seric 	int		 ac_ndots;
127b44da627Seric 	char		*ac_domain;
128b44da627Seric 	int		 ac_domcount;
129b44da627Seric 	char		*ac_dom[ASR_MAXDOM];
130b44da627Seric 	int		 ac_dbcount;
1311ed934d0Seric 	char		 ac_db[ASR_MAXDB + 1];
132b44da627Seric 	int		 ac_family[3];
133b44da627Seric 
134b44da627Seric 	int		 ac_nscount;
135b44da627Seric 	int		 ac_nstimeout;
136b44da627Seric 	int		 ac_nsretries;
137b44da627Seric 	struct sockaddr *ac_ns[ASR_MAXNS];
138b44da627Seric 
139b44da627Seric };
140b44da627Seric 
141b44da627Seric struct asr {
1425aaab171Seric 	pid_t		 a_pid;
143b44da627Seric 	time_t		 a_mtime;
144b44da627Seric 	time_t		 a_rtime;
145b44da627Seric 	struct asr_ctx	*a_ctx;
146b44da627Seric };
147b44da627Seric 
1485be03f8fSeric #define ASYNC_COND		0
1495be03f8fSeric #define ASYNC_DONE		1
150b44da627Seric 
151b44da627Seric #define	ASYNC_DOM_FQDN		0x00000001
152b44da627Seric #define	ASYNC_DOM_NDOTS		0x00000002
1536a7a3d64Seric #define	ASYNC_DOM_DOMAIN	0x00000004
1546a7a3d64Seric #define ASYNC_DOM_ASIS		0x00000008
155b44da627Seric 
156b44da627Seric #define	ASYNC_NODATA		0x00000100
157b44da627Seric #define	ASYNC_AGAIN		0x00000200
158b44da627Seric 
159b5afe704Sschwarze #define	ASYNC_GETNET		0x00001000
160b44da627Seric #define	ASYNC_EXTOBUF		0x00002000
161b44da627Seric 
1628b59b78cSjca #define	ASYNC_NO_INET		0x00010000
1638b59b78cSjca #define	ASYNC_NO_INET6		0x00020000
164b44da627Seric 
1655be03f8fSeric struct asr_query {
1665be03f8fSeric 	int		(*as_run)(struct asr_query *, struct asr_result *);
167b44da627Seric 	struct asr_ctx	*as_ctx;
168b44da627Seric 	int		 as_type;
169abe78e02Sjca 	int		 as_flags;
170b44da627Seric 	int		 as_state;
171b44da627Seric 
172b44da627Seric 	/* cond */
173b44da627Seric 	int		 as_timeout;
174b44da627Seric 	int		 as_fd;
175f6f51dadSeric 	struct asr_query *as_subq;
176b44da627Seric 
177b44da627Seric 	/* loop indices in ctx */
178b44da627Seric 	int		 as_dom_step;
179b44da627Seric 	int		 as_dom_idx;
180b44da627Seric 	int		 as_dom_flags;
181b44da627Seric 	int		 as_family_idx;
182b44da627Seric 	int		 as_db_idx;
183b44da627Seric 
184b44da627Seric 	int		 as_count;
185b44da627Seric 
186b44da627Seric 	union {
187b44da627Seric 		struct {
188b44da627Seric 			uint16_t	 reqid;
189b44da627Seric 			int		 class;
190b44da627Seric 			int		 type;
191b44da627Seric 			char		*dname;		/* not fqdn! */
192b44da627Seric 			int		 rcode;		/* response code */
193b44da627Seric 			int		 ancount;	/* answer count */
194b44da627Seric 
195d3064b1fSeric 			int		 nsidx;
196d3064b1fSeric 			int		 nsloop;
197d3064b1fSeric 
198b44da627Seric 			/* io buffers for query/response */
199b44da627Seric 			unsigned char	*obuf;
200b44da627Seric 			size_t		 obuflen;
201b44da627Seric 			size_t		 obufsize;
202b44da627Seric 			unsigned char	*ibuf;
203b44da627Seric 			size_t		 ibuflen;
204b44da627Seric 			size_t		 ibufsize;
205b44da627Seric 			size_t		 datalen; /* for tcp io */
2067856d263Seric 			uint16_t	 pktlen;
207b44da627Seric 		} dns;
208b44da627Seric 
209b44da627Seric 		struct {
210b44da627Seric 			int		 class;
211b44da627Seric 			int		 type;
212b44da627Seric 			char		*name;
213b44da627Seric 			int		 saved_h_errno;
214b44da627Seric 		} search;
215b44da627Seric 
216b44da627Seric 		struct {
217b44da627Seric 			int		 flags;
218b44da627Seric 			int		 class;
219b44da627Seric 			int		 type;
220b44da627Seric 			char		*name;
221b44da627Seric 		} rrset;
222b44da627Seric 
223b44da627Seric 		struct {
224b44da627Seric 			char		*name;
225b44da627Seric 			int		 family;
226b44da627Seric 			char		 addr[16];
227b44da627Seric 			int		 addrlen;
2287ffb6b35Seric 			int		 subq_h_errno;
229b44da627Seric 		} hostnamadr;
230b44da627Seric 
231b44da627Seric 		struct {
232b44da627Seric 			char		*hostname;
233b44da627Seric 			char		*servname;
234b44da627Seric 			int		 port_tcp;
235b44da627Seric 			int		 port_udp;
236b44da627Seric 			union {
237b44da627Seric 				struct sockaddr		sa;
238b44da627Seric 				struct sockaddr_in	sain;
239b44da627Seric 				struct sockaddr_in6	sain6;
240b44da627Seric 			}		 sa;
241b44da627Seric 
242b44da627Seric 			struct addrinfo	 hints;
243c5c8c49bSeric 			char		*fqdn;
244b44da627Seric 			struct addrinfo	*aifirst;
245b44da627Seric 			struct addrinfo	*ailast;
246b44da627Seric 		} ai;
247b44da627Seric 
248b44da627Seric 		struct {
249b44da627Seric 			char		*hostname;
250b44da627Seric 			char		*servname;
251b44da627Seric 			size_t		 hostnamelen;
252b44da627Seric 			size_t		 servnamelen;
253b44da627Seric 			union {
254b44da627Seric 				struct sockaddr		sa;
255b44da627Seric 				struct sockaddr_in	sain;
256b44da627Seric 				struct sockaddr_in6	sain6;
257b44da627Seric 			}		 sa;
258b44da627Seric 			int		 flags;
259b44da627Seric 		} ni;
260b44da627Seric #define MAXTOKEN 10
261b44da627Seric 	} as;
262b44da627Seric 
263b44da627Seric };
264b44da627Seric 
265b44da627Seric #define AS_DB(p) ((p)->as_ctx->ac_db[(p)->as_db_idx - 1])
266b44da627Seric #define AS_FAMILY(p) ((p)->as_ctx->ac_family[(p)->as_family_idx])
267b44da627Seric 
268b44da627Seric enum asr_state {
269b44da627Seric 	ASR_STATE_INIT,
270b44da627Seric 	ASR_STATE_NEXT_DOMAIN,
271b44da627Seric 	ASR_STATE_NEXT_DB,
272b44da627Seric 	ASR_STATE_SAME_DB,
273b44da627Seric 	ASR_STATE_NEXT_FAMILY,
274b44da627Seric 	ASR_STATE_NEXT_NS,
275b44da627Seric 	ASR_STATE_UDP_SEND,
276b44da627Seric 	ASR_STATE_UDP_RECV,
277b44da627Seric 	ASR_STATE_TCP_WRITE,
278b44da627Seric 	ASR_STATE_TCP_READ,
279b44da627Seric 	ASR_STATE_PACKET,
280b44da627Seric 	ASR_STATE_SUBQUERY,
281b44da627Seric 	ASR_STATE_NOT_FOUND,
282b44da627Seric 	ASR_STATE_HALT,
283b44da627Seric };
284b44da627Seric 
2852aa4cd21Sjca #define MAXPACKETSZ	4096
286b44da627Seric 
287253ef892Sderaadt __BEGIN_HIDDEN_DECLS
288253ef892Sderaadt 
289b44da627Seric /* asr_utils.c */
290253ef892Sderaadt void _asr_pack_init(struct asr_pack *, char *, size_t);
291253ef892Sderaadt int _asr_pack_header(struct asr_pack *, const struct asr_dns_header *);
292253ef892Sderaadt int _asr_pack_query(struct asr_pack *, uint16_t, uint16_t, const char *);
293d4d39a6fSjca int _asr_pack_edns0(struct asr_pack *, uint16_t, int);
294253ef892Sderaadt void _asr_unpack_init(struct asr_unpack *, const char *, size_t);
295253ef892Sderaadt int _asr_unpack_header(struct asr_unpack *, struct asr_dns_header *);
296253ef892Sderaadt int _asr_unpack_query(struct asr_unpack *, struct asr_dns_query *);
297253ef892Sderaadt int _asr_unpack_rr(struct asr_unpack *, struct asr_dns_rr *);
298253ef892Sderaadt int _asr_sockaddr_from_str(struct sockaddr *, int, const char *);
299253ef892Sderaadt ssize_t _asr_dname_from_fqdn(const char *, char *, size_t);
300253ef892Sderaadt ssize_t _asr_addr_as_fqdn(const char *, int, char *, size_t);
3011b04c78cSflorian int hnok_lenient(const char *);
302*373da8abSflorian int _asr_is_localhost(const char*);
303b44da627Seric 
304b44da627Seric /* asr.c */
305253ef892Sderaadt void _asr_resolver_done(void *);
306253ef892Sderaadt struct asr_ctx *_asr_use_resolver(void *);
307656b8d51Sderaadt struct asr_ctx *_asr_no_resolver(void);
308253ef892Sderaadt void _asr_ctx_unref(struct asr_ctx *);
309253ef892Sderaadt struct asr_query *_asr_async_new(struct asr_ctx *, int);
310253ef892Sderaadt void _asr_async_free(struct asr_query *);
311253ef892Sderaadt size_t _asr_make_fqdn(const char *, const char *, char *, size_t);
312253ef892Sderaadt char *_asr_strdname(const char *, char *, size_t);
313253ef892Sderaadt int _asr_iter_db(struct asr_query *);
314253ef892Sderaadt int _asr_parse_namedb_line(FILE *, char **, int, char *, size_t);
315b44da627Seric 
316f90bf415Seric /* *_async.c */
317253ef892Sderaadt struct asr_query *_res_query_async_ctx(const char *, int, int, struct asr_ctx *);
318253ef892Sderaadt struct asr_query *_res_search_async_ctx(const char *, int, int, struct asr_ctx *);
319253ef892Sderaadt struct asr_query *_gethostbyaddr_async_ctx(const void *, socklen_t, int,
320b44da627Seric     struct asr_ctx *);
321b44da627Seric 
322253ef892Sderaadt int _asr_iter_domain(struct asr_query *, const char *, char *, size_t);
323253ef892Sderaadt 
324b44da627Seric #ifdef DEBUG
325b44da627Seric 
32655f55055Seric #define DPRINT(...)		do { if(_asr_debug) {		\
32755f55055Seric 		fprintf(_asr_debug, __VA_ARGS__);		\
32846ab4803Seric 	} } while (0)
32955f55055Seric #define DPRINT_PACKET(n, p, s)	do { if(_asr_debug) {		\
33055f55055Seric 		fprintf(_asr_debug, "----- %s -----\n", n);	\
33155f55055Seric 		_asr_dump_packet(_asr_debug, (p), (s));		\
33255f55055Seric 		fprintf(_asr_debug, "--------------\n");		\
33346ab4803Seric 	} } while (0)
334b44da627Seric 
3358031c0b5Sjca #else /* DEBUG */
3368031c0b5Sjca 
3378031c0b5Sjca #define DPRINT(...)
3388031c0b5Sjca #define DPRINT_PACKET(...)
3398031c0b5Sjca 
3408031c0b5Sjca #endif /* DEBUG */
3418031c0b5Sjca 
342253ef892Sderaadt const char *_asr_querystr(int);
343253ef892Sderaadt const char *_asr_statestr(int);
344253ef892Sderaadt const char *_asr_transitionstr(int);
345253ef892Sderaadt const char *_asr_print_sockaddr(const struct sockaddr *, char *, size_t);
346253ef892Sderaadt void _asr_dump_config(FILE *, struct asr *);
347253ef892Sderaadt void _asr_dump_packet(FILE *, const void *, size_t);
348d4cf23afSeric 
349253ef892Sderaadt extern FILE *_asr_debug;
350b44da627Seric 
351d4cf23afSeric #define async_set_state(a, s) do {		\
352d4cf23afSeric 	DPRINT("asr: [%s@%p] %s -> %s\n",	\
35355f55055Seric 		_asr_querystr((a)->as_type),	\
354d4cf23afSeric 		as,				\
35555f55055Seric 		_asr_statestr((a)->as_state),	\
35655f55055Seric 		_asr_statestr((s)));		\
357d4cf23afSeric 	(a)->as_state = (s); } while (0)
358253ef892Sderaadt 
359253ef892Sderaadt __END_HIDDEN_DECLS
360