/** * Close traffic dumping. */ void dump_close(void) { if (dump_rx.initialized) dump_disable(&dump_rx); if (dump_tx.initialized) dump_disable(&dump_tx); }
/** * Close traffic dumping. */ void dump_close(void) { if (dump_rx.initialized) dump_disable(&dump_rx); if (dump_tx.initialized) dump_disable(&dump_tx); ipset_clear(&dump_rx_addrs); ipset_clear(&dump_tx_from_addrs); ipset_clear(&dump_tx_to_addrs); }
/** * Initialize RX dumping. * * @return TRUE if initialized. */ static gboolean dump_initialize(struct dump *dump) { char *pathname; if (dump->initialized) return TRUE; pathname = make_pathname(settings_config_dir(), dump->filename); dump->fd = file_open_missing(pathname, O_WRONLY | O_APPEND | O_NONBLOCK); HFREE_NULL(pathname); /* * If the dump "file" is actually a named pipe, we'd block quickly * if there was no reader. So set the file as non-blocking and * we'll disable dumping as soon as we can't write all the data * we want. */ if (dump->fd < 0) { g_warning("can't open %s -- disabling dumping", dump->filename); dump_disable(dump); return FALSE; } fd_set_nonblocking(dump->fd); dump->slist = slist_new(); dump->fill = 0; dump->initialized = TRUE; return TRUE; }
/** * Dump packet received from node. */ void dump_rx_packet(const struct gnutella_node *node) { if (GNET_PROPERTY(dump_received_gnutella_packets)) { dump_packet_from(&dump_rx, node); } else if (dump_rx.initialized) { dump_disable(&dump_rx); } }
/** * Dump transmitted message block via TCP. * If ``from'' is NULL, packet was emitted locally. */ void dump_tx_tcp_packet( const struct gnutella_node *from, const struct gnutella_node *to, const pmsg_t *mb) { if (GNET_PROPERTY(dump_transmitted_gnutella_packets)) { g_assert(to != NULL); g_assert(mb != NULL); g_assert(!NODE_IS_UDP(to)); dump_packet_from_to(&dump_tx, from, to, mb); } else if (dump_tx.initialized) { dump_disable(&dump_tx); } }
/** * Flush buffered data. */ static void dump_flush(struct dump *dump) { while (dump->fill > 0) { ssize_t written; iovec_t *iov; int iov_cnt; iov = pmsg_slist_to_iovec(dump->slist, &iov_cnt, NULL); written = writev(dump->fd, iov, iov_cnt); HFREE_NULL(iov); if ((ssize_t)-1 == written) { if (!is_temporary_error(errno)) { g_warning("error writing to %s: %s -- disabling dumping", dump->filename, g_strerror(errno)); dump_disable(dump); } if (dump->fill >= 256 * 1024UL) { g_warning( "queue is full: %s -- disabling dumping", dump->filename); dump_disable(dump); } break; } else if (0 == written) { g_warning("error writing to %s: hang up -- disabling dumping", dump->filename); dump_disable(dump); break; } else { g_assert(dump->fill >= (size_t) written); dump->fill -= written; pmsg_slist_discard(dump->slist, written); } } }
/** * Dump locally-emitted message block sent via UDP. */ void dump_tx_udp_packet(const gnet_host_t *to, const pmsg_t *mb) { if (GNET_PROPERTY(dump_transmitted_gnutella_packets)) { struct gnutella_node udp; g_assert(to != NULL); g_assert(mb != NULL); /* * Fill only the fields which will be perused by * dump_packet_from_to(). */ udp.peermode = NODE_P_UDP; udp.addr = gnet_host_get_addr(to); udp.port = gnet_host_get_port(to); dump_packet_from_to(&dump_tx, NULL, &udp, mb); } else if (dump_tx.initialized) { dump_disable(&dump_tx); } }