Mercurial > hg > index.fcgi > gift-gnutella > gift-gnutella-0.0.11-1pba
comparison src/message/ping.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:5631ce47728c |
---|---|
1 /* | |
2 * $Id: ping.c,v 1.4 2004/03/05 17:49:40 hipnod 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_list.h" | |
21 #include "gt_bind.h" | |
22 #include "gt_netorg.h" | |
23 | |
24 #include "gt_stats.h" | |
25 #include "gt_share.h" | |
26 | |
27 /******************************************************************************/ | |
28 | |
29 BOOL gt_is_pow2 (uint32_t num) | |
30 { | |
31 return BOOL_EXPR (num > 0 && (num & (num-1)) == 0); | |
32 } | |
33 | |
34 static uint32_t get_shared_size (unsigned long size_mb) | |
35 { | |
36 uint32_t size_kb; | |
37 | |
38 size_kb = size_mb * 1024; | |
39 | |
40 if (GT_SELF->klass & GT_NODE_ULTRA) | |
41 /* TODO: round up to nearest power of two >= 8 here */; | |
42 else if (gt_is_pow2 (size_kb)) | |
43 size_kb += 5; /* unmakes all powers of two, including 1 */ | |
44 | |
45 return size_kb; | |
46 } | |
47 | |
48 /* reply to a ping packet */ | |
49 static void ping_reply_self (GtPacket *packet, TCPC *c) | |
50 { | |
51 unsigned long files, size_kb; | |
52 double size_mb; | |
53 GtPacket *reply; | |
54 | |
55 share_index (&files, &size_mb); | |
56 size_kb = get_shared_size (size_mb); | |
57 | |
58 if (!(reply = gt_packet_reply (packet, GT_MSG_PING_REPLY))) | |
59 return; | |
60 | |
61 gt_packet_put_port (reply, GT_SELF->gt_port); | |
62 gt_packet_put_ip (reply, GT_NODE(c)->my_ip); | |
63 gt_packet_put_uint32 (reply, (uint32_t)files); | |
64 gt_packet_put_uint32 (reply, (uint32_t)size_kb); | |
65 | |
66 if (gt_packet_error (reply)) | |
67 { | |
68 gt_packet_free (reply); | |
69 return; | |
70 } | |
71 | |
72 gt_packet_send (c, reply); | |
73 gt_packet_free (reply); | |
74 } | |
75 | |
76 /* send info about node dst to node c */ | |
77 static TCPC *send_status (TCPC *c, GtNode *node, void **data) | |
78 { | |
79 GtPacket *pkt = (GtPacket *) data[0]; | |
80 TCPC *dst = (TCPC *) data[1]; | |
81 GtPacket *reply; | |
82 | |
83 /* don't send a ping for the node itself */ | |
84 if (c == dst) | |
85 return NULL; | |
86 | |
87 if (!(reply = gt_packet_reply (pkt, GT_MSG_PING_REPLY))) | |
88 return NULL; | |
89 | |
90 gt_packet_put_port (reply, node->gt_port); | |
91 gt_packet_put_ip (reply, node->ip); | |
92 gt_packet_put_uint32 (reply, node->files); | |
93 gt_packet_put_uint32 (reply, node->size_kb); | |
94 | |
95 /* set the number of hops travelled to 1 */ | |
96 gt_packet_set_hops (reply, 1); | |
97 | |
98 if (gt_packet_error (reply)) | |
99 { | |
100 gt_packet_free (reply); | |
101 return NULL; | |
102 } | |
103 | |
104 gt_packet_send (dst, reply); | |
105 gt_packet_free (reply); | |
106 | |
107 return NULL; | |
108 } | |
109 | |
110 static void handle_crawler_ping (GtPacket *packet, TCPC *c) | |
111 { | |
112 void *data[2]; | |
113 | |
114 data[0] = packet; | |
115 data[1] = c; | |
116 | |
117 /* reply ourselves */ | |
118 ping_reply_self (packet, c); | |
119 | |
120 /* send pings from connected hosts */ | |
121 gt_conn_foreach (GT_CONN_FOREACH(send_status), data, | |
122 GT_NODE_NONE, GT_NODE_CONNECTED, 0); | |
123 } | |
124 | |
125 static BOOL need_connections (void) | |
126 { | |
127 BOOL am_ultrapeer; | |
128 | |
129 am_ultrapeer = GT_SELF->klass & GT_NODE_ULTRA; | |
130 | |
131 /* send a pong if we need connections, but do this | |
132 * only if this is a search node: leaves shouldnt send pongs */ | |
133 if (gt_conn_need_connections (GT_NODE_ULTRA) > 0 && am_ultrapeer) | |
134 return TRUE; | |
135 | |
136 /* pretend we need connections temporarily even if we don't in order to | |
137 * figure out whether we are firewalled or not */ | |
138 if (gt_uptime () < 10 * EMINUTES && GT_SELF->firewalled) | |
139 return TRUE; | |
140 | |
141 return FALSE; | |
142 } | |
143 | |
144 GT_MSG_HANDLER(gt_msg_ping) | |
145 { | |
146 time_t last_ping_time, now; | |
147 uint8_t ttl, hops; | |
148 | |
149 now = time (NULL); | |
150 | |
151 ttl = gt_packet_ttl (packet); | |
152 hops = gt_packet_hops (packet); | |
153 | |
154 last_ping_time = GT_NODE(c)->last_ping_time; | |
155 GT_NODE(c)->last_ping_time = now; | |
156 | |
157 if ((ttl == 1 && (hops == 0 || hops == 1)) /* tests if host is up */ | |
158 || GT_NODE(c)->state == GT_NODE_CONNECTING_2 /* need to reply */ | |
159 || need_connections ()) /* we need connections */ | |
160 { | |
161 ping_reply_self (packet, c); | |
162 | |
163 if (ttl == 1) | |
164 return; | |
165 } | |
166 else if (ttl == 2 && hops == 0) | |
167 { | |
168 /* crawler ping: respond with all connected nodes */ | |
169 handle_crawler_ping (packet, c); | |
170 return; | |
171 } | |
172 | |
173 /* dont re-broadcast pings from search nodes if we are not one */ | |
174 if ((GT_NODE(c)->klass & GT_NODE_ULTRA) && !(GT_SELF->klass & GT_NODE_ULTRA)) | |
175 return; | |
176 | |
177 #if 0 | |
178 /* notify this host when the pong cache gets full */ | |
179 pong_cache_waiter_add (c, packet); | |
180 #endif | |
181 | |
182 /* dont accept pings too often */ | |
183 if (now - last_ping_time < 30 * ESECONDS) | |
184 return; | |
185 | |
186 #if 0 | |
187 if (!pong_cache_reply (c, packet)) | |
188 { | |
189 /* refill the pong cache */ | |
190 pong_cache_refill (); | |
191 return; | |
192 } | |
193 | |
194 pong_cache_waiter_remove (c); | |
195 #endif | |
196 } |