2 Unix SMB/Netbios implementation.
4 Copyright (C) Andrew Tridgell 1997
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 extern int DEBUGLEVEL
;
26 /***************************************************************************
27 add a DNS result to the name cache
28 ****************************************************************************/
29 static struct name_record
*add_dns_result(struct nmb_name
*question
, struct in_addr addr
)
31 int name_type
= question
->name_type
;
32 char *qname
= question
->name
;
35 /* add the fail to WINS cache of names. give it 1 hour in the cache */
36 DEBUG(3,("Negative DNS answer for %s\n", qname
));
37 add_netbios_entry(wins_client_subnet
,qname
,name_type
,NB_ACTIVE
,60*60,
42 /* add it to our WINS cache of names. give it 2 hours in the cache */
43 DEBUG(3,("DNS gave answer for %s of %s\n", qname
, inet_ntoa(addr
)));
45 return add_netbios_entry(wins_client_subnet
,qname
,name_type
,NB_ACTIVE
,
46 2*60*60,DNS
,addr
, True
);
53 static int fd_in
= -1, fd_out
= -1;
54 static int child_pid
= -1;
57 /* this is the structure that is passed between the parent and child */
60 struct in_addr result
;
63 /* a queue of pending requests waiting to be sent to the DNS child */
64 static struct packet_struct
*dns_queue
;
66 /* the packet currently being processed by the dns child */
67 static struct packet_struct
*dns_current
;
70 /***************************************************************************
71 return the fd used to gather async dns replies. This is added to the select
73 ****************************************************************************/
79 /***************************************************************************
80 handle DNS queries arriving from the parent
81 ****************************************************************************/
82 static void asyncdns_process(void)
84 struct query_record r
;
90 if (read_data(fd_in
, (char *)&r
, sizeof(r
)) != sizeof(r
))
93 fstrcpy(qname
, r
.name
.name
);
95 r
.result
.s_addr
= interpret_addr(qname
);
97 if (write_data(fd_out
, (char *)&r
, sizeof(r
)) != sizeof(r
))
105 /***************************************************************************
106 create a child process to handle DNS lookups
107 ****************************************************************************/
108 void start_async_dns(void)
112 signal(SIGCLD
, SIG_IGN
);
114 if (pipe(fd1
) || pipe(fd2
)) {
131 signal(SIGUSR2
, SIG_IGN
);
132 signal(SIGUSR1
, SIG_IGN
);
133 signal(SIGHUP
, SIG_IGN
);
139 /***************************************************************************
140 check if a particular name is already being queried
141 ****************************************************************************/
142 static BOOL
query_current(struct query_record
*r
)
144 return dns_current
&&
146 &dns_current
->packet
.nmb
.question
.question_name
);
150 /***************************************************************************
151 write a query to the child process
152 ****************************************************************************/
153 static BOOL
write_child(struct packet_struct
*p
)
155 struct query_record r
;
157 r
.name
= p
->packet
.nmb
.question
.question_name
;
159 return write_data(fd_out
, (char *)&r
, sizeof(r
)) == sizeof(r
);
162 /***************************************************************************
164 ****************************************************************************/
165 void run_dns_queue(void)
167 struct query_record r
;
168 struct packet_struct
*p
, *p2
;
174 if (!process_exists(child_pid
)) {
179 if ((size
=read_data(fd_in
, (char *)&r
, sizeof(r
))) != sizeof(r
)) {
181 DEBUG(0,("Incomplete DNS answer from child!\n"));
187 add_dns_result(&r
.name
, r
.result
);
190 if (query_current(&r
)) {
191 DEBUG(3,("DNS calling reply_name_query\n"));
193 reply_name_query(dns_current
);
197 dns_current
->locked
= False
;
198 free_packet(dns_current
);
202 /* loop over the whole dns queue looking for entries that
203 match the result we just got */
204 for (p
= dns_queue
; p
;) {
205 struct nmb_packet
*nmb
= &p
->packet
.nmb
;
206 struct nmb_name
*question
= &nmb
->question
.question_name
;
208 if (name_equal(question
, &r
.name
)) {
209 DEBUG(3,("DNS calling reply_name_query\n"));
216 p
->prev
->next
= p
->next
;
220 p
->next
->prev
= p
->prev
;
230 dns_current
= dns_queue
;
231 dns_queue
= dns_queue
->next
;
232 if (dns_queue
) dns_queue
->prev
= NULL
;
233 dns_current
->next
= NULL
;
235 if (!write_child(dns_current
)) {
236 DEBUG(3,("failed to send DNS query to child!\n"));
243 /***************************************************************************
245 ****************************************************************************/
246 BOOL
queue_dns_query(struct packet_struct
*p
,struct nmb_name
*question
,
247 struct name_record
**n
)
249 if (in_dns
|| fd_in
== -1)
253 if (!write_child(p
)) {
254 DEBUG(3,("failed to send DNS query to child!\n"));
268 DEBUG(3,("added DNS query for %s\n", namestr(question
)));
275 /***************************************************************************
276 we use this then we can't do async DNS lookups
277 ****************************************************************************/
278 BOOL
queue_dns_query(struct packet_struct
*p
,struct nmb_name
*question
,
279 struct name_record
**n
)
281 char *qname
= question
->name
;
282 struct in_addr dns_ip
;
284 DEBUG(3,("DNS search for %s - ", namestr(question
)));
286 dns_ip
.s_addr
= interpret_addr(qname
);
288 *n
= add_dns_result(question
, dns_ip
);