diff options
author | dfr <dfr@FreeBSD.org> | 2008-11-03 10:38:00 +0000 |
---|---|---|
committer | dfr <dfr@FreeBSD.org> | 2008-11-03 10:38:00 +0000 |
commit | 2fb03513fc4b5d35a398f1ceb4b439fe4bb5fb74 (patch) | |
tree | c59f88924c0b3ead68523ce14806894836f8d9a7 /sys/nlm | |
parent | 8b86595849b35ac7c26977f1b8206c1678c9b5bb (diff) | |
download | FreeBSD-src-2fb03513fc4b5d35a398f1ceb4b439fe4bb5fb74.zip FreeBSD-src-2fb03513fc4b5d35a398f1ceb4b439fe4bb5fb74.tar.gz |
Implement support for RPCSEC_GSS authentication to both the NFS client
and server. This replaces the RPC implementation of the NFS client and
server with the newer RPC implementation originally developed
(actually ported from the userland sunrpc code) to support the NFS
Lock Manager. I have tested this code extensively and I believe it is
stable and that performance is at least equal to the legacy RPC
implementation.
The NFS code currently contains support for both the new RPC
implementation and the older legacy implementation inherited from the
original NFS codebase. The default is to use the new implementation -
add the NFS_LEGACYRPC option to fall back to the old code. When I
merge this support back to RELENG_7, I will probably change this so
that users have to 'opt in' to get the new code.
To use RPCSEC_GSS on either client or server, you must build a kernel
which includes the KGSSAPI option and the crypto device. On the
userland side, you must build at least a new libc, mountd, mount_nfs
and gssd. You must install new versions of /etc/rc.d/gssd and
/etc/rc.d/nfsd and add 'gssd_enable=YES' to /etc/rc.conf.
As long as gssd is running, you should be able to mount an NFS
filesystem from a server that requires RPCSEC_GSS authentication. The
mount itself can happen without any kerberos credentials but all
access to the filesystem will be denied unless the accessing user has
a valid ticket file in the standard place (/tmp/krb5cc_<uid>). There
is currently no support for situations where the ticket file is in a
different place, such as when the user logged in via SSH and has
delegated credentials from that login. This restriction is also
present in Solaris and Linux. In theory, we could improve this in
future, possibly using Brooks Davis' implementation of variant
symlinks.
Supporting RPCSEC_GSS on a server is nearly as simple. You must create
service creds for the server in the form 'nfs/<fqdn>@<REALM>' and
install them in /etc/krb5.keytab. The standard heimdal utility ktutil
makes this fairly easy. After the service creds have been created, you
can add a '-sec=krb5' option to /etc/exports and restart both mountd
and nfsd.
The only other difference an administrator should notice is that nfsd
doesn't fork to create service threads any more. In normal operation,
there will be two nfsd processes, one in userland waiting for TCP
connections and one in the kernel handling requests. The latter
process will create as many kthreads as required - these should be
visible via 'top -H'. The code has some support for varying the number
of service threads according to load but initially at least, nfsd uses
a fixed number of threads according to the value supplied to its '-n'
option.
Sponsored by: Isilon Systems
MFC after: 1 month
Diffstat (limited to 'sys/nlm')
-rw-r--r-- | sys/nlm/nlm.h | 2 | ||||
-rw-r--r-- | sys/nlm/nlm_advlock.c | 9 | ||||
-rw-r--r-- | sys/nlm/nlm_prot_impl.c | 116 | ||||
-rw-r--r-- | sys/nlm/nlm_prot_svc.c | 72 |
4 files changed, 121 insertions, 78 deletions
diff --git a/sys/nlm/nlm.h b/sys/nlm/nlm.h index addd07e..27b921f 100644 --- a/sys/nlm/nlm.h +++ b/sys/nlm/nlm.h @@ -93,7 +93,7 @@ extern void nlm_host_release(struct nlm_host *host); * Return an RPC client handle that can be used to talk to the NLM * running on the given host. */ -extern CLIENT *nlm_host_get_rpc(struct nlm_host *host); +extern CLIENT *nlm_host_get_rpc(struct nlm_host *host, bool_t isserver); /* * Return the system ID for a host. diff --git a/sys/nlm/nlm_advlock.c b/sys/nlm/nlm_advlock.c index 5d1cc83..2c1f1a6 100644 --- a/sys/nlm/nlm_advlock.c +++ b/sys/nlm/nlm_advlock.c @@ -267,6 +267,7 @@ nlm_advlock_internal(struct vnode *vp, void *id, int op, struct flock *fl, ext.rc_feedback = nlm_feedback; ext.rc_feedback_arg = &nf; + ext.rc_timers = NULL; ns = NULL; if (flags & F_FLOCK) { @@ -753,7 +754,7 @@ nlm_setlock(struct nlm_host *host, struct rpc_callextra *ext, retry = 5*hz; for (;;) { - client = nlm_host_get_rpc(host); + client = nlm_host_get_rpc(host, FALSE); if (!client) return (ENOLCK); /* XXX retry? */ @@ -834,7 +835,7 @@ nlm_setlock(struct nlm_host *host, struct rpc_callextra *ext, cancel.alock = args.alock; do { - client = nlm_host_get_rpc(host); + client = nlm_host_get_rpc(host, FALSE); if (!client) /* XXX retry? */ return (ENOLCK); @@ -942,7 +943,7 @@ nlm_clearlock(struct nlm_host *host, struct rpc_callextra *ext, return (error); for (;;) { - client = nlm_host_get_rpc(host); + client = nlm_host_get_rpc(host, FALSE); if (!client) return (ENOLCK); /* XXX retry? */ @@ -1023,7 +1024,7 @@ nlm_getlock(struct nlm_host *host, struct rpc_callextra *ext, args.exclusive = exclusive; for (;;) { - client = nlm_host_get_rpc(host); + client = nlm_host_get_rpc(host, FALSE); if (!client) return (ENOLCK); /* XXX retry? */ diff --git a/sys/nlm/nlm_prot_impl.c b/sys/nlm/nlm_prot_impl.c index 831d330..1add718 100644 --- a/sys/nlm/nlm_prot_impl.c +++ b/sys/nlm/nlm_prot_impl.c @@ -26,6 +26,7 @@ */ #include "opt_inet6.h" +#include "opt_nfs.h" #include <sys/cdefs.h> __FBSDID("$FreeBSD$"); @@ -205,6 +206,12 @@ enum nlm_host_state { NLM_MONITOR_FAILED, NLM_RECOVERING }; + +struct nlm_rpc { + CLIENT *nr_client; /* (l) RPC client handle */ + time_t nr_create_time; /* (l) when client was created */ +}; + struct nlm_host { struct mtx nh_lock; volatile u_int nh_refs; /* (a) reference count */ @@ -213,12 +220,12 @@ struct nlm_host { uint32_t nh_sysid; /* (c) our allocaed system ID */ char nh_sysid_string[10]; /* (c) string rep. of sysid */ struct sockaddr_storage nh_addr; /* (s) remote address of host */ - CLIENT *nh_rpc; /* (l) RPC handle to send to host */ + struct nlm_rpc nh_srvrpc; /* (l) RPC for server replies */ + struct nlm_rpc nh_clntrpc; /* (l) RPC for client requests */ rpcvers_t nh_vers; /* (s) NLM version of host */ int nh_state; /* (s) last seen NSM state of host */ enum nlm_host_state nh_monstate; /* (l) local NSM monitoring state */ time_t nh_idle_timeout; /* (s) Time at which host is idle */ - time_t nh_rpc_create_time; /* (s) Time we create RPC client */ struct sysctl_ctx_list nh_sysctl; /* (c) vfs.nlm.sysid nodes */ struct nlm_async_lock_list nh_pending; /* (l) pending async locks */ struct nlm_async_lock_list nh_finished; /* (l) finished async locks */ @@ -283,7 +290,7 @@ nlm_copy_netobj(struct netobj *dst, struct netobj *src, static CLIENT * nlm_get_rpc(struct sockaddr *sa, rpcprog_t prog, rpcvers_t vers) { - const char *wchan = "nlmrcv"; + char *wchan = "nlmrcv"; const char* protofmly; struct sockaddr_storage ss; struct socket *so; @@ -472,7 +479,7 @@ again: rpcb = clnt_reconnect_create(nconf, (struct sockaddr *)&ss, prog, vers, 0, 0); - CLNT_CONTROL(rpcb, CLSET_WAITCHAN, &wchan); + CLNT_CONTROL(rpcb, CLSET_WAITCHAN, wchan); rpcb->cl_auth = nlm_auth; } else { @@ -482,7 +489,7 @@ again: CLNT_CONTROL(rpcb, CLSET_SVC_ADDR, &ss); CLNT_CONTROL(rpcb, CLSET_PROG, &prog); CLNT_CONTROL(rpcb, CLSET_VERS, &vers); - CLNT_CONTROL(rpcb, CLSET_WAITCHAN, &wchan); + CLNT_CONTROL(rpcb, CLSET_WAITCHAN, wchan); rpcb->cl_auth = nlm_auth; } @@ -646,13 +653,17 @@ nlm_host_destroy(struct nlm_host *host) TAILQ_REMOVE(&nlm_hosts, host, nh_link); mtx_unlock(&nlm_global_lock); - if (host->nh_rpc) - CLNT_RELEASE(host->nh_rpc); + if (host->nh_srvrpc.nr_client) + CLNT_RELEASE(host->nh_srvrpc.nr_client); + if (host->nh_clntrpc.nr_client) + CLNT_RELEASE(host->nh_clntrpc.nr_client); mtx_destroy(&host->nh_lock); sysctl_ctx_free(&host->nh_sysctl); free(host, M_NLM); } +#ifdef NFSCLIENT + /* * Thread start callback for client lock recovery */ @@ -677,6 +688,8 @@ nlm_client_recovery_start(void *arg) kthread_exit(); } +#endif + /* * This is called when we receive a host state change notification. We * unlock any active locks owned by the host. When rpc.lockd is @@ -716,6 +729,7 @@ nlm_host_notify(struct nlm_host *host, int newstate) lf_clearremotesys(host->nh_sysid); host->nh_state = newstate; +#ifdef NFSCLIENT /* * If we have any remote locks for this host (i.e. it * represents a remote NFS server that our local NFS client @@ -730,6 +744,7 @@ nlm_host_notify(struct nlm_host *host, int newstate) kthread_add(nlm_client_recovery_start, host, curproc, &td, 0, 0, "NFS lock recovery for %s", host->nh_caller_name); } +#endif } /* @@ -783,7 +798,6 @@ nlm_create_host(const char* caller_name) host->nh_sysid = nlm_next_sysid++; snprintf(host->nh_sysid_string, sizeof(host->nh_sysid_string), "%d", host->nh_sysid); - host->nh_rpc = NULL; host->nh_vers = 0; host->nh_state = 0; host->nh_monstate = NLM_UNMONITORED; @@ -933,15 +947,15 @@ nlm_find_host_by_name(const char *name, const struct sockaddr *addr, * have an RPC client handle, make sure the address is * the same, otherwise discard the client handle. */ - if (host->nh_addr.ss_len && host->nh_rpc) { + if (host->nh_addr.ss_len && host->nh_srvrpc.nr_client) { if (!nlm_compare_addr( (struct sockaddr *) &host->nh_addr, addr) || host->nh_vers != vers) { CLIENT *client; mtx_lock(&host->nh_lock); - client = host->nh_rpc; - host->nh_rpc = NULL; + client = host->nh_srvrpc.nr_client; + host->nh_srvrpc.nr_client = NULL; mtx_unlock(&host->nh_lock); if (client) { CLNT_RELEASE(client); @@ -1173,12 +1187,18 @@ nlm_host_monitor(struct nlm_host *host, int state) * running on the given host. */ CLIENT * -nlm_host_get_rpc(struct nlm_host *host) +nlm_host_get_rpc(struct nlm_host *host, bool_t isserver) { + struct nlm_rpc *rpc; CLIENT *client; mtx_lock(&host->nh_lock); + if (isserver) + rpc = &host->nh_srvrpc; + else + rpc = &host->nh_clntrpc; + /* * We can't hold onto RPC handles for too long - the async * call/reply protocol used by some NLM clients makes it hard @@ -1187,33 +1207,33 @@ nlm_host_get_rpc(struct nlm_host *host) * holding any locks, it won't bother to notify us. We * expire the RPC handles after two minutes. */ - if (host->nh_rpc && time_uptime > host->nh_rpc_create_time + 2*60) { - client = host->nh_rpc; - host->nh_rpc = NULL; + if (rpc->nr_client && time_uptime > rpc->nr_create_time + 2*60) { + client = rpc->nr_client; + rpc->nr_client = NULL; mtx_unlock(&host->nh_lock); CLNT_RELEASE(client); mtx_lock(&host->nh_lock); } - if (!host->nh_rpc) { + if (!rpc->nr_client) { mtx_unlock(&host->nh_lock); client = nlm_get_rpc((struct sockaddr *)&host->nh_addr, NLM_PROG, host->nh_vers); mtx_lock(&host->nh_lock); if (client) { - if (host->nh_rpc) { + if (rpc->nr_client) { mtx_unlock(&host->nh_lock); CLNT_DESTROY(client); mtx_lock(&host->nh_lock); } else { - host->nh_rpc = client; - host->nh_rpc_create_time = time_uptime; + rpc->nr_client = client; + rpc->nr_create_time = time_uptime; } } } - client = host->nh_rpc; + client = rpc->nr_client; if (client) CLNT_ACQUIRE(client); mtx_unlock(&host->nh_lock); @@ -1439,8 +1459,10 @@ nlm_server_main(int addr_count, char **addrs) enum clnt_stat stat; struct nlm_host *host, *nhost; struct nlm_waiting_lock *nw; +#ifdef NFSCLIENT vop_advlock_t *old_nfs_advlock; vop_reclaim_t *old_nfs_reclaim; +#endif int v4_used; #ifdef INET6 int v6_used; @@ -1512,7 +1534,7 @@ nlm_server_main(int addr_count, char **addrs) goto out; } - pool = svcpool_create(); + pool = svcpool_create("NLM", NULL); error = nlm_register_services(pool, addr_count, addrs); if (error) @@ -1541,16 +1563,20 @@ nlm_server_main(int addr_count, char **addrs) printf("NLM: local NSM state is %d\n", smstat.state); nlm_nsm_state = smstat.state; +#ifdef NFSCLIENT old_nfs_advlock = nfs_advlock_p; nfs_advlock_p = nlm_advlock; old_nfs_reclaim = nfs_reclaim_p; nfs_reclaim_p = nlm_reclaim; +#endif svc_run(pool); error = 0; +#ifdef NFSCLIENT nfs_advlock_p = old_nfs_advlock; nfs_reclaim_p = old_nfs_reclaim; +#endif out: if (pool) @@ -1595,7 +1621,8 @@ out: } TAILQ_FOREACH_SAFE(host, &nlm_hosts, nh_link, nhost) { mtx_lock(&host->nh_lock); - if (host->nh_rpc) { + if (host->nh_srvrpc.nr_client + || host->nh_clntrpc.nr_client) { if (host->nh_addr.ss_family == AF_INET) v4_used++; #ifdef INET6 @@ -1607,7 +1634,12 @@ out: * correctly with the fact that a socket may * be used by many rpc handles. */ - CLNT_CONTROL(host->nh_rpc, CLSET_FD_CLOSE, 0); + if (host->nh_srvrpc.nr_client) + CLNT_CONTROL(host->nh_srvrpc.nr_client, + CLSET_FD_CLOSE, 0); + if (host->nh_clntrpc.nr_client) + CLNT_CONTROL(host->nh_clntrpc.nr_client, + CLSET_FD_CLOSE, 0); } mtx_unlock(&host->nh_lock); } @@ -1687,11 +1719,10 @@ static int nlm_get_vfs_state(struct nlm_host *host, struct svc_req *rqstp, fhandle_t *fhp, struct vfs_state *vs) { - int error, exflags, freecred; + int error, exflags; struct ucred *cred = NULL, *credanon; memset(vs, 0, sizeof(*vs)); - freecred = FALSE; vs->vs_mp = vfs_getvfs(&fhp->fh_fsid); if (!vs->vs_mp) { @@ -1700,7 +1731,7 @@ nlm_get_vfs_state(struct nlm_host *host, struct svc_req *rqstp, vs->vs_vfslocked = VFS_LOCK_GIANT(vs->vs_mp); error = VFS_CHECKEXP(vs->vs_mp, (struct sockaddr *)&host->nh_addr, - &exflags, &credanon); + &exflags, &credanon, NULL, NULL); if (error) goto out; @@ -1714,16 +1745,13 @@ nlm_get_vfs_state(struct nlm_host *host, struct svc_req *rqstp, goto out; vs->vs_vnlocked = TRUE; - cred = crget(); - freecred = TRUE; - if (!svc_getcred(rqstp, cred, NULL)) { + if (!svc_getcred(rqstp, &cred, NULL)) { error = EINVAL; goto out; } if (cred->cr_uid == 0 || (exflags & MNT_EXPORTANON)) { crfree(cred); - cred = credanon; - freecred = FALSE; + cred = crhold(credanon); } /* @@ -1741,7 +1769,7 @@ nlm_get_vfs_state(struct nlm_host *host, struct svc_req *rqstp, vs->vs_vnlocked = FALSE; out: - if (freecred) + if (cred) crfree(cred); return (error); @@ -1788,7 +1816,7 @@ nlm_do_test(nlm4_testargs *argp, nlm4_testres *result, struct svc_req *rqstp, memset(&vs, 0, sizeof(vs)); host = nlm_find_host_by_name(argp->alock.caller_name, - (struct sockaddr *) rqstp->rq_xprt->xp_rtaddr.buf, rqstp->rq_vers); + svc_getrpccaller(rqstp), rqstp->rq_vers); if (!host) { result->stat.stat = nlm4_denied_nolocks; return (ENOMEM); @@ -1866,7 +1894,7 @@ nlm_do_test(nlm4_testargs *argp, nlm4_testres *result, struct svc_req *rqstp, out: nlm_release_vfs_state(&vs); if (rpcp) - *rpcp = nlm_host_get_rpc(host); + *rpcp = nlm_host_get_rpc(host, TRUE); nlm_host_release(host); return (0); } @@ -1885,7 +1913,7 @@ nlm_do_lock(nlm4_lockargs *argp, nlm4_res *result, struct svc_req *rqstp, memset(&vs, 0, sizeof(vs)); host = nlm_find_host_by_name(argp->alock.caller_name, - (struct sockaddr *) rqstp->rq_xprt->xp_rtaddr.buf, rqstp->rq_vers); + svc_getrpccaller(rqstp), rqstp->rq_vers); if (!host) { result->stat.stat = nlm4_denied_nolocks; return (ENOMEM); @@ -1937,7 +1965,7 @@ nlm_do_lock(nlm4_lockargs *argp, nlm4_res *result, struct svc_req *rqstp, /* * First, make sure we can contact the host's NLM. */ - client = nlm_host_get_rpc(host); + client = nlm_host_get_rpc(host, TRUE); if (!client) { result->stat.stat = nlm4_failed; goto out; @@ -2049,7 +2077,7 @@ nlm_do_lock(nlm4_lockargs *argp, nlm4_res *result, struct svc_req *rqstp, out: nlm_release_vfs_state(&vs); if (rpcp) - *rpcp = nlm_host_get_rpc(host); + *rpcp = nlm_host_get_rpc(host, TRUE); nlm_host_release(host); return (0); } @@ -2069,7 +2097,7 @@ nlm_do_cancel(nlm4_cancargs *argp, nlm4_res *result, struct svc_req *rqstp, memset(&vs, 0, sizeof(vs)); host = nlm_find_host_by_name(argp->alock.caller_name, - (struct sockaddr *) rqstp->rq_xprt->xp_rtaddr.buf, rqstp->rq_vers); + svc_getrpccaller(rqstp), rqstp->rq_vers); if (!host) { result->stat.stat = nlm4_denied_nolocks; return (ENOMEM); @@ -2140,7 +2168,7 @@ nlm_do_cancel(nlm4_cancargs *argp, nlm4_res *result, struct svc_req *rqstp, out: nlm_release_vfs_state(&vs); if (rpcp) - *rpcp = nlm_host_get_rpc(host); + *rpcp = nlm_host_get_rpc(host, TRUE); nlm_host_release(host); return (0); } @@ -2159,7 +2187,7 @@ nlm_do_unlock(nlm4_unlockargs *argp, nlm4_res *result, struct svc_req *rqstp, memset(&vs, 0, sizeof(vs)); host = nlm_find_host_by_name(argp->alock.caller_name, - (struct sockaddr *) rqstp->rq_xprt->xp_rtaddr.buf, rqstp->rq_vers); + svc_getrpccaller(rqstp), rqstp->rq_vers); if (!host) { result->stat.stat = nlm4_denied_nolocks; return (ENOMEM); @@ -2203,7 +2231,7 @@ nlm_do_unlock(nlm4_unlockargs *argp, nlm4_res *result, struct svc_req *rqstp, out: nlm_release_vfs_state(&vs); if (rpcp) - *rpcp = nlm_host_get_rpc(host); + *rpcp = nlm_host_get_rpc(host, TRUE); nlm_host_release(host); return (0); } @@ -2218,9 +2246,7 @@ nlm_do_granted(nlm4_testargs *argp, nlm4_res *result, struct svc_req *rqstp, memset(result, 0, sizeof(*result)); - host = nlm_find_host_by_addr( - (struct sockaddr *) rqstp->rq_xprt->xp_rtaddr.buf, - rqstp->rq_vers); + host = nlm_find_host_by_addr(svc_getrpccaller(rqstp), rqstp->rq_vers); if (!host) { result->stat.stat = nlm4_denied_nolocks; return (ENOMEM); @@ -2247,7 +2273,7 @@ nlm_do_granted(nlm4_testargs *argp, nlm4_res *result, struct svc_req *rqstp, } mtx_unlock(&nlm_global_lock); if (rpcp) - *rpcp = nlm_host_get_rpc(host); + *rpcp = nlm_host_get_rpc(host, TRUE); nlm_host_release(host); return (0); } diff --git a/sys/nlm/nlm_prot_svc.c b/sys/nlm/nlm_prot_svc.c index 3b1a140..5141f87 100644 --- a/sys/nlm/nlm_prot_svc.c +++ b/sys/nlm/nlm_prot_svc.c @@ -57,8 +57,9 @@ nlm_prog_0(struct svc_req *rqstp, SVCXPRT *transp) switch (rqstp->rq_proc) { case NULLPROC: - (void) svc_sendreply(transp, + (void) svc_sendreply(rqstp, (xdrproc_t) xdr_void, (char *)NULL); + svc_freereq(rqstp); return; case NLM_SM_NOTIFY: @@ -68,19 +69,22 @@ nlm_prog_0(struct svc_req *rqstp, SVCXPRT *transp) break; default: - svcerr_noproc(transp); + svcerr_noproc(rqstp); + svc_freereq(rqstp); return; } (void) memset((char *)&argument, 0, sizeof (argument)); - if (!svc_getargs(transp, xdr_argument, (char *)(caddr_t) &argument)) { - svcerr_decode(transp); + if (!svc_getargs(rqstp, xdr_argument, (char *)(caddr_t) &argument)) { + svcerr_decode(rqstp); + svc_freereq(rqstp); return; } retval = (bool_t) (*local)((char *)&argument, (void *)&result, rqstp); - if (retval > 0 && !svc_sendreply(transp, xdr_result, (char *)&result)) { - svcerr_systemerr(transp); + if (retval > 0 && !svc_sendreply(rqstp, xdr_result, (char *)&result)) { + svcerr_systemerr(rqstp); } - if (!svc_freeargs(transp, xdr_argument, (char *)(caddr_t) &argument)) { + svc_freereq(rqstp); + if (!svc_freeargs(rqstp, xdr_argument, (char *)(caddr_t) &argument)) { printf("unable to free arguments"); //exit(1); } @@ -121,8 +125,9 @@ nlm_prog_1(struct svc_req *rqstp, SVCXPRT *transp) switch (rqstp->rq_proc) { case NULLPROC: - (void) svc_sendreply(transp, + (void) svc_sendreply(rqstp, (xdrproc_t) xdr_void, (char *)NULL); + svc_freereq(rqstp); return; case NLM_TEST: @@ -216,22 +221,25 @@ nlm_prog_1(struct svc_req *rqstp, SVCXPRT *transp) break; default: - svcerr_noproc(transp); + svcerr_noproc(rqstp); + svc_freereq(rqstp); return; } (void) memset((char *)&argument, 0, sizeof (argument)); - if (!svc_getargs(transp, xdr_argument, (char *)(caddr_t) &argument)) { - svcerr_decode(transp); + if (!svc_getargs(rqstp, xdr_argument, (char *)(caddr_t) &argument)) { + svcerr_decode(rqstp); + svc_freereq(rqstp); return; } retval = (bool_t) (*local)((char *)&argument, (void *)&result, rqstp); - if (retval > 0 && !svc_sendreply(transp, xdr_result, (char *)&result)) { - svcerr_systemerr(transp); + if (retval > 0 && !svc_sendreply(rqstp, xdr_result, (char *)&result)) { + svcerr_systemerr(rqstp); } - if (!svc_freeargs(transp, xdr_argument, (char *)(caddr_t) &argument)) { + if (!svc_freeargs(rqstp, xdr_argument, (char *)(caddr_t) &argument)) { printf("unable to free arguments"); //exit(1); } + svc_freereq(rqstp); if (!nlm_prog_1_freeresult(transp, xdr_result, (caddr_t) &result)) printf("unable to free results"); @@ -258,8 +266,9 @@ nlm_prog_3(struct svc_req *rqstp, SVCXPRT *transp) switch (rqstp->rq_proc) { case NULLPROC: - (void) svc_sendreply(transp, + (void) svc_sendreply(rqstp, (xdrproc_t) xdr_void, (char *)NULL); + svc_freereq(rqstp); return; case NLM_TEST: @@ -305,22 +314,25 @@ nlm_prog_3(struct svc_req *rqstp, SVCXPRT *transp) break; default: - svcerr_noproc(transp); + svcerr_noproc(rqstp); + svc_freereq(rqstp); return; } (void) memset((char *)&argument, 0, sizeof (argument)); - if (!svc_getargs(transp, xdr_argument, (char *)(caddr_t) &argument)) { - svcerr_decode(transp); + if (!svc_getargs(rqstp, xdr_argument, (char *)(caddr_t) &argument)) { + svcerr_decode(rqstp); + svc_freereq(rqstp); return; } retval = (bool_t) (*local)((char *)&argument, (void *)&result, rqstp); - if (retval > 0 && !svc_sendreply(transp, xdr_result, (char *)&result)) { - svcerr_systemerr(transp); + if (retval > 0 && !svc_sendreply(rqstp, xdr_result, (char *)&result)) { + svcerr_systemerr(rqstp); } - if (!svc_freeargs(transp, xdr_argument, (char *)(caddr_t) &argument)) { + if (!svc_freeargs(rqstp, xdr_argument, (char *)(caddr_t) &argument)) { printf("unable to free arguments"); //exit(1); } + svc_freereq(rqstp); if (!nlm_prog_3_freeresult(transp, xdr_result, (caddr_t) &result)) printf("unable to free results"); @@ -367,8 +379,9 @@ nlm_prog_4(struct svc_req *rqstp, SVCXPRT *transp) switch (rqstp->rq_proc) { case NULLPROC: - (void) svc_sendreply(transp, + (void) svc_sendreply(rqstp, (xdrproc_t) xdr_void, (char *)NULL); + svc_freereq(rqstp); return; case NLM4_TEST: @@ -486,22 +499,25 @@ nlm_prog_4(struct svc_req *rqstp, SVCXPRT *transp) break; default: - svcerr_noproc(transp); + svcerr_noproc(rqstp); + svc_freereq(rqstp); return; } (void) memset((char *)&argument, 0, sizeof (argument)); - if (!svc_getargs(transp, xdr_argument, (char *)(caddr_t) &argument)) { - svcerr_decode(transp); + if (!svc_getargs(rqstp, xdr_argument, (char *)(caddr_t) &argument)) { + svcerr_decode(rqstp); + svc_freereq(rqstp); return; } retval = (bool_t) (*local)((char *)&argument, (void *)&result, rqstp); - if (retval > 0 && !svc_sendreply(transp, xdr_result, (char *)&result)) { - svcerr_systemerr(transp); + if (retval > 0 && !svc_sendreply(rqstp, xdr_result, (char *)&result)) { + svcerr_systemerr(rqstp); } - if (!svc_freeargs(transp, xdr_argument, (char *)(caddr_t) &argument)) { + if (!svc_freeargs(rqstp, xdr_argument, (char *)(caddr_t) &argument)) { printf("unable to free arguments"); //exit(1); } + svc_freereq(rqstp); if (!nlm_prog_4_freeresult(transp, xdr_result, (caddr_t) &result)) printf("unable to free results"); |