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

📄 clnt_udp.c

📁 RTEMS (Real-Time Executive for Multiprocessor Systems) is a free open source real-time operating sys
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Sun RPC is a product of Sun Microsystems, Inc. and is provided for * unrestricted use provided that this legend is included on all tape * media and as a part of the software program in whole or part.  Users * may copy or modify Sun RPC without charge, but are not authorized * to license or distribute it to anyone else except as part of a product or * program developed by the user. * * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. * * Sun RPC is provided with no support and without any obligation on the * part of Sun Microsystems, Inc. to assist in its use, correction, * modification or enhancement. * * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC * OR ANY PART THEREOF. * * In no event will Sun Microsystems, Inc. be liable for any lost revenue * or profits or other special, indirect and consequential damages, even if * Sun has been advised of the possibility of such damages. * * Sun Microsystems, Inc. * 2550 Garcia Avenue * Mountain View, California  94043 */#if defined(LIBC_SCCS) && !defined(lint)/*static char *sccsid = "from: @(#)clnt_udp.c 1.39 87/08/11 Copyr 1984 Sun Micro";*//*static char *sccsid = "from: @(#)clnt_udp.c	2.2 88/08/01 4.0 RPCSRC";*/static char *rcsid = "$FreeBSD: src/lib/libc/rpc/clnt_udp.c,v 1.15 2000/01/27 23:06:36 jasone Exp $";#endif/* * clnt_udp.c, Implements a UDP/IP based, client side RPC. * * Copyright (C) 1984, Sun Microsystems, Inc. */#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <string.h>#include <rpc/rpc.h>#include <sys/socket.h>#include <sys/ioctl.h>#include <netdb.h>#include <errno.h>#include <rpc/pmap_clnt.h>#include <sys/select.h>/* * UDP bases client side rpc operations */static enum clnt_stat	clntudp_call();static void		clntudp_abort();static void		clntudp_geterr();static bool_t		clntudp_freeres();static bool_t           clntudp_control();static void		clntudp_destroy();static struct clnt_ops udp_ops = {	clntudp_call,	clntudp_abort,	clntudp_geterr,	clntudp_freeres,	clntudp_destroy,	clntudp_control};/* * Private data kept per client handle */struct cu_data {	int		   cu_sock;	bool_t		   cu_closeit;	struct sockaddr_in cu_raddr;	int		   cu_rlen;	struct timeval	   cu_wait;	struct timeval     cu_total;	struct rpc_err	   cu_error;	XDR		   cu_outxdrs;	u_int		   cu_xdrpos;	u_int		   cu_sendsz;	char		   *cu_outbuf;	u_int		   cu_recvsz;	char		   cu_inbuf[1];};/* * Create a UDP based client handle. * If *sockp<0, *sockp is set to a newly created UPD socket. * If raddr->sin_port is 0 a binder on the remote machine * is consulted for the correct port number. * NB: It is the clients responsibility to close *sockp. * NB: The rpch->cl_auth is initialized to null authentication. *     Caller may wish to set this something more useful. * * wait is the amount of time used between retransmitting a call if * no response has been heard;  retransmition occurs until the actual * rpc call times out. * * sendsz and recvsz are the maximum allowable packet sizes that can be * sent and received. */CLIENT *clntudp_bufcreate(raddr, program, version, wait, sockp, sendsz, recvsz)	struct sockaddr_in *raddr;	u_long program;	u_long version;	struct timeval wait;	register int *sockp;	u_int sendsz;	u_int recvsz;{	CLIENT *cl;	register struct cu_data *cu = NULL;	struct timeval now;	struct rpc_msg call_msg;	static u_int32_t disrupt;	if (disrupt == 0)		disrupt = (u_int32_t)(long)raddr;	cl = (CLIENT *)mem_alloc(sizeof(CLIENT));	if (cl == NULL) {		(void) fprintf(stderr, "clntudp_create: out of memory\n");		rpc_createerr.cf_stat = RPC_SYSTEMERROR;		rpc_createerr.cf_error.re_errno = errno;		goto fooy;	}	sendsz = ((sendsz + 3) / 4) * 4;	recvsz = ((recvsz + 3) / 4) * 4;	cu = (struct cu_data *)mem_alloc(sizeof(*cu) + sendsz + recvsz);	if (cu == NULL) {		(void) fprintf(stderr, "clntudp_create: out of memory\n");		rpc_createerr.cf_stat = RPC_SYSTEMERROR;		rpc_createerr.cf_error.re_errno = errno;		goto fooy;	}	cu->cu_outbuf = &cu->cu_inbuf[recvsz];	(void)gettimeofday(&now, (struct timezone *)0);	if (raddr->sin_port == 0) {		u_short port;		if ((port =		    pmap_getport(raddr, program, version, IPPROTO_UDP)) == 0) {			goto fooy;		}		raddr->sin_port = htons(port);	}	cl->cl_ops = &udp_ops;	cl->cl_private = (caddr_t)cu;	cu->cu_raddr = *raddr;	cu->cu_rlen = sizeof (cu->cu_raddr);	cu->cu_wait = wait;	cu->cu_total.tv_sec = -1;	cu->cu_total.tv_usec = -1;	cu->cu_sendsz = sendsz;	cu->cu_recvsz = recvsz;	call_msg.rm_xid = (++disrupt) ^ getpid() ^ now.tv_sec ^ now.tv_usec;	call_msg.rm_direction = CALL;	call_msg.rm_call.cb_rpcvers = RPC_MSG_VERSION;	call_msg.rm_call.cb_prog = program;	call_msg.rm_call.cb_vers = version;	xdrmem_create(&(cu->cu_outxdrs), cu->cu_outbuf,	    sendsz, XDR_ENCODE);	if (! xdr_callhdr(&(cu->cu_outxdrs), &call_msg)) {		goto fooy;	}	cu->cu_xdrpos = XDR_GETPOS(&(cu->cu_outxdrs));	if (*sockp < 0) {		int dontblock = 1;		*sockp = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);		if (*sockp < 0) {			rpc_createerr.cf_stat = RPC_SYSTEMERROR;			rpc_createerr.cf_error.re_errno = errno;			goto fooy;		}		/* attempt to bind to priv port */		(void)bindresvport(*sockp, (struct sockaddr_in *)0);		/* the sockets rpc controls are non-blocking */		(void)ioctl(*sockp, FIONBIO, (char *) &dontblock);		cu->cu_closeit = TRUE;	} else {		cu->cu_closeit = FALSE;	}	cu->cu_sock = *sockp;	cl->cl_auth = authnone_create();	return (cl);fooy:	if (cu)		mem_free((caddr_t)cu, sizeof(*cu) + sendsz + recvsz);	if (cl)		mem_free((caddr_t)cl, sizeof(CLIENT));	return ((CLIENT *)NULL);}CLIENT *clntudp_create(raddr, program, version, wait, sockp)	struct sockaddr_in *raddr;	u_long program;	u_long version;	struct timeval wait;	register int *sockp;{	return(clntudp_bufcreate(raddr, program, version, wait, sockp,	    UDPMSGSIZE, UDPMSGSIZE));}static enum clnt_statclntudp_call(cl, proc, xargs, argsp, xresults, resultsp, utimeout)	register CLIENT	*cl;		/* client handle */	u_long		proc;		/* procedure number */	xdrproc_t	xargs;		/* xdr routine for args */	caddr_t		argsp;		/* pointer to args */	xdrproc_t	xresults;	/* xdr routine for results */	caddr_t		resultsp;	/* pointer to results */	struct timeval	utimeout;	/* seconds to wait before giving up */{	register struct cu_data *cu = (struct cu_data *)cl->cl_private;	register XDR *xdrs;	register int outlen;	register int inlen;	int fromlen;	fd_set *fds, readfds;	struct sockaddr_in from;	struct rpc_msg reply_msg;	XDR reply_xdrs;	struct timeval time_waited, start, after, tmp1, tmp2, tv;	bool_t ok;	int nrefreshes = 2;	/* number of times to refresh cred */	struct timeval timeout;	if (cu->cu_total.tv_usec == -1)		timeout = utimeout;     /* use supplied timeout */	else		timeout = cu->cu_total; /* use default timeout */	if (cu->cu_sock + 1 > FD_SETSIZE) {		int bytes = howmany(cu->cu_sock + 1, NFDBITS) * sizeof(fd_mask);		fds = (fd_set *)malloc(bytes);		if (fds == NULL)			return (cu->cu_error.re_status = RPC_CANTSEND);		memset(fds, 0, bytes);	} else {		fds = &readfds;		FD_ZERO(fds);	}	timerclear(&time_waited);call_again:	xdrs = &(cu->cu_outxdrs);	xdrs->x_op = XDR_ENCODE;	XDR_SETPOS(xdrs, cu->cu_xdrpos);	/*	 * the transaction is the first thing in the out buffer	 */	(*(u_short *)(cu->cu_outbuf))++;	if ((! XDR_PUTLONG(xdrs, (long *)&proc)) ||	    (! AUTH_MARSHALL(cl->cl_auth, xdrs)) ||	    (! (*xargs)(xdrs, argsp))) {		if (fds != &readfds)			free(fds);		return (cu->cu_error.re_status = RPC_CANTENCODEARGS);	}	outlen = (int)XDR_GETPOS(xdrs);send_again:	if (sendto(cu->cu_sock, cu->cu_outbuf, outlen, 0,	    (struct sockaddr *)&(cu->cu_raddr), cu->cu_rlen) != outlen) {		cu->cu_error.re_errno = errno;		if (fds != &readfds)			free(fds);		return (cu->cu_error.re_status = RPC_CANTSEND);	}	/*	 * Hack to provide rpc-based message passing	 */

⌨️ 快捷键说明

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