]> git.ipfire.org Git - thirdparty/squid.git/blame - src/dnsserver.cc
updating to squid-1.0.1
[thirdparty/squid.git] / src / dnsserver.cc
CommitLineData
983061ed 1/* $Id: dnsserver.cc,v 1.6 1996/05/03 22:56:24 wessels Exp $ */
ed43818f 2
44a47c6e 3#include "squid.h"
090089c4 4
5extern int h_errno;
6
7int do_debug = 0;
8
9/* error messages from gethostbyname() */
10#define my_h_msgs(x) (\
11 ((x) == HOST_NOT_FOUND) ? \
12 "Host not found (authoritative)" : \
13 ((x) == TRY_AGAIN) ? \
14 "Host not found (non-authoritative)" : \
15 ((x) == NO_RECOVERY) ? \
16 "Non recoverable errors" : \
17 ((x) == NO_DATA) ? \
18 "Valid name, no data record of requested type" : \
19 ((x) == NO_ADDRESS) ? \
20 "No address, look for MX record" : \
21 "Unknown DNS problem")
22
23/*
b8de7ebe 24 * Modified to use UNIX domain sockets between squid and the dnsservers to
090089c4 25 * save an FD per DNS server, Hong Mei, USC.
26 *
b8de7ebe 27 * Before forking a dnsserver, squid creates listens on a UNIX domain
28 * socket. After the fork(), squid closes its end of the rendevouz socket
090089c4 29 * but then immediately connects to it to establish the connection to the
30 * dnsserver process. We use AF_UNIX to prevent other folks from
31 * connecting to our little dnsservers after we fork but before we connect
32 * to them.
33 *
b8de7ebe 34 * Squid creates UNIX domain sockets named dns.PID.NN, e.g. dns.19215.11
090089c4 35 *
36 * In ipcache_init():
37 * . dnssocket = ipcache_opensocket(getDnsProgram())
38 * . dns_child_table[i]->inpipe = dnssocket
39 * . dns_child_table[i]->outpipe = dnssocket
40 *
b8de7ebe 41 * The dnsserver inherits socket(socket_from_ipcache) from squid which it
090089c4 42 * uses to rendevouz with. The child takes responsibility for cleaning up
43 * the UNIX domain pathnames by setting a few signal handlers.
44 *
45 */
46
47int main(argc, argv)
48 int argc;
49 char *argv[];
50{
51 char request[256];
52 char msg[256];
53 struct hostent *result = NULL;
54 FILE *logfile = NULL;
55 long start;
56 long stop;
57 char *t = NULL;
58 char buf[256];
59 int socket_from_cache, fd;
60 int a1, a2, a3, a4;
61 int addr_count = 0;
62 int alias_count = 0;
63 int i;
64 char *dnsServerPathname = NULL;
65 int c;
66 extern char *optarg;
67
68 while ((c = getopt(argc, argv, "vhdp:")) != -1)
69 switch (c) {
70 case 'v':
71 case 'h':
73a5465f 72 printf("dnsserver version %s\n", SQUID_VERSION);
090089c4 73 exit(0);
74 break;
75 case 'd':
76 sprintf(buf, "dnsserver.%d.log", (int) getpid());
77 logfile = fopen(buf, "a");
78 do_debug++;
79 if (!logfile)
80 fprintf(stderr, "Could not open dnsserver's log file\n");
81 break;
82 case 'p':
83 dnsServerPathname = xstrdup(optarg);
84 break;
85 default:
86 fprintf(stderr, "usage: dnsserver -h -d -p socket-filename\n");
87 exit(1);
88 break;
89 }
90
91 socket_from_cache = 3;
92
93 /* accept DNS look up from ipcache */
94 if (dnsServerPathname) {
95 fd = accept(socket_from_cache, (struct sockaddr *) 0, (int *) 0);
96 unlink(dnsServerPathname);
97 if (fd < 0) {
98 fprintf(stderr, "dnsserver: accept: %s\n", xstrerror());
99 exit(1);
100 }
101 close(socket_from_cache);
102
103 /* point stdout to fd */
104 dup2(fd, 1);
105 dup2(fd, 0);
106 close(fd);
107 }
108 while (1) {
109 memset(request, '\0', 256);
110
111 /* read from ipcache */
112 if (fgets(request, 255, stdin) == (char *) NULL)
113 exit(1);
114 if ((t = strrchr(request, '\n')) != NULL)
115 *t = '\0'; /* strip NL */
116 if ((t = strrchr(request, '\r')) != NULL)
117 *t = '\0'; /* strip CR */
118 if (strcmp(request, "$shutdown") == 0) {
119 exit(0);
120 }
121 if (strcmp(request, "$hello") == 0) {
122 printf("$alive\n");
123 printf("$end\n");
124 fflush(stdout);
125 continue;
126 }
127 /* check if it's already an IP address in text form. */
128 if (sscanf(request, "%d.%d.%d.%d", &a1, &a2, &a3, &a4) == 4) {
129 printf("$name %s\n", request);
130 printf("$h_name %s\n", request);
131 printf("$h_len %d\n", 4);
132 printf("$ipcount %d\n", 1);
133 printf("%s\n", request);
134 printf("$aliascount %d\n", 0);
135 printf("$end\n");
136 fflush(stdout);
137 continue;
138 }
139 start = time(NULL);
140 result = gethostbyname(request);
141 if (!result) {
142 if (h_errno == TRY_AGAIN) {
143 sleep(2);
144 result = gethostbyname(request); /* try a little harder */
145 }
146 }
147 stop = time(NULL);
148
149 msg[0] = '\0';
150 if (!result) {
151 if (h_errno == TRY_AGAIN) {
152 sprintf(msg, "Name Server for domain '%s' is unavailable.",
153 request);
154 } else {
155 sprintf(msg, "DNS Domain '%s' is invalid: %s.\n",
156 request, my_h_msgs(h_errno));
157 }
158 }
159 if (!result || (strlen(result->h_name) == 0)) {
160 if (logfile) {
161 fprintf(logfile, "%s %d\n", request, (int) (stop - start));
162 fflush(logfile);
163 }
164 printf("$fail %s\n", request);
165 printf("$message %s\n", msg[0] ? msg : "Unknown Error");
166 printf("$end\n");
167 fflush(stdout);
168 continue;
169 } else {
170
171 printf("$name %s\n", request);
172 printf("$h_name %s\n", result->h_name);
173 printf("$h_len %d\n", result->h_length);
174
175 addr_count = alias_count = 0;
176 while (result->h_addr_list[addr_count] && addr_count < 255)
177 ++addr_count;
178 printf("$ipcount %d\n", addr_count);
179 for (i = 0; i < addr_count; i++) {
180 struct in_addr addr;
181 memcpy((char *) &addr, result->h_addr_list[i], result->h_length);
182 printf("%s\n", inet_ntoa(addr));
183 }
184
185#ifdef SEND_ALIASES
186 while ((alias_count < 255) && result->h_aliases[alias_count])
187 ++alias_count;
188#endif
189 printf("$aliascount %d\n", alias_count);
190 for (i = 0; i < alias_count; i++) {
191 printf("%s\n", result->h_aliases[i]);
192 }
193
194 printf("$end\n");
195 fflush(stdout);
196 continue;
197 }
198 }
199
200 exit(0);
201 /*NOTREACHED */
983061ed 202 return 0;
090089c4 203}