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