Mercurial > hg > index.fcgi > gift-gnutella > gift-gnutella-0.0.11-1pba
diff 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 |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/message/ping.c Sat Feb 20 21:18:28 2010 -0800 1.3 @@ -0,0 +1,196 @@ 1.4 +/* 1.5 + * $Id: ping.c,v 1.4 2004/03/05 17:49:40 hipnod 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_list.h" 1.24 +#include "gt_bind.h" 1.25 +#include "gt_netorg.h" 1.26 + 1.27 +#include "gt_stats.h" 1.28 +#include "gt_share.h" 1.29 + 1.30 +/******************************************************************************/ 1.31 + 1.32 +BOOL gt_is_pow2 (uint32_t num) 1.33 +{ 1.34 + return BOOL_EXPR (num > 0 && (num & (num-1)) == 0); 1.35 +} 1.36 + 1.37 +static uint32_t get_shared_size (unsigned long size_mb) 1.38 +{ 1.39 + uint32_t size_kb; 1.40 + 1.41 + size_kb = size_mb * 1024; 1.42 + 1.43 + if (GT_SELF->klass & GT_NODE_ULTRA) 1.44 + /* TODO: round up to nearest power of two >= 8 here */; 1.45 + else if (gt_is_pow2 (size_kb)) 1.46 + size_kb += 5; /* unmakes all powers of two, including 1 */ 1.47 + 1.48 + return size_kb; 1.49 +} 1.50 + 1.51 +/* reply to a ping packet */ 1.52 +static void ping_reply_self (GtPacket *packet, TCPC *c) 1.53 +{ 1.54 + unsigned long files, size_kb; 1.55 + double size_mb; 1.56 + GtPacket *reply; 1.57 + 1.58 + share_index (&files, &size_mb); 1.59 + size_kb = get_shared_size (size_mb); 1.60 + 1.61 + if (!(reply = gt_packet_reply (packet, GT_MSG_PING_REPLY))) 1.62 + return; 1.63 + 1.64 + gt_packet_put_port (reply, GT_SELF->gt_port); 1.65 + gt_packet_put_ip (reply, GT_NODE(c)->my_ip); 1.66 + gt_packet_put_uint32 (reply, (uint32_t)files); 1.67 + gt_packet_put_uint32 (reply, (uint32_t)size_kb); 1.68 + 1.69 + if (gt_packet_error (reply)) 1.70 + { 1.71 + gt_packet_free (reply); 1.72 + return; 1.73 + } 1.74 + 1.75 + gt_packet_send (c, reply); 1.76 + gt_packet_free (reply); 1.77 +} 1.78 + 1.79 +/* send info about node dst to node c */ 1.80 +static TCPC *send_status (TCPC *c, GtNode *node, void **data) 1.81 +{ 1.82 + GtPacket *pkt = (GtPacket *) data[0]; 1.83 + TCPC *dst = (TCPC *) data[1]; 1.84 + GtPacket *reply; 1.85 + 1.86 + /* don't send a ping for the node itself */ 1.87 + if (c == dst) 1.88 + return NULL; 1.89 + 1.90 + if (!(reply = gt_packet_reply (pkt, GT_MSG_PING_REPLY))) 1.91 + return NULL; 1.92 + 1.93 + gt_packet_put_port (reply, node->gt_port); 1.94 + gt_packet_put_ip (reply, node->ip); 1.95 + gt_packet_put_uint32 (reply, node->files); 1.96 + gt_packet_put_uint32 (reply, node->size_kb); 1.97 + 1.98 + /* set the number of hops travelled to 1 */ 1.99 + gt_packet_set_hops (reply, 1); 1.100 + 1.101 + if (gt_packet_error (reply)) 1.102 + { 1.103 + gt_packet_free (reply); 1.104 + return NULL; 1.105 + } 1.106 + 1.107 + gt_packet_send (dst, reply); 1.108 + gt_packet_free (reply); 1.109 + 1.110 + return NULL; 1.111 +} 1.112 + 1.113 +static void handle_crawler_ping (GtPacket *packet, TCPC *c) 1.114 +{ 1.115 + void *data[2]; 1.116 + 1.117 + data[0] = packet; 1.118 + data[1] = c; 1.119 + 1.120 + /* reply ourselves */ 1.121 + ping_reply_self (packet, c); 1.122 + 1.123 + /* send pings from connected hosts */ 1.124 + gt_conn_foreach (GT_CONN_FOREACH(send_status), data, 1.125 + GT_NODE_NONE, GT_NODE_CONNECTED, 0); 1.126 +} 1.127 + 1.128 +static BOOL need_connections (void) 1.129 +{ 1.130 + BOOL am_ultrapeer; 1.131 + 1.132 + am_ultrapeer = GT_SELF->klass & GT_NODE_ULTRA; 1.133 + 1.134 + /* send a pong if we need connections, but do this 1.135 + * only if this is a search node: leaves shouldnt send pongs */ 1.136 + if (gt_conn_need_connections (GT_NODE_ULTRA) > 0 && am_ultrapeer) 1.137 + return TRUE; 1.138 + 1.139 + /* pretend we need connections temporarily even if we don't in order to 1.140 + * figure out whether we are firewalled or not */ 1.141 + if (gt_uptime () < 10 * EMINUTES && GT_SELF->firewalled) 1.142 + return TRUE; 1.143 + 1.144 + return FALSE; 1.145 +} 1.146 + 1.147 +GT_MSG_HANDLER(gt_msg_ping) 1.148 +{ 1.149 + time_t last_ping_time, now; 1.150 + uint8_t ttl, hops; 1.151 + 1.152 + now = time (NULL); 1.153 + 1.154 + ttl = gt_packet_ttl (packet); 1.155 + hops = gt_packet_hops (packet); 1.156 + 1.157 + last_ping_time = GT_NODE(c)->last_ping_time; 1.158 + GT_NODE(c)->last_ping_time = now; 1.159 + 1.160 + if ((ttl == 1 && (hops == 0 || hops == 1)) /* tests if host is up */ 1.161 + || GT_NODE(c)->state == GT_NODE_CONNECTING_2 /* need to reply */ 1.162 + || need_connections ()) /* we need connections */ 1.163 + { 1.164 + ping_reply_self (packet, c); 1.165 + 1.166 + if (ttl == 1) 1.167 + return; 1.168 + } 1.169 + else if (ttl == 2 && hops == 0) 1.170 + { 1.171 + /* crawler ping: respond with all connected nodes */ 1.172 + handle_crawler_ping (packet, c); 1.173 + return; 1.174 + } 1.175 + 1.176 + /* dont re-broadcast pings from search nodes if we are not one */ 1.177 + if ((GT_NODE(c)->klass & GT_NODE_ULTRA) && !(GT_SELF->klass & GT_NODE_ULTRA)) 1.178 + return; 1.179 + 1.180 +#if 0 1.181 + /* notify this host when the pong cache gets full */ 1.182 + pong_cache_waiter_add (c, packet); 1.183 +#endif 1.184 + 1.185 + /* dont accept pings too often */ 1.186 + if (now - last_ping_time < 30 * ESECONDS) 1.187 + return; 1.188 + 1.189 +#if 0 1.190 + if (!pong_cache_reply (c, packet)) 1.191 + { 1.192 + /* refill the pong cache */ 1.193 + pong_cache_refill (); 1.194 + return; 1.195 + } 1.196 + 1.197 + pong_cache_waiter_remove (c); 1.198 +#endif 1.199 +}