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