1dfdcada3SDoug Rabson /* $NetBSD: svc_generic.c,v 1.3 2000/07/06 03:10:35 christos Exp $ */ 2dfdcada3SDoug Rabson 32e322d37SHiroki Sato /*- 451369649SPedro F. Giffuni * SPDX-License-Identifier: BSD-3-Clause 551369649SPedro F. Giffuni * 62e322d37SHiroki Sato * Copyright (c) 2009, Sun Microsystems, Inc. 72e322d37SHiroki Sato * All rights reserved. 8dfdcada3SDoug Rabson * 92e322d37SHiroki Sato * Redistribution and use in source and binary forms, with or without 102e322d37SHiroki Sato * modification, are permitted provided that the following conditions are met: 112e322d37SHiroki Sato * - Redistributions of source code must retain the above copyright notice, 122e322d37SHiroki Sato * this list of conditions and the following disclaimer. 132e322d37SHiroki Sato * - Redistributions in binary form must reproduce the above copyright notice, 142e322d37SHiroki Sato * this list of conditions and the following disclaimer in the documentation 152e322d37SHiroki Sato * and/or other materials provided with the distribution. 162e322d37SHiroki Sato * - Neither the name of Sun Microsystems, Inc. nor the names of its 172e322d37SHiroki Sato * contributors may be used to endorse or promote products derived 182e322d37SHiroki Sato * from this software without specific prior written permission. 19dfdcada3SDoug Rabson * 202e322d37SHiroki Sato * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 212e322d37SHiroki Sato * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 222e322d37SHiroki Sato * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 232e322d37SHiroki Sato * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 242e322d37SHiroki Sato * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 252e322d37SHiroki Sato * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 262e322d37SHiroki Sato * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 272e322d37SHiroki Sato * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 282e322d37SHiroki Sato * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 292e322d37SHiroki Sato * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 302e322d37SHiroki Sato * POSSIBILITY OF SUCH DAMAGE. 31dfdcada3SDoug Rabson */ 32dfdcada3SDoug Rabson 33dfdcada3SDoug Rabson /* 34dfdcada3SDoug Rabson * Copyright (c) 1986-1991 by Sun Microsystems Inc. 35dfdcada3SDoug Rabson */ 36dfdcada3SDoug Rabson 37dfdcada3SDoug Rabson /* 38dfdcada3SDoug Rabson * svc_generic.c, Server side for RPC. 39dfdcada3SDoug Rabson * 40dfdcada3SDoug Rabson */ 41dfdcada3SDoug Rabson 42dfdcada3SDoug Rabson #include "opt_inet6.h" 43dfdcada3SDoug Rabson 44dfdcada3SDoug Rabson #include <sys/param.h> 45dfdcada3SDoug Rabson #include <sys/lock.h> 46dfdcada3SDoug Rabson #include <sys/kernel.h> 47dfdcada3SDoug Rabson #include <sys/malloc.h> 48dfdcada3SDoug Rabson #include <sys/mutex.h> 49dfdcada3SDoug Rabson #include <sys/protosw.h> 50dfdcada3SDoug Rabson #include <sys/queue.h> 51dfdcada3SDoug Rabson #include <sys/socket.h> 52dfdcada3SDoug Rabson #include <sys/socketvar.h> 53dfdcada3SDoug Rabson #include <sys/systm.h> 54dfdcada3SDoug Rabson #include <sys/sx.h> 55dfdcada3SDoug Rabson #include <sys/ucred.h> 56dfdcada3SDoug Rabson 570348c661SMarko Zec #include <net/vnet.h> 580348c661SMarko Zec 59dfdcada3SDoug Rabson #include <rpc/rpc.h> 60dfdcada3SDoug Rabson #include <rpc/rpcb_clnt.h> 61dfdcada3SDoug Rabson #include <rpc/nettype.h> 62dfdcada3SDoug Rabson 63ee31b83aSDoug Rabson #include <rpc/rpc_com.h> 64dfdcada3SDoug Rabson 65dfdcada3SDoug Rabson extern int __svc_vc_setflag(SVCXPRT *, int); 66dfdcada3SDoug Rabson 67dfdcada3SDoug Rabson /* 68dfdcada3SDoug Rabson * The high level interface to svc_tli_create(). 69dfdcada3SDoug Rabson * It tries to create a server for "nconf" and registers the service 70dfdcada3SDoug Rabson * with the rpcbind. It calls svc_tli_create(); 71dfdcada3SDoug Rabson */ 72dfdcada3SDoug Rabson SVCXPRT * 73dfdcada3SDoug Rabson svc_tp_create( 74dfdcada3SDoug Rabson SVCPOOL *pool, 75dfdcada3SDoug Rabson void (*dispatch)(struct svc_req *, SVCXPRT *), 76dfdcada3SDoug Rabson rpcprog_t prognum, /* Program number */ 77dfdcada3SDoug Rabson rpcvers_t versnum, /* Version number */ 78dfdcada3SDoug Rabson const char *uaddr, /* Address (or null for default) */ 79dfdcada3SDoug Rabson const struct netconfig *nconf) /* Netconfig structure for the network */ 80dfdcada3SDoug Rabson { 81dfdcada3SDoug Rabson struct netconfig nconfcopy; 82dfdcada3SDoug Rabson struct netbuf *taddr; 83dfdcada3SDoug Rabson struct t_bind bind; 84dfdcada3SDoug Rabson SVCXPRT *xprt; 85dfdcada3SDoug Rabson 86dfdcada3SDoug Rabson if (nconf == NULL) { 87dfdcada3SDoug Rabson printf( 88dfdcada3SDoug Rabson "svc_tp_create: invalid netconfig structure for prog %u vers %u\n", 89dfdcada3SDoug Rabson (unsigned)prognum, (unsigned)versnum); 90dfdcada3SDoug Rabson return (NULL); 91dfdcada3SDoug Rabson } 92dfdcada3SDoug Rabson if (uaddr) { 93dfdcada3SDoug Rabson taddr = uaddr2taddr(nconf, uaddr); 94dfdcada3SDoug Rabson bind.addr = *taddr; 95dfdcada3SDoug Rabson free(taddr, M_RPC); 9680867e61SAlexander Motin bind.qlen = -1; 97*d052fcbdSGleb Smirnoff xprt = svc_tli_create(pool, nconf, &bind, 0, 0); 98dfdcada3SDoug Rabson free(bind.addr.buf, M_RPC); 99dfdcada3SDoug Rabson } else { 100*d052fcbdSGleb Smirnoff xprt = svc_tli_create(pool, nconf, NULL, 0, 0); 101dfdcada3SDoug Rabson } 102dfdcada3SDoug Rabson if (xprt == NULL) { 103dfdcada3SDoug Rabson return (NULL); 104dfdcada3SDoug Rabson } 105dfdcada3SDoug Rabson /*LINTED const castaway*/ 106dfdcada3SDoug Rabson nconfcopy = *nconf; 107dfdcada3SDoug Rabson (void) rpcb_unset(prognum, versnum, &nconfcopy); 108dfdcada3SDoug Rabson if (svc_reg(xprt, prognum, versnum, dispatch, nconf) == FALSE) { 109dfdcada3SDoug Rabson printf( 110dfdcada3SDoug Rabson "svc_tp_create: Could not register prog %u vers %u on %s\n", 111dfdcada3SDoug Rabson (unsigned)prognum, (unsigned)versnum, 112dfdcada3SDoug Rabson nconf->nc_netid); 113a9148abdSDoug Rabson xprt_unregister(xprt); 1146b97c9f0SRick Macklem SVC_RELEASE(xprt); 115dfdcada3SDoug Rabson return (NULL); 116dfdcada3SDoug Rabson } 117dfdcada3SDoug Rabson return (xprt); 118dfdcada3SDoug Rabson } 119dfdcada3SDoug Rabson 120dfdcada3SDoug Rabson /* 121dfdcada3SDoug Rabson * If so is NULL, then it opens a socket for the given transport 122dfdcada3SDoug Rabson * provider (nconf cannot be NULL then). If the t_state is T_UNBND and 123dfdcada3SDoug Rabson * bindaddr is NON-NULL, it performs a t_bind using the bindaddr. For 124dfdcada3SDoug Rabson * NULL bindadr and Connection oriented transports, the value of qlen 125dfdcada3SDoug Rabson * is set to 8. 126dfdcada3SDoug Rabson * 127dfdcada3SDoug Rabson * If sendsz or recvsz are zero, their default values are chosen. 128dfdcada3SDoug Rabson */ 129dfdcada3SDoug Rabson SVCXPRT * 130dfdcada3SDoug Rabson svc_tli_create( 131dfdcada3SDoug Rabson SVCPOOL *pool, 132dfdcada3SDoug Rabson const struct netconfig *nconf, /* Netconfig struct for nettoken */ 133dfdcada3SDoug Rabson const struct t_bind *bindaddr, /* Local bind address */ 134dfdcada3SDoug Rabson size_t sendsz, /* Max sendsize */ 135dfdcada3SDoug Rabson size_t recvsz) /* Max recvsize */ 136dfdcada3SDoug Rabson { 137*d052fcbdSGleb Smirnoff struct socket *so; 138dfdcada3SDoug Rabson SVCXPRT *xprt = NULL; /* service handle */ 139dfdcada3SDoug Rabson struct __rpc_sockinfo si; 140dfdcada3SDoug Rabson struct sockaddr_storage ss; 141dfdcada3SDoug Rabson 142dfdcada3SDoug Rabson if (nconf == NULL) { 143dfdcada3SDoug Rabson printf("svc_tli_create: invalid netconfig\n"); 144dfdcada3SDoug Rabson return (NULL); 145dfdcada3SDoug Rabson } 146dfdcada3SDoug Rabson so = __rpc_nconf2socket(nconf); 147dfdcada3SDoug Rabson if (!so) { 148dfdcada3SDoug Rabson printf( 149dfdcada3SDoug Rabson "svc_tli_create: could not open connection for %s\n", 150dfdcada3SDoug Rabson nconf->nc_netid); 151dfdcada3SDoug Rabson return (NULL); 152dfdcada3SDoug Rabson } 153dfdcada3SDoug Rabson __rpc_nconf2sockinfo(nconf, &si); 154dfdcada3SDoug Rabson 155dfdcada3SDoug Rabson if (bindaddr == NULL) { 156dfdcada3SDoug Rabson if (bindresvport(so, NULL)) { 157dfdcada3SDoug Rabson memset(&ss, 0, sizeof ss); 158dfdcada3SDoug Rabson ss.ss_family = si.si_af; 159dfdcada3SDoug Rabson ss.ss_len = si.si_alen; 160dfdcada3SDoug Rabson if (sobind(so, (struct sockaddr *)&ss, 161dfdcada3SDoug Rabson curthread)) { 162dfdcada3SDoug Rabson printf( 163dfdcada3SDoug Rabson "svc_tli_create: could not bind to anonymous port\n"); 164dfdcada3SDoug Rabson goto freedata; 165dfdcada3SDoug Rabson } 166dfdcada3SDoug Rabson } 16780867e61SAlexander Motin solisten(so, -1, curthread); 168dfdcada3SDoug Rabson } else { 169dfdcada3SDoug Rabson if (bindresvport(so, 170dfdcada3SDoug Rabson (struct sockaddr *)bindaddr->addr.buf)) { 171dfdcada3SDoug Rabson printf( 172dfdcada3SDoug Rabson "svc_tli_create: could not bind to requested address\n"); 173dfdcada3SDoug Rabson goto freedata; 174dfdcada3SDoug Rabson } 175dfdcada3SDoug Rabson solisten(so, (int)bindaddr->qlen, curthread); 176dfdcada3SDoug Rabson } 177dfdcada3SDoug Rabson 178dfdcada3SDoug Rabson /* 179dfdcada3SDoug Rabson * call transport specific function. 180dfdcada3SDoug Rabson */ 181dfdcada3SDoug Rabson switch (si.si_socktype) { 182dfdcada3SDoug Rabson case SOCK_STREAM: 183dfdcada3SDoug Rabson #if 0 184dfdcada3SDoug Rabson slen = sizeof ss; 185dfdcada3SDoug Rabson if (_getpeername(fd, (struct sockaddr *)(void *)&ss, &slen) 186dfdcada3SDoug Rabson == 0) { 187dfdcada3SDoug Rabson /* accepted socket */ 188dfdcada3SDoug Rabson xprt = svc_fd_create(fd, sendsz, recvsz); 189dfdcada3SDoug Rabson } else 190dfdcada3SDoug Rabson #endif 191dfdcada3SDoug Rabson xprt = svc_vc_create(pool, so, sendsz, recvsz); 192dfdcada3SDoug Rabson if (!nconf || !xprt) 193dfdcada3SDoug Rabson break; 194dfdcada3SDoug Rabson #if 0 195dfdcada3SDoug Rabson /* XXX fvdl */ 196dfdcada3SDoug Rabson if (strcmp(nconf->nc_protofmly, "inet") == 0 || 197dfdcada3SDoug Rabson strcmp(nconf->nc_protofmly, "inet6") == 0) 198dfdcada3SDoug Rabson (void) __svc_vc_setflag(xprt, TRUE); 199dfdcada3SDoug Rabson #endif 200dfdcada3SDoug Rabson break; 201dfdcada3SDoug Rabson case SOCK_DGRAM: 202dfdcada3SDoug Rabson xprt = svc_dg_create(pool, so, sendsz, recvsz); 203dfdcada3SDoug Rabson break; 204dfdcada3SDoug Rabson default: 205dfdcada3SDoug Rabson printf("svc_tli_create: bad service type"); 206dfdcada3SDoug Rabson goto freedata; 207dfdcada3SDoug Rabson } 208dfdcada3SDoug Rabson 209dfdcada3SDoug Rabson if (xprt == NULL) 210dfdcada3SDoug Rabson /* 211dfdcada3SDoug Rabson * The error messages here are spitted out by the lower layers: 212dfdcada3SDoug Rabson * svc_vc_create(), svc_fd_create() and svc_dg_create(). 213dfdcada3SDoug Rabson */ 214dfdcada3SDoug Rabson goto freedata; 215dfdcada3SDoug Rabson 216dfdcada3SDoug Rabson /* Fill in type of service */ 217dfdcada3SDoug Rabson xprt->xp_type = __rpc_socktype2seman(si.si_socktype); 218dfdcada3SDoug Rabson 219dfdcada3SDoug Rabson if (nconf) { 220dfdcada3SDoug Rabson xprt->xp_netid = strdup(nconf->nc_netid, M_RPC); 221dfdcada3SDoug Rabson } 222dfdcada3SDoug Rabson return (xprt); 223dfdcada3SDoug Rabson 224dfdcada3SDoug Rabson freedata: 225dfdcada3SDoug Rabson (void)soclose(so); 226*d052fcbdSGleb Smirnoff if (xprt) 227a9148abdSDoug Rabson xprt_unregister(xprt); 228dfdcada3SDoug Rabson return (NULL); 229dfdcada3SDoug Rabson } 230