fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * CDDL HEADER START
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * The contents of this file are subject to the terms of the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Common Development and Distribution License (the "License").
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * You may not use this file except in compliance with the License.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * or http://www.opensolaris.org/os/licensing.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * See the License for the specific language governing permissions
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * and limitations under the License.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * When distributing Covered Code, include this CDDL HEADER in each
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If applicable, add the following below this CDDL HEADER, with the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * fields enclosed by brackets "[]" replaced with your own identifying
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * information: Portions Copyright [yyyy] [name of copyright owner]
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * CDDL HEADER END
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
570de38f63910201fdd77246630b7aa8f9dc5661Surya Prakki
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
570de38f63910201fdd77246630b7aa8f9dc5661Surya Prakki * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Use is subject to license terms.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
5539384561c0efe744226d5e5d331f5546e500e4Marcel Telka/*
5539384561c0efe744226d5e5d331f5546e500e4Marcel Telka * Copyright 2014 Nexenta Systems, Inc. All rights reserved.
09b0d01c5bc323b8ee7043100e09aded27cc12abGary Mills * Copyright 2014 Gary Mills
5539384561c0efe744226d5e5d331f5546e500e4Marcel Telka */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Network SNDR/ncall-ip server - based on nfsd
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/types.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <rpc/types.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <errno.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <netdb.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/socket.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <netconfig.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <stropts.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <fcntl.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <stdio.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <strings.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <signal.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <unistd.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <stdlib.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <netdir.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <rpc/rpc_com.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <rpc/rpc.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <tiuser.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <netinet/tcp.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <netinet/in.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <syslog.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <locale.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <langinfo.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <libintl.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <libgen.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <deflt.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/resource.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/nsctl/nsctl.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#ifdef __NCALL__
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/ncall/ncall.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/ncall/ncall_ip.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/nsctl/libncall.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#define RDC_POOL_CREATE NC_IOC_POOL_CREATE
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#define RDC_POOL_RUN NC_IOC_POOL_RUN
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#define RDC_POOL_WAIT NC_IOC_POOL_WAIT
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#define RDC_PROGRAM NCALL_PROGRAM
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#define RDC_SERVICE "ncall"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#undef RDC_SVCPOOL_ID /* We are overloading this value */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#define RDC_SVCPOOL_ID NCALL_SVCPOOL_ID
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#define RDC_SVC_NAME "NCALL"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#define RDC_VERS_MIN NCALL_VERS_MIN
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#define RDC_VERS_MAX NCALL_VERS_MAX
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#else /* !__NCALL__ */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/nsctl/rdc_ioctl.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/nsctl/rdc_io.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <sys/nsctl/librdc.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#define RDC_SERVICE "rdc"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#define RDC_SVC_NAME "RDC"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#endif /* __NCALL__ */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#define RDCADMIN "/etc/default/sndr"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <nsctl.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestruct conn_ind {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct conn_ind *conn_next;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct conn_ind *conn_prev;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct t_call *conn_call;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte};
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestruct conn_entry {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte bool_t closing;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct netconfig nc;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte};
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic char *progname;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic struct conn_entry *conn_polled;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int num_conns; /* Current number of connections */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic struct pollfd *poll_array; /* array of poll descriptors for poll */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic size_t num_fds = 0; /* number of transport fds opened */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void poll_for_action();
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void remove_from_poll_list(int);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int do_poll_cots_action(int, int);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int do_poll_clts_action(int, int);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void add_to_poll_list(int, struct netconfig *);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int bind_to_provider(char *, char *, struct netbuf **,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct netconfig **);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int set_addrmask(int, struct netconfig *, struct netbuf *);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void conn_close_oldest(void);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic boolean_t conn_get(int, struct netconfig *, struct conn_ind **);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void cots_listen_event(int, int);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int discon_get(int, struct netconfig *, struct conn_ind **);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int nofile_increase(int);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int is_listen_fd_index(int);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#if !defined(_SunOS_5_6) && !defined(_SunOS_5_7) && !defined(_SunOS_5_8)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int sndrsvcpool(int);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int svcwait(int id);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#endif
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * RPC protocol block. Useful for passing registration information.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestruct protob {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte char *serv; /* ASCII service name, e.g. "RDC" */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int versmin; /* minimum version no. to be registered */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int versmax; /* maximum version no. to be registered */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int program; /* program no. to be registered */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct protob *next; /* next entry on list */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte};
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic size_t end_listen_fds;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int debugflg = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int max_conns_allowed = -1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int listen_backlog = 10;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic char *trans_provider = (char *)NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int rdcsvc(int, struct netbuf, struct netconfig *);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/* used by cots_listen_event() */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int (*Mysvc)(int, struct netbuf, struct netconfig *) = rdcsvc;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Determine valid semantics for rdc.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#define OK_TPI_TYPE(_nconf) \
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (_nconf->nc_semantics == NC_TPI_CLTS || \
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte _nconf->nc_semantics == NC_TPI_COTS || \
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte _nconf->nc_semantics == NC_TPI_COTS_ORD)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#define BE32_TO_U32(a) \
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ((((uint32_t)((uchar_t *)a)[0] & 0xFF) << (uint32_t)24) |\
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (((uint32_t)((uchar_t *)a)[1] & 0xFF) << (uint32_t)16) |\
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (((uint32_t)((uchar_t *)a)[2] & 0xFF) << (uint32_t)8) |\
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ((uint32_t)((uchar_t *)a)[3] & 0xFF))
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#ifdef DEBUG
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Only support UDP in DEBUG mode for now
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic char *defaultproviders[] = { "/dev/tcp", "/dev/tcp6", "/dev/udp",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "/dev/udp6", NULL };
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#else
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic char *defaultproviders[] = { "/dev/tcp6", "/dev/tcp", NULL };
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#endif
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Number of elements to add to the poll array on each allocation.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#define POLL_ARRAY_INC_SIZE 64
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#define NOFILE_INC_SIZE 64
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#ifdef __NCALL__
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteconst char *rdc_devr = "/dev/ncallip";
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#else
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteconst char *rdc_devr = "/dev/rdc";
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#endif
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int rdc_fdr;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteopen_rdc(void)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int fd = open(rdc_devr, O_RDONLY);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fd < 0)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (-1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (rdc_fdr = fd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortesndrsys(int type, void *arg)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int ret = -1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!rdc_fdr && open_rdc() < 0) { /* open failed */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte syslog(LOG_ERR, "open_rdc() failed: %m\n");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((ret = ioctl(rdc_fdr, type, arg)) < 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte syslog(LOG_ERR, "ioctl(rdc_ioctl) failed: %m\n");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (ret);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteint
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forterdc_transport_open(struct netconfig *nconf)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int fd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct strioctl strioc;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((nconf == (struct netconfig *)NULL) ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (nconf->nc_device == (char *)NULL)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte syslog(LOG_ERR, "No netconfig device");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (-1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Open the transport device.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fd = t_open(nconf->nc_device, O_RDWR, (struct t_info *)NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fd == -1) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (t_errno == TSYSERR && errno == EMFILE &&
5539384561c0efe744226d5e5d331f5546e500e4Marcel Telka (nofile_increase(0) == 0)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Try again with a higher NOFILE limit. */
5539384561c0efe744226d5e5d331f5546e500e4Marcel Telka fd = t_open(nconf->nc_device, O_RDWR, NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fd == -1) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (t_errno == TSYSERR) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte syslog(LOG_ERR, "t_open failed: %m");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte syslog(LOG_ERR, "t_open failed: %s",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte t_errlist[t_errno]);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (-1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Pop timod because the RPC module must be as close as possible
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * to the transport.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ioctl(fd, I_POP, 0) < 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte syslog(LOG_ERR, "I_POP of timod failed: %m");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (t_close(fd) == -1) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (t_errno == TSYSERR) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte syslog(LOG_ERR, "t_close failed on %d: %m", fd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte syslog(LOG_ERR, "t_close failed on %d: %s",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fd, t_errlist[t_errno]);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (-1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (nconf->nc_semantics == NC_TPI_CLTS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Push rpcmod to filter data traffic to KRPC.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ioctl(fd, I_PUSH, "rpcmod") < 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte syslog(LOG_ERR, "I_PUSH of rpcmod failed: %m");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) t_close(fd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (-1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ioctl(fd, I_PUSH, "rpcmod") < 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte syslog(LOG_ERR, "I_PUSH of CONS rpcmod failed: %m");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (t_close(fd) == -1) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (t_errno == TSYSERR) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte syslog(LOG_ERR,
5539384561c0efe744226d5e5d331f5546e500e4Marcel Telka "t_close failed on %d: %m", fd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte syslog(LOG_ERR,
5539384561c0efe744226d5e5d331f5546e500e4Marcel Telka "t_close failed on %d: %s",
5539384561c0efe744226d5e5d331f5546e500e4Marcel Telka fd, t_errlist[t_errno]);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (-1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte strioc.ic_cmd = RPC_SERVER;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte strioc.ic_dp = (char *)0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte strioc.ic_len = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte strioc.ic_timout = -1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Tell CONS rpcmod to act like a server stream. */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ioctl(fd, I_STR, &strioc) < 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte syslog(LOG_ERR, "CONS rpcmod set-up ioctl failed: %m");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (t_close(fd) == -1) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (t_errno == TSYSERR) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte syslog(LOG_ERR,
5539384561c0efe744226d5e5d331f5546e500e4Marcel Telka "t_close failed on %d: %m", fd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte syslog(LOG_ERR,
5539384561c0efe744226d5e5d331f5546e500e4Marcel Telka "t_close failed on %d: %s",
5539384561c0efe744226d5e5d331f5546e500e4Marcel Telka fd, t_errlist[t_errno]);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (-1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Re-push timod so that we will still be doing TLI
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * operations on the descriptor.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ioctl(fd, I_PUSH, "timod") < 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte syslog(LOG_ERR, "I_PUSH of timod failed: %m");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (t_close(fd) == -1) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (t_errno == TSYSERR) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte syslog(LOG_ERR, "t_close failed on %d: %m", fd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte syslog(LOG_ERR, "t_close failed on %d: %s",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fd, t_errlist[t_errno]);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (-1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (fd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortevoid
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forterdcd_log_tli_error(char *tli_name, int fd, struct netconfig *nconf)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int error;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Save the error code across syslog(), just in case syslog()
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * gets its own error and, therefore, overwrites errno.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte error = errno;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (t_errno == TSYSERR) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte syslog(LOG_ERR, "%s(file descriptor %d/transport %s) %m",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tli_name, fd, nconf->nc_proto);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte syslog(LOG_ERR,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "%s(file descriptor %d/transport %s) TLI error %d",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tli_name, fd, nconf->nc_proto, t_errno);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte errno = error;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Called to set up service over a particular transport
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortevoid
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortedo_one(char *provider, char *proto, struct protob *protobp0,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int (*svc)(int, struct netbuf, struct netconfig *))
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct netbuf *retaddr;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct netconfig *retnconf;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct netbuf addrmask;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int vers;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int sock;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (provider) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sock = bind_to_provider(provider, protobp0->serv, &retaddr,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte &retnconf);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) syslog(LOG_ERR,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "Cannot establish %s service over %s: transport setup problem.",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte protobp0->serv, provider ? provider : proto);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (sock == -1) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((Is_ipv6present() &&
5539384561c0efe744226d5e5d331f5546e500e4Marcel Telka (strcmp(provider, "/dev/tcp6") == 0)) ||
5539384561c0efe744226d5e5d331f5546e500e4Marcel Telka (!Is_ipv6present() && (strcmp(provider, "/dev/tcp") == 0)))
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) syslog(LOG_ERR,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "Cannot establish %s service over %s: transport "
5539384561c0efe744226d5e5d331f5546e500e4Marcel Telka "setup problem.",
5539384561c0efe744226d5e5d331f5546e500e4Marcel Telka protobp0->serv, provider ? provider : proto);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (set_addrmask(sock, retnconf, &addrmask) < 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) syslog(LOG_ERR,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "Cannot set address mask for %s", retnconf->nc_netid);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Register all versions of the programs in the protocol block list
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (vers = protobp0->versmin; vers <= protobp0->versmax; vers++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) rpcb_unset(protobp0->program, vers, retnconf);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) rpcb_set(protobp0->program, vers, retnconf, retaddr);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (retnconf->nc_semantics == NC_TPI_CLTS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Don't drop core if supporting module(s) aren't loaded. */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) signal(SIGSYS, SIG_IGN);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * svc() doesn't block, it returns success or failure.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((*svc)(sock, addrmask, retnconf) < 0) {
5539384561c0efe744226d5e5d331f5546e500e4Marcel Telka (void) syslog(LOG_ERR, "Cannot establish %s service "
5539384561c0efe744226d5e5d331f5546e500e4Marcel Telka "over <file desc. %d, protocol %s> : %m. Exiting",
5539384561c0efe744226d5e5d331f5546e500e4Marcel Telka protobp0->serv, sock, retnconf->nc_proto);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte exit(1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * We successfully set up the server over this transport.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Add this descriptor to the one being polled on.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte add_to_poll_list(sock, retnconf);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Set up the SNDR/ncall-ip service over all the available transports.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Returns -1 for failure, 0 for success.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteint
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortedo_all(struct protob *protobp,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int (*svc)(int, struct netbuf, struct netconfig *))
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct netconfig *nconf;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte NCONF_HANDLE *nc;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((nc = setnetconfig()) == (NCONF_HANDLE *)NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte syslog(LOG_ERR, "setnetconfig failed: %m");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (-1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while (nconf = getnetconfig(nc)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((nconf->nc_flag & NC_VISIBLE) &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte strcmp(nconf->nc_protofmly, "loopback") != 0 &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte OK_TPI_TYPE(nconf))
5539384561c0efe744226d5e5d331f5546e500e4Marcel Telka do_one(nconf->nc_device, nconf->nc_proto, protobp, svc);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) endnetconfig(nc);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Read the /etc/default/sndr configuration file to determine if the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * client has been configured for number of threads, backlog or transport
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * provider.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteread_default(void)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte char *defval, *tmp_str;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int errno;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int tmp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Fail silently if error in opening the default rdc config file */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((defopen(RDCADMIN)) == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((defval = defread("SNDR_THREADS=")) != NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte errno = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tmp = strtol(defval, (char **)NULL, 10);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (errno == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte max_conns_allowed = tmp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((defval = defread("SNDR_LISTEN_BACKLOG=")) != NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte errno = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tmp = strtol(defval, (char **)NULL, 10);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (errno == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte listen_backlog = tmp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((defval = defread("SNDR_TRANSPORT=")) != NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte errno = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tmp_str = strdup(defval);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (errno == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte trans_provider = tmp_str;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* close defaults file */
570de38f63910201fdd77246630b7aa8f9dc5661Surya Prakki (void) defopen(NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#ifdef lint
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteint
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortesndrd_lintmain(int ac, char **av)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#else
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteint
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortemain(int ac, char **av)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#endif
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte const char *dir = "/";
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int allflag = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int pid;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int i, rc;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct protob *protobp0, *protobp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte char **providerp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte char *required;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#if !defined(_SunOS_5_6) && !defined(_SunOS_5_7) && !defined(_SunOS_5_8)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int maxservers;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#endif
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) setlocale(LC_ALL, "");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#ifdef __NCALL__
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) textdomain("ncall");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#else
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) textdomain("rdc");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#endif
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte progname = basename(av[0]);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#ifdef __NCALL__
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rc = ncall_check_release(&required);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#else
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rc = rdc_check_release(&required);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#endif
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rc < 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) fprintf(stderr,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte gettext("%s: unable to determine the current "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "Solaris release: %s\n"), progname, strerror(errno));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte exit(1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else if (rc == FALSE) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) fprintf(stderr,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte gettext("%s: incorrect Solaris release (requires %s)\n"),
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte progname, required);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte exit(1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte openlog(progname, LOG_PID|LOG_CONS, LOG_DAEMON);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte read_default();
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Usage: <progname> [-c <number of threads>] [-t protocol] \
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * [-d] [-l <listen backlog>]
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while ((i = getopt(ac, av, "ac:t:dl:")) != EOF) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte switch (i) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case 'a':
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte allflag = 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case 'c':
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte max_conns_allowed = atoi(optarg);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (max_conns_allowed <= 0)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte max_conns_allowed = 16;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case 'd':
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte debugflg++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case 't':
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte trans_provider = optarg;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case 'l':
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte listen_backlog = atoi(optarg);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (listen_backlog < 0)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte listen_backlog = 32;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte default:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte syslog(LOG_ERR,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "Usage: %s [-c <number of threads>] "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "[-d] [-t protocol] "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "[-l <listen backlog>]\n", progname);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte exit(1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (chroot(dir) < 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte syslog(LOG_ERR, "chroot failed: %m");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte exit(1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (chdir(dir) < 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte syslog(LOG_ERR, "chdir failed: %m");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte exit(1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!debugflg) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte pid = fork();
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pid < 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte syslog(LOG_ERR, "Fork failed\n");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte exit(1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (pid != 0)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte exit(0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Close existing file descriptors, open "/dev/null" as
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * standard input, output, and error, and detach from
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * controlling terminal.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#if !defined(_SunOS_5_6) && !defined(_SunOS_5_7) && !defined(_SunOS_5_8)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* use closefrom(3C) from PSARC/2000/193 when possible */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte closefrom(0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#else
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (i = 0; i < _NFILE; i++)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) close(i);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#endif
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) open("/dev/null", O_RDONLY);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) open("/dev/null", O_WRONLY);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) dup(1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) setsid();
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * ignore all signals apart from SIGTERM.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (i = 1; i < _sys_nsig; i++)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) sigset(i, SIG_IGN);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) sigset(SIGTERM, SIG_DFL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#if !defined(_SunOS_5_6) && !defined(_SunOS_5_7) && !defined(_SunOS_5_8)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Set up kernel RPC thread pool for the SNDR/ncall-ip server.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte maxservers = (max_conns_allowed < 0 ? 16 : max_conns_allowed);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (sndrsvcpool(maxservers)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) syslog(LOG_ERR,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "Can't set up kernel %s service: %m. Exiting", progname);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte exit(1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Set up blocked thread to do LWP creation on behalf of the kernel.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (svcwait(RDC_SVCPOOL_ID)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) syslog(LOG_ERR,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "Can't set up %s pool creator: %m, Exiting", progname);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte exit(1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#endif
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Build a protocol block list for registration.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte protobp0 = protobp = (struct protob *)malloc(sizeof (struct protob));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte protobp->serv = RDC_SVC_NAME;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte protobp->versmin = RDC_VERS_MIN;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte protobp->versmax = RDC_VERS_MAX;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte protobp->program = RDC_PROGRAM;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte protobp->next = (struct protob *)NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (allflag) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (do_all(protobp0, rdcsvc) == -1)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte exit(1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else if (trans_provider)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte do_one(trans_provider, NULL, protobp0, rdcsvc);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (providerp = defaultproviders;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *providerp != NULL; providerp++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte trans_provider = *providerp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte do_one(trans_provider, NULL, protobp0, rdcsvc);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortedone:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte free(protobp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte end_listen_fds = num_fds;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Poll for non-data control events on the transport descriptors.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte poll_for_action();
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte syslog(LOG_ERR, "%s fatal server error\n", progname);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (-1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortereuseaddr(int fd)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct t_optmgmt req, resp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct opthdr *opt;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte char reqbuf[128];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int *ip;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* LINTED pointer alignment */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte opt = (struct opthdr *)reqbuf;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte opt->level = SOL_SOCKET;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte opt->name = SO_REUSEADDR;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte opt->len = sizeof (int);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* LINTED pointer alignment */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ip = (int *)&reqbuf[sizeof (struct opthdr)];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *ip = 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte req.flags = T_NEGOTIATE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte req.opt.len = sizeof (struct opthdr) + opt->len;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte req.opt.buf = (char *)opt;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte resp.flags = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte resp.opt.buf = reqbuf;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte resp.opt.maxlen = sizeof (reqbuf);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (t_optmgmt(fd, &req, &resp) < 0 || resp.flags != T_SUCCESS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (t_errno == TSYSERR) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte syslog(LOG_ERR, "reuseaddr() t_optmgmt failed: %m\n");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte syslog(LOG_ERR, "reuseaddr() t_optmgmt failed: %s\n",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte t_errlist[t_errno]);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (-1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * poll on the open transport descriptors for events and errors.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortevoid
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortepoll_for_action(void)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int nfds;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int i;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Keep polling until all transports have been closed. When this
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * happens, we return.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while ((int)num_fds > 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nfds = poll(poll_array, num_fds, INFTIM);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte switch (nfds) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case 0:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte continue;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case -1:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Some errors from poll could be
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * due to temporary conditions, and we try to
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * be robust in the face of them. Other
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * errors (should never happen in theory)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * are fatal (eg. EINVAL, EFAULT).
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte switch (errno) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case EINTR:
5539384561c0efe744226d5e5d331f5546e500e4Marcel Telka continue;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case EAGAIN:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case ENOMEM:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) sleep(10);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte continue;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte default:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) syslog(LOG_ERR,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "poll failed: %m. Exiting");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte exit(1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte default:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Go through the poll list looking for events.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (i = 0; i < num_fds && nfds > 0; i++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (poll_array[i].revents) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nfds--;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * We have a message, so try to read it.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Record the error return in errno,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * so that syslog(LOG_ERR, "...%m")
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * dumps the corresponding error string.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (conn_polled[i].nc.nc_semantics ==
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte NC_TPI_CLTS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte errno = do_poll_clts_action(
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte poll_array[i].fd, i);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte errno = do_poll_cots_action(
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte poll_array[i].fd, i);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (errno == 0)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte continue;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Most returned error codes mean that there is
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * fatal condition which we can only deal with
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * by closing the transport.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (errno != EAGAIN && errno != ENOMEM) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) syslog(LOG_ERR,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "Error (%m) reading descriptor %d"
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "/transport %s. Closing it.",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte poll_array[i].fd,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte conn_polled[i].nc.nc_proto);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) t_close(poll_array[i].fd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte remove_from_poll_list(poll_array[i].fd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else if (errno == ENOMEM)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) sleep(5);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) syslog(LOG_ERR,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "All transports have been closed with errors. Exiting.");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Allocate poll/transport array entries for this descriptor.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteadd_to_poll_list(int fd, struct netconfig *nconf)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte static int poll_array_size = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If the arrays are full, allocate new ones.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (num_fds == poll_array_size) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct pollfd *tpa;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct conn_entry *tnp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (poll_array_size != 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tpa = poll_array;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tnp = conn_polled;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tpa = (struct pollfd *)0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte poll_array_size += POLL_ARRAY_INC_SIZE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Allocate new arrays.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte poll_array = (struct pollfd *)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte malloc(poll_array_size * sizeof (struct pollfd) + 256);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte conn_polled = (struct conn_entry *)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte malloc(poll_array_size * sizeof (struct conn_entry) + 256);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (poll_array == (struct pollfd *)NULL ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte conn_polled == (struct conn_entry *)NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte syslog(LOG_ERR, "malloc failed for poll array");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte exit(1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Copy the data of the old ones into new arrays, and
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * free the old ones.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * num_fds is guaranteed to be less than
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * poll_array_size, so this memcpy is safe.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (tpa) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) memcpy((void *)poll_array, (void *)tpa,
5539384561c0efe744226d5e5d331f5546e500e4Marcel Telka num_fds * sizeof (struct pollfd));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) memcpy((void *)conn_polled, (void *)tnp,
5539384561c0efe744226d5e5d331f5546e500e4Marcel Telka num_fds * sizeof (struct conn_entry));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte free((void *)tpa);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte free((void *)tnp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Set the descriptor and event list. All possible events are
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * polled for.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte poll_array[num_fds].fd = fd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte poll_array[num_fds].events = POLLIN|POLLRDNORM|POLLRDBAND|POLLPRI;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Copy the transport data over too.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte conn_polled[num_fds].nc = *nconf; /* structure copy */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte conn_polled[num_fds].closing = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Set the descriptor to non-blocking. Avoids a race
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * between data arriving on the stream and then having it
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * flushed before we can read it.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (fcntl(fd, F_SETFL, O_NONBLOCK) == -1) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) syslog(LOG_ERR,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "fcntl(file desc. %d/transport %s, F_SETFL, "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "O_NONBLOCK): %m. Exiting",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte num_fds, nconf->nc_proto);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte exit(1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Count this descriptor.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ++num_fds;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteremove_from_poll_list(int fd)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int i;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int num_to_copy;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (i = 0; i < num_fds; i++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (poll_array[i].fd == fd) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte --num_fds;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte num_to_copy = num_fds - i;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) memcpy((void *)&poll_array[i],
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void *)&poll_array[i+1],
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte num_to_copy * sizeof (struct pollfd));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) memset((void *)&poll_array[num_fds], 0,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (struct pollfd));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) memcpy((void *)&conn_polled[i],
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void *)&conn_polled[i+1],
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte num_to_copy * sizeof (struct conn_entry));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) memset((void *)&conn_polled[num_fds], 0,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte sizeof (struct conn_entry));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte syslog(LOG_ERR, "attempt to remove nonexistent fd from poll list");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteconn_close_oldest(void)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int fd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int i1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Find the oldest connection that is not already in the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * process of shutting down.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (i1 = end_listen_fds; /* no conditional expression */; i1++) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (i1 >= num_fds)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (conn_polled[i1].closing == 0)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#ifdef DEBUG
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) printf("too many connections (%d), releasing oldest (%d)\n",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte num_conns, poll_array[i1].fd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#else
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte syslog(LOG_WARNING, "too many connections (%d), releasing oldest (%d)",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte num_conns, poll_array[i1].fd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#endif
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte fd = poll_array[i1].fd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (conn_polled[i1].nc.nc_semantics == NC_TPI_COTS) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * For politeness, send a T_DISCON_REQ to the transport
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * provider. We close the stream anyway.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) t_snddis(fd, (struct t_call *)0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte num_conns--;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte remove_from_poll_list(fd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) t_close(fd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * For orderly release, we do not close the stream
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * until the T_ORDREL_IND arrives to complete
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the handshake.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (t_sndrel(fd) == 0)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte conn_polled[i1].closing = 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic boolean_t
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteconn_get(int fd, struct netconfig *nconf, struct conn_ind **connp)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct conn_ind *conn;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct conn_ind *next_conn;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte conn = (struct conn_ind *)malloc(sizeof (*conn));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (conn == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte syslog(LOG_ERR, "malloc for listen indication failed");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (FALSE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* LINTED pointer alignment */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte conn->conn_call = (struct t_call *)t_alloc(fd, T_CALL, T_ALL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (conn->conn_call == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte free((char *)conn);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rdcd_log_tli_error("t_alloc", fd, nconf);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (FALSE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (t_listen(fd, conn->conn_call) == -1) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rdcd_log_tli_error("t_listen", fd, nconf);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) t_free((char *)conn->conn_call, T_CALL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte free((char *)conn);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (FALSE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (conn->conn_call->udata.len > 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte syslog(LOG_WARNING,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "rejecting inbound connection(%s) with %d bytes "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "of connect data",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nconf->nc_proto, conn->conn_call->udata.len);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte conn->conn_call->udata.len = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) t_snddis(fd, conn->conn_call);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) t_free((char *)conn->conn_call, T_CALL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte free((char *)conn);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (FALSE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((next_conn = *connp) != NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte next_conn->conn_prev->conn_next = conn;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte conn->conn_next = next_conn;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte conn->conn_prev = next_conn->conn_prev;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte next_conn->conn_prev = conn;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte conn->conn_next = conn;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte conn->conn_prev = conn;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *connp = conn;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (TRUE);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortediscon_get(int fd, struct netconfig *nconf, struct conn_ind **connp)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct conn_ind *conn;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct t_discon discon;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte discon.udata.buf = (char *)0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte discon.udata.maxlen = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (t_rcvdis(fd, &discon) == -1) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rdcd_log_tli_error("t_rcvdis", fd, nconf);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (-1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte conn = *connp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (conn == NULL)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte do {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (conn->conn_call->sequence == discon.sequence) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (conn->conn_next == conn)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *connp = (struct conn_ind *)0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (conn == *connp) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *connp = conn->conn_next;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte conn->conn_next->conn_prev = conn->conn_prev;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte conn->conn_prev->conn_next = conn->conn_next;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte free((char *)conn);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte conn = conn->conn_next;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } while (conn != *connp);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortecots_listen_event(int fd, int conn_index)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct t_call *call;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct conn_ind *conn;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct conn_ind *conn_head;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int event;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct netconfig *nconf = &conn_polled[conn_index].nc;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int new_fd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct netbuf addrmask;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int ret = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
5539384561c0efe744226d5e5d331f5546e500e4Marcel Telka conn_head = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) conn_get(fd, nconf, &conn_head);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while ((conn = conn_head) != NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte conn_head = conn->conn_next;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (conn_head == conn)
5539384561c0efe744226d5e5d331f5546e500e4Marcel Telka conn_head = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte conn_head->conn_prev = conn->conn_prev;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte conn->conn_prev->conn_next = conn_head;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte call = conn->conn_call;
5539384561c0efe744226d5e5d331f5546e500e4Marcel Telka free(conn);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If we have already accepted the maximum number of
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * connections allowed on the command line, then drop
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the oldest connection (for any protocol) before
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * accepting the new connection. Unless explicitly
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * set on the command line, max_conns_allowed is -1.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (max_conns_allowed != -1 && num_conns >= max_conns_allowed)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte conn_close_oldest();
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Create a new transport endpoint for the same proto as
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the listener.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte new_fd = rdc_transport_open(nconf);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (new_fd == -1) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte call->udata.len = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) t_snddis(fd, call);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) t_free((char *)call, T_CALL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte syslog(LOG_ERR, "Cannot establish transport over %s",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nconf->nc_device);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte continue;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Bind to a generic address/port for the accepting stream. */
5539384561c0efe744226d5e5d331f5546e500e4Marcel Telka if (t_bind(new_fd, NULL, NULL) == -1) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rdcd_log_tli_error("t_bind", new_fd, nconf);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte call->udata.len = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) t_snddis(fd, call);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) t_free((char *)call, T_CALL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) t_close(new_fd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte continue;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while (t_accept(fd, new_fd, call) == -1) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (t_errno != TLOOK) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rdcd_log_tli_error("t_accept", fd, nconf);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte call->udata.len = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) t_snddis(fd, call);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) t_free((char *)call, T_CALL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) t_close(new_fd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto do_next_conn;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while (event = t_look(fd)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte switch (event) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case T_LISTEN:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) conn_get(fd, nconf, &conn_head);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte continue;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case T_DISCONNECT:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) discon_get(fd, nconf,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte &conn_head);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte continue;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte default:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte syslog(LOG_ERR,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "unexpected event 0x%x during "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "accept processing (%s)",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte event, nconf->nc_proto);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte call->udata.len = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) t_snddis(fd, call);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) t_free((char *)call, T_CALL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) t_close(new_fd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto do_next_conn;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (set_addrmask(new_fd, nconf, &addrmask) < 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) syslog(LOG_ERR, "Cannot set address mask for %s",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nconf->nc_netid);
5539384561c0efe744226d5e5d331f5546e500e4Marcel Telka (void) t_snddis(new_fd, NULL);
5539384561c0efe744226d5e5d331f5546e500e4Marcel Telka (void) t_free((char *)call, T_CALL);
5539384561c0efe744226d5e5d331f5546e500e4Marcel Telka (void) t_close(new_fd);
5539384561c0efe744226d5e5d331f5546e500e4Marcel Telka continue;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
5539384561c0efe744226d5e5d331f5546e500e4Marcel Telka /* Tell kRPC about the new stream. */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ret = (*Mysvc)(new_fd, addrmask, nconf);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ret < 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte syslog(LOG_ERR,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "unable to register with kernel rpc: %m");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte free(addrmask.buf);
5539384561c0efe744226d5e5d331f5546e500e4Marcel Telka (void) t_snddis(new_fd, NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) t_free((char *)call, T_CALL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) t_close(new_fd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto do_next_conn;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte free(addrmask.buf);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) t_free((char *)call, T_CALL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Poll on the new descriptor so that we get disconnect
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * and orderly release indications.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte num_conns++;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte add_to_poll_list(new_fd, nconf);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Reset nconf in case it has been moved. */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nconf = &conn_polled[conn_index].nc;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortedo_next_conn:;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortedo_poll_cots_action(int fd, int conn_index)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte char buf[256];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int event;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int i1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int flags;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct conn_entry *connent = &conn_polled[conn_index];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct netconfig *nconf = &(connent->nc);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte const char *errorstr;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while (event = t_look(fd)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte switch (event) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case T_LISTEN:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte cots_listen_event(fd, conn_index);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case T_DATA:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Receive a private notification from CONS rpcmod.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte i1 = t_rcv(fd, buf, sizeof (buf), &flags);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (i1 == -1) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte syslog(LOG_ERR, "t_rcv failed");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (i1 < sizeof (int))
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte i1 = BE32_TO_U32(buf);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (i1 == 1 || i1 == 2) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * This connection has been idle for too long,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * so release it as politely as we can. If we
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * have already initiated an orderly release
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * and we get notified that the stream is
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * still idle, pull the plug. This prevents
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * hung connections from continuing to consume
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * resources.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (nconf->nc_semantics == NC_TPI_COTS ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte connent->closing != 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) t_snddis(fd, (struct t_call *)0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto fdclose;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * For NC_TPI_COTS_ORD, the stream is closed
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * and removed from the poll list when the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * T_ORDREL is received from the provider. We
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * don't wait for it here because it may take
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * a while for the transport to shut down.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (t_sndrel(fd) == -1) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte syslog(LOG_ERR,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "unable to send orderly release %m");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte connent->closing = 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte syslog(LOG_ERR,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "unexpected event from CONS rpcmod %d", i1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case T_ORDREL:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* Perform an orderly release. */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (t_rcvrel(fd) == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* T_ORDREL on listen fd's should be ignored */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!is_listen_fd_index(fd)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) t_sndrel(fd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto fdclose;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else if (t_errno == TLOOK) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rdcd_log_tli_error("t_rcvrel", fd, nconf);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * check to make sure we do not close
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * listen fd
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!is_listen_fd_index(fd))
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte else
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto fdclose;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case T_DISCONNECT:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (t_rcvdis(fd, (struct t_discon *)NULL) == -1)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rdcd_log_tli_error("t_rcvdis", fd, nconf);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * T_DISCONNECT on listen fd's should be ignored.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (!is_listen_fd_index(fd))
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte else
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto fdclose;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte default:
09b0d01c5bc323b8ee7043100e09aded27cc12abGary Mills if (t_errno == TSYSERR) {
5539384561c0efe744226d5e5d331f5546e500e4Marcel Telka if ((errorstr = strerror(errno)) == NULL) {
5539384561c0efe744226d5e5d331f5546e500e4Marcel Telka (void) snprintf(buf, sizeof (buf),
5539384561c0efe744226d5e5d331f5546e500e4Marcel Telka "Unknown error num %d", errno);
5539384561c0efe744226d5e5d331f5546e500e4Marcel Telka errorstr = (const char *)buf;
5539384561c0efe744226d5e5d331f5546e500e4Marcel Telka }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else if (event == -1)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte errorstr = t_strerror(t_errno);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte else
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte errorstr = "";
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#ifdef DEBUG
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte syslog(LOG_ERR,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "unexpected TLI event (0x%x) on "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "connection-oriented transport(%s, %d):%s",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte event, nconf->nc_proto, fd, errorstr);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#endif
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortefdclose:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte num_conns--;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte remove_from_poll_list(fd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) t_close(fd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Called to read and interpret the event on a connectionless descriptor.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Returns 0 if successful, or a UNIX error code if failure.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortedo_poll_clts_action(int fd, int conn_index)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int error;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int ret;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int flags;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct netconfig *nconf = &conn_polled[conn_index].nc;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte static struct t_unitdata *unitdata = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte static struct t_uderr *uderr = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte static int oldfd = -1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct nd_hostservlist *host = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct strbuf ctl[1], data[1];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * We just need to have some space to consume the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * message in the event we can't use the TLI interface to do the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * job.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * We flush the message using getmsg(). For the control part
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * we allocate enough for any TPI header plus 32 bytes for address
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * and options. For the data part, there is nothing magic about
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the size of the array, but 256 bytes is probably better than
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * 1 byte, and we don't expect any data portion anyway.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If the array sizes are too small, we handle this because getmsg()
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * (called to consume the message) will return MOREDATA|MORECTL.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Thus we just call getmsg() until it's read the message.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte char ctlbuf[sizeof (union T_primitives) + 32];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte char databuf[256];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If this is the same descriptor as the last time
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * do_poll_clts_action was called, we can save some
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * de-allocation and allocation.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (oldfd != fd) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte oldfd = fd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (unitdata) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) t_free((char *)unitdata, T_UNITDATA);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte unitdata = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (uderr) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) t_free((char *)uderr, T_UDERROR);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uderr = NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Allocate a unitdata structure for receiving the event.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (unitdata == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* LINTED pointer alignment */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte unitdata = (struct t_unitdata *)t_alloc(fd, T_UNITDATA, T_ALL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (unitdata == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (t_errno == TSYSERR) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Save the error code across
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * syslog(), just in case
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * syslog() gets its own error
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * and therefore overwrites errno.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte error = errno;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) syslog(LOG_ERR,
5539384561c0efe744226d5e5d331f5546e500e4Marcel Telka "t_alloc(file descriptor %d/transport %s, "
5539384561c0efe744226d5e5d331f5546e500e4Marcel Telka "T_UNITDATA) failed: %m",
5539384561c0efe744226d5e5d331f5546e500e4Marcel Telka fd, nconf->nc_proto);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (error);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
5539384561c0efe744226d5e5d331f5546e500e4Marcel Telka (void) syslog(LOG_ERR, "t_alloc(file descriptor %d/"
5539384561c0efe744226d5e5d331f5546e500e4Marcel Telka "transport %s, T_UNITDATA) failed TLI error %d",
5539384561c0efe744226d5e5d331f5546e500e4Marcel Telka fd, nconf->nc_proto, t_errno);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto flush_it;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortetry_again:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte flags = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * The idea is we wait for T_UNITDATA_IND's. Of course,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * we don't get any, because rpcmod filters them out.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * However, we need to call t_rcvudata() to let TLI
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * tell us we have a T_UDERROR_IND.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * algorithm is:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * t_rcvudata(), expecting TLOOK.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * t_look(), expecting T_UDERR.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * t_rcvuderr(), expecting success (0).
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * expand destination address into ASCII,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * and dump it.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ret = t_rcvudata(fd, unitdata, &flags);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ret == 0 || t_errno == TBUFOVFLW) {
5539384561c0efe744226d5e5d331f5546e500e4Marcel Telka (void) syslog(LOG_WARNING, "t_rcvudata(file descriptor %d/"
5539384561c0efe744226d5e5d331f5546e500e4Marcel Telka "transport %s) got unexpected data, %d bytes",
5539384561c0efe744226d5e5d331f5546e500e4Marcel Telka fd, nconf->nc_proto, unitdata->udata.len);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Even though we don't expect any data, in case we do,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * keep reading until there is no more.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (flags & T_MORE)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto try_again;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte switch (t_errno) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case TNODATA:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case TSYSERR:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * System errors are returned to caller.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Save the error code across
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * syslog(), just in case
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * syslog() gets its own error
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * and therefore overwrites errno.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte error = errno;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) syslog(LOG_ERR,
5539384561c0efe744226d5e5d331f5546e500e4Marcel Telka "t_rcvudata(file descriptor %d/transport %s) %m",
5539384561c0efe744226d5e5d331f5546e500e4Marcel Telka fd, nconf->nc_proto);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (error);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case TLOOK:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte default:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) syslog(LOG_ERR,
5539384561c0efe744226d5e5d331f5546e500e4Marcel Telka "t_rcvudata(file descriptor %d/transport %s) TLI error %d",
5539384561c0efe744226d5e5d331f5546e500e4Marcel Telka fd, nconf->nc_proto, t_errno);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto flush_it;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ret = t_look(fd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte switch (ret) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case 0:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case -1:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * System errors are returned to caller.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (t_errno == TSYSERR) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Save the error code across
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * syslog(), just in case
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * syslog() gets its own error
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * and therefore overwrites errno.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte error = errno;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) syslog(LOG_ERR,
5539384561c0efe744226d5e5d331f5546e500e4Marcel Telka "t_look(file descriptor %d/transport %s) %m",
5539384561c0efe744226d5e5d331f5546e500e4Marcel Telka fd, nconf->nc_proto);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (error);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) syslog(LOG_ERR,
5539384561c0efe744226d5e5d331f5546e500e4Marcel Telka "t_look(file descriptor %d/transport %s) TLI error %d",
5539384561c0efe744226d5e5d331f5546e500e4Marcel Telka fd, nconf->nc_proto, t_errno);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto flush_it;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case T_UDERR:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte default:
5539384561c0efe744226d5e5d331f5546e500e4Marcel Telka (void) syslog(LOG_WARNING, "t_look(file descriptor %d/"
5539384561c0efe744226d5e5d331f5546e500e4Marcel Telka "transport %s) returned %d not T_UDERR (%d)",
5539384561c0efe744226d5e5d331f5546e500e4Marcel Telka fd, nconf->nc_proto, ret, T_UDERR);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (uderr == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* LINTED pointer alignment */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte uderr = (struct t_uderr *)t_alloc(fd, T_UDERROR, T_ALL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (uderr == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (t_errno == TSYSERR) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Save the error code across
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * syslog(), just in case
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * syslog() gets its own error
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * and therefore overwrites errno.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte error = errno;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) syslog(LOG_ERR,
5539384561c0efe744226d5e5d331f5546e500e4Marcel Telka "t_alloc(file descriptor %d/transport %s, "
5539384561c0efe744226d5e5d331f5546e500e4Marcel Telka "T_UDERROR) failed: %m",
5539384561c0efe744226d5e5d331f5546e500e4Marcel Telka fd, nconf->nc_proto);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (error);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
5539384561c0efe744226d5e5d331f5546e500e4Marcel Telka (void) syslog(LOG_ERR, "t_alloc(file descriptor %d/"
5539384561c0efe744226d5e5d331f5546e500e4Marcel Telka "transport %s, T_UDERROR) failed TLI error: %d",
5539384561c0efe744226d5e5d331f5546e500e4Marcel Telka fd, nconf->nc_proto, t_errno);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto flush_it;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ret = t_rcvuderr(fd, uderr);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ret == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Save the datagram error in errno, so that the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * %m argument to syslog picks up the error string.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte errno = uderr->error;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Log the datagram error, then log the host that
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * probably triggerred. Cannot log both in the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * same transaction because of packet size limitations
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * in /dev/log.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) syslog((errno == ECONNREFUSED) ? LOG_DEBUG : LOG_WARNING,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "%s response over <file descriptor %d/transport %s> "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "generated error: %m",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte progname, fd, nconf->nc_proto);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Try to map the client's address back to a
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * name.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ret = netdir_getbyaddr(nconf, &host, &uderr->addr);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ret != -1 && host && host->h_cnt > 0 &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte host->h_hostservs) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) syslog((errno == ECONNREFUSED) ? LOG_DEBUG : LOG_WARNING,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "Bad %s response was sent to client with "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "host name: %s; service port: %s",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte progname, host->h_hostservs->h_host,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte host->h_hostservs->h_serv);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int i, j;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte char *buf;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte char *hex = "0123456789abcdef";
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Mapping failed, print the whole thing
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * in ASCII hex.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte buf = (char *)malloc(uderr->addr.len * 2 + 1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte for (i = 0, j = 0; i < uderr->addr.len; i++, j += 2) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte buf[j] = hex[((uderr->addr.buf[i]) >> 4) & 0xf];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte buf[j+1] = hex[uderr->addr.buf[i] & 0xf];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte buf[j] = '\0';
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) syslog((errno == ECONNREFUSED) ?
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte LOG_DEBUG : LOG_WARNING,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "Bad %s response was sent to client with "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "transport address: 0x%s",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte progname, buf);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte free((void *)buf);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ret == 0 && host != NULL)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte netdir_free((void *)host, ND_HOSTSERVLIST);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte switch (t_errno) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case TNOUDERR:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto flush_it;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte case TSYSERR:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * System errors are returned to caller.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Save the error code across
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * syslog(), just in case
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * syslog() gets its own error
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * and therefore overwrites errno.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte error = errno;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) syslog(LOG_ERR,
5539384561c0efe744226d5e5d331f5546e500e4Marcel Telka "t_rcvuderr(file descriptor %d/transport %s) %m",
5539384561c0efe744226d5e5d331f5546e500e4Marcel Telka fd, nconf->nc_proto);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (error);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte default:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) syslog(LOG_ERR,
5539384561c0efe744226d5e5d331f5546e500e4Marcel Telka "t_rcvuderr(file descriptor %d/transport %s) TLI error %d",
5539384561c0efe744226d5e5d331f5546e500e4Marcel Telka fd, nconf->nc_proto, t_errno);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte goto flush_it;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteflush_it:
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If we get here, then we could not cope with whatever message
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * we attempted to read, so flush it. If we did read a message,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * and one isn't present, that is all right, because fd is in
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * nonblocking mode.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) syslog(LOG_ERR,
5539384561c0efe744226d5e5d331f5546e500e4Marcel Telka "Flushing one input message from <file descriptor %d/transport %s>",
5539384561c0efe744226d5e5d331f5546e500e4Marcel Telka fd, nconf->nc_proto);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Read and discard the message. Do this this until there is
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * no more control/data in the message or until we get an error.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte do {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ctl->maxlen = sizeof (ctlbuf);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ctl->buf = ctlbuf;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte data->maxlen = sizeof (databuf);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte data->buf = databuf;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte flags = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ret = getmsg(fd, ctl, data, &flags);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ret == -1)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (errno);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte } while (ret != 0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Establish service thread.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forterdcsvc(int fd, struct netbuf addrmask, struct netconfig *nconf)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#ifdef __NCALL__
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct ncall_svc_args nsa;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#else /* !__NCALL__ */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct rdc_svc_args nsa;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte _rdc_ioctl_t rdc_args = { 0, };
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#endif /* __NCALL__ */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsa.fd = fd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsa.nthr = (max_conns_allowed < 0 ? 16 : max_conns_allowed);
570de38f63910201fdd77246630b7aa8f9dc5661Surya Prakki (void) strncpy(nsa.netid, nconf->nc_netid, sizeof (nsa.netid));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsa.addrmask.len = addrmask.len;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsa.addrmask.maxlen = addrmask.maxlen;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nsa.addrmask.buf = addrmask.buf;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#ifdef __NCALL__
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (sndrsys(NC_IOC_SERVER, &nsa));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#else /* !__NCALL__ */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rdc_args.arg0 = (long)&nsa;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (sndrsys(RDC_ENABLE_SVR, &rdc_args));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#endif /* __NCALL__ */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortenofile_increase(int limit)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct rlimit rl;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (getrlimit(RLIMIT_NOFILE, &rl) == -1) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte syslog(LOG_ERR,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "nofile_increase() getrlimit of NOFILE failed: %m");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (-1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (limit > 0)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rl.rlim_cur = limit;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte else
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rl.rlim_cur += NOFILE_INC_SIZE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (rl.rlim_cur > rl.rlim_max && rl.rlim_max != RLIM_INFINITY)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rl.rlim_max = rl.rlim_cur;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (setrlimit(RLIMIT_NOFILE, &rl) == -1) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte syslog(LOG_ERR,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "nofile_increase() setrlimit of NOFILE to %d failed: %m",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte rl.rlim_cur);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (-1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteint
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forterdcd_bindit(struct netconfig *nconf, struct netbuf **addr,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct nd_hostserv *hs, int backlog)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int fd;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct t_bind *ntb;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct t_bind tb;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct nd_addrlist *addrlist;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct t_optmgmt req, resp;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct opthdr *opt;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte char reqbuf[128];
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((fd = rdc_transport_open(nconf)) == -1) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte syslog(LOG_ERR, "cannot establish transport service over %s",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nconf->nc_device);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (-1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte addrlist = (struct nd_addrlist *)NULL;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (netdir_getbyname(nconf, hs, &addrlist) != 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (strncmp(nconf->nc_netid, "udp", 3) != 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte syslog(LOG_ERR, "Cannot get address for transport "
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "%s host %s service %s",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte nconf->nc_netid, hs->h_host, hs->h_serv);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) t_close(fd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (-1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (strcmp(nconf->nc_proto, "tcp") == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If we're running over TCP, then set the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * SO_REUSEADDR option so that we can bind
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * to our preferred address even if previously
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * left connections exist in FIN_WAIT states.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * This is somewhat bogus, but otherwise you have
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * to wait 2 minutes to restart after killing it.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (reuseaddr(fd) == -1) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte syslog(LOG_WARNING,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte "couldn't set SO_REUSEADDR option on transport");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (nconf->nc_semantics == NC_TPI_CLTS)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tb.qlen = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte else
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tb.qlen = backlog;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* LINTED pointer alignment */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ntb = (struct t_bind *)t_alloc(fd, T_BIND, T_ALL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (ntb == (struct t_bind *)NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte syslog(LOG_ERR, "t_alloc failed: t_errno %d, %m", t_errno);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) t_close(fd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte netdir_free((void *)addrlist, ND_ADDRLIST);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (-1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte tb.addr = *(addrlist->n_addrs); /* structure copy */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (t_bind(fd, &tb, ntb) == -1) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte syslog(LOG_ERR, "t_bind failed: t_errno %d, %m", t_errno);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) t_free((char *)ntb, T_BIND);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte netdir_free((void *)addrlist, ND_ADDRLIST);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) t_close(fd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (-1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* make sure we bound to the right address */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (tb.addr.len != ntb->addr.len ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte memcmp(tb.addr.buf, ntb->addr.buf, tb.addr.len) != 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte syslog(LOG_ERR, "t_bind to wrong address");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) t_free((char *)ntb, T_BIND);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte netdir_free((void *)addrlist, ND_ADDRLIST);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) t_close(fd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (-1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *addr = &ntb->addr;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte netdir_free((void *)addrlist, ND_ADDRLIST);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (strcmp(nconf->nc_proto, "tcp") == 0 ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte strcmp(nconf->nc_proto, "tcp6") == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Disable the Nagle algorithm on TCP connections.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Connections accepted from this listener will
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * inherit the listener options.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* LINTED pointer alignment */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte opt = (struct opthdr *)reqbuf;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte opt->level = IPPROTO_TCP;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte opt->name = TCP_NODELAY;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte opt->len = sizeof (int);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* LINTED pointer alignment */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *(int *)((char *)opt + sizeof (*opt)) = 1;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte req.flags = T_NEGOTIATE;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte req.opt.len = sizeof (*opt) + opt->len;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte req.opt.buf = (char *)opt;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte resp.flags = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte resp.opt.buf = reqbuf;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte resp.opt.maxlen = sizeof (reqbuf);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (t_optmgmt(fd, &req, &resp) < 0 ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte resp.flags != T_SUCCESS) {
5539384561c0efe744226d5e5d331f5546e500e4Marcel Telka syslog(LOG_ERR, "couldn't set NODELAY option for "
5539384561c0efe744226d5e5d331f5546e500e4Marcel Telka "proto %s: t_errno = %d, %m", nconf->nc_proto,
5539384561c0efe744226d5e5d331f5546e500e4Marcel Telka t_errno);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (fd);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/* ARGSUSED */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortebind_to_provider(char *provider, char *serv, struct netbuf **addr,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct netconfig **retnconf)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct netconfig *nconf;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte NCONF_HANDLE *nc;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct nd_hostserv hs;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte hs.h_host = HOST_SELF;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte hs.h_serv = RDC_SERVICE; /* serv_name_to_port_name(serv); */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((nc = setnetconfig()) == (NCONF_HANDLE *)NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte syslog(LOG_ERR, "setnetconfig failed: %m");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (-1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while (nconf = getnetconfig(nc)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (OK_TPI_TYPE(nconf) &&
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte strcmp(nconf->nc_device, provider) == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte *retnconf = nconf;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (rdcd_bindit(nconf, addr, &hs, listen_backlog));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) endnetconfig(nc);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if ((Is_ipv6present() && (strcmp(provider, "/dev/tcp6") == 0)) ||
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (!Is_ipv6present() && (strcmp(provider, "/dev/tcp") == 0)))
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte syslog(LOG_ERR, "couldn't find netconfig entry for provider %s",
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte provider);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (-1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * For listen fd's index is always less than end_listen_fds.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * It's value is equal to the number of open file descriptors after the
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * last listen end point was opened but before any connection was accepted.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteis_listen_fd_index(int index)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (index < end_listen_fds);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Create an address mask appropriate for the transport.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * The mask is used to obtain the host-specific part of
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * a network address when comparing addresses.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * For an internet address the host-specific part is just
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * the 32 bit IP address and this part of the mask is set
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * to all-ones. The port number part of the mask is zeroes.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forteset_addrmask(int fd, struct netconfig *nconf, struct netbuf *mask)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct t_info info;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Find the size of the address we need to mask.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (t_getinfo(fd, &info) < 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte t_error("t_getinfo");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (-1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mask->len = mask->maxlen = info.addr;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (info.addr <= 0) {
5539384561c0efe744226d5e5d331f5546e500e4Marcel Telka syslog(LOG_ERR, "set_addrmask: address size: %ld", info.addr);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (-1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte mask->buf = (char *)malloc(mask->len);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (mask->buf == NULL) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte syslog(LOG_ERR, "set_addrmask: no memory");
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (-1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) memset(mask->buf, 0, mask->len); /* reset all mask bits */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (strcmp(nconf->nc_protofmly, NC_INET) == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Set the mask so that the port is ignored.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* LINTED pointer alignment */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ((struct sockaddr_in *)mask->buf)->sin_addr.s_addr =
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (in_addr_t)~0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* LINTED pointer alignment */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ((struct sockaddr_in *)mask->buf)->sin_family = (sa_family_t)~0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#ifdef NC_INET6
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte else if (strcmp(nconf->nc_protofmly, NC_INET6) == 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* LINTED pointer alignment */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) memset(&((struct sockaddr_in6 *)mask->buf)->sin6_addr,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (uchar_t)~0, sizeof (struct in6_addr));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* LINTED pointer alignment */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte ((struct sockaddr_in6 *)mask->buf)->sin6_family =
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (sa_family_t)~0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#endif
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte else {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Set all mask bits.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) memset(mask->buf, (uchar_t)~0, mask->len);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#if !defined(_SunOS_5_6) && !defined(_SunOS_5_7) && !defined(_SunOS_5_8)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortesndrsvcpool(int maxservers)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte struct svcpool_args npa;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte npa.id = RDC_SVCPOOL_ID;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte npa.maxthreads = maxservers;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte npa.redline = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte npa.qsize = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte npa.timeout = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte npa.stksize = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte npa.max_same_xprt = 0;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (sndrsys(RDC_POOL_CREATE, &npa));
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * The following stolen from cmd/fs.d/nfs/lib/thrpool.c
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#include <thread.h>
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Thread to call into the kernel and do work on behalf of SNDR/ncall-ip.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortesvcstart(void *arg)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int id = (int)arg;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int err;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while ((err = sndrsys(RDC_POOL_RUN, &id)) != 0) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Interrupted by a signal while in the kernel.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * this process is still alive, try again.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (err == EINTR)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte continue;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte else
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If we weren't interrupted by a signal, but did
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * return from the kernel, this thread's work is done,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * and it should exit.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte thr_exit(NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte/*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * User-space "creator" thread. This thread blocks in the kernel
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * until new worker threads need to be created for the service
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * pool. On return to userspace, if there is no error, create a
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * new thread for the service pool.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic void *
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortesvcblock(void *arg)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int id = (int)arg;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /* CONSTCOND */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte while (1) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte thread_t tid;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte int err;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Call into the kernel, and hang out there
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * until a thread needs to be created.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (err = sndrsys(RDC_POOL_WAIT, &id)) {
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (err == ECANCELED || err == EBUSY)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * If we get back ECANCELED, the service
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * pool is exiting, and we may as well
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * clean up this thread. If EBUSY is
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * returned, there's already a thread
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * looping on this pool, so we should
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * give up.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte break;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte else
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte continue;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte (void) thr_create(NULL, NULL, svcstart, (void *)id,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte THR_BOUND | THR_DETACHED, &tid);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte }
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte thr_exit(NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (NULL);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortestatic int
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Fortesvcwait(int id)
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte{
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte thread_t tid;
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte /*
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * Create a bound thread to wait for kernel LWPs that
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte * need to be created.
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte */
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte if (thr_create(NULL, NULL, svcblock, (void *)id,
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte THR_BOUND | THR_DETACHED, &tid))
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (1);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte return (0);
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte}
fcf3ce441efd61da9bb2884968af01cb7c1452ccJohn Forte#endif /* Solaris 9+ */