xref: /openbsd-src/lib/libc/asr/asr_private.h (revision 897fc685943471cf985a0fe38ba076ea6fe74fa5)
1 /*	$OpenBSD: asr_private.h,v 1.46 2017/02/27 11:38:08 jca 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 
35 struct asr_pack {
36 	char		*buf;
37 	size_t		 len;
38 	size_t		 offset;
39 	int		 err;
40 };
41 
42 struct asr_unpack {
43 	const char	*buf;
44 	size_t		 len;
45 	size_t		 offset;
46 	int		 err;
47 };
48 
49 struct 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 
58 struct asr_dns_query {
59 	char		q_dname[MAXDNAME];
60 	uint16_t	q_type;
61 	uint16_t	q_class;
62 };
63 
64 struct 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 
110 enum async_type {
111 	ASR_SEND,
112 	ASR_SEARCH,
113 	ASR_GETRRSETBYNAME,
114 	ASR_GETHOSTBYNAME,
115 	ASR_GETHOSTBYADDR,
116 	ASR_GETNETBYNAME,
117 	ASR_GETNETBYADDR,
118 	ASR_GETADDRINFO,
119 	ASR_GETNAMEINFO,
120 };
121 
122 #define	ASR_DB_FILE	'f'
123 #define	ASR_DB_DNS	'b'
124 
125 struct asr_ctx {
126 	int		 ac_refcount;
127 	int		 ac_options;
128 	int		 ac_ndots;
129 	char		*ac_domain;
130 	int		 ac_domcount;
131 	char		*ac_dom[ASR_MAXDOM];
132 	int		 ac_dbcount;
133 	char		 ac_db[ASR_MAXDB + 1];
134 	int		 ac_family[3];
135 
136 	int		 ac_nscount;
137 	int		 ac_nstimeout;
138 	int		 ac_nsretries;
139 	struct sockaddr *ac_ns[ASR_MAXNS];
140 
141 };
142 
143 struct asr {
144 	pid_t		 a_pid;
145 	time_t		 a_mtime;
146 	time_t		 a_rtime;
147 	struct asr_ctx	*a_ctx;
148 };
149 
150 #define ASYNC_COND		0
151 #define ASYNC_DONE		1
152 
153 #define	ASYNC_DOM_FQDN		0x00000001
154 #define	ASYNC_DOM_NDOTS		0x00000002
155 #define	ASYNC_DOM_DOMAIN	0x00000004
156 #define ASYNC_DOM_ASIS		0x00000008
157 
158 #define	ASYNC_NODATA		0x00000100
159 #define	ASYNC_AGAIN		0x00000200
160 
161 #define	ASYNC_EXTOBUF		0x00002000
162 
163 #define	ASYNC_NO_INET		0x00010000
164 #define	ASYNC_NO_INET6		0x00020000
165 
166 struct asr_query {
167 	int		(*as_run)(struct asr_query *, struct asr_result *);
168 	struct asr_ctx	*as_ctx;
169 	int		 as_type;
170 	int		 as_flags;
171 	int		 as_state;
172 
173 	/* cond */
174 	int		 as_timeout;
175 	int		 as_fd;
176 	struct asr_query *as_subq;
177 
178 	/* loop indices in ctx */
179 	int		 as_dom_step;
180 	int		 as_dom_idx;
181 	int		 as_dom_flags;
182 	int		 as_family_idx;
183 	int		 as_db_idx;
184 
185 	int		 as_count;
186 
187 	union {
188 		struct {
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		 class;
212 			int		 type;
213 			char		*name;
214 			int		 saved_h_errno;
215 		} search;
216 
217 		struct {
218 			int		 flags;
219 			int		 class;
220 			int		 type;
221 			char		*name;
222 		} rrset;
223 
224 		struct {
225 			char		*name;
226 			int		 family;
227 			char		 addr[16];
228 			int		 addrlen;
229 			int		 subq_h_errno;
230 		} hostnamadr;
231 
232 		struct {
233 			char		*name;
234 			int		 family;
235 			in_addr_t	 addr;
236 		} netnamadr;
237 
238 		struct {
239 			char		*hostname;
240 			char		*servname;
241 			int		 port_tcp;
242 			int		 port_udp;
243 			union {
244 				struct sockaddr		sa;
245 				struct sockaddr_in	sain;
246 				struct sockaddr_in6	sain6;
247 			}		 sa;
248 
249 			struct addrinfo	 hints;
250 			char		*fqdn;
251 			struct addrinfo	*aifirst;
252 			struct addrinfo	*ailast;
253 		} ai;
254 
255 		struct {
256 			char		*hostname;
257 			char		*servname;
258 			size_t		 hostnamelen;
259 			size_t		 servnamelen;
260 			union {
261 				struct sockaddr		sa;
262 				struct sockaddr_in	sain;
263 				struct sockaddr_in6	sain6;
264 			}		 sa;
265 			int		 flags;
266 		} ni;
267 #define MAXTOKEN 10
268 	} as;
269 
270 };
271 
272 #define AS_DB(p) ((p)->as_ctx->ac_db[(p)->as_db_idx - 1])
273 #define AS_FAMILY(p) ((p)->as_ctx->ac_family[(p)->as_family_idx])
274 
275 enum asr_state {
276 	ASR_STATE_INIT,
277 	ASR_STATE_NEXT_DOMAIN,
278 	ASR_STATE_NEXT_DB,
279 	ASR_STATE_SAME_DB,
280 	ASR_STATE_NEXT_FAMILY,
281 	ASR_STATE_NEXT_NS,
282 	ASR_STATE_UDP_SEND,
283 	ASR_STATE_UDP_RECV,
284 	ASR_STATE_TCP_WRITE,
285 	ASR_STATE_TCP_READ,
286 	ASR_STATE_PACKET,
287 	ASR_STATE_SUBQUERY,
288 	ASR_STATE_NOT_FOUND,
289 	ASR_STATE_HALT,
290 };
291 
292 #define MAXPACKETSZ	4096
293 
294 __BEGIN_HIDDEN_DECLS
295 
296 /* asr_utils.c */
297 void _asr_pack_init(struct asr_pack *, char *, size_t);
298 int _asr_pack_header(struct asr_pack *, const struct asr_dns_header *);
299 int _asr_pack_query(struct asr_pack *, uint16_t, uint16_t, const char *);
300 int _asr_pack_edns0(struct asr_pack *, uint16_t, int);
301 void _asr_unpack_init(struct asr_unpack *, const char *, size_t);
302 int _asr_unpack_header(struct asr_unpack *, struct asr_dns_header *);
303 int _asr_unpack_query(struct asr_unpack *, struct asr_dns_query *);
304 int _asr_unpack_rr(struct asr_unpack *, struct asr_dns_rr *);
305 int _asr_sockaddr_from_str(struct sockaddr *, int, const char *);
306 ssize_t _asr_dname_from_fqdn(const char *, char *, size_t);
307 ssize_t _asr_addr_as_fqdn(const char *, int, char *, size_t);
308 
309 /* asr.c */
310 void _asr_resolver_done(void *);
311 struct asr_ctx *_asr_use_resolver(void *);
312 struct asr_ctx *_asr_no_resolver(void);
313 void _asr_ctx_unref(struct asr_ctx *);
314 struct asr_query *_asr_async_new(struct asr_ctx *, int);
315 void _asr_async_free(struct asr_query *);
316 size_t _asr_make_fqdn(const char *, const char *, char *, size_t);
317 char *_asr_strdname(const char *, char *, size_t);
318 int _asr_iter_db(struct asr_query *);
319 int _asr_parse_namedb_line(FILE *, char **, int, char *, size_t);
320 
321 /* *_async.c */
322 struct asr_query *_res_query_async_ctx(const char *, int, int, struct asr_ctx *);
323 struct asr_query *_res_search_async_ctx(const char *, int, int, struct asr_ctx *);
324 struct asr_query *_gethostbyaddr_async_ctx(const void *, socklen_t, int,
325     struct asr_ctx *);
326 
327 int _asr_iter_domain(struct asr_query *, const char *, char *, size_t);
328 
329 #ifdef DEBUG
330 
331 #define DPRINT(...)		do { if(_asr_debug) {		\
332 		fprintf(_asr_debug, __VA_ARGS__);		\
333 	} } while (0)
334 #define DPRINT_PACKET(n, p, s)	do { if(_asr_debug) {		\
335 		fprintf(_asr_debug, "----- %s -----\n", n);	\
336 		_asr_dump_packet(_asr_debug, (p), (s));		\
337 		fprintf(_asr_debug, "--------------\n");		\
338 	} } while (0)
339 
340 #else /* DEBUG */
341 
342 #define DPRINT(...)
343 #define DPRINT_PACKET(...)
344 
345 #endif /* DEBUG */
346 
347 const char *_asr_querystr(int);
348 const char *_asr_statestr(int);
349 const char *_asr_transitionstr(int);
350 const char *_asr_print_sockaddr(const struct sockaddr *, char *, size_t);
351 void _asr_dump_config(FILE *, struct asr *);
352 void _asr_dump_packet(FILE *, const void *, size_t);
353 
354 extern FILE *_asr_debug;
355 
356 #define async_set_state(a, s) do {		\
357 	DPRINT("asr: [%s@%p] %s -> %s\n",	\
358 		_asr_querystr((a)->as_type),	\
359 		as,				\
360 		_asr_statestr((a)->as_state),	\
361 		_asr_statestr((s)));		\
362 	(a)->as_state = (s); } while (0)
363 
364 __END_HIDDEN_DECLS
365