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; }
/* * 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; }