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