xref: /netbsd-src/lib/libc/rpc/svc_raw.c (revision 85f5e301f5b0e5c7695c7222d16769f8f55f6aeb)
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