xref: /illumos-gate/usr/src/lib/libnsl/rpc/svc_raw.c (revision 2a6fb28d)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  */
22 
23 /*
24  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
25  * Use is subject to license terms.
26  */
27 /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
28 /* All Rights Reserved */
29 /*
30  * Portions of this source code were derived from Berkeley
31  * 4.3 BSD under license from the Regents of the University of
32  * California.
33  */
34 
35 /*
36  * svc_raw.c,   This is a toy for simple testing and timing.
37  * Interface to create an rpc client and server in the same UNIX process.
38  * This lets us simulate rpc and get rpc (round trip) overhead, without
39  * any interference from the kernal.
40  */
41 
42 #include "mt.h"
43 #include "rpc_mt.h"
44 #include <stdlib.h>
45 #include <rpc/rpc.h>
46 #include <sys/types.h>
47 #include <syslog.h>
48 
49 #ifndef UDPMSGSIZE
50 #define	UDPMSGSIZE 8800
51 #endif
52 
53 /*
54  * This is the "network" that we will be moving data over
55  */
56 static struct svc_raw_private {
57 	struct netbuf	*raw_netbuf;
58 	SVCXPRT	*server;
59 	XDR	xdr_stream;
60 	char	verf_body[MAX_AUTH_BYTES];
61 } *svc_raw_private;
62 
63 static struct xp_ops *svc_raw_ops();
64 extern mutex_t	svcraw_lock;
65 
66 /*
67  * This netbuf is shared with the raw client.
68  */
69 struct netbuf _rawcomnetbuf;
70 
71 SVCXPRT *
svc_raw_create(void)72 svc_raw_create(void)
73 {
74 	struct svc_raw_private *srp;
75 
76 /* VARIABLES PROTECTED BY svcraw_lock: svc_raw_private, srp */
77 	(void) mutex_lock(&svcraw_lock);
78 	srp = svc_raw_private;
79 	if (srp != NULL) {
80 		(void) mutex_unlock(&svcraw_lock);
81 		return (srp->server);
82 	}
83 
84 	srp = calloc(1, sizeof (*srp));
85 	if (srp == NULL) {
86 		syslog(LOG_ERR, "svc_raw_create: out of memory");
87 
88 		(void) mutex_unlock(&svcraw_lock);
89 		return (NULL);
90 	}
91 
92 	srp->raw_netbuf = &_rawcomnetbuf;
93 	srp->raw_netbuf->buf = malloc(UDPMSGSIZE);
94 	if (srp->raw_netbuf->buf == NULL) {
95 		free(srp);
96 		syslog(LOG_ERR, "svc_raw_create: out of memory");
97 
98 		(void) mutex_unlock(&svcraw_lock);
99 		return (NULL);
100 	}
101 	srp->raw_netbuf->maxlen = UDPMSGSIZE;
102 	srp->raw_netbuf->len = 0;
103 
104 	if ((srp->server = svc_xprt_alloc()) == NULL) {
105 		free(srp->raw_netbuf->buf);
106 		srp->raw_netbuf->buf = NULL;
107 		srp->raw_netbuf->maxlen = 0;
108 
109 		free(srp);
110 
111 		(void) mutex_unlock(&svcraw_lock);
112 		return (NULL);
113 	}
114 
115 	/*
116 	 * By convention, using FD_SETSIZE as the pseudo file descriptor
117 	 */
118 	srp->server->xp_fd = FD_SETSIZE;
119 	srp->server->xp_port = 0;
120 	srp->server->xp_ops = svc_raw_ops();
121 	srp->server->xp_verf.oa_base = srp->verf_body;
122 	xprt_register(srp->server);
123 
124 	svc_raw_private = srp;
125 
126 	(void) mutex_unlock(&svcraw_lock);
127 	return (srp->server);
128 }
129 
130 /*ARGSUSED*/
131 static enum xprt_stat
svc_raw_stat(SVCXPRT * xprt)132 svc_raw_stat(SVCXPRT *xprt)
133 {
134 	return (XPRT_IDLE);
135 }
136 
137 /*ARGSUSED*/
138 static bool_t
svc_raw_recv(SVCXPRT * xprt,struct rpc_msg * msg)139 svc_raw_recv(SVCXPRT *xprt, struct rpc_msg *msg)
140 {
141 	struct svc_raw_private *srp;
142 	XDR *xdrs;
143 
144 	(void) mutex_lock(&svcraw_lock);
145 	srp = svc_raw_private;
146 	if (srp == NULL) {
147 		(void) mutex_unlock(&svcraw_lock);
148 		return (FALSE);
149 	}
150 	(void) mutex_unlock(&svcraw_lock);
151 
152 	xdrs = &srp->xdr_stream;
153 
154 	xdrmem_create(xdrs, srp->raw_netbuf->buf, srp->raw_netbuf->len,
155 	    XDR_DECODE);
156 
157 	if (!xdr_callmsg(xdrs, msg)) {
158 		XDR_DESTROY(xdrs);
159 		return (FALSE);
160 	}
161 
162 	return (TRUE);
163 }
164 
165 /*ARGSUSED*/
166 static bool_t
svc_raw_reply(SVCXPRT * xprt,struct rpc_msg * msg)167 svc_raw_reply(SVCXPRT *xprt, struct rpc_msg *msg)
168 {
169 	struct svc_raw_private *srp;
170 	XDR *xdrs;
171 	uint_t start;
172 
173 	(void) mutex_lock(&svcraw_lock);
174 	srp = svc_raw_private;
175 	if (srp == NULL) {
176 		(void) mutex_unlock(&svcraw_lock);
177 		return (FALSE);
178 	}
179 	(void) mutex_unlock(&svcraw_lock);
180 
181 	xdrs = &srp->xdr_stream;
182 
183 	XDR_DESTROY(xdrs);
184 	xdrmem_create(xdrs, srp->raw_netbuf->buf, srp->raw_netbuf->maxlen,
185 	    XDR_ENCODE);
186 
187 	start = XDR_GETPOS(xdrs);
188 	if (!xdr_replymsg(xdrs, msg)) {
189 		XDR_DESTROY(xdrs);
190 		return (FALSE);
191 	}
192 	srp->raw_netbuf->len = XDR_GETPOS(xdrs) - start;
193 
194 	return (TRUE);
195 }
196 
197 /*ARGSUSED*/
198 static bool_t
svc_raw_getargs(SVCXPRT * xprt,xdrproc_t xdr_args,caddr_t args_ptr)199 svc_raw_getargs(SVCXPRT *xprt, xdrproc_t xdr_args, caddr_t args_ptr)
200 {
201 	struct svc_raw_private *srp;
202 
203 	(void) mutex_lock(&svcraw_lock);
204 	srp = svc_raw_private;
205 	if (srp == NULL) {
206 		(void) mutex_unlock(&svcraw_lock);
207 		return (FALSE);
208 	}
209 	(void) mutex_unlock(&svcraw_lock);
210 
211 	return ((*xdr_args)(&srp->xdr_stream, args_ptr));
212 }
213 
214 /*ARGSUSED*/
215 static bool_t
svc_raw_freeargs(SVCXPRT * xprt,xdrproc_t xdr_args,caddr_t args_ptr)216 svc_raw_freeargs(SVCXPRT *xprt, xdrproc_t xdr_args, caddr_t args_ptr)
217 {
218 	struct svc_raw_private *srp;
219 
220 	(void) mutex_lock(&svcraw_lock);
221 	srp = svc_raw_private;
222 	if (srp == NULL) {
223 		(void) mutex_unlock(&svcraw_lock);
224 		return (FALSE);
225 	}
226 	(void) mutex_unlock(&svcraw_lock);
227 
228 	XDR_DESTROY(&srp->xdr_stream);
229 
230 	xdr_free(xdr_args, args_ptr);
231 
232 	return (TRUE);
233 }
234 
235 /*ARGSUSED*/
236 static void
svc_raw_destroy(SVCXPRT * xprt)237 svc_raw_destroy(SVCXPRT *xprt)
238 {
239 }
240 
241 /*ARGSUSED*/
242 static bool_t
svc_raw_control(SVCXPRT * xprt,const uint_t rq,void * in)243 svc_raw_control(SVCXPRT *xprt, const uint_t rq, void *in)
244 {
245 	switch (rq) {
246 	case SVCGET_XID: /* fall through for now */
247 	default:
248 		return (FALSE);
249 	}
250 }
251 
252 static struct xp_ops *
svc_raw_ops(void)253 svc_raw_ops(void)
254 {
255 	static struct xp_ops ops;
256 	extern mutex_t ops_lock;
257 
258 /* VARIABLES PROTECTED BY ops_lock: ops */
259 
260 	(void) mutex_lock(&ops_lock);
261 	if (ops.xp_recv == NULL) {
262 		ops.xp_recv = svc_raw_recv;
263 		ops.xp_stat = svc_raw_stat;
264 		ops.xp_getargs = svc_raw_getargs;
265 		ops.xp_reply = svc_raw_reply;
266 		ops.xp_freeargs = svc_raw_freeargs;
267 		ops.xp_destroy = svc_raw_destroy;
268 		ops.xp_control = svc_raw_control;
269 	}
270 	(void) mutex_unlock(&ops_lock);
271 	return (&ops);
272 }
273