Move epoch and cid generation into the rx core
authorBen Kaduk <kaduk@mit.edu>
Tue, 26 Mar 2013 17:41:40 +0000 (13:41 -0400)
committerJeffrey Altman <jaltman@your-file-system.com>
Wed, 10 Sep 2014 19:05:32 +0000 (15:05 -0400)
Now that we have hcrypto available everywhere, we can get real randomness
in the rx core (both uerspace and kernel), and thus can initialize the
RX epoch to a real random value when first initializing a host; there is
no need to rely on rxkad to produce randomness for this purpose.
Initialize a connection ID counter at the same time, and use that in
rx_NewConnection, also supplanting rxkad-specific logic.

The rxkad-specific logic is removed, and in particular there is no longer
a need to export rxkad_EpochWasSet to the rest of the world.
The code in afs_Daemon() to check whether the rxepoch was set can be
removed, as if the epoch is not set, rx initialization fails.

Add libafshcrypto to LIBS in the handful of places it hadn't crept already,
and likewise afshcrypto.lib in the NTMakefiles.

Change-Id: I1dd1015b29a600aaf72b6b4b36f8a17032453c97
Reviewed-on: http://gerrit.openafs.org/10841
Tested-by: BuildBot <buildbot@rampaginggeek.com>
Reviewed-by: Jeffrey Altman <jaltman@your-file-system.com>

21 files changed:
src/afs/afs_daemons.c
src/afsmonitor/Makefile.in
src/auth/test/NTMakefile
src/kauth/test/NTMakefile
src/rx/rx.c
src/rx/test/generator.c
src/rxdebug/Makefile.in
src/rxdebug/NTMakefile
src/rxkad/private_data.h
src/rxkad/rxkad.p.h
src/rxkad/rxkad_client.c
src/rxkad/rxkad_common.c
src/rxkad/test/NTMakefile
src/tools/dumpscan/Makefile.in
src/ubik/Makefile.in
src/ubik/NTMakefile
src/venus/Makefile.in
src/vol/Makefile.in
src/volser/Makefile.in
src/xstat/Makefile.in
src/xstat/NTMakefile

index 4f51b50..fb79170 100644 (file)
@@ -36,10 +36,6 @@ struct brequest afs_brs[NBRS];       /* request structures */
 struct afs_osi_WaitHandle AFS_WaitHandler, AFS_CSWaitHandler;
 static int afs_brs_count = 0;  /* request counter, to service reqs in order */
 
-static int rxepoch_checked = 0;
-#define afs_CheckRXEpoch() {if (rxepoch_checked == 0 && rxkad_EpochWasSet) { \
-       rxepoch_checked = 1; afs_GCUserData(/* force flag */ 1);  } }
-
 /* PAG garbage collection */
 /* We induce a compile error if param.h does not define AFS_GCPAGS */
 afs_int32 afs_gcpags = AFS_GCPAGS;
@@ -202,7 +198,6 @@ afs_Daemon(void)
 #if 0
            afs_StoreDirtyVcaches();
 #endif
-           afs_CheckRXEpoch();
            last1MinCheck = now;
        }
 
