ubik-pause-collapsing-20020624
[openafs.git] / src / ubik / beacon.c
index c3c6f38..140927f 100644 (file)
@@ -25,6 +25,13 @@ RCSID("$Header$");
 #endif
 #include <errno.h>
 #include <lock.h>
+#ifdef HAVE_STRING_H
+#include <string.h>
+#else
+#ifdef HAVE_STRINGS_H
+#include <strings.h>
+#endif
+#endif
 #include <rx/xdr.h>
 #include <rx/rx.h>
 #include <rx/rx_multi.h>
@@ -50,6 +57,7 @@ int (*ubik_CRXSecurityProc)();
 char *ubik_CRXSecurityRock;
 afs_int32 ubikSecIndex;
 struct rx_securityClass     *ubikSecClass;
+static verifyInterfaceAddress();
 
 
 /* Module responsible for both deciding if we're currently the sync site,
@@ -170,7 +178,7 @@ ubeacon_InitServerListCommon(ame, info, clones, aservers)
     struct ubik_server *magicServer;
 
     /* verify that the addresses passed in are correct */
-    if (code = verifyInterfaceAddress(&ame, info, aservers))
+    if ((code = verifyInterfaceAddress(&ame, info, aservers)))
        return code;
 
     /* get the security index to use, if we can */
@@ -201,7 +209,7 @@ ubeacon_InitServerListCommon(ame, info, clones, aservers)
         for (i = 0; i < info->numServers; i++) {
             if (i == me) continue;
            ts = (struct ubik_server *) malloc(sizeof(struct ubik_server));
-           bzero(ts, sizeof(struct ubik_server));
+           memset(ts, 0, sizeof(struct ubik_server));
            ts->next = ubik_servers;
            ubik_servers = ts;
             ts->addr[0] = info->hostAddr[i].sin_addr.s_addr;
@@ -229,10 +237,10 @@ ubeacon_InitServerListCommon(ame, info, clones, aservers)
        }
     } else {
         i = 0;
-        while (servAddr = *aservers++) {
+        while ((servAddr = *aservers++)) {
            if (i >= MAXSERVERS) return UNHOSTS;            /* too many hosts */
            ts = (struct ubik_server *) malloc(sizeof(struct ubik_server));
-           bzero(ts, sizeof(struct ubik_server));
+           memset(ts, 0, sizeof(struct ubik_server));
            ts->next = ubik_servers;
            ubik_servers = ts;
            ts->addr[0] = servAddr;     /* primary address in  net byte order */
@@ -356,6 +364,9 @@ ubeacon_Interact() {
          }
        else
            ttid.counter = ubik_dbase->tidCounter+1;
+#if defined(UBIK_PAUSE)
+       ubik_dbase->flags |= DBVOTING;
+#endif /* UBIK_PAUSE */
 
        /* now analyze return codes, counting up our votes */
        yesVotes = 0;               /* count how many to ensure we have quorum */
@@ -403,12 +414,15 @@ ubeacon_Interact() {
        /* now call our own voter module to see if we'll vote for ourself.  Note that
            the same restrictions apply for our voting for ourself as for our voting
            for anyone else. */
-       i = SVOTE_Beacon((struct rx_connection *) 0, ubeacon_AmSyncSite(), startTime, &ubik_dbase->version, &ttid);
+       i = SVOTE_Beacon((struct rx_call *) 0, ubeacon_AmSyncSite(), startTime, &ubik_dbase->version, &ttid);
        if (i) {
            yesVotes += 2;
            if (amIMagic) yesVotes++;   /* extra epsilon */
            if (i < oldestYesVote) oldestYesVote = i;
        }
+#if defined(UBIK_PAUSE)
+       ubik_dbase->flags &= ~DBVOTING;
+#endif /* UBIK_PAUSE */
 
        /* now decide if we have enough votes to become sync site.
            Note that we can still get enough votes even if we didn't for ourself. */
@@ -447,7 +461,8 @@ static verifyInterfaceAddress(ame, info, aservers)
     afs_uint32 aservers[];     /* list of all possible server addresses */
 {
     afs_uint32 myAddr[UBIK_MAX_INTERFACE_ADDR], *servList, tmpAddr;
-    int        count, index, found, i, j, totalServers, start, end;
+    afs_uint32  myAddr2[UBIK_MAX_INTERFACE_ADDR];
+    int        count, found, i, j, totalServers, start, end, usednetfiles = 0;
 
     if (info)
         totalServers = info->numServers;
@@ -476,6 +491,7 @@ static verifyInterfaceAddress(ame, info, aservers)
        ubik_print("Aborting..\n");
        return UBADHOST;
       }
+      usednetfiles++;
     }
     else {
       /* get all my interface addresses in net byte order */
@@ -503,7 +519,32 @@ static verifyInterfaceAddress(ame, info, aservers)
     {
        ubik_print("ubik: primary address %s does not exist\n",
                        afs_inet_ntoa(*ame));
-       return UBADHOST;
+       /* if we had the result of rx_getAllAddr already, avoid subverting
+          the "is gethostbyname(gethostname()) us" check. If we're
+          using NetInfo/NetRestrict, we assume they have enough clue
+          to avoid that big hole in their foot from the loaded gun. */
+       if (usednetfiles) {
+           /* take the address we did get, then see if ame was masked */
+           *ame=myAddr[0];
+           count = rx_getAllAddr(myAddr2, UBIK_MAX_INTERFACE_ADDR); 
+           if ( count <= 0 )           /* no address found */
+           {
+               ubik_print("ubik: No network addresses found, aborting..");
+               return UBADHOST;
+           }
+           
+           /* verify that the My-address passed in by ubik is correct */
+           for ( j=0, found = 0; j < count; j++)
+           {
+               if ( *ame == myAddr2[j] ) /* both in net byte order */
+               {
+                   found = 1;
+                   break;
+               }
+           }
+       }
+       if ( !found )
+           return UBADHOST;
     }
 
     /* if any of my addresses are there in serverList, then
@@ -574,7 +615,7 @@ int
 updateUbikNetworkAddress(ubik_host)
 afs_uint32 ubik_host[UBIK_MAX_INTERFACE_ADDR];
 {
-    int                        j, count, found, index, code = 0;
+    int                        j, count, code = 0;
     UbikInterfaceAddr   inAddr, outAddr;
     struct rx_connection *conns[MAXSERVERS];
     struct ubik_server         *ts, *server[MAXSERVERS];