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 309487 2016-12-03 17:27:28Z ngie $");
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(void)
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(SVCXPRT *xprt)
129{
130	return (XPRT_IDLE);
131}
132
133/*ARGSUSED*/
134static bool_t
135svc_raw_recv(SVCXPRT *xprt, struct rpc_msg *msg)
136{
137	struct svc_raw_private *srp;
138	XDR *xdrs;
139
140	mutex_lock(&svcraw_lock);
141	srp = svc_raw_private;
142	if (srp == NULL) {
143		mutex_unlock(&svcraw_lock);
144		return (FALSE);
145	}
146	mutex_unlock(&svcraw_lock);
147
148	xdrs = &srp->xdr_stream;
149	xdrs->x_op = XDR_DECODE;
150	(void) XDR_SETPOS(xdrs, 0);
151	if (! xdr_callmsg(xdrs, msg)) {
152		return (FALSE);
153	}
154	return (TRUE);
155}
156
157/*ARGSUSED*/
158static bool_t
159svc_raw_reply(SVCXPRT *xprt, struct rpc_msg *msg)
160{
161	struct svc_raw_private *srp;
162	XDR *xdrs;
163	bool_t stat;
164	xdrproc_t xdr_proc;
165	caddr_t xdr_where;
166
167	mutex_lock(&svcraw_lock);
168	srp = svc_raw_private;
169	if (srp == NULL) {
170		mutex_unlock(&svcraw_lock);
171		return (FALSE);
172	}
173	mutex_unlock(&svcraw_lock);
174
175	xdrs = &srp->xdr_stream;
176	xdrs->x_op = XDR_ENCODE;
177	(void) XDR_SETPOS(xdrs, 0);
178	if (msg->rm_reply.rp_stat == MSG_ACCEPTED &&
179	    msg->rm_reply.rp_acpt.ar_stat == SUCCESS) {
180		xdr_proc = msg->acpted_rply.ar_results.proc;
181		xdr_where = msg->acpted_rply.ar_results.where;
182		msg->acpted_rply.ar_results.proc = (xdrproc_t) xdr_void;
183		msg->acpted_rply.ar_results.where = NULL;
184
185		stat = xdr_replymsg(xdrs, msg) &&
186		    SVCAUTH_WRAP(&SVC_AUTH(xprt), xdrs, xdr_proc, xdr_where);
187	} else {
188		stat = xdr_replymsg(xdrs, msg);
189	}
190	if (!stat) {
191		return (FALSE);
192	}
193	(void) XDR_GETPOS(xdrs);  /* called just for overhead */
194	return (TRUE);
195}
196
197/*ARGSUSED*/
198static bool_t
199svc_raw_getargs(SVCXPRT *xprt, xdrproc_t xdr_args, void *args_ptr)
200{
201	struct svc_raw_private *srp;
202
203	mutex_lock(&svcraw_lock);
204	srp = svc_raw_private;
205	if (srp == NULL) {
206		mutex_unlock(&svcraw_lock);
207		return (FALSE);
208	}
209	mutex_unlock(&svcraw_lock);
210
211	return (SVCAUTH_UNWRAP(&SVC_AUTH(xprt), &srp->xdr_stream,
212		xdr_args, args_ptr));
213}
214
215/*ARGSUSED*/
216static bool_t
217svc_raw_freeargs(SVCXPRT *xprt, xdrproc_t xdr_args, void *args_ptr)
218{
219	struct svc_raw_private *srp;
220	XDR *xdrs;
221
222	mutex_lock(&svcraw_lock);
223	srp = svc_raw_private;
224	if (srp == NULL) {
225		mutex_unlock(&svcraw_lock);
226		return (FALSE);
227	}
228	mutex_unlock(&svcraw_lock);
229
230	xdrs = &srp->xdr_stream;
231	xdrs->x_op = XDR_FREE;
232	return (*xdr_args)(xdrs, args_ptr);
233}
234
235/*ARGSUSED*/
236static void
237svc_raw_destroy(SVCXPRT *xprt)
238{
239}
240
241/*ARGSUSED*/
242static bool_t
243svc_raw_control(SVCXPRT *xprt, const u_int rq, void *in)
244{
245	return (FALSE);
246}
247
248static void
249svc_raw_ops(SVCXPRT *xprt)
250{
251	static struct xp_ops ops;
252	static struct xp_ops2 ops2;
253
254/* VARIABLES PROTECTED BY ops_lock: ops */
255
256	mutex_lock(&ops_lock);
257	if (ops.xp_recv == NULL) {
258		ops.xp_recv = svc_raw_recv;
259		ops.xp_stat = svc_raw_stat;
260		ops.xp_getargs = svc_raw_getargs;
261		ops.xp_reply = svc_raw_reply;
262		ops.xp_freeargs = svc_raw_freeargs;
263		ops.xp_destroy = svc_raw_destroy;
264		ops2.xp_control = svc_raw_control;
265	}
266	xprt->xp_ops = &ops;
267	xprt->xp_ops2 = &ops2;
268	mutex_unlock(&ops_lock);
269}
270