view 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 source
1 /*
2 * $Id: ping_reply.c,v 1.7 2005/01/04 15:00:52 mkern Exp $
3 *
4 * Copyright (C) 2001-2003 giFT project (gift.sourceforge.net)
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2, or (at your option) any
9 * later version.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
15 */
17 #include "gt_gnutella.h"
18 #include "message/msg_handler.h"
20 #include "gt_node_cache.h"
21 #include "gt_connect.h"
22 #include "gt_bind.h"
24 #include "gt_search.h"
25 #include "gt_share_state.h"
26 #include "gt_query_route.h"
27 #include "gt_stats.h"
29 /*****************************************************************************/
31 extern BOOL gt_is_pow2 (uint32_t num); /* ping.c */
33 /*****************************************************************************/
35 /*
36 * Update the port on the first pong or when the pong contains a different
37 * pong.
38 */
39 static void update_port (GtNode *node, in_port_t new_port)
40 {
41 /* update the port */
42 node->gt_port = new_port;
44 /*
45 * Test if the node is connectable. This will play with the node's
46 * ->verified and ->firewalled bits.
47 *
48 * This is only important if this node is running as an ultrapeer, because
49 * it lets us know whether we should route queries from firewalled peers
50 * to the remote node.
51 */
52 if (GT_SELF->klass & GT_NODE_ULTRA)
53 gt_connect_test (node, node->gt_port);
54 }
56 /*
57 * Transition the node into state 'connected', and do various things. This
58 * has become a bit crufty and miscellaneous. TODO: change this to a callback
59 * registration system in gt_node.c, register the callbacks in gt_gnutella.c
60 */
61 static BOOL complete_connection (GtNode *node)
62 {
63 /* mark this node as now connected */
64 gt_node_state_set (node, GT_NODE_CONNECTED);
66 /* submit the routing table */
67 if ((node->klass & GT_NODE_ULTRA) &&
68 !(GT_SELF->klass & GT_NODE_ULTRA))
69 {
70 query_route_table_submit (GT_CONN(node));
71 }
73 /* submit unfinished searches soon */
74 gt_searches_submit (GT_CONN(node), 30 * SECONDS);
76 /* let the bind subsystem send a ConnectBack for tracking firewalled
77 * status */
78 gt_bind_completed_connection (node);
80 if (!(node->share_state = gt_share_state_new ()))
81 return FALSE;
83 gt_share_state_update (node);
85 return TRUE;
86 }
88 GT_MSG_HANDLER(gt_msg_ping_reply)
89 {
90 in_port_t port;
91 in_addr_t ip;
92 uint32_t files;
93 uint32_t size_kb;
94 gt_node_class_t klass;
96 port = gt_packet_get_port (packet);
97 ip = gt_packet_get_ip (packet);
98 files = gt_packet_get_uint32 (packet);
99 size_kb = gt_packet_get_uint32 (packet);
101 /* this will keep the node from being disconnected by idle-check loop */
102 if (node->pings_with_noreply > 0)
103 node->pings_with_noreply = 0;
105 /* update stats and port */
106 if (gt_packet_ttl (packet) == 1 && gt_packet_hops (packet) == 0)
107 {
108 /* check if this is the first ping response on this connection */
109 if (node->state == GT_NODE_CONNECTING_2)
110 {
111 if (!complete_connection (node))
112 {
113 gt_node_disconnect (c);
114 return;
115 }
116 }
118 if (ip == node->ip)
119 {
120 if (node->gt_port != port || !node->verified)
121 update_port (node, port);
123 /* update stats information */
124 node->size_kb = size_kb;
125 node->files = files;
127 /* don't add this node to the cache */
128 return;
129 }
131 /*
132 * Morpheus nodes send pongs for other nodes with Hops=1. If
133 * the IP doesn't equal the observed IP, then add the node to the
134 * node cache. This may create problems with trying to connect twice
135 * to some users, though.
136 */
137 }
139 /* add this node to the cache */
140 klass = GT_NODE_LEAF;
142 /* LimeWire marks ultrapeer pongs by making files size a power of two */
143 if (size_kb >= 8 && gt_is_pow2 (size_kb))
144 klass = GT_NODE_ULTRA;
146 /* don't register this node if its local and the peer isnt */
147 if (gt_is_local_ip (ip, node->ip))
148 return;
150 /* keep track of stats from pongs */
151 gt_stats_accumulate (ip, port, node->ip, files, size_kb);
153 /* TODO: check uptime GGEP extension and add it here */
154 gt_node_cache_add_ipv4 (ip, port, klass, time (NULL), 0, node->ip);
155 gt_node_cache_trace ();
156 }