⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 svc_kudp.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 2 页
字号:
#ifndef lintstatic	char	*sccsid = "@(#)svc_kudp.c	4.4	(ULTRIX)	3/7/91";#endif lint/************************************************************************ *									* *			Copyright (c) 1990 by			        * *		Digital Equipment Corporation, Maynard, MA		* *			All rights reserved.				* *									* *   This software is furnished under a license and may be used and	* *   copied  only  in accordance with the terms of such license and	* *   with the  inclusion  of  the  above  copyright  notice.   This	* *   software  or  any  other copies thereof may not be provided or	* *   otherwise made available to any other person.  No title to and	* *   ownership of the software is hereby transferred.			* *									* *   This software is  derived  from  software  received  from  the	* *   University    of   California,   Berkeley,   and   from   Bell	* *   Laboratories.  Use, duplication, or disclosure is  subject  to	* *   restrictions  under  license  agreements  with  University  of	* *   California and with AT&T.						* *									* *   The information in this software is subject to change  without	* *   notice  and should not be construed as a commitment by Digital	* *   Equipment Corporation.						* *									* *   Digital assumes no responsibility for the use  or  reliability	* *   of its software on equipment which is not supplied by Digital.	* *									* ************************************************************************//* *	Portions of this software have been licensed to  *	Digital Equipment Company, Maynard, MA. *	Copyright (c) 1986 Sun Microsystems, Inc.  ALL RIGHTS RESERVED. *//* * *   Modification history: * * 25 Aug 90 -- chet *	Allow for Prestoserve in sizing of duplicate request cache. *	Shrink dupreq struct and fix NOTDUP macro. * *  9 Mar 90 -- chet *	Add dynamic allocation of duplicate request cache hash lists. * * 10 Dec 89 -- chet *	Re-do duplicate request cache allocation and locking scheme. * *  30 May 89 -- U. Sinkewicz *	Replaced smp_lock(&so->lk_socket, LK_RETRY) with SO_LOCK() *	as part of an smp bug fix.  Fix guarantees that socket doesn't *	changed while unlocked during sleeps or for the lock hierarchy. * *  6 Mar 89 -- chet *      Made duplicate request cache size a function of "system size". * * 19-Dec-88	condylis *	Restructured some of dupreq cache code because of inability to call *	kmem_alloc while holding a spin lock. * * 10-Jun-88	condylis *	Added smp locking to dupreq hash list and dupreq event counters *	and interaction with socket locks.  Added SMP locking for *	RPC server statistics. * * 12-11-87	Robin L. and Larry C. and Ricky P. *	Added new kmalloc memory allocation to system. * * 11 May 87 -- chet *	Changed/added new server duplicate *	transaction cache interface routines. * *//* * svc_kudp.c, * Server side for UDP/IP based RPC in the kernel. * */#include "../h/param.h"#include "../h/systm.h"#include "../h/time.h"#include "../rpc/types.h"#include "../netinet/in.h"#include "../rpc/xdr.h"#include "../rpc/auth.h"#include "../rpc/clnt.h"#include "../rpc/rpc_msg.h"#include "../rpc/svc.h"#include "../h/socket.h"#include "../h/socketvar.h"#include "../h/mbuf.h"#include "../h/kernel.h"#include "../h/smp_lock.h"#include "../h/cpudata.h"extern struct timeval *timepick;#define rpc_buffer(xprt) ((xprt)->xp_p1)/* * Routines exported through ops vector. */bool_t		svckudp_recv();bool_t		svckudp_send();enum xprt_stat	svckudp_stat();bool_t		svckudp_getargs();bool_t		svckudp_freeargs();void		svckudp_destroy();/* * Server transport operations vector. */struct xp_ops svckudp_op = {	svckudp_recv,		/* Get requests */	svckudp_stat,		/* Return status */	svckudp_getargs,	/* Deserialize arguments */	svckudp_send,		/* Send reply */	svckudp_freeargs,	/* Free argument data space */	svckudp_destroy		/* Destroy transport handle */};struct mbuf	*ku_recvfrom();void		xdrmbuf_init();/* * Transport private data. * Kept in xprt->xp_p2. */struct udp_data {	int	ud_flags;			/* flag bits, see below */	u_long 	ud_xid;				/* id */	struct	mbuf *ud_inmbuf;		/* input mbuf chain */	XDR	ud_xdrin;			/* input xdr stream */	XDR	ud_xdrout;			/* output xdr stream */	char	ud_verfbody[MAX_AUTH_BYTES];	/* verifier */	struct	lock_t	u_lk_udpdata;		/* smp lock for type 2*/						/* mbuf data  */};/* * Flags */#define	UD_BUSY		0x001		/* buffer is busy */#define	UD_WANTED	0x002		/* buffer wanted *//* * Server statistics */struct {	int	rscalls;	int	rsbadcalls;	int	rsnullrecv;	int	rsbadlen;	int	rsxdrcall;} rsstat;extern struct lock_t lk_nfsstat;/* * Create a transport record. * The transport record, output buffer, and private data structure * are allocated.  The output buffer is serialized into using xdrmem. * There is one transport record per user process which implements a * set of services. */SVCXPRT *svckudp_create(sock, port)	struct socket	*sock;	u_short		 port;{	register SVCXPRT	 *xprt;	register struct udp_data *ud;#ifdef RPCDEBUG	rpc_debug(4, "svckudp_create so = %x, port = %d\n", sock, port);#endif	kmem_alloc(xprt, SVCXPRT *, (u_int)sizeof(SVCXPRT), KM_RPC);	kmem_alloc(rpc_buffer(xprt), caddr_t, (u_int)UDPMSGSIZE, KM_RPC);	kmem_alloc(ud, struct udp_data *, (u_int)sizeof(struct udp_data), KM_RPC);	/* Initialize smp lock for outgoing type 2 mbuf data	*/	lockinit(&ud->u_lk_udpdata, &lock_udpdata_d);	xprt->xp_addrlen = 0;	xprt->xp_p2 = (caddr_t)ud;	xprt->xp_verf.oa_base = ud->ud_verfbody;	xprt->xp_ops = &svckudp_op;	xprt->xp_port = port;	xprt->xp_sock = sock;	xprt_register(xprt);	return (xprt);} /* * Destroy a transport record. * Frees the space allocated for a transport record. */voidsvckudp_destroy(xprt)	register SVCXPRT   *xprt;{	register struct udp_data *ud = (struct udp_data *)xprt->xp_p2;#ifdef RPCDEBUG	rpc_debug(4, "usr_destroy %x\n", xprt);#endif	if (ud->ud_inmbuf) {		m_freem(ud->ud_inmbuf);	}	kmem_free((caddr_t)ud, KM_RPC);	kmem_free((caddr_t)rpc_buffer(xprt), KM_RPC);	kmem_free((caddr_t)xprt, KM_RPC);}/* * Receive rpc requests. * Pulls a request in off the socket, checks if the packet is intact, * and deserializes the call packet. */bool_tsvckudp_recv(xprt, msg)	register SVCXPRT	 *xprt;	struct rpc_msg		 *msg;{	register struct udp_data *ud = (struct udp_data *)xprt->xp_p2;	register XDR	 *xdrs = &(ud->ud_xdrin);	register struct mbuf	 *m;	int			  s;#ifdef RPCDEBUG	rpc_debug(4, "svckudp_recv %x\n", xprt);#endif	smp_lock(&lk_nfsstat, LK_RETRY);	rsstat.rscalls++;	smp_unlock(&lk_nfsstat);	s = splnet();	/* smp lock socket during receive		*/	/* smp_lock(&xprt->xp_sock->lk_socket, LK_RETRY); */	SO_LOCK(xprt->xp_sock);	m = ku_recvfrom(xprt->xp_sock, &(xprt->xp_raddr));	smp_unlock(&xprt->xp_sock->lk_socket);	(void) splx(s);	if (m == NULL) {		/*		 * This looks silly, but this stat is useless		 * on an SMP machine by design. Leave it here		 * for non-SMP use only.		 */		if (!smp) {			smp_lock(&lk_nfsstat, LK_RETRY);			rsstat.rsnullrecv++;			smp_unlock(&lk_nfsstat);		}		return (FALSE);	}	if (m->m_len < 4*sizeof(u_long)) {		smp_lock(&lk_nfsstat, LK_RETRY);		rsstat.rsbadlen++;		smp_unlock(&lk_nfsstat);		goto bad;	}	xdrmbuf_init(&ud->ud_xdrin, m, XDR_DECODE);	if (! xdr_callmsg(xdrs, msg)) {		smp_lock(&lk_nfsstat, LK_RETRY);		rsstat.rsxdrcall++;		smp_unlock(&lk_nfsstat);		goto bad;	}	ud->ud_xid = msg->rm_xid;	ud->ud_inmbuf = m;#ifdef RPCDEBUG	rpc_debug(5, "svckudp_recv done\n");#endif	return (TRUE);bad:	m_freem(m);	ud->ud_inmbuf = NULL;	smp_lock(&lk_nfsstat, LK_RETRY);	rsstat.rsbadcalls++;	smp_unlock(&lk_nfsstat);	return (FALSE);}staticnoop(){}staticbuffree(ud)	register struct udp_data *ud;{	int	s;	s = splimp();	smp_lock(&ud->u_lk_udpdata, LK_RETRY);	ud->ud_flags &= ~UD_BUSY;	if (ud->ud_flags & UD_WANTED) {		ud->ud_flags &= ~UD_WANTED;		wakeup((caddr_t)ud);	}	smp_unlock(&ud->u_lk_udpdata);	splx(s);}/* * Send rpc reply. * Serialize the reply packet into the output buffer then * call ku_sendto to make an mbuf out of it and send it. */bool_t/* ARGSUSED */svckudp_send(xprt, msg)	register SVCXPRT *xprt; 	struct rpc_msg *msg; {	register struct udp_data *ud = (struct udp_data *)xprt->xp_p2;	register XDR *xdrs = &(ud->ud_xdrout);	register int slen;	register int stat = FALSE;	int s;	struct mbuf *m, *mclgetx();#ifdef RPCDEBUG	rpc_debug(4, "svckudp_send %x\n", xprt);#endif	s = splimp();	/* SMP lock mbuf data while setting up for sleep	*/	smp_lock(&ud->u_lk_udpdata, LK_RETRY);	while (ud->ud_flags & UD_BUSY) {		ud->ud_flags |= UD_WANTED;		sleep_unlock((caddr_t)ud, PZERO-2, &ud->u_lk_udpdata);		smp_lock(&ud->u_lk_udpdata, LK_RETRY);	}	ud->ud_flags |= UD_BUSY;	smp_unlock(&ud->u_lk_udpdata);	(void) splx(s);	m = mclgetx(buffree, (caddr_t)ud, rpc_buffer(xprt), UDPMSGSIZE, M_WAIT);	if (m == NULL) {		buffree(ud);		return (stat);	}	xdrmbuf_init(&ud->ud_xdrout, m, XDR_ENCODE);	msg->rm_xid = ud->ud_xid;	if (xdr_replymsg(xdrs, msg)) {		slen = (int)XDR_GETPOS(xdrs);		if (m->m_next == 0) {		/* XXX */			m->m_len = slen;		}		if (!ku_sendto_mbuf(xprt->xp_sock, m, &xprt->xp_raddr))			stat = TRUE;	} else {		printf("svckudp_send: xdr_replymsg failed\n");		m_freem(m);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -