dns: Use new DNS debugclass in DNS server
[kai/samba.git] / source3 / nmbd / asyncdns.c
index c86ee69a097db639d9a5f3a3f64519730fad0995..90340efe3970600195f9f2462da0303adbcbec76 100644 (file)
@@ -2,23 +2,23 @@
    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
+   the Free Software Foundation; either version 3 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.
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
    */
 
 #include "includes.h"
+#include "nmbd/nmbd.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 ) );
-}
+       int name_type = question->name_type;
+       unstring qname;
 
+       pull_ascii_nstring(qname, sizeof(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));
+               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)));
+
+       add_name_to_subnet( wins_server_subnet, qname, name_type,
+                              NB_ACTIVE, 2*60*60, DNS_NAME, 1, &addr);
+
+       return find_name_on_subnet(wins_server_subnet, question, FIND_ANY_NAME);
+}
 
 #ifndef SYNC_DNS
 
@@ -70,6 +71,7 @@ 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;
@@ -81,16 +83,20 @@ int asyncdns_fd(void)
 static void asyncdns_process(void)
 {
        struct query_record r;
-       fstring qname;
+       unstring qname;
 
        DEBUGLEVEL = -1;
 
        while (1) {
-               if (read_data(fd_in, (char *)&r, sizeof(r)) != sizeof(r)) 
-                       break;
+               NTSTATUS status;
 
-               fstrcpy(qname, r.name.name);
+               status = read_data(fd_in, (char *)&r, sizeof(r));
+
+               if (!NT_STATUS_IS_OK(status)) {
+                       break;
+               }
 
+               pull_ascii_nstring( qname, sizeof(qname), r.name.name);
                r.result.s_addr = interpret_addr(qname);
 
                if (write_data(fd_out, (char *)&r, sizeof(r)) != sizeof(r))
@@ -110,7 +116,7 @@ static void asyncdns_process(void)
 
 static void sig_term(int sig)
 {
-  _exit(0);
+       _exit(0);
 }
 
 /***************************************************************************
@@ -129,9 +135,10 @@ void kill_async_dns_child(void)
 /***************************************************************************
   create a child process to handle DNS lookups
   ****************************************************************************/
-void start_async_dns(void)
+void start_async_dns(struct messaging_context *msg)
 {
        int fd1[2], fd2[2];
+       NTSTATUS status;
 
        CatchChild();
 
@@ -140,7 +147,7 @@ void start_async_dns(void)
                return;
        }
 
-       child_pid = sys_fork();
+       child_pid = fork();
 
        if (child_pid) {
                fd_in = fd1[0];
@@ -157,7 +164,14 @@ void start_async_dns(void)
        CatchSignal(SIGUSR2, SIG_IGN);
        CatchSignal(SIGUSR1, SIG_IGN);
        CatchSignal(SIGHUP, SIG_IGN);
-        CatchSignal(SIGTERM, SIGNAL_CAST sig_term );
+        CatchSignal(SIGTERM, sig_term);
+
+       status = reinit_after_fork(msg, nmbd_event_context(), true);
+
+       if (!NT_STATUS_IS_OK(status)) {
+               DEBUG(0,("reinit_after_fork() failed\n"));
+               smb_panic("reinit_after_fork() failed");
+       }
 
        asyncdns_process();
 }
@@ -166,7 +180,7 @@ void start_async_dns(void)
 /***************************************************************************
 check if a particular name is already being queried
   ****************************************************************************/
-static BOOL query_current(struct query_record *r)
+static bool query_current(struct query_record *r)
 {
        return dns_current &&
                nmb_name_equal(&r->name, 
@@ -177,7 +191,7 @@ static BOOL query_current(struct query_record *r)
 /***************************************************************************
   write a query to the child process
   ****************************************************************************/
-static BOOL write_child(struct packet_struct *p)
+static bool write_child(struct packet_struct *p)
 {
        struct query_record r;
 
@@ -189,45 +203,40 @@ static BOOL write_child(struct packet_struct *p)
 /***************************************************************************
   check the DNS queue
   ****************************************************************************/
-void run_dns_queue(void)
+void run_dns_queue(struct messaging_context *msg)
 {
        struct query_record r;
        struct packet_struct *p, *p2;
        struct name_record *namerec;
-       int size;
+       NTSTATUS status;
 
        if (fd_in == -1)
                return;
 
-        /* Allow SIGTERM to kill us. */
-        BlockSignals(False, SIGTERM);
-
-       if (!process_exists(child_pid)) {
+       if (!process_exists_by_pid(child_pid)) {
                close(fd_in);
-               start_async_dns();
+               close(fd_out);
+               start_async_dns(msg);
        }
 
-       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);
+       status = read_data(fd_in, (char *)&r, sizeof(r));
+
+       if (!NT_STATUS_IS_OK(status)) {
+               DEBUG(0, ("read from child failed: %s\n", nt_errstr(status)));
+               fd_in = -1;
                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);
+                       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;
                }
 
@@ -245,20 +254,15 @@ void run_dns_queue(void)
                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);
+                       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;
+                       DLIST_REMOVE(dns_queue, p);
                        free_packet(p);
                        p = p2;
                } else {
@@ -268,23 +272,20 @@ void run_dns_queue(void)
 
        if (dns_queue) {
                dns_current = dns_queue;
-               dns_queue = dns_queue->next;
-               if (dns_queue) dns_queue->prev = NULL;
-               dns_current->next = NULL;
+               DLIST_REMOVE(dns_queue, dns_queue);
 
                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)
+
+bool queue_dns_query(struct packet_struct *p,struct nmb_name *question)
 {
        if (in_dns || fd_in == -1)
                return False;
@@ -298,11 +299,7 @@ BOOL queue_dns_query(struct packet_struct *p,struct nmb_name *question,
                p->locked = True;
        } else {
                p->locked = True;
-               p->next = dns_queue;
-               p->prev = NULL;
-               if (p->next)
-                       p->next->prev = p;
-               dns_queue = p;
+               DLIST_ADD(dns_queue, p);
        }
 
        DEBUG(3,("added DNS query for %s\n", nmb_namestr(question)));
@@ -315,35 +312,34 @@ BOOL queue_dns_query(struct packet_struct *p,struct nmb_name *question,
 /***************************************************************************
   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)
+
+bool queue_dns_query(struct packet_struct *p,struct nmb_name *question)
 {
-       char *qname = question->name;
+       struct name_record *namerec = NULL;
        struct in_addr dns_ip;
+       unstring qname;
 
-       DEBUG(3,("DNS search for %s - ", nmb_namestr(question)));
+       pull_ascii_nstring(qname, sizeof(qname), question->name);
 
-        /* Unblock TERM signal so we can be killed in DNS lookup. */
-        BlockSignals(False, SIGTERM);
+       DEBUG(3,("DNS search for %s - ", nmb_namestr(question)));
 
        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);
+       namerec = add_dns_result(question, dns_ip);
+       if(namerec == NULL) {
+               send_wins_name_query_response(NAM_ERR, p, NULL);
+       } else {
+               send_wins_name_query_response(0, p, namerec);
+       }
        return False;
 }
 
 /***************************************************************************
  With sync dns there is no child to kill on SIGTERM.
   ****************************************************************************/
+
 void kill_async_dns_child(void)
 {
-  return;
+       return;
 }
 #endif