void hsep_timer(time_t now) { const GSList *sl; bool scanning_shared; static time_t last_sent = 0; /* update number of shared files and KiB */ gnet_prop_get_boolean_val(PROP_LIBRARY_REBUILDING, &scanning_shared); if (!scanning_shared) { if (upload_is_enabled()) hsep_notify_shared(shared_files_scanned(), shared_kbytes_scanned()); else hsep_notify_shared(0UL, 0UL); } for (sl = node_all_nodes(); sl; sl = g_slist_next(sl)) { struct gnutella_node *n = sl->data; int diff; /* only consider established connections here */ if (!NODE_IS_ESTABLISHED(n)) continue; if (!(n->attrs & NODE_A_CAN_HSEP)) continue; /* check how many seconds ago the last message was sent */ diff = n->hsep->random_skew + delta_time(now, n->hsep->last_sent); /* the -900 is used to react to changes in system time */ if (diff >= HSEP_MSG_INTERVAL || diff < -900) hsep_send_msg(n, now); } /* * Quick'n dirty hack to update the horizon stats in the * statusbar at least once every 3 seconds. * * TODO: remove this and implement it properly in the * statusbar code. */ if (delta_time(now, last_sent) >= 3) { hsep_fire_global_table_changed(now); last_sent = now; } }
static void hsep_sanity_check(void) { const GSList *sl; hsep_triple sum[G_N_ELEMENTS(hsep_global_table)]; unsigned int i, j; ZERO(&sum); g_assert(1 == hsep_own[HSEP_IDX_NODES]); /* * Iterate over all HSEP-capable nodes, and for each triple index * sum up all the connections' triple values. */ for (sl = node_all_nodes() ; sl; sl = g_slist_next(sl)) { struct gnutella_node *n = sl->data; /* also consider unestablished connections here */ if (!(n->attrs & NODE_A_CAN_HSEP)) continue; g_assert(0 == n->hsep->table[0][HSEP_IDX_NODES]); /* check nodes */ g_assert(0 == n->hsep->table[0][HSEP_IDX_FILES]); /* check files */ g_assert(0 == n->hsep->table[0][HSEP_IDX_KIB]); /* check KiB */ g_assert(1 == n->hsep->table[1][HSEP_IDX_NODES]); /* check nodes */ /* check if values are monotonously increasing (skip first) */ g_assert( hsep_check_monotony(cast_to_pointer(n->hsep->table[1]), G_N_ELEMENTS(n->hsep->table[1]) - 1) ); /* sum up the values */ for (i = 0; i < G_N_ELEMENTS(sum); i++) { for (j = 0; j < G_N_ELEMENTS(sum[0]); j++) sum[i][j] += n->hsep->table[i][j]; } } /* check sums */ for (i = 0; i < G_N_ELEMENTS(sum); i++) { for (j = 0; j < G_N_ELEMENTS(sum[0]); j++) g_assert(hsep_global_table[i][j] == sum[i][j]); } }
/** * Displays all connected nodes */ enum shell_reply shell_exec_nodes(struct gnutella_shell *sh, int argc, const char *argv[]) { const GSList *sl; shell_check(sh); g_assert(argv); g_assert(argc > 0); shell_set_msg(sh, ""); shell_write(sh, "100~ \n" "Node Port Flags CC Since Uptime User-Agent\n"); for (sl = node_all_nodes(); sl; sl = g_slist_next(sl)) { const struct gnutella_node *n = sl->data; print_node_info(sh, n); } shell_write(sh, ".\n"); /* Terminate message body */ return REPLY_READY; }
/** * Displays all connected nodes */ enum shell_reply shell_exec_nodes(struct gnutella_shell *sh, int argc, const char *argv[]) { const pslist_t *sl; shell_check(sh); g_assert(argv); g_assert(argc > 0); shell_set_msg(sh, ""); shell_write(sh, "100~ \n" "Node Flags CC Since Uptime User-Agent\n"); PSLIST_FOREACH(node_all_nodes(), sl) { const gnutella_node_t *n = sl->data; print_node_info(sh, n); } shell_write(sh, ".\n"); /* Terminate message body */ return REPLY_READY; }
void hsep_get_non_hsep_triple(hsep_triple *tripledest) { const GSList *sl; uint64 other_nodes = 0; /* # of non-HSEP nodes */ uint64 other_files = 0; /* what non-HSEP nodes share (files) */ uint64 other_kib = 0; /* what non-HSEP nodes share (KiB) */ g_assert(tripledest); /* * Iterate over all established non-HSEP nodes and count these nodes and * sum up what they share (PONG-based library size). */ for (sl = node_all_nodes() ; sl; sl = g_slist_next(sl)) { struct gnutella_node *n = sl->data; gnet_node_status_t status; if ((!NODE_IS_ESTABLISHED(n)) || n->attrs & NODE_A_CAN_HSEP) continue; other_nodes++; if (!node_get_status(NODE_ID(n), &status)) continue; if (status.gnet_info_known) { other_files += status.gnet_files_count; other_kib += status.gnet_kbytes_count; } } tripledest[0][HSEP_IDX_NODES] = other_nodes; tripledest[0][HSEP_IDX_FILES] = other_files; tripledest[0][HSEP_IDX_KIB] = other_kib; }
void hsep_reset(void) { const GSList *sl; uint i; ZERO(&hsep_global_table); for (sl = node_all_nodes(); sl; sl = g_slist_next(sl)) { struct gnutella_node *n = sl->data; /* also consider unestablished connections here */ if (!(n->attrs & NODE_A_CAN_HSEP)) continue; g_assert(n->hsep); ZERO(&n->hsep->table); ZERO(&n->hsep->sent_table); /* this is what we know before receiving the first message */ for (i = 1; i < G_N_ELEMENTS(hsep_global_table); i++) { n->hsep->table[i][HSEP_IDX_NODES] = 1; hsep_global_table[i][HSEP_IDX_NODES]++; } /* * There's no need to reset the last_sent timestamp. * If we'd do this, hsep_timer() would send a message * to all HSEP connections the next time it is called. */ } hsep_fire_global_table_changed(tm_time()); }
/** * 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 GSList *sl; hsep_triple table[HSEP_N_MAX + 1]; for (sl = node_all_nodes(); sl; sl = g_slist_next(sl)) { const struct gnutella_node *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; }