summaryrefslogtreecommitdiff
path: root/source3/nameresp.c
diff options
context:
space:
mode:
authorSamba Release Account <samba-bugs@samba.org>1996-07-01 18:29:21 +0000
committerSamba Release Account <samba-bugs@samba.org>1996-07-01 18:29:21 +0000
commit7a804a2e838846715f036e5e93630a4436a4ec4b (patch)
treec31452440cd49448bec35d4abba4b89ee659165f /source3/nameresp.c
parenta853abd9ae082d5b69093e662a57194b17babaff (diff)
downloadsamba-7a804a2e838846715f036e5e93630a4436a4ec4b.tar.gz
samba-7a804a2e838846715f036e5e93630a4436a4ec4b.tar.bz2
samba-7a804a2e838846715f036e5e93630a4436a4ec4b.zip
updated the NetBIOS code due to some bugs found by writing the first draft
of the low level design docs. (This used to be commit 103012e5f2fac09598d60c4263c3a30992680729)
Diffstat (limited to 'source3/nameresp.c')
-rw-r--r--source3/nameresp.c82
1 files changed, 50 insertions, 32 deletions
diff --git a/source3/nameresp.c b/source3/nameresp.c
index 31df799691..14b9956186 100644
--- a/source3/nameresp.c
+++ b/source3/nameresp.c
@@ -39,6 +39,19 @@ extern struct in_addr ipgrp;
int num_response_packets = 0;
/***************************************************************************
+ updates the unique transaction identifier
+ **************************************************************************/
+static void update_name_trn_id(void)
+{
+ if (!name_trn_id)
+ {
+ name_trn_id = (time(NULL)%(unsigned)0x7FFF) + (getpid()%(unsigned)100);
+ }
+ name_trn_id = (name_trn_id+1) % (unsigned)0x7FFF;
+}
+
+
+/***************************************************************************
add an initated name query into the list
**************************************************************************/
static void add_response_record(struct subnet_record *d,
@@ -74,20 +87,20 @@ static void dead_netbios_entry(struct subnet_record *d,
inet_ntoa(n->to_ip), namestr(&n->name), n->num_msgs));
switch (n->cmd_type)
- {
+ {
case NAME_QUERY_CONFIRM:
- {
+ {
if (!lp_wins_support()) return; /* only if we're a WINS server */
- if (n->num_msgs == 0)
+ if (n->num_msgs == 0)
{
/* oops. name query had no response. check that the name is
unique and then remove it from our WINS database */
-
+
/* IMPORTANT: see query_refresh_names() */
-
+
if ((!NAME_GROUP(n->nb_flags)))
- {
+ {
struct subnet_record *d = find_subnet(ipgrp);
if (d)
{
@@ -97,24 +110,24 @@ static void dead_netbios_entry(struct subnet_record *d,
*/
remove_netbios_name(d, n->name.name, n->name.name_type,
REGISTER, n->to_ip);
- }
- }
-}
+ }
+ }
+ }
break;
}
case NAME_QUERY_MST_CHK:
-{
+ {
/* if no response received, the master browser must have gone
down on that subnet, without telling anyone. */
-
+
/* IMPORTANT: see response_netbios_packet() */
if (n->num_msgs == 0)
browser_gone(n->name.name, n->to_ip);
break;
}
-
+
case NAME_RELEASE:
{
/* if no response received, it must be OK for us to release the
@@ -122,7 +135,7 @@ static void dead_netbios_entry(struct subnet_record *d,
WINS server) */
/* IMPORTANT: see response_name_release() */
-
+
if (ismyip(n->to_ip))
{
remove_netbios_name(d,n->name.name,n->name.name_type,SELF,n->to_ip);
@@ -133,7 +146,7 @@ static void dead_netbios_entry(struct subnet_record *d,
}
break;
}
-
+
case NAME_REGISTER:
{
/* if no response received, and we are using a broadcast registration
@@ -145,14 +158,14 @@ static void dead_netbios_entry(struct subnet_record *d,
{
/* broadcast method: implicit acceptance of the name registration
by not receiving any objections. */
-
+
/* IMPORTANT: see response_name_reg() */
-
+
enum name_source source = ismyip(n->to_ip) ? SELF : REGISTER;
-
+
add_netbios_entry(d,n->name.name,n->name.name_type,
n->nb_flags, n->ttl, source,n->to_ip, True,!n->bcast);
- }
+ }
else
{
/* XXXX oops. this is where i wish this code could retry DGRAM
@@ -160,12 +173,12 @@ static void dead_netbios_entry(struct subnet_record *d,
received no response. rfc1001.txt states that after retrying,
we should assume the WINS server is dead, and fall back to
broadcasting. */
-
+
DEBUG(1,("WINS server did not respond to name registration!\n"));
}
break;
}
-
+
default:
{
/* nothing to do but delete the dead expected-response structure */
@@ -181,8 +194,8 @@ static void dead_netbios_entry(struct subnet_record *d,
****************************************************************************/
static void initiate_netbios_packet(uint16 *id,
int fd,int quest_type,char *name,int name_type,
- int nb_flags,BOOL bcast,BOOL recurse,
- struct in_addr to_ip)
+ int nb_flags,BOOL bcast,BOOL recurse,
+ struct in_addr to_ip)
{
struct packet_struct p;
struct nmb_packet *nmb = &p.packet.nmb;
@@ -204,9 +217,7 @@ static void initiate_netbios_packet(uint16 *id,
bzero((char *)&p,sizeof(p));
- if (!name_trn_id) name_trn_id = (time(NULL)%(unsigned)0x7FFF) +
- (getpid()%(unsigned)100);
- name_trn_id = (name_trn_id+1) % (unsigned)0x7FFF;
+ update_name_trn_id();
if (*id == 0xffff) *id = name_trn_id; /* allow resending with same id */
@@ -409,7 +420,7 @@ void queue_netbios_pkt_wins(struct subnet_record *d,
static struct response_record *
make_response_queue_record(enum cmd_type cmd,int id,int fd,
int quest_type, char *name,int type, int nb_flags, time_t ttl,
- BOOL bcast,BOOL recurse,struct in_addr ip)
+ BOOL bcast,BOOL recurse, struct in_addr ip)
{
struct response_record *n;
@@ -476,19 +487,24 @@ void queue_netbios_packet(struct subnet_record *d,
/****************************************************************************
find a response in a subnet's name query response list.
**************************************************************************/
-struct response_record *find_response_record(struct subnet_record *d,
+struct response_record *find_response_record(struct subnet_record **d,
uint16 id)
-{
+{
struct response_record *n;
if (!d) return NULL;
- for (n = d->responselist; n; n = n->next)
+ for ((*d) = subnetlist; (*d); (*d) = (*d)->next)
+ {
+ for (n = (*d)->responselist; n; n = n->next)
{
- if (n->response_id == id) {
- return n;
+ if (n->response_id == id) {
+ return n;
}
}
+ }
+
+ *d = NULL;
return NULL;
}
@@ -724,11 +740,13 @@ BOOL send_mailslot_reply(char *mailslot,int fd,char *buf,int len,char *srcname,
bzero((char *)&p,sizeof(p));
+ update_name_trn_id();
+
dgram->header.msg_type = 0x11; /* DIRECT GROUP DATAGRAM */
dgram->header.flags.node_type = M_NODE;
dgram->header.flags.first = True;
dgram->header.flags.more = False;
- dgram->header.dgm_id = name_trn_id++;
+ dgram->header.dgm_id = name_trn_id;
dgram->header.source_ip = src_ip;
dgram->header.source_port = DGRAM_PORT;
dgram->header.dgm_length = 0; /* let build_dgram() handle this */