/** * Send a new Gnutella ping message to the specified host. * * @param muid the MUID to use (allocated randomly if NULL) * @param addr address to which ping should be sent * @param port port number * @param uhc_ping if TRUE, include the "SCP" GGEP extension * * @return TRUE if we sent the ping, FALSE it we throttled it. */ bool udp_send_ping(const struct guid *muid, const host_addr_t addr, uint16 port, bool uhc_ping) { gnutella_msg_init_t *m; uint32 size; /* * Don't send too frequent pings: they may throttle us anyway. */ if (aging_lookup(udp_aging_pings, &addr)) { if (GNET_PROPERTY(udp_debug) > 1) { g_warning("UDP throttling %sping to %s", uhc_ping ? "UHC " : "", host_addr_to_string(addr)); } return FALSE; } if (uhc_ping && GNET_PROPERTY(log_uhc_pings_tx)) { g_debug("UDP UHC sending ping to %s", host_addr_to_string(addr)); } m = build_ping_msg(muid, 1, uhc_ping, &size); return udp_send_ping_with_callback(m, size, addr, port, NULL, NULL, FALSE); }
/** * Attempt Gnutella host connection. * @return TRUE if OK, FALSE if attempt was throttled */ static gboolean host_gnutella_connect(host_addr_t addr, guint16 port) { if (aging_lookup(node_connects, &addr)) return FALSE; node_add_socket(NULL, addr, port, 0); aging_insert(node_connects, wcopy(&addr, sizeof addr), GUINT_TO_POINTER(1)); return TRUE; }
/** * Handle reception of a /PI */ static void g2_node_handle_ping(gnutella_node_t *n, const g2_tree_t *t) { g2_tree_t *c; /* * Throttle pings received from UDP. */ if (NODE_IS_UDP(n)) { if (aging_lookup(g2_udp_pings, &n->addr)) { gnet_stats_count_dropped(n, MSG_DROP_THROTTLE); return; } aging_record(g2_udp_pings, WCOPY(&n->addr)); /* FALL THROUGH */ } c = g2_tree_first_child(t); /* * If there is no payload, it's a keep-alive ping, send back a pong. */ if (NULL == c) { g2_node_send_pong(n); return; } /* * There are children. * * If there is a /PI/UDP present, drop the message: we're not a hub, * we don't have to relay this message to its UDP target (we're only * connected to hubs, and the hub which got it should only forward that * message it its neighbouring hubs, not to leaves). * * If there is a /PI/RELAY, the ping was relayed by a hub, but it made * a mistake because we are a leaf node. */ g2_node_drop(G_STRFUNC, n, t, "has children and we are a leaf"); }