Mercurial > hg > index.fcgi > gift-gnutella > gift-gnutella-0.0.11-1pba
diff src/message/ping_reply.c @ 0:d39e1d0d75b6
initial add
author | paulo@hit-nxdomain.opendns.com |
---|---|
date | Sat, 20 Feb 2010 21:18:28 -0800 |
parents | |
children |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/message/ping_reply.c Sat Feb 20 21:18:28 2010 -0800 1.3 @@ -0,0 +1,156 @@ 1.4 +/* 1.5 + * $Id: ping_reply.c,v 1.7 2005/01/04 15:00:52 mkern Exp $ 1.6 + * 1.7 + * Copyright (C) 2001-2003 giFT project (gift.sourceforge.net) 1.8 + * 1.9 + * This program is free software; you can redistribute it and/or modify it 1.10 + * under the terms of the GNU General Public License as published by the 1.11 + * Free Software Foundation; either version 2, or (at your option) any 1.12 + * later version. 1.13 + * 1.14 + * This program is distributed in the hope that it will be useful, but 1.15 + * WITHOUT ANY WARRANTY; without even the implied warranty of 1.16 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 1.17 + * General Public License for more details. 1.18 + */ 1.19 + 1.20 +#include "gt_gnutella.h" 1.21 +#include "message/msg_handler.h" 1.22 + 1.23 +#include "gt_node_cache.h" 1.24 +#include "gt_connect.h" 1.25 +#include "gt_bind.h" 1.26 + 1.27 +#include "gt_search.h" 1.28 +#include "gt_share_state.h" 1.29 +#include "gt_query_route.h" 1.30 +#include "gt_stats.h" 1.31 + 1.32 +/*****************************************************************************/ 1.33 + 1.34 +extern BOOL gt_is_pow2 (uint32_t num); /* ping.c */ 1.35 + 1.36 +/*****************************************************************************/ 1.37 + 1.38 +/* 1.39 + * Update the port on the first pong or when the pong contains a different 1.40 + * pong. 1.41 + */ 1.42 +static void update_port (GtNode *node, in_port_t new_port) 1.43 +{ 1.44 + /* update the port */ 1.45 + node->gt_port = new_port; 1.46 + 1.47 + /* 1.48 + * Test if the node is connectable. This will play with the node's 1.49 + * ->verified and ->firewalled bits. 1.50 + * 1.51 + * This is only important if this node is running as an ultrapeer, because 1.52 + * it lets us know whether we should route queries from firewalled peers 1.53 + * to the remote node. 1.54 + */ 1.55 + if (GT_SELF->klass & GT_NODE_ULTRA) 1.56 + gt_connect_test (node, node->gt_port); 1.57 +} 1.58 + 1.59 +/* 1.60 + * Transition the node into state 'connected', and do various things. This 1.61 + * has become a bit crufty and miscellaneous. TODO: change this to a callback 1.62 + * registration system in gt_node.c, register the callbacks in gt_gnutella.c 1.63 + */ 1.64 +static BOOL complete_connection (GtNode *node) 1.65 +{ 1.66 + /* mark this node as now connected */ 1.67 + gt_node_state_set (node, GT_NODE_CONNECTED); 1.68 + 1.69 + /* submit the routing table */ 1.70 + if ((node->klass & GT_NODE_ULTRA) && 1.71 + !(GT_SELF->klass & GT_NODE_ULTRA)) 1.72 + { 1.73 + query_route_table_submit (GT_CONN(node)); 1.74 + } 1.75 + 1.76 + /* submit unfinished searches soon */ 1.77 + gt_searches_submit (GT_CONN(node), 30 * SECONDS); 1.78 + 1.79 + /* let the bind subsystem send a ConnectBack for tracking firewalled 1.80 + * status */ 1.81 + gt_bind_completed_connection (node); 1.82 + 1.83 + if (!(node->share_state = gt_share_state_new ())) 1.84 + return FALSE; 1.85 + 1.86 + gt_share_state_update (node); 1.87 + 1.88 + return TRUE; 1.89 +} 1.90 + 1.91 +GT_MSG_HANDLER(gt_msg_ping_reply) 1.92 +{ 1.93 + in_port_t port; 1.94 + in_addr_t ip; 1.95 + uint32_t files; 1.96 + uint32_t size_kb; 1.97 + gt_node_class_t klass; 1.98 + 1.99 + port = gt_packet_get_port (packet); 1.100 + ip = gt_packet_get_ip (packet); 1.101 + files = gt_packet_get_uint32 (packet); 1.102 + size_kb = gt_packet_get_uint32 (packet); 1.103 + 1.104 + /* this will keep the node from being disconnected by idle-check loop */ 1.105 + if (node->pings_with_noreply > 0) 1.106 + node->pings_with_noreply = 0; 1.107 + 1.108 + /* update stats and port */ 1.109 + if (gt_packet_ttl (packet) == 1 && gt_packet_hops (packet) == 0) 1.110 + { 1.111 + /* check if this is the first ping response on this connection */ 1.112 + if (node->state == GT_NODE_CONNECTING_2) 1.113 + { 1.114 + if (!complete_connection (node)) 1.115 + { 1.116 + gt_node_disconnect (c); 1.117 + return; 1.118 + } 1.119 + } 1.120 + 1.121 + if (ip == node->ip) 1.122 + { 1.123 + if (node->gt_port != port || !node->verified) 1.124 + update_port (node, port); 1.125 + 1.126 + /* update stats information */ 1.127 + node->size_kb = size_kb; 1.128 + node->files = files; 1.129 + 1.130 + /* don't add this node to the cache */ 1.131 + return; 1.132 + } 1.133 + 1.134 + /* 1.135 + * Morpheus nodes send pongs for other nodes with Hops=1. If 1.136 + * the IP doesn't equal the observed IP, then add the node to the 1.137 + * node cache. This may create problems with trying to connect twice 1.138 + * to some users, though. 1.139 + */ 1.140 + } 1.141 + 1.142 + /* add this node to the cache */ 1.143 + klass = GT_NODE_LEAF; 1.144 + 1.145 + /* LimeWire marks ultrapeer pongs by making files size a power of two */ 1.146 + if (size_kb >= 8 && gt_is_pow2 (size_kb)) 1.147 + klass = GT_NODE_ULTRA; 1.148 + 1.149 + /* don't register this node if its local and the peer isnt */ 1.150 + if (gt_is_local_ip (ip, node->ip)) 1.151 + return; 1.152 + 1.153 + /* keep track of stats from pongs */ 1.154 + gt_stats_accumulate (ip, port, node->ip, files, size_kb); 1.155 + 1.156 + /* TODO: check uptime GGEP extension and add it here */ 1.157 + gt_node_cache_add_ipv4 (ip, port, klass, time (NULL), 0, node->ip); 1.158 + gt_node_cache_trace (); 1.159 +}