svc_raw.c revision 261046
1/*	$NetBSD: svc_raw.c,v 1.14 2000/07/06 03:10:35 christos Exp $	*/
2
3/*-
4 * Copyright (c) 2009, Sun Microsystems, Inc.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions are met:
9 * - Redistributions of source code must retain the above copyright notice,
10 *   this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright notice,
12 *   this list of conditions and the following disclaimer in the documentation
13 *   and/or other materials provided with the distribution.
14 * - Neither the name of Sun Microsystems, Inc. nor the names of its
15 *   contributors may be used to endorse or promote products derived
16 *   from this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
22 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28 * POSSIBILITY OF SUCH DAMAGE.
29 */
30/*
31 * Copyright (c) 1986-1991 by Sun Microsystems Inc.
32 */
33
34/* #ident	"@(#)svc_raw.c	1.16	94/04/24 SMI" */
35
36#if defined(LIBC_SCCS) && !defined(lint)
37static char sccsid[] = "@(#)svc_raw.c 1.25 89/01/31 Copyr 1984 Sun Micro";
38#endif
39#include <sys/cdefs.h>
40__FBSDID("$FreeBSD: stable/10/lib/libc/rpc/svc_raw.c 261046 2014-01-22 23:45:27Z mav $");
41
42/*
43 * svc_raw.c,   This a toy for simple testing and timing.
44 * Interface to create an rpc client and server in the same UNIX process.
45 * This lets us similate rpc and get rpc (round trip) overhead, without
46 * any interference from the kernel.
47 *
48 */
49
50#include "namespace.h"
51#include "reentrant.h"
52#include <rpc/rpc.h>
53#include <sys/types.h>
54#include <rpc/raw.h>
55#include <stdlib.h>
56#include "un-namespace.h"
57#include "mt_misc.h"
58
59#ifndef UDPMSGSIZE
60#define	UDPMSGSIZE 8800
61#endif
62
63/*
64 * This is the "network" that we will be moving data over
65 */
66static struct svc_raw_private {
67	char	*raw_buf;	/* should be shared with the cl handle */
68	SVCXPRT	*server;
69	XDR	xdr_stream;
70	char	verf_body[MAX_AUTH_BYTES];
71} *svc_raw_private;
72
73static enum xprt_stat svc_raw_stat(SVCXPRT *);
74static bool_t svc_raw_recv(SVCXPRT *, struct rpc_msg *);
75static bool_t svc_raw_reply(SVCXPRT *, struct rpc_msg *);
76static bool_t svc_raw_getargs(SVCXPRT *, xdrproc_t, void *);
77static bool_t svc_raw_freeargs(SVCXPRT *, xdrproc_t, void *);
78static void svc_raw_destroy(SVCXPRT *);
79static void svc_raw_ops(SVCXPRT *);
80static bool_t svc_raw_control(SVCXPRT *, const u_int, void *);
81
82char *__rpc_rawcombuf = NULL;
83
84SVCXPRT *
85svc_raw_create()
86{
87	struct svc_raw_private *srp;
88/* VARIABLES PROTECTED BY svcraw_lock: svc_raw_private, srp */
89
90	mutex_lock(&svcraw_lock);
91	srp = svc_raw_private;
92	if (srp == NULL) {
93		srp = (struct svc_raw_private *)calloc(1, sizeof (*srp));
94		if (srp == NULL) {
95			mutex_unlock(&svcraw_lock);
96			return (NULL);
97		}
98		if (__rpc_rawcombuf == NULL) {
99			__rpc_rawcombuf = calloc(UDPMSGSIZE, sizeof (char));
100			if (__rpc_rawcombuf == NULL) {
101				free(srp);
102				mutex_unlock(&svcraw_lock);
103				return (NULL);
104			}
105		}
106		srp->raw_buf = __rpc_rawcombuf; /* Share it with the client */
107		srp->server = svc_xprt_alloc();
108		if (srp->server == NULL) {
109			free(__rpc_rawcombuf);
110			free(srp);
111			mutex_unlock(&svcraw_lock);
112			return (NULL);
113		}
114		svc_raw_private = srp;
115	}
116	srp->server->xp_fd = FD_SETSIZE;
117	srp->server->xp_port = 0;
118	svc_raw_ops(srp->server);
119	srp->server->xp_verf.oa_base = srp->verf_body;
120	xdrmem_create(&srp->xdr_stream, srp->raw_buf, UDPMSGSIZE, XDR_DECODE);
121	xprt_register(srp->server);
122	mutex_unlock(&svcraw_lock);
123	return (srp->server);
124}
125
126/*ARGSUSED*/
127static enum xprt_stat
128svc_raw_stat(xprt)
129SVCXPRT *xprt; /* args needed to satisfy ANSI-C typechecking */
130{
131	return (XPRT_IDLE);
132}
133
134/*ARGSUSED*/
135static bool_t
136svc_raw_recv(xprt, msg)
137	SVCXPRT *xprt;
138	struct rpc_msg *msg;
139{
140	struct svc_raw_private *srp;
141	XDR *xdrs;
142
143	mutex_lock(&svcraw_lock);
144	srp = svc_raw_private;
145	if (srp == NULL) {
146		mutex_unlock(&svcraw_lock);
147		return (FALSE);
148	}
149	mutex_unlock(&svcraw_lock);
150
151	xdrs = &srp->xdr_stream;
152	xdrs->x_op = XDR_DECODE;
153	(void) XDR_SETPOS(xdrs, 0);
154	if (! xdr_callmsg(xdrs, msg)) {
155		return (FALSE);
156	}
157	return (TRUE);
158}
159
160/*ARGSUSED*/
161static bool_t
162svc_raw_reply(xprt, msg)
163	SVCXPRT *xprt;
164	struct rpc_msg *msg;
165{
166	struct svc_raw_private *srp;
167	XDR *xdrs;
168	bool_t stat;
169	xdrproc_t xdr_proc;
170	caddr_t xdr_where;
171
172	mutex_lock(&svcraw_lock);
173	srp = svc_raw_private;
174	if (srp == NULL) {
175		mutex_unlock(&svcraw_lock);
176		return (FALSE);
177	}
178	mutex_unlock(&svcraw_lock);
179
180	xdrs = &srp->xdr_stream;
181	xdrs->x_op = XDR_ENCODE;
182	(void) XDR_SETPOS(xdrs, 0);
183	if (msg->rm_reply.rp_stat == MSG_ACCEPTED &&
184	    msg->rm_reply.rp_acpt.ar_stat == SUCCESS) {
185		xdr_proc = msg->acpted_rply.ar_results.proc;
186		xdr_where = msg->acpted_rply.ar_results.where;
187		msg->acpted_rply.ar_results.proc = (xdrproc_t) xdr_void;
188		msg->acpted_rply.ar_results.where = NULL;
189
190		stat = xdr_replymsg(xdrs, msg) &&
191		    SVCAUTH_WRAP(&SVC_AUTH(xprt), xdrs, xdr_proc, xdr_where);
192	} else {
193		stat = xdr_replymsg(xdrs, msg);
194	}
195	if (!stat) {
196		return (FALSE);
197	}
198	(void) XDR_GETPOS(xdrs);  /* called just for overhead */
199	return (TRUE);
200}
201
202/*ARGSUSED*/
203static bool_t
204svc_raw_getargs(xprt, xdr_args, args_ptr)
205	SVCXPRT *xprt;
206	xdrproc_t xdr_args;
207	void *args_ptr;
208{
209	struct svc_raw_private *srp;
210
211	mutex_lock(&svcraw_lock);
212	srp = svc_raw_private;
213	if (srp == NULL) {
214		mutex_unlock(&svcraw_lock);
215		return (FALSE);
216	}
217	mutex_unlock(&svcraw_lock);
218
219	return (SVCAUTH_UNWRAP(&SVC_AUTH(xprt), &srp->xdr_stream,
220		xdr_args, args_ptr));
221}
222
223/*ARGSUSED*/
224static bool_t
225svc_raw_freeargs(xprt, xdr_args, args_ptr)
226	SVCXPRT *xprt;
227	xdrproc_t xdr_args;
228	void *args_ptr;
229{
230	struct svc_raw_private *srp;
231	XDR *xdrs;
232
233	mutex_lock(&svcraw_lock);
234	srp = svc_raw_private;
235	if (srp == NULL) {
236		mutex_unlock(&svcraw_lock);
237		return (FALSE);
238	}
239	mutex_unlock(&svcraw_lock);
240
241	xdrs = &srp->xdr_stream;
242	xdrs->x_op = XDR_FREE;
243	return (*xdr_args)(xdrs, args_ptr);
244}
245
246/*ARGSUSED*/
247static void
248svc_raw_destroy(xprt)
249SVCXPRT *xprt;
250{
251}
252
253/*ARGSUSED*/
254static bool_t
255svc_raw_control(xprt, rq, in)
256	SVCXPRT *xprt;
257	const u_int	rq;
258	void		*in;
259{
260	return (FALSE);
261}
262
263static void
264svc_raw_ops(xprt)
265	SVCXPRT *xprt;
266{
267	static struct xp_ops ops;
268	static struct xp_ops2 ops2;
269
270/* VARIABLES PROTECTED BY ops_lock: ops */
271
272	mutex_lock(&ops_lock);
273	if (ops.xp_recv == NULL) {
274		ops.xp_recv = svc_raw_recv;
275		ops.xp_stat = svc_raw_stat;
276		ops.xp_getargs = svc_raw_getargs;
277		ops.xp_reply = svc_raw_reply;
278		ops.xp_freeargs = svc_raw_freeargs;
279		ops.xp_destroy = svc_raw_destroy;
280		ops2.xp_control = svc_raw_control;
281	}
282	xprt->xp_ops = &ops;
283	xprt->xp_ops2 = &ops2;
284	mutex_unlock(&ops_lock);
285}
286