source: rtems-libbsd/freebsd/lib/libc/rpc/clnt_raw.c @ 60b1d40

55-freebsd-126-freebsd-12freebsd-9.3
Last change on this file since 60b1d40 was 60b1d40, checked in by Sebastian Huber <sebastian.huber@…>, on 06/09/16 at 08:23:57

RPC(3): Import from FreeBSD

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