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 * 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 132 svc_raw_stat(SVCXPRT *xprt) 133 { 134 return (XPRT_IDLE); 135 } 136 137 /*ARGSUSED*/ 138 static bool_t 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 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 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 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 237 svc_raw_destroy(SVCXPRT *xprt) 238 { 239 } 240 241 /*ARGSUSED*/ 242 static bool_t 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 * 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