X-Git-Url: http://git.samba.org/samba.git/?a=blobdiff_plain;f=source3%2Fnmbd%2Fasyncdns.c;h=90340efe3970600195f9f2462da0303adbcbec76;hb=HEAD;hp=c86ee69a097db639d9a5f3a3f64519730fad0995;hpb=4b68935a519955f7cda9b874220fdbd037a5b0c0;p=kai%2Fsamba.git diff --git a/source3/nmbd/asyncdns.c b/source3/nmbd/asyncdns.c index c86ee69a097..90340efe397 100644 --- a/source3/nmbd/asyncdns.c +++ b/source3/nmbd/asyncdns.c @@ -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 . */ #include "includes.h" +#include "nmbd/nmbd.h" /*************************************************************************** Add a DNS result to the name cache. @@ -26,26 +26,27 @@ 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