1 /* @(#)clnt_raw.c 2.2 88/08/01 4.0 RPCSRC */
3 * Copyright (c) 2010, Oracle America, Inc.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions are met:
10 * * Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
13 * * Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in
15 * the documentation and/or other materials provided with the
18 * * Neither the name of the "Oracle America, Inc." nor the names of
19 * its contributors may be used to endorse or promote products
20 * derived from this software without specific prior written permission.
22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
23 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
24 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
25 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
26 * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
27 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
28 * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
29 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
30 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
31 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
32 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 #if !defined(lint) && defined(SCCSIDS)
35 static char sccsid[] = "@(#)clnt_raw.c 1.22 87/08/11 Copyr 1984 Sun Micro";
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.
47 #include <gssrpc/rpc.h>
49 #define MCALL_MSG_SIZE 24
52 * This is the "network" we will be moving stuff over.
54 static struct clntraw_private {
57 char _raw_buf[UDPMSGSIZE];
59 struct rpc_msg mashl_rpcmsg;
60 char mashl_callmsg[MCALL_MSG_SIZE];
65 static enum clnt_stat clntraw_call(CLIENT *, rpcproc_t, xdrproc_t,
66 void *, xdrproc_t, void *,
68 static void clntraw_abort(CLIENT *);
69 static void clntraw_geterr(CLIENT *, struct rpc_err *);
70 static bool_t clntraw_freeres(CLIENT *, xdrproc_t, void *);
71 static bool_t clntraw_control(CLIENT *, int, void *);
72 static void clntraw_destroy(CLIENT *);
74 static struct clnt_ops client_ops = {
86 * Create a client handle for memory based rpc.
93 struct clntraw_private *clp;
94 struct rpc_msg call_msg;
98 if (clntraw_private == NULL) {
99 clntraw_private = calloc(1, sizeof(*clp));
100 if (clntraw_private == NULL)
103 clp = clntraw_private;
104 xdrs = &clp->xdr_stream;
105 client = &clp->client_object;
107 * pre-serialize the staic part of the call msg and stash it away
109 call_msg.rm_direction = CALL;
110 call_msg.rm_call.cb_rpcvers = RPC_MSG_VERSION;
111 call_msg.rm_call.cb_prog = prog;
112 call_msg.rm_call.cb_vers = vers;
113 xdrmem_create(xdrs, clp->u.mashl_callmsg, MCALL_MSG_SIZE, XDR_ENCODE);
114 if (! xdr_callhdr(xdrs, &call_msg)) {
115 perror("clnt_raw.c - Fatal header serialization error.");
117 clp->mcnt = XDR_GETPOS(xdrs);
121 * Set xdrmem for client/server shared buffer
123 xdrmem_create(xdrs, clp->_raw_buf, UDPMSGSIZE, XDR_FREE);
126 * create client handle
128 client->cl_ops = &client_ops;
129 client->cl_auth = authnone_create();
133 static enum clnt_stat
141 struct timeval timeout)
143 register struct clntraw_private *clp = clntraw_private;
144 register XDR *xdrs = &clp->xdr_stream;
146 enum clnt_stat status;
147 struct rpc_err error;
156 xdrs->x_op = XDR_ENCODE;
158 clp->u.mashl_rpcmsg.rm_xid ++ ;
159 if ((! XDR_PUTBYTES(xdrs, clp->u.mashl_callmsg, clp->mcnt)) ||
160 (! XDR_PUTLONG(xdrs, &procl)) ||
161 (! AUTH_MARSHALL(h->cl_auth, xdrs)) ||
162 (! (*xargs)(xdrs, argsp))) {
163 return (RPC_CANTENCODEARGS);
165 (void)XDR_GETPOS(xdrs); /* called just to cause overhead */
168 * We have to call server input routine here because this is
169 * all going on in one process. Yuk.
176 xdrs->x_op = XDR_DECODE;
178 msg.acpted_rply.ar_verf = gssrpc__null_auth;
179 msg.acpted_rply.ar_results.where = resultsp;
180 msg.acpted_rply.ar_results.proc = xresults;
181 if (! xdr_replymsg(xdrs, &msg)) {
183 * It's possible for xdr_replymsg() to fail partway
184 * through its attempt to decode the result from the
185 * server. If this happens, it will leave the reply
186 * structure partially populated with dynamically
187 * allocated memory. (This can happen if someone uses
188 * clntudp_bufcreate() to create a CLIENT handle and
189 * specifies a receive buffer size that is too small.)
190 * This memory must be free()ed to avoid a leak.
192 enum xdr_op op = xdrs->x_op;
193 xdrs->x_op = XDR_FREE;
194 xdr_replymsg(xdrs, &msg);
196 return (RPC_CANTDECODERES);
198 gssrpc__seterr_reply(&msg, &error);
199 status = error.re_status;
201 if (status == RPC_SUCCESS) {
202 if (! AUTH_VALIDATE(h->cl_auth, &msg.acpted_rply.ar_verf)) {
203 status = RPC_AUTHERROR;
205 } /* end successful completion */
207 if (AUTH_REFRESH(h->cl_auth, &msg))
209 } /* end of unsuccessful completion */
211 if (status == RPC_SUCCESS) {
212 if (! AUTH_VALIDATE(h->cl_auth, &msg.acpted_rply.ar_verf)) {
213 status = RPC_AUTHERROR;
215 if (msg.acpted_rply.ar_verf.oa_base != NULL) {
216 xdrs->x_op = XDR_FREE;
217 (void)xdr_opaque_auth(xdrs, &(msg.acpted_rply.ar_verf));
239 register struct clntraw_private *clp = clntraw_private;
240 register XDR *xdrs = &clp->xdr_stream;
245 rval = (bool_t) RPC_FAILED;
248 xdrs->x_op = XDR_FREE;
249 return ((*xdr_res)(xdrs, res_ptr));
254 clntraw_abort(CLIENT *cl)
270 clntraw_destroy(CLIENT *cl)