示例#1
0
g2_node_drop(const char *routine, gnutella_node_t *n, const g2_tree_t *t,
	const char *fmt, ...)
{
	if (GNET_PROPERTY(g2_debug) || GNET_PROPERTY(log_dropped_g2)) {
		va_list args;
		char buf[256];

		va_start(args, fmt);

		if (fmt != NULL)
			str_vbprintf(ARYLEN(buf), fmt, args);
		else
			buf[0] = '\0';

		g_debug("%s(): dropping /%s from %s%s%s",
			routine, g2_tree_name(t), node_infostr(n),
			NULL == fmt ? "" : ": ", buf);

		va_end(args);
	}

	gnet_stats_count_dropped(n, MSG_DROP_G2_UNEXPECTED);

	if (GNET_PROPERTY(log_dropped_g2)) {
		g2_tfmt_tree_dump(t, stderr, G2FMT_O_PAYLEN);
	}
}
示例#2
0
/**
 * Flush current /QH2.
 *
 * Depending how the QH2 builder is configured, this either sends the message
 * to the target node or invokes a processing callback.
 */
static void
g2_build_qh2_flush(struct g2_qh2_builder *ctx)
{
	pmsg_t *mb;

	g_assert(ctx != NULL);
	g_assert(ctx->t != NULL);
	g_assert((ctx->n != NULL) ^ (ctx->cb != NULL));

	/*
	 * Restore the order of children in the root packet to be the order we
	 * used when we added the nodes, since we prepend new children.
	 */

	g2_tree_reverse_children(ctx->t);

	/*
	 * If sending over UDP, ask for reliable delivery of the query hit.
	 * To be able to monitor the fate of the message, we asssociate a free
	 * routine to it.
	 */

	if (ctx->to_udp) {
		struct g2_qh2_pmsg_info *pmi;

		WALLOC0(pmi);
		pmi->magic = G2_QH2_PMI_MAGIC;
		pmi->hub_id = nid_ref(NODE_ID(ctx->hub));
		mb = g2_build_pmsg_extended(ctx->t, g2_qh2_pmsg_free, pmi);
		pmsg_mark_reliable(mb);
	} else {
		mb = g2_build_pmsg(ctx->t);
	}

	if (GNET_PROPERTY(g2_debug) > 3) {
		g_debug("%s(): flushing the following hit for "
			"Q2 #%s to %s%s (%d bytes):",
			G_STRFUNC, guid_hex_str(ctx->muid),
			NULL == ctx->n ?
				stacktrace_function_name(ctx->cb) : node_infostr(ctx->n),
			NULL == ctx->n ? "()" : "", pmsg_size(mb));
		g2_tfmt_tree_dump(ctx->t, stderr, G2FMT_O_PAYLOAD | G2FMT_O_PAYLEN);
	}

	if (ctx->n != NULL)
		g2_node_send(ctx->n, mb);
	else
		(*ctx->cb)(mb, ctx->arg);

	ctx->messages++;
	ctx->current_size = 0;
	g2_tree_free_null(&ctx->t);
}
示例#3
0
/**
 * 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);
}