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