sorted out various timer delay bugs: nameannounce.c nameserv.c
[Samba.git] / source / nameresp.c
blob3a9d46bf9d8ae163a51dc004f4de3a0ec6d5e442
1 /*
2 Unix SMB/Netbios implementation.
3 Version 1.9.
4 NBT netbios library routines
5 Copyright (C) Andrew Tridgell 1994-1996
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.
21 Module name: nameresp.c
25 #include "includes.h"
27 extern int ClientNMB;
28 extern int ClientDGRAM;
30 extern struct subnet_record *subnetlist;
32 extern int DEBUGLEVEL;
34 extern pstring scope;
35 extern struct in_addr ipzero;
36 extern struct in_addr ipgrp;
39 /***************************************************************************
40 deals with an entry before it dies
41 **************************************************************************/
42 static void dead_netbios_entry(struct subnet_record *d,
43 struct response_record *n)
45 DEBUG(3,("Removing dead netbios entry for %s %s (num_msgs=%d)\n",
46 inet_ntoa(n->send_ip), namestr(&n->name), n->num_msgs));
48 switch (n->state)
50 case NAME_QUERY_CONFIRM:
52 if (!lp_wins_support()) return; /* only if we're a WINS server */
54 if (n->num_msgs == 0)
56 /* oops. name query had no response. check that the name is
57 unique and then remove it from our WINS database */
59 /* IMPORTANT: see query_refresh_names() */
61 if ((!NAME_GROUP(n->nb_flags)))
63 struct subnet_record *d1 = find_subnet(ipgrp);
64 if (d1)
66 /* remove the name that had been registered with us,
67 and we're now getting no response when challenging.
68 see rfc1001.txt 15.5.2
70 remove_netbios_name(d1, n->name.name, n->name.name_type,
71 REGISTER, n->send_ip);
75 break;
78 case NAME_QUERY_MST_CHK:
80 /* if no response received, the master browser must have gone
81 down on that subnet, without telling anyone. */
83 /* IMPORTANT: see response_netbios_packet() */
85 if (n->num_msgs == 0)
86 browser_gone(n->name.name, n->send_ip);
87 break;
90 case NAME_RELEASE:
92 /* if no response received, it must be OK for us to release the
93 name. nobody objected (including a potentially dead or deaf
94 WINS server) */
96 /* IMPORTANT: see response_name_release() */
98 if (ismyip(n->send_ip))
100 name_unregister_work(d,n->name.name,n->name.name_type);
102 if (!n->bcast)
104 DEBUG(0,("WINS server did not respond to name release!\n"));
105 /* XXXX whoops. we have problems. must deal with this */
107 break;
110 case NAME_REGISTER_CHALLENGE:
112 /* name challenge: no reply. we can reply to the person that
113 wanted the unique name and tell them that they can have it
116 add_netbios_entry(d, n->name.name, n->name.name_type,
117 n->nb_flags, GET_TTL(0), REGISTER,
118 n->reply_to_ip, False, True);
120 send_name_response(n->fd, n->response_id, NMB_REG,
121 True, True,
122 &n->name, n->nb_flags, GET_TTL(0), n->reply_to_ip);
123 break;
125 case NAME_REGISTER:
127 /* if no response received, and we are using a broadcast registration
128 method, it must be OK for us to register the name: nobody objected
129 on that subnet. if we are using a WINS server, then the WINS
130 server must be dead or deaf.
132 if (n->bcast)
134 /* broadcast method: implicit acceptance of the name registration
135 by not receiving any objections. */
137 /* IMPORTANT: see response_name_reg() */
139 name_register_work(d,n->name.name,n->name.name_type,
140 n->nb_flags, n->ttl, n->send_ip, n->bcast);
142 else
144 /* XXXX oops. this is where i wish this code could retry DGRAM
145 packets. we directed a name registration at a WINS server, and
146 received no response. rfc1001.txt states that after retrying,
147 we should assume the WINS server is dead, and fall back to
148 broadcasting. */
150 DEBUG(1,("WINS server did not respond to name registration!\n"));
151 /* XXXX whoops. we have problems. must deal with this */
153 break;
156 default:
158 /* nothing to do but delete the dead expected-response structure */
159 /* this is normal. */
160 break;
166 /*******************************************************************
167 remove old name response entries
169 XXXX retry code needs to be added, including a retry wait period and a count
170 see name_query() and name_status() for suggested implementation.
172 ******************************************************************/
173 void expire_netbios_response_entries()
175 struct subnet_record *d;
177 for (d = subnetlist; d; d = d->next)
179 struct response_record *n, *nextn;
181 for (n = d->responselist; n; n = nextn)
183 nextn = n->next;
185 if (n->repeat_time <= time(NULL))
187 if (n->repeat_count > 0)
189 /* resend the entry */
190 initiate_netbios_packet(&n->response_id, n->fd, n->quest_type,
191 n->name.name, n->name.name_type,
192 n->nb_flags, n->bcast, n->recurse, n->send_ip);
194 n->repeat_time += n->repeat_interval; /* XXXX ms needed */
195 n->repeat_count--;
198 else
200 DEBUG(4,("timeout response %d for %s %s\n",
201 n->response_id, namestr(&n->name),
202 inet_ntoa(n->send_ip)));
204 dead_netbios_entry (d,n); /* process the non-response */
205 remove_response_record(d,n); /* remove the non-response */
207 continue;
215 /****************************************************************************
216 wrapper function to override a broadcast message and send it to the WINS
217 name server instead, if it exists. if wins is false, and there has been no
218 WINS server specified, the packet will NOT be sent.
219 ****************************************************************************/
220 struct response_record *queue_netbios_pkt_wins(struct subnet_record *d,
221 int fd,int quest_type,enum state_type state,
222 char *name,int name_type,int nb_flags, time_t ttl,
223 BOOL bcast,BOOL recurse,
224 struct in_addr send_ip, struct in_addr reply_to_ip)
226 /* XXXX note: please see rfc1001.txt section 10 for details on this
227 function: it is currently inappropriate to use this - it will do
228 for now - once there is a clarification of B, M and P nodes and
229 which one samba is supposed to be
232 if ((!lp_wins_support()) && (*lp_wins_server()))
234 /* samba is not a WINS server, and we are using a WINS server */
235 struct in_addr wins_ip;
236 wins_ip = *interpret_addr2(lp_wins_server());
238 if (!zero_ip(wins_ip))
240 bcast = False;
241 send_ip = wins_ip;
243 else
245 /* oops. smb.conf's wins server parameter MUST be a host_name
246 or an ip_address. */
247 DEBUG(0,("invalid smb.conf parameter 'wins server'\n"));
251 if (zero_ip(send_ip)) return NULL;
253 return queue_netbios_packet(d,fd, quest_type, state,
254 name, name_type, nb_flags, ttl,
255 bcast, recurse, send_ip, reply_to_ip);
259 /****************************************************************************
260 initiate a netbios name query to find someone's or someones' IP
261 this is intended to be used (not exclusively) for broadcasting to
262 master browsers (WORKGROUP(1d or 1b) or __MSBROWSE__(1)) to get
263 complete lists across a wide area network
264 ****************************************************************************/
265 struct response_record *queue_netbios_packet(struct subnet_record *d,
266 int fd,int quest_type,enum state_type state,char *name,
267 int name_type,int nb_flags, time_t ttl,
268 BOOL bcast,BOOL recurse,
269 struct in_addr send_ip, struct in_addr reply_to_ip)
271 struct in_addr wins_ip = ipgrp;
272 struct response_record *n;
273 uint16 id = 0xffff;
275 /* ha ha. no. do NOT broadcast to 255.255.255.255: it's a pseudo address */
276 if (ip_equal(wins_ip, send_ip)) return NULL;
278 initiate_netbios_packet(&id, fd, quest_type, name, name_type,
279 nb_flags, bcast, recurse, send_ip);
281 if (id == 0xffff) {
282 DEBUG(4,("did not initiate netbios packet: %s\n", inet_ntoa(send_ip)));
283 return NULL;
286 if ((n = make_response_queue_record(state,id,fd,
287 quest_type,name,name_type,nb_flags,ttl,
288 bcast,recurse,send_ip,reply_to_ip)))
290 add_response_record(d,n);
291 return n;
293 return NULL;