Esempio n. 1
0
/*
 * Teardown any transport infrastructure after all connections are closed.
 * Return 0 for success, or nonzero for failure.
 */
int
etm_xport_fini(fmd_hdl_t *hdl, etm_xport_hdl_t tlhdl)
{
	exs_hdl_t *hp = (exs_hdl_t *)tlhdl;
	exs_hdl_t *xp, **ppx;

	(void) pthread_mutex_lock(&List_lock);

	ppx = &Exh_head;

	for (xp = *ppx; xp; xp = xp->h_next) {
		if (xp != hp)
			ppx = &xp->h_next;
		else
			break;
	}

	if (xp != hp) {
		(void) pthread_mutex_unlock(&List_lock);
		fmd_hdl_abort(hdl, "xport - fini failed, tlhdl %p not on list",
		    (void *)hp);
	}

	*ppx = hp->h_next;
	hp->h_next = NULL;

	if (hp->h_tid != EXS_TID_FREE) {
		hp->h_quit = 1;
		fmd_thr_signal(hdl, hp->h_tid);
		fmd_thr_destroy(hdl, hp->h_tid);
	}

	if (hp->h_server.c_sd != EXS_SD_FREE)
		(void) close(hp->h_server.c_sd);

	if (hp->h_client.c_sd != EXS_SD_FREE)
		(void) close(hp->h_client.c_sd);

	fmd_hdl_strfree(hdl, hp->h_endpt_id);
	fmd_hdl_free(hdl, hp, sizeof (exs_hdl_t));

	if (Exh_head == NULL) {
		/* Undo one-time initializations */
		exs_filter_fini(hdl);

		/* Destroy the accept/listen thread */
		if (Acc_tid != EXS_TID_FREE) {
			Acc_quit = 1;
			fmd_thr_signal(hdl, Acc_tid);
			fmd_thr_destroy(hdl, Acc_tid);
		}

		if (Acc.c_sd != EXS_SD_FREE)
			EXS_CLOSE_CLR(Acc);
	}

	(void) pthread_mutex_unlock(&List_lock);

	return (0);
}
Esempio n. 2
0
/*
 * Open a connection with the given endpoint,
 * Return etm_xport_conn_t for success, NULL and set errno for failure.
 */
etm_xport_conn_t
etm_xport_open(fmd_hdl_t *hdl, etm_xport_hdl_t tlhdl)
{
	int flags;
	exs_hdl_t *hp = (exs_hdl_t *)tlhdl;

	if (hp->h_destroy) {
		fmd_thr_destroy(hp->h_hdl, hp->h_tid);
		hp->h_tid = EXS_TID_FREE;
		hp->h_destroy = 0;
	}

	if (hp->h_client.c_sd == EXS_SD_FREE) {
		if (exs_prep_client(hp) != 0)
			return (NULL);
	}

	/* Set the socket to be non-blocking */
	flags = fcntl(hp->h_client.c_sd, F_GETFL, 0);
	(void) fcntl(hp->h_client.c_sd, F_SETFL, flags | O_NONBLOCK);

	if ((connect(hp->h_client.c_sd,
	    (struct sockaddr *)&hp->h_client.c_saddr,
	    hp->h_client.c_len)) == -1) {
		if (errno != EINPROGRESS) {
			fmd_hdl_debug(hdl, "xport - failed to connect to %s",
			    hp->h_endpt_id);
			EXS_CLOSE_CLR(hp->h_client);
			return (NULL);
		}
	}

	fmd_hdl_debug(hdl, "xport - connected client socket for %s",
	    hp->h_endpt_id);

	return (&hp->h_client);
}
Esempio n. 3
0
/*
 * Accept a new incoming connection.
 */
