1*7f2fe78bSCy Schubert /* @(#)clnt_raw.c 2.2 88/08/01 4.0 RPCSRC */
2*7f2fe78bSCy Schubert /*
3*7f2fe78bSCy Schubert * Copyright (c) 2010, Oracle America, Inc.
4*7f2fe78bSCy Schubert *
5*7f2fe78bSCy Schubert * All rights reserved.
6*7f2fe78bSCy Schubert *
7*7f2fe78bSCy Schubert * Redistribution and use in source and binary forms, with or without
8*7f2fe78bSCy Schubert * modification, are permitted provided that the following conditions are met:
9*7f2fe78bSCy Schubert *
10*7f2fe78bSCy Schubert * * Redistributions of source code must retain the above copyright
11*7f2fe78bSCy Schubert * notice, this list of conditions and the following disclaimer.
12*7f2fe78bSCy Schubert *
13*7f2fe78bSCy Schubert * * Redistributions in binary form must reproduce the above copyright
14*7f2fe78bSCy Schubert * notice, this list of conditions and the following disclaimer in
15*7f2fe78bSCy Schubert * the documentation and/or other materials provided with the
16*7f2fe78bSCy Schubert * distribution.
17*7f2fe78bSCy Schubert *
18*7f2fe78bSCy Schubert * * Neither the name of the "Oracle America, Inc." nor the names of
19*7f2fe78bSCy Schubert * its contributors may be used to endorse or promote products
20*7f2fe78bSCy Schubert * derived from this software without specific prior written permission.
21*7f2fe78bSCy Schubert *
22*7f2fe78bSCy Schubert * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
23*7f2fe78bSCy Schubert * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
24*7f2fe78bSCy Schubert * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
25*7f2fe78bSCy Schubert * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
26*7f2fe78bSCy Schubert * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
27*7f2fe78bSCy Schubert * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
28*7f2fe78bSCy Schubert * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
29*7f2fe78bSCy Schubert * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
30*7f2fe78bSCy Schubert * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
31*7f2fe78bSCy Schubert * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
32*7f2fe78bSCy Schubert * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33*7f2fe78bSCy Schubert */
34*7f2fe78bSCy Schubert #if !defined(lint) && defined(SCCSIDS)
35*7f2fe78bSCy Schubert static char sccsid[] = "@(#)clnt_raw.c 1.22 87/08/11 Copyr 1984 Sun Micro";
36*7f2fe78bSCy Schubert #endif
37*7f2fe78bSCy Schubert
38*7f2fe78bSCy Schubert /*
39*7f2fe78bSCy Schubert * clnt_raw.c
40*7f2fe78bSCy Schubert *
41*7f2fe78bSCy Schubert * Memory based rpc for simple testing and timing.
42*7f2fe78bSCy Schubert * Interface to create an rpc client and server in the same process.
43*7f2fe78bSCy Schubert * This lets us similate rpc and get round trip overhead, without
44*7f2fe78bSCy Schubert * any interference from the kernel.
45*7f2fe78bSCy Schubert */
46*7f2fe78bSCy Schubert
47*7f2fe78bSCy Schubert #include <gssrpc/rpc.h>
48*7f2fe78bSCy Schubert
49*7f2fe78bSCy Schubert #define MCALL_MSG_SIZE 24
50*7f2fe78bSCy Schubert
51*7f2fe78bSCy Schubert /*
52*7f2fe78bSCy Schubert * This is the "network" we will be moving stuff over.
53*7f2fe78bSCy Schubert */
54*7f2fe78bSCy Schubert static struct clntraw_private {
55*7f2fe78bSCy Schubert CLIENT client_object;
56*7f2fe78bSCy Schubert XDR xdr_stream;
57*7f2fe78bSCy Schubert char _raw_buf[UDPMSGSIZE];
58*7f2fe78bSCy Schubert union {
59*7f2fe78bSCy Schubert struct rpc_msg mashl_rpcmsg;
60*7f2fe78bSCy Schubert char mashl_callmsg[MCALL_MSG_SIZE];
61*7f2fe78bSCy Schubert } u;
62*7f2fe78bSCy Schubert u_int mcnt;
63*7f2fe78bSCy Schubert } *clntraw_private;
64*7f2fe78bSCy Schubert
65*7f2fe78bSCy Schubert static enum clnt_stat clntraw_call(CLIENT *, rpcproc_t, xdrproc_t,
66*7f2fe78bSCy Schubert void *, xdrproc_t, void *,
67*7f2fe78bSCy Schubert struct timeval);
68*7f2fe78bSCy Schubert static void clntraw_abort(CLIENT *);
69*7f2fe78bSCy Schubert static void clntraw_geterr(CLIENT *, struct rpc_err *);
70*7f2fe78bSCy Schubert static bool_t clntraw_freeres(CLIENT *, xdrproc_t, void *);
71*7f2fe78bSCy Schubert static bool_t clntraw_control(CLIENT *, int, void *);
72*7f2fe78bSCy Schubert static void clntraw_destroy(CLIENT *);
73*7f2fe78bSCy Schubert
74*7f2fe78bSCy Schubert static struct clnt_ops client_ops = {
75*7f2fe78bSCy Schubert clntraw_call,
76*7f2fe78bSCy Schubert clntraw_abort,
77*7f2fe78bSCy Schubert clntraw_geterr,
78*7f2fe78bSCy Schubert clntraw_freeres,
79*7f2fe78bSCy Schubert clntraw_destroy,
80*7f2fe78bSCy Schubert clntraw_control
81*7f2fe78bSCy Schubert };
82*7f2fe78bSCy Schubert
83*7f2fe78bSCy Schubert void svc_getreq();
84*7f2fe78bSCy Schubert
85*7f2fe78bSCy Schubert /*
86*7f2fe78bSCy Schubert * Create a client handle for memory based rpc.
87*7f2fe78bSCy Schubert */
88*7f2fe78bSCy Schubert CLIENT *
clntraw_create(rpcprog_t prog,rpcvers_t vers)89*7f2fe78bSCy Schubert clntraw_create(
90*7f2fe78bSCy Schubert rpcprog_t prog,
91*7f2fe78bSCy Schubert rpcvers_t vers)
92*7f2fe78bSCy Schubert {
93*7f2fe78bSCy Schubert struct clntraw_private *clp;
94*7f2fe78bSCy Schubert struct rpc_msg call_msg;
95*7f2fe78bSCy Schubert XDR *xdrs;
96*7f2fe78bSCy Schubert CLIENT *client;
97*7f2fe78bSCy Schubert
98*7f2fe78bSCy Schubert if (clntraw_private == NULL) {
99*7f2fe78bSCy Schubert clntraw_private = calloc(1, sizeof(*clp));
100*7f2fe78bSCy Schubert if (clntraw_private == NULL)
101*7f2fe78bSCy Schubert return (NULL);
102*7f2fe78bSCy Schubert }
103*7f2fe78bSCy Schubert clp = clntraw_private;
104*7f2fe78bSCy Schubert xdrs = &clp->xdr_stream;
105*7f2fe78bSCy Schubert client = &clp->client_object;
106*7f2fe78bSCy Schubert /*
107*7f2fe78bSCy Schubert * pre-serialize the staic part of the call msg and stash it away
108*7f2fe78bSCy Schubert */
109*7f2fe78bSCy Schubert call_msg.rm_direction = CALL;
110*7f2fe78bSCy Schubert call_msg.rm_call.cb_rpcvers = RPC_MSG_VERSION;
111*7f2fe78bSCy Schubert call_msg.rm_call.cb_prog = prog;
112*7f2fe78bSCy Schubert call_msg.rm_call.cb_vers = vers;
113*7f2fe78bSCy Schubert xdrmem_create(xdrs, clp->u.mashl_callmsg, MCALL_MSG_SIZE, XDR_ENCODE);
114*7f2fe78bSCy Schubert if (! xdr_callhdr(xdrs, &call_msg)) {
115*7f2fe78bSCy Schubert perror("clnt_raw.c - Fatal header serialization error.");
116*7f2fe78bSCy Schubert }
117*7f2fe78bSCy Schubert clp->mcnt = XDR_GETPOS(xdrs);
118*7f2fe78bSCy Schubert XDR_DESTROY(xdrs);
119*7f2fe78bSCy Schubert
120*7f2fe78bSCy Schubert /*
121*7f2fe78bSCy Schubert * Set xdrmem for client/server shared buffer
122*7f2fe78bSCy Schubert */
123*7f2fe78bSCy Schubert xdrmem_create(xdrs, clp->_raw_buf, UDPMSGSIZE, XDR_FREE);
124*7f2fe78bSCy Schubert
125*7f2fe78bSCy Schubert /*
126*7f2fe78bSCy Schubert * create client handle
127*7f2fe78bSCy Schubert */
128*7f2fe78bSCy Schubert client->cl_ops = &client_ops;
129*7f2fe78bSCy Schubert client->cl_auth = authnone_create();
130*7f2fe78bSCy Schubert return (client);
131*7f2fe78bSCy Schubert }
132*7f2fe78bSCy Schubert
133*7f2fe78bSCy Schubert static enum clnt_stat
clntraw_call(CLIENT * h,rpcproc_t proc,xdrproc_t xargs,void * argsp,xdrproc_t xresults,void * resultsp,struct timeval timeout)134*7f2fe78bSCy Schubert clntraw_call(
135*7f2fe78bSCy Schubert CLIENT *h,
136*7f2fe78bSCy Schubert rpcproc_t proc,
137*7f2fe78bSCy Schubert xdrproc_t xargs,
138*7f2fe78bSCy Schubert void * argsp,
139*7f2fe78bSCy Schubert xdrproc_t xresults,
140*7f2fe78bSCy Schubert void * resultsp,
141*7f2fe78bSCy Schubert struct timeval timeout)
142*7f2fe78bSCy Schubert {
143*7f2fe78bSCy Schubert struct clntraw_private *clp = clntraw_private;
144*7f2fe78bSCy Schubert XDR *xdrs = &clp->xdr_stream;
145*7f2fe78bSCy Schubert struct rpc_msg msg;
146*7f2fe78bSCy Schubert enum clnt_stat status;
147*7f2fe78bSCy Schubert struct rpc_err error;
148*7f2fe78bSCy Schubert long procl = proc;
149*7f2fe78bSCy Schubert
150*7f2fe78bSCy Schubert if (clp == 0)
151*7f2fe78bSCy Schubert return (RPC_FAILED);
152*7f2fe78bSCy Schubert call_again:
153*7f2fe78bSCy Schubert /*
154*7f2fe78bSCy Schubert * send request
155*7f2fe78bSCy Schubert */
156*7f2fe78bSCy Schubert xdrs->x_op = XDR_ENCODE;
157*7f2fe78bSCy Schubert XDR_SETPOS(xdrs, 0);
158*7f2fe78bSCy Schubert clp->u.mashl_rpcmsg.rm_xid ++ ;
159*7f2fe78bSCy Schubert if ((! XDR_PUTBYTES(xdrs, clp->u.mashl_callmsg, clp->mcnt)) ||
160*7f2fe78bSCy Schubert (! XDR_PUTLONG(xdrs, &procl)) ||
161*7f2fe78bSCy Schubert (! AUTH_MARSHALL(h->cl_auth, xdrs)) ||
162*7f2fe78bSCy Schubert (! (*xargs)(xdrs, argsp))) {
163*7f2fe78bSCy Schubert return (RPC_CANTENCODEARGS);
164*7f2fe78bSCy Schubert }
165*7f2fe78bSCy Schubert (void)XDR_GETPOS(xdrs); /* called just to cause overhead */
166*7f2fe78bSCy Schubert
167*7f2fe78bSCy Schubert /*
168*7f2fe78bSCy Schubert * We have to call server input routine here because this is
169*7f2fe78bSCy Schubert * all going on in one process. Yuk.
170*7f2fe78bSCy Schubert */
171*7f2fe78bSCy Schubert svc_getreq(1);
172*7f2fe78bSCy Schubert
173*7f2fe78bSCy Schubert /*
174*7f2fe78bSCy Schubert * get results
175*7f2fe78bSCy Schubert */
176*7f2fe78bSCy Schubert xdrs->x_op = XDR_DECODE;
177*7f2fe78bSCy Schubert XDR_SETPOS(xdrs, 0);
178*7f2fe78bSCy Schubert msg.acpted_rply.ar_verf = gssrpc__null_auth;
179*7f2fe78bSCy Schubert msg.acpted_rply.ar_results.where = resultsp;
180*7f2fe78bSCy Schubert msg.acpted_rply.ar_results.proc = xresults;
181*7f2fe78bSCy Schubert if (! xdr_replymsg(xdrs, &msg)) {
182*7f2fe78bSCy Schubert /*
183*7f2fe78bSCy Schubert * It's possible for xdr_replymsg() to fail partway
184*7f2fe78bSCy Schubert * through its attempt to decode the result from the
185*7f2fe78bSCy Schubert * server. If this happens, it will leave the reply
186*7f2fe78bSCy Schubert * structure partially populated with dynamically
187*7f2fe78bSCy Schubert * allocated memory. (This can happen if someone uses
188*7f2fe78bSCy Schubert * clntudp_bufcreate() to create a CLIENT handle and
189*7f2fe78bSCy Schubert * specifies a receive buffer size that is too small.)
190*7f2fe78bSCy Schubert * This memory must be free()ed to avoid a leak.
191*7f2fe78bSCy Schubert */
192*7f2fe78bSCy Schubert enum xdr_op op = xdrs->x_op;
193*7f2fe78bSCy Schubert xdrs->x_op = XDR_FREE;
194*7f2fe78bSCy Schubert xdr_replymsg(xdrs, &msg);
195*7f2fe78bSCy Schubert xdrs->x_op = op;
196*7f2fe78bSCy Schubert return (RPC_CANTDECODERES);
197*7f2fe78bSCy Schubert }
198*7f2fe78bSCy Schubert gssrpc__seterr_reply(&msg, &error);
199*7f2fe78bSCy Schubert status = error.re_status;
200*7f2fe78bSCy Schubert
201*7f2fe78bSCy Schubert if (status == RPC_SUCCESS) {
202*7f2fe78bSCy Schubert if (! AUTH_VALIDATE(h->cl_auth, &msg.acpted_rply.ar_verf)) {
203*7f2fe78bSCy Schubert status = RPC_AUTHERROR;
204*7f2fe78bSCy Schubert }
205*7f2fe78bSCy Schubert } /* end successful completion */
206*7f2fe78bSCy Schubert else {
207*7f2fe78bSCy Schubert if (AUTH_REFRESH(h->cl_auth, &msg))
208*7f2fe78bSCy Schubert goto call_again;
209*7f2fe78bSCy Schubert } /* end of unsuccessful completion */
210*7f2fe78bSCy Schubert
211*7f2fe78bSCy Schubert if (status == RPC_SUCCESS) {
212*7f2fe78bSCy Schubert if (! AUTH_VALIDATE(h->cl_auth, &msg.acpted_rply.ar_verf)) {
213*7f2fe78bSCy Schubert status = RPC_AUTHERROR;
214*7f2fe78bSCy Schubert }
215*7f2fe78bSCy Schubert if (msg.acpted_rply.ar_verf.oa_base != NULL) {
216*7f2fe78bSCy Schubert xdrs->x_op = XDR_FREE;
217*7f2fe78bSCy Schubert (void)xdr_opaque_auth(xdrs, &(msg.acpted_rply.ar_verf));
218*7f2fe78bSCy Schubert }
219*7f2fe78bSCy Schubert }
220*7f2fe78bSCy Schubert
221*7f2fe78bSCy Schubert return (status);
222*7f2fe78bSCy Schubert }
223*7f2fe78bSCy Schubert
224*7f2fe78bSCy Schubert /*ARGSUSED*/
225*7f2fe78bSCy Schubert static void
clntraw_geterr(CLIENT * cl,struct rpc_err * err)226*7f2fe78bSCy Schubert clntraw_geterr(
227*7f2fe78bSCy Schubert CLIENT *cl,
228*7f2fe78bSCy Schubert struct rpc_err *err)
229*7f2fe78bSCy Schubert {
230*7f2fe78bSCy Schubert }
231*7f2fe78bSCy Schubert
232*7f2fe78bSCy Schubert
233*7f2fe78bSCy Schubert static bool_t
clntraw_freeres(CLIENT * cl,xdrproc_t xdr_res,void * res_ptr)234*7f2fe78bSCy Schubert clntraw_freeres(
235*7f2fe78bSCy Schubert CLIENT *cl,
236*7f2fe78bSCy Schubert xdrproc_t xdr_res,
237*7f2fe78bSCy Schubert void *res_ptr)
238*7f2fe78bSCy Schubert {
239*7f2fe78bSCy Schubert struct clntraw_private *clp = clntraw_private;
240*7f2fe78bSCy Schubert XDR *xdrs = &clp->xdr_stream;
241*7f2fe78bSCy Schubert bool_t rval;
242*7f2fe78bSCy Schubert
243*7f2fe78bSCy Schubert if (clp == 0)
244*7f2fe78bSCy Schubert {
245*7f2fe78bSCy Schubert rval = (bool_t) RPC_FAILED;
246*7f2fe78bSCy Schubert return (rval);
247*7f2fe78bSCy Schubert }
248*7f2fe78bSCy Schubert xdrs->x_op = XDR_FREE;
249*7f2fe78bSCy Schubert return ((*xdr_res)(xdrs, res_ptr));
250*7f2fe78bSCy Schubert }
251*7f2fe78bSCy Schubert
252*7f2fe78bSCy Schubert /*ARGSUSED*/
253*7f2fe78bSCy Schubert static void
clntraw_abort(CLIENT * cl)254*7f2fe78bSCy Schubert clntraw_abort(CLIENT *cl)
255*7f2fe78bSCy Schubert {
256*7f2fe78bSCy Schubert }
257*7f2fe78bSCy Schubert
258*7f2fe78bSCy Schubert /*ARGSUSED*/
259*7f2fe78bSCy Schubert static bool_t
clntraw_control(CLIENT * cl,int request,void * info)260*7f2fe78bSCy Schubert clntraw_control(
261*7f2fe78bSCy Schubert CLIENT *cl,
262*7f2fe78bSCy Schubert int request,
263*7f2fe78bSCy Schubert void *info)
264*7f2fe78bSCy Schubert {
265*7f2fe78bSCy Schubert return (FALSE);
266*7f2fe78bSCy Schubert }
267*7f2fe78bSCy Schubert
268*7f2fe78bSCy Schubert /*ARGSUSED*/
269*7f2fe78bSCy Schubert static void
clntraw_destroy(CLIENT * cl)270*7f2fe78bSCy Schubert clntraw_destroy(CLIENT *cl)
271*7f2fe78bSCy Schubert {
272*7f2fe78bSCy Schubert }
273