/** * Handle reception of a /LNI */ static void g2_node_handle_lni(gnutella_node_t *n, const g2_tree_t *t) { g2_tree_t *c; /* * Handle the children of /LNI. */ G2_TREE_CHILD_FOREACH(t, c) { enum g2_lni_child ct = TOKENIZE(g2_tree_name(c), g2_lni_children); const char *payload; size_t paylen; switch (ct) { case G2_LNI_GU: /* the node's GUID */ payload = g2_tree_node_payload(c, &paylen); if (GUID_RAW_SIZE == paylen) node_set_guid(n, (guid_t *) payload, TRUE); break; case G2_LNI_NA: /* the node's address, with listening port */ { host_addr_t addr; uint16 port; if (g2_node_parse_address(c, &addr, &port)) { if (host_address_is_usable(addr)) n->gnet_addr = addr; n->gnet_port = port; } } break; case G2_LNI_LS: /* library statistics */ payload = g2_tree_node_payload(c, &paylen); if (paylen >= 8) { uint32 files = peek_le32(payload); uint32 kbytes = peek_le32(&payload[4]); n->gnet_files_count = files; n->gnet_kbytes_count = kbytes; n->flags |= NODE_F_SHARED_INFO; } break; case G2_LNI_V: /* vendor code */ payload = g2_tree_node_payload(c, &paylen); if (paylen >= 4) n->vcode.u32 = peek_be32(payload); break; case G2_LNI_UP: /* uptime */ payload = g2_tree_node_payload(c, &paylen); if (paylen <= 4) n->up_date = tm_time() - vlint_decode(payload, paylen); break; } } }
/** * Check whether host is connectible. * * i.e. that it has a valid port and that its IP address is not private * nor bogus. */ gboolean host_is_valid(const host_addr_t addr, guint16 port) { if (!port_is_valid(port)) return FALSE; return host_address_is_usable(addr); }
/** * @return whether host's address is a valid DHT value creator. */ bool knode_addr_is_usable(const knode_t *kn) { knode_check(kn); if (!host_address_is_usable(kn->addr)) return FALSE; if (hostiles_is_bad(kn->addr)) return FALSE; return TRUE; }