Random/unique NFS xids.
authorangelos <angelos@openbsd.org>
Sun, 27 Apr 1997 23:55:49 +0000 (23:55 +0000)
committerangelos <angelos@openbsd.org>
Sun, 27 Apr 1997 23:55:49 +0000 (23:55 +0000)
sys/nfs/nfs_subs.c

index 3edd8a9..9906b69 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: nfs_subs.c,v 1.16 1997/04/25 09:30:14 deraadt Exp $   */
+/*     $OpenBSD: nfs_subs.c,v 1.17 1997/04/27 23:55:49 angelos Exp $   */
 /*     $NetBSD: nfs_subs.c,v 1.27.4.3 1996/07/08 20:34:24 jtc Exp $    */
 
 /*
@@ -68,6 +68,7 @@
 #include <nfs/xdr_subs.h>
 #include <nfs/nfsm_subs.h>
 #include <nfs/nfsmount.h>
+#include <nfs/nfsrvcache.h>
 #include <nfs/nqnfs.h>
 #include <nfs/nfsrtt.h>
 #include <nfs/nfs_var.h>
 #include <netiso/iso.h>
 #endif
 
+#include <dev/rndvar.h>
+
 #ifdef __GNUC__
 #define INLINE __inline
 #else
 #define INLINE
 #endif
 
+#define NFSRCHASH(xid) \
+        (&nfsrvhashtbl[((xid) + ((xid) >> 24)) & nfsrvhash])
+extern LIST_HEAD(nfsrvhash, nfsrvcache) *nfsrvhashtbl;
+extern TAILQ_HEAD(nfsrvlru, nfsrvcache) nfsrvlruhead;
+extern u_long nfsrvhash;
+
 int    nfs_attrtimeo __P((struct nfsnode *np));
 
 /*
@@ -618,10 +627,9 @@ nfsm_rpchead(cr, nmflag, procid, auth_type, auth_len, auth_str, verf_len,
        register u_int32_t *tl;
        register caddr_t bpos;
        register int i;
+       register struct nfsrvcache *rp;
        struct mbuf *mreq, *mb2;
        int siz, grpsiz, authsiz;
-       struct timeval tv;
-       static u_int32_t base;
 
        authsiz = nfsm_rndup(auth_len);
        MGETHDR(mb, M_WAIT, MT_DATA);
@@ -641,21 +649,27 @@ nfsm_rpchead(cr, nmflag, procid, auth_type, auth_len, auth_str, verf_len,
         */
        nfsm_build(tl, u_int32_t *, 8 * NFSX_UNSIGNED);
 
-       /*
-        * derive initial xid from system time
-        * XXX time is invalid if root not yet mounted
-        */
-       if (!base && (rootvp)) {
-               microtime(&tv);
-               base = tv.tv_sec << 12;
-               nfs_xid = base;
-       }
-       /*
-        * Skip zero xid if it should ever happen.
-        */
-       if (++nfs_xid == 0)
-               nfs_xid++;
-
+       /* Get a new (non-zero) xid */
+
+       do
+       {
+           i = 0;
+
+           while (((*xidp = arc4random()) == nfs_xid) || (*xidp == 0))
+             ;
+
+           nfs_xid = *xidp;
+           
+           for (rp = NFSRCHASH(nfs_xid)->lh_first; rp !=0; 
+                rp = rp->rc_hash.le_next)
+             if ((nfs_xid == rp->rc_xid) &&
+                 (rp->rc_proc == procid))
+             {
+                 i = 1;     /* do the loop again */
+                 break;
+             }
+       } while (i);
+     
        *tl++ = *xidp = txdr_unsigned(nfs_xid);
        *tl++ = rpc_call;
        *tl++ = rpc_vers;