summaryrefslogtreecommitdiff
path: root/source4/nmbd/asyncdns.c
diff options
context:
space:
mode:
Diffstat (limited to 'source4/nmbd/asyncdns.c')
-rw-r--r--source4/nmbd/asyncdns.c349
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