예제 #1
0
파일: hsep.c 프로젝트: MrJoe/gtk-gnutella
/**
 * @returns a static string of the cell contents of the given row and column.
 *
 * @attention
 * NB: The static buffers for each column are disjunct.
 */
const char *
hsep_get_static_str(int row, int column)
{
	const char *ret = NULL;
	hsep_triple hsep_table[G_N_ELEMENTS(hsep_global_table)];
	hsep_triple other[1];
	uint64 v;

	hsep_get_global_table(hsep_table, G_N_ELEMENTS(hsep_table));
	hsep_get_non_hsep_triple(other);

    switch (column) {
    case HSEP_IDX_NODES:
		{
			static char buf[UINT64_DEC_BUFLEN];

			v = hsep_table[row][HSEP_IDX_NODES] + other[0][HSEP_IDX_NODES];
			uint64_to_string_buf(v, buf, sizeof buf);
			ret = buf;
		}
		break;

    case HSEP_IDX_FILES:
		{
			static char buf[UINT64_DEC_BUFLEN];

			v = hsep_table[row][HSEP_IDX_FILES] + other[0][HSEP_IDX_FILES];
			uint64_to_string_buf(v, buf, sizeof buf);
			ret = buf;
		}
		break;

	case HSEP_IDX_KIB:
		{
			static char buf[UINT64_DEC_BUFLEN];

			/* Make a copy because concurrent usage of short_kb_size()
	 	 	 * could be hard to discover. */
			v = hsep_table[row][HSEP_IDX_KIB] + other[0][HSEP_IDX_KIB];
			g_strlcpy(buf,
				short_kb_size(v, GNET_PROPERTY(display_metric_units)),
				sizeof buf);
  			ret = buf;
		}
		break;
    }

	g_assert(ret != NULL);
	return ret;
}
예제 #2
0
파일: hsep.c 프로젝트: MrJoe/gtk-gnutella
void
hsep_send_msg(struct gnutella_node *n, time_t now)
{
	hsep_triple tmp[G_N_ELEMENTS(n->hsep->sent_table)], other;
	unsigned int i, j, msglen, msgsize, triples, opttriples;
	gnutella_msg_hsep_t *msg;
	hsep_ctx_t *hsep;

	g_assert(n);
	g_assert(n->hsep);

	hsep = n->hsep;
	ZERO(&other);

	/*
	 * If we are a leaf, we just need to send one triple,
	 * which contains our own data (this triple is expanded
	 * to the needed number of triples on the peer's side).
	 * As the 0'th global and 0'th connection triple are zero,
	 * it contains only our own triple, which is correct.
	 */

	triples = settings_is_leaf() ? 1 : G_N_ELEMENTS(tmp);

	/*
	 * Allocate and initialize message to send.
	 */

	msgsize = GTA_HEADER_SIZE + triples * (sizeof *msg - GTA_HEADER_SIZE);
	msg = walloc(msgsize);

	{
		gnutella_header_t *header;
		
		header = gnutella_msg_hsep_header(msg);
		message_set_muid(header, GTA_MSG_HSEP_DATA);
		gnutella_header_set_function(header, GTA_MSG_HSEP_DATA);
		gnutella_header_set_ttl(header, 1);
		gnutella_header_set_hops(header, 0);
	}

	/*
	 * Collect HSEP data to send and convert the data to
	 * little endian byte order.
	 */

	if (triples > 1) {
		/* determine what we know about non-HSEP nodes in 1 hop distance */
		hsep_get_non_hsep_triple(&other);
	}

	for (i = 0; i < triples; i++) {
		for (j = 0; j < G_N_ELEMENTS(other); j++) {
			uint64 val;

			val = hsep_own[j] + (0 == i ? 0 : other[j]) +
				hsep_global_table[i][j] - hsep->table[i][j];
			poke_le64(&tmp[i][j], val);
		}
	}

	STATIC_ASSERT(sizeof hsep->sent_table == sizeof tmp);
	/* check if the table differs from the previously sent table */
	if (
		0 == memcmp(tmp, hsep->sent_table, sizeof tmp)
	) {
		WFREE_NULL(msg, msgsize);
		goto charge_timer;
	}

	memcpy(cast_to_char_ptr(msg) + GTA_HEADER_SIZE,
		tmp, triples * sizeof tmp[0]);

	/* store the table for later comparison */
	memcpy(hsep->sent_table, tmp, triples * sizeof tmp[0]);

	/*
	 * Note that on big endian architectures the message data is now in
	 * the wrong byte order. Nevertheless, we can use hsep_triples_to_send()
	 * with that data.
	 */

	/* optimize number of triples to send */
	opttriples = hsep_triples_to_send(cast_to_pointer(tmp), triples);

	if (GNET_PROPERTY(hsep_debug) > 1) {
		printf("HSEP: Sending %d %s to node %s (msg #%u): ", opttriples,
		    opttriples == 1 ? "triple" : "triples",
			host_addr_port_to_string(n->addr, n->port),
			hsep->msgs_sent + 1);
	}

	for (i = 0; i < opttriples; i++) {
		if (GNET_PROPERTY(hsep_debug) > 1) {
			char buf[G_N_ELEMENTS(hsep_own)][32];

			for (j = 0; j < G_N_ELEMENTS(buf); j++) {
				uint64 v;

				v = hsep_own[j] + hsep_global_table[i][j] - hsep->table[i][j];
				uint64_to_string_buf(v, buf[j], sizeof buf[0]);
			}

			STATIC_ASSERT(3 == G_N_ELEMENTS(buf));
			printf("(%s, %s, %s) ", buf[0], buf[1], buf[2]);
		}
	}

	if (GNET_PROPERTY(hsep_debug) > 1)
		puts("\n");

	/* write message size */
	msglen = opttriples * 24;
	gnutella_header_set_size(gnutella_msg_hsep_header(msg), msglen);

	/* correct message length */
	msglen += GTA_HEADER_SIZE;

	/* send message to peer node */
	gmsg_sendto_one(n, msg, msglen);

	WFREE_NULL(msg, msgsize);

	/*
	 * Update counters.
	 */

	hsep->msgs_sent++;
	hsep->triples_sent += opttriples;

charge_timer:

	hsep->last_sent = now;
	hsep->random_skew = random_value(2 * HSEP_MSG_SKEW) - HSEP_MSG_SKEW;
}
예제 #3
0
파일: ui2c.c 프로젝트: Haxe/gtk-gnutella
void
guc_hsep_get_non_hsep_triple(hsep_triple *tripledest)
{
    hsep_get_non_hsep_triple(tripledest);
}
예제 #4
0
/**
 * Displays horizon size information.
 */
