xref: /openbsd-src/lib/libc/asr/asr_private.h (revision bbd2633af484e00bfb4b6416bd71f10c8f6cc3fb)
1 /*	$OpenBSD: asr_private.h,v 1.40 2016/12/18 01:34:51 krw 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		(0x7 <<  4)
27 #define RCODE_MASK	(0xf)
28 
29 #define OPCODE(v)	((v) & OPCODE_MASK)
30 #define RCODE(v)	((v) & RCODE_MASK)
31 
32 
33 struct asr_pack {
34 	char		*buf;
35 	size_t		 len;
36 	size_t		 offset;
37 	const char	*err;
38 };
39 
40 struct asr_unpack {
41 	const char	*buf;
42 	size_t		 len;
43 	size_t		 offset;
44 	const char	*err;
45 };
46 
47 struct asr_dns_header {
48 	uint16_t	id;
49 	uint16_t	flags;
50 	uint16_t	qdcount;
51 	uint16_t	ancount;
52 	uint16_t	nscount;
53 	uint16_t	arcount;
54 };
55 
56 struct asr_dns_query {
57 	char		q_dname[MAXDNAME];
58 	uint16_t	q_type;
59 	uint16_t	q_class;
60 };
61 
62 struct asr_dns_rr {
63 	char		rr_dname[MAXDNAME];
64 	uint16_t	rr_type;
65 	uint16_t	rr_class;
66 	uint32_t	rr_ttl;
67 	union {
68 		struct {
69 			char	cname[MAXDNAME];
70 		} cname;
71 		struct {
72 			uint16_t	preference;
73 			char		exchange[MAXDNAME];
74 		} mx;
75 		struct {
76 			char	nsname[MAXDNAME];
77 		} ns;
78 		struct {
79 			char	ptrname[MAXDNAME];
80 		} ptr;
81 		struct {
82 			char		mname[MAXDNAME];
83 			char		rname[MAXDNAME];
84 			uint32_t	serial;
85 			uint32_t	refresh;
86 			uint32_t	retry;
87 			uint32_t	expire;
88 			uint32_t	minimum;
89 		} soa;
90 		struct {
91 			struct in_addr	addr;
92 		} in_a;
93 		struct {
94 			struct in6_addr	addr6;
95 		} in_aaaa;
96 		struct {
97 			uint16_t	 rdlen;
98 			const void	*rdata;
99 		} other;
100 	} rr;
101 };
102 
103 
104 #define ASR_MAXNS	5
105 #define ASR_MAXDB	3
106 #define ASR_MAXDOM	10
107 
108 enum async_type {
109 	ASR_SEND,
110 	ASR_SEARCH,
111 	ASR_GETRRSETBYNAME,
112 	ASR_GETHOSTBYNAME,
113 	ASR_GETHOSTBYADDR,
114 	ASR_GETNETBYNAME,
115 	ASR_GETNETBYADDR,
116 	ASR_GETADDRINFO,
117 	ASR_GETNAMEINFO,
118 };
119 
120 #define	ASR_DB_FILE	'f'
121 #define	ASR_DB_DNS	'b'
122 
123 struct 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 
141 struct 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_EXTOBUF		0x00002000
160 
161 #define	ASYNC_NO_INET		0x00010000
162 #define	ASYNC_NO_INET6		0x00020000
163 
164 struct asr_query {
165 	int		(*as_run)(struct asr_query *, struct asr_result *);
166 	struct asr_ctx	*as_ctx;
167 	int		 as_type;
168 	int		 as_state;
169 
170 	/* cond */
171 	int		 as_timeout;
172 	int		 as_fd;
173 
174 	/* loop indices in ctx */
175 	int		 as_dom_step;
176 	int		 as_dom_idx;
177 	int		 as_dom_flags;
178 	int		 as_family_idx;
179 	int		 as_db_idx;
180 
181 	int		 as_count;
182 
183 	union {
184 		struct {
185 			int		 flags;
186 			uint16_t	 reqid;
187 			int		 class;
188 			int		 type;
189 			char		*dname;		/* not fqdn! */
190 			int		 rcode;		/* response code */
191 			int		 ancount;	/* answer count */
192 
193 			int		 nsidx;
194 			int		 nsloop;
195 
196 			/* io buffers for query/response */
197 			unsigned char	*obuf;
198 			size_t		 obuflen;
199 			size_t		 obufsize;
200 			unsigned char	*ibuf;
201 			size_t		 ibuflen;
202 			size_t		 ibufsize;
203 			size_t		 datalen; /* for tcp io */
204 			uint16_t	 pktlen;
205 		} dns;
206 
207 		struct {
208 			int		 flags;
209 			int		 class;
210 			int		 type;
211 			char		*name;
212 			struct asr_query	*subq;
213 			int		 saved_h_errno;
214 		} search;
215 
216 		struct {
217 			int		 flags;
218 			int		 class;
219 			int		 type;
220 			char		*name;
221 			struct asr_query	*subq;
222 		} rrset;
223 
224 		struct {
225 			char		*name;
226 			int		 family;
227 			struct asr_query	*subq;
228 			char		 addr[16];
229 			int		 addrlen;
230 			int		 subq_h_errno;
231 		} hostnamadr;
232 
233 		struct {
234 			char		*name;
235 			int		 family;
236 			struct asr_query	*subq;
237 			in_addr_t	 addr;
238 		} netnamadr;
239 
240 		struct {
241 			char		*hostname;
242 			char		*servname;
243 			int		 port_tcp;
244 			int		 port_udp;
245 			union {
246 				struct sockaddr		sa;
247 				struct sockaddr_in	sain;
248 				struct sockaddr_in6	sain6;
249 			}		 sa;
250 
251 			struct addrinfo	 hints;
252 			char		*fqdn;
253 			struct addrinfo	*aifirst;
254 			struct addrinfo	*ailast;
255 			struct asr_query	*subq;
256 			int		 flags;
257 		} ai;
258 
259 		struct {
260 			char		*hostname;
261 			char		*servname;
262 			size_t		 hostnamelen;
263 			size_t		 servnamelen;
264 			union {
265 				struct sockaddr		sa;
266 				struct sockaddr_in	sain;
267 				struct sockaddr_in6	sain6;
268 			}		 sa;
269 			int		 flags;
270 			struct asr_query	*subq;
271 		} ni;
272 #define MAXTOKEN 10
273 	} as;
274 
275 };
276 
277 #define AS_DB(p) ((p)->as_ctx->ac_db[(p)->as_db_idx - 1])
278 #define AS_FAMILY(p) ((p)->as_ctx->ac_family[(p)->as_family_idx])
279 
280 enum asr_state {
281 	ASR_STATE_INIT,
282 	ASR_STATE_NEXT_DOMAIN,
283 	ASR_STATE_NEXT_DB,
284 	ASR_STATE_SAME_DB,
285 	ASR_STATE_NEXT_FAMILY,
286 	ASR_STATE_NEXT_NS,
287 	ASR_STATE_UDP_SEND,
288 	ASR_STATE_UDP_RECV,
289 	ASR_STATE_TCP_WRITE,
290 	ASR_STATE_TCP_READ,
291 	ASR_STATE_PACKET,
292 	ASR_STATE_SUBQUERY,
293 	ASR_STATE_NOT_FOUND,
294 	ASR_STATE_HALT,
295 };
296 
297 
298 __BEGIN_HIDDEN_DECLS
299 
300 /* asr_utils.c */
301 void _asr_pack_init(struct asr_pack *, char *, size_t);
302 int _asr_pack_header(struct asr_pack *, const struct asr_dns_header *);
303 int _asr_pack_query(struct asr_pack *, uint16_t, uint16_t, const char *);
304 void _asr_unpack_init(struct asr_unpack *, const char *, size_t);
305 int _asr_unpack_header(struct asr_unpack *, struct asr_dns_header *);
306 int _asr_unpack_query(struct asr_unpack *, struct asr_dns_query *);
307 int _asr_unpack_rr(struct asr_unpack *, struct asr_dns_rr *);
308 int _asr_sockaddr_from_str(struct sockaddr *, int, const char *);
309 ssize_t _asr_dname_from_fqdn(const char *, char *, size_t);
310 ssize_t _asr_addr_as_fqdn(const char *, int, char *, size_t);
311 
312 /* asr.c */
313 void _asr_resolver_done(void *);
314 struct asr_ctx *_asr_use_resolver(void *);
315 struct asr_ctx *_asr_no_resolver(void);
316 void _asr_ctx_unref(struct asr_ctx *);
317 struct asr_query *_asr_async_new(struct asr_ctx *, int);
318 void _asr_async_free(struct asr_query *);
319 size_t _asr_make_fqdn(const char *, const char *, char *, size_t);
320 char *_asr_strdname(const char *, char *, size_t);
321 int _asr_iter_db(struct asr_query *);
322 int _asr_parse_namedb_line(FILE *, char **, int, char *, size_t);
323 
324 /* *_async.c */
325 struct asr_query *_res_query_async_ctx(const char *, int, int, struct asr_ctx *);
326 struct asr_query *_res_search_async_ctx(const char *, int, int, struct asr_ctx *);
327 struct asr_query *_gethostbyaddr_async_ctx(const void *, socklen_t, int,
328     struct asr_ctx *);
329 
330 int _asr_iter_domain(struct asr_query *, const char *, char *, size_t);
331 
332 #ifdef DEBUG
333 
334 #define DPRINT(...)		do { if(_asr_debug) {		\
335 		fprintf(_asr_debug, __VA_ARGS__);		\
336 	} } while (0)
337 #define DPRINT_PACKET(n, p, s)	do { if(_asr_debug) {		\
338 		fprintf(_asr_debug, "----- %s -----\n", n);	\
339 		_asr_dump_packet(_asr_debug, (p), (s));		\
340 		fprintf(_asr_debug, "--------------\n");		\
341 	} } while (0)
342 
343 #else /* DEBUG */
344 
345 #define DPRINT(...)
346 #define DPRINT_PACKET(...)
347 
348 #endif /* DEBUG */
349 
350 const char *_asr_querystr(int);
351 const char *_asr_statestr(int);
352 const char *_asr_transitionstr(int);
353 const char *_asr_print_sockaddr(const struct sockaddr *, char *, size_t);
354 void _asr_dump_config(FILE *, struct asr *);
355 void _asr_dump_packet(FILE *, const void *, size_t);
356 
357 extern FILE *_asr_debug;
358 
359 #define async_set_state(a, s) do {		\
360 	DPRINT("asr: [%s@%p] %s -> %s\n",	\
361 		_asr_querystr((a)->as_type),	\
362 		as,				\
363 		_asr_statestr((a)->as_state),	\
364 		_asr_statestr((s)));		\
365 	(a)->as_state = (s); } while (0)
366 
367 __END_HIDDEN_DECLS
368