~ubuntu-branches/ubuntu/raring/gift-gnutella/raring

« back to all changes in this revision

Viewing changes to src/message/ping.c

  • Committer: Bazaar Package Importer
  • Author(s): Göran Weinholt
  • Date: 2005-07-31 13:56:53 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20050731135653-3i7bcwnrbe7wfd1i
Tags: 0.0.10.1-1
* New upstream version.
  - Fixes FTBFS with gcc-4.0 (closes: #286732).
* Updated debian/patches/update-gwebcaches.patch.
* Updated debian/patches/remove-too-old-check.patch.
* debian/control:
  - Change the encoding of my name to UTF-8.
  - Updated to Standards-Version: 3.6.2 (no changes).

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
}