Example #1
0
File: hooks.c Project: op5/merlin
static int send_generic(merlin_event *pkt, void *data)
{
	int result = 0;
	uint i, ntable_stop = num_masters + num_peers;
	linked_item *li;

	if ((!num_nodes || pkt->hdr.code == MAGIC_NONET) && !daemon_wants(pkt->hdr.type)) {
		ldebug("ipcfilter: Not sending %s event. %s, and daemon doesn't want it",
			   callback_name(pkt->hdr.type),
			   pkt->hdr.code == MAGIC_NONET ? "No-net magic" : "No nodes");
		return 0;
	}
	if (!pkt->hdr.code == MAGIC_NONET && !daemon_wants(pkt->hdr.type)) {
		ldebug("ipcfilter: Not sending %s event. No-net magic and daemon doesn't want it",
			   callback_name(pkt->hdr.type));
		return 0;
	}

	pkt->hdr.len = merlin_encode_event(pkt, data);
	if (!pkt->hdr.len) {
		lerr("Header len is 0 for callback %d. Update offset in hookinfo.h", pkt->hdr.type);
		return -1;
	}

	if (is_dupe(pkt)) {
		ldebug("ipcfilter: Not sending %s event: Duplicate packet",
		       callback_name(pkt->hdr.type));
		return 0;
	}

	if (daemon_wants(pkt->hdr.type)) {
		result = ipc_send_event(pkt);
		/*
		 * preserve the event so we can check for dupes,
		 * but only if we successfully sent it
		 */
		if (result < 0)
			memset(&last_pkt, 0, sizeof(last_pkt));
		else
			memcpy(&last_pkt, pkt, packet_size(pkt));
	}

	if (!num_nodes)
		return 0;
	if (pkt->hdr.code == MAGIC_NONET)
		return 0;

	/*
	 * The module can mark certain packets with a magic destination.
	 * Such packets avoid all other inspection and get sent to where
	 * the module wants us to.
	 */
	if (magic_destination(pkt)) {
		if ((pkt->hdr.selection & DEST_MASTERS) == DEST_MASTERS) {
			for (i = 0; i < num_masters; i++) {
				net_sendto(node_table[i], pkt);
			}
		}
		if ((pkt->hdr.selection & DEST_PEERS) == DEST_PEERS) {
			for (i = 0; i < num_peers; i++) {
				net_sendto(peer_table[i], pkt);
			}
		}
		if ((pkt->hdr.selection & DEST_POLLERS) == DEST_POLLERS) {
			for (i = 0; i < num_pollers; i++) {
				net_sendto(poller_table[i], pkt);
			}
		}

		return 0;
	}

	/*
	 * "normal" packets get sent to all peers and masters, and possibly
	 * a group of, or all, pollers as well
	 */

	/* general control packets are for everyone */
	if (pkt->hdr.selection == CTRL_GENERIC && pkt->hdr.type == CTRL_PACKET) {
		ntable_stop = num_nodes;
	}

	/* Send this to all who should have it */
	for (i = 0; i < ntable_stop; i++) {
		net_sendto(node_table[i], pkt);
	}

	/* if we've already sent to everyone we return early */
	if (ntable_stop == num_nodes || !num_pollers)
		return 0;

	li = nodes_by_sel_id(pkt->hdr.selection);
	if (!li) {
		lerr("No matching selection for id %d", pkt->hdr.selection);
		return -1;
	}

	for (; li; li = li->next_item) {
		net_sendto((merlin_node *)li->item, pkt);
	}

	return result;
}
Example #2
0
File: net.c Project: ageric/merlin
/*
 * Sends an event read from the ipc socket to the appropriate nodes
 */
int net_send_ipc_data(merlin_event *pkt)
{
	uint i, ntable_stop = num_masters + num_peers;
	linked_item *li;

	if (!num_nodes)
		return 0;

	/*
	 * The module can mark certain packets with a magic destination.
	 * Such packets avoid all other inspection and get sent to where
	 * the module wants us to.
	 */
	if (magic_destination(pkt)) {
		if ((pkt->hdr.selection & DEST_MASTERS) == DEST_MASTERS) {
			for (i = 0; i < num_masters; i++) {
				net_sendto(node_table[i], pkt);
			}
		}
		if ((pkt->hdr.selection & DEST_PEERS) == DEST_PEERS) {
			for (i = 0; i < num_peers; i++) {
				net_sendto(peer_table[i], pkt);
			}
		}
		if ((pkt->hdr.selection & DEST_POLLERS) == DEST_POLLERS) {
			for (i = 0; i < num_pollers; i++) {
				net_sendto(poller_table[i], pkt);
			}
		}

		return 0;
	}

	/*
	 * "normal" packets get sent to all peers and masters, and possibly
	 * a group of, or all, pollers as well
	 */

	/* general control packets are for everyone */
	if (pkt->hdr.selection == CTRL_GENERIC && pkt->hdr.type == CTRL_PACKET) {
		ntable_stop = num_nodes;
	}

	/* Send this to all who should have it */
	for (i = 0; i < ntable_stop; i++) {
		net_sendto(node_table[i], pkt);
	}

	/* if we've already sent to everyone we return early */
	if (ntable_stop == num_nodes || !num_pollers)
		return 0;

	li = nodes_by_sel_id(pkt->hdr.selection);
	if (!li) {
		lerr("No matching selection for id %d", pkt->hdr.selection);
		return -1;
	}

	for (; li; li = li->next_item) {
		net_sendto((merlin_node *)li->item, pkt);
	}

	return 0;
}