xref: /netbsd-src/external/mpl/bind/dist/bin/tests/system/pipelined/pipequeries.c (revision 33881f779a77dce6440bdc44610d94de75bebefe)
1 /*	$NetBSD: pipequeries.c,v 1.3 2019/01/09 16:55:03 christos Exp $	*/
2 
3 /*
4  * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
5  *
6  * This Source Code Form is subject to the terms of the Mozilla Public
7  * License, v. 2.0. If a copy of the MPL was not distributed with this
8  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9  *
10  * See the COPYRIGHT file distributed with this work for additional
11  * information regarding copyright ownership.
12  */
13 
14 #include <config.h>
15 
16 #include <inttypes.h>
17 #include <stdbool.h>
18 #include <stdlib.h>
19 #include <string.h>
20 #include <unistd.h>
21 
22 #include <isc/app.h>
23 #include <isc/base64.h>
24 #include <isc/commandline.h>
25 #include <isc/hash.h>
26 #include <isc/log.h>
27 #include <isc/mem.h>
28 #include <isc/net.h>
29 #include <isc/parseint.h>
30 #include <isc/platform.h>
31 #include <isc/print.h>
32 #include <isc/sockaddr.h>
33 #include <isc/socket.h>
34 #include <isc/task.h>
35 #include <isc/timer.h>
36 #include <isc/util.h>
37 
38 #include <dns/dispatch.h>
39 #include <dns/fixedname.h>
40 #include <dns/message.h>
41 #include <dns/name.h>
42 #include <dns/request.h>
43 #include <dns/result.h>
44 #include <dns/view.h>
45 
46 #include <dns/events.h>
47 #include <dns/rdataset.h>
48 #include <dns/resolver.h>
49 #include <dns/types.h>
50 
51 #include <dst/result.h>
52 
53 #define CHECK(str, x) { \
54 	if ((x) != ISC_R_SUCCESS) { \
55 		fprintf(stderr, "I:%s: %s\n", (str), isc_result_totext(x)); \
56 		exit(-1); \
57 	} \
58 }
59 
60 #define RUNCHECK(x) RUNTIME_CHECK((x) == ISC_R_SUCCESS)
61 
62 #define PORT 5300
63 #define TIMEOUT 30
64 
65 static isc_mem_t *mctx;
66 static dns_requestmgr_t *requestmgr;
67 static bool have_src = false;
68 static isc_sockaddr_t srcaddr;
69 static isc_sockaddr_t dstaddr;
70 static int onfly;
71 
72 static void
73 recvresponse(isc_task_t *task, isc_event_t *event) {
74 	dns_requestevent_t *reqev = (dns_requestevent_t *)event;
75 	isc_result_t result;
76 	dns_message_t *query, *response;
77 	isc_buffer_t outbuf;
78 	char output[1024];
79 
80 	UNUSED(task);
81 
82 	REQUIRE(reqev != NULL);
83 
84 	if (reqev->result != ISC_R_SUCCESS) {
85 		fprintf(stderr, "I:request event result: %s\n",
86 			isc_result_totext(reqev->result));
87 		exit(-1);
88 	}
89 
90 	query = reqev->ev_arg;
91 
92 	response = NULL;
93 	result = dns_message_create(mctx, DNS_MESSAGE_INTENTPARSE, &response);
94 	CHECK("dns_message_create", result);
95 
96 	result = dns_request_getresponse(reqev->request, response,
97 					 DNS_MESSAGEPARSE_PRESERVEORDER);
98 	CHECK("dns_request_getresponse", result);
99 
100 	if (response->rcode != dns_rcode_noerror) {
101 		result = ISC_RESULTCLASS_DNSRCODE + response->rcode;
102 		fprintf(stderr, "I:response rcode: %s\n",
103 			isc_result_totext(result));
104 			exit(-1);
105 	}
106 	if (response->counts[DNS_SECTION_ANSWER] != 1U) {
107 		fprintf(stderr, "I:response answer count (%u!=1)\n",
108 			response->counts[DNS_SECTION_ANSWER]);
109 	}
110 
111 	isc_buffer_init(&outbuf, output, sizeof(output));
112 	result = dns_message_sectiontotext(response, DNS_SECTION_ANSWER,
113 					   &dns_master_style_simple,
114 					   DNS_MESSAGETEXTFLAG_NOCOMMENTS,
115 					   &outbuf);
116 	CHECK("dns_message_sectiontotext", result);
117 	printf("%.*s", (int)isc_buffer_usedlength(&outbuf),
118 	       (char *)isc_buffer_base(&outbuf));
119 	fflush(stdout);
120 
121 	dns_message_destroy(&query);
122 	dns_message_destroy(&response);
123 	dns_request_destroy(&reqev->request);
124 	isc_event_free(&event);
125 
126 	if (--onfly == 0)
127 		isc_app_shutdown();
128 	return;
129 }
130 
131 static isc_result_t
132 sendquery(isc_task_t *task) {
133 	dns_request_t *request;
134 	dns_message_t *message;
135 	dns_name_t *qname;
136 	dns_rdataset_t *qrdataset;
137 	isc_result_t result;
138 	dns_fixedname_t queryname;
139 	isc_buffer_t buf;
140 	static char host[256];
141 	int c;
142 
143 	c = scanf("%255s", host);
144 	if (c == EOF)
145 		return ISC_R_NOMORE;
146 
147 	onfly++;
148 
149 	dns_fixedname_init(&queryname);
150 	isc_buffer_init(&buf, host, strlen(host));
151 	isc_buffer_add(&buf, strlen(host));
152 	result = dns_name_fromtext(dns_fixedname_name(&queryname), &buf,
153 				   dns_rootname, 0, NULL);
154 	CHECK("dns_name_fromtext", result);
155 
156 	message = NULL;
157 	result = dns_message_create(mctx, DNS_MESSAGE_INTENTRENDER, &message);
158 	CHECK("dns_message_create", result);
159 
160 	message->opcode = dns_opcode_query;
161 	message->flags |= DNS_MESSAGEFLAG_RD;
162 	message->rdclass = dns_rdataclass_in;
163 	message->id = (unsigned short)(random() & 0xFFFF);
164 
165 	qname = NULL;
166 	result = dns_message_gettempname(message, &qname);
167 	CHECK("dns_message_gettempname", result);
168 
169 	qrdataset = NULL;
170 	result = dns_message_gettemprdataset(message, &qrdataset);
171 	CHECK("dns_message_gettemprdataset", result);
172 
173 	dns_name_init(qname, NULL);
174 	dns_name_clone(dns_fixedname_name(&queryname), qname);
175 	dns_rdataset_makequestion(qrdataset, dns_rdataclass_in,
176 				  dns_rdatatype_a);
177 	ISC_LIST_APPEND(qname->list, qrdataset, link);
178 	dns_message_addname(message, qname, DNS_SECTION_QUESTION);
179 
180 	request = NULL;
181 	result = dns_request_createvia(requestmgr, message,
182 				       have_src ? &srcaddr : NULL, &dstaddr,
183 				       -1,
184 				       DNS_REQUESTOPT_TCP |
185 				       DNS_REQUESTOPT_SHARE,
186 				       NULL, TIMEOUT, 0, 0, task, recvresponse,
187 				       message, &request);
188 	CHECK("dns_request_create", result);
189 
190 	return ISC_R_SUCCESS;
191 }
192 
193 static void
194 sendqueries(isc_task_t *task, isc_event_t *event) {
195 	isc_result_t result;
196 
197 	isc_event_free(&event);
198 
199 	do {
200 		result = sendquery(task);
201 	} while (result == ISC_R_SUCCESS);
202 
203 	if (onfly == 0)
204 		isc_app_shutdown();
205 	return;
206 }
207 
208 int
209 main(int argc, char *argv[]) {
210 	isc_sockaddr_t bind_any;
211 	struct in_addr inaddr;
212 	isc_result_t result;
213 	isc_log_t *lctx;
214 	isc_logconfig_t *lcfg;
215 	isc_taskmgr_t *taskmgr;
216 	isc_task_t *task;
217 	isc_timermgr_t *timermgr;
218 	isc_socketmgr_t *socketmgr;
219 	dns_dispatchmgr_t *dispatchmgr;
220 	unsigned int attrs, attrmask;
221 	dns_dispatch_t *dispatchv4;
222 	dns_view_t *view;
223 	uint16_t port = PORT;
224 	int c;
225 
226 	RUNCHECK(isc_app_start());
227 
228 	isc_commandline_errprint = false;
229 	while ((c = isc_commandline_parse(argc, argv, "p:r:")) != -1) {
230 		switch (c) {
231 		case 'p':
232 			result = isc_parse_uint16(&port,
233 						  isc_commandline_argument, 10);
234 			if (result != ISC_R_SUCCESS) {
235 				fprintf(stderr, "bad port '%s'\n",
236 					isc_commandline_argument);
237 				exit(1);
238 			}
239 			break;
240 		case 'r':
241 			fprintf(stderr, "The -r option has been deprecated.\n");
242 			break;
243 		case '?':
244 			fprintf(stderr, "%s: invalid argument '%c'",
245 				argv[0], c);
246 			break;
247 		default:
248 			break;
249 		}
250 	}
251 
252 	argc -= isc_commandline_index;
253 	argv += isc_commandline_index;
254 	POST(argv);
255 
256 	if (argc > 0) {
257 		have_src = true;
258 	}
259 
260 	dns_result_register();
261 
262 	isc_sockaddr_any(&bind_any);
263 
264 	result = ISC_R_FAILURE;
265 	if (inet_pton(AF_INET, "10.53.0.7", &inaddr) != 1)
266 		CHECK("inet_pton", result);
267 	isc_sockaddr_fromin(&srcaddr, &inaddr, 0);
268 
269 	result = ISC_R_FAILURE;
270 	if (inet_pton(AF_INET, "10.53.0.4", &inaddr) != 1)
271 		CHECK("inet_pton", result);
272 	isc_sockaddr_fromin(&dstaddr, &inaddr, port);
273 
274 	mctx = NULL;
275 	RUNCHECK(isc_mem_create(0, 0, &mctx));
276 
277 	lctx = NULL;
278 	lcfg = NULL;
279 	RUNCHECK(isc_log_create(mctx, &lctx, &lcfg));
280 
281 	RUNCHECK(dst_lib_init(mctx, NULL));
282 
283 	taskmgr = NULL;
284 	RUNCHECK(isc_taskmgr_create(mctx, 1, 0, &taskmgr));
285 	task = NULL;
286 	RUNCHECK(isc_task_create(taskmgr, 0, &task));
287 	timermgr = NULL;
288 
289 	RUNCHECK(isc_timermgr_create(mctx, &timermgr));
290 	socketmgr = NULL;
291 	RUNCHECK(isc_socketmgr_create(mctx, &socketmgr));
292 	dispatchmgr = NULL;
293 	RUNCHECK(dns_dispatchmgr_create(mctx, &dispatchmgr));
294 
295 	attrs = DNS_DISPATCHATTR_UDP |
296 		DNS_DISPATCHATTR_MAKEQUERY |
297 		DNS_DISPATCHATTR_IPV4;
298 	attrmask = DNS_DISPATCHATTR_UDP |
299 		   DNS_DISPATCHATTR_TCP |
300 		   DNS_DISPATCHATTR_IPV4 |
301 		   DNS_DISPATCHATTR_IPV6;
302 	dispatchv4 = NULL;
303 	RUNCHECK(dns_dispatch_getudp(dispatchmgr, socketmgr, taskmgr,
304 				     have_src ? &srcaddr : &bind_any,
305 				     4096, 4, 2, 3, 5,
306 				     attrs, attrmask, &dispatchv4));
307 	requestmgr = NULL;
308 	RUNCHECK(dns_requestmgr_create(mctx, timermgr, socketmgr, taskmgr,
309 					    dispatchmgr, dispatchv4, NULL,
310 					    &requestmgr));
311 
312 	view = NULL;
313 	RUNCHECK(dns_view_create(mctx, 0, "_test", &view));
314 
315 	RUNCHECK(isc_app_onrun(mctx, task, sendqueries, NULL));
316 
317 	(void)isc_app_run();
318 
319 	dns_view_detach(&view);
320 
321 	dns_requestmgr_shutdown(requestmgr);
322 	dns_requestmgr_detach(&requestmgr);
323 
324 	dns_dispatch_detach(&dispatchv4);
325 	dns_dispatchmgr_destroy(&dispatchmgr);
326 
327 	isc_socketmgr_destroy(&socketmgr);
328 	isc_timermgr_destroy(&timermgr);
329 
330 	isc_task_shutdown(task);
331 	isc_task_detach(&task);
332 	isc_taskmgr_destroy(&taskmgr);
333 
334 	dst_lib_destroy();
335 
336 	isc_log_destroy(&lctx);
337 
338 	isc_mem_destroy(&mctx);
339 
340 	isc_app_finish();
341 
342 	return (0);
343 }
344 
345