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

📄 clnt_kudp.c

📁 操作系统SunOS 4.1.3版本的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
			/*			 * Set timeout then wait for input, timeout			 * or interrupt.			 */#ifdef RPCDEBUG			rpc_debug(3, "callit: waiting %d\n", timohz);#endif			timeout(ckuwakeup, (caddr_t)p, timohz);			so->so_rcv.sb_flags |= SB_WAIT;#if defined(ASYNCHIO) && defined(LWP)			if (!runthreads) {#endif /* ASYNCHIO && LWP */				smask = pp->p_sigmask;				pp->p_sigmask |= ~(sigmask(SIGHUP) |					sigmask(SIGINT) | sigmask(SIGQUIT) |					sigmask(SIGTERM));#if defined(ASYNCHIO) && defined(LWP)			}#endif /* ASYNCHIO && LWP */			/*			 * Hideous hack here for sunview locking bug			 * Please remove this when they fix their code			 */			pp->p_flag |= SRPC;			interrupted = sleep((caddr_t)&so->so_rcv.sb_cc,				PZERO+1 | PCATCH);			pp->p_flag &= ~SRPC;#if defined(ASYNCHIO) && defined(LWP)			if (!runthreads)#endif /* ASYNCHIO && LWP */				pp->p_sigmask = smask;			untimeout(ckuwakeup, (caddr_t)p);			if (interrupted) {				(void) splx(s);				p->cku_err.re_status = RPC_INTR;				p->cku_err.re_errno = EINTR;				goto done;			}			if (p->cku_flags & CKU_TIMEDOUT) {				p->cku_flags &= ~CKU_TIMEDOUT;				(void) splx(s);				p->cku_err.re_status = RPC_TIMEDOUT;				p->cku_err.re_errno = ETIMEDOUT;				rcstat.rctimeouts++;				goto done;			}		}		if (so->so_error) {			so->so_error = 0;			(void) splx(s);			continue;		}		{			/*			 * Declare this variable here to have smaller			 * demand for stack space in this procedure.			 */			struct sockaddr_in from;			p->cku_inmbuf = ku_recvfrom(so, &from);			if (sin) {				*sin = from;			}		}		(void) splx(s);		if (p->cku_inmbuf == NULL) {			continue;		}		p->cku_inbuf = mtod(p->cku_inmbuf, char *);		if (p->cku_inmbuf->m_len < sizeof (u_long)) {			m_freem(p->cku_inmbuf);			continue;		}		/*		 * If reply transaction id matches id sent		 * we have a good packet.		 */		if (*((u_long *)(p->cku_inbuf))		    != *((u_long *)(p->cku_outbuf))) {			rcstat.rcbadxids++;			m_freem(p->cku_inmbuf);			continue;		}		break;	}	if (rtries == 0) {		p->cku_err.re_status = RPC_CANTRECV;		p->cku_err.re_errno = EIO;		goto done;	}	round_trip = time_in_hz - round_trip;	/*	 * Van Jacobson timer algorithm here, only if NOT a retransmission.	 */	if (p->cku_timers != (struct rpc_timers *)0 &&	    (stries == p->cku_retrys) && !ignorebad) {		register int rt;		rt = round_trip;		rt -= (p->cku_timers->rt_srtt >> 3);		p->cku_timers->rt_srtt += rt;		if (rt < 0)			rt = - rt;		rt -= (p->cku_timers->rt_deviate >> 2);		p->cku_timers->rt_deviate += rt;		p->cku_timers->rt_rtxcur =			((p->cku_timers->rt_srtt >> 2) +			    p->cku_timers->rt_deviate) >> 1;		rt = round_trip;		rt -= (p->cku_timeall->rt_srtt >> 3);		p->cku_timeall->rt_srtt += rt;		if (rt < 0)			rt = - rt;		rt -= (p->cku_timeall->rt_deviate >> 2);		p->cku_timeall->rt_deviate += rt;		p->cku_timeall->rt_rtxcur =			((p->cku_timeall->rt_srtt >> 2) +			    p->cku_timeall->rt_deviate) >> 1;		if (p->cku_feedback != (void (*)()) 0)		    (*p->cku_feedback)(FEEDBACK_OK, procnum, p->cku_feedarg);	}	/*	 * Process reply	 */	xdrs = &(p->cku_inxdr);	xdrmbuf_init(xdrs, p->cku_inmbuf, XDR_DECODE);	{		/*		 * Declare this variable here to have smaller		 * demand for stack space in this procedure.		 */		struct rpc_msg		   reply_msg;		reply_msg.acpted_rply.ar_verf = _null_auth;		reply_msg.acpted_rply.ar_results.where = resultsp;		reply_msg.acpted_rply.ar_results.proc = xdr_results;		/*		 * Decode and validate the response.		 */		if (xdr_replymsg(xdrs, &reply_msg)) {			_seterr_reply(&reply_msg, &(p->cku_err));			if (p->cku_err.re_status == RPC_SUCCESS) {				/*				 * Reply is good, check auth.				 */				if (! AUTH_VALIDATE(h->cl_auth,				    &reply_msg.acpted_rply.ar_verf)) {					p->cku_err.re_status = RPC_AUTHERROR;					p->cku_err.re_why = AUTH_INVALIDRESP;					rcstat.rcbadverfs++;				}				if (reply_msg.acpted_rply.ar_verf.oa_base !=				    NULL) {					/* free auth handle */					xdrs->x_op = XDR_FREE;					(void) xdr_opaque_auth(xdrs,					    &(reply_msg.acpted_rply.ar_verf));				}			} else {				p->cku_err.re_errno = EIO;				/*				 * Maybe our credential needs refreshed				 */				if (refreshes > 0 && AUTH_REFRESH(h->cl_auth)) {					refreshes--;					rcstat.rcnewcreds++;					rempos = 0;				}			}		} else {			p->cku_err.re_status = RPC_CANTDECODERES;			p->cku_err.re_errno = EIO;		}	}	m_freem(p->cku_inmbuf);#ifdef RPCDEBUG	rpc_debug(4, "cku_callit done\n");#endifdone:	/*	 * Weed out remote rpc error replies.	 */	if (ignorebad &&		((p->cku_err.re_status == RPC_VERSMISMATCH) ||		    (p->cku_err.re_status == RPC_AUTHERROR) ||		    (p->cku_err.re_status == RPC_PROGUNAVAIL) ||		    (p->cku_err.re_status == RPC_PROGVERSMISMATCH) ||		    (p->cku_err.re_status == RPC_PROCUNAVAIL) ||		    (p->cku_err.re_status == RPC_CANTDECODEARGS) ||		    (p->cku_err.re_status == RPC_SYSTEMERROR)))		goto recv_again;	/*	 * Flush the rest of the stuff on the input queue	 * for the socket.	 */	s = splnet();	sbflush(&so->so_rcv);	(void) splx(s);	if ((p->cku_err.re_status != RPC_SUCCESS) &&	    (p->cku_err.re_status != RPC_INTR) &&	    (p->cku_err.re_status != RPC_CANTENCODEARGS)) {		if (p->cku_feedback != (void (*)()) 0 &&		    stries == p->cku_retrys)			(*p->cku_feedback)(FEEDBACK_REXMIT1,				procnum, p->cku_feedarg);		timohz = backoff(timohz);		if (p->cku_timeall != (struct rpc_timers *)0)			p->cku_timeall->rt_rtxcur = timohz;		if (p->cku_err.re_status == RPC_SYSTEMERROR ||		    p->cku_err.re_status == RPC_CANTSEND) {			/*			 * Errors due to lack o resources, wait a bit			 * and try again.			 */			(void) sleep((caddr_t)&lbolt, PZERO-4);		}		if (--stries > 0) {			rcstat.rcretrans++;			goto call_again;		}	}	u.u_cred = tmpcred;	/*	 * Insure that buffer is not busy prior to releasing client handle.	 */	s = splimp();	while (p->cku_flags & CKU_BUFBUSY) {		p->cku_flags |= CKU_BUFWANTED;		timeout(wakeup, (caddr_t)&p->cku_outbuf, hz);		(void) sleep((caddr_t)&p->cku_outbuf, PZERO-3);		if (!(p->cku_flags & CKU_BUFBUSY)) {			/* probably woke up from buffree	*/			untimeout(wakeup, (caddr_t)&p->cku_outbuf);		}		sbflush(&so->so_rcv);	}	(void) splx(s);	p->cku_flags &= ~CKU_BUSY;	if (p->cku_flags & CKU_WANTED) {		p->cku_flags &= ~CKU_WANTED;		wakeup((caddr_t)h);	}	if (p->cku_err.re_status != RPC_SUCCESS) {		rcstat.rcbadcalls++;	}	return (p->cku_err.re_status);}enum clnt_statclntkudp_callit(h, procnum, xdr_args, argsp, xdr_results, resultsp, wait)	register CLIENT *h;	u_long		procnum;	xdrproc_t	xdr_args;	caddr_t		argsp;	xdrproc_t	xdr_results;	caddr_t		resultsp;	struct timeval	wait;{	return (clntkudp_callit_addr(h, procnum, xdr_args, argsp, xdr_results,		resultsp, wait, (struct sockaddr_in *)0, 0));}/* * Wake up client waiting for a reply. */ckuwakeup(p)	register struct cku_private *p;{	register struct socket	*so = p->cku_sock;#ifdef RPCDEBUG	rpc_debug(4, "cku_timeout\n");#endif	p->cku_flags |= CKU_TIMEDOUT;	sbwakeup(so, &so->so_rcv);}/* * Return error info on this handle. */voidclntkudp_error(h, err)	CLIENT *h;	struct rpc_err *err;{	register struct cku_private *p = htop(h);	*err = p->cku_err;}static bool_tclntkudp_freeres(cl, xdr_res, res_ptr)	CLIENT *cl;	xdrproc_t xdr_res;	caddr_t res_ptr;{	register struct cku_private *p = (struct cku_private *)cl->cl_private;	register XDR *xdrs = &(p->cku_outxdr);	xdrs->x_op = XDR_FREE;	return ((*xdr_res)(xdrs, res_ptr));}voidclntkudp_abort(){}bool_tclntkudp_control(){	return (FALSE);}/* * Destroy rpc handle. * Frees the space used for output buffer, private data, and handle * structure, and closes the socket for this handle. */voidclntkudp_destroy(h)	CLIENT *h;{	register struct cku_private *p = htop(h);#ifdef RPCDEBUG	rpc_debug(4, "cku_destroy %x\n", h);#endif	(void) soclose(p->cku_sock);	kmem_free((caddr_t)p->cku_outbuf, (u_int)UDPMSGSIZE);	kmem_free((caddr_t)p, sizeof (*p));}/* * try to bind to a reserved port */bindresvport(so)	struct socket *so;{	struct sockaddr_in *sin;	struct mbuf *m;	u_short i;	int error;	struct ucred *tmpcred;	struct ucred *savecred;#	define MAX_PRIV	(IPPORT_RESERVED-1)#	define MIN_PRIV	(IPPORT_RESERVED/2)	m = m_get(M_WAIT, MT_SONAME);	if (m == NULL) {		printf("bindresvport: couldn't alloc mbuf");		return (ENOBUFS);	}	sin = mtod(m, struct sockaddr_in *);	sin->sin_family = AF_INET;	sin->sin_addr.s_addr = INADDR_ANY;	m->m_len = sizeof (struct sockaddr_in);	/*	 * Only root can bind to a privileged port number, so	 * temporarily change the uid to 0 to do the bind.	 */	tmpcred = crdup(u.u_cred);	savecred = u.u_cred;	u.u_cred = tmpcred;	u.u_uid = 0;	error = EADDRINUSE;	for (i = MAX_PRIV; error == EADDRINUSE && i >= MIN_PRIV; i--) {		sin->sin_port = htons(i);		error = sobind(so, m);	}	(void) m_freem(m);	u.u_cred = savecred;	crfree(tmpcred);	return (error);}#endif	KERNEL

⌨️ 快捷键说明

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