1 /*
2 * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
3 *
4 * SPDX-License-Identifier: MPL-2.0
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 https://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 /*! \file
15 */
16
17 #include <stdbool.h>
18 #include <stdlib.h>
19
20 #include <isc/app.h>
21 #include <isc/commandline.h>
22 #include <isc/managers.h>
23 #include <isc/mem.h>
24 #include <isc/netaddr.h>
25 #include <isc/print.h>
26 #include <isc/task.h>
27 #include <isc/timer.h>
28 #include <isc/util.h>
29
30 #include <dns/byaddr.h>
31 #include <dns/cache.h>
32 #include <dns/dispatch.h>
33 #include <dns/events.h>
34 #include <dns/forward.h>
35 #include <dns/resolver.h>
36 #include <dns/result.h>
37 #include <dns/view.h>
38
39 static void
done(isc_task_t * task,isc_event_t * event)40 done(isc_task_t *task, isc_event_t *event) {
41 dns_byaddrevent_t *bevent;
42 dns_byaddr_t *byaddr;
43 dns_name_t *name;
44
45 REQUIRE(event->ev_type == DNS_EVENT_BYADDRDONE);
46 bevent = (dns_byaddrevent_t *)event;
47
48 UNUSED(task);
49
50 printf("byaddr event result = %s\n", isc_result_totext(bevent->result));
51
52 if (bevent->result == ISC_R_SUCCESS) {
53 for (name = ISC_LIST_HEAD(bevent->names); name != NULL;
54 name = ISC_LIST_NEXT(name, link))
55 {
56 char text[DNS_NAME_FORMATSIZE];
57 dns_name_format(name, text, sizeof(text));
58 printf("%s\n", text);
59 }
60 }
61
62 byaddr = event->ev_sender;
63 dns_byaddr_destroy(&byaddr);
64 isc_event_free(&event);
65
66 isc_app_shutdown();
67 }
68
69 int
main(int argc,char * argv[])70 main(int argc, char *argv[]) {
71 isc_mem_t *mctx = NULL;
72 bool verbose = false;
73 unsigned int workers = 2;
74 isc_nm_t *netmgr = NULL;
75 isc_taskmgr_t *taskmgr = NULL;
76 isc_task_t *task = NULL;
77 isc_timermgr_t *timermgr = NULL;
78 dns_view_t *view = NULL;
79 int ch;
80 isc_socketmgr_t *socketmgr = NULL;
81 dns_dispatchmgr_t *dispatchmgr = NULL;
82 isc_netaddr_t na;
83 dns_byaddr_t *byaddr = NULL;
84 isc_result_t result;
85 unsigned int options = 0;
86 dns_cache_t *cache;
87
88 RUNTIME_CHECK(isc_app_start() == ISC_R_SUCCESS);
89
90 dns_result_register();
91
92 isc_mem_create(&mctx);
93
94 while ((ch = isc_commandline_parse(argc, argv, "nvw:")) != -1) {
95 switch (ch) {
96 case 'n':
97 /*
98 * We only try nibbles, so do nothing for this option.
99 */
100 break;
101 case 'v':
102 verbose = true;
103 break;
104 case 'w':
105 workers = (unsigned int)atoi(isc_commandline_argument);
106 break;
107 }
108 }
109
110 if (verbose) {
111 printf("%u workers\n", workers);
112 printf("IPv4: %s\n", isc_result_totext(isc_net_probeipv4()));
113 printf("IPv6: %s\n", isc_result_totext(isc_net_probeipv6()));
114 }
115
116 RUNTIME_CHECK(isc_managers_create(mctx, workers, 0, &netmgr,
117 &taskmgr) == ISC_R_SUCCESS);
118 RUNTIME_CHECK(isc_task_create(taskmgr, 0, &task) == ISC_R_SUCCESS);
119 isc_task_setname(task, "byaddr", NULL);
120
121 RUNTIME_CHECK(dns_dispatchmgr_create(mctx, &dispatchmgr) ==
122 ISC_R_SUCCESS);
123
124 RUNTIME_CHECK(isc_timermgr_create(mctx, &timermgr) == ISC_R_SUCCESS);
125 RUNTIME_CHECK(isc_socketmgr_create(mctx, &socketmgr) == ISC_R_SUCCESS);
126
127 RUNTIME_CHECK(dns_cache_create(mctx, mctx, taskmgr, timermgr,
128 dns_rdataclass_in, "", "rbt", 0, NULL,
129 &cache) == ISC_R_SUCCESS);
130
131 RUNTIME_CHECK(dns_view_create(mctx, dns_rdataclass_in, "default",
132 &view) == ISC_R_SUCCESS);
133
134 {
135 unsigned int attrs;
136 dns_dispatch_t *disp4 = NULL;
137 dns_dispatch_t *disp6 = NULL;
138
139 if (isc_net_probeipv4() == ISC_R_SUCCESS) {
140 isc_sockaddr_t any4;
141
142 isc_sockaddr_any(&any4);
143
144 attrs = DNS_DISPATCHATTR_IPV4 | DNS_DISPATCHATTR_UDP;
145 RUNTIME_CHECK(
146 dns_dispatch_getudp(dispatchmgr, socketmgr,
147 taskmgr, &any4, 512, 6,
148 1024, 17, 19, attrs, attrs,
149 &disp4) == ISC_R_SUCCESS);
150 INSIST(disp4 != NULL);
151 }
152
153 if (isc_net_probeipv6() == ISC_R_SUCCESS) {
154 isc_sockaddr_t any6;
155
156 isc_sockaddr_any6(&any6);
157
158 attrs = DNS_DISPATCHATTR_IPV6 | DNS_DISPATCHATTR_UDP;
159 RUNTIME_CHECK(
160 dns_dispatch_getudp(dispatchmgr, socketmgr,
161 taskmgr, &any6, 512, 6,
162 1024, 17, 19, attrs, attrs,
163 &disp6) == ISC_R_SUCCESS);
164 INSIST(disp6 != NULL);
165 }
166
167 RUNTIME_CHECK(dns_view_createresolver(view, taskmgr, 10, 1,
168 socketmgr, timermgr, 0,
169 dispatchmgr, disp4,
170 disp6) == ISC_R_SUCCESS);
171
172 if (disp4 != NULL) {
173 dns_dispatch_detach(&disp4);
174 }
175 if (disp6 != NULL) {
176 dns_dispatch_detach(&disp6);
177 }
178 }
179
180 {
181 struct in_addr ina;
182 isc_sockaddr_t sa;
183 isc_sockaddrlist_t sal;
184
185 ISC_LIST_INIT(sal);
186 ina.s_addr = inet_addr("127.0.0.1");
187 isc_sockaddr_fromin(&sa, &ina, 53);
188 ISC_LIST_APPEND(sal, &sa, link);
189
190 RUNTIME_CHECK(dns_fwdtable_add(view->fwdtable, dns_rootname,
191 &sal, dns_fwdpolicy_only) ==
192 ISC_R_SUCCESS);
193 }
194
195 dns_view_setcache(view, cache, false);
196 dns_view_freeze(view);
197
198 dns_cache_detach(&cache);
199
200 printf("address = %s\n", argv[isc_commandline_index]);
201 na.family = AF_INET;
202 if (inet_pton(AF_INET, argv[isc_commandline_index],
203 (char *)&na.type.in) != 1) {
204 na.family = AF_INET6;
205 if (inet_pton(AF_INET6, argv[isc_commandline_index],
206 (char *)&na.type.in6) != 1) {
207 printf("unknown address format\n");
208 exit(1);
209 }
210 }
211
212 result = dns_byaddr_create(mctx, &na, view, options, task, done, NULL,
213 &byaddr);
214 if (result != ISC_R_SUCCESS) {
215 printf("dns_byaddr_create() returned %s\n",
216 isc_result_totext(result));
217 RUNTIME_CHECK(0);
218 }
219
220 (void)isc_app_run();
221
222 /*
223 * XXXRTH if we get a control-C before we get to isc_app_run(),
224 * we're in trouble (because we might try to destroy things before
225 * they've been created.
226 */
227
228 dns_view_detach(&view);
229
230 isc_task_shutdown(task);
231 isc_task_detach(&task);
232
233 dns_dispatchmgr_destroy(&dispatchmgr);
234
235 isc_managers_destroy(&netmgr, &taskmgr);
236
237 isc_socketmgr_destroy(&socketmgr);
238 isc_timermgr_destroy(&timermgr);
239
240 if (verbose) {
241 isc_mem_stats(mctx, stdout);
242 }
243 isc_mem_destroy(&mctx);
244
245 isc_app_finish();
246
247 return (0);
248 }
249