static void
exs_accept(fmd_hdl_t *hdl)
{
	int new_sd, dom, flags, rv;
	struct sockaddr_in new_saddr;
	socklen_t new_len = sizeof (struct sockaddr);
	exs_hdl_t *hp;

	if ((new_sd = accept(Acc.c_sd, (struct sockaddr *)&new_saddr,
	    &new_len)) != -1) {
		/* Translate saddr to domain id */
		if ((rv = dscpIdent((struct sockaddr *)&new_saddr, (int)new_len,
		    &dom)) != DSCP_OK) {
			fmd_hdl_error(hdl, "dscpIdent failed : rv = %d\n", rv);
			(void) close(new_sd);
			return;
		}

		/* Find the exs_hdl_t for the domain trying to connect */
		(void) pthread_mutex_lock(&List_lock);
		for (hp = Exh_head; hp; hp = hp->h_next) {
			if (hp->h_dom == dom)
				break;
		}
		(void) pthread_mutex_unlock(&List_lock);

		if (hp == NULL) {
			fmd_hdl_error(hdl, "Not configured to accept a "
			    "connection from domain %d. Check "
			    "event-transport.conf\n", dom);
			(void) close(new_sd);
			return;
		}

		/* Authenticate this connection request */
		if ((rv = dscpAuth(dom, (struct sockaddr *)&new_saddr,
		    (int)new_len)) != DSCP_OK) {
			fmd_hdl_error(hdl, "dscpAuth failed for %s : rv = %d ",
			    " Possible spoofing attack\n", hp->h_endpt_id, rv);
			(void) close(new_sd);
			return;
		}

		if (hp->h_tid != EXS_TID_FREE) {
			hp->h_quit = 1;
			fmd_thr_signal(hp->h_hdl, hp->h_tid);
			fmd_thr_destroy(hp->h_hdl, hp->h_tid);
			hp->h_destroy = 0;
			hp->h_quit = 0;
		}

		if (hp->h_server.c_sd != EXS_SD_FREE)
			EXS_CLOSE_CLR(hp->h_server);

		/* Set the socket to be non-blocking */
		flags = fcntl(new_sd, F_GETFL, 0);
		(void) fcntl(new_sd, F_SETFL, flags | O_NONBLOCK);

		hp->h_server.c_sd = new_sd;

		hp->h_tid = fmd_thr_create(hdl, exs_server, hp);

	} else {
		fmd_hdl_error(hp->h_hdl, "Failed to accept() a new connection");
	}
}
Esempio n. 4
0
/*
 * Prepare to accept a connection.
 * Return 0 for success, nonzero for failure.
 */
void
exs_prep_accept(fmd_hdl_t *hdl, int dom)
{
	int flags, optval = 1;
	int rv;

	if (Acc.c_sd != EXS_SD_FREE)
		return;	/* nothing to do */

	if (Acc_destroy) {
		fmd_thr_destroy(hdl, Acc_tid);
		Acc_tid = EXS_TID_FREE;
	}

	/* Check to see if the DSCP interface is configured */
	if ((rv = dscpAddr(dom, DSCP_ADDR_LOCAL,
	    (struct sockaddr *)&Acc.c_saddr, &Acc.c_len)) != DSCP_OK) {
		fmd_hdl_debug(hdl, "xport - dscpAddr on the accept socket "
		    "failed for domain %d : rv = %d", dom, rv);
		return;
	}

	if ((Acc.c_sd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
		fmd_hdl_error(hdl, "Failed to create the accept socket");
		return;
	}

	if (setsockopt(Acc.c_sd, SOL_SOCKET, SO_REUSEADDR, &optval,
	    sizeof (optval))) {
		fmd_hdl_error(hdl, "Failed to set REUSEADDR for the accept "
		    "socket");
		EXS_CLOSE_CLR(Acc);
		return;
	}

	/* Bind the socket to the local IP address of the DSCP link */
	if ((rv = dscpBind(dom, Acc.c_sd, EXS_SERVER_PORT)) != DSCP_OK) {
		if (rv == DSCP_ERROR_DOWN) {
			fmd_hdl_debug(hdl, "xport - dscp link for domain %d "
			    "is down", dom);
		} else {
			fmd_hdl_error(hdl, "dscpBind on the accept socket "
			    "failed : rv = %d\n", rv);
		}
		EXS_CLOSE_CLR(Acc);
		return;
	}

	/* Activate IPsec security policy for this socket */
	if ((rv = dscpSecure(dom, Acc.c_sd)) != DSCP_OK) {
		fmd_hdl_error(hdl, "dscpSecure on the accept socket failed : "
		    "rv = %d\n", dom, rv);
		EXS_CLOSE_CLR(Acc);
		return;
	}

	if ((listen(Acc.c_sd, EXS_NUM_SOCKS)) == -1) {
		fmd_hdl_debug(hdl, "Failed to listen() for connections");
		EXS_CLOSE_CLR(Acc);
		return;
	}

	flags = fcntl(Acc.c_sd, F_GETFL, 0);
	(void) fcntl(Acc.c_sd, F_SETFL, flags | O_NONBLOCK);

	Acc_tid = fmd_thr_create(hdl, exs_listen, hdl);
}
Esempio n. 5
0
void
dm_plugin_thr_destroy(pthread_t tid)
{
	fmd_thr_destroy(g_fm_hdl, tid);
}