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/*
677fd05c3b05c78948501f6ffdced37dab9368feMary Beale * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * Use is subject to license terms.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl */
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
d338766d6376ee721b7f1778e12bf79a112bd778jrutt#include "ex_dscp.h"
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl/*
d338766d6376ee721b7f1778e12bf79a112bd778jrutt * On the SP, there is one DSCP interface for every domain.
d338766d6376ee721b7f1778e12bf79a112bd778jrutt * Each domain has one and only one DSCP interface to the SP.
d338766d6376ee721b7f1778e12bf79a112bd778jrutt *
d338766d6376ee721b7f1778e12bf79a112bd778jrutt * The DSCP interface is created when the domain powers-on. On the SP,
d338766d6376ee721b7f1778e12bf79a112bd778jrutt * a sysevent will be generated when the DSCP interface is up. On the domain,
d338766d6376ee721b7f1778e12bf79a112bd778jrutt * the DSCP interface should be up when ETM loads.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
ac92251dc182f030faf6a5f76981d551b0b16072jruttexs_conn_t Acc; /* Connection for accepting/listening */
ac92251dc182f030faf6a5f76981d551b0b16072jruttpthread_t Acc_tid; /* Thread ID for accepting conns */
ac92251dc182f030faf6a5f76981d551b0b16072jruttint Acc_quit; /* Signal to quit the acceptor thread */
ac92251dc182f030faf6a5f76981d551b0b16072jruttint Acc_destroy; /* Destroy accept/listen thread? */
d338766d6376ee721b7f1778e12bf79a112bd778jruttexs_hdl_t *Exh_head = NULL; /* Head of ex_hdl_t list */
d338766d6376ee721b7f1778e12bf79a112bd778jruttpthread_mutex_t List_lock = PTHREAD_MUTEX_INITIALIZER;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* Protects linked list of ex_hdl_t */
77a7fd96f77f04bbd7634db14755686062589ecajruttstatic void *Dlp = NULL; /* Handle for dlopen/dlclose/dlsym */
77a7fd96f77f04bbd7634db14755686062589ecajruttstatic int (*Send_filter)(fmd_hdl_t *hdl, nvlist_t *event, const char *dest);
77a7fd96f77f04bbd7634db14755686062589ecajruttstatic int (*Post_filter)(fmd_hdl_t *hdl, nvlist_t *event, const char *src);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl/*
d338766d6376ee721b7f1778e12bf79a112bd778jrutt * * * * * * * * * * * * * *
d338766d6376ee721b7f1778e12bf79a112bd778jrutt * Module specific routines
d338766d6376ee721b7f1778e12bf79a112bd778jrutt * * * * * * * * * * * * * *
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,
d338766d6376ee721b7f1778e12bf79a112bd778jrutt void *arg), void *cb_func_arg, int dom)
25cf1a301a396c38e8adf52c15f537b80d2483f7jl{
25cf1a301a396c38e8adf52c15f537b80d2483f7jl exs_hdl_t *hp;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl hp = fmd_hdl_zalloc(hdl, sizeof (exs_hdl_t), FMD_SLEEP);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl hp->h_endpt_id = fmd_hdl_strdup(hdl, endpoint_id, FMD_SLEEP);
d338766d6376ee721b7f1778e12bf79a112bd778jrutt hp->h_dom = dom;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl hp->h_client.c_sd = EXS_SD_FREE;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl hp->h_server.c_sd = EXS_SD_FREE;
d338766d6376ee721b7f1778e12bf79a112bd778jrutt hp->h_tid = EXS_TID_FREE;
4573608322e68a31a57d0d851d7b324f4ffb66b5jrutt hp->h_destroy = 0;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl hp->h_hdl = hdl;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl hp->h_cb_func = cb_func;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl hp->h_cb_func_arg = cb_func_arg;
d338766d6376ee721b7f1778e12bf79a112bd778jrutt hp->h_quit = 0;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (hp);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl}
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
77a7fd96f77f04bbd7634db14755686062589ecajrutt/*
77a7fd96f77f04bbd7634db14755686062589ecajrutt * dlopen() the platform filter library and dlsym() the filter funcs.
77a7fd96f77f04bbd7634db14755686062589ecajrutt */
77a7fd96f77f04bbd7634db14755686062589ecajruttstatic void
77a7fd96f77f04bbd7634db14755686062589ecajruttexs_filter_init(fmd_hdl_t *hdl)
77a7fd96f77f04bbd7634db14755686062589ecajrutt{
77a7fd96f77f04bbd7634db14755686062589ecajrutt char *propstr = fmd_prop_get_string(hdl, "filter_path");
77a7fd96f77f04bbd7634db14755686062589ecajrutt
77a7fd96f77f04bbd7634db14755686062589ecajrutt if (propstr == NULL) {
77a7fd96f77f04bbd7634db14755686062589ecajrutt fmd_hdl_debug(hdl, "No filter plugin specified");
77a7fd96f77f04bbd7634db14755686062589ecajrutt Send_filter = NULL;
77a7fd96f77f04bbd7634db14755686062589ecajrutt Post_filter = NULL;
77a7fd96f77f04bbd7634db14755686062589ecajrutt return;
77a7fd96f77f04bbd7634db14755686062589ecajrutt } else {
77a7fd96f77f04bbd7634db14755686062589ecajrutt if ((Dlp = dlopen(propstr, RTLD_LOCAL | RTLD_NOW)) == NULL) {
77a7fd96f77f04bbd7634db14755686062589ecajrutt fmd_hdl_debug(hdl, "Failed to dlopen filter plugin");
77a7fd96f77f04bbd7634db14755686062589ecajrutt Send_filter = NULL;
77a7fd96f77f04bbd7634db14755686062589ecajrutt Post_filter = NULL;
77a7fd96f77f04bbd7634db14755686062589ecajrutt fmd_prop_free_string(hdl, propstr);
77a7fd96f77f04bbd7634db14755686062589ecajrutt return;
77a7fd96f77f04bbd7634db14755686062589ecajrutt }
77a7fd96f77f04bbd7634db14755686062589ecajrutt
77a7fd96f77f04bbd7634db14755686062589ecajrutt if ((Send_filter = (int (*)())dlsym(Dlp, "send_filter"))
77a7fd96f77f04bbd7634db14755686062589ecajrutt == NULL) {
77a7fd96f77f04bbd7634db14755686062589ecajrutt fmd_hdl_debug(hdl, "failed to dlsym send_filter()");
77a7fd96f77f04bbd7634db14755686062589ecajrutt Send_filter = NULL;
77a7fd96f77f04bbd7634db14755686062589ecajrutt }
77a7fd96f77f04bbd7634db14755686062589ecajrutt
77a7fd96f77f04bbd7634db14755686062589ecajrutt if ((Post_filter = (int (*)())dlsym(Dlp, "post_filter"))
77a7fd96f77f04bbd7634db14755686062589ecajrutt == NULL) {
77a7fd96f77f04bbd7634db14755686062589ecajrutt fmd_hdl_debug(hdl, "failed to dlsym post_filter()");
77a7fd96f77f04bbd7634db14755686062589ecajrutt Post_filter = NULL;
77a7fd96f77f04bbd7634db14755686062589ecajrutt }
77a7fd96f77f04bbd7634db14755686062589ecajrutt }
77a7fd96f77f04bbd7634db14755686062589ecajrutt
77a7fd96f77f04bbd7634db14755686062589ecajrutt fmd_prop_free_string(hdl, propstr);
77a7fd96f77f04bbd7634db14755686062589ecajrutt}
77a7fd96f77f04bbd7634db14755686062589ecajrutt
77a7fd96f77f04bbd7634db14755686062589ecajrutt/*
77a7fd96f77f04bbd7634db14755686062589ecajrutt * If open, dlclose() the platform filter library.
77a7fd96f77f04bbd7634db14755686062589ecajrutt */
77a7fd96f77f04bbd7634db14755686062589ecajrutt/*ARGSUSED*/
77a7fd96f77f04bbd7634db14755686062589ecajruttstatic void
77a7fd96f77f04bbd7634db14755686062589ecajruttexs_filter_fini(fmd_hdl_t *hdl)
77a7fd96f77f04bbd7634db14755686062589ecajrutt{
77a7fd96f77f04bbd7634db14755686062589ecajrutt if (Dlp != NULL)
77a7fd96f77f04bbd7634db14755686062589ecajrutt (void) dlclose(Dlp);
77a7fd96f77f04bbd7634db14755686062589ecajrutt}
77a7fd96f77f04bbd7634db14755686062589ecajrutt
d338766d6376ee721b7f1778e12bf79a112bd778jrutt/*
d338766d6376ee721b7f1778e12bf79a112bd778jrutt * Translate endpoint_id string to int.
d338766d6376ee721b7f1778e12bf79a112bd778jrutt * Return the domain ID via "dom_id".
d338766d6376ee721b7f1778e12bf79a112bd778jrutt * Return 0 for success, nonzero for failure
d338766d6376ee721b7f1778e12bf79a112bd778jrutt */
d338766d6376ee721b7f1778e12bf79a112bd778jruttstatic int
d338766d6376ee721b7f1778e12bf79a112bd778jruttexs_get_id(fmd_hdl_t *hdl, char *endpoint_id, int *dom_id)
d338766d6376ee721b7f1778e12bf79a112bd778jrutt{
d338766d6376ee721b7f1778e12bf79a112bd778jrutt char *ptr;
d338766d6376ee721b7f1778e12bf79a112bd778jrutt
d338766d6376ee721b7f1778e12bf79a112bd778jrutt if (strstr(endpoint_id, EXS_SP_PREFIX) != NULL) {
d338766d6376ee721b7f1778e12bf79a112bd778jrutt /* Remote endpoint is the SP */
d338766d6376ee721b7f1778e12bf79a112bd778jrutt *dom_id = DSCP_IDENT_SP;
d338766d6376ee721b7f1778e12bf79a112bd778jrutt return (0);
d338766d6376ee721b7f1778e12bf79a112bd778jrutt } else {
d338766d6376ee721b7f1778e12bf79a112bd778jrutt if ((ptr = strstr(endpoint_id, EXS_DOMAIN_PREFIX)) == NULL) {
ac92251dc182f030faf6a5f76981d551b0b16072jrutt fmd_hdl_error(hdl, "Property parsing error : %s not "
ac92251dc182f030faf6a5f76981d551b0b16072jrutt "found in %s. Check event-transport.conf\n",
d338766d6376ee721b7f1778e12bf79a112bd778jrutt EXS_DOMAIN_PREFIX, endpoint_id);
d338766d6376ee721b7f1778e12bf79a112bd778jrutt return (1);
d338766d6376ee721b7f1778e12bf79a112bd778jrutt }
d338766d6376ee721b7f1778e12bf79a112bd778jrutt
d338766d6376ee721b7f1778e12bf79a112bd778jrutt ptr += EXS_DOMAIN_PREFIX_LEN;
d338766d6376ee721b7f1778e12bf79a112bd778jrutt
d338766d6376ee721b7f1778e12bf79a112bd778jrutt if ((sscanf(ptr, "%d", dom_id)) != 1) {
ac92251dc182f030faf6a5f76981d551b0b16072jrutt fmd_hdl_error(hdl, "Property parsing error : no "
ac92251dc182f030faf6a5f76981d551b0b16072jrutt "integer found in %s. Check event-transport.conf\n",
d338766d6376ee721b7f1778e12bf79a112bd778jrutt endpoint_id);
ac92251dc182f030faf6a5f76981d551b0b16072jrutt return (2);
d338766d6376ee721b7f1778e12bf79a112bd778jrutt }
d338766d6376ee721b7f1778e12bf79a112bd778jrutt }
d338766d6376ee721b7f1778e12bf79a112bd778jrutt
d338766d6376ee721b7f1778e12bf79a112bd778jrutt return (0);
d338766d6376ee721b7f1778e12bf79a112bd778jrutt}
d338766d6376ee721b7f1778e12bf79a112bd778jrutt
25cf1a301a396c38e8adf52c15f537b80d2483f7jl/*
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * Prepare the client connection.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * Return 0 for success, nonzero for failure.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl */
25cf1a301a396c38e8adf52c15f537b80d2483f7jlstatic int
d338766d6376ee721b7f1778e12bf79a112bd778jruttexs_prep_client(exs_hdl_t *hp)
25cf1a301a396c38e8adf52c15f537b80d2483f7jl{
535096c2bb10e7c765411fcb939b54c081ba4e07jrutt int rv, optval = 1;
c0e3f49ac0b4f11393ded2ed1fdf519a0b57c098jrutt struct linger ling;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* Find the DSCP address for the remote endpoint */
d338766d6376ee721b7f1778e12bf79a112bd778jrutt if ((rv = dscpAddr(hp->h_dom, DSCP_ADDR_REMOTE,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (struct sockaddr *)&hp->h_client.c_saddr,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl &hp->h_client.c_len)) != DSCP_OK) {
ac92251dc182f030faf6a5f76981d551b0b16072jrutt fmd_hdl_debug(hp->h_hdl, "dscpAddr on the client socket "
d338766d6376ee721b7f1778e12bf79a112bd778jrutt "failed for %s : rv = %d\n", hp->h_endpt_id, rv);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (1);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if ((hp->h_client.c_sd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
ac92251dc182f030faf6a5f76981d551b0b16072jrutt fmd_hdl_error(hp->h_hdl, "Failed to create the client socket "
d338766d6376ee721b7f1778e12bf79a112bd778jrutt "for %s", hp->h_endpt_id);
d338766d6376ee721b7f1778e12bf79a112bd778jrutt return (2);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
535096c2bb10e7c765411fcb939b54c081ba4e07jrutt if (setsockopt(hp->h_client.c_sd, SOL_SOCKET, SO_REUSEADDR,
535096c2bb10e7c765411fcb939b54c081ba4e07jrutt &optval, sizeof (optval))) {
ac92251dc182f030faf6a5f76981d551b0b16072jrutt fmd_hdl_error(hp->h_hdl, "Failed to set REUSEADDR on the "
535096c2bb10e7c765411fcb939b54c081ba4e07jrutt "client socket for %s", hp->h_endpt_id);
ac92251dc182f030faf6a5f76981d551b0b16072jrutt EXS_CLOSE_CLR(hp->h_client);
535096c2bb10e7c765411fcb939b54c081ba4e07jrutt return (3);
535096c2bb10e7c765411fcb939b54c081ba4e07jrutt }
535096c2bb10e7c765411fcb939b54c081ba4e07jrutt
c0e3f49ac0b4f11393ded2ed1fdf519a0b57c098jrutt /*
c0e3f49ac0b4f11393ded2ed1fdf519a0b57c098jrutt * Set SO_LINGER so TCP aborts the connection when closed.
c0e3f49ac0b4f11393ded2ed1fdf519a0b57c098jrutt * If the domain's client socket goes into the TIME_WAIT state,
c0e3f49ac0b4f11393ded2ed1fdf519a0b57c098jrutt * ETM will be unable to connect to the SP until this clears.
c0e3f49ac0b4f11393ded2ed1fdf519a0b57c098jrutt * This connection is over DSCP, which is a simple point-to-point
c0e3f49ac0b4f11393ded2ed1fdf519a0b57c098jrutt * connection and therefore has no routers or multiple forwarding.
c0e3f49ac0b4f11393ded2ed1fdf519a0b57c098jrutt * The risk of receiving old packets from a previously terminated
c0e3f49ac0b4f11393ded2ed1fdf519a0b57c098jrutt * connection is very small.
c0e3f49ac0b4f11393ded2ed1fdf519a0b57c098jrutt */
c0e3f49ac0b4f11393ded2ed1fdf519a0b57c098jrutt ling.l_onoff = 1;
c0e3f49ac0b4f11393ded2ed1fdf519a0b57c098jrutt ling.l_linger = 0;
c0e3f49ac0b4f11393ded2ed1fdf519a0b57c098jrutt if (setsockopt(hp->h_client.c_sd, SOL_SOCKET, SO_LINGER, &ling,
c0e3f49ac0b4f11393ded2ed1fdf519a0b57c098jrutt sizeof (ling))) {
ac92251dc182f030faf6a5f76981d551b0b16072jrutt fmd_hdl_error(hp->h_hdl, "Failed to set SO_LINGER on the "
c0e3f49ac0b4f11393ded2ed1fdf519a0b57c098jrutt "client socket for %s", hp->h_endpt_id);
ac92251dc182f030faf6a5f76981d551b0b16072jrutt EXS_CLOSE_CLR(hp->h_client);
c0e3f49ac0b4f11393ded2ed1fdf519a0b57c098jrutt return (4);
c0e3f49ac0b4f11393ded2ed1fdf519a0b57c098jrutt }
c0e3f49ac0b4f11393ded2ed1fdf519a0b57c098jrutt
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* Bind the socket to the local IP address of the DSCP link */
d338766d6376ee721b7f1778e12bf79a112bd778jrutt if ((rv = dscpBind(hp->h_dom, hp->h_client.c_sd,
25cf1a301a396c38e8adf52c15f537b80d2483f7jl EXS_CLIENT_PORT)) != DSCP_OK) {
ac92251dc182f030faf6a5f76981d551b0b16072jrutt if (rv == DSCP_ERROR_DOWN) {
ac92251dc182f030faf6a5f76981d551b0b16072jrutt fmd_hdl_debug(hp->h_hdl, "xport - dscp link for %s "
ac92251dc182f030faf6a5f76981d551b0b16072jrutt "is down", hp->h_endpt_id);
ac92251dc182f030faf6a5f76981d551b0b16072jrutt } else {
677fd05c3b05c78948501f6ffdced37dab9368feMary Beale fmd_hdl_debug(hp->h_hdl, "dscpBind on the client "
ac92251dc182f030faf6a5f76981d551b0b16072jrutt "socket failed : rv = %d\n", rv);
ac92251dc182f030faf6a5f76981d551b0b16072jrutt }
ac92251dc182f030faf6a5f76981d551b0b16072jrutt EXS_CLOSE_CLR(hp->h_client);
c0e3f49ac0b4f11393ded2ed1fdf519a0b57c098jrutt return (5);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl hp->h_client.c_saddr.sin_port = htons(EXS_SERVER_PORT);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* Set IPsec security policy for this socket */
d338766d6376ee721b7f1778e12bf79a112bd778jrutt if ((rv = dscpSecure(hp->h_dom, hp->h_client.c_sd)) != DSCP_OK) {
ac92251dc182f030faf6a5f76981d551b0b16072jrutt fmd_hdl_error(hp->h_hdl, "dscpSecure on the client socket "
d338766d6376ee721b7f1778e12bf79a112bd778jrutt "failed for %s : rv = %d\n", hp->h_endpt_id, rv);
ac92251dc182f030faf6a5f76981d551b0b16072jrutt EXS_CLOSE_CLR(hp->h_client);
c0e3f49ac0b4f11393ded2ed1fdf519a0b57c098jrutt return (6);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (0);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl}
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl/*
ac92251dc182f030faf6a5f76981d551b0b16072jrutt * Server function/thread. There is one thread per endpoint.
ac92251dc182f030faf6a5f76981d551b0b16072jrutt * Accepts incoming connections and notifies ETM of incoming data.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl */
ac92251dc182f030faf6a5f76981d551b0b16072jruttvoid
ac92251dc182f030faf6a5f76981d551b0b16072jruttexs_server(void *arg)
25cf1a301a396c38e8adf52c15f537b80d2483f7jl{
ac92251dc182f030faf6a5f76981d551b0b16072jrutt exs_hdl_t *hp = (exs_hdl_t *)arg;
ac92251dc182f030faf6a5f76981d551b0b16072jrutt struct pollfd pfd;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
ac92251dc182f030faf6a5f76981d551b0b16072jrutt while (!hp->h_quit) {
ac92251dc182f030faf6a5f76981d551b0b16072jrutt pfd.events = POLLIN;
ac92251dc182f030faf6a5f76981d551b0b16072jrutt pfd.revents = 0;
ac92251dc182f030faf6a5f76981d551b0b16072jrutt pfd.fd = hp->h_server.c_sd;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
ac92251dc182f030faf6a5f76981d551b0b16072jrutt if (poll(&pfd, 1, -1) <= 0)
ac92251dc182f030faf6a5f76981d551b0b16072jrutt continue; /* loop around and check h_quit */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
ac92251dc182f030faf6a5f76981d551b0b16072jrutt if (pfd.revents & (POLLHUP | POLLERR)) {
ac92251dc182f030faf6a5f76981d551b0b16072jrutt fmd_hdl_debug(hp->h_hdl, "xport - poll hangup/err for "
ac92251dc182f030faf6a5f76981d551b0b16072jrutt "%s server socket", hp->h_endpt_id);
ac92251dc182f030faf6a5f76981d551b0b16072jrutt EXS_CLOSE_CLR(hp->h_server);
ac92251dc182f030faf6a5f76981d551b0b16072jrutt hp->h_destroy++;
ac92251dc182f030faf6a5f76981d551b0b16072jrutt break; /* thread exits */
ac92251dc182f030faf6a5f76981d551b0b16072jrutt }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
ac92251dc182f030faf6a5f76981d551b0b16072jrutt if (pfd.revents & POLLIN) {
ac92251dc182f030faf6a5f76981d551b0b16072jrutt /* Notify ETM that incoming data is available */
ac92251dc182f030faf6a5f76981d551b0b16072jrutt if (hp->h_cb_func(hp->h_hdl, &hp->h_server,
ac92251dc182f030faf6a5f76981d551b0b16072jrutt ETM_CBFLAG_RECV, hp->h_cb_func_arg)) {
ac92251dc182f030faf6a5f76981d551b0b16072jrutt /*
ac92251dc182f030faf6a5f76981d551b0b16072jrutt * For any non-zero return, close the
ac92251dc182f030faf6a5f76981d551b0b16072jrutt * connection and exit the thread.
ac92251dc182f030faf6a5f76981d551b0b16072jrutt */
ac92251dc182f030faf6a5f76981d551b0b16072jrutt EXS_CLOSE_CLR(hp->h_server);
ac92251dc182f030faf6a5f76981d551b0b16072jrutt hp->h_destroy++;
ac92251dc182f030faf6a5f76981d551b0b16072jrutt break; /* thread exits */
ac92251dc182f030faf6a5f76981d551b0b16072jrutt }
ac92251dc182f030faf6a5f76981d551b0b16072jrutt }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
ac92251dc182f030faf6a5f76981d551b0b16072jrutt fmd_hdl_debug(hp->h_hdl, "xport - exiting server thread for %s",
ac92251dc182f030faf6a5f76981d551b0b16072jrutt hp->h_endpt_id);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl}
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl/*
d338766d6376ee721b7f1778e12bf79a112bd778jrutt * Accept a new incoming connection.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl */
d338766d6376ee721b7f1778e12bf79a112bd778jruttstatic void
ac92251dc182f030faf6a5f76981d551b0b16072jruttexs_accept(fmd_hdl_t *hdl)
25cf1a301a396c38e8adf52c15f537b80d2483f7jl{
d338766d6376ee721b7f1778e12bf79a112bd778jrutt int new_sd, dom, flags, rv;
d338766d6376ee721b7f1778e12bf79a112bd778jrutt struct sockaddr_in new_saddr;
d338766d6376ee721b7f1778e12bf79a112bd778jrutt socklen_t new_len = sizeof (struct sockaddr);
ac92251dc182f030faf6a5f76981d551b0b16072jrutt exs_hdl_t *hp;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
ac92251dc182f030faf6a5f76981d551b0b16072jrutt if ((new_sd = accept(Acc.c_sd, (struct sockaddr *)&new_saddr,
d338766d6376ee721b7f1778e12bf79a112bd778jrutt &new_len)) != -1) {
d338766d6376ee721b7f1778e12bf79a112bd778jrutt /* Translate saddr to domain id */
d338766d6376ee721b7f1778e12bf79a112bd778jrutt if ((rv = dscpIdent((struct sockaddr *)&new_saddr, (int)new_len,
d338766d6376ee721b7f1778e12bf79a112bd778jrutt &dom)) != DSCP_OK) {
ac92251dc182f030faf6a5f76981d551b0b16072jrutt fmd_hdl_error(hdl, "dscpIdent failed : rv = %d\n", rv);
ac92251dc182f030faf6a5f76981d551b0b16072jrutt (void) close(new_sd);
d338766d6376ee721b7f1778e12bf79a112bd778jrutt return;
d338766d6376ee721b7f1778e12bf79a112bd778jrutt }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
ac92251dc182f030faf6a5f76981d551b0b16072jrutt /* Find the exs_hdl_t for the domain trying to connect */
ac92251dc182f030faf6a5f76981d551b0b16072jrutt (void) pthread_mutex_lock(&List_lock);
ac92251dc182f030faf6a5f76981d551b0b16072jrutt for (hp = Exh_head; hp; hp = hp->h_next) {
ac92251dc182f030faf6a5f76981d551b0b16072jrutt if (hp->h_dom == dom)
ac92251dc182f030faf6a5f76981d551b0b16072jrutt break;
ac92251dc182f030faf6a5f76981d551b0b16072jrutt }
ac92251dc182f030faf6a5f76981d551b0b16072jrutt (void) pthread_mutex_unlock(&List_lock);
ac92251dc182f030faf6a5f76981d551b0b16072jrutt
ac92251dc182f030faf6a5f76981d551b0b16072jrutt if (hp == NULL) {
ac92251dc182f030faf6a5f76981d551b0b16072jrutt fmd_hdl_error(hdl, "Not configured to accept a "
ac92251dc182f030faf6a5f76981d551b0b16072jrutt "connection from domain %d. Check "
ac92251dc182f030faf6a5f76981d551b0b16072jrutt "event-transport.conf\n", dom);
ac92251dc182f030faf6a5f76981d551b0b16072jrutt (void) close(new_sd);
d338766d6376ee721b7f1778e12bf79a112bd778jrutt return;
d338766d6376ee721b7f1778e12bf79a112bd778jrutt }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
d338766d6376ee721b7f1778e12bf79a112bd778jrutt /* Authenticate this connection request */
d338766d6376ee721b7f1778e12bf79a112bd778jrutt if ((rv = dscpAuth(dom, (struct sockaddr *)&new_saddr,
d338766d6376ee721b7f1778e12bf79a112bd778jrutt (int)new_len)) != DSCP_OK) {
ac92251dc182f030faf6a5f76981d551b0b16072jrutt fmd_hdl_error(hdl, "dscpAuth failed for %s : rv = %d ",
ac92251dc182f030faf6a5f76981d551b0b16072jrutt " Possible spoofing attack\n", hp->h_endpt_id, rv);
ac92251dc182f030faf6a5f76981d551b0b16072jrutt (void) close(new_sd);
d338766d6376ee721b7f1778e12bf79a112bd778jrutt return;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
ac92251dc182f030faf6a5f76981d551b0b16072jrutt if (hp->h_tid != EXS_TID_FREE) {
ac92251dc182f030faf6a5f76981d551b0b16072jrutt hp->h_quit = 1;
ac92251dc182f030faf6a5f76981d551b0b16072jrutt fmd_thr_signal(hp->h_hdl, hp->h_tid);
ac92251dc182f030faf6a5f76981d551b0b16072jrutt fmd_thr_destroy(hp->h_hdl, hp->h_tid);
ac92251dc182f030faf6a5f76981d551b0b16072jrutt hp->h_destroy = 0;
ac92251dc182f030faf6a5f76981d551b0b16072jrutt hp->h_quit = 0;
d338766d6376ee721b7f1778e12bf79a112bd778jrutt }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
ac92251dc182f030faf6a5f76981d551b0b16072jrutt if (hp->h_server.c_sd != EXS_SD_FREE)
ac92251dc182f030faf6a5f76981d551b0b16072jrutt EXS_CLOSE_CLR(hp->h_server);
ac92251dc182f030faf6a5f76981d551b0b16072jrutt
d338766d6376ee721b7f1778e12bf79a112bd778jrutt /* Set the socket to be non-blocking */
d338766d6376ee721b7f1778e12bf79a112bd778jrutt flags = fcntl(new_sd, F_GETFL, 0);
d338766d6376ee721b7f1778e12bf79a112bd778jrutt (void) fcntl(new_sd, F_SETFL, flags | O_NONBLOCK);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
d338766d6376ee721b7f1778e12bf79a112bd778jrutt hp->h_server.c_sd = new_sd;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
ac92251dc182f030faf6a5f76981d551b0b16072jrutt hp->h_tid = fmd_thr_create(hdl, exs_server, hp);
ac92251dc182f030faf6a5f76981d551b0b16072jrutt
d338766d6376ee721b7f1778e12bf79a112bd778jrutt } else {
45179f4335d029f1129eb7283f8087740f0395f1Karl Davis fmd_hdl_error(hdl, "Failed to accept() a new connection");
d338766d6376ee721b7f1778e12bf79a112bd778jrutt }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl}
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl/*
ac92251dc182f030faf6a5f76981d551b0b16072jrutt * Listen for and accept incoming connections.
ac92251dc182f030faf6a5f76981d551b0b16072jrutt * There is only one such thread.
25cf1a301a396c38e8adf52c15f537b80d2483f7jl */
d338766d6376ee721b7f1778e12bf79a112bd778jruttvoid
ac92251dc182f030faf6a5f76981d551b0b16072jruttexs_listen(void *arg)
25cf1a301a396c38e8adf52c15f537b80d2483f7jl{
ac92251dc182f030faf6a5f76981d551b0b16072jrutt fmd_hdl_t *hdl = (fmd_hdl_t *)arg;
ac92251dc182f030faf6a5f76981d551b0b16072jrutt struct pollfd pfd;
ac92251dc182f030faf6a5f76981d551b0b16072jrutt
ac92251dc182f030faf6a5f76981d551b0b16072jrutt while (!Acc_quit) {
ac92251dc182f030faf6a5f76981d551b0b16072jrutt pfd.events = POLLIN;
ac92251dc182f030faf6a5f76981d551b0b16072jrutt pfd.revents = 0;
ac92251dc182f030faf6a5f76981d551b0b16072jrutt pfd.fd = Acc.c_sd;
ac92251dc182f030faf6a5f76981d551b0b16072jrutt
ac92251dc182f030faf6a5f76981d551b0b16072jrutt if (poll(&pfd, 1, -1) <= 0)
ac92251dc182f030faf6a5f76981d551b0b16072jrutt continue; /* loop around and check Acc_quit */
ac92251dc182f030faf6a5f76981d551b0b16072jrutt
ac92251dc182f030faf6a5f76981d551b0b16072jrutt if (pfd.revents & (POLLHUP | POLLERR)) {
ac92251dc182f030faf6a5f76981d551b0b16072jrutt fmd_hdl_debug(hdl, "xport - poll hangup/err on "
ac92251dc182f030faf6a5f76981d551b0b16072jrutt "accept socket");
ac92251dc182f030faf6a5f76981d551b0b16072jrutt EXS_CLOSE_CLR(Acc);
ac92251dc182f030faf6a5f76981d551b0b16072jrutt Acc_destroy++;
ac92251dc182f030faf6a5f76981d551b0b16072jrutt break; /* thread exits */
ac92251dc182f030faf6a5f76981d551b0b16072jrutt }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
ac92251dc182f030faf6a5f76981d551b0b16072jrutt if (pfd.revents & POLLIN)
ac92251dc182f030faf6a5f76981d551b0b16072jrutt exs_accept(hdl);
ac92251dc182f030faf6a5f76981d551b0b16072jrutt }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
ac92251dc182f030faf6a5f76981d551b0b16072jrutt fmd_hdl_debug(hdl, "xport - exiting accept-listen thread");
ac92251dc182f030faf6a5f76981d551b0b16072jrutt}
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
ac92251dc182f030faf6a5f76981d551b0b16072jrutt/*
ac92251dc182f030faf6a5f76981d551b0b16072jrutt * Prepare to accept a connection.
ac92251dc182f030faf6a5f76981d551b0b16072jrutt * Return 0 for success, nonzero for failure.
ac92251dc182f030faf6a5f76981d551b0b16072jrutt */
ac92251dc182f030faf6a5f76981d551b0b16072jruttvoid
ac92251dc182f030faf6a5f76981d551b0b16072jruttexs_prep_accept(fmd_hdl_t *hdl, int dom)
ac92251dc182f030faf6a5f76981d551b0b16072jrutt{
ac92251dc182f030faf6a5f76981d551b0b16072jrutt int flags, optval = 1;
ac92251dc182f030faf6a5f76981d551b0b16072jrutt int rv;
d338766d6376ee721b7f1778e12bf79a112bd778jrutt
ac92251dc182f030faf6a5f76981d551b0b16072jrutt if (Acc.c_sd != EXS_SD_FREE)
ac92251dc182f030faf6a5f76981d551b0b16072jrutt return; /* nothing to do */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
ac92251dc182f030faf6a5f76981d551b0b16072jrutt if (Acc_destroy) {
ac92251dc182f030faf6a5f76981d551b0b16072jrutt fmd_thr_destroy(hdl, Acc_tid);
ac92251dc182f030faf6a5f76981d551b0b16072jrutt Acc_tid = EXS_TID_FREE;
ac92251dc182f030faf6a5f76981d551b0b16072jrutt }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
ac92251dc182f030faf6a5f76981d551b0b16072jrutt /* Check to see if the DSCP interface is configured */
ac92251dc182f030faf6a5f76981d551b0b16072jrutt if ((rv = dscpAddr(dom, DSCP_ADDR_LOCAL,
ac92251dc182f030faf6a5f76981d551b0b16072jrutt (struct sockaddr *)&Acc.c_saddr, &Acc.c_len)) != DSCP_OK) {
ac92251dc182f030faf6a5f76981d551b0b16072jrutt fmd_hdl_debug(hdl, "xport - dscpAddr on the accept socket "
ac92251dc182f030faf6a5f76981d551b0b16072jrutt "failed for domain %d : rv = %d", dom, rv);
ac92251dc182f030faf6a5f76981d551b0b16072jrutt return;
ac92251dc182f030faf6a5f76981d551b0b16072jrutt }
d338766d6376ee721b7f1778e12bf79a112bd778jrutt
ac92251dc182f030faf6a5f76981d551b0b16072jrutt if ((Acc.c_sd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
ac92251dc182f030faf6a5f76981d551b0b16072jrutt fmd_hdl_error(hdl, "Failed to create the accept socket");
ac92251dc182f030faf6a5f76981d551b0b16072jrutt return;
ac92251dc182f030faf6a5f76981d551b0b16072jrutt }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
ac92251dc182f030faf6a5f76981d551b0b16072jrutt if (setsockopt(Acc.c_sd, SOL_SOCKET, SO_REUSEADDR, &optval,
ac92251dc182f030faf6a5f76981d551b0b16072jrutt sizeof (optval))) {
ac92251dc182f030faf6a5f76981d551b0b16072jrutt fmd_hdl_error(hdl, "Failed to set REUSEADDR for the accept "
ac92251dc182f030faf6a5f76981d551b0b16072jrutt "socket");
ac92251dc182f030faf6a5f76981d551b0b16072jrutt EXS_CLOSE_CLR(Acc);
ac92251dc182f030faf6a5f76981d551b0b16072jrutt return;
ac92251dc182f030faf6a5f76981d551b0b16072jrutt }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
ac92251dc182f030faf6a5f76981d551b0b16072jrutt /* Bind the socket to the local IP address of the DSCP link */
ac92251dc182f030faf6a5f76981d551b0b16072jrutt if ((rv = dscpBind(dom, Acc.c_sd, EXS_SERVER_PORT)) != DSCP_OK) {
ac92251dc182f030faf6a5f76981d551b0b16072jrutt if (rv == DSCP_ERROR_DOWN) {
ac92251dc182f030faf6a5f76981d551b0b16072jrutt fmd_hdl_debug(hdl, "xport - dscp link for domain %d "
ac92251dc182f030faf6a5f76981d551b0b16072jrutt "is down", dom);
ac92251dc182f030faf6a5f76981d551b0b16072jrutt } else {
677fd05c3b05c78948501f6ffdced37dab9368feMary Beale fmd_hdl_debug(hdl, "dscpBind on the accept socket "
ac92251dc182f030faf6a5f76981d551b0b16072jrutt "failed : rv = %d\n", rv);
ac92251dc182f030faf6a5f76981d551b0b16072jrutt }
ac92251dc182f030faf6a5f76981d551b0b16072jrutt EXS_CLOSE_CLR(Acc);
ac92251dc182f030faf6a5f76981d551b0b16072jrutt return;
d338766d6376ee721b7f1778e12bf79a112bd778jrutt }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
ac92251dc182f030faf6a5f76981d551b0b16072jrutt /* Activate IPsec security policy for this socket */
ac92251dc182f030faf6a5f76981d551b0b16072jrutt if ((rv = dscpSecure(dom, Acc.c_sd)) != DSCP_OK) {
ac92251dc182f030faf6a5f76981d551b0b16072jrutt fmd_hdl_error(hdl, "dscpSecure on the accept socket failed : "
ac92251dc182f030faf6a5f76981d551b0b16072jrutt "rv = %d\n", dom, rv);
ac92251dc182f030faf6a5f76981d551b0b16072jrutt EXS_CLOSE_CLR(Acc);
ac92251dc182f030faf6a5f76981d551b0b16072jrutt return;
ac92251dc182f030faf6a5f76981d551b0b16072jrutt }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
ac92251dc182f030faf6a5f76981d551b0b16072jrutt if ((listen(Acc.c_sd, EXS_NUM_SOCKS)) == -1) {
ac92251dc182f030faf6a5f76981d551b0b16072jrutt fmd_hdl_debug(hdl, "Failed to listen() for connections");
ac92251dc182f030faf6a5f76981d551b0b16072jrutt EXS_CLOSE_CLR(Acc);
ac92251dc182f030faf6a5f76981d551b0b16072jrutt return;
ac92251dc182f030faf6a5f76981d551b0b16072jrutt }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
ac92251dc182f030faf6a5f76981d551b0b16072jrutt flags = fcntl(Acc.c_sd, F_GETFL, 0);
ac92251dc182f030faf6a5f76981d551b0b16072jrutt (void) fcntl(Acc.c_sd, F_SETFL, flags | O_NONBLOCK);
ac92251dc182f030faf6a5f76981d551b0b16072jrutt
ac92251dc182f030faf6a5f76981d551b0b16072jrutt Acc_tid = fmd_thr_create(hdl, exs_listen, hdl);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl}
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl/*
d338766d6376ee721b7f1778e12bf79a112bd778jrutt * * * * * * * * * * * * * * * * * * * * * * * * * * *
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * ETM-to-Transport API Connection Management routines
d338766d6376ee721b7f1778e12bf79a112bd778jrutt * * * * * * * * * * * * * * * * * * * * * * * * * * *
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;
d338766d6376ee721b7f1778e12bf79a112bd778jrutt int dom;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
ac92251dc182f030faf6a5f76981d551b0b16072jrutt if (exs_get_id(hdl, endpoint_id, &dom))
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (NULL);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) pthread_mutex_lock(&List_lock);
d338766d6376ee721b7f1778e12bf79a112bd778jrutt
d338766d6376ee721b7f1778e12bf79a112bd778jrutt /* Check for a duplicate endpoint_id on the list */
d338766d6376ee721b7f1778e12bf79a112bd778jrutt for (curr = Exh_head; curr; curr = curr->h_next) {
d338766d6376ee721b7f1778e12bf79a112bd778jrutt if (dom == curr->h_dom) {
d338766d6376ee721b7f1778e12bf79a112bd778jrutt fmd_hdl_debug(hdl, "xport - init failed, "
d338766d6376ee721b7f1778e12bf79a112bd778jrutt "duplicate domain id : %d\n", dom);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) pthread_mutex_unlock(&List_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl return (NULL);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
77a7fd96f77f04bbd7634db14755686062589ecajrutt if (Exh_head == NULL) {
77a7fd96f77f04bbd7634db14755686062589ecajrutt /* Do one-time initializations */
77a7fd96f77f04bbd7634db14755686062589ecajrutt exs_filter_init(hdl);
ac92251dc182f030faf6a5f76981d551b0b16072jrutt
ac92251dc182f030faf6a5f76981d551b0b16072jrutt /* Initialize the accept/listen vars */
ac92251dc182f030faf6a5f76981d551b0b16072jrutt Acc.c_sd = EXS_SD_FREE;
ac92251dc182f030faf6a5f76981d551b0b16072jrutt Acc_tid = EXS_TID_FREE;
ac92251dc182f030faf6a5f76981d551b0b16072jrutt Acc_destroy = 0;
ac92251dc182f030faf6a5f76981d551b0b16072jrutt Acc_quit = 0;
77a7fd96f77f04bbd7634db14755686062589ecajrutt }
77a7fd96f77f04bbd7634db14755686062589ecajrutt
d338766d6376ee721b7f1778e12bf79a112bd778jrutt hp = exs_hdl_alloc(hdl, endpoint_id, cb_func, cb_func_arg, dom);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl /* Add this transport instance handle to the list */
25cf1a301a396c38e8adf52c15f537b80d2483f7jl hp->h_next = Exh_head;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl Exh_head = hp;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
d338766d6376ee721b7f1778e12bf79a112bd778jrutt (void) pthread_mutex_unlock(&List_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
ac92251dc182f030faf6a5f76981d551b0b16072jrutt exs_prep_accept(hdl, dom);
ac92251dc182f030faf6a5f76981d551b0b16072jrutt
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;
ac92251dc182f030faf6a5f76981d551b0b16072jrutt exs_hdl_t *xp, **ppx;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) pthread_mutex_lock(&List_lock);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
ac92251dc182f030faf6a5f76981d551b0b16072jrutt ppx = &Exh_head;
ac92251dc182f030faf6a5f76981d551b0b16072jrutt
d338766d6376ee721b7f1778e12bf79a112bd778jrutt for (xp = *ppx; xp; xp = xp->h_next) {
d338766d6376ee721b7f1778e12bf79a112bd778jrutt if (xp != hp)
d338766d6376ee721b7f1778e12bf79a112bd778jrutt ppx = &xp->h_next;
d338766d6376ee721b7f1778e12bf79a112bd778jrutt else
25cf1a301a396c38e8adf52c15f537b80d2483f7jl break;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
d338766d6376ee721b7f1778e12bf79a112bd778jrutt if (xp != hp) {
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) pthread_mutex_unlock(&List_lock);
d338766d6376ee721b7f1778e12bf79a112bd778jrutt fmd_hdl_abort(hdl, "xport - fini failed, tlhdl %p not on list",
d338766d6376ee721b7f1778e12bf79a112bd778jrutt (void *)hp);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
d338766d6376ee721b7f1778e12bf79a112bd778jrutt *ppx = hp->h_next;
d338766d6376ee721b7f1778e12bf79a112bd778jrutt hp->h_next = NULL;
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
d338766d6376ee721b7f1778e12bf79a112bd778jrutt if (hp->h_tid != EXS_TID_FREE) {
d338766d6376ee721b7f1778e12bf79a112bd778jrutt hp->h_quit = 1;
d338766d6376ee721b7f1778e12bf79a112bd778jrutt fmd_thr_signal(hdl, hp->h_tid);
d338766d6376ee721b7f1778e12bf79a112bd778jrutt fmd_thr_destroy(hdl, hp->h_tid);
d338766d6376ee721b7f1778e12bf79a112bd778jrutt }
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
ac92251dc182f030faf6a5f76981d551b0b16072jrutt if (hp->h_server.c_sd != EXS_SD_FREE)
ac92251dc182f030faf6a5f76981d551b0b16072jrutt (void) close(hp->h_server.c_sd);
ac92251dc182f030faf6a5f76981d551b0b16072jrutt
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (hp->h_client.c_sd != EXS_SD_FREE)
25cf1a301a396c38e8adf52c15f537b80d2483f7jl (void) close(hp->h_client.c_sd);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
25cf1a301a396c38e8adf52c15f537b80d2483f7jl fmd_hdl_strfree(hdl, hp->h_endpt_id);
25cf1a301a396c38e8adf52c15f537b80d2483f7jl fmd_hdl_free(hdl, hp, sizeof (exs_hdl_t));
25cf1a301a396c38e8adf52c15f537b80d2483f7jl
77a7fd96f77f04bbd7634db14755686062589ecajrutt if (Exh_head == NULL) {
77a7fd96f77f04bbd7634db14755686062589ecajrutt /* Undo one-time initializations */
77a7fd96f77f04bbd7634db14755686062589ecajrutt exs_filter_fini(hdl);
ac92251dc182f030faf6a5f76981d551b0b16072jrutt
ac92251dc182f030faf6a5f76981d551b0b16072jrutt /* Destroy the accept/listen thread */
ac92251dc182f030faf6a5f76981d551b0b16072jrutt if (Acc_tid != EXS_TID_FREE) {
ac92251dc182f030faf6a5f76981d551b0b16072jrutt Acc_quit = 1;
ac92251dc182f030faf6a5f76981d551b0b16072jrutt fmd_thr_signal(hdl, Acc_tid);
ac92251dc182f030faf6a5f76981d551b0b16072jrutt fmd_thr_destroy(hdl, Acc_tid);
ac92251dc182f030faf6a5f76981d551b0b16072jrutt }
ac92251dc182f030faf6a5f76981d551b0b16072jrutt
ac92251dc182f030faf6a5f76981d551b0b16072jrutt if (Acc.c_sd != EXS_SD_FREE)
ac92251dc182f030faf6a5f76981d551b0b16072jrutt EXS_CLOSE_CLR(Acc);
77a7fd96f77f04bbd7634db14755686062589ecajrutt }
77a7fd96f77f04bbd7634db14755686062589ecajrutt
d338766d6376ee721b7f1778e12bf79a112bd778jrutt (void) pthread_mutex_unlock(&List_lock);
d338766d6376ee721b7f1778e12bf79a112bd778jrutt
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
4573608322e68a31a57d0d851d7b324f4ffb66b5jrutt if (hp->h_destroy) {
4573608322e68a31a57d0d851d7b324f4ffb66b5jrutt fmd_thr_destroy(hp->h_hdl, hp->h_tid);
4573608322e68a31a57d0d851d7b324f4ffb66b5jrutt hp->h_tid = EXS_TID_FREE;
4573608322e68a31a57d0d851d7b324f4ffb66b5jrutt hp->h_destroy = 0;
4573608322e68a31a57d0d851d7b324f4ffb66b5jrutt }
4573608322e68a31a57d0d851d7b324f4ffb66b5jrutt
25cf1a301a396c38e8adf52c15f537b80d2483f7jl if (hp->h_client.c_sd == EXS_SD_FREE) {
d338766d6376ee721b7f1778e12bf79a112bd778jrutt if (exs_prep_client(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) {
ac92251dc182f030faf6a5f76981d551b0b16072jrutt fmd_hdl_debug(hdl, "xport - failed to connect to %s",
154b1f02449b21af9273efd1a7776a3fe65a0744jrutt hp->h_endpt_id);
ac92251dc182f030faf6a5f76981d551b0b16072jrutt EXS_CLOSE_CLR(hp->h_client);
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/*
d338766d6376ee721b7f1778e12bf79a112bd778jrutt * * * * * * * * * * * * * * * * * *
25cf1a301a396c38e8adf52c15f537b80d2483f7jl * ETM-to-Transport API I/O routines
d338766d6376ee721b7f1778e12bf79a112bd778jrutt * * * * * * * * * * * * * * * * * *
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}
77a7fd96f77f04bbd7634db14755686062589ecajrutt
77a7fd96f77f04bbd7634db14755686062589ecajrutt/*
77a7fd96f77f04bbd7634db14755686062589ecajrutt * * * * * * * * * * * * * * * * * * * *
77a7fd96f77f04bbd7634db14755686062589ecajrutt * ETM-to-Transport API Filter routines
77a7fd96f77f04bbd7634db14755686062589ecajrutt * * * * * * * * * * * * * * * * * * * *
77a7fd96f77f04bbd7634db14755686062589ecajrutt */
77a7fd96f77f04bbd7634db14755686062589ecajrutt
77a7fd96f77f04bbd7634db14755686062589ecajrutt/*
77a7fd96f77f04bbd7634db14755686062589ecajrutt * Call the platform's send_filter function.
77a7fd96f77f04bbd7634db14755686062589ecajrutt * Otherwise return ETM_XPORT_FILTER_OK.
77a7fd96f77f04bbd7634db14755686062589ecajrutt */
77a7fd96f77f04bbd7634db14755686062589ecajruttint
77a7fd96f77f04bbd7634db14755686062589ecajruttetm_xport_send_filter(fmd_hdl_t *hdl, nvlist_t *event, const char *dest)
77a7fd96f77f04bbd7634db14755686062589ecajrutt{
77a7fd96f77f04bbd7634db14755686062589ecajrutt if (Send_filter != NULL)
77a7fd96f77f04bbd7634db14755686062589ecajrutt return (Send_filter(hdl, event, dest));
77a7fd96f77f04bbd7634db14755686062589ecajrutt else
77a7fd96f77f04bbd7634db14755686062589ecajrutt return (ETM_XPORT_FILTER_OK);
77a7fd96f77f04bbd7634db14755686062589ecajrutt}
77a7fd96f77f04bbd7634db14755686062589ecajrutt
77a7fd96f77f04bbd7634db14755686062589ecajrutt/*
77a7fd96f77f04bbd7634db14755686062589ecajrutt * Call the platform's post_filter function.
77a7fd96f77f04bbd7634db14755686062589ecajrutt * Otherwise return ETM_XPORT_FILTER_OK.
77a7fd96f77f04bbd7634db14755686062589ecajrutt */
77a7fd96f77f04bbd7634db14755686062589ecajruttint
77a7fd96f77f04bbd7634db14755686062589ecajruttetm_xport_post_filter(fmd_hdl_t *hdl, nvlist_t *event, const char *src)
77a7fd96f77f04bbd7634db14755686062589ecajrutt{
77a7fd96f77f04bbd7634db14755686062589ecajrutt if (Post_filter != NULL)
77a7fd96f77f04bbd7634db14755686062589ecajrutt return (Post_filter(hdl, event, src));
77a7fd96f77f04bbd7634db14755686062589ecajrutt else
77a7fd96f77f04bbd7634db14755686062589ecajrutt return (ETM_XPORT_FILTER_OK);
77a7fd96f77f04bbd7634db14755686062589ecajrutt}