static inline void nodes_gui_reverse_lookup_selected_helper(GtkTreeModel *model, GtkTreePath *unused_path, GtkTreeIter *iter, gpointer unused_data) { struct node_data *data; gnet_node_info_t info; (void) unused_path; (void) unused_data; gtk_tree_model_get(model, iter, 0, &data, (-1)); g_assert(NULL != find_node(data->node_id)); if (hset_contains(ht_pending_lookups, data->node_id)) return; guc_node_fill_info(data->node_id, &info); g_assert(data->node_id == info.node_id); if (!info.is_pseudo) { const struct nid *key = nid_ref(data->node_id); WFREE_NULL(data->host, data->host_size); data->host_size = w_concat_strings(&data->host, _("Reverse lookup in progress..."), " (", host_addr_port_to_string(info.addr, info.port), ")", (void *) 0); hset_insert(ht_pending_lookups, key); adns_reverse_lookup(info.addr, host_lookup_callback, deconstify_gpointer(nid_ref(key))); } guc_node_clear_info(&info); }
/** * Adds the given node to the gui. */ void nodes_gui_add_node(gnet_node_info_t *n) { GtkCList *clist_nodes; const gchar *titles[c_gnet_num]; gchar proto_tmp[32]; gint row; g_assert(n != NULL); str_bprintf(proto_tmp, sizeof proto_tmp, "%d.%d", n->proto_major, n->proto_minor); titles[c_gnet_host] = host_addr_port_to_string(n->addr, n->port); titles[c_gnet_flags] = "..."; titles[c_gnet_user_agent] = n->vendor ? lazy_utf8_to_locale(n->vendor) : "..."; titles[c_gnet_loc] = iso3166_country_cc(n->country); titles[c_gnet_version] = proto_tmp; titles[c_gnet_connected] = "..."; titles[c_gnet_uptime] = "..."; titles[c_gnet_info] = "..."; clist_nodes = GTK_CLIST(gui_main_window_lookup("clist_nodes")); row = gtk_clist_append(clist_nodes, (gchar **) titles); /* override const */ gtk_clist_set_row_data(clist_nodes, row, deconstify_gpointer(nid_ref(n->node_id))); }
/** * Send time synchronization request to specified node. * * When node_id is non-zero, it refers to the connected node to which * we're sending the time synchronization request. */ void tsync_send(struct gnutella_node *n, const struct nid *node_id) { struct tsync *ts; g_return_if_fail(n->port != 0); if (!NODE_IS_WRITABLE(n)) return; WALLOC(ts); ts->magic = TSYNC_MAGIC; tm_now_exact(&ts->sent); ts->sent.tv_sec = clock_loc2gmt(ts->sent.tv_sec); ts->node_id = nid_ref(node_id); ts->udp = booleanize(NODE_IS_UDP(n)); /* * As far as time synchronization goes, we must get the reply within * the next TSYNC_EXPIRE_MS millisecs. */ ts->expire_ev = cq_main_insert(TSYNC_EXPIRE_MS, tsync_expire, ts); hevset_insert(tsync_by_time, ts); vmsg_send_time_sync_req(n, GNET_PROPERTY(ntp_detected), &ts->sent); }
/** * Adds the given node to the gui. */ void nodes_gui_add_node(gnet_node_info_t *info) { static const struct node_data zero_data; struct node_data *data; gnet_node_flags_t flags; g_return_if_fail(info); g_return_if_fail(!htable_contains(nodes_handles, info->node_id)); WALLOC(data); *data = zero_data; data->node_id = nid_ref(info->node_id); data->user_agent = info->vendor ? atom_str_get(info->vendor) : NULL; data->country = info->country; data->host_size = w_concat_strings(&data->host, host_addr_port_to_string(info->addr, info->port), (void *) 0); str_bprintf(data->version, sizeof data->version, "%u.%u", info->proto_major, info->proto_minor); guc_node_fill_flags(data->node_id, &flags); nodes_gui_update_node_flags(data, &flags); htable_insert(nodes_handles, data->node_id, data); gtk_list_store_append(nodes_model, &data->iter); gtk_list_store_set(nodes_model, &data->iter, 0, data, (-1)); }
/** * Callback invoked when the node's user-visible flags are changed. * * This schedules an update of the node information in the gui at the * next tick. */ static void nodes_gui_node_flags_changed(const struct nid *node_id) { if (!hset_contains(hs_node_flags_changed, node_id)) { const struct nid *key = nid_ref(node_id); hset_insert(hs_node_flags_changed, key); } }
/** * 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); }
/** * Mutate the message so that we can be notified about its freeing by * the mq to which it will be sent to. */ static void smsg_mutate(smsg_t *sb, struct gnutella_node *n) { struct smsg_info *smi; pmsg_t *omb; WALLOC(smi); smi->shandle = sb->shandle; smi->node_id = nid_ref(NODE_ID(n)); omb = sb->mb; sb->mb = pmsg_clone_extend(omb, sq_pmsg_free, smi); pmsg_free(omb); }