diff options
author | Damien Miller <djm@cvs.openbsd.org> | 2008-06-09 22:47:43 +0000 |
---|---|---|
committer | Damien Miller <djm@cvs.openbsd.org> | 2008-06-09 22:47:43 +0000 |
commit | 4292580034d73b1c4cdfac0005dc9e4d2589bda1 (patch) | |
tree | 39707a15c935037c1af790655424866680302eaa /sys/nfs/krpc_subr.c | |
parent | 8585245d5a6e10c2e09d2a4a531f89455bf9193d (diff) |
Introduce a facility to generate unpredictable 32 bit numbers with
near maximal (2^32) cycle times. These are useful for network
IDs in cases where there are negative consequences to ID prediction
and/or reuse.
Use the idgen32() functions to generate IPv6 IDs and NFS client/server
XIDs.
Pseudorandom permutation code in crypto/idgen.c based on public
domain skip32.c from Greg Rose.
feedback & ok thib@ deraadt@
Diffstat (limited to 'sys/nfs/krpc_subr.c')
-rw-r--r-- | sys/nfs/krpc_subr.c | 25 |
1 files changed, 21 insertions, 4 deletions
diff --git a/sys/nfs/krpc_subr.c b/sys/nfs/krpc_subr.c index 39dfe6ffa59..363a837d985 100644 --- a/sys/nfs/krpc_subr.c +++ b/sys/nfs/krpc_subr.c @@ -1,4 +1,4 @@ -/* $OpenBSD: krpc_subr.c,v 1.15 2008/05/23 15:51:12 thib Exp $ */ +/* $OpenBSD: krpc_subr.c,v 1.16 2008/06/09 22:47:42 djm Exp $ */ /* $NetBSD: krpc_subr.c,v 1.12.4.1 1996/06/07 00:52:26 cgd Exp $ */ /* @@ -61,6 +61,7 @@ #include <nfs/krpc.h> #include <nfs/xdr_subs.h> #include <dev/rndvar.h> +#include <crypto/idgen.h> /* * Kernel support for Sun RPC @@ -115,6 +116,24 @@ struct rpc_reply { #define MIN_REPLY_HDR 16 /* xid, dir, astat, errno */ +u_int32_t krpc_get_xid(void); + +/* + * Return an unpredictable XID. + */ +u_int32_t +krpc_get_xid(void) +{ + static struct idgen32_ctx krpc_xid_ctx; + static int called = 0; + + if (!called) { + called = 1; + idgen32_init(&krpc_xid_ctx); + } + return idgen32(&krpc_xid_ctx); +} + /* * What is the longest we will wait before re-sending a request? * Note this is also the frequency of "RPC timeout" messages. @@ -201,7 +220,6 @@ krpc_call(sa, prog, vers, func, data, from_p, retries) struct uio auio; int error, rcvflg, timo, secs, len; static u_int32_t xid = 0; - u_int32_t newxid; int *ip; struct timeval *tv; @@ -299,8 +317,7 @@ krpc_call(sa, prog, vers, func, data, from_p, retries) mhead->m_len = sizeof(*call); bzero((caddr_t)call, sizeof(*call)); /* rpc_call part */ - while ((newxid = arc4random()) == xid); - xid = newxid; + xid = krpc_get_xid(); call->rp_xid = txdr_unsigned(xid); /* call->rp_direction = 0; */ call->rp_rpcvers = txdr_unsigned(2); |