enum shell_reply
shell_exec_horizon(struct gnutella_shell *sh, int argc, const char *argv[])
{
	const char *all;
	const option_t options[] = {
		{ "a", &all },
	};
	char buf[200];
	hsep_triple globaltable[HSEP_N_MAX + 1];
	hsep_triple non_hsep[1];
	int parsed;
	unsigned num_hsep, num_total;

	shell_check(sh);
	g_assert(argv);
	g_assert(argc > 0);

	parsed = shell_options_parse(sh, argv, options, G_N_ELEMENTS(options));
	if (parsed < 0)
		return REPLY_ERROR;

	shell_write(sh, "100~\n");

	hsep_get_global_table(globaltable, G_N_ELEMENTS(globaltable));
	hsep_get_non_hsep_triple(non_hsep);

	num_hsep = globaltable[1][HSEP_IDX_NODES];
	num_total = globaltable[1][HSEP_IDX_NODES] + non_hsep[0][HSEP_IDX_NODES];
	str_bprintf(buf, sizeof buf,
		_("Total horizon size (%u/%u nodes support HSEP):"),
		num_hsep, num_total);

	shell_write(sh, buf);
	shell_write(sh, "\n\n");

	print_hsep_table(sh, globaltable, HSEP_N_MAX, non_hsep);

	if (all) {
		const pslist_t *sl;
		hsep_triple table[HSEP_N_MAX + 1];

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

			if ((!NODE_IS_ESTABLISHED(n)) || !(n->attrs & NODE_A_CAN_HSEP))
				continue;

			shell_write(sh, "\n");

			str_bprintf(buf, sizeof buf,
				_("Horizon size via HSEP node %s (%s):"),
				node_addr(n),
				node_peermode_to_string(n->peermode));

			shell_write(sh, buf);
			shell_write(sh, "\n\n");

			hsep_get_connection_table(n, table, G_N_ELEMENTS(table));
			print_hsep_table(sh, table, NODE_IS_LEAF(n) ? 1 : HSEP_N_MAX, NULL);
		}
	}

	shell_write(sh, ".\n");
	return REPLY_READY;
}