1 /* $NetBSD: svc_raw.c,v 1.26 2024/01/23 17:24:38 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.26 2024/01/23 17:24:38 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 #include "rpc_internal.h"
65
66 #ifdef __weak_alias
67 __weak_alias(svc_raw_create,_svc_raw_create)
68 #endif
69
70 #ifndef UDPMSGSIZE
71 #define UDPMSGSIZE 8800
72 #endif
73
74 /*
75 * This is the "network" that we will be moving data over
76 */
77 static struct svc_raw_private {
78 char *raw_buf; /* should be shared with the cl handle */
79 SVCXPRT server;
80 XDR xdr_stream;
81 char verf_body[MAX_AUTH_BYTES];
82 } *svc_raw_private;
83
84 static enum xprt_stat svc_raw_stat(SVCXPRT *);
85 static bool_t svc_raw_recv(SVCXPRT *, struct rpc_msg *);
86 static bool_t svc_raw_reply(SVCXPRT *, struct rpc_msg *);
87 static bool_t svc_raw_getargs(SVCXPRT *, xdrproc_t, caddr_t);
88 static bool_t svc_raw_freeargs(SVCXPRT *, xdrproc_t, caddr_t);
89 static void svc_raw_destroy(SVCXPRT *);
90 static void svc_raw_ops(SVCXPRT *);
91 static bool_t svc_raw_control(SVCXPRT *, const u_int, void *);
92
93 char *__rpc_rawcombuf = NULL;
94
95 SVCXPRT *
svc_raw_create(void)96 svc_raw_create(void)
97 {
98 struct svc_raw_private *srp;
99 /* VARIABLES PROTECTED BY svcraw_lock: svc_raw_private, srp */
100
101 mutex_lock(&svcraw_lock);
102 srp = svc_raw_private;
103 if (srp == NULL) {
104 srp = calloc(1, sizeof(*srp));
105 if (srp == NULL)
106 goto out;
107 if (__rpc_rawcombuf == NULL)
108 __rpc_rawcombuf = malloc(UDPMSGSIZE);
109 if (__rpc_rawcombuf == NULL)
110 goto out;
111 srp->raw_buf = __rpc_rawcombuf; /* Share it with the client */
112 svc_raw_private = srp;
113 }
114 srp->server.xp_fd = -1;
115 srp->server.xp_port = 0;
116 srp->server.xp_p3 = NULL;
117 svc_raw_ops(&srp->server);
118 srp->server.xp_verf.oa_base = srp->verf_body;
119 xdrmem_create(&srp->xdr_stream, srp->raw_buf, UDPMSGSIZE, XDR_DECODE);
120 if (!xprt_register(&srp->server))
121 goto out;
122 mutex_unlock(&svcraw_lock);
123 return (&srp->server);
124 out:
125 if (srp != NULL)
126 free(srp);
127 mutex_unlock(&svcraw_lock);
128 return (NULL);
129 }
130
131 /*ARGSUSED*/
132 static enum xprt_stat
svc_raw_stat(SVCXPRT * xprt)133 svc_raw_stat(SVCXPRT *xprt) /* args needed to satisfy ANSI-C typechecking */
134 {
135 return (XPRT_IDLE);
136 }
137
138 /*ARGSUSED*/
139 static bool_t
svc_raw_recv(SVCXPRT * xprt,struct rpc_msg * msg)140 svc_raw_recv(SVCXPRT *xprt, struct rpc_msg *msg)
141 {
142 struct svc_raw_private *srp;
143 XDR *xdrs;
144
145 mutex_lock(&svcraw_lock);
146 srp = svc_raw_private;
147 if (srp == NULL) {
148 mutex_unlock(&svcraw_lock);
149 return (FALSE);
150 }
151 mutex_unlock(&svcraw_lock);
152
153 xdrs = &srp->xdr_stream;
154 xdrs->x_op = XDR_DECODE;
155 (void) XDR_SETPOS(xdrs, 0);
156 if (! xdr_callmsg(xdrs, msg)) {
157 return (FALSE);
158 }
159 return (TRUE);
160 }
161
162 /*ARGSUSED*/
163 static bool_t
svc_raw_reply(SVCXPRT * xprt,struct rpc_msg * msg)164 svc_raw_reply(SVCXPRT *xprt, struct rpc_msg *msg)
165 {
166 struct svc_raw_private *srp;
167 XDR *xdrs;
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 (! xdr_replymsg(xdrs, msg)) {
181 return (FALSE);
182 }
183 (void) XDR_GETPOS(xdrs); /* called just for overhead */
184 return (TRUE);
185 }
186
187 /*ARGSUSED*/
188 static bool_t
svc_raw_getargs(SVCXPRT * xprt,xdrproc_t xdr_args,caddr_t args_ptr)189 svc_raw_getargs(SVCXPRT *xprt, xdrproc_t xdr_args, caddr_t args_ptr)
190 {
191 struct svc_raw_private *srp;
192
193 mutex_lock(&svcraw_lock);
194 srp = svc_raw_private;
195 if (srp == NULL) {
196 mutex_unlock(&svcraw_lock);
197 return (FALSE);
198 }
199 mutex_unlock(&svcraw_lock);
200 return (*xdr_args)(&srp->xdr_stream, args_ptr);
201 }
202
203 /*ARGSUSED*/
204 static bool_t
svc_raw_freeargs(SVCXPRT * xprt,xdrproc_t xdr_args,caddr_t args_ptr)205 svc_raw_freeargs(SVCXPRT *xprt, xdrproc_t xdr_args, caddr_t args_ptr)
206 {
207 struct svc_raw_private *srp;
208 XDR *xdrs;
209
210 mutex_lock(&svcraw_lock);
211 srp = svc_raw_private;
212 if (srp == NULL) {
213 mutex_unlock(&svcraw_lock);
214 return (FALSE);
215 }
216 mutex_unlock(&svcraw_lock);
217
218 xdrs = &srp->xdr_stream;
219 xdrs->x_op = XDR_FREE;
220 return (*xdr_args)(xdrs, args_ptr);
221 }
222
223 /*ARGSUSED*/
224 static void
svc_raw_destroy(SVCXPRT * xprt)225 svc_raw_destroy(SVCXPRT *xprt)
226 {
227 }
228
229 /*ARGSUSED*/
230 static bool_t
svc_raw_control(SVCXPRT * xprt,const u_int rq,void * in)231 svc_raw_control(SVCXPRT *xprt, const u_int rq, void *in)
232 {
233 return (FALSE);
234 }
235
236 static void
svc_raw_ops(SVCXPRT * xprt)237 svc_raw_ops(SVCXPRT *xprt)
238 {
239 static struct xp_ops ops;
240 static struct xp_ops2 ops2;
241
242 _DIAGASSERT(xprt != NULL);
243
244 /* VARIABLES PROTECTED BY ops_lock: ops */
245
246 mutex_lock(&ops_lock);
247 if (ops.xp_recv == NULL) {
248 ops.xp_recv = svc_raw_recv;
249 ops.xp_stat = svc_raw_stat;
250 ops.xp_getargs = svc_raw_getargs;
251 ops.xp_reply = svc_raw_reply;
252 ops.xp_freeargs = svc_raw_freeargs;
253 ops.xp_destroy = svc_raw_destroy;
254 ops2.xp_control = svc_raw_control;
255 }
256 xprt->xp_ops = &ops;
257 xprt->xp_ops2 = &ops2;
258 mutex_unlock(&ops_lock);
259 }
260