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