diff options
-rw-r--r-- | src/dnsclient.c | 208 | ||||
-rw-r--r-- | src/dnsclient.h | 32 | ||||
-rw-r--r-- | src/dnsserver.c | 242 |
3 files changed, 0 insertions, 482 deletions
diff --git a/src/dnsclient.c b/src/dnsclient.c deleted file mode 100644 index 4415b81..0000000 --- a/src/dnsclient.c +++ /dev/null @@ -1,208 +0,0 @@ -/* $Id: dnsclient.c,v 1.2 2002-05-24 04:45:32 rjkaes Exp $ - * - * Create the dnsserver child process, and then include functions to - * retrieve IP addresses or host names. These functions are required - * since the traditional gethostbyaddr() and getaddrbyname() functions - * are not thread reentrant. By spawning a child process the blocking - * has been moved outside the threads. - * - * Copyright (C) 2002 Robert James Kaes (rjkaes@flarenet.com) - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2, or (at your option) any - * later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - */ - -#include "tinyproxy.h" - -#include "dnsclient.h" -#include "heap.h" -#include "log.h" -#include "network.h" -#include "text.h" - -/* - * Static variable which holds the "dnsserver" process. - */ -static pid_t dnsserver_process; - -/* - * Hold the location of the Unix socket for client communication. - */ -static char* unix_socket_loc; - -/* - * Fork a copy of the "dnsserver" program. Two arguments are used - * by this function: 'dnsserver_location' is the complete path to the - * dnsserver executable; 'path' is the absolute path used by the - * Unix socket. - */ -int -start_dnsserver(const char* dnsserver_location, const char* path) -{ - int ret; - - assert(dnsserver_location != NULL); - assert(path != NULL); - - unix_socket_loc = safestrdup(path); - - if ((dnsserver_process = fork()) == 0) { - /* Child process */ - chdir("/"); - umask(077); - - close(0); - close(1); - close(2); - - /* Start the "dnsserver" program */ - ret = execl(dnsserver_location, - dnsserver_location, - path, - NULL); - - if (ret < 0) - return -ENOEXEC; - } - - /* Parent process */ - return 0; -} - -/* - * Stop the dnsserver process. - */ -int -stop_dnsserver(void) -{ - kill(dnsserver_process, SIGTERM); - kill(dnsserver_process, SIGKILL); - unlink(unix_socket_loc); - - return 0; -} - -/* - * Returns a socket connected to the "dnsserver" - */ -int -dns_connect(void) -{ - int dns; - struct sockaddr_un addr; - - dns = socket(AF_LOCAL, SOCK_STREAM, 0); - if (dns < 0) - return -EIO; - - memset(&addr, 0, sizeof(addr)); - addr.sun_family = AF_LOCAL; - strcpy(addr.sun_path, unix_socket_loc); - - if (connect(dns, (struct sockaddr *)&addr, sizeof(addr)) < 0) - return -EIO; - else - return dns; -} - -/* - * Closes the connection to the "dnsserver" - */ -void -dns_disconnect(int dns) -{ - assert(dns >= 0); - - safe_write(dns, "$shutdown\n", 10); - close(dns); -} - -/* - * Takes a dotted-decimal IP address and returns the host name in the - * buffer supplied by the caller. - * - * Returns: 0 if the buffer is filled correctly, or - * -1 if there was an error - */ -int -dns_gethostbyaddr(int dns, const char* ipaddr, char** hostname, - size_t hostlen) -{ - char* buffer; - ssize_t len; - char *ptr; - - assert(dns >= 0); - assert(ipaddr != NULL); - assert(hostname != NULL); - assert(hostlen > 0); - - write_message(dns, "%s\n", ipaddr); - len = readline(dns, &buffer); - if (len < 0) - return len; - chomp(buffer, len); - - if (strncmp(buffer, "$fail", 5) == 0) { - /* There was a problem. */ - safefree(buffer); - return -ENOMSG; - } - - ptr = strchr(buffer, ' '); - ptr++; - - strlcpy(*hostname, ptr, hostlen); - - safefree(buffer); - return 0; -} - -/* - * Takes a host name and returns an array of IP addresses. The caller - * is responsible for freeing the 'addresses' memory block. - */ -int -dns_getaddrbyname(int dns, const char* name, struct in_addr** addresses) -{ - char* buffer; - ssize_t len; - char *ptr; - - assert(dns >= 0); - assert(name != NULL); - assert(addresses != NULL); - - write_message(dns, "%s\n", name); - len = readline(dns, &buffer); - if (len < 0) - return len; - chomp(buffer, len); - - if (strncmp(buffer, "$fail", 5) == 0) { - safefree(buffer); - return -ENOMSG; - } - - ptr = strchr(buffer + 6, ' '); - if (ptr) - *ptr = '\0'; - - *addresses = safemalloc(sizeof(struct in_addr)); - if (!*addresses) { - safefree(buffer); - return -ENOMEM; - } - - inet_aton(buffer + 6, *addresses); - - safefree(buffer); - return 0; -} diff --git a/src/dnsclient.h b/src/dnsclient.h deleted file mode 100644 index 32bad58..0000000 --- a/src/dnsclient.h +++ /dev/null @@ -1,32 +0,0 @@ -/* $Id: dnsclient.h,v 1.1 2002-05-23 04:40:06 rjkaes Exp $ - * - * See 'dnsclient.c' for a detailed description. - * - * Copyright (C) 2002 Robert James Kaes (rjkaes@flarenet.com) - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2, or (at your option) any - * later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - */ - -#ifndef TINYPROXY_DNSCLIENT_H -#define TINYPROXY_DNSCLIENT_H - -extern int start_dnsserver(const char* dnsserver_location, const char* path); -extern int stop_dnsserver(void); - -extern int dns_connect(void); -extern void dns_disconnect(int dns); - -extern int dns_gethostbyaddr(int dns, const char* ipaddr, char** hostname, - size_t hostlen); -extern int dns_getaddrbyname(int dns, const char* name, - struct in_addr** addresses); - -#endif diff --git a/src/dnsserver.c b/src/dnsserver.c deleted file mode 100644 index e06ecb1..0000000 --- a/src/dnsserver.c +++ /dev/null @@ -1,242 +0,0 @@ -/* $Id: dnsserver.c,v 1.1 2002-05-23 04:40:42 rjkaes Exp $ - * - * This is a DNS resolver program. I've borrowed _liberally_ from - * Squid's dnsserver program. Only one argument is passed to this - * program (the path to the Unix socket.) Additionally, this program - * will be started by tinyproxy itself. - * - * As noted, communication is conducted over a Unix socket. The - * client opens a connection and writes a '\n' terminated string with - * either a domain name (if an address is required) or a - * dotted-decimal IP address (if the domain name is required.) This - * program will then respond with a '\n' terminated string starting - * with either "$addr" if IP addresses are being returned, or "$name" - * if a host name is returned. The connection will remain open until - * the "$shutdown" command is sent by the client. - * - * Copyright (C) 2002 Robert James Kaes (rjkaes@flarenet.com) - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2, or (at your option) any - * later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - */ - -#include "common.h" - -#include "daemon.h" -#include "heap.h" -#include "network.h" -#include "text.h" - -/* - * Store a copy of the location of the Unix socket - */ -static char *unix_socket_path; - -/* - * Handle SIGCHLD signals so that zombies are reaped. - */ -static void -child_signal_handler(int signo) -{ - pid_t pid; - int status; - - while ((pid = waitpid(-1, &status, WNOHANG)) > 0) - ; - return; -} - -/* - * Handle the SIGTERM signal to remove the Unix socket - */ -static void -term_signal_handler(int signo) -{ - unlink(unix_socket_path); - return; -} - -/* - * Text error messages for DNS problems. - */ -static char* -dns_error_messages(int err) -{ - if (err == HOST_NOT_FOUND) - return "Host not found (authoritative)"; - else if (err == TRY_AGAIN) - return "Host not found (non-authoritative)"; - else if (err == NO_RECOVERY) - return "Non recoverable errors"; - else if (err == NO_DATA || err == NO_ADDRESS) - return "Valid name, no data record of requested type"; - else - return "Unknown DNS problem"; -} - -/* - * Lookup and return the information for a host name (or IP address) - */ -static int -lookup_dns(int fd) -{ - const struct hostent *result = NULL; - int reverse_lookup = 0; - int retry = 0; - int i; - struct in_addr addr; - char *buf; - ssize_t len; - char address_buf[1024]; - - len = readline(fd, &buf); - chomp(buf, len); - - if (strcmp(buf, "$shutdown") == 0) - return 0; - if (strcmp(buf, "$hello") == 0) { - write_message(fd, "$alive\n"); - return 1; - } - - /* - * Check to see if the buffer is an IP address in dotted-decimal - * form. - */ - for (;;) { - if (inet_aton(buf, &addr)) { - reverse_lookup = 1; - result = gethostbyaddr((char *)&addr.s_addr, 4, AF_INET); - } else { - result = gethostbyname(buf); - } - - if (NULL != result) - break; - if (h_errno != TRY_AGAIN) - break; - if (++retry == 3) - break; - sleep(1); - } - - if (NULL == result) { - if (h_errno == TRY_AGAIN) { - write_message(fd, "$fail Name Server for domain '%s' is unavailable.\n", buf); - } else { - write_message(fd, "$fail DNS Domain '%s' is invalid: %s.\n", - buf, dns_error_messages(h_errno)); - } - return 1; - } - - if (reverse_lookup) { - write_message(fd, "$name %s\n", result->h_name); - return 1; - } - - strlcpy(address_buf, "$addr", sizeof(address_buf)); - for (i = 0; i < 32; i++) { - if (!result->h_addr_list[i]) - break; - - memcpy(&addr, result->h_addr_list[i], sizeof(addr)); - - strlcat(address_buf, " ", sizeof(address_buf)); - strlcat(address_buf, inet_ntoa(addr), sizeof(address_buf)); - } - write_message(fd, "%s\n", address_buf); - - return 1; -} - -/* - * Print out a usage message. - */ -static void -usage(void) -{ - fprintf(stderr, "usage: dnsserver path\n"); -} - -/* - * Start up function. Create the sockets and fork() when needed. - */ -int -main(int argc, char **argv) -{ - int listenfd, connfd; - pid_t childpid; - socklen_t clilen; - struct sockaddr_un cliaddr, servaddr; - - if (--argc != 1) { - usage(); - exit(1); - } - - /* - * The path for the socket is supplied as the one (and only) command - * line argument. - */ - unix_socket_path = safestrdup(argv[1]); - if (!unix_socket_path) { - fprintf(stderr, "%s: could not allocate memory.\n", argv[0]); - exit(1); - } - - /* Create the listening socket */ - listenfd = socket(AF_LOCAL, SOCK_STREAM, 0); - if (listenfd < 0) { - fprintf(stderr, "%s: could not create listening socket.\n", - argv[0]); - exit(1); - } - - memset(&servaddr, 0, sizeof(servaddr)); - servaddr.sun_family = AF_LOCAL; - strcpy(servaddr.sun_path, unix_socket_path); - - if (bind(listenfd, (struct sockaddr *)&servaddr, sizeof(servaddr)) < 0) { - fprintf(stderr, "%s: could not bind socket.\n", argv[0]); - exit(1); - } - if (listen(listenfd, MAXLISTEN) < 0) { - fprintf(stderr, "%s: could not start listening on socket.\n", - argv[0]); - exit(1); - } - - set_signal_handler(SIGCHLD, child_signal_handler); - set_signal_handler(SIGTERM, term_signal_handler); - - for ( ; ; ) { - clilen = sizeof(cliaddr); - if ((connfd = accept(listenfd, (struct sockaddr *)&cliaddr, &clilen)) < 0) { - if (errno == EINTR) - continue; - else - exit(1); - } - - if ((childpid = fork()) == 0) { - /* child process */ - close(listenfd); - - while (lookup_dns(connfd)) - ; - - close(connfd); - exit(0); - } - - close(connfd); /* parent closes connected socket */ - } -} |