2 Unix SMB/Netbios implementation.
5 Copyright (C) Andrew Tridgell 1994-1997
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 14 jan 96: lkcl@pires.co.uk
24 added multiple workgroup domain master support
30 extern int DEBUGLEVEL;
33 /***************************************************************************
34 add a DNS result to the name cache
35 ****************************************************************************/
36 static struct name_record *add_dns_result(struct nmb_name *question, struct in_addr addr)
38 int name_type = question->name_type;
39 char *qname = question->name;
42 /* add the fail to WINS cache of names. give it 1 hour in the cache */
43 DEBUG(3,("Negative DNS answer for %s\n", qname));
44 add_netbios_entry(wins_client_subnet,qname,name_type,NB_ACTIVE,60*60,
49 /* add it to our WINS cache of names. give it 2 hours in the cache */
50 DEBUG(3,("DNS gave answer for %s of %s\n", qname, inet_ntoa(addr)));
52 return add_netbios_entry(wins_client_subnet,qname,name_type,NB_ACTIVE,
53 2*60*60,DNS,addr, True);
60 static int fd_in = -1, fd_out = -1;
61 static int child_pid = -1;
64 /* this is the structure that is passed between the parent and child */
67 struct in_addr result;
70 /* a queue of pending requests waiting for DNS responses */
71 static struct packet_struct *dns_queue;
75 /***************************************************************************
76 return the fd used to gather async dns replies. This is added to the select
78 ****************************************************************************/
84 /***************************************************************************
85 handle DNS queries arriving from the parent
86 ****************************************************************************/
87 static void asyncdns_process(void)
89 struct query_record r;
95 if (read_data(fd_in, (char *)&r, sizeof(r)) != sizeof(r))
98 fstrcpy(qname, r.name.name);
100 r.result.s_addr = interpret_addr(qname);
102 if (write_data(fd_out, (char *)&r, sizeof(r)) != sizeof(r))
110 /***************************************************************************
111 create a child process to handle DNS lookups
112 ****************************************************************************/
113 void start_async_dns(void)
117 signal(SIGCLD, SIG_IGN);
119 if (pipe(fd1) || pipe(fd2)) {
140 /***************************************************************************
141 check if a particular name is already being queried
142 ****************************************************************************/
143 static BOOL query_in_queue(struct query_record *r)
145 struct packet_struct *p;
146 for (p = dns_queue; p; p = p->next) {
147 struct nmb_packet *nmb = &p->packet.nmb;
148 struct nmb_name *question = &nmb->question.question_name;
150 if (name_equal(question, &r->name))
157 /***************************************************************************
159 ****************************************************************************/
160 void run_dns_queue(void)
162 struct query_record r;
163 struct packet_struct *p, *p2;
168 if (read_data(fd_in, (char *)&r, sizeof(r)) != sizeof(r)) {
169 DEBUG(0,("Incomplete DNS answer from child!\n"));
174 add_dns_result(&r.name, r.result);
176 /* loop over the whole dns queue looking for entries that
177 match the result we just got */
178 for (p = dns_queue; p;) {
179 struct nmb_packet *nmb = &p->packet.nmb;
180 struct nmb_name *question = &nmb->question.question_name;
182 if (name_equal(question, &r.name)) {
183 DEBUG(3,("DNS calling reply_name_query\n"));
190 p->prev->next = p->next;
194 p->next->prev = p->prev;
205 /***************************************************************************
207 ****************************************************************************/
208 BOOL queue_dns_query(struct packet_struct *p,struct nmb_name *question,
209 struct name_record **n)
211 struct query_record r;
213 if (in_dns || fd_in == -1)
218 if (!query_in_queue(&r) &&
219 !write_data(fd_out, (char *)&r, sizeof(r))) {
220 DEBUG(3,("failed to send DNS query to child!\n"));
232 DEBUG(3,("added DNS query for %s\n", namestr(question)));
239 /***************************************************************************
240 we use this then we can't do async DNS lookups
241 ****************************************************************************/
242 BOOL queue_dns_query(struct packet_struct *p,struct nmb_name *question,
243 struct name_record **n)
245 int name_type = question->name_type;
246 char *qname = question->name;
247 struct in_addr dns_ip;
249 DEBUG(3,("DNS search for %s - ", namestr(question)));
251 dns_ip.s_addr = interpret_addr(qname);
253 *n = add_dns_result(question, dns_ip);