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