changed the format of the wins.dat file slightly.
authorAndrew Tridgell <tridge@samba.org>
Sun, 30 Aug 1998 05:43:59 +0000 (05:43 +0000)
committerAndrew Tridgell <tridge@samba.org>
Sun, 30 Aug 1998 05:43:59 +0000 (05:43 +0000)
It now has a line like this:

VERSION 1 251152

the first number is a version #define in nmbd_winsserver.c and will be
used if we ever have to change the format again.

The second number is a hash of the current interfaces setting. It is
used to detect the case where nmbd is restarted on a machine after the
IP of the machine has changed (or the interfaces list has changed in
any way). When that happens we need to discard the old wins.dat cache
or you end up with chaos. This has bitten quite a few people, they
find that when they move a machine it continues using the old IP for
some things for the next week until the wins entries time out!

I've checked, and the old nmbd can handle the new format, although it
does spit out a spurious error message about the VERSION line. So
users can safely run 2.0alpha then switch back to 1.9.18 without
problems.
(This used to be commit c4a8cdc60a5b01894ab2456e77b6d89d4c16a088)

source3/include/proto.h
source3/lib/interface.c
source3/nmbd/nmbd_winsserver.c

index 991e4f3e31d1ad00a765b2c9574395f8577cb251..0312d25f86aeb0e7a8b947af5cfa62b5867c197b 100644 (file)
@@ -102,6 +102,7 @@ int iface_count(void);
 BOOL we_are_multihomed(void);
 struct interface *get_interface(int n);
 struct in_addr *iface_n_ip(int n);
+unsigned iface_hash(void);
 struct in_addr *iface_bcast(struct in_addr ip);
 struct in_addr *iface_nmask(struct in_addr ip);
 struct in_addr *iface_ip(struct in_addr ip);
index 7aae803abf3dfcf5e0051324b4d8ee55faa66fa8..8cc5cfb0b16ff36040760c80423b51f8efb41248 100644 (file)
@@ -350,6 +350,28 @@ static struct interface *iface_find(struct in_addr ip)
   return NULL;
 }
 
+
+/****************************************************************************
+this function provides a simple hash of the configured interfaces. It is
+used to detect a change in interfaces to tell us whether to discard
+the current wins.dat file.
+Note that the result is independent of the order of the interfaces
+  **************************************************************************/
+unsigned iface_hash(void)
+{
+       unsigned ret = 0;
+       struct interface *i;
+
+       for (i=local_interfaces;i;i=i->next) {
+               unsigned x1 = (unsigned)str_checksum(inet_ntoa(i->ip));
+               unsigned x2 = (unsigned)str_checksum(inet_ntoa(i->nmask));
+               ret ^= (x1 ^ x2);
+       }
+
+       return ret;
+}
+
+
 /* these 3 functions return the ip/bcast/nmask for the interface
    most appropriate for the given ip address. If they can't find
    an appropriate interface they return the requested field of the
index dfa52a65f81244354073678f25f923b71e005833..11e0aaecd62feccf83929ab0187789134f329b88 100644 (file)
@@ -24,6 +24,7 @@
 #include "includes.h"
 
 #define WINS_LIST "wins.dat"
+#define WINS_VERSION 1
 
 extern int DEBUGLEVEL;
 extern struct in_addr ipzero;
@@ -158,6 +159,8 @@ BOOL initialise_wins(void)
     BOOL got_token;
     BOOL was_ip;
     int i;
+    unsigned hash;
+    int version;
 
     /* Read a line from the wins.dat file. Strips whitespace
        from the beginning and end of the line.
@@ -168,6 +171,17 @@ BOOL initialise_wins(void)
     if (*line == '#')
       continue;
 
+    if (strncmp(line,"VERSION ", 8) == 0) {
+           if (sscanf(line,"VERSION %d %u", &version, &hash) != 2 ||
+               version != WINS_VERSION ||
+               hash != iface_hash()) {
+                   DEBUG(0,("Discarding invalid wins.dat file [%s]\n",line));
+                   fclose(fp);
+                   return True;
+           }
+           continue;
+    }
+
     ptr = line;
 
     /* 
@@ -1561,6 +1575,8 @@ void wins_write_database(void)
   }
 
   DEBUG(4,("wins_write_database: Dump of WINS name list.\n"));
+
+  fprintf(fp,"VERSION %d %u\n", WINS_VERSION, iface_hash());
  
   for( namerec 
            = (struct name_record *)ubi_trFirst( wins_server_subnet->namelist );