1/*	$NetBSD: svc_raw.c,v 1.14 2000/07/06 03:10:35 christos Exp $	*/
2
3/*-
4 * SPDX-License-Identifier: BSD-3-Clause
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 * Copyright (c) 1986-1991 by Sun Microsystems Inc.
34 */
35
36/* #ident	"@(#)svc_raw.c	1.16	94/04/24 SMI" */
37
38#if defined(LIBC_SCCS) && !defined(lint)
39static char sccsid[] = "@(#)svc_raw.c 1.25 89/01/31 Copyr 1984 Sun Micro";
40#endif
41#include <sys/cdefs.h>
42__FBSDID("$FreeBSD$");
43
44/*
45 * svc_raw.c,   This a toy for simple testing and timing.
46 * Interface to create an rpc client and server in the same UNIX process.
47 * This lets us similate rpc and get rpc (round trip) overhead, without
48 * any interference from the kernel.
49 *
50 */
51
52#include "namespace.h"
53#include "reentrant.h"
54#include <rpc/rpc.h>
55#include <sys/types.h>
56#include <rpc/raw.h>
57#include <stdlib.h>
58#include "un-namespace.h"
59#include "mt_misc.h"
60
61#ifndef UDPMSGSIZE
62#define	UDPMSGSIZE 8800
63#endif
64
65/*
66 * This is the "network" that we will be moving data over
67 */
68static struct svc_raw_private {
69	char	*raw_buf;	/* should be shared with the cl handle */
70	SVCXPRT	*server;
71	XDR	xdr_stream;
72	char	verf_body[MAX_AUTH_BYTES];
73} *svc_raw_private;
74
75static enum xprt_stat svc_raw_stat(SVCXPRT *);
76static bool_t svc_raw_recv(SVCXPRT *, struct rpc_msg *);
77static bool_t svc_raw_reply(SVCXPRT *, struct rpc_msg *);
78static bool_t svc_raw_getargs(SVCXPRT *, xdrproc_t, void *);
79static bool_t svc_raw_freeargs(SVCXPRT *, xdrproc_t, void *);
80static void svc_raw_destroy(SVCXPRT *);
81static void svc_raw_ops(SVCXPRT *);
82static bool_t svc_raw_control(SVCXPRT *, const u_int, void *);
83
84char *__rpc_rawcombuf = NULL;
85
86SVCXPRT *
87svc_raw_create(void)
88{
89	struct svc_raw_private *srp;
90/* VARIABLES PROTECTED BY svcraw_lock: svc_raw_private, srp */
91
92	mutex_lock(&svcraw_lock);
93	srp = svc_raw_private;
94	if (srp == NULL) {
95		srp = (struct svc_raw_private *)calloc(1, sizeof (*srp));
96		if (srp == NULL) {
97			mutex_unlock(&svcraw_lock);
98			return (NULL);
99		}
100		if (__rpc_rawcombuf == NULL) {
101			__rpc_rawcombuf = calloc(UDPMSGSIZE, sizeof (char));
102			if (__rpc_rawcombuf == NULL) {
103				free(srp);
104				mutex_unlock(&svcraw_lock);
105				return (NULL);
106			}
107		}
108		srp->raw_buf = __rpc_rawcombuf; /* Share it with the client */
109		srp->server = svc_xprt_alloc();
110		if (srp->server == NULL) {
111			free(__rpc_rawcombuf);
112			free(srp);
113			mutex_unlock(&svcraw_lock);
114			return (NULL);
115		}
116		svc_raw_private = srp;
117	}
118	srp->server->xp_fd = FD_SETSIZE;
119	srp->server->xp_port = 0;
120	svc_raw_ops(srp->server);
121	srp->server->xp_verf.oa_base = srp->verf_body;
122	xdrmem_create(&srp->xdr_stream, srp->raw_buf, UDPMSGSIZE, XDR_DECODE);
123	xprt_register(srp->server);
124	mutex_unlock(&svcraw_lock);
125	return (srp->server);
126}
127
128/*ARGSUSED*/
129static enum xprt_stat
130svc_raw_stat(SVCXPRT *xprt)
131{
132	return (XPRT_IDLE);
133}
134
135/*ARGSUSED*/
136static bool_t
137svc_raw_recv(SVCXPRT *xprt, struct rpc_msg *msg)
138{
139	struct svc_raw_private *srp;
140	XDR *xdrs;
141
142	mutex_lock(&svcraw_lock);
143	srp = svc_raw_private;
144	if (srp == NULL) {
145		mutex_unlock(&svcraw_lock);
146		return (FALSE);
147	}
148	mutex_unlock(&svcraw_lock);
149
150	xdrs = &srp->xdr_stream;
151	xdrs->x_op = XDR_DECODE;
152	(void) XDR_SETPOS(xdrs, 0);
153	if (! xdr_callmsg(xdrs, msg)) {
154		return (FALSE);
155	}
156	return (TRUE);
157}
158
159/*ARGSUSED*/
160static bool_t
161svc_raw_reply(SVCXPRT *xprt, struct rpc_msg *msg)
162{
163	struct svc_raw_private *srp;
164	XDR *xdrs;
165	bool_t stat;
166	xdrproc_t xdr_proc;
167	caddr_t xdr_where;
168
169	mutex_lock(&svcraw_lock);
170	srp = svc_raw_private;
171	if (srp == NULL) {
172		mutex_unlock(&svcraw_lock);
173		return (FALSE);
174	}
175	mutex_unlock(&svcraw_lock);
176
177	xdrs = &srp->xdr_stream;
178	xdrs->x_op = XDR_ENCODE;
179	(void) XDR_SETPOS(xdrs, 0);
180	if (msg->rm_reply.rp_stat == MSG_ACCEPTED &&
181	    msg->rm_reply.rp_acpt.ar_stat == SUCCESS) {
182		xdr_proc = msg->acpted_rply.ar_results.proc;
183		xdr_where = msg->acpted_rply.ar_results.where;
184		msg->acpted_rply.ar_results.proc = (xdrproc_t) xdr_void;
185		msg->acpted_rply.ar_results.where = NULL;
186
187		stat = xdr_replymsg(xdrs, msg) &&
188		    SVCAUTH_WRAP(&SVC_AUTH(xprt), xdrs, xdr_proc, xdr_where);
189	} else {
190		stat = xdr_replymsg(xdrs, msg);
191	}
192	if (!stat) {
193		return (FALSE);
194	}
195	(void) XDR_GETPOS(xdrs);  /* called just for overhead */
196	return (TRUE);
197}
198
199/*ARGSUSED*/
200static bool_t
201svc_raw_getargs(SVCXPRT *xprt, xdrproc_t xdr_args, void *args_ptr)
202{
203	struct svc_raw_private *srp;
204
205	mutex_lock(&svcraw_lock);
206	srp = svc_raw_private;
207	if (srp == NULL) {
208		mutex_unlock(&svcraw_lock);
209		return (FALSE);
210	}
211	mutex_unlock(&svcraw_lock);
212
213	return (SVCAUTH_UNWRAP(&SVC_AUTH(xprt), &srp->xdr_stream,
214		xdr_args, args_ptr));
215}
216
217/*ARGSUSED*/
218static bool_t
219svc_raw_freeargs(SVCXPRT *xprt, xdrproc_t xdr_args, void *args_ptr)
220{
221	struct svc_raw_private *srp;
222	XDR *xdrs;
223
224	mutex_lock(&svcraw_lock);
225	srp = svc_raw_private;
226	if (srp == NULL) {
227		mutex_unlock(&svcraw_lock);
228		return (FALSE);
229	}
230	mutex_unlock(&svcraw_lock);
231
232	xdrs = &srp->xdr_stream;
233	xdrs->x_op = XDR_FREE;
234	return (*xdr_args)(xdrs, args_ptr);
235}
236
237/*ARGSUSED*/
238static void
239svc_raw_destroy(SVCXPRT *xprt)
240{
241}
242
243/*ARGSUSED*/
244static bool_t
245svc_raw_control(SVCXPRT *xprt, const u_int rq, void *in)
246{
247	return (FALSE);
248}
249
250static void
251svc_raw_ops(SVCXPRT *xprt)
252{
253	static struct xp_ops ops;
254	static struct xp_ops2 ops2;
255
256/* VARIABLES PROTECTED BY ops_lock: ops */
257
258	mutex_lock(&ops_lock);
259	if (ops.xp_recv == NULL) {
260		ops.xp_recv = svc_raw_recv;
261		ops.xp_stat = svc_raw_stat;
262		ops.xp_getargs = svc_raw_getargs;
263		ops.xp_reply = svc_raw_reply;
264		ops.xp_freeargs = svc_raw_freeargs;
265		ops.xp_destroy = svc_raw_destroy;
266		ops2.xp_control = svc_raw_control;
267	}
268	xprt->xp_ops = &ops;
269	xprt->xp_ops2 = &ops2;
270	mutex_unlock(&ops_lock);
271}
272