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