diff options
Diffstat (limited to 'source4/nmbd/asyncdns.c')
-rw-r--r-- | source4/nmbd/asyncdns.c | 349 |
1 files changed, 0 insertions, 349 deletions
diff --git a/source4/nmbd/asyncdns.c b/source4/nmbd/asyncdns.c deleted file mode 100644 index c86ee69a09..0000000000 --- a/source4/nmbd/asyncdns.c +++ /dev/null @@ -1,349 +0,0 @@ -/* - Unix SMB/CIFS implementation. - a async DNS handler - Copyright (C) Andrew Tridgell 1997-1998 - - 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 of the License, 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. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include "includes.h" - -/*************************************************************************** - Add a DNS result to the name cache. -****************************************************************************/ - -static struct name_record *add_dns_result(struct nmb_name *question, struct in_addr addr) -{ - int name_type = question->name_type; - char *qname = question->name; - - - if (!addr.s_addr) { - /* add the fail to WINS cache of names. give it 1 hour in the cache */ - DEBUG(3,("add_dns_result: Negative DNS answer for %s\n", qname)); - (void)add_name_to_subnet( wins_server_subnet, qname, name_type, - NB_ACTIVE, 60*60, DNSFAIL_NAME, 1, &addr ); - return( NULL ); - } - - /* add it to our WINS cache of names. give it 2 hours in the cache */ - DEBUG(3,("add_dns_result: DNS gave answer for %s of %s\n", qname, inet_ntoa(addr))); - - return( add_name_to_subnet( wins_server_subnet, qname, name_type, - NB_ACTIVE, 2*60*60, DNS_NAME, 1, &addr ) ); -} - - - -#ifndef SYNC_DNS - -static int fd_in = -1, fd_out = -1; -static pid_t child_pid = -1; -static int in_dns; - -/* this is the structure that is passed between the parent and child */ -struct query_record { - struct nmb_name name; - struct in_addr result; -}; - -/* a queue of pending requests waiting to be sent to the DNS child */ -static struct packet_struct *dns_queue; - -/* the packet currently being processed by the dns child */ -static struct packet_struct *dns_current; - - -/*************************************************************************** - return the fd used to gather async dns replies. This is added to the select - loop - ****************************************************************************/ -int asyncdns_fd(void) -{ - return fd_in; -} - -/*************************************************************************** - handle DNS queries arriving from the parent - ****************************************************************************/ -static void asyncdns_process(void) -{ - struct query_record r; - fstring qname; - - DEBUGLEVEL = -1; - - while (1) { - if (read_data(fd_in, (char *)&r, sizeof(r)) != sizeof(r)) - break; - - fstrcpy(qname, r.name.name); - - r.result.s_addr = interpret_addr(qname); - - if (write_data(fd_out, (char *)&r, sizeof(r)) != sizeof(r)) - break; - } - - _exit(0); -} - -/**************************************************************************** ** - catch a sigterm (in the child process - the parent has a different handler - see nmbd.c for details). - We need a separate term handler here so we don't release any - names that our parent is going to release, or overwrite a - WINS db that our parent is going to write. - **************************************************************************** */ - -static void sig_term(int sig) -{ - _exit(0); -} - -/*************************************************************************** - Called by the parent process when it receives a SIGTERM - also kills the - child so we don't get child async dns processes lying around, causing trouble. - ****************************************************************************/ - -void kill_async_dns_child(void) -{ - if (child_pid > 0) { - kill(child_pid, SIGTERM); - child_pid = -1; - } -} - -/*************************************************************************** - create a child process to handle DNS lookups - ****************************************************************************/ -void start_async_dns(void) -{ - int fd1[2], fd2[2]; - - CatchChild(); - - if (pipe(fd1) || pipe(fd2)) { - DEBUG(0,("can't create asyncdns pipes\n")); - return; - } - - child_pid = sys_fork(); - - if (child_pid) { - fd_in = fd1[0]; - fd_out = fd2[1]; - close(fd1[1]); - close(fd2[0]); - DEBUG(0,("started asyncdns process %d\n", (int)child_pid)); - return; - } - - fd_in = fd2[0]; - fd_out = fd1[1]; - - CatchSignal(SIGUSR2, SIG_IGN); - CatchSignal(SIGUSR1, SIG_IGN); - CatchSignal(SIGHUP, SIG_IGN); - CatchSignal(SIGTERM, SIGNAL_CAST sig_term ); - - asyncdns_process(); -} - - -/*************************************************************************** -check if a particular name is already being queried - ****************************************************************************/ -static BOOL query_current(struct query_record *r) -{ - return dns_current && - nmb_name_equal(&r->name, - &dns_current->packet.nmb.question.question_name); -} - - -/*************************************************************************** - write a query to the child process - ****************************************************************************/ -static BOOL write_child(struct packet_struct *p) -{ - struct query_record r; - - r.name = p->packet.nmb.question.question_name; - - return write_data(fd_out, (char *)&r, sizeof(r)) == sizeof(r); -} - -/*************************************************************************** - check the DNS queue - ****************************************************************************/ -void run_dns_queue(void) -{ - struct query_record r; - struct packet_struct *p, *p2; - struct name_record *namerec; - int size; - - if (fd_in == -1) - return; - - /* Allow SIGTERM to kill us. */ - BlockSignals(False, SIGTERM); - - if (!process_exists(child_pid)) { - close(fd_in); - start_async_dns(); - } - - if ((size=read_data(fd_in, (char *)&r, sizeof(r))) != sizeof(r)) { - if (size) { - DEBUG(0,("Incomplete DNS answer from child!\n")); - fd_in = -1; - } - BlockSignals(True, SIGTERM); - return; - } - - BlockSignals(True, SIGTERM); - - namerec = add_dns_result(&r.name, r.result); - - if (dns_current) { - if (query_current(&r)) { - DEBUG(3,("DNS calling send_wins_name_query_response\n")); - in_dns = 1; - if(namerec == NULL) - send_wins_name_query_response(NAM_ERR, dns_current, NULL); - else - send_wins_name_query_response(0,dns_current,namerec); - in_dns = 0; - } - - dns_current->locked = False; - free_packet(dns_current); - dns_current = NULL; - } - - /* loop over the whole dns queue looking for entries that - match the result we just got */ - for (p = dns_queue; p;) { - struct nmb_packet *nmb = &p->packet.nmb; - struct nmb_name *question = &nmb->question.question_name; - - if (nmb_name_equal(question, &r.name)) { - DEBUG(3,("DNS calling send_wins_name_query_response\n")); - in_dns = 1; - if(namerec == NULL) - send_wins_name_query_response(NAM_ERR, p, NULL); - else - send_wins_name_query_response(0,p,namerec); - in_dns = 0; - p->locked = False; - - if (p->prev) - p->prev->next = p->next; - else - dns_queue = p->next; - if (p->next) - p->next->prev = p->prev; - p2 = p->next; - free_packet(p); - p = p2; - } else { - p = p->next; - } - } - - if (dns_queue) { - dns_current = dns_queue; - dns_queue = dns_queue->next; - if (dns_queue) dns_queue->prev = NULL; - dns_current->next = NULL; - - if (!write_child(dns_current)) { - DEBUG(3,("failed to send DNS query to child!\n")); - return; - } - } - -} - -/*************************************************************************** -queue a DNS query - ****************************************************************************/ -BOOL queue_dns_query(struct packet_struct *p,struct nmb_name *question, - struct name_record **n) -{ - if (in_dns || fd_in == -1) - return False; - - if (!dns_current) { - if (!write_child(p)) { - DEBUG(3,("failed to send DNS query to child!\n")); - return False; - } - dns_current = p; - p->locked = True; - } else { - p->locked = True; - p->next = dns_queue; - p->prev = NULL; - if (p->next) - p->next->prev = p; - dns_queue = p; - } - - DEBUG(3,("added DNS query for %s\n", nmb_namestr(question))); - return True; -} - -#else - - -/*************************************************************************** - we use this when we can't do async DNS lookups - ****************************************************************************/ -BOOL queue_dns_query(struct packet_struct *p,struct nmb_name *question, - struct name_record **n) -{ - char *qname = question->name; - struct in_addr dns_ip; - - DEBUG(3,("DNS search for %s - ", nmb_namestr(question))); - - /* Unblock TERM signal so we can be killed in DNS lookup. */ - BlockSignals(False, SIGTERM); - - dns_ip.s_addr = interpret_addr(qname); - - /* Re-block TERM signal. */ - BlockSignals(True, SIGTERM); - - *n = add_dns_result(question, dns_ip); - if(*n == NULL) - send_wins_name_query_response(NAM_ERR, p, NULL); - else - send_wins_name_query_response(0, p, *n); - return False; -} - -/*************************************************************************** - With sync dns there is no child to kill on SIGTERM. - ****************************************************************************/ -void kill_async_dns_child(void) -{ - return; -} -#endif |