diff options
Diffstat (limited to 'source3/nmbd')
-rw-r--r-- | source3/nmbd/asyncdns.c | 85 |
1 files changed, 58 insertions, 27 deletions
diff --git a/source3/nmbd/asyncdns.c b/source3/nmbd/asyncdns.c index 4982f7f340..a451f6b617 100644 --- a/source3/nmbd/asyncdns.c +++ b/source3/nmbd/asyncdns.c @@ -67,9 +67,11 @@ struct query_record { struct in_addr result; }; -/* a queue of pending requests waiting for DNS responses */ +/* 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; /*************************************************************************** @@ -140,21 +142,27 @@ void start_async_dns(void) /*************************************************************************** check if a particular name is already being queried ****************************************************************************/ -static BOOL query_in_queue(struct query_record *r) +static BOOL query_current(struct query_record *r) { - struct packet_struct *p; - for (p = dns_queue; p; p = p->next) { - struct nmb_packet *nmb = &p->packet.nmb; - struct nmb_name *question = &nmb->question.question_name; - - if (name_equal(question, &r->name)) - return True; - } - return False; + return dns_current && + 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) @@ -173,6 +181,19 @@ void run_dns_queue(void) add_dns_result(&r.name, r.result); + if (dns_current) { + if (query_current(&r)) { + DEBUG(3,("DNS calling reply_name_query\n")); + in_dns = 1; + reply_name_query(dns_current); + 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;) { @@ -200,6 +221,18 @@ 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; + + if (!write_child(dns_current)) { + DEBUG(3,("failed to send DNS query to child!\n")); + return; + } + } + } /*************************************************************************** @@ -208,27 +241,25 @@ queue a DNS query BOOL queue_dns_query(struct packet_struct *p,struct nmb_name *question, struct name_record **n) { - struct query_record r; - if (in_dns || fd_in == -1) return False; - r.name = *question; - - if (!query_in_queue(&r) && - !write_data(fd_out, (char *)&r, sizeof(r))) { - DEBUG(3,("failed to send DNS query to child!\n")); - 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; } - 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", namestr(question))); return True; } |