Mercurial > hg > index.fcgi > gift-gnutella > gift-gnutella-0.0.11-1pba
comparison 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 |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:a3a0851834ba |
---|---|
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 */ | |
16 | |
17 #include "gt_gnutella.h" | |
18 #include "message/msg_handler.h" | |
19 | |
20 #include "gt_node_cache.h" | |
21 #include "gt_connect.h" | |
22 #include "gt_bind.h" | |
23 | |
24 #include "gt_search.h" | |
25 #include "gt_share_state.h" | |
26 #include "gt_query_route.h" | |
27 #include "gt_stats.h" | |
28 | |
29 /*****************************************************************************/ | |
30 | |
31 extern BOOL gt_is_pow2 (uint32_t num); /* ping.c */ | |
32 | |
33 /*****************************************************************************/ | |
34 | |
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; | |
43 | |
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 } | |
55 | |
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); | |
65 | |
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 } | |
72 | |
73 /* submit unfinished searches soon */ | |
74 gt_searches_submit (GT_CONN(node), 30 * SECONDS); | |
75 | |
76 /* let the bind subsystem send a ConnectBack for tracking firewalled | |
77 * status */ | |
78 gt_bind_completed_connection (node); | |
79 | |
80 if (!(node->share_state = gt_share_state_new ())) | |
81 return FALSE; | |
82 | |
83 gt_share_state_update (node); | |
84 | |
85 return TRUE; | |
86 } | |
87 | |
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; | |
95 | |
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); | |
100 | |
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; | |
104 | |
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 } | |
117 | |
118 if (ip == node->ip) | |
119 { | |
120 if (node->gt_port != port || !node->verified) | |
121 update_port (node, port); | |
122 | |
123 /* update stats information */ | |
124 node->size_kb = size_kb; | |
125 node->files = files; | |
126 | |
127 /* don't add this node to the cache */ | |
128 return; | |
129 } | |
130 | |
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 } | |
138 | |
139 /* add this node to the cache */ | |
140 klass = GT_NODE_LEAF; | |
141 | |
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; | |
145 | |
146 /* don't register this node if its local and the peer isnt */ | |
147 if (gt_is_local_ip (ip, node->ip)) | |
148 return; | |
149 | |
150 /* keep track of stats from pongs */ | |
151 gt_stats_accumulate (ip, port, node->ip, files, size_kb); | |
152 | |
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 } |