@@ -1189,7 +1184,7 @@ shutdown_daemons(void)
     AFS_STATCNT(shutdown_daemons);
     if (afs_cold_shutdown) {
        afs_brsDaemons = brsInit = 0;
-       rxepoch_checked = afs_nbrs = 0;
+       afs_nbrs = 0;
        memset(afs_brs, 0, sizeof(afs_brs));
        memset(&afs_xbrs, 0, sizeof(afs_lock_t));
        afs_brsWaiters = 0;
index b8cd117..73ef4d2 100644 (file)
@@ -32,6 +32,7 @@ LIBS=${TOP_LIBDIR}/libxstat_fs.a \
        ${TOP_LIBDIR}/libafsint.a \
        ${TOP_LIBDIR}/libcmd.a \
        ${TOP_LIBDIR}/librx.a \
+       ${TOP_LIBDIR}/libafshcrypto_lwp.a \
        ${TOP_LIBDIR}/liblwp.a \
        ${TOP_LIBDIR}/libsys.a \
        $(TOP_LIBDIR)/libopr.a \
index b1fa46c..8891d61 100644 (file)
@@ -42,6 +42,7 @@ KTC_EXELIBS =\
        $(DESTDIR)\lib\afs\afsutil.lib \
        $(DESTDIR)\lib\afs\afsauth.lib \
        $(DESTDIR)\lib\afsrx.lib \
+       $(DESTDIR)\lib\afshcrypto.lib \
        $(DESTDIR)\lib\afslwp.lib \
        $(DESTDIR)\lib\afs\afsreg.lib \
        $(DESTDIR)\lib\afs\afspioctl.lib \
index 8a836c7..a5eebca 100644 (file)
@@ -17,6 +17,7 @@ EXELIBS = \
        $(DESTDIR)\afsubik.lib \
        $(DESTDIR)\afs\afsprot.lib \
        $(DESTDIR)\afsrx.lib \
+       $(DESTDIR)\lib\afshcrypto.lib \
        $(DESTDIR)\afs\afscom_err.lib \
        $(DESTDIR)\afs\afskauth.lib \
        $(DESTDIR)\lib\afsrfc3961.lib
index 68b7b02..07c6d73 100644 (file)
@@ -73,6 +73,7 @@ extern afs_int32 afs_termState;
 #endif /* KERNEL */
 
 #include <opr/queue.h>
+#include <hcrypto/rand.h>
 
 #include "rx.h"
 #include "rx_clock.h"
@@ -157,6 +158,7 @@ static void rxi_AckAllInTransmitQueue(struct rx_call *call);
 static void rxi_CancelKeepAliveEvent(struct rx_call *call);
 static void rxi_CancelDelayedAbortEvent(struct rx_call *call);
 static void rxi_CancelGrowMTUEvent(struct rx_call *call);
+static void update_nextCid(void);
 
 #ifdef RX_ENABLE_LOCKS
 struct rx_tq_debug {
@@ -394,6 +396,7 @@ struct rx_connection *rxLastConn = 0;
  * tiers:
  *
  * rx_connHashTable_lock - synchronizes conn creation, rx_connHashTable access
+ *                         also protects updates to rx_nextCid
  * conn_call_lock - used to synchonize rx_EndCall and rx_NewCall
  * call->lock - locks call data fields.
  * These are independent of each other:
@@ -440,13 +443,6 @@ struct rx_serverQueueEntry *rx_waitForPacket = 0;
 
 /* ------------Exported Interfaces------------- */
 
-/* This function allows rxkad to set the epoch to a suitably random number
- * which rx_NewConnection will use in the future.  The principle purpose is to
- * get rxnull connections to use the same epoch as the rxkad connections do, at
- * least once the first rxkad connection is established.  This is important now
- * that the host/port addresses aren't used in FindConnection: the uniqueness
- * of epoch/cid matters and the start time won't do. */
-
 #ifdef AFS_PTHREAD_ENV
 /*
  * This mutex protects the following global variables:
@@ -608,12 +604,12 @@ rx_InitHost(u_int host, u_int port)
 #endif
     }
     rx_stats.minRtt.sec = 9999999;
-#ifdef KERNEL
-    rx_SetEpoch(tv.tv_sec | 0x80000000);
-#else
-    rx_SetEpoch(tv.tv_sec);    /* Start time of this package, rxkad
-                                * will provide a randomer value. */
-#endif
+    if (RAND_bytes(&rx_epoch, sizeof(rx_epoch)) != 1)
+       return -1;
+    rx_epoch  = (rx_epoch & ~0x40000000) | 0x80000000;
+    if (RAND_bytes(&rx_nextCid, sizeof(rx_nextCid)) != 1)
+       return -1;
+    rx_nextCid &= RX_CIDMASK;
     MUTEX_ENTER(&rx_quota_mutex);
     rxi_dataQuota += rx_extraQuota; /* + extra pkts caller asked to rsrv */
     MUTEX_EXIT(&rx_quota_mutex);
@@ -1042,7 +1038,6 @@ rx_NewConnection(afs_uint32 shost, u_short sport, u_short sservice,
                 int serviceSecurityIndex)
 {
     int hashindex, i;
-    afs_int32 cid;
     struct rx_connection *conn;
 
     SPLVAR;
@@ -1063,10 +1058,10 @@ rx_NewConnection(afs_uint32 shost, u_short sport, u_short sservice,
 #endif
     NETPRI;
     MUTEX_ENTER(&rx_connHashTable_lock);
-    cid = (rx_nextCid += RX_MAXCALLS);
     conn->type = RX_CLIENT_CONNECTION;
-    conn->cid = cid;
     conn->epoch = rx_epoch;
+    conn->cid = rx_nextCid;
+    update_nextCid();
     conn->peer = rxi_FindPeer(shost, sport, 1);
     conn->serviceId = sservice;
     conn->securityObject = securityObject;
@@ -6726,6 +6721,19 @@ rxi_CancelGrowMTUEvent(struct rx_call *call)
     }
 }
 
+/*
+ * Increment the counter for the next connection ID, handling overflow.
+ */
+static void
+update_nextCid(void)
+{
+    /* Overflow is technically undefined behavior; avoid it. */
+    if (rx_nextCid > MAX_AFS_INT32 - (1 << RX_CIDSHIFT))
+       rx_nextCid = -1 * ((MAX_AFS_INT32 / RX_CIDSHIFT) * RX_CIDSHIFT);
+    else
+       rx_nextCid += 1 << RX_CIDSHIFT;
+}
+
 static void
 rxi_KeepAliveOn(struct rx_call *call)
 {
index 8f3d929..d2cb3e9 100644 (file)
@@ -107,6 +107,7 @@ static char *nt_symbols[] = {
 /* all one string */
     "LIBS = $(DESTDIR)/lib/afsrxkad.lib \\\n"
        "\t$(DESTDIR)/lib/afsdes.lib \\\n" "\t$(DESTDIR)/lib/afsrx.lib \\\n"
+       "\t$(DESTDIR)/lib/afshcrypto.lib \\\n"
        "\t$(DESTDIR)/lib/afslwp.lib \\\n"
        "\t$(DESTDIR)/lib/afs/afscmd.lib \\\n"
        "\t$(DESTDIR)/lib/afs/afsafs_com_err.lib \\\n"
index df83359..18dfc33 100644 (file)
@@ -11,6 +11,7 @@ include @TOP_OBJDIR@/src/config/Makefile.lwp
 
 
 LIBS=${TOP_LIBDIR}/librx.a \
+     ${TOP_LIBDIR}/libafshcrypto_lwp.a \
      ${TOP_LIBDIR}/liblwp.a \
      ${TOP_LIBDIR}/libcmd.a \
      ${TOP_LIBDIR}/libsys.a \
index 21c4416..17bc0e4 100644 (file)
@@ -22,6 +22,7 @@ RXDOBJS = $(OUT)\rxdebug.obj \
 LIBDIR  = $(DESTDIR)\lib
 RXDLIBS = $(LIBDIR)\afs\afscmd.lib \
          $(LIBDIR)\afsrx.lib \
+         $(LIBDIR)\afshcrypto.lib \
          $(LIBDIR)\afslwp.lib \
          $(LIBDIR)\afs\afsutil.lib \
           $(LIBDIR)\afs\afsreg.lib \
index fc4ccf6..b0caeb9 100644 (file)
@@ -36,18 +36,6 @@ struct rxkad_endpoint {
     afs_int32 securityIndex;   /* security index */
 };
 
-/* structure used for generating connection IDs; must be encrypted in network
- * byte order.  Also must be a multiple of 8 bytes for encryption to work
- * properly.
- */
-struct rxkad_cidgen {
-    struct clock time;         /* time now */
-    afs_int32 random1;         /* some implementation-specific random info */
-    afs_int32 random2;         /* more random info */
-    afs_int32 counter;         /* a counter */
-    afs_int32 ipAddr;          /* or an approximation to it */
-};
-
 #define PDATA_SIZE(l) (sizeof(struct rxkad_cprivate) - MAXKTCTICKETLEN + (l))
 
 /* private data in client-side security object */
index 141f534..160644d 100644 (file)
@@ -90,7 +90,6 @@ typedef signed char rxkad_level;
     ((((type) == 1) || ((type) == 2)) ? ((type)-1) : 0)
 
 
-extern int rxkad_EpochWasSet;  /* TRUE => we called rx_SetEpoch */
 /* Get key by enctype.  Takes a rock (path to conf dir), kvno and enctype as
  * input and returns the key and key length.  On input, the keylength parameter
  * must be set to the length of storage allocated by the caller. */
index 71866b7..2f89425 100644 (file)
@@ -68,82 +68,6 @@ static struct rx_securityOps rxkad_client_ops = {
     0,
 };
 
-/* To minimize changes to epoch, we set this Cuid once, and everyone (including
- * rxnull) uses it after that.  This means that the Ksession of the first
- * authencticated connection should be a good one. */
-
-#ifdef AFS_PTHREAD_ENV
-/*
- * This mutex protects the following global variables:
- * Cuid
- * counter
- * rxkad_EpochWasSet
- */
-pthread_mutex_t rxkad_client_uid_mutex;
-#define LOCK_CUID osi_Assert(pthread_mutex_lock(&rxkad_client_uid_mutex)==0)
-#define UNLOCK_CUID osi_Assert(pthread_mutex_unlock(&rxkad_client_uid_mutex)==0)
-#else
-#define LOCK_CUID
-#define UNLOCK_CUID
-#endif /* AFS_PTHREAD_ENV */
-
-static afs_int32 Cuid[2];      /* set once and shared by all */
-int rxkad_EpochWasSet = 0;     /* TRUE => we called rx_SetEpoch */
-
-/* allocate a new connetion ID in place */
-int
-rxkad_AllocCID(struct rx_securityClass *aobj, struct rx_connection *aconn)
-{
-    struct rxkad_cprivate *tcp;
-    struct rxkad_cidgen tgen;
-    static afs_int32 counter = 0;      /* not used anymore */
-
-    LOCK_CUID;
-    if (Cuid[0] == 0) {
-       afs_uint32 xor[2];
-       tgen.ipAddr = rxi_getaddr();    /* comes back in net order */
-       clock_GetTime(&tgen.time);      /* changes time1 and time2 */
-       tgen.time.sec = htonl(tgen.time.sec);
-       tgen.time.usec = htonl(tgen.time.usec);
-       tgen.counter = htonl(counter);
-       counter++;
-#ifdef KERNEL
-       tgen.random1 = afs_random() & 0x7fffffff;       /* was "80000" */
-       tgen.random2 = afs_random() & 0x7fffffff;       /* was "htonl(100)" */
-#else
-       tgen.random1 = htonl(getpid());
-       tgen.random2 = htonl(100);
-#endif
-       if (aobj) {
-           /* block is ready for encryption with session key, let's go for it. */
-           tcp = (struct rxkad_cprivate *)aobj->privateData;
-           memcpy((void *)xor, (void *)tcp->ivec, 2 * sizeof(afs_int32));
-           fc_cbc_encrypt((char *)&tgen, (char *)&tgen, sizeof(tgen),
-                          tcp->keysched, xor, ENCRYPT);
-       } else {
-           /* Create a session key so that we can encrypt it */
-
-       }
-       memcpy((void *)Cuid,
-              ((char *)&tgen) + sizeof(tgen) - ENCRYPTIONBLOCKSIZE,
-              ENCRYPTIONBLOCKSIZE);
-       Cuid[0] = (Cuid[0] & ~0x40000000) | 0x80000000;
-       Cuid[1] &= RX_CIDMASK;
-       rx_SetEpoch(Cuid[0]);   /* for future rxnull connections */
-       rxkad_EpochWasSet++;
-    }
-
-    if (!aconn) {
-       UNLOCK_CUID;
-       return 0;
-    }
-    rx_SetConnectionEpoch(aconn, Cuid[0]);
-    rx_SetConnectionId(aconn, Cuid[1]);
-    Cuid[1] += 1 << RX_CIDSHIFT;
-    UNLOCK_CUID;
-    return 0;
-}
-
 /* Allocate a new client security object.  Called with the encryption level,
  * the session key and the ticket for the other side obtained from the
  * AuthServer.  Refers to export control to determine level. */
@@ -287,12 +211,3 @@ rxkad_GetResponse(struct rx_securityClass *aobj, struct rx_connection *aconn,
     rx_SetDataSize(apacket, responseSize + tcp->ticketLen);
     return 0;
 }
-
-void
-rxkad_ResetState(void)
-{
-    LOCK_CUID;
-    Cuid[0] = 0;
-    rxkad_EpochWasSet = 0;
-    UNLOCK_CUID;
-}
index 0f14e4b..463573c 100644 (file)
@@ -70,7 +70,6 @@ struct rxkad_stats rxkad_stats;
 #ifdef AFS_PTHREAD_ENV
 /* Pthread initialisation */
 static pthread_once_t rxkad_once_init = PTHREAD_ONCE_INIT;
-extern pthread_mutex_t rxkad_client_uid_mutex;
 extern pthread_mutex_t rxkad_random_mutex;
 
 static void
@@ -83,7 +82,6 @@ rxkad_global_stats_init(void)
 
 static void
 rxkad_InitPthread(void) {
-    MUTEX_INIT(&rxkad_client_uid_mutex, "uid", MUTEX_DEFAULT, 0);
     MUTEX_INIT(&rxkad_random_mutex, "rxkad random", MUTEX_DEFAULT, 0);
 
     rxkad_global_stats_init();
@@ -356,7 +354,6 @@ rxkad_NewConnection(struct rx_securityClass *aobj,
        if (!(tcp->type & rxkad_client))
            return RXKADINCONSISTENCY;
        rxkad_SetLevel(aconn, tcp->level);      /* set header and trailer sizes */
-       rxkad_AllocCID(aobj, aconn);    /* CHANGES cid AND epoch!!!! */
        rxkad_DeriveXORInfo(aconn, (fc_KeySchedule *)tcp->keysched, (char *)tcp->ivec, (char *)data->preSeq);
        INC_RXKAD_STATS(connections[rxkad_LevelIndex(tcp->level)]);
     }
index d514e20..03ddb38 100644 (file)
@@ -26,6 +26,7 @@ EXEOBJS =\
 EXELIBS =\
        $(DESTDIR)\lib\afsrxkad.lib \
        $(DESTDIR)\lib\afsrx.lib \
+       $(DESTDIR)\lib\afshcrypto.lib \
        $(DESTDIR)\lib\afsdes.lib \
        $(DESTDIR)\lib\afslwp.lib \
        $(DESTDIR)\lib\afs\afscmd.lib \
index 33d5c89..0420508 100644 (file)
@@ -20,6 +20,7 @@ LIBS=\
        ${TOP_LIBDIR}/librxkad.a \
        ${TOP_LIBDIR}/libsys.a \
        ${TOP_LIBDIR}/librx.a \
+       ${TOP_LIBDIR}/libafshcrypto_lwp.a \
        ${TOP_LIBDIR}/liblwp.a \
        ${TOP_LIBDIR}/util.a \
        $(TOP_LIBDIR)/libopr.a \
index 08a6ba0..a380cfe 100644 (file)
@@ -28,7 +28,8 @@ INCLS=${TOP_INCDIR}/lwp.h ${TOP_INCDIR}/lock.h \
        ${TOP_INCDIR}/rx/rx.h ${TOP_INCDIR}/rx/xdr.h \
        ${TOP_INCDIR}/lock.h ubik.h ubik_int.h
 
-LIBS=${TOP_LIBDIR}/librx.a ${TOP_LIBDIR}/liblwp.a ${TOP_LIBDIR}/libauth.a \
+LIBS=${TOP_LIBDIR}/librx.a ${TOP_LIBDIR}/libafshcrypto_lwp.a \
+       ${TOP_LIBDIR}/liblwp.a ${TOP_LIBDIR}/libauth.a \
        ${TOP_LIBDIR}/libafscom_err.a ${TOP_LIBDIR}/libcmd.a \
        ${TOP_LIBDIR}/libsys.a ${TOP_LIBDIR}/libauth.a \
        ${TOP_LIBDIR}/libafsutil.a ${TOP_LIBDIR}/libopr.a \
index d1ccf56..4a1b142 100644 (file)
@@ -131,6 +131,7 @@ UDBG_EXEOBJS =\
 UDBG_EXELIBS =\
        $(DESTDIR)\lib\afsubik.lib \
        $(DESTDIR)\lib\afsrx.lib \
+       $(DESTDIR)\lib\afshcrypto.lib \
        $(DESTDIR)\lib\afs\afsreg.lib \
        $(DESTDIR)\lib\afslwp.lib \
        $(DESTDIR)\lib\afs\afscom_err.lib \
index 20f4629..d0cabf6 100644 (file)
@@ -57,6 +57,7 @@ CMLIBS=${TOP_LIBDIR}/libsys.a \
         ${TOP_LIBDIR}/libafscom_err.a \
         ${TOP_LIBDIR}/libcmd.a \
         ${TOP_LIBDIR}/librx.a \
+        ${TOP_LIBDIR}/libafshcrypto_lwp.a \
         ${TOP_LIBDIR}/libsys.a \
         ${TOP_LIBDIR}/liblwp.a \
         $(TOP_LIBDIR)/libopr.a \
index d875bc6..192dea4 100644 (file)
@@ -15,6 +15,7 @@ HELPER_SPLINT=@HELPER_SPLINT@
 
 LIBS=${TOP_LIBDIR}/libcmd.a vlib.a ${TOP_LIBDIR}/util.a \
        ${TOP_LIBDIR}/libdir.a ${TOP_LIBDIR}/librx.a \
+       ${TOP_LIBDIR}/libafshcrypto_lwp.a \
        ${TOP_LIBDIR}/liblwp.a ${TOP_LIBDIR}/libsys.a \
        ${TOP_LIBDIR}/libacl.a ${TOP_LIBDIR}/libopr.a
 
index 18455d0..a402ef8 100644 (file)
@@ -54,6 +54,7 @@ VOLDUMP_LIBS = \
        ${TOP_LIBDIR}/libafscom_err.a \
        ${TOP_LIBDIR}/libdir.a \
        ${TOP_LIBDIR}/librx.a  \
+       ${TOP_LIBDIR}/libafshcrypto_lwp.a \
        ${TOP_LIBDIR}/liblwp.a  \
        ${TOP_LIBDIR}/libsys.a  \
        ${TOP_LIBDIR}/libacl.a \
index f91b67e..fcd0a42 100644 (file)
@@ -18,6 +18,7 @@ RPCINCLS=${TOP_INCDIR}/lwp.h ${TOP_INCDIR}/rx/rx.h
 LIBS=${TOP_LIBDIR}/libafsint.a \
        ${TOP_LIBDIR}/libcmd.a \
        ${TOP_LIBDIR}/librx.a \
+       ${TOP_LIBDIR}/libafshcrypto_lwp.a \
        ${TOP_LIBDIR}/liblwp.a \
        ${TOP_LIBDIR}/libsys.a \
        ${TOP_LIBDIR}/libopr.a \
index 23d456a..feee07d 100644 (file)
@@ -22,6 +22,7 @@ LIBS= \
        $(LIBDIR)\afs\afsint.lib \
        $(LIBDIR)\afs\afscmd.lib \
        $(LIBDIR)\afsrx.lib \
+       $(LIBDIR)\afshcrypto.lib \
        $(LIBDIR)\afslwp.lib \
        $(LIBDIR)\afs\afspioctl.lib \
        $(LIBDIR)\afs\afsutil.lib \