clnt_raw.c revision 11845
1284345Ssjg/*
2284345Ssjg * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
3284345Ssjg * unrestricted use provided that this legend is included on all tape
4284345Ssjg * media and as a part of the software program in whole or part.  Users
5284345Ssjg * may copy or modify Sun RPC without charge, but are not authorized
6284345Ssjg * to license or distribute it to anyone else except as part of a product or
7284345Ssjg * program developed by the user.
8284345Ssjg *
9284345Ssjg * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
10284345Ssjg * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
11284345Ssjg * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
12284345Ssjg *
13284345Ssjg * Sun RPC is provided with no support and without any obligation on the
14284345Ssjg * part of Sun Microsystems, Inc. to assist in its use, correction,
15284345Ssjg * modification or enhancement.
16284345Ssjg *
17284345Ssjg * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
18284345Ssjg * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
19284345Ssjg * OR ANY PART THEREOF.
20 *
21 * In no event will Sun Microsystems, Inc. be liable for any lost revenue
22 * or profits or other special, indirect and consequential damages, even if
23 * Sun has been advised of the possibility of such damages.
24 *
25 * Sun Microsystems, Inc.
26 * 2550 Garcia Avenue
27 * Mountain View, California  94043
28 */
29
30#if defined(LIBC_SCCS) && !defined(lint)
31/*static char *sccsid = "from: @(#)clnt_raw.c 1.22 87/08/11 Copyr 1984 Sun Micro";*/
32/*static char *sccsid = "from: @(#)clnt_raw.c	2.2 88/08/01 4.0 RPCSRC";*/
33static char *rcsid = "$Id: clnt_raw.c,v 1.3 1995/10/22 14:51:16 phk Exp $";
34#endif
35
36/*
37 * clnt_raw.c
38 *
39 * Copyright (C) 1984, Sun Microsystems, Inc.
40 *
41 * Memory based rpc for simple testing and timing.
42 * Interface to create an rpc client and server in the same process.
43 * This lets us similate rpc and get round trip overhead, without
44 * any interference from the kernal.
45 */
46
47#include <rpc/rpc.h>
48#include <stdlib.h>
49
50#define MCALL_MSG_SIZE 24
51
52/*
53 * This is the "network" we will be moving stuff over.
54 */
55static struct clntraw_private {
56	CLIENT	client_object;
57	XDR	xdr_stream;
58	char	_raw_buf[UDPMSGSIZE];
59	char	mashl_callmsg[MCALL_MSG_SIZE];
60	u_int	mcnt;
61} *clntraw_private;
62
63static enum clnt_stat	clntraw_call();
64static void		clntraw_abort();
65static void		clntraw_geterr();
66static bool_t		clntraw_freeres();
67static bool_t		clntraw_control();
68static void		clntraw_destroy();
69
70static struct clnt_ops client_ops = {
71	clntraw_call,
72	clntraw_abort,
73	clntraw_geterr,
74	clntraw_freeres,
75	clntraw_destroy,
76	clntraw_control
77};
78
79void	svc_getreq();
80
81/*
82 * Create a client handle for memory based rpc.
83 */
84CLIENT *
85clntraw_create(prog, vers)
86	u_long prog;
87	u_long vers;
88{
89	register struct clntraw_private *clp = clntraw_private;
90	struct rpc_msg call_msg;
91	XDR *xdrs = &clp->xdr_stream;
92	CLIENT	*client = &clp->client_object;
93
94	if (clp == 0) {
95		clp = (struct clntraw_private *)calloc(1, sizeof (*clp));
96		if (clp == 0)
97			return (0);
98		clntraw_private = clp;
99	}
100	/*
101	 * pre-serialize the static part of the call msg and stash it away
102	 */
103	call_msg.rm_direction = CALL;
104	call_msg.rm_call.cb_rpcvers = RPC_MSG_VERSION;
105	call_msg.rm_call.cb_prog = prog;
106	call_msg.rm_call.cb_vers = vers;
107	xdrmem_create(xdrs, clp->mashl_callmsg, MCALL_MSG_SIZE, XDR_ENCODE);
108	if (! xdr_callhdr(xdrs, &call_msg)) {
109		perror("clnt_raw.c - Fatal header serialization error.");
110	}
111	clp->mcnt = XDR_GETPOS(xdrs);
112	XDR_DESTROY(xdrs);
113
114	/*
115	 * Set xdrmem for client/server shared buffer
116	 */
117	xdrmem_create(xdrs, clp->_raw_buf, UDPMSGSIZE, XDR_FREE);
118
119	/*
120	 * create client handle
121	 */
122	client->cl_ops = &client_ops;
123	client->cl_auth = authnone_create();
124	return (client);
125}
126
127static enum clnt_stat
128clntraw_call(h, proc, xargs, argsp, xresults, resultsp, timeout)
129	CLIENT *h;
130	u_long proc;
131	xdrproc_t xargs;
132	caddr_t argsp;
133	xdrproc_t xresults;
134	caddr_t resultsp;
135	struct timeval timeout;
136{
137	register struct clntraw_private *clp = clntraw_private;
138	register XDR *xdrs = &clp->xdr_stream;
139	struct rpc_msg msg;
140	enum clnt_stat status;
141	struct rpc_err error;
142
143	if (clp == 0)
144		return (RPC_FAILED);
145call_again:
146	/*
147	 * send request
148	 */
149	xdrs->x_op = XDR_ENCODE;
150	XDR_SETPOS(xdrs, 0);
151	((struct rpc_msg *)clp->mashl_callmsg)->rm_xid ++ ;
152	if ((! XDR_PUTBYTES(xdrs, clp->mashl_callmsg, clp->mcnt)) ||
153	    (! XDR_PUTLONG(xdrs, (long *)&proc)) ||
154	    (! AUTH_MARSHALL(h->cl_auth, xdrs)) ||
155	    (! (*xargs)(xdrs, argsp))) {
156		return (RPC_CANTENCODEARGS);
157	}
158	(void)XDR_GETPOS(xdrs);  /* called just to cause overhead */
159
160	/*
161	 * We have to call server input routine here because this is
162	 * all going on in one process. Yuk.
163	 */
164	svc_getreq(1);
165
166	/*
167	 * get results
168	 */
169	xdrs->x_op = XDR_DECODE;
170	XDR_SETPOS(xdrs, 0);
171	msg.acpted_rply.ar_verf = _null_auth;
172	msg.acpted_rply.ar_results.where = resultsp;
173	msg.acpted_rply.ar_results.proc = xresults;
174	if (! xdr_replymsg(xdrs, &msg))
175		return (RPC_CANTDECODERES);
176	_seterr_reply(&msg, &error);
177	status = error.re_status;
178
179	if (status == RPC_SUCCESS) {
180		if (! AUTH_VALIDATE(h->cl_auth, &msg.acpted_rply.ar_verf)) {
181			status = RPC_AUTHERROR;
182		}
183	}  /* end successful completion */
184	else {
185		if (AUTH_REFRESH(h->cl_auth))
186			goto call_again;
187	}  /* end of unsuccessful completion */
188
189	if (status == RPC_SUCCESS) {
190		if (! AUTH_VALIDATE(h->cl_auth, &msg.acpted_rply.ar_verf)) {
191			status = RPC_AUTHERROR;
192		}
193		if (msg.acpted_rply.ar_verf.oa_base != NULL) {
194			xdrs->x_op = XDR_FREE;
195			(void)xdr_opaque_auth(xdrs, &(msg.acpted_rply.ar_verf));
196		}
197	}
198
199	return (status);
200}
201
202static void
203clntraw_geterr()
204{
205}
206
207
208static bool_t
209clntraw_freeres(cl, xdr_res, res_ptr)
210	CLIENT *cl;
211	xdrproc_t xdr_res;
212	caddr_t res_ptr;
213{
214	register struct clntraw_private *clp = clntraw_private;
215	register XDR *xdrs = &clp->xdr_stream;
216	bool_t rval;
217
218	if (clp == 0)
219	{
220		rval = (bool_t) RPC_FAILED;
221		return (rval);
222	}
223	xdrs->x_op = XDR_FREE;
224	return ((*xdr_res)(xdrs, res_ptr));
225}
226
227static void
228clntraw_abort()
229{
230}
231
232static bool_t
233clntraw_control()
234{
235	return (FALSE);
236}
237
238static void
239clntraw_destroy()
240{
241}
242