ex_dscp.c revision 154b1f02449b21af9273efd1a7776a3fe65a0744
25cf1a301a396c38e8adf52c15f537b80d2483f7jl/*
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * CDDL HEADER START
25cf1a301a396c38e8adf52c15f537b80d2483f7jl *
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * The contents of this file are subject to the terms of the
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * Common Development and Distribution License (the "License").
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * You may not use this file except in compliance with the License.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl *
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * or http://www.opensolaris.org/os/licensing.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * See the License for the specific language governing permissions
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * and limitations under the License.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl *
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * When distributing Covered Code, include this CDDL HEADER in each
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * If applicable, add the following below this CDDL HEADER, with the
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * fields enclosed by brackets "[]" replaced with your own identifying
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * information: Portions Copyright [yyyy] [name of copyright owner]
25cf1a301a396c38e8adf52c15f537b80d2483f7jl *
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * CDDL HEADER END
25cf1a301a396c38e8adf52c15f537b80d2483f7jl */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl/*
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * Use is subject to license terms.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl#pragma ident "%Z%%M% %I% %E% SMI"
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl/*
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * FMA Event Transport Module Transport Layer API implementation.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl *
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * Library for establishing connections and transporting FMA events between
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * ETMs (event-transport modules) in separate fault domains.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl *
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * The transport for this library is internet socket based and uses the DSCP
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * client services library (libdscp).
25cf1a301a396c38e8adf52c15f537b80d2483f7jl */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl#include <unistd.h>
25cf1a301a396c38e8adf52c15f537b80d2483f7jl#include <strings.h>
25cf1a301a396c38e8adf52c15f537b80d2483f7jl#include <sys/socket.h>
25cf1a301a396c38e8adf52c15f537b80d2483f7jl#include <fcntl.h>
25cf1a301a396c38e8adf52c15f537b80d2483f7jl#include <netdb.h>
25cf1a301a396c38e8adf52c15f537b80d2483f7jl#include <pthread.h>
25cf1a301a396c38e8adf52c15f537b80d2483f7jl#include <errno.h>
25cf1a301a396c38e8adf52c15f537b80d2483f7jl#include <time.h>
25cf1a301a396c38e8adf52c15f537b80d2483f7jl#include <libdscp.h>
25cf1a301a396c38e8adf52c15f537b80d2483f7jl#include "etm_xport_api.h"
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl/*
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * Transport Layer handle implementations
25cf1a301a396c38e8adf52c15f537b80d2483f7jl */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl/* Connection handle */
25cf1a301a396c38e8adf52c15f537b80d2483f7jltypedef struct etm_xport_sock_conn {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl int c_len; /* Length of saddr */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl int c_sd; /* Socket descriptor */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl struct sockaddr_in c_saddr; /* Sockaddr for DSCP connection */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl} exs_conn_t;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jltypedef enum etm_xport_sock_status {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl S_WAITING, /* Server thread is waiting to start */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl S_RUNNING, /* Server thread is running */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl S_DOEXIT /* Server thread needs to exit */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl} exs_status_t;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl/* Transport instance handle */
25cf1a301a396c38e8adf52c15f537b80d2483f7jltypedef struct etm_xport_sock_hdl {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl exs_conn_t h_client; /* Sending connection handle */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl exs_conn_t h_server; /* Receiving connection handle */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl char *h_endpt_id; /* Endpoint id from ETM common */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl int h_domain_id; /* Domain ID from platform (libdscp) */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl pthread_mutex_t h_lock; /* Lock for instance handle */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl fmd_hdl_t *h_hdl; /* fmd handle */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl int (*h_cb_func)(fmd_hdl_t *, etm_xport_conn_t, etm_cb_flag_t, void *);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* Callback function for ETM common */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl void *h_cb_func_arg; /* Arg to pass when calling h_cb_func */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl struct etm_xport_sock_hdl *h_next;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl} exs_hdl_t;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl/* For the socket */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl#define EXS_SERVER_PORT 24 /* Port number for server */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl#define EXS_SERVER_ADDR in6addr_any /* Address for server */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl#define EXS_CLIENT_PORT 0 /* Port number for client */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl#define EXS_NUM_SOCKS 5 /* Length of socket queue */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl#define EXS_SD_FREE -1 /* Socket descr value when unset */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl#define EXS_DOMAIN_PREFIX "dom" /* Domain auth prefix in FMRI string */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl#define EXS_DOMAIN_PREFIX_LEN 3 /* Length of domain prefix */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl#define EXS_SP_PREFIX "sp" /* SP auth prefix in FMRI string */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl#define EXS_IO_SLEEP_DIV 100 /* Divisor for I/O sleeptime */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl/*
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * Global variables
25cf1a301a396c38e8adf52c15f537b80d2483f7jl */
25cf1a301a396c38e8adf52c15f537b80d2483f7jlstatic exs_status_t Server_status = S_WAITING;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* Status of Server */
25cf1a301a396c38e8adf52c15f537b80d2483f7jlstatic pthread_t Server_tid = 0; /* Thread ID of Server */
25cf1a301a396c38e8adf52c15f537b80d2483f7jlstatic exs_conn_t Acceptor_conn; /* Connection handle for Acceptor */
25cf1a301a396c38e8adf52c15f537b80d2483f7jlstatic fd_set Conn_set; /* Set of accepted connections */
25cf1a301a396c38e8adf52c15f537b80d2483f7jlstatic pthread_mutex_t Mod_lock = PTHREAD_MUTEX_INITIALIZER;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* Protects globals (above) */
25cf1a301a396c38e8adf52c15f537b80d2483f7jlstatic exs_hdl_t *Exh_head = NULL; /* Head of ex_hdl_t list */
25cf1a301a396c38e8adf52c15f537b80d2483f7jlstatic pthread_mutex_t List_lock = PTHREAD_MUTEX_INITIALIZER;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* Protects linked list of ex_hdl_t */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl/*
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * Mutex lock order
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * (1) List_lock
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * (2) hp->h_lock
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * (3) Mod_lock
25cf1a301a396c38e8adf52c15f537b80d2483f7jl */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl/*
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * Module specific routines.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl/*
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * Allocate and initialize a transport instance handle.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * Return hdl pointer for success, NULL for failure.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl */
25cf1a301a396c38e8adf52c15f537b80d2483f7jlstatic exs_hdl_t *
25cf1a301a396c38e8adf52c15f537b80d2483f7jlexs_hdl_alloc(fmd_hdl_t *hdl, char *endpoint_id,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl int (*cb_func)(fmd_hdl_t *hdl, etm_xport_conn_t conn, etm_cb_flag_t flag,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl void *arg), void *cb_func_arg, int domain_id)
25cf1a301a396c38e8adf52c15f537b80d2483f7jl{
25cf1a301a396c38e8adf52c15f537b80d2483f7jl exs_hdl_t *hp;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl hp = fmd_hdl_zalloc(hdl, sizeof (exs_hdl_t), FMD_SLEEP);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) pthread_mutex_init(&hp->h_lock, NULL);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl hp->h_endpt_id = fmd_hdl_strdup(hdl, endpoint_id, FMD_SLEEP);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl hp->h_domain_id = domain_id;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl hp->h_client.c_sd = EXS_SD_FREE;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl hp->h_server.c_sd = EXS_SD_FREE;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl hp->h_hdl = hdl;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl hp->h_cb_func = cb_func;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl hp->h_cb_func_arg = cb_func_arg;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (hp);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl}
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl/*
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * Prepare the client connection.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * Return 0 for success, nonzero for failure.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl */
25cf1a301a396c38e8adf52c15f537b80d2483f7jlstatic int
25cf1a301a396c38e8adf52c15f537b80d2483f7jlexs_prep_client(fmd_hdl_t *hdl, exs_hdl_t *hp)
25cf1a301a396c38e8adf52c15f537b80d2483f7jl{
25cf1a301a396c38e8adf52c15f537b80d2483f7jl int rv;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* Find the DSCP address for the remote endpoint */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if ((rv = dscpAddr(hp->h_domain_id, DSCP_ADDR_REMOTE,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (struct sockaddr *)&hp->h_client.c_saddr,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl &hp->h_client.c_len)) != DSCP_OK) {
154b1f02449b21af9273efd1a7776a3fe65a0744jrutt fmd_hdl_error(hdl, "xport - dscpAddr for %s failed: %d",
25cf1a301a396c38e8adf52c15f537b80d2483f7jl hp->h_endpt_id, rv);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (1);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if ((hp->h_client.c_sd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
154b1f02449b21af9273efd1a7776a3fe65a0744jrutt fmd_hdl_error(hdl, "xport - client socket failed for %s",
25cf1a301a396c38e8adf52c15f537b80d2483f7jl hp->h_endpt_id);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (1);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* Bind the socket to the local IP address of the DSCP link */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if ((rv = dscpBind(hp->h_domain_id, hp->h_client.c_sd,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl EXS_CLIENT_PORT)) != DSCP_OK) {
154b1f02449b21af9273efd1a7776a3fe65a0744jrutt fmd_hdl_error(hdl, "xport - client bind for %s failed: %d",
25cf1a301a396c38e8adf52c15f537b80d2483f7jl hp->h_endpt_id, rv);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) close(hp->h_client.c_sd);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl hp->h_client.c_sd = EXS_SD_FREE;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (1);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl hp->h_client.c_saddr.sin_port = htons(EXS_SERVER_PORT);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* Set IPsec security policy for this socket */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if ((rv = dscpSecure(hp->h_domain_id, hp->h_client.c_sd)) != DSCP_OK) {
154b1f02449b21af9273efd1a7776a3fe65a0744jrutt fmd_hdl_error(hdl, "xport - dscpSecure for %s failed: %d",
25cf1a301a396c38e8adf52c15f537b80d2483f7jl hp->h_endpt_id, rv);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) close(hp->h_client.c_sd);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl hp->h_client.c_sd = EXS_SD_FREE;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (1);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (0);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl}
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl/*
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * Prepare to accept a connection.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * Assume Mod_lock is held by caller.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * Return 0 for success, nonzero for failure.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl */
25cf1a301a396c38e8adf52c15f537b80d2483f7jlstatic int
25cf1a301a396c38e8adf52c15f537b80d2483f7jlexs_prep_accept(fmd_hdl_t *hdl)
25cf1a301a396c38e8adf52c15f537b80d2483f7jl{
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl int flags, domain = 0, optval = 1;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl int rv;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if ((Acceptor_conn.c_sd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
154b1f02449b21af9273efd1a7776a3fe65a0744jrutt fmd_hdl_error(hdl, "xport - acceptor socket failed");
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (1);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (setsockopt(Acceptor_conn.c_sd, SOL_SOCKET, SO_REUSEADDR,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl &optval, sizeof (optval))) {
154b1f02449b21af9273efd1a7776a3fe65a0744jrutt fmd_hdl_error(hdl, "xport - set REUSEADDR failed");
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) close(Acceptor_conn.c_sd);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl Acceptor_conn.c_sd = EXS_SD_FREE;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (1);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* Bind the socket to the local IP address of the DSCP link */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if ((rv = dscpBind(domain, Acceptor_conn.c_sd,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl EXS_SERVER_PORT)) != DSCP_OK) {
154b1f02449b21af9273efd1a7776a3fe65a0744jrutt fmd_hdl_error(hdl, "xport - acceptor bind failed: %d", rv);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) close(Acceptor_conn.c_sd);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl Acceptor_conn.c_sd = EXS_SD_FREE;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (1);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* Activate IPsec security policy for this socket */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if ((rv = dscpSecure(domain, Acceptor_conn.c_sd)) != DSCP_OK) {
154b1f02449b21af9273efd1a7776a3fe65a0744jrutt fmd_hdl_error(hdl, "xport - dscpSecure for acceptor failed: %d",
25cf1a301a396c38e8adf52c15f537b80d2483f7jl rv);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) close(Acceptor_conn.c_sd);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl Acceptor_conn.c_sd = EXS_SD_FREE;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (1);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if ((listen(Acceptor_conn.c_sd, EXS_NUM_SOCKS)) == -1) {
154b1f02449b21af9273efd1a7776a3fe65a0744jrutt fmd_hdl_error(hdl, "xport - acceptor listen failed");
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) close(Acceptor_conn.c_sd);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl Acceptor_conn.c_sd = EXS_SD_FREE;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (1);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl flags = fcntl(Acceptor_conn.c_sd, F_GETFL, 0);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) fcntl(Acceptor_conn.c_sd, F_SETFL, flags | O_NONBLOCK);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (0);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl}
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl/*
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * Translate endpoint_id str to int.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * Return the domain ID via "dom_id".
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * Return 0 for success, nonzero for failure
25cf1a301a396c38e8adf52c15f537b80d2483f7jl */
25cf1a301a396c38e8adf52c15f537b80d2483f7jlstatic int
25cf1a301a396c38e8adf52c15f537b80d2483f7jlexs_get_id(fmd_hdl_t *hdl, char *endpoint_id, int *dom_id)
25cf1a301a396c38e8adf52c15f537b80d2483f7jl{
25cf1a301a396c38e8adf52c15f537b80d2483f7jl char *ptr;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (strstr(endpoint_id, EXS_SP_PREFIX) != NULL) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* Remote endpoint is the SP */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl *dom_id = DSCP_IDENT_SP;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (0);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl } else {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if ((ptr = strstr(endpoint_id, EXS_DOMAIN_PREFIX)) == NULL) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl fmd_hdl_debug(hdl, "xport - %s not found in %s\n",
25cf1a301a396c38e8adf52c15f537b80d2483f7jl EXS_DOMAIN_PREFIX, endpoint_id);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (1);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl ptr += EXS_DOMAIN_PREFIX_LEN;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if ((sscanf(ptr, "%d", dom_id)) != 1) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl fmd_hdl_debug(hdl, "xport - no integer found in %s\n",
25cf1a301a396c38e8adf52c15f537b80d2483f7jl endpoint_id);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (1);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (0);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl}
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl/*
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * Build set of socket descriptors based on the current list of exs_hdl_t.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * Return the largest descriptor.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl */
25cf1a301a396c38e8adf52c15f537b80d2483f7jlstatic int
25cf1a301a396c38e8adf52c15f537b80d2483f7jlexs_build_set(fmd_hdl_t *hdl)
25cf1a301a396c38e8adf52c15f537b80d2483f7jl{
25cf1a301a396c38e8adf52c15f537b80d2483f7jl exs_hdl_t *curr;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl struct sockaddr sa;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl socklen_t slen = sizeof (struct sockaddr);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl fd_set rset;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl int max_sd = 0;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl fmd_hdl_debug(hdl, "xport - building set of socket descr");
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl FD_ZERO(&rset);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl FD_SET(Acceptor_conn.c_sd, &rset);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) pthread_mutex_lock(&List_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl for (curr = Exh_head; curr; curr = curr->h_next) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) pthread_mutex_lock(&curr->h_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (curr->h_server.c_sd != EXS_SD_FREE) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* Use getsockname to test for valid socket descr */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (getsockname(curr->h_server.c_sd, &sa, &slen) == 0)
25cf1a301a396c38e8adf52c15f537b80d2483f7jl FD_SET(curr->h_server.c_sd, &rset);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl else if ((errno == EBADF) || (errno == ENOTSOCK))
25cf1a301a396c38e8adf52c15f537b80d2483f7jl curr->h_server.c_sd = EXS_SD_FREE;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl else
154b1f02449b21af9273efd1a7776a3fe65a0744jrutt fmd_hdl_debug(hdl, "xport - getsockname fail");
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (curr->h_server.c_sd > max_sd)
25cf1a301a396c38e8adf52c15f537b80d2483f7jl max_sd = curr->h_server.c_sd;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) pthread_mutex_unlock(&curr->h_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) pthread_mutex_unlock(&List_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) pthread_mutex_lock(&Mod_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl Conn_set = rset;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) pthread_mutex_unlock(&Mod_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (max_sd > FD_SETSIZE)
25cf1a301a396c38e8adf52c15f537b80d2483f7jl fmd_hdl_abort(hdl, "xport - max_sd too big");
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (max_sd);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl}
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl/*
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * Find the exs_hdl_t associated with the given sockaddr_in.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * Assume caller holds lock on List_lock.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * Return the exs_hdl_t for success, NULL for failure.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl */
25cf1a301a396c38e8adf52c15f537b80d2483f7jlstatic exs_hdl_t *
25cf1a301a396c38e8adf52c15f537b80d2483f7jlexs_find_hdl(fmd_hdl_t *hdl, struct sockaddr_in *saddr, socklen_t salen)
25cf1a301a396c38e8adf52c15f537b80d2483f7jl{
25cf1a301a396c38e8adf52c15f537b80d2483f7jl exs_hdl_t *curr;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl int domain_id, rv;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* Translate saddr to a domain id string */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if ((rv = dscpIdent((struct sockaddr *)saddr, (int)salen,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl &domain_id)) != DSCP_OK) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl fmd_hdl_debug(hdl, "xport - dscpIdent failed for 0x%x : %d",
25cf1a301a396c38e8adf52c15f537b80d2483f7jl saddr->sin_addr.s_addr, rv);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (NULL);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if ((rv = dscpAuth(domain_id, (struct sockaddr *)saddr,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (int)salen)) != DSCP_OK) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl fmd_hdl_debug(hdl, "xport - dscpAuth failed for 0x%x : %d",
25cf1a301a396c38e8adf52c15f537b80d2483f7jl saddr->sin_addr.s_addr, rv);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (NULL);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* Lookup this domain id */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl for (curr = Exh_head; curr; curr = curr->h_next) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (curr->h_domain_id == domain_id)
25cf1a301a396c38e8adf52c15f537b80d2483f7jl break;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (curr);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl}
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl/*
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * Main server function, runs on thread started at init.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * Accepts incoming connections and notifies ETM of incoming data.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * Thread/function runs until Server_status changes to S_DOEXIT.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl */
25cf1a301a396c38e8adf52c15f537b80d2483f7jlstatic void
25cf1a301a396c38e8adf52c15f537b80d2483f7jlexs_server(void *arg)
25cf1a301a396c38e8adf52c15f537b80d2483f7jl{
25cf1a301a396c38e8adf52c15f537b80d2483f7jl int new_sd; /* Socket desc of new conn */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl int nready; /* Num readable sockets from select */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl int max_sd; /* Max socket desc : for select */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl fd_set rset; /* Read socket desc set for select */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl struct sockaddr_in new_saddr; /* Sockaddr of remote endpt */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl exs_hdl_t *hp;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl fmd_hdl_t *hdl = (fmd_hdl_t *)arg;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl socklen_t new_len = sizeof (struct sockaddr);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl int flags, old_sd = 0;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) pthread_mutex_lock(&Mod_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl Server_status = S_RUNNING;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl FD_ZERO(&Conn_set);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl FD_SET(Acceptor_conn.c_sd, &Conn_set);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl max_sd = Acceptor_conn.c_sd;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl while (Server_status != S_DOEXIT) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl rset = Conn_set;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) pthread_mutex_unlock(&Mod_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if ((nready = select(max_sd + 1, &rset, NULL, NULL,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl NULL)) == -1) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (errno == EINTR)
25cf1a301a396c38e8adf52c15f537b80d2483f7jl fmd_hdl_debug(hdl, "xport - select EINTR");
25cf1a301a396c38e8adf52c15f537b80d2483f7jl else
25cf1a301a396c38e8adf52c15f537b80d2483f7jl max_sd = exs_build_set(hdl);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) pthread_mutex_lock(&Mod_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl continue;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* First check if a new connection has arrived */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (FD_ISSET(Acceptor_conn.c_sd, &rset)) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if ((new_sd = accept(Acceptor_conn.c_sd,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (struct sockaddr *)&new_saddr, &new_len)) != -1) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) pthread_mutex_lock(&List_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if ((hp = exs_find_hdl(hdl, &new_saddr,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl new_len)) != NULL) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl fmd_hdl_debug(hdl, "xport - new server "
25cf1a301a396c38e8adf52c15f537b80d2483f7jl "connection for %s",
25cf1a301a396c38e8adf52c15f537b80d2483f7jl hp->h_endpt_id);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) pthread_mutex_lock(&hp->h_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (hp->h_server.c_sd != EXS_SD_FREE) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) close(hp->h_server.c_sd);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl old_sd = hp->h_server.c_sd;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl hp->h_server.c_sd = new_sd;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* Set the socket to be non-blocking */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl flags = fcntl(hp->h_server.c_sd,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl F_GETFL, 0);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) fcntl(hp->h_server.c_sd,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl F_SETFL, flags | O_NONBLOCK);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) pthread_mutex_unlock(
25cf1a301a396c38e8adf52c15f537b80d2483f7jl &hp->h_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) pthread_mutex_unlock(&List_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /*
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * Add this socket descriptor to the
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * fd_set and remove the old one.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) pthread_mutex_lock(&Mod_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl FD_SET(new_sd, &Conn_set);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (old_sd) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl FD_CLR(old_sd, &Conn_set);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl old_sd = 0;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) pthread_mutex_unlock(&Mod_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (new_sd > max_sd)
25cf1a301a396c38e8adf52c15f537b80d2483f7jl max_sd = new_sd;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl } else {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) pthread_mutex_unlock(&List_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl fmd_hdl_debug(hdl,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl "xport - no tlhdl for endpt 0x%x",
25cf1a301a396c38e8adf52c15f537b80d2483f7jl new_saddr.sin_addr.s_addr);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) close(new_sd);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl } else {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl fmd_hdl_debug(hdl,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl "xport - accept failed");
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (--nready <= 0) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* No more sockets to check */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) pthread_mutex_lock(&Mod_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl continue;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* Check if any of the other sockets have data to recv */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) pthread_mutex_lock(&List_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl for (hp = Exh_head; hp; hp = hp->h_next) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) pthread_mutex_lock(&hp->h_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (hp->h_server.c_sd == EXS_SD_FREE) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) pthread_mutex_unlock(&hp->h_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl continue;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (FD_ISSET(hp->h_server.c_sd, &rset)) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /*
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * Data is available on this socket
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * or the remote side has closed.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if ((hp->h_cb_func(hp->h_hdl,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl &hp->h_server, ETM_CBFLAG_RECV,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl hp->h_cb_func_arg)) != 0) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /*
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * Remove the socket descriptor from
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * the fd_set
25cf1a301a396c38e8adf52c15f537b80d2483f7jl */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) pthread_mutex_lock(&Mod_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl FD_CLR(hp->h_server.c_sd, &Conn_set);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) pthread_mutex_unlock(&Mod_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* Close the server socket */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) close(hp->h_server.c_sd);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl hp->h_server.c_sd = EXS_SD_FREE;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (--nready <= 0) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* No more sockets to check */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) pthread_mutex_unlock(
25cf1a301a396c38e8adf52c15f537b80d2483f7jl &hp->h_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl break;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) pthread_mutex_unlock(&hp->h_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) pthread_mutex_unlock(&List_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) pthread_mutex_lock(&Mod_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl fmd_hdl_debug(hdl, "xport - exiting server thread %d", Server_tid);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) close(Acceptor_conn.c_sd);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl Acceptor_conn.c_sd = EXS_SD_FREE;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl Server_tid = 0;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl Server_status = S_WAITING;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) pthread_mutex_unlock(&Mod_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* Thread dies */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl}
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl/*
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * ETM-to-Transport API Connection Management routines
25cf1a301a396c38e8adf52c15f537b80d2483f7jl */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl/*
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * Initialize and setup any transport infrastructure before any connections
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * are opened.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * Return etm_xport_hdl_t for success, NULL for failure.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl */
25cf1a301a396c38e8adf52c15f537b80d2483f7jletm_xport_hdl_t
25cf1a301a396c38e8adf52c15f537b80d2483f7jletm_xport_init(fmd_hdl_t *hdl, char *endpoint_id,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl int (*cb_func)(fmd_hdl_t *hdl, etm_xport_conn_t conn, etm_cb_flag_t flag,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl void *arg), void *cb_func_arg)
25cf1a301a396c38e8adf52c15f537b80d2483f7jl{
25cf1a301a396c38e8adf52c15f537b80d2483f7jl exs_hdl_t *hp, *curr;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl int domain_id;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
154b1f02449b21af9273efd1a7776a3fe65a0744jrutt if (exs_get_id(hdl, endpoint_id, &domain_id))
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (NULL);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) pthread_mutex_lock(&List_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (Exh_head == NULL) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* This is the first init */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) pthread_mutex_lock(&Mod_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (exs_prep_accept(hdl)) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) pthread_mutex_unlock(&Mod_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) pthread_mutex_unlock(&List_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (NULL);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) pthread_mutex_unlock(&Mod_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl } else {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* Check for a duplicate endpoint_id on the list */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl for (curr = Exh_head; curr; curr = curr->h_next) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (domain_id == curr->h_domain_id) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl fmd_hdl_debug(hdl, "xport - init failed, "
25cf1a301a396c38e8adf52c15f537b80d2483f7jl "duplicate domain_id : %d\n", domain_id);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) pthread_mutex_unlock(&List_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (NULL);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* Alloc and init a transport instance handle */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl hp = exs_hdl_alloc(hdl, endpoint_id, cb_func, cb_func_arg,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl domain_id);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* Prep the client-side connection */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (exs_prep_client(hdl, hp)) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (Exh_head == NULL) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) pthread_mutex_lock(&Mod_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (Acceptor_conn.c_sd != EXS_SD_FREE) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) close(Acceptor_conn.c_sd);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl Acceptor_conn.c_sd = EXS_SD_FREE;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) pthread_mutex_unlock(&Mod_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl fmd_hdl_strfree(hdl, hp->h_endpt_id);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) pthread_mutex_unlock(&hp->h_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) pthread_mutex_destroy(&hp->h_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl fmd_hdl_free(hdl, hp, sizeof (exs_hdl_t));
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) pthread_mutex_unlock(&List_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (NULL);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* Add this transport instance handle to the list */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl hp->h_next = Exh_head;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl Exh_head = hp;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) pthread_mutex_unlock(&List_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* Create the Server thread, if necessary */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) pthread_mutex_lock(&Mod_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (Server_tid == 0)
25cf1a301a396c38e8adf52c15f537b80d2483f7jl Server_tid = fmd_thr_create(hdl, exs_server, hdl);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) pthread_mutex_unlock(&Mod_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return ((etm_xport_hdl_t)hp);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl}
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl/*
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * Teardown any transport infrastructure after all connections are closed.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * Return 0 for success, or nonzero for failure.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl */
25cf1a301a396c38e8adf52c15f537b80d2483f7jlint
25cf1a301a396c38e8adf52c15f537b80d2483f7jletm_xport_fini(fmd_hdl_t *hdl, etm_xport_hdl_t tlhdl)
25cf1a301a396c38e8adf52c15f537b80d2483f7jl{
25cf1a301a396c38e8adf52c15f537b80d2483f7jl exs_hdl_t *hp = (exs_hdl_t *)tlhdl;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl exs_hdl_t *prev, *curr;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* Remove this handle from the list */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl prev = NULL;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) pthread_mutex_lock(&List_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl for (curr = Exh_head; curr; curr = curr->h_next) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (curr == hp)
25cf1a301a396c38e8adf52c15f537b80d2483f7jl break;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl prev = curr;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (curr == NULL) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) pthread_mutex_unlock(&List_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl fmd_hdl_debug(hdl, "xport - fini failed, tlhdl %p not on list",
25cf1a301a396c38e8adf52c15f537b80d2483f7jl curr);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (1);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (prev == NULL)
25cf1a301a396c38e8adf52c15f537b80d2483f7jl Exh_head = Exh_head->h_next;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl else
25cf1a301a396c38e8adf52c15f537b80d2483f7jl prev->h_next = hp->h_next;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* If this is the last handle, cleanup and exit the Server thread */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (Exh_head == NULL) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) pthread_mutex_lock(&Mod_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl Server_status = S_DOEXIT;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) pthread_mutex_unlock(&Mod_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl fmd_thr_signal(hdl, Server_tid);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl fmd_thr_destroy(hdl, Server_tid);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) pthread_mutex_unlock(&List_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* Close the handle's client connection */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) pthread_mutex_lock(&hp->h_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (hp->h_client.c_sd != EXS_SD_FREE)
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) close(hp->h_client.c_sd);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /*
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * Close the handle's server connection and remove it from the fd_set
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * used in the Server thread.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (hp->h_server.c_sd != EXS_SD_FREE) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) close(hp->h_server.c_sd);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) pthread_mutex_lock(&Mod_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl FD_CLR(hp->h_server.c_sd, &Conn_set);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) pthread_mutex_unlock(&Mod_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl fmd_hdl_strfree(hdl, hp->h_endpt_id);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) pthread_mutex_unlock(&hp->h_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) pthread_mutex_destroy(&hp->h_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl fmd_hdl_free(hdl, hp, sizeof (exs_hdl_t));
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (0);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl}
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl/*
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * Open a connection with the given endpoint,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * Return etm_xport_conn_t for success, NULL and set errno for failure.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl */
25cf1a301a396c38e8adf52c15f537b80d2483f7jletm_xport_conn_t
25cf1a301a396c38e8adf52c15f537b80d2483f7jletm_xport_open(fmd_hdl_t *hdl, etm_xport_hdl_t tlhdl)
25cf1a301a396c38e8adf52c15f537b80d2483f7jl{
25cf1a301a396c38e8adf52c15f537b80d2483f7jl int flags;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl exs_hdl_t *hp = (exs_hdl_t *)tlhdl;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (hp->h_client.c_sd == EXS_SD_FREE) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (exs_prep_client(hdl, hp) != 0)
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (NULL);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
154b1f02449b21af9273efd1a7776a3fe65a0744jrutt /* Set the socket to be non-blocking */
154b1f02449b21af9273efd1a7776a3fe65a0744jrutt flags = fcntl(hp->h_client.c_sd, F_GETFL, 0);
154b1f02449b21af9273efd1a7776a3fe65a0744jrutt (void) fcntl(hp->h_client.c_sd, F_SETFL, flags | O_NONBLOCK);
154b1f02449b21af9273efd1a7776a3fe65a0744jrutt
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if ((connect(hp->h_client.c_sd,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (struct sockaddr *)&hp->h_client.c_saddr,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl hp->h_client.c_len)) == -1) {
154b1f02449b21af9273efd1a7776a3fe65a0744jrutt if (errno != EINPROGRESS) {
154b1f02449b21af9273efd1a7776a3fe65a0744jrutt fmd_hdl_error(hdl, "xport - failed server connect : %s",
154b1f02449b21af9273efd1a7776a3fe65a0744jrutt hp->h_endpt_id);
154b1f02449b21af9273efd1a7776a3fe65a0744jrutt (void) close(hp->h_client.c_sd);
154b1f02449b21af9273efd1a7776a3fe65a0744jrutt hp->h_client.c_sd = EXS_SD_FREE;
154b1f02449b21af9273efd1a7776a3fe65a0744jrutt return (NULL);
154b1f02449b21af9273efd1a7776a3fe65a0744jrutt }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl fmd_hdl_debug(hdl, "xport - connected client socket for %s",
25cf1a301a396c38e8adf52c15f537b80d2483f7jl hp->h_endpt_id);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (&hp->h_client);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl}
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl/*
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * Close a connection from either endpoint.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * Return zero for success, nonzero for failure.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl/*ARGSUSED*/
25cf1a301a396c38e8adf52c15f537b80d2483f7jlint
25cf1a301a396c38e8adf52c15f537b80d2483f7jletm_xport_close(fmd_hdl_t *hdl, etm_xport_conn_t conn)
25cf1a301a396c38e8adf52c15f537b80d2483f7jl{
25cf1a301a396c38e8adf52c15f537b80d2483f7jl exs_conn_t *cp = (exs_conn_t *)conn;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (cp->c_sd == EXS_SD_FREE)
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (0); /* Connection already closed */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) close(cp->c_sd);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl cp->c_sd = EXS_SD_FREE;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (0);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl}
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl/*
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * ETM-to-Transport API I/O routines
25cf1a301a396c38e8adf52c15f537b80d2483f7jl */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl/*
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * Try to read byte_cnt bytes from the connection into the given buffer.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * Return how many bytes actually read for success, negative value for failure.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl */
25cf1a301a396c38e8adf52c15f537b80d2483f7jlssize_t
25cf1a301a396c38e8adf52c15f537b80d2483f7jletm_xport_read(fmd_hdl_t *hdl, etm_xport_conn_t conn, hrtime_t timeout,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl void *buf, size_t byte_cnt)
25cf1a301a396c38e8adf52c15f537b80d2483f7jl{
25cf1a301a396c38e8adf52c15f537b80d2483f7jl ssize_t len, nbytes = 0;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl hrtime_t endtime, sleeptime;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl struct timespec tms;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl char *ptr = (char *)buf;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl exs_conn_t *cp = (exs_conn_t *)conn;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (cp->c_sd == EXS_SD_FREE) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl fmd_hdl_debug(hdl, "xport - read socket %d is closed\n",
25cf1a301a396c38e8adf52c15f537b80d2483f7jl cp->c_sd);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (-EBADF);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl endtime = gethrtime() + timeout;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl sleeptime = timeout / EXS_IO_SLEEP_DIV;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl tms.tv_sec = 0;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl tms.tv_nsec = sleeptime;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl while (nbytes < byte_cnt) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (gethrtime() < endtime) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if ((len = recv(cp->c_sd, ptr, byte_cnt - nbytes,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl 0)) < 0) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (errno != EINTR && errno != EWOULDBLOCK) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl fmd_hdl_debug(hdl, "xport - recv "
25cf1a301a396c38e8adf52c15f537b80d2483f7jl "failed for socket %d", cp->c_sd);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) nanosleep(&tms, 0);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl continue;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl } else if (len == 0) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl fmd_hdl_debug(hdl, "xport - remote endpt "
25cf1a301a396c38e8adf52c15f537b80d2483f7jl "closed for socket %d", cp->c_sd);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (0);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl ptr += len;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl nbytes += len;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl } else {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl fmd_hdl_debug(hdl, "xport - read timed out for socket "
25cf1a301a396c38e8adf52c15f537b80d2483f7jl "%d", cp->c_sd);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl break;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (nbytes)
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (nbytes);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl else
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (-1);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl}
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl/*
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * Try to write byte_cnt bytes to the connection from the given buffer.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * Return how many bytes actually written for success, negative value
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * for failure.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl */
25cf1a301a396c38e8adf52c15f537b80d2483f7jlssize_t
25cf1a301a396c38e8adf52c15f537b80d2483f7jletm_xport_write(fmd_hdl_t *hdl, etm_xport_conn_t conn, hrtime_t timeout,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl void *buf, size_t byte_cnt)
25cf1a301a396c38e8adf52c15f537b80d2483f7jl{
25cf1a301a396c38e8adf52c15f537b80d2483f7jl ssize_t len, nbytes = 0;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl hrtime_t endtime, sleeptime;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl struct timespec tms;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl char *ptr = (char *)buf;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl exs_conn_t *cp = (exs_conn_t *)conn;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (cp->c_sd == EXS_SD_FREE) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl fmd_hdl_debug(hdl, "xport - write socket %d is closed\n",
25cf1a301a396c38e8adf52c15f537b80d2483f7jl cp->c_sd);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (-EBADF);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl endtime = gethrtime() + timeout;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl sleeptime = timeout / EXS_IO_SLEEP_DIV;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl tms.tv_sec = 0;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl tms.tv_nsec = sleeptime;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl while (nbytes < byte_cnt) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (gethrtime() < endtime) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if ((len = send(cp->c_sd, ptr, byte_cnt - nbytes,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl 0)) < 0) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (errno != EINTR && errno != EWOULDBLOCK) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl fmd_hdl_debug(hdl, "xport - send "
25cf1a301a396c38e8adf52c15f537b80d2483f7jl "failed for socket %d", cp->c_sd);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) nanosleep(&tms, 0);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl continue;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl ptr += len;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl nbytes += len;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl } else {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl fmd_hdl_debug(hdl, "xport - write timed out for socket "
25cf1a301a396c38e8adf52c15f537b80d2483f7jl "%d", cp->c_sd);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl break;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (nbytes)
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (nbytes);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl else
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (-1);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl}