コード例 #1
0
ファイル: gnet_stats.c プロジェクト: Longdengyu/gtk-gnutella
void
gnet_stats_count_dropped(gnutella_node_t *n, msg_drop_reason_t reason)
{
	uint32 size;
	uint type;
	gnet_stats_t *stats;

	g_assert(UNSIGNED(reason) < MSG_DROP_REASON_COUNT);
	g_assert(thread_is_main());

	stats = NODE_USES_UDP(n) ? &gnet_udp_stats : &gnet_tcp_stats;

	if (NODE_TALKS_G2(n)) {
		int f = g2_msg_type(n->data, n->size);
		if (f != G2_MSG_MAX) {
			f += MSG_G2_BASE;
		} else {
			f = G_N_ELEMENTS(stats_lut) - 1;	/* Last, holds MSG_UNKNOWN */
		}
		type = stats_lut[f];
		size = n->size;
	} else {
		type = stats_lut[gnutella_header_get_function(&n->header)];
		size = n->size + sizeof(n->header);
	}

	entropy_harvest_small(
		VARLEN(n->addr), VARLEN(n->port), VARLEN(reason), VARLEN(type),
		VARLEN(size), NULL);

	DROP_STATS(stats, type, size);
	node_inc_rxdrop(n);

	switch (reason) {
	case MSG_DROP_HOSTILE_IP: n->n_hostile++; break;
	case MSG_DROP_SPAM: n->n_spam++; break;
	case MSG_DROP_EVIL: n->n_evil++; break;
	default: ;
	}

	if (NODE_TALKS_G2(n)) {
		if (GNET_PROPERTY(log_dropped_g2)) {
			g2_msg_log_dropped_data(n->data, n->size,
				"from %s: %s", node_infostr(n),
				gnet_stats_drop_reason_to_string(reason));
		}
	} else {
		if (GNET_PROPERTY(log_dropped_gnutella)) {
			gmsg_log_split_dropped(&n->header, n->data, n->size,
				"from %s: %s", node_infostr(n),
				gnet_stats_drop_reason_to_string(reason));
		}
	}
}
コード例 #2
0
ファイル: gnet_stats.c プロジェクト: Longdengyu/gtk-gnutella
void
gnet_stats_count_sent(const gnutella_node_t *n,
	uint8 type, const void *base, uint32 size)
{
	uint t = stats_lut[type];
	gnet_stats_t *stats;
	uint8 hops;

	g_assert(t != MSG_UNKNOWN);
	g_assert(thread_is_main());
	g_assert(!NODE_TALKS_G2(n));

	stats = NODE_USES_UDP(n) ? &gnet_udp_stats : &gnet_tcp_stats;

	/*
	 * Adjust for Kademlia messages.
	 */

	if (GTA_MSG_DHT == type && size >= KDA_HEADER_SIZE) {
		uint8 opcode = kademlia_header_get_function(base);

		if (UNSIGNED(opcode + MSG_DHT_BASE) < G_N_ELEMENTS(stats_lut)) {
			t = stats_lut[opcode + MSG_DHT_BASE];
		}
		hops = 0;
	} else {
		hops = gnutella_header_get_hops(base);
	}

	gnet_stats_count_sent_internal(n, t, hops, size, stats);
}
コード例 #3
0
ファイル: node.c プロジェクト: graaff/gtk-gnutella
/**
 * Send a message to target node.
 *
 * @param n		the G2 node to which message should be sent
 * @param mb	the message to sent (ownership taken, will be freed later)
 */
void
g2_node_send(const gnutella_node_t *n, pmsg_t *mb)
{
	node_check(n);
	g_assert(NODE_TALKS_G2(n));

	if (NODE_IS_UDP(n))
		mq_udp_node_putq(n->outq, mb, n);
	else if (NODE_IS_WRITABLE(n))
		mq_tcp_putq(n->outq, mb, NULL);
	else
		goto drop;

	if (GNET_PROPERTY(log_sending_g2)) {
		g_debug("%s(): sending %s to %s",
			G_STRFUNC, g2_msg_infostr_mb(mb), node_infostr(n));
	}

	return;

drop:
	if (GNET_PROPERTY(log_sending_g2)) {
		g_debug("%s(): aborting sending %s to %s",
			G_STRFUNC, g2_msg_infostr_mb(mb), node_infostr(n));
	}

	pmsg_free(mb);		/* Cannot send it, free it now */
}
コード例 #4
0
ファイル: gnet_stats.c プロジェクト: Longdengyu/gtk-gnutella
void
gnet_stats_g2_count_queued(const gnutella_node_t *n,
	const void *base, size_t len)
{
	gnet_stats_t *stats;
	uint t;
	uint8 f;

	g_assert(thread_is_main());
	g_assert(NODE_TALKS_G2(n));

	stats = NODE_USES_UDP(n) ? &gnet_udp_stats : &gnet_tcp_stats;

	f = g2_msg_type(base, len);

	if (f != G2_MSG_MAX) {
		f += MSG_G2_BASE;
	} else {
		f = G_N_ELEMENTS(stats_lut) - 1;	/* Last, holds MSG_UNKNOWN */
	}

	t = stats_lut[f];

	/* Leaf mode => hops = 0 */
	gnet_stats_count_queued_internal(n, t, 0, len, stats);
}
コード例 #5
0
ファイル: gnet_stats.c プロジェクト: Longdengyu/gtk-gnutella
/**
 * Called when Gnutella header has been read.
 */
void
gnet_stats_count_received_header(gnutella_node_t *n)
{
	uint t = stats_lut[gnutella_header_get_function(&n->header)];
	uint8 ttl, hops;

	g_assert(thread_is_main());
	g_assert(!NODE_TALKS_G2(n));

	ttl = gnutella_header_get_ttl(&n->header);
	hops = gnutella_header_get_hops(&n->header);

	gnet_stats_count_received_header_internal(n, GTA_HEADER_SIZE, t, ttl, hops);
}
コード例 #6
0
ファイル: build.c プロジェクト: Eppo791906066/gtk-gnutella
/**
 * Generate as many "NH" children to the root as we have neihbouring hubs,
 * when the node is firewalled.  They can act as "push proxies", as in Gnutella.
 */
static void
g2_build_add_neighbours(g2_tree_t *t)
{
	if (GNET_PROPERTY(is_firewalled) || GNET_PROPERTY(is_udp_firewalled)) {
		const pslist_t *sl;

		PSLIST_FOREACH(node_all_g2_nodes(), sl) {
			const gnutella_node_t *n = sl->data;

			node_check(n);
			g_assert(NODE_TALKS_G2(n));

			if (NODE_IS_ESTABLISHED(n) && node_address_known(n))
				g2_build_add_host(t, "NH", n->gnet_addr, n->gnet_port);
		}
	}
}
コード例 #7
0
ファイル: gnet_stats.c プロジェクト: Longdengyu/gtk-gnutella
void
gnet_stats_g2_count_sent(const gnutella_node_t *n,
	enum g2_msg type, uint32 size)
{
	uint t;
	gnet_stats_t *stats;

	g_assert(thread_is_main());
	g_assert((uint) type < UNSIGNED(G2_MSG_MAX));
	g_assert(NODE_TALKS_G2(n));

	stats = NODE_USES_UDP(n) ? &gnet_udp_stats : &gnet_tcp_stats;

	t = stats_lut[MSG_G2_BASE + type];

	g_assert(t != MSG_UNKNOWN);

	/* Leaf mode => hops = 0 */
	gnet_stats_count_sent_internal(n, t, 0, size, stats);
}
コード例 #8
0
ファイル: gnet_stats.c プロジェクト: Longdengyu/gtk-gnutella
void
gnet_stats_count_expired(const gnutella_node_t *n)
{
    uint32 size = n->size + sizeof(n->header);
	uint t = stats_lut[gnutella_header_get_function(&n->header)];
	gnet_stats_t *stats;

	g_assert(thread_is_main());
	g_assert(!NODE_TALKS_G2(n));

	stats = NODE_USES_UDP(n) ? &gnet_udp_stats : &gnet_tcp_stats;

    gnet_stats.pkg.expired[MSG_TOTAL]++;
    gnet_stats.pkg.expired[t]++;
    gnet_stats.byte.expired[MSG_TOTAL] += size;
    gnet_stats.byte.expired[t] += size;

    stats->pkg.expired[MSG_TOTAL]++;
    stats->pkg.expired[t]++;
    stats->byte.expired[MSG_TOTAL] += size;
    stats->byte.expired[t] += size;
}
コード例 #9
0
ファイル: gnet_stats.c プロジェクト: Longdengyu/gtk-gnutella
/**
 * Called to transform Gnutella header counting into Kademlia header counting.
 *
 * @param n		the node receiving the message
 * @param kt
 */
static void
gnet_stats_count_kademlia_header(const gnutella_node_t *n, uint kt)
{
	uint t = stats_lut[gnutella_header_get_function(&n->header)];
	uint i;
	gnet_stats_t *stats;

	g_assert(thread_is_main());
	g_assert(!NODE_TALKS_G2(n));

	stats = NODE_USES_UDP(n) ? &gnet_udp_stats : &gnet_tcp_stats;

    gnet_stats.pkg.received[t]--;
    gnet_stats.pkg.received[kt]++;
    gnet_stats.byte.received[t] -= GTA_HEADER_SIZE;
    gnet_stats.byte.received[kt] += GTA_HEADER_SIZE;

    stats->pkg.received[t]--;
    stats->pkg.received[kt]++;
    stats->byte.received[t] -= GTA_HEADER_SIZE;
    stats->byte.received[kt] += GTA_HEADER_SIZE;

	i = MIN(gnutella_header_get_ttl(&n->header), STATS_RECV_COLUMNS - 1);
    stats->pkg.received_ttl[i][MSG_TOTAL]--;
    stats->pkg.received_ttl[i][t]--;

	i = MIN(gnutella_header_get_hops(&n->header), STATS_RECV_COLUMNS - 1);
    stats->pkg.received_hops[i][MSG_TOTAL]--;
    stats->pkg.received_hops[i][t]--;

	/* DHT messages have no hops nor ttl, use 0 */

    stats->pkg.received_ttl[0][MSG_TOTAL]++;
    stats->pkg.received_ttl[0][kt]++;
    stats->pkg.received_hops[0][MSG_TOTAL]++;
    stats->pkg.received_hops[0][kt]++;
}
コード例 #10
0
ファイル: gnet_stats.c プロジェクト: Longdengyu/gtk-gnutella
void
gnet_stats_count_dropped_nosize(
	const gnutella_node_t *n, msg_drop_reason_t reason)
{
	uint type;
	gnet_stats_t *stats;

	g_assert(UNSIGNED(reason) < MSG_DROP_REASON_COUNT);
	g_assert(thread_is_main());
	g_assert(!NODE_TALKS_G2(n));

	type = stats_lut[gnutella_header_get_function(&n->header)];
	stats = NODE_USES_UDP(n) ? &gnet_udp_stats : &gnet_tcp_stats;

	entropy_harvest_small(VARLEN(n->addr), VARLEN(n->port), NULL);

	/* Data part of message not read */
	DROP_STATS(stats, type, sizeof(n->header));

	if (GNET_PROPERTY(log_dropped_gnutella))
		gmsg_log_split_dropped(&n->header, n->data, 0,
			"from %s: %s", node_infostr(n),
			gnet_stats_drop_reason_to_string(reason));
}
コード例 #11
0
ファイル: gnet_stats.c プロジェクト: Longdengyu/gtk-gnutella
/**
 * Called when Gnutella payload has been read, or when a G2 messsage is read.
 *
 * The actual payload size (effectively read) is expected to be found
 * in n->size for Gnutella messages and G2 messages.
 *
 * @param n			the node from which message was received
 * @param payload	start of Gnutella payload, or head of G2 frame
 */
void
gnet_stats_count_received_payload(const gnutella_node_t *n, const void *payload)
{
	uint8 f;
	uint t;
	uint i;
	gnet_stats_t *stats;
    uint32 size;
	uint8 hops, ttl;

	g_assert(thread_is_main());

	stats = NODE_USES_UDP(n) ? &gnet_udp_stats : &gnet_tcp_stats;
	size = n->size;

	/*
	 * Size is NOT read in the Gnutella header but in n->size, which
	 * reflects how much data we have in the payload, as opposed to the
	 * size in the header which may be wrong, or have highest bits set
	 * because they indicate flags.
	 *
	 * In particular, broken DHT messages often come with an invalid size in
	 * the header.
	 *		--RAM, 2010-10-30
	 */

	if (NODE_TALKS_G2(n)) {
		f = g2_msg_type(payload, size);
		if (f != G2_MSG_MAX) {
			f += MSG_G2_BASE;
		} else {
			f = G_N_ELEMENTS(stats_lut) - 1;	/* Last, holds MSG_UNKNOWN */
		}
		ttl = 1;
		hops = NODE_USES_UDP(n) ? 0 : 1;
		t = stats_lut[f];
		/*
		 * No header for G2, so count header reception now with a size of zero.
		 * This is required to update the other packet reception statistics.
		 */
		gnet_stats_count_received_header_internal(
			deconstify_pointer(n),
			0, t, ttl, hops);
	} else {
		f = gnutella_header_get_function(&n->header);
		hops = gnutella_header_get_hops(&n->header);
		ttl = gnutella_header_get_ttl(&n->header);
		t = stats_lut[f];
	}

	gnet_stats_randomness(n, f, size);

	/*
	 * If we're dealing with a Kademlia message, we need to do two things:
	 *
	 * We counted the Gnutella header for the GTA_MSG_DHT message, but we
	 * now need to undo that and count it as a Kademlia message.
	 *
	 * To access the proper entry in the array, we need to offset the
	 * Kademlia OpCode from the header with MSG_DHT_BASE to get the entry
	 * in the statistics that are associated with that particular message.
	 *		--RAM, 2010-11-01
	 */

	if (GTA_MSG_DHT == f && size + GTA_HEADER_SIZE >= KDA_HEADER_SIZE) {
		uint8 opcode = peek_u8(payload);	/* Kademlia Opcode */

		if (UNSIGNED(opcode + MSG_DHT_BASE) < G_N_ELEMENTS(stats_lut)) {
			t = stats_lut[opcode + MSG_DHT_BASE];
			gnet_stats_count_kademlia_header(n, t);
		}
	}

	g_assert(t < MSG_TOTAL);

    gnet_stats.byte.received[MSG_TOTAL] += size;
    gnet_stats.byte.received[t] += size;

    stats->byte.received[MSG_TOTAL] += size;
    stats->byte.received[t] += size;

	i = MIN(ttl, STATS_RECV_COLUMNS - 1);
    stats->byte.received_ttl[i][MSG_TOTAL] += size;
    stats->byte.received_ttl[i][t] += size;

	i = MIN(hops, STATS_RECV_COLUMNS - 1);
    stats->byte.received_hops[i][MSG_TOTAL] += size;
    stats->byte.received_hops[i][t] += size;
}
コード例 #12
0
ファイル: node.c プロジェクト: graaff/gtk-gnutella
/**
 * Handle message coming from G2 node.
 */
void
g2_node_handle(gnutella_node_t *n)
{
	g2_tree_t *t;
	size_t plen;
	enum g2_msg type;

	node_check(n);
	g_assert(NODE_TALKS_G2(n));

	t = g2_frame_deserialize(n->data, n->size, &plen, FALSE);
	if (NULL == t) {
		if (GNET_PROPERTY(g2_debug) > 0 || GNET_PROPERTY(log_bad_g2)) {
			g_warning("%s(): cannot deserialize /%s from %s",
				G_STRFUNC, g2_msg_raw_name(n->data, n->size), node_infostr(n));
		}
		if (GNET_PROPERTY(log_bad_g2))
			dump_hex(stderr, "G2 Packet", n->data, n->size);
		return;
	} else if (plen != n->size) {
		if (GNET_PROPERTY(g2_debug) > 0 || GNET_PROPERTY(log_bad_g2)) {
			g_warning("%s(): consumed %zu bytes but /%s from %s had %u",
				G_STRFUNC, plen, g2_msg_raw_name(n->data, n->size),
				node_infostr(n), n->size);
		}
		if (GNET_PROPERTY(log_bad_g2))
			dump_hex(stderr, "G2 Packet", n->data, n->size);
		hostiles_dynamic_add(n->addr,
			"cannot parse incoming messages", HSTL_GIBBERISH);
		goto done;
	} else if (GNET_PROPERTY(g2_debug) > 19) {
		g_debug("%s(): received packet from %s", G_STRFUNC, node_infostr(n));
		g2_tfmt_tree_dump(t, stderr, G2FMT_O_PAYLEN);
	}

	type = g2_msg_name_type(g2_tree_name(t));

	switch (type) {
	case G2_MSG_PI:
		g2_node_handle_ping(n, t);
		break;
	case G2_MSG_PO:
		g2_node_handle_pong(n, t);
		break;
	case G2_MSG_LNI:
		g2_node_handle_lni(n, t);
		break;
	case G2_MSG_KHL:
		g2_node_handle_khl(t);
		break;
	case G2_MSG_PUSH:
		handle_push_request(n, t);
		break;
	case G2_MSG_Q2:
		g2_node_handle_q2(n, t);
		break;
	case G2_MSG_QA:
	case G2_MSG_QKA:
		g2_node_handle_rpc_answer(n, t, type);
		break;
	case G2_MSG_QH2:
		search_g2_results(n, t);
		break;
	default:
		g2_node_drop(G_STRFUNC, n, t, "default");
		break;
	}

done:
	g2_tree_free_null(&t);
}