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