1 /* $NetBSD: clnt_raw.c,v 1.29 2008/04/25 17:44:44 christos Exp $ */
4 * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
5 * unrestricted use provided that this legend is included on all tape
6 * media and as a part of the software program in whole or part. Users
7 * may copy or modify Sun RPC without charge, but are not authorized
8 * to license or distribute it to anyone else except as part of a product or
9 * program developed by the user.
11 * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
12 * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
13 * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
15 * Sun RPC is provided with no support and without any obligation on the
16 * part of Sun Microsystems, Inc. to assist in its use, correction,
17 * modification or enhancement.
19 * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
20 * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
21 * OR ANY PART THEREOF.
23 * In no event will Sun Microsystems, Inc. be liable for any lost revenue
24 * or profits or other special, indirect and consequential damages, even if
25 * Sun has been advised of the possibility of such damages.
27 * Sun Microsystems, Inc.
29 * Mountain View, California 94043
32 #include <sys/cdefs.h>
33 #if defined(LIBC_SCCS) && !defined(lint)
35 static char *sccsid
= "@(#)clnt_raw.c 1.22 87/08/11 Copyr 1984 Sun Micro";
36 static char *sccsid
= "@(#)clnt_raw.c 2.2 88/08/01 4.0 RPCSRC";
38 __RCSID("$NetBSD: clnt_raw.c,v 1.29 2008/04/25 17:44:44 christos Exp $");
45 * Copyright (C) 1984, Sun Microsystems, Inc.
47 * Memory based rpc for simple testing and timing.
48 * Interface to create an rpc client and server in the same process.
49 * This lets us similate rpc and get round trip overhead, without
50 * any interference from the kernel.
53 #include "namespace.h"
54 #include "reentrant.h"
64 __weak_alias(clntraw_create
,_clntraw_create
)
65 __weak_alias(clnt_raw_create
,_clnt_raw_create
)
69 extern mutex_t clntraw_lock
;
72 #define MCALL_MSG_SIZE 24
75 * This is the "network" we will be moving stuff over.
77 static struct clntraw_private
{
82 struct rpc_msg mashl_rpcmsg
;
83 char mashl_callmsg
[MCALL_MSG_SIZE
];
88 static enum clnt_stat clnt_raw_call
__P((CLIENT
*, rpcproc_t
, xdrproc_t
,
89 const char *, xdrproc_t
, caddr_t
, struct timeval
));
90 static void clnt_raw_geterr
__P((CLIENT
*, struct rpc_err
*));
91 static bool_t clnt_raw_freeres
__P((CLIENT
*, xdrproc_t
, caddr_t
));
92 static void clnt_raw_abort
__P((CLIENT
*));
93 static bool_t clnt_raw_control
__P((CLIENT
*, u_int
, char *));
94 static void clnt_raw_destroy
__P((CLIENT
*));
95 static struct clnt_ops
*clnt_raw_ops
__P((void));
98 * Create a client handle for memory based rpc.
101 clnt_raw_create(prog
, vers
)
105 struct clntraw_private
*clp
= clntraw_private
;
106 struct rpc_msg call_msg
;
107 XDR
*xdrs
= &clp
->xdr_stream
;
108 CLIENT
*client
= &clp
->client_object
;
110 mutex_lock(&clntraw_lock
);
112 clp
= calloc((size_t)1, sizeof (*clp
));
115 if (__rpc_rawcombuf
== NULL
)
118 if (__rpc_rawcombuf
== NULL
)
120 clp
->_raw_buf
= __rpc_rawcombuf
;
121 clntraw_private
= clp
;
124 * pre-serialize the static part of the call msg and stash it away
126 call_msg
.rm_direction
= CALL
;
127 call_msg
.rm_call
.cb_rpcvers
= RPC_MSG_VERSION
;
128 /* XXX: prog and vers have been long historically :-( */
129 call_msg
.rm_call
.cb_prog
= (u_int32_t
)prog
;
130 call_msg
.rm_call
.cb_vers
= (u_int32_t
)vers
;
131 xdrmem_create(xdrs
, clp
->u
.mashl_callmsg
, MCALL_MSG_SIZE
, XDR_ENCODE
);
132 if (! xdr_callhdr(xdrs
, &call_msg
))
133 warnx("clntraw_create - Fatal header serialization error.");
134 clp
->mcnt
= XDR_GETPOS(xdrs
);
138 * Set xdrmem for client/server shared buffer
140 xdrmem_create(xdrs
, clp
->_raw_buf
, UDPMSGSIZE
, XDR_FREE
);
143 * create client handle
145 client
->cl_ops
= clnt_raw_ops();
146 client
->cl_auth
= authnone_create();
147 mutex_unlock(&clntraw_lock
);
152 mutex_unlock(&clntraw_lock
);
158 static enum clnt_stat
159 clnt_raw_call(h
, proc
, xargs
, argsp
, xresults
, resultsp
, timeout
)
166 struct timeval timeout
;
168 struct clntraw_private
*clp
= clntraw_private
;
169 XDR
*xdrs
= &clp
->xdr_stream
;
171 enum clnt_stat status
;
172 struct rpc_err error
;
174 _DIAGASSERT(h
!= NULL
);
176 mutex_lock(&clntraw_lock
);
178 mutex_unlock(&clntraw_lock
);
181 mutex_unlock(&clntraw_lock
);
187 xdrs
->x_op
= XDR_ENCODE
;
189 clp
->u
.mashl_rpcmsg
.rm_xid
++ ;
190 if ((! XDR_PUTBYTES(xdrs
, clp
->u
.mashl_callmsg
, clp
->mcnt
)) ||
191 (! XDR_PUTINT32(xdrs
, (int32_t *)&proc
)) ||
192 (! AUTH_MARSHALL(h
->cl_auth
, xdrs
)) ||
193 (! (*xargs
)(xdrs
, __UNCONST(argsp
)))) {
194 return (RPC_CANTENCODEARGS
);
196 (void)XDR_GETPOS(xdrs
); /* called just to cause overhead */
199 * We have to call server input routine here because this is
200 * all going on in one process. Yuk.
202 svc_getreq_common(FD_SETSIZE
);
207 xdrs
->x_op
= XDR_DECODE
;
209 msg
.acpted_rply
.ar_verf
= _null_auth
;
210 msg
.acpted_rply
.ar_results
.where
= resultsp
;
211 msg
.acpted_rply
.ar_results
.proc
= xresults
;
212 if (! xdr_replymsg(xdrs
, &msg
)) {
214 * It's possible for xdr_replymsg() to fail partway
215 * through its attempt to decode the result from the
216 * server. If this happens, it will leave the reply
217 * structure partially populated with dynamically
218 * allocated memory. (This can happen if someone uses
219 * clntudp_bufcreate() to create a CLIENT handle and
220 * specifies a receive buffer size that is too small.)
221 * This memory must be free()ed to avoid a leak.
224 xdrs
->x_op
= XDR_FREE
;
225 xdr_replymsg(xdrs
, &msg
);
227 return (RPC_CANTDECODERES
);
229 _seterr_reply(&msg
, &error
);
230 status
= error
.re_status
;
232 if (status
== RPC_SUCCESS
) {
233 if (! AUTH_VALIDATE(h
->cl_auth
, &msg
.acpted_rply
.ar_verf
)) {
234 status
= RPC_AUTHERROR
;
236 } /* end successful completion */
238 if (AUTH_REFRESH(h
->cl_auth
))
240 } /* end of unsuccessful completion */
242 if (status
== RPC_SUCCESS
) {
243 if (! AUTH_VALIDATE(h
->cl_auth
, &msg
.acpted_rply
.ar_verf
)) {
244 status
= RPC_AUTHERROR
;
246 if (msg
.acpted_rply
.ar_verf
.oa_base
!= NULL
) {
247 xdrs
->x_op
= XDR_FREE
;
248 (void)xdr_opaque_auth(xdrs
, &(msg
.acpted_rply
.ar_verf
));
257 clnt_raw_geterr(cl
, error
)
259 struct rpc_err
*error
;
266 clnt_raw_freeres(cl
, xdr_res
, res_ptr
)
271 struct clntraw_private
*clp
= clntraw_private
;
272 XDR
*xdrs
= &clp
->xdr_stream
;
275 mutex_lock(&clntraw_lock
);
277 rval
= (bool_t
) RPC_FAILED
;
278 mutex_unlock(&clntraw_lock
);
281 mutex_unlock(&clntraw_lock
);
282 xdrs
->x_op
= XDR_FREE
;
283 return ((*xdr_res
)(xdrs
, res_ptr
));
295 clnt_raw_control(cl
, ui
, str
)
310 static struct clnt_ops
*
313 static struct clnt_ops ops
;
315 extern mutex_t ops_lock
;
318 /* VARIABLES PROTECTED BY ops_lock: ops */
320 mutex_lock(&ops_lock
);
321 if (ops
.cl_call
== NULL
) {
322 ops
.cl_call
= clnt_raw_call
;
323 ops
.cl_abort
= clnt_raw_abort
;
324 ops
.cl_geterr
= clnt_raw_geterr
;
325 ops
.cl_freeres
= clnt_raw_freeres
;
326 ops
.cl_destroy
= clnt_raw_destroy
;
327 ops
.cl_control
= clnt_raw_control
;
329 mutex_unlock(&ops_lock
);