diff options
author | Gordon Ross <gwr@nexenta.com> | 2016-12-18 18:24:35 -0500 |
---|---|---|
committer | Gordon Ross <gwr@nexenta.com> | 2017-07-20 21:54:31 -0400 |
commit | dec98d2aa2912b1fbd0abd2574307a695b566692 (patch) | |
tree | a171c296b3e5cd7563a0f82f4d7bad7c42ff4cc5 /usr/src | |
parent | 6e270ca825f06ec0e2d77db462b83074ec585f2f (diff) | |
download | illumos-gate-dec98d2aa2912b1fbd0abd2574307a695b566692.tar.gz |
8330 Add svc_tp_create_addr to libnsl
Reviewed by: Paul Dagnelie <pcd@delphix.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
Reviewed by: Sebastien Roy <sebastien.roy@delphix.com>
Approved by: Prakash Surya <prakash.surya@delphix.com>
Diffstat (limited to 'usr/src')
-rw-r--r-- | usr/src/cmd/fs.d/nfs/Makefile | 2 | ||||
-rw-r--r-- | usr/src/cmd/fs.d/nfs/tests/Makefile | 50 | ||||
-rw-r--r-- | usr/src/cmd/fs.d/nfs/tests/test_svc_tp_create.c | 332 | ||||
-rw-r--r-- | usr/src/lib/libnsl/common/mapfile-vers | 7 | ||||
-rw-r--r-- | usr/src/lib/libnsl/rpc/svc_generic.c | 127 | ||||
-rw-r--r-- | usr/src/man/man3nsl/Makefile | 4 | ||||
-rw-r--r-- | usr/src/man/man3nsl/rpc_svc_create.3nsl | 76 | ||||
-rw-r--r-- | usr/src/pkg/manifests/system-library.man3nsl.inc | 4 | ||||
-rw-r--r-- | usr/src/uts/common/rpc/svc.h | 16 |
9 files changed, 559 insertions, 59 deletions
diff --git a/usr/src/cmd/fs.d/nfs/Makefile b/usr/src/cmd/fs.d/nfs/Makefile index 20b6690023..7f9ae26ae2 100644 --- a/usr/src/cmd/fs.d/nfs/Makefile +++ b/usr/src/cmd/fs.d/nfs/Makefile @@ -33,7 +33,7 @@ include $(SRC)/Makefile.master SUBDIR1= exportfs nfsd rquotad \ statd nfsstat mountd dfshares \ - nfsfind nfs4cbd share + nfsfind nfs4cbd share tests # These do "make catalog" SUBDIR2= clear_locks lockd umount showmount \ diff --git a/usr/src/cmd/fs.d/nfs/tests/Makefile b/usr/src/cmd/fs.d/nfs/tests/Makefile new file mode 100644 index 0000000000..1229b37f3e --- /dev/null +++ b/usr/src/cmd/fs.d/nfs/tests/Makefile @@ -0,0 +1,50 @@ +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License, Version 1.0 only +# (the "License"). You may not use this file except in compliance +# with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# +# +# Copyright 2004 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# +# cmd/fs.d/nfs/tests/Makefile + +FSTYPE= nfs +LIBPROG= test_svc_tp_create + +include ../../Makefile.fstype + +OBJS= $(LIBPROG).o +SRCS= $(LIBPROG).c + +CFLAGS += $(CCVERBOSE) + +LDLIBS += -lnsl -lsocket + +# message catalog +catalog: + +$(LIBPROG): $(OBJS) + $(LINK.c) -o $@ $(OBJS) $(LDLIBS) + $(POST_PROCESS) + +lint: lint_SRCS + +clean: + $(RM) $(LIBPROG).o diff --git a/usr/src/cmd/fs.d/nfs/tests/test_svc_tp_create.c b/usr/src/cmd/fs.d/nfs/tests/test_svc_tp_create.c new file mode 100644 index 0000000000..aec14d25b9 --- /dev/null +++ b/usr/src/cmd/fs.d/nfs/tests/test_svc_tp_create.c @@ -0,0 +1,332 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ + +/* + * Copyright (c) 1989, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2016 by Delphix. All rights reserved. + * Copyright 2017 Nexenta Systems, Inc. All rights reserved. + */ + +/* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */ +/* All Rights Reserved */ + +/* + * Portions of this source code were derived from Berkeley 4.3 BSD + * under license from the Regents of the University of California. + */ + +#include <stdio.h> +#include <stdlib.h> +#include <ctype.h> +#include <sys/types.h> +#include <string.h> +#include <syslog.h> +#include <sys/param.h> +#include <rpc/rpc.h> +#include <sys/stat.h> +#include <netconfig.h> +#include <netdir.h> + +#include <sys/file.h> +#include <sys/time.h> +#include <sys/errno.h> +#include <rpcsvc/mount.h> + +#include <signal.h> +#include <locale.h> +#include <unistd.h> +#include <errno.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <arpa/inet.h> +#include <netdb.h> + +#include <thread.h> +#include <assert.h> + +#include <limits.h> + +#define TESTPROG 987654 + +uint32_t test_vers_max = 2; +uint32_t test_vers_min = 1; + +int debug; +int verbose; +int testd_port; + +static void mysvc(struct svc_req *, SVCXPRT *); +static void bind2(void); + +/* + * This function is called for each configured network type to + * bind and register our RPC service programs. + * + * On TCP or UDP, we want to bind TESTPROG on a specific port + * (when testd_port is specified) in which case we'll use the + * variant of svc_tp_create() that lets us pass a bind address. + */ +static void +test_svc_tp_create(struct netconfig *nconf) +{ + char port_str[8]; + struct nd_hostserv hs; + struct nd_addrlist *al = NULL; + SVCXPRT *xprt = NULL; + rpcvers_t vers; + + vers = test_vers_max; + + /* + * If testd_port is set and this is an inet transport, + * bind this service on the specified port. + */ + if (testd_port != 0 && + (strcmp(nconf->nc_protofmly, NC_INET) == 0 || + strcmp(nconf->nc_protofmly, NC_INET6) == 0)) { + int err; + + snprintf(port_str, sizeof (port_str), "%u", + (unsigned short)testd_port); + + hs.h_host = HOST_SELF_BIND; + hs.h_serv = port_str; + err = netdir_getbyname((struct netconfig *)nconf, &hs, &al); + if (err == 0 && al != NULL) { + xprt = svc_tp_create_addr(mysvc, TESTPROG, vers, + nconf, al->n_addrs); + netdir_free(al, ND_ADDRLIST); + } + if (xprt == NULL) { + printf("testd: unable to create " + "(TESTD,%d) on transport %s (port %d)\n", + (int)vers, nconf->nc_netid, testd_port); + } + /* fall-back to default bind */ + } + if (xprt == NULL) { + /* + * Had testd_port=0, or non-inet transport, + * or the bind to a specific port failed. + * Do a default bind. + */ + xprt = svc_tp_create(mysvc, TESTPROG, vers, nconf); + } + if (xprt == NULL) { + printf("testd: unable to create " + "(TESTD,%d) on transport %s\n", + (int)vers, nconf->nc_netid); + return; + } + + /* + * Register additional versions on this transport. + */ + while (--vers >= test_vers_min) { + if (!svc_reg(xprt, TESTPROG, vers, mysvc, nconf)) { + printf("testd: " + "failed to register vers %d on %s\n", + (int)vers, nconf->nc_netid); + } + } +} + +static void +test_svc_unreg(void) +{ + rpcvers_t vers; + + for (vers = test_vers_min; vers <= test_vers_max; vers++) + svc_unreg(TESTPROG, vers); +} + +int +main(int argc, char *argv[]) +{ + int c; + bool_t exclbind = TRUE; + int tmp; + struct netconfig *nconf; + NCONF_HANDLE *nc; + + while ((c = getopt(argc, argv, "dvp:")) != EOF) { + switch (c) { + case 'd': + debug++; + break; + case 'v': + verbose++; + break; + case 'p': + (void) sscanf(optarg, "%d", &tmp); + if (tmp < 1 || tmp > UINT16_MAX) { + (void) fprintf(stderr, + "testd: -P port invalid.\n"); + return (1); + } + testd_port = tmp; + break; + default: + fprintf(stderr, "usage: testd [-v] [-r]\n"); + exit(1); + } + } + + (void) setlocale(LC_ALL, ""); + +#if !defined(TEXT_DOMAIN) +#define TEXT_DOMAIN "SYS_TEST" +#endif + (void) textdomain(TEXT_DOMAIN); + + /* + * Prevent our non-priv udp and tcp ports bound w/wildcard addr + * from being hijacked by a bind to a more specific addr. + */ + if (!rpc_control(__RPC_SVC_EXCLBIND_SET, &exclbind)) { + fprintf(stderr, "warning: unable to set udp/tcp EXCLBIND\n"); + } + + if (testd_port < 0 || testd_port > UINT16_MAX) { + fprintf(stderr, "unable to use specified port\n"); + exit(1); + } + + /* + * Make sure to unregister any previous versions in case the + * user is reconfiguring the server in interesting ways. + */ + test_svc_unreg(); + + /* + * Enumerate network transports and create service listeners + * as appropriate for each. + */ + if ((nc = setnetconfig()) == NULL) { + perror("setnetconfig failed"); + return (-1); + } + while ((nconf = getnetconfig(nc)) != NULL) { + /* + * Skip things like tpi_raw, invisible... + */ + if ((nconf->nc_flag & NC_VISIBLE) == 0) + continue; + if (nconf->nc_semantics != NC_TPI_CLTS && + nconf->nc_semantics != NC_TPI_COTS && + nconf->nc_semantics != NC_TPI_COTS_ORD) + continue; + + test_svc_tp_create(nconf); + } + (void) endnetconfig(nc); + + /* + * XXX: Normally would call svc_run() here, but + * we just want to check our IP bindings. + */ + if (testd_port != 0) + bind2(); + + if (debug) { + char sysbuf[100]; + + snprintf(sysbuf, sizeof (sysbuf), + "rpcinfo -p |grep %u", TESTPROG); + printf("x %s\n", sysbuf); + fflush(stdout); + system(sysbuf); + + if (testd_port) { + snprintf(sysbuf, sizeof (sysbuf), + "netstat -a -f inet -P udp |grep %u", testd_port); + printf("x %s\n", sysbuf); + fflush(stdout); + system(sysbuf); + + snprintf(sysbuf, sizeof (sysbuf), + "netstat -a -f inet -P tcp |grep %u", testd_port); + printf("x %s\n", sysbuf); + fflush(stdout); + system(sysbuf); + } + } + + /* cleanup */ + test_svc_unreg(); + + printf("%s complete\n", argv[0]); + return (0); +} + +/* + * Server procedure switch routine + */ +static void +mysvc(struct svc_req *rq, SVCXPRT *xprt) +{ + + switch (rq->rq_proc) { + case NULLPROC: + errno = 0; + (void) svc_sendreply(xprt, xdr_void, (char *)0); + return; + + default: + svcerr_noproc(xprt); + return; + } +} + +struct sockaddr_in addr; + +/* + * The actual test: Try doing a 2nd bind with a specific IP. + * The exclusive wildcard bind should prvent this. + */ +static void +bind2(void) +{ + int ret; + int sock; + + addr.sin_family = AF_INET; + addr.sin_port = htons(testd_port); + addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); + + sock = socket(AF_INET, SOCK_STREAM, 0); + if (sock == -1) { + fprintf(stderr, "bind2 socket fail %s\n", + strerror(errno)); + exit(1); + } + + ret = bind(sock, (struct sockaddr *)&addr, sizeof (addr)); + if (ret == -1) { + fprintf(stderr, "bind2 bind fail %s (expected) PASS\n", + strerror(errno)); + close(sock); + return; + } + + printf("Oh no, bind2 worked! test FAILED\n"); + close(sock); +} diff --git a/usr/src/lib/libnsl/common/mapfile-vers b/usr/src/lib/libnsl/common/mapfile-vers index 3f31af2f5e..9a0b25a16b 100644 --- a/usr/src/lib/libnsl/common/mapfile-vers +++ b/usr/src/lib/libnsl/common/mapfile-vers @@ -20,7 +20,7 @@ # # # Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. -# Copyright 2014 Nexenta Systems, Inc. All rights reserved. +# Copyright 2017 Nexenta Systems, Inc. All rights reserved. # # @@ -39,6 +39,11 @@ $mapfile_version 2 +SYMBOL_VERSION ILLUMOS_0.1 { # Illumos additions + global: + svc_tp_create_addr; +} SUNW_1.10; + SYMBOL_VERSION SUNW_1.10 { # SunOS 5.11 (Solaris 11) global: SUNW_1.10; diff --git a/usr/src/lib/libnsl/rpc/svc_generic.c b/usr/src/lib/libnsl/rpc/svc_generic.c index ca9322b45d..3b5bb2b4bf 100644 --- a/usr/src/lib/libnsl/rpc/svc_generic.c +++ b/usr/src/lib/libnsl/rpc/svc_generic.c @@ -20,8 +20,8 @@ */ /* + * Copyright 2016 Nexenta Systems, Inc. All rights reserved. * Copyright (c) 1989, 2010, Oracle and/or its affiliates. All rights reserved. - * Copyright 2014 Nexenta Systems, Inc. All rights reserved. */ /* Copyright (c) 1988 AT&T */ @@ -87,6 +87,10 @@ extern mutex_t xprtlist_lock; static SVCXPRT * svc_tli_create_common(int, const struct netconfig *, const struct t_bind *, uint_t, uint_t, boolean_t); +static SVCXPRT *svc_tp_create_bind(void (*dispatch)(), + const rpcprog_t, const rpcvers_t, + const struct netconfig *, const struct t_bind *); + boolean_t is_multilevel(rpcprog_t prognum) { @@ -176,11 +180,50 @@ svc_create(void (*dispatch)(), const rpcprog_t prognum, const rpcvers_t versnum, /* * The high level interface to svc_tli_create(). * It tries to create a server for "nconf" and registers the service - * with the rpcbind. It calls svc_tli_create(); + * with the rpcbind. */ SVCXPRT * svc_tp_create(void (*dispatch)(), const rpcprog_t prognum, - const rpcvers_t versnum, const struct netconfig *nconf) + const rpcvers_t versnum, const struct netconfig *nconf) +{ + return (svc_tp_create_bind(dispatch, prognum, versnum, nconf, NULL)); +} + +/* + * svc_tp_create_addr() + * Variant of svc_tp_create() that allows specifying just the + * the binding address, for convenience. + */ +SVCXPRT * +svc_tp_create_addr(void (*dispatch)(), const rpcprog_t prognum, + const rpcvers_t versnum, const struct netconfig *nconf, + const struct netbuf *addr) +{ + struct t_bind bind; + struct t_bind *bindp = NULL; + + if (addr != NULL) { + + bind.addr = *addr; + if (!rpc_control(__RPC_SVC_LSTNBKLOG_GET, &bind.qlen)) { + syslog(LOG_ERR, + "svc_tp_create: can't get listen backlog"); + return (NULL); + } + bindp = &bind; + } + + /* + * When bindp == NULL, this is the same as svc_tp_create(). + */ + return (svc_tp_create_bind(dispatch, prognum, versnum, + nconf, bindp)); +} + +static SVCXPRT * +svc_tp_create_bind(void (*dispatch)(), const rpcprog_t prognum, + const rpcvers_t versnum, const struct netconfig *nconf, + const struct t_bind *bindaddr) { SVCXPRT *xprt; boolean_t anon_mlp = B_FALSE; @@ -194,7 +237,8 @@ svc_tp_create(void (*dispatch)(), const rpcprog_t prognum, /* Some programs need to allocate MLP for multilevel services */ if (is_system_labeled() && is_multilevel(prognum)) anon_mlp = B_TRUE; - xprt = svc_tli_create_common(RPC_ANYFD, nconf, NULL, 0, 0, anon_mlp); + xprt = svc_tli_create_common(RPC_ANYFD, nconf, bindaddr, 0, 0, + anon_mlp); if (xprt == NULL) return (NULL); @@ -324,7 +368,6 @@ svc_tli_create_common(const int ofd, const struct netconfig *nconf, } switch (state) { - bool_t tcp, exclbind; case T_UNBND: /* If this is a labeled system, then ask for an MLP */ if (is_system_labeled() && @@ -337,32 +380,15 @@ svc_tli_create_common(const int ofd, const struct netconfig *nconf, SO_ANON_MLP, 1); } - /* - * SO_EXCLBIND has the following properties - * - an fd bound to port P via IPv4 will prevent an IPv6 - * bind to port P (and vice versa) - * - an fd bound to a wildcard IP address for port P will - * prevent a more specific IP address bind to port P - * (see {tcp,udp}.c for details) - * - * We use the latter property to prevent hijacking of RPC - * services that reside at non-privileged ports. - */ - tcp = nconf ? (strcmp(nconf->nc_proto, NC_TCP) == 0) : 0; - if (nconf && - (tcp || (strcmp(nconf->nc_proto, NC_UDP) == 0)) && - rpc_control(__RPC_SVC_EXCLBIND_GET, &exclbind)) { - if (exclbind) { - if (__rpc_tli_set_options(fd, SOL_SOCKET, - SO_EXCLBIND, 1) < 0) { - syslog(LOG_ERR, - "svc_tli_create: can't set EXCLBIND [netid='%s']", - nconf->nc_netid); - goto freedata; - } - } - } if (bindaddr) { + /* + * Services that specify a bind address typically + * use a fixed service (IP port) so we need to set + * SO_REUSEADDR to prevent bind errors on restart. + */ + if (bindaddr->addr.len != 0) + (void) __rpc_tli_set_options(fd, SOL_SOCKET, + SO_REUSEADDR, 1); if (t_bind(fd, (struct t_bind *)bindaddr, tres) == -1) { char errorstr[100]; @@ -405,6 +431,47 @@ svc_tli_create_common(const int ofd, const struct netconfig *nconf, } } + /* + * If requested, set SO_EXCLBIND on each binding. + * + * SO_EXCLBIND has the following properties + * - an fd bound to port P via IPv4 will prevent an IPv6 + * bind to port P (and vice versa) + * - an fd bound to a wildcard IP address for port P will + * prevent a more specific IP address bind to port P + * (see {tcp,udp}.c for details) + * + * We use the latter property to prevent hijacking of RPC + * services that reside at non-privileged ports. + * + * When the bind address is not specified, each bind gets a + * new port number, and (for IP transports) we should set + * the exclusive flag after every IP bind. That's the + * strcmp nc_proto part of the expression below. + * + * When the bind address IS specified, we need to set the + * exclusive flag only after we've bound both IPv6+IPv4, + * or the IPv4 bind will fail. Setting the exclusive flag + * after the "tcp" or "udp" transport bind does that. + * That's the strcmp nc_netid part below. + */ + if (nconf != NULL && ((bindaddr == NULL && + (strcmp(nconf->nc_proto, NC_TCP) == 0 || + strcmp(nconf->nc_proto, NC_UDP) == 0)) || + (strcmp(nconf->nc_netid, "tcp") == 0 || + strcmp(nconf->nc_netid, "udp") == 0))) { + bool_t exclbind = FALSE; + (void) rpc_control(__RPC_SVC_EXCLBIND_GET, &exclbind); + if (exclbind && + __rpc_tli_set_options(fd, SOL_SOCKET, + SO_EXCLBIND, 1) < 0) { + syslog(LOG_ERR, + "svc_tli_create: can't set EXCLBIND [netid='%s']", + nconf->nc_netid); + goto freedata; + } + } + /* Enable options of returning the ip's for udp */ if (nconf) { int ret = 0; diff --git a/usr/src/man/man3nsl/Makefile b/usr/src/man/man3nsl/Makefile index 906382cab1..f731531339 100644 --- a/usr/src/man/man3nsl/Makefile +++ b/usr/src/man/man3nsl/Makefile @@ -11,7 +11,7 @@ # # Copyright 2011, Richard Lowe -# Copyright 2013 Nexenta Systems, Inc. All rights reserved. +# Copyright 2017 Nexenta Systems, Inc. All rights reserved. # include $(SRC)/Makefile.master @@ -237,6 +237,7 @@ MANLINKS= auth_destroy.3nsl \ svc_sendreply.3nsl \ svc_tli_create.3nsl \ svc_tp_create.3nsl \ + svc_tp_create_addr.3nsl \ svc_unreg.3nsl \ svc_unregister.3nsl \ svc_vc_create.3nsl \ @@ -462,6 +463,7 @@ svc_fd_create.3nsl := LINKSRC = rpc_svc_create.3nsl svc_raw_create.3nsl := LINKSRC = rpc_svc_create.3nsl svc_tli_create.3nsl := LINKSRC = rpc_svc_create.3nsl svc_tp_create.3nsl := LINKSRC = rpc_svc_create.3nsl +svc_tp_create_addr.3nsl := LINKSRC = rpc_svc_create.3nsl svc_vc_create.3nsl := LINKSRC = rpc_svc_create.3nsl svcerr_auth.3nsl := LINKSRC = rpc_svc_err.3nsl diff --git a/usr/src/man/man3nsl/rpc_svc_create.3nsl b/usr/src/man/man3nsl/rpc_svc_create.3nsl index b70380a244..476692d442 100644 --- a/usr/src/man/man3nsl/rpc_svc_create.3nsl +++ b/usr/src/man/man3nsl/rpc_svc_create.3nsl @@ -1,14 +1,15 @@ '\" te -.\" Copyright 2014 Nexenta Systems, Inc. All Rights Reserved. +.\" Copyright 2017 Nexenta Systems, Inc. All Rights Reserved. .\" Copyright 1989 AT&T .\" Copyright (C) 2005, Sun Microsystems, Inc. All Rights Reserved. .\" The contents of this file are subject to the terms of the Common Development and Distribution License (the "License"). You may not use this file except in compliance with the License. .\" You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE or http://www.opensolaris.org/os/licensing. See the License for the specific language governing permissions and limitations under the License. .\" When distributing Covered Code, include this CDDL HEADER in each file and include the License file at usr/src/OPENSOLARIS.LICENSE. If applicable, add the following below this CDDL HEADER, with the fields enclosed by brackets "[]" replaced with your own identifying information: Portions Copyright [yyyy] [name of copyright owner] -.TH RPC_SVC_CREATE 3NSL "May 18, 2017" +.TH RPC_SVC_CREATE 3NSL "Jun 19, 2017" .SH NAME rpc_svc_create, svc_control, svc_create, svc_destroy, svc_dg_create, -svc_fd_create, svc_raw_create, svc_tli_create, svc_tp_create, svc_vc_create, +svc_fd_create, svc_raw_create, svc_tli_create, svc_tp_create, +svc_tp_create_addr, svc_vc_create, svc_door_create \- server handle creation routines .SH SYNOPSIS .LP @@ -50,7 +51,7 @@ svc_door_create \- server handle creation routines .LP .nf \fBSVCXPRT *\fR\fBsvc_tli_create\fR(\fBconst int\fR \fIfildes\fR, \fBconst struct netconfig *\fR\fInetconf\fR, - \fBconst struct t_bind *\fR\fIbind_addr\fR, \fBconst uint_t\fR \fIsendsz\fR, + \fBconst struct t_bind *\fR\fIbind_info\fR, \fBconst uint_t\fR \fIsendsz\fR, \fBconst uint_t\fR \fIrecvsz\fR); .fi @@ -63,6 +64,15 @@ svc_door_create \- server handle creation routines .LP .nf +\fBSVCXPRT *\fR\fBsvc_tp_create_addr\fR(\fBconst void (*\fR\fIdispatch\fR) + (const struct svc_req *, const SVCXPRT *), \fBconst rpcprog_t\fR \fIprognum\fR, + \fBconst rpcvers_t\fR \fIversnum\fR, \fBconst struct netconfig *\fR\fInetconf\fR, + \fBconst struct netbuf *\fR\fIbind_addr\fR) +); +.fi + +.LP +.nf \fBSVCXPRT *\fR\fBsvc_vc_create\fR(\fBconst int\fR \fIfildes\fR, \fBconst uint_t\fR \fIsendsz\fR, \fBconst uint_t\fR \fIrecvsz\fR); .fi @@ -88,7 +98,7 @@ See \fBrpc\fR(3NSL) for the definition of the \fBSVCXPRT\fR data structure. .na \fB\fBsvc_control()\fR\fR .ad -.RS 21n +.RS 15n A function to change or retrieve information about a service object. \fIreq\fR indicates the type of operation and \fIinfo\fR is a pointer to the information. The supported values of \fIreq\fR, their argument types, and what they do are: @@ -97,7 +107,7 @@ The supported values of \fIreq\fR, their argument types, and what they do are: .na \fB\fBSVCGET_VERSQUIET\fR\fR .ad -.RS 25n +.RS 10n If a request is received for a program number served by this server but the version number is outside the range registered with the server, an \fBRPC_PROGVERSMISMATCH\fR error will normally be returned. \fIinfo\fR should @@ -113,7 +123,7 @@ behavior, that is, an \fBRPC_PROGVERSMISMATCH\fR error will be returned. .na \fB\fBSVCSET_VERSQUIET\fR\fR .ad -.RS 25n +.RS 10n If a request is received for a program number served by this server but the version number is outside the range registered with the server, an \fBRPC_PROGVERSMISMATCH\fR error will normally be returned. It is sometimes @@ -128,7 +138,7 @@ the out of range request should be silently ignored. .na \fB\fBSVCGET_XID\fR\fR .ad -.RS 25n +.RS 10n Returns the transaction \fBID\fR of connection\(mioriented and connectionless transport service calls. The transaction \fBID\fR assists in uniquely identifying client requests for a given \fBRPC\fR version, program number, @@ -148,7 +158,7 @@ of rendezvous or raw type, and the request is of type \fBSVCGET_XID,\fR .na \fB\fBSVCSET_RECVERRHANDLER\fR\fR .ad -.RS 25n +.RS 10n Attaches or detaches a disconnection handler to the service handle, \fIsvc\fR, that will be called when a transport error arrives during the reception of a request or when the server is waiting for a request and the connection shuts @@ -177,7 +187,7 @@ MT-safe way. .na \fB\fBSVCGET_RECVERRHANDLER\fR\fR .ad -.RS 25n +.RS 10n Upon successful completion of the \fBSVCGET_RECVERRHANDLER\fR request, \fI*info\fR contains the address of the handler for receiving errors. Upon failure, \fI*info\fR contains \fINULL\fR. @@ -188,7 +198,7 @@ failure, \fI*info\fR contains \fINULL\fR. .na \fB\fBSVCSET_CONNMAXREC\fR\fR .ad -.RS 25n +.RS 10n Set the maximum record size (in bytes) and enable non-blocking mode for this service handle. Value can be set and read for both connection and non-connection oriented transports, but is silently ignored for the @@ -201,7 +211,7 @@ non-connection oriented case. The \fIinfo\fR argument should be a pointer to an .na \fB\fBSVCGET_CONNMAXREC\fR\fR .ad -.RS 25n +.RS 10n Get the maximum record size for this service handle. Zero means no maximum in effect and the connection is in blocking mode. The result is not significant for non-connection oriented transports. The \fIinfo\fR argument should be a @@ -217,7 +227,7 @@ returns false. .na \fB\fBsvc_create()\fR\fR .ad -.RS 21n +.RS 15n \fBsvc_create()\fR creates server handles for all the transports belonging to the class \fInettype\fR. .sp @@ -239,7 +249,7 @@ created, otherwise it returns \fB0\fR and an error message is logged. .na \fB\fBsvc_destroy()\fR\fR .ad -.RS 21n +.RS 15n A function macro that destroys the \fBRPC\fR service handle \fIxprt\fR. Destruction usually involves deallocation of private data structures, including \fIxprt\fR itself. Use of \fIxprt\fR is undefined after calling this routine. @@ -250,7 +260,7 @@ Destruction usually involves deallocation of private data structures, including .na \fB\fBsvc_dg_create()\fR\fR .ad -.RS 21n +.RS 15n This routine creates a connectionless \fBRPC\fR service handle, and returns a pointer to it. This routine returns \fINULL\fR if it fails, and an error message is logged. \fIsendsz\fR and \fIrecvsz\fR are parameters used to specify @@ -268,7 +278,7 @@ large arguments or return huge results. .na \fB\fBsvc_fd_create()\fR\fR .ad -.RS 21n +.RS 15n This routine creates a service on top of an open and bound file descriptor, and returns the handle to it. Typically, this descriptor is a connected file descriptor for a connection-oriented transport. \fIsendsz\fR and \fIrecvsz\fR @@ -282,7 +292,7 @@ and an error message is logged. .na \fB\fBsvc_raw_create()\fR\fR .ad -.RS 21n +.RS 15n This routine creates an \fBRPC\fR service handle and returns a pointer to it. The transport is really a buffer within the process's address space, so the corresponding \fBRPC\fR client should live in the same address space; (see @@ -300,13 +310,13 @@ used. .na \fB\fBsvc_tli_create()\fR\fR .ad -.RS 21n +.RS 15n This routine creates an \fBRPC\fR server handle, and returns a pointer to it. \fIfildes\fR is the file descriptor on which the service is listening. If \fIfildes\fR is \fBRPC_ANYFD\fR, it opens a file descriptor on the transport specified by \fInetconf\fR. If the file descriptor is unbound and -\fIbindaddr\fR is non-null \fIfildes\fR is bound to the address specified by -\fIbindaddr\fR, otherwise \fIfildes\fR is bound to a default address chosen by +\fIbind_info\fR is non-null \fIfildes\fR is bound to the address specified by +\fIbind_info\fR, otherwise \fIfildes\fR is bound to a default address chosen by the transport. In the case where the default address is chosen, the number of outstanding connect requests is set to 8 for connection-oriented transports. The user may specify the size of the send and receive buffers with the @@ -321,7 +331,7 @@ service. .na \fB\fBsvc_tp_create()\fR\fR .ad -.RS 21n +.RS 15n \fBsvc_tp_create()\fR creates a server handle for the network specified by \fInetconf\fR, and registers itself with the \fBrpcbind\fR service. \fIdispatch\fR is called when there is a remote procedure call for the given @@ -333,9 +343,25 @@ service. .sp .ne 2 .na +\fB\fBsvc_tp_create_addr()\fR\fR +.ad +.RS 15n +\fBsvc_tp_create_addr()\fR creates a server handle for the network specified +by \fInetconf\fR, and registers itself with the \fBrpcbind\fR service. +If \fIbind_addr\fR is non-NULL, that address is used for the listener binding. +If \fIbind_addr\fR is NULL, this call is the same as \fBsvc_tp_create()\fR. +\fIdispatch\fR is called when there is a remote procedure call for the given +\fIprognum\fR and \fIversnum\fR; this requires calling \fBsvc_run()\fR. +\fBsvc_tp_create_addr()\fR returns the service handle if it succeeds, +otherwise a \fINULL\fR is returned and an error message is logged. +.RE + +.sp +.ne 2 +.na \fB\fBsvc_vc_create()\fR\fR .ad -.RS 21n +.RS 15n This routine creates a connection-oriented \fBRPC\fR service and returns a pointer to it. This routine returns \fINULL\fR if it fails, and an error message is logged. The users may specify the size of the send and receive @@ -349,10 +375,10 @@ bound. The server is not registered with the \fBrpcbind\fR(1M) service. .na \fB\fBsvc_door_create()\fR\fR .ad -.RS 21n +.RS 15n This routine creates an RPC server handle over doors for the given program -\fIprognum\fR and version \fIversnum\fR and returns a pointer to -it. Doors is a transport mechanism that facilitates fast data transfer between +\fIprognum\fR and version \fIversnum\fR and returns a pointer to it. +Doors is a transport mechanism that facilitates fast data transfer between processes on the same machine. The user may set the size of the send buffer with the parameter \fIsendsz\fR. If \fIsendsz\fR is 0, the corresponding default buffer size is 16 Kbyte. If successful, the diff --git a/usr/src/pkg/manifests/system-library.man3nsl.inc b/usr/src/pkg/manifests/system-library.man3nsl.inc index 0634729d47..d9b9f7475e 100644 --- a/usr/src/pkg/manifests/system-library.man3nsl.inc +++ b/usr/src/pkg/manifests/system-library.man3nsl.inc @@ -11,7 +11,7 @@ # # Copyright 2011, Richard Lowe -# Copyright 2012 Nexenta Systems, Inc. All rights reserved. +# Copyright 2017 Nexenta Systems, Inc. All rights reserved. # file path=usr/share/man/man3nsl/dial.3nsl @@ -263,6 +263,8 @@ link path=usr/share/man/man3nsl/svc_run.3nsl target=rpc_svc_calls.3nsl link path=usr/share/man/man3nsl/svc_sendreply.3nsl target=rpc_svc_calls.3nsl link path=usr/share/man/man3nsl/svc_tli_create.3nsl target=rpc_svc_create.3nsl link path=usr/share/man/man3nsl/svc_tp_create.3nsl target=rpc_svc_create.3nsl +link path=usr/share/man/man3nsl/svc_tp_create_addr.3nsl \ + target=rpc_svc_create.3nsl link path=usr/share/man/man3nsl/svc_unreg.3nsl target=rpc_svc_reg.3nsl link path=usr/share/man/man3nsl/svc_unregister.3nsl target=rpc_soc.3nsl link path=usr/share/man/man3nsl/svc_vc_create.3nsl target=rpc_svc_create.3nsl diff --git a/usr/src/uts/common/rpc/svc.h b/usr/src/uts/common/rpc/svc.h index f7f8df05db..fadf6b2609 100644 --- a/usr/src/uts/common/rpc/svc.h +++ b/usr/src/uts/common/rpc/svc.h @@ -924,6 +924,22 @@ extern SVCXPRT *svc_tp_create(void (*)(struct svc_req *, SVCXPRT *), */ /* + * Variant of svc_tp_create that accepts a binding address. + * If addr == NULL, this is the same as svc_tp_create(). + */ +extern SVCXPRT *svc_tp_create_addr(void (*)(struct svc_req *, SVCXPRT *), + const rpcprog_t, const rpcvers_t, + const struct netconfig *, + const struct netbuf *); + /* + * void (*dispatch)(); -- dispatch routine + * const rpcprog_t prognum; -- program number + * const rpcvers_t versnum; -- version number + * const struct netconfig *nconf; -- netconfig structure + * const struct netbuf *addr; -- address to bind + */ + +/* * Generic TLI create routine */ extern SVCXPRT *svc_tli_create(const int, const struct netconfig *, |