xref: /openbsd-src/lib/libc/asr/asr_private.h (revision ac9b4aacc1da35008afea06a5d23c2f2dea9b93e)
1 /*	$OpenBSD: asr_private.h,v 1.3 2012/07/07 20:41:52 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 #include <stdio.h>
18 
19 #define DEBUG
20 
21 #define QR_MASK		(0x1 << 15)
22 #define OPCODE_MASK	(0xf << 11)
23 #define AA_MASK		(0x1 << 10)
24 #define TC_MASK		(0x1 <<  9)
25 #define RD_MASK		(0x1 <<  8)
26 #define RA_MASK		(0x1 <<  7)
27 #define Z_MASK		(0x7 <<  4)
28 #define RCODE_MASK	(0xf)
29 
30 #define OPCODE(v)	((v) & OPCODE_MASK)
31 #define RCODE(v)	((v) & RCODE_MASK)
32 
33 
34 struct packed {
35 	char		*data;
36 	size_t		 len;
37 	size_t		 offset;
38 	const char	*err;
39 };
40 
41 struct header {
42 	uint16_t	id;
43 	uint16_t	flags;
44 	uint16_t	qdcount;
45 	uint16_t	ancount;
46 	uint16_t	nscount;
47 	uint16_t	arcount;
48 };
49 
50 struct query {
51 	char		q_dname[MAXDNAME];
52 	uint16_t	q_type;
53 	uint16_t	q_class;
54 };
55 
56 struct rr {
57 	char		rr_dname[MAXDNAME];
58 	uint16_t	rr_type;
59 	uint16_t	rr_class;
60 	uint32_t	rr_ttl;
61 	union {
62 		struct {
63 			char	cname[MAXDNAME];
64 		} cname;
65 		struct {
66 			uint16_t	preference;
67 			char		exchange[MAXDNAME];
68 		} mx;
69 		struct {
70 			char	nsname[MAXDNAME];
71 		} ns;
72 		struct {
73 			char	ptrname[MAXDNAME];
74 		} ptr;
75 		struct {
76 			char		mname[MAXDNAME];
77 			char		rname[MAXDNAME];
78 			uint32_t	serial;
79 			uint32_t	refresh;
80 			uint32_t	retry;
81 			uint32_t	expire;
82 			uint32_t	minimum;
83 		} soa;
84 		struct {
85 			struct in_addr	addr;
86 		} in_a;
87 		struct {
88 			struct in6_addr	addr6;
89 		} in_aaaa;
90 		struct {
91 			uint16_t	 rdlen;
92 			const void	*rdata;
93 		} other;
94 	} rr;
95 };
96 
97 
98 #define ASR_MAXNS	5
99 #define ASR_MAXDB	3
100 #define ASR_MAXDOM	10
101 
102 enum async_type {
103 	ASR_SEND,
104 	ASR_SEARCH,
105 	ASR_GETRRSETBYNAME,
106 	ASR_GETHOSTBYNAME,
107 	ASR_GETHOSTBYADDR,
108 	ASR_GETNETBYNAME,
109 	ASR_GETNETBYADDR,
110 	ASR_GETADDRINFO,
111 	ASR_GETNAMEINFO,
112 	ASR_HOSTADDR,
113 };
114 
115 enum asr_db_type {
116 	ASR_DB_FILE,
117 	ASR_DB_DNS,
118 	ASR_DB_YP,
119 };
120 
121 struct asr_ctx {
122 	int		 ac_refcount;
123 	int		 ac_options;
124 	int		 ac_ndots;
125 	char		*ac_domain;
126 	int		 ac_domcount;
127 	char		*ac_dom[ASR_MAXDOM];
128 	int		 ac_dbcount;
129 	int		 ac_db[ASR_MAXDB];
130 	int		 ac_family[3];
131 
132 	char		*ac_hostfile;
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 	char		*a_path;
143 	time_t		 a_mtime;
144 	time_t		 a_rtime;
145 	struct asr_ctx	*a_ctx;
146 };
147 
148 
149 #define	ASYNC_DOM_FQDN		0x00000001
150 #define	ASYNC_DOM_NDOTS		0x00000002
151 #define	ASYNC_DOM_HOSTALIAS	0x00000004
152 #define	ASYNC_DOM_DOMAIN	0x00000008
153 #define ASYNC_DOM_ASIS		0x00000010
154 
155 #define	ASYNC_NODATA		0x00000100
156 #define	ASYNC_AGAIN		0x00000200
157 
158 #define	ASYNC_EXTIBUF		0x00001000
159 #define	ASYNC_EXTOBUF		0x00002000
160 
161 
162 struct async {
163 	int		(*as_run)(struct async *, struct async_res *);
164 	struct asr_ctx	*as_ctx;
165 	int		 as_type;
166 	int		 as_state;
167 
168 	/* cond */
169 	int		 as_timeout;
170 	int		 as_fd;
171 
172 	/* loop indices in ctx */
173 	int		 as_dom_step;
174 	int		 as_dom_idx;
175 	int		 as_dom_flags;
176 	int		 as_family_idx;
177 	int		 as_db_idx;
178 	int		 as_ns_idx;
179 	int		 as_ns_cycles;
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 			/* io buffers for query/response */
194 			unsigned char	*obuf;
195 			size_t		 obuflen;
196 			size_t		 obufsize;
197 			unsigned char	*ibuf;
198 			size_t		 ibuflen;
199 			size_t		 ibufsize;
200 			size_t		 bufpos;
201 			size_t		 datalen; /* for tcp io */
202 		} dns;
203 
204 		struct {
205 			int		 flags;
206 			int		 class;
207 			int		 type;
208 			char		*name;
209 			struct async	*subq;
210 			int		 saved_h_errno;
211 			unsigned char	*ibuf;
212 			size_t		 ibuflen;
213 			size_t		 ibufsize;
214 		} search;
215 
216 		struct {
217 			int		 flags;
218 			int		 class;
219 			int		 type;
220 			char		*name;
221 			struct async	*subq;
222 		} rrset;
223 
224 		struct {
225 			char		*name;
226 			int		 family;
227 			char		*dname;
228 			struct async	*subq;
229 			char		 addr[16];
230 			int		 addrlen;
231 		} hostnamadr;
232 
233 		struct {
234 			char		*name;
235 			int		 family;
236 			struct async	*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 			struct addrinfo	*aifirst;
253 			struct addrinfo	*ailast;
254 			struct async	*subq;
255 			int		 flags;
256 		} ai;
257 
258 		struct {
259 			char		*hostname;
260 			char		*servname;
261 			size_t		 hostnamelen;
262 			size_t		 servnamelen;
263 			union {
264 				struct sockaddr		sa;
265 				struct sockaddr_in	sain;
266 				struct sockaddr_in6	sain6;
267 			}		 sa;
268 			int		 flags;
269 			struct async	*subq;
270 		} ni;
271 
272 		struct {
273 			char		*name;
274 			int		 family;
275 			int		 aiflags;
276 			union {
277 				struct sockaddr		sa;
278 				struct sockaddr_in	sain;
279 				struct sockaddr_in6	sain6;
280 			}		 sa;
281 
282 			struct async	*subq;
283 			int		 class;
284 			int		 type;
285 			int		 ancount;
286 			unsigned char	*pkt;
287 			size_t		 pktlen;
288 			size_t		 pktpos;
289 			FILE		*file;
290 #define MAXTOKEN 10
291 			char		*tokens[MAXTOKEN];
292 			int		 token_count;
293 			int		 token_idx;
294 		} host;
295 	} as;
296 
297 };
298 
299 #define AS_DB(p) ((p)->as_ctx->ac_db[(p)->as_db_idx - 1])
300 #define AS_FAMILY(p) ((p)->as_ctx->ac_family[(p)->as_family_idx])
301 
302 enum asr_state {
303 	ASR_STATE_INIT,
304 	ASR_STATE_SEARCH_DOMAIN,
305 	ASR_STATE_LOOKUP_DOMAIN,
306 	ASR_STATE_NEXT_DOMAIN,
307 	ASR_STATE_NEXT_DB,
308 	ASR_STATE_SAME_DB,
309 	ASR_STATE_NEXT_FAMILY,
310 	ASR_STATE_LOOKUP_FAMILY,
311 	ASR_STATE_NEXT_NS,
312 	ASR_STATE_READ_RR,
313 	ASR_STATE_READ_FILE,
314 	ASR_STATE_UDP_SEND,
315 	ASR_STATE_UDP_RECV,
316 	ASR_STATE_TCP_WRITE,
317 	ASR_STATE_TCP_READ,
318 	ASR_STATE_PACKET,
319 	ASR_STATE_SUBQUERY,
320 	ASR_STATE_NOT_FOUND,
321 	ASR_STATE_HALT,
322 };
323 
324 
325 /* asr_utils.c */
326 void	packed_init(struct packed*, char*, size_t);
327 int	pack_header(struct packed*, const struct header*);
328 int	pack_query(struct packed*, uint16_t, uint16_t, const char*);
329 int	unpack_header(struct packed*, struct header*);
330 int	unpack_query(struct packed*, struct query*);
331 int	unpack_rr(struct packed*, struct rr*);
332 int	sockaddr_from_str(struct sockaddr *, int, const char *);
333 ssize_t dname_from_fqdn(const char*, char*, size_t);
334 
335 /* asr.c */
336 struct asr_ctx *asr_use_resolver(struct asr *);
337 void asr_ctx_unref(struct asr_ctx *);
338 struct async *async_new(struct asr_ctx *, int);
339 void async_free(struct async *);
340 size_t asr_make_fqdn(const char *, const char *, char *, size_t);
341 size_t asr_domcat(const char *, const char *, char *, size_t);
342 char *asr_strdname(const char *, char *, size_t);
343 int asr_iter_db(struct async *);
344 int asr_iter_ns(struct async *);
345 int asr_iter_domain(struct async *, const char *, char *, size_t);
346 int asr_parse_namedb_line(FILE *, char **, int);
347 
348 /* <*>_async.h */
349 struct async *res_query_async_ctx(const char *, int, int, unsigned char *, int,
350     struct asr_ctx *);
351 struct async *res_search_async_ctx(const char *, int, int, unsigned char *, int,
352     struct asr_ctx *);
353 struct async *gethostbyaddr_async_ctx(const void *, socklen_t, int,
354     struct asr_ctx *);
355 struct async *hostaddr_async_ctx(const char *, int, int, struct asr_ctx *);
356 
357 #ifdef DEBUG
358 
359 extern int asr_debug;
360 
361 /* asr_debug.h */
362 const char *asr_querystr(int);
363 const char *asr_transitionstr(int);
364 void asr_dump(struct asr *);
365 void asr_dump_async(struct async *);
366 void asr_dump_packet(FILE *, const void *, size_t, int);
367 void asr_printf(const char *fmt, ...);
368 void async_set_state(struct async *, int);
369 char *asr_print_addr(const struct sockaddr *, char *, size_t);
370 
371 #else /* DEBUG */
372 
373 #define async_set_state(a, s) do { (a)->as_state = (s); } while (0)
374 
375 #endif /* DEBUG */
376