]> git.ipfire.org Git - thirdparty/squid.git/blame - src/dnsserver.cc
update
[thirdparty/squid.git] / src / dnsserver.cc
CommitLineData
b560dd20 1
30a4f2a8 2/*
c68e9c6b 3 * $Id: dnsserver.cc,v 1.53 1998/11/12 06:28:03 wessels Exp $
30a4f2a8 4 *
5 * DEBUG: section 0 DNS Resolver
6 * AUTHOR: Harvest Derived
7 *
42c04c16 8 * SQUID Internet Object Cache http://squid.nlanr.net/Squid/
e25c139f 9 * ----------------------------------------------------------
30a4f2a8 10 *
11 * Squid is the result of efforts by numerous individuals from the
12 * Internet community. Development is led by Duane Wessels of the
e25c139f 13 * National Laboratory for Applied Network Research and funded by the
14 * National Science Foundation. Squid is Copyrighted (C) 1998 by
15 * Duane Wessels and the University of California San Diego. Please
16 * see the COPYRIGHT file for full details. Squid incorporates
17 * software developed and/or copyrighted by other sources. Please see
18 * the CREDITS file for full details.
30a4f2a8 19 *
20 * This program is free software; you can redistribute it and/or modify
21 * it under the terms of the GNU General Public License as published by
22 * the Free Software Foundation; either version 2 of the License, or
23 * (at your option) any later version.
24 *
25 * This program is distributed in the hope that it will be useful,
26 * but WITHOUT ANY WARRANTY; without even the implied warranty of
27 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28 * GNU General Public License for more details.
29 *
30 * You should have received a copy of the GNU General Public License
31 * along with this program; if not, write to the Free Software
cbdec147 32 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
e25c139f 33 *
30a4f2a8 34 */
ed43818f 35
af00901c 36#include "config.h"
37
38#if HAVE_UNISTD_H
39#include <unistd.h>
40#endif
41#if HAVE_STDLIB_H
42#include <stdlib.h>
43#endif
44#if HAVE_STDIO_H
45#include <stdio.h>
46#endif
47#if HAVE_SYS_TYPES_H
48#include <sys/types.h>
49#endif
50#if HAVE_CTYPE_H
51#include <ctype.h>
52#endif
53#if HAVE_ERRNO_H
54#include <errno.h>
55#endif
56#if HAVE_FCNTL_H
57#include <fcntl.h>
58#endif
59#if HAVE_GRP_H
60#include <grp.h>
61#endif
88738790 62#if HAVE_GNUMALLOC_H
63#include <gnumalloc.h>
64#elif HAVE_MALLOC_H && !defined(_SQUID_FREEBSD_) && !defined(_SQUID_NEXT_)
af00901c 65#include <malloc.h>
66#endif
67#if HAVE_MEMORY_H
68#include <memory.h>
69#endif
70#if HAVE_NETDB_H && !defined(_SQUID_NETDB_H_) /* protect NEXTSTEP */
71#define _SQUID_NETDB_H_
72#include <netdb.h>
73#endif
74#if HAVE_PWD_H
75#include <pwd.h>
76#endif
77#if HAVE_SIGNAL_H
78#include <signal.h>
79#endif
80#if HAVE_TIME_H
81#include <time.h>
82#endif
83#if HAVE_SYS_PARAM_H
84#include <sys/param.h>
85#endif
86#if HAVE_SYS_TIME_H
87#include <sys/time.h>
88#endif
89#if HAVE_SYS_RESOURCE_H
90#include <sys/resource.h> /* needs sys/time.h above it */
91#endif
92#if HAVE_SYS_SOCKET_H
93#include <sys/socket.h>
94#endif
95#if HAVE_NETINET_IN_H
96#include <netinet/in.h>
97#endif
98#if HAVE_ARPA_INET_H
99#include <arpa/inet.h>
100#endif
101#if HAVE_SYS_STAT_H
102#include <sys/stat.h>
103#endif
104#if HAVE_SYS_UN_H
105#include <sys/un.h>
106#endif
107#if HAVE_SYS_WAIT_H
108#include <sys/wait.h>
109#endif
110#if HAVE_LIBC_H
111#include <libc.h>
112#endif
113#ifdef HAVE_SYS_SYSCALL_H
114#include <sys/syscall.h>
115#endif
116#ifdef HAVE_STRING_H
117#include <string.h>
118#endif
119#ifdef HAVE_STRINGS_H
120#include <strings.h>
121#endif
122#if HAVE_BSTRING_H
123#include <bstring.h>
124#endif
125#ifdef HAVE_CRYPT_H
126#include <crypt.h>
127#endif
128#if HAVE_SYS_SELECT_H
129#include <sys/select.h>
130#endif
131
30a4f2a8 132#if HAVE_ARPA_NAMESER_H
133#include <arpa/nameser.h>
134#endif
135#if HAVE_RESOLV_H
136#include <resolv.h>
137#endif
090089c4 138
af00901c 139#include "util.h"
8350fe9b 140#include "snprintf.h"
af00901c 141
44965270 142#if !defined(_SQUID_AIX_)
090089c4 143extern int h_errno;
44965270 144#endif
090089c4 145
6bf65235 146#if LIBRESOLV_DNS_TTL_HACK
28b2f45f 147extern int _dns_ttl_; /* this is a really *dirty* hack - bne */
6bf65235 148#endif
149
3bf15742 150#ifdef _SQUID_NEXT_
151/* This is a really bloody hack. frank@langen.bull.de
152 * Workaround bug in gethostbyname which sets h_errno wrong
153 * WARNING: This hack queries only the resolver and not NetInfo or YP
154 */
155struct hostent *_res_gethostbyname(char *name);
156#define gethostbyname _res_gethostbyname
157#endif /* _SQUID_NEXT_ */
158
429fdbec 159static struct in_addr no_addr;
090089c4 160
161/* error messages from gethostbyname() */
b8d8561b 162static char *
163my_h_msgs(int x)
a0b481fd 164{
165 if (x == HOST_NOT_FOUND)
166 return "Host not found (authoritative)";
167 else if (x == TRY_AGAIN)
168 return "Host not found (non-authoritative)";
169 else if (x == NO_RECOVERY)
170 return "Non recoverable errors";
171 else if (x == NO_DATA || x == NO_ADDRESS)
172 return "Valid name, no data record of requested type";
173 else
174 return "Unknown DNS problem";
175}
090089c4 176
88738790 177#define REQ_SZ 512
178
bd34f258 179static void
180lookup(const char *buf)
181{
182 const struct hostent *result = NULL;
183 int reverse = 0;
184 int ttl = 0;
185 int retry = 0;
186 int i;
187 struct in_addr addr;
188 if (0 == strcmp(buf, "$shutdown"))
189 exit(0);
190 if (0 == strcmp(buf, "$hello")) {
191 printf("$alive\n");
192 return;
193 }
194 /* check if it's already an IP address in text form. */
195 for (;;) {
196 if (safe_inet_addr(buf, &addr)) {
197 reverse = 1;
198 result = gethostbyaddr((char *) &addr.s_addr, 4, AF_INET);
199 } else {
200 result = gethostbyname(buf);
201 }
202 if (NULL != result)
203 break;
204 if (h_errno != TRY_AGAIN)
205 break;
206 if (++retry == 3)
207 break;
208 sleep(1);
209 }
210 if (NULL == result) {
211 if (h_errno == TRY_AGAIN) {
212 printf("$fail Name Server for domain '%s' is unavailable.\n", buf);
213 } else {
214 printf("$fail DNS Domain '%s' is invalid: %s.\n",
215 buf, my_h_msgs(h_errno));
216 }
217 return;
218 }
219#if LIBRESOLV_DNS_TTL_HACK
220 /* DNS TTL handling - bne@CareNet.hu
221 * for first try it's a dirty hack, by hacking getanswer
222 * to place the ttl in a global variable */
223 if (_dns_ttl_ > -1)
224 ttl = _dns_ttl_;
225#endif
226 if (reverse) {
227 printf("$name %d %s\n", ttl, result->h_name);
228 return;
229 }
230 printf("$addr %d", ttl);
231 for (i = 0; NULL != result->h_addr_list[i]; i++) {
232 if (32 == i)
233 break;
234 xmemcpy(&addr, result->h_addr_list[i], sizeof(addr));
235 printf(" %s", inet_ntoa(addr));
236 }
237 printf("\n");
238}
239
240static void
241usage(void)
242{
243 fprintf(stderr, "usage: dnsserver -Dhv -s nameserver\n"
244 "\t-D Enable resolver RES_DEFNAMES and RES_DNSRCH options\n"
245 "\t-h Help\n"
246 "\t-v Version\n"
247 "\t-s nameserver Specify alternate name server(s). 'nameserver'\n"
248 "\t must be an IP address, -s option may be repeated\n");
249}
250
b8d8561b 251int
252main(int argc, char *argv[])
090089c4 253{
88738790 254 char request[512];
090089c4 255 char *t = NULL;
090089c4 256 int c;
09c483ec 257 int opt_s = 0;
258 extern char *optarg;
090089c4 259
429fdbec 260 safe_inet_addr("255.255.255.255", &no_addr);
451bf90b 261
30a4f2a8 262#if HAVE_RES_INIT
263 res_init();
ec762af2 264#ifdef RES_DEFAULT
265 _res.options = RES_DEFAULT;
266#endif
30a4f2a8 267#ifdef RES_DEFNAMES
268 _res.options &= ~RES_DEFNAMES;
269#endif
270#ifdef RES_DNSRCH
271 _res.options &= ~RES_DNSRCH;
272#endif
273#endif
274
bd34f258 275 while ((c = getopt(argc, argv, "Dhs:v")) != -1) {
090089c4 276 switch (c) {
a0bb9c7a 277 case 'D':
278#ifdef RES_DEFNAMES
279 _res.options |= RES_DEFNAMES;
5a0188b7 280#endif
281#ifdef RES_DNSRCH
282 _res.options |= RES_DNSRCH;
a0bb9c7a 283#endif
284 break;
09c483ec 285 case 's':
df087e68 286#if HAVE_RES_INIT
09c483ec 287 if (opt_s == 0) {
288 _res.nscount = 0;
289 _res.options |= RES_INIT;
290 opt_s = 1;
291 }
c68e9c6b 292#if HAVE_RES_NSADDR_LIST
09c483ec 293 safe_inet_addr(optarg, &_res.nsaddr_list[_res.nscount++].sin_addr);
c68e9c6b 294#elif HAVE_RES_NS_LIST
295 safe_inet_addr(optarg, &_res.ns_list[_res.nscount++].addr.sin_addr);
296#endif
297 fprintf(stderr, "-s is not supported on this resolver\n");
df087e68 298#else
4b4cd312 299 fprintf(stderr, "-s is not supported on this resolver\n");
df087e68 300#endif /* HAVE_RES_INIT */
09c483ec 301 break;
302 case 'v':
303 printf("dnsserver version %s\n", SQUID_VERSION);
304 exit(0);
305 break;
bd34f258 306 case 'h':
090089c4 307 default:
bd34f258 308 usage();
090089c4 309 exit(1);
310 break;
311 }
30a4f2a8 312 }
090089c4 313
cb0486c3 314 for (;;) {
88738790 315 memset(request, '\0', REQ_SZ);
bd34f258 316 if (fgets(request, REQ_SZ, stdin) == NULL)
090089c4 317 exit(1);
88738790 318 t = strrchr(request, '\n');
319 if (t == NULL) /* Ignore if no newline */
320 continue;
321 *t = '\0'; /* strip NL */
090089c4 322 if ((t = strrchr(request, '\r')) != NULL)
323 *t = '\0'; /* strip CR */
bd34f258 324 lookup(request);
325 fflush(stdout);
090089c4 326 }
b44c0fb4 327 /* NOTREACHED */
7690e8eb 328 return 0;
090089c4 329}