2
* $Id: pcache.c,v 1.48 2004/01/14 20:52:33 rmanfredi Exp $
4
* Copyright (c) 2001-2003, Raphael Manfredi
6
* Pong caching (LimeWire's ping/pong reducing scheme).
8
*----------------------------------------------------------------------
9
* This file is part of gtk-gnutella.
11
* gtk-gnutella is free software; you can redistribute it and/or modify
12
* it under the terms of the GNU General Public License as published by
13
* the Free Software Foundation; either version 2 of the License, or
14
* (at your option) any later version.
16
* gtk-gnutella is distributed in the hope that it will be useful,
17
* but WITHOUT ANY WARRANTY; without even the implied warranty of
18
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19
* GNU General Public License for more details.
21
* You should have received a copy of the GNU General Public License
22
* along with gtk-gnutella; if not, write to the Free Software
24
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25
*----------------------------------------------------------------------
32
#include <sys/types.h>
35
#include <netinet/in.h>
36
#include <arpa/inet.h>
43
#include "share.h" /* For files_scanned and kbytes_scanned. */
48
#include "gnet_stats.h"
52
#include "override.h" /* Must be the last header included */
54
RCSID("$Id: pcache.c,v 1.48 2004/01/14 20:52:33 rmanfredi Exp $");
63
* Sends a ping to given node, or broadcast to everyone if `n' is NULL.
65
static void send_ping(struct gnutella_node *n, guint8 ttl)
67
struct gnutella_msg_init m;
69
message_set_muid(&m.header, GTA_MSG_INIT);
71
m.header.function = GTA_MSG_INIT;
75
WRITE_GUINT32_LE(0, m.header.size);
78
if (NODE_IS_WRITABLE(n)) {
80
gmsg_sendto_one(n, (gchar *) &m, sizeof(struct gnutella_msg_init));
83
const GSList *sl_nodes = node_all_nodes();
87
* XXX Have to loop to count pings sent.
88
* XXX Need to do that more generically, to factorize code.
91
for (sl = sl_nodes; sl; sl = g_slist_next(sl)) {
92
n = (struct gnutella_node *) sl->data;
93
if (!NODE_IS_WRITABLE(n))
98
gmsg_sendto_all(sl_nodes, (gchar *) &m,
99
sizeof(struct gnutella_msg_init));
106
* Send ping to immediate neighbour, to check its latency and the fact
107
* that it is alive, or get its Gnet sharing information (ip, port).
108
* The message is sent as a "control" one, i.e. it's put ahead of the queue.
110
* The message ID used is copied back to `muid'.
112
* NB: this routine is only made visible for "alive.c".
114
void send_alive_ping(struct gnutella_node *n, gchar *muid)
116
struct gnutella_msg_init m;
118
g_assert(NODE_IS_WRITABLE(n));
121
message_set_muid(&m.header, GTA_MSG_INIT);
122
memcpy(muid, &m.header, 16);
124
m.header.function = GTA_MSG_INIT;
128
WRITE_GUINT32_LE(0, m.header.size);
131
gmsg_ctrl_sendto_one(n, (gchar *) &m, sizeof(struct gnutella_msg_init));
137
* Build pong message, returns pointer to static data.
139
struct gnutella_msg_init_response *build_pong_msg(
140
guint8 hops, guint8 ttl, gchar *muid,
141
guint32 ip, guint16 port, guint32 files, guint32 kbytes)
143
static struct gnutella_msg_init_response pong;
145
pong.header.function = GTA_MSG_INIT_RESPONSE;
146
pong.header.hops = hops;
147
pong.header.ttl = ttl;
148
memcpy(&pong.header.muid, muid, 16);
150
WRITE_GUINT16_LE(port, pong.response.host_port);
151
WRITE_GUINT32_BE(ip, pong.response.host_ip);
152
WRITE_GUINT32_LE(files, pong.response.files_count);
153
WRITE_GUINT32_LE(kbytes, pong.response.kbytes_count);
154
WRITE_GUINT32_LE(sizeof(struct gnutella_init_response), pong.header.size);
162
* Send pong message back to node.
163
* If `control' is true, send it as a higher priority message.
165
static void send_pong(struct gnutella_node *n, gboolean control,
166
guint8 hops, guint8 ttl, gchar *muid,
167
guint32 ip, guint16 port, guint32 files, guint32 kbytes)
169
struct gnutella_msg_init_response *r;
173
if (!NODE_IS_WRITABLE(n))
176
r = build_pong_msg(hops, ttl, muid, ip, port, files, kbytes);
180
gmsg_ctrl_sendto_one(n, (gchar *) r, sizeof(*r));
182
gmsg_sendto_one(n, (gchar *) r, sizeof(*r));
188
* Send info about us back to node, using the hopcount information present in
189
* the header of the node structure to construct the TTL of the pong we
192
* If `control' is true, send it as a higher priority message.
194
static void send_personal_info(struct gnutella_node *n, gboolean control)
198
g_assert(n->header.function == GTA_MSG_INIT); /* Replying to a ping */
200
if (!force_local_ip && !local_ip)
201
return; /* If we don't know yet our local IP, we can't reply */
204
* Mark pong if we are an ultra node: the amount of kbytes scanned must
205
* be an exact power of two, and at minimum 8.
208
if (current_peermode == NODE_P_ULTRA) {
209
if (kbytes_scanned <= 8)
212
kbytes = next_pow2(kbytes_scanned);
213
} else if (kbytes_scanned)
214
kbytes = kbytes_scanned | 0x1; /* Ensure not a power of two */
217
* Pongs are sent with a TTL just large enough to reach the pinging host,
218
* up to a maximum of max_ttl. Note that we rely on the hop count being
223
send_pong(n, control, 0, MIN(n->header.hops + 1, max_ttl), n->header.muid,
224
listen_ip(), listen_port, files_scanned, kbytes);
228
* send_neighbouring_info
230
* Send a pong for each of our connected neighbours to specified node.
232
static void send_neighbouring_info(struct gnutella_node *n)
236
g_assert(n->header.function == GTA_MSG_INIT); /* Replying to a ping */
237
g_assert(n->header.hops == 0); /* Originates from node */
238
g_assert(n->header.ttl == 2); /* "Crawler" ping */
240
for (sl = node_all_nodes(); sl; sl = g_slist_next(sl)) {
241
struct gnutella_node *cn = (struct gnutella_node *) sl->data;
243
if (!NODE_IS_WRITABLE(cn))
247
* If we have valid Gnet information for the node, build the pong
248
* as if it came from the neighbour, only we don't send the ping,
249
* and don't have to read back the pong and resent it.
251
* Otherwise, don't send anything back: we no longer keep routing
252
* information for pings.
255
if (cn->gnet_ip == 0)
256
continue; /* No information yet */
259
1, 1, n->header.muid, /* hops = 1, TTL = 1 */
260
cn->gnet_ip, cn->gnet_port,
261
cn->gnet_files_count, cn->gnet_kbytes_count);
264
* Since we won't see the neighbour pong, we won't be able to store
265
* it in our reserve, so do it from here.
268
if (!NODE_IS_LEAF(n))
269
host_add(cn->gnet_ip, cn->gnet_port, FALSE);
272
* Node can be removed should its send queue saturate.
275
if (!NODE_IS_CONNECTED(n))
281
*** Ping/pong reducing scheme.
285
* Data structures used:
287
* `pong_cache' is an array of MAX_CACHE_HOPS+1 entries.
288
* Each entry is a structure holding a one-way list and a traversal pointer
289
* so we may iterate over the list of cached pongs at that hop level.
291
* `cache_expire_time' is the time after which we will expire the whole cache
292
* and ping all our connections.
295
static time_t pcache_expire_time = 0;
297
struct cached_pong { /* A cached pong */
298
gint refcount; /* How many lists reference us? */
299
guint32 node_id; /* The node ID from which we got that pong */
300
guint32 last_sent_id; /* Node ID to which we last sent this pong */
301
guint32 ip; /* Values from the pong message */
304
guint32 kbytes_count;
307
struct cache_line { /* A cache line for a given hop value */
308
gint hops; /* Hop count of this cache line */
309
GSList *pongs; /* List of cached_pong */
310
GSList *cursor; /* Cursor within list: last item traversed */
314
GHashTable *ht_recent_pongs; /* Recent pongs we know about */
315
GList *recent_pongs; /* Recent pongs we got */
316
GList *last_returned_pong; /* Last returned from list */
317
gint recent_pong_count; /* # of pongs in recent list */
320
#define PONG_CACHE_SIZE (MAX_CACHE_HOPS+1)
322
static struct cache_line pong_cache[PONG_CACHE_SIZE];
323
static struct recent recent_pongs[HCACHE_MAX];
325
#define CACHE_UP_LIFESPAN 5 /* seconds -- ultra/normal mode */
326
#define CACHE_LEAF_LIFESPAN 120 /* seconds -- leaf mode */
327
#define MAX_PONGS 10 /* Max pongs returned per ping */
328
#define OLD_PING_PERIOD 45 /* Pinging period for "old" clients */
329
#define OLD_CACHE_RATIO 20 /* % of pongs from "old" clients we cache */
330
#define RECENT_PING_SIZE 50 /* remember last 50 pongs we saw */
331
#define MIN_UP_PING 3 /* ping at least 3 neighbours */
332
#define UP_PING_RATIO 20 /* ping 20% of UP, at random */
334
#define cache_lifespan(m) \
335
((m) == NODE_P_LEAF ? CACHE_LEAF_LIFESPAN : CACHE_UP_LIFESPAN)
341
* Callbacks for the `ht_recent_pongs' hash table.
344
static guint cached_pong_hash(gconstpointer key)
346
const struct cached_pong *cp = (const struct cached_pong *) key;
348
return (guint) (cp->ip ^ ((cp->port << 16) | cp->port));
350
static gint cached_pong_eq(gconstpointer v1, gconstpointer v2)
352
const struct cached_pong *h1 = (const struct cached_pong *) v1;
353
const struct cached_pong *h2 = (const struct cached_pong *) v2;
355
return h1->ip == h2->ip && h1->port == h2->port;
361
void pcache_init(void)
365
memset(pong_cache, 0, sizeof(pong_cache));
366
memset(recent_pongs, 0, sizeof(recent_pongs));
368
for (h = 0; h < PONG_CACHE_SIZE; h++)
369
pong_cache[h].hops = h;
371
recent_pongs[HCACHE_ANY].ht_recent_pongs =
372
g_hash_table_new(cached_pong_hash, cached_pong_eq);
374
recent_pongs[HCACHE_ULTRA].ht_recent_pongs =
375
g_hash_table_new(cached_pong_hash, cached_pong_eq);
381
* Free cached pong when noone references it any more.
383
static void free_cached_pong(struct cached_pong *cp)
385
g_assert(cp->refcount > 0); /* Someone was referencing it */
387
if (--(cp->refcount) != 0)
390
wfree(cp, sizeof(*cp));
397
* Get a recent pong from the list, updating `last_returned_pong' as we
398
* go along, so that we never return twice the same pong instance.
400
* Fills `ip' and `port' with the pong value and return TRUE if we
401
* got a pong. Otherwise return FALSE.
403
gboolean pcache_get_recent(hcache_type_t type, guint32 *ip, guint16 *port)
405
static guint32 last_ip = 0;
406
static guint16 last_port = 0;
408
struct cached_pong *cp;
411
g_assert(type >= 0 && type < HCACHE_MAX);
413
rec = &recent_pongs[type];
415
if (!rec->recent_pongs) /* List empty */
419
* If `last_returned_pong' is NULL, it means we reached the head
420
* of the list, so we traverse faster than we get pongs.
422
* Try with the head of the list, because maybe we have a recent pong
423
* there, but if it is the same as the last ip/port we returned, then
424
* go back to the tail of the list.
427
if (rec->last_returned_pong == NULL) {
428
l = g_list_first(rec->recent_pongs);
429
cp = (struct cached_pong *) l->data;
431
if (cp->ip != last_ip || cp->port != last_port)
434
if (g_list_next(l) == NULL) /* Head is the only item in list */
438
l = g_list_previous(rec->last_returned_pong);
439
for (/* empty */ ; l; l = g_list_previous(l)) {
440
cp = (struct cached_pong *) l->data;
441
if (cp->ip != last_ip || cp->port != last_port)
447
* Still none found, go back to the end of the list.
450
for (l = g_list_last(rec->recent_pongs); l; l = g_list_previous(l)) {
451
cp = (struct cached_pong *) l->data;
452
if (cp->ip != last_ip || cp->port != last_port)
459
rec->last_returned_pong = l;
460
*ip = last_ip = cp->ip;
461
*port = last_port = cp->port;
464
printf("returning recent %s PONG %s\n",
465
hcache_type_to_gchar(type), ip_port_to_gchar(cp->ip, cp->port));
473
* Add recent pong to the list, handled as a FIFO cache, if not already
476
static void add_recent_pong(hcache_type_t type, struct cached_pong *cp)
480
g_assert(type >= 0 && type < HCACHE_MAX);
482
rec = &recent_pongs[type];
484
if (g_hash_table_lookup(rec->ht_recent_pongs, (gconstpointer) cp))
487
if (rec->recent_pong_count == RECENT_PING_SIZE) { /* Full */
488
GList *lnk = g_list_last(rec->recent_pongs);
489
struct cached_pong *cp = (struct cached_pong *) lnk->data;
491
rec->recent_pongs = g_list_remove_link(rec->recent_pongs, lnk);
492
g_hash_table_remove(rec->ht_recent_pongs, cp);
494
if (lnk == rec->last_returned_pong)
495
rec->last_returned_pong = g_list_previous(rec->last_returned_pong);
497
free_cached_pong(cp);
500
rec->recent_pong_count++;
502
rec->recent_pongs = g_list_prepend(rec->recent_pongs, cp);
503
g_hash_table_insert(rec->ht_recent_pongs, cp, (gpointer) 1);
504
cp->refcount++; /* We don't refcount insertion in the hash table */
510
* Determine the pong type (any, or of the ultra kind).
512
static hcache_type_t pong_type(struct gnutella_init_response *pong)
516
READ_GUINT32_LE(pong->kbytes_count, kbytes);
519
* Ultra pongs are marked by having their kbytes count be an
520
* exact power of two, and greater than 8.
523
return (kbytes >= 8 && is_pow2(kbytes)) ? HCACHE_ULTRA : HCACHE_ANY;
527
* pcache_clear_recent
529
* Clear the whole recent pong list.
531
void pcache_clear_recent(hcache_type_t type)
536
g_assert(type >= 0 && type < HCACHE_MAX);
538
rec = &recent_pongs[type];
540
for (l = rec->recent_pongs; l; l = g_list_next(l)) {
541
struct cached_pong *cp = (struct cached_pong *) l->data;
543
g_hash_table_remove(rec->ht_recent_pongs, cp);
544
free_cached_pong(cp);
547
g_list_free(rec->recent_pongs);
548
rec->recent_pongs = NULL;
549
rec->last_returned_pong = NULL;
550
rec->recent_pong_count = 0;
554
* pcache_outgoing_connection
556
* Called when a new outgoing connection has been made.
558
* + If we need a connection, or have less than MAX_PONGS entries in our caught
559
* list, send a ping at normal TTL value.
560
* + Otherwise, send a handshaking ping with TTL=1
562
void pcache_outgoing_connection(struct gnutella_node *n)
564
g_assert(NODE_IS_CONNECTED(n));
566
if (connected_nodes() < up_connections || hcache_is_low(HCACHE_ANY))
567
send_ping(n, my_ttl); /* Regular ping, get fresh pongs */
569
send_ping(n, 1); /* Handshaking ping */
575
* Expire the whole cache.
577
static void pcache_expire(void)
582
for (i = 0; i < PONG_CACHE_SIZE; i++) {
583
struct cache_line *cl = &pong_cache[i];
586
for (sl = cl->pongs; sl; sl = g_slist_next(sl)) {
588
free_cached_pong((struct cached_pong *) sl->data);
590
g_slist_free(cl->pongs);
597
printf("Pong CACHE expired (%d entr%s, %d in reserve)\n",
598
entries, entries == 1 ? "y" : "ies", hcache_size(HCACHE_ANY));
606
void pcache_close(void)
608
static hcache_type_t types[] = { HCACHE_ANY, HCACHE_ULTRA };
613
for (i = 0; i < sizeof(types) / sizeof(types[0]); i++) {
614
hcache_type_t type = types[i];
616
pcache_clear_recent(type);
617
g_hash_table_destroy(recent_pongs[type].ht_recent_pongs);
622
* ping_all_neighbours
624
* Send a ping to all "new" clients to which we are connected, and one to
625
* older client if and only if at least OLD_PING_PERIOD seconds have
626
* elapsed since our last ping, as determined by `next_ping'.
628
static void ping_all_neighbours(time_t now)
631
GSList *may_ping = NULL;
632
GSList *to_ping = NULL;
638
* Because nowadays the network has a higher outdegree for ultrapeers,
639
* and because of the widespread use of X-Try-Ultrapeers headers, it is
640
* less critical to use pings as a way to collect hosts.
642
* Therefore, don't ping all neighbours but only UP_PING_RATIO percent
643
* of them, chosen at random, with at least MIN_UP_PING hosts chosen.
648
for (sl = node_all_nodes(); sl; sl = g_slist_next(sl)) {
649
struct gnutella_node *n = (struct gnutella_node *) sl->data;
651
if (!NODE_IS_WRITABLE(n) || NODE_IS_LEAF(n))
655
* If node is in TX flow control, we already have problems,
656
* so don't increase them by sending more pings.
660
if (NODE_IN_TX_FLOW_CONTROL(n))
663
if ((n->attrs & NODE_A_PONG_CACHING) || now > n->next_ping) {
664
may_ping = g_slist_prepend(may_ping, n);
669
for (sl = may_ping, left = ping_cnt; sl; sl = g_slist_next(sl), left--) {
670
struct gnutella_node *n = (struct gnutella_node *) sl->data;
673
ping_cnt <= MIN_UP_PING ||
674
(selected < MIN_UP_PING && left <= (MIN_UP_PING - selected)) ||
675
random_value(99) < UP_PING_RATIO
677
to_ping = g_slist_prepend(to_ping, n);
682
for (sl = to_ping; sl; sl = g_slist_next(sl)) {
683
struct gnutella_node *n = (struct gnutella_node *) sl->data;
685
if (!(n->attrs & NODE_A_PONG_CACHING))
686
n->next_ping = now + OLD_PING_PERIOD;
688
send_ping(n, my_ttl);
691
g_slist_free(may_ping);
692
g_slist_free(to_ping);
696
* pcache_possibly_expired
698
* Check pong cache for expiration.
699
* If expiration time is reached, flush it and ping all our neighbours.
701
void pcache_possibly_expired(time_t now)
703
if (now >= pcache_expire_time) {
705
pcache_expire_time = now + cache_lifespan(current_peermode);
706
ping_all_neighbours(now);
711
* pcache_set_peermode
713
* Called when peer mode is changed to recompute the pong cache lifetime.
715
void pcache_set_peermode(node_peer_t mode)
717
pcache_expire_time = time(NULL) + cache_lifespan(mode);
721
* setup_pong_demultiplexing
723
* Fill ping_guid[] and pong_needed[] arrays in the node from which we just
726
* When we accept a ping from a connection, we don't really relay the ping.
727
* Our cache is filled by the pongs we receive back from our periodic
728
* pinging of the neighbours.
730
* However, when we get some pongs back, we forward them back to the nodes
731
* for which we have accepted a ping and which still need results, as
732
* determined by pong_needed[] (index by pong hop count). The saved GUID
733
* of the ping allows us to fake the pong reply, so the sending node recognizes
734
* those as being "his" pongs.
736
static void setup_pong_demultiplexing(
737
struct gnutella_node *n, gchar *muid, guint8 ttl)
742
g_assert(n->header.function == GTA_MSG_INIT);
744
memcpy(n->ping_guid, n->header.muid, 16);
745
memset(n->pong_needed, 0, sizeof(n->pong_needed));
749
* `ttl' is currently the amount of hops the ping could travel.
750
* If it's 1, it means it would have travelled on host still, and we
751
* would have got a pong back with an hop count of 0.
753
* Since our pong_needed[] array is indexed by the hop count of pongs,
754
* we need to substract one from the ttl parameter.
760
ttl = MIN(ttl, MAX_CACHE_HOPS); /* We limit the maximum hop count */
763
* Now we're going to distribute "evenly" the MAX_PONGS we can return
764
* to this ping accross the (0..ttl) range. We start by the beginning
765
* of the array to give more weight to high-hops pongs.
768
n->pong_missing = remains = MAX_PONGS;
770
for (h = 0; h <= MAX_CACHE_HOPS; h++) {
771
guchar amount = (guchar) (remains / (MAX_CACHE_HOPS + 1 - h));
772
n->pong_needed[h] = amount;
775
printf("pong_needed[%d] = %d, remains = %d\n", h, amount, remains);
778
g_assert(remains == 0);
782
* iterate_on_cached_line
784
* Internal routine for send_cached_pongs.
786
* Iterates on a list of cached pongs and send back any pong to node `n'
787
* that did not originate from it. Update `cursor' in the cached line
788
* to be the address of the last traversed item.
790
* Return FALSE if we're definitely done, TRUE if we can still iterate.
792
static gboolean iterate_on_cached_line(
793
struct gnutella_node *n, struct cache_line *cl, guint8 ttl,
794
GSList *start, GSList *end, gboolean strict)
796
gint hops = cl->hops;
799
for (l = start; l && l != end && n->pong_missing; l = g_slist_next(l)) {
800
struct cached_pong *cp = (struct cached_pong *) l->data;
805
* We never send a cached pong to the node from which it came along.
807
* The `last_sent_id' trick is used because we're going to iterate
808
* twice on the cache list: once to send pongs that strictly match
809
* the hop counts needed, and another time to send pongs as needed,
810
* more loosely. The two runs are consecutive, so we're saving in
811
* each cached entry the node to which we sent it last, so we don't
812
* resend the same pong twice.
814
* We're only iterating upon reception of the intial ping from the
815
* node. After that, we'll send pongs as we receive them, and
816
* only if they strictly match the needed TTL.
819
if (n->id == cp->node_id)
821
if (n->id == cp->last_sent_id)
823
cp->last_sent_id = n->id;
826
* When sending a cached pong, don't forget that its cached hop count
827
* is the one we got when we received it, i.e. hops=0 means a pong
828
* from one of our immediate neighbours. However, we're now "routing"
829
* it, so we must increase the hop count.
832
g_assert(hops < 255); /* Because of MAX_CACHE_HOPS */
834
send_pong(n, FALSE, hops + 1, ttl, n->ping_guid,
835
cp->ip, cp->port, cp->files_count, cp->kbytes_count);
840
printf("iterate: sent cached pong %s (hops=%d, TTL=%d) to %s, "
841
"missing=%d %s\n", ip_port_to_gchar(cp->ip, cp->port),
842
hops, ttl, node_ip(n), n->pong_missing,
843
strict ? "STRICT" : "loose");
845
if (strict && --(n->pong_needed[hops]) == 0)
849
* Node can be removed should its send queue saturate.
852
if (!NODE_IS_CONNECTED(n))
856
return n->pong_missing != 0;
862
* Send pongs from cache line back to node `n' if more are needed for this
863
* hop count and they are not originating from the node. When `strict'
864
* is false, we send even if no pong at that hop level is needed.
866
static void send_cached_pongs(struct gnutella_node *n,
867
struct cache_line *cl, guint8 ttl, gboolean strict)
869
gint hops = cl->hops;
870
GSList *old = cl->cursor;
872
if (strict && !n->pong_needed[hops])
876
* We start iterating after `cursor', until the end of the list, at which
877
* time we restart from the beginning until we reach `cursor', included.
878
* When we leave, `cursor' will point to the last traversed item.
882
if (!iterate_on_cached_line(n, cl, ttl, old->next, NULL, strict))
884
(void) iterate_on_cached_line(n, cl, ttl, cl->pongs, old->next, strict);
886
(void) iterate_on_cached_line(n, cl, ttl, cl->pongs, NULL, strict);
890
* pong_all_neighbours_but_one
892
* We received a pong we cached from `n'. Send it to all other nodes if
893
* they need one at this hop count.
895
static void pong_all_neighbours_but_one(
896
struct gnutella_node *n, struct cached_pong *cp, hcache_type_t ptype,
897
guint8 hops, guint8 ttl)
901
for (sl = node_all_nodes(); sl; sl = g_slist_next(sl)) {
902
struct gnutella_node *cn = (struct gnutella_node *) sl->data;
907
if (!NODE_IS_WRITABLE(cn))
911
* Since we iterate twice initially at ping reception, once strictly
912
* and the other time loosly, `pong_missing' is always accurate but
913
* can be different from the sum of `pong_needed[i]', for all `i'.
916
if (!cn->pong_missing)
919
if (!cn->pong_needed[hops])
923
* If node is a leaf node, we can only send it Ultra pongs.
926
if (NODE_IS_LEAF(cn) && ptype != HCACHE_ULTRA)
930
cn->pong_needed[hops]--;
933
* When sending a cached pong, don't forget that its cached hop count
934
* is the one we got when we received it, i.e. hops=0 means a pong
935
* from one of our immediate neighbours. However, we're now "routing"
936
* it, so we must increase the hop count.
939
g_assert(hops < 255);
941
send_pong(cn, FALSE, hops + 1, ttl, cn->ping_guid,
942
cp->ip, cp->port, cp->files_count, cp->kbytes_count);
945
printf("pong_all: sent cached pong %s (hops=%d, TTL=%d) to %s "
946
"missing=%d\n", ip_port_to_gchar(cp->ip, cp->port),
947
hops, ttl, node_ip(cn), cn->pong_missing);
954
* We received an ultra pong.
955
* Send it to one randomly selected leaf, which is not already missing pongs.
957
static void pong_random_leaf(struct cached_pong *cp, guint8 hops, guint8 ttl)
961
struct gnutella_node *leaf = NULL;
963
g_assert(current_peermode == NODE_P_ULTRA);
965
for (sl = node_all_nodes(), leaves = 0; sl; sl = g_slist_next(sl)) {
966
struct gnutella_node *cn = (struct gnutella_node *) sl->data;
969
if (cn->pong_missing) /* A job for pong_all_neighbours_but_one() */
972
if (!NODE_IS_LEAF(cn))
975
if (NODE_IN_TX_FLOW_CONTROL(cn)) /* Already overwhelmed */
979
* Randomly select one leaf.
981
* As we go along, the probability that we retain the current leaf
982
* decreases. It is 1 for the first leaf, 1/2 for the second leaf,
983
* 1/3 for the third leaf, etc...
987
threshold = (gint) (1000.0 / leaves);
989
if (random_value(999) < threshold)
994
* Send the pong to the selected leaf, if any.
996
* NB: If the leaf never sent a ping before, leaf->ping_guid will
997
* be a zero GUID. That's OK.
1001
send_pong(leaf, FALSE, hops + 1, ttl, leaf->ping_guid,
1002
cp->ip, cp->port, cp->files_count, cp->kbytes_count);
1005
printf("pong_random_leaf: sent pong %s (hops=%d, TTL=%d) to %s\n",
1006
ip_port_to_gchar(cp->ip, cp->port), hops, ttl, node_ip(leaf));
1013
* Add pong from node `n' to our cache of recent pongs.
1014
* Returns the cached pong object.
1016
static struct cached_pong *record_fresh_pong(
1018
struct gnutella_node *n,
1019
guint8 hops, guint32 ip, guint16 port,
1020
guint32 files_count, guint32 kbytes_count)
1022
struct cache_line *cl;
1023
struct cached_pong *cp;
1026
g_assert(type >= 0 && type < HCACHE_MAX);
1028
cp = (struct cached_pong *) walloc(sizeof(struct cached_pong));
1031
cp->node_id = n->id;
1032
cp->last_sent_id = n->id;
1035
cp->files_count = files_count;
1036
cp->kbytes_count = kbytes_count;
1038
hop = CACHE_HOP_IDX(hops); /* Trim high values to MAX_CACHE_HOPS */
1039
cl = &pong_cache[hop];
1040
cl->pongs = g_slist_append(cl->pongs, cp);
1041
add_recent_pong(type, cp);
1047
* pcache_ping_received
1049
* Called when a ping is received from a node.
1051
* + If current time is less than what `ping_accept' says, drop the ping.
1052
* Otherwise, accept the ping and increment `ping_accept' by n->ping_throttle.
1053
* + If cache expired, call pcache_expire() and broadcast a new ping to all
1054
* the "new" clients (i.e. those flagged NODE_A_PONG_CACHING). For "old"
1055
* clients, do so only if "next_ping" time was reached.
1056
* + Handle "alive" pings (TTL=1) and "crawler" pings (TTL=2) immediately,
1058
* + Setup pong demultiplexing tables, recording the fact that the node needs
1059
* to be sent pongs as we receive them.
1060
* + Return a pong for us if we accept incoming connections right now.
1061
* + Return cached pongs, avoiding to resend a pong coming from that node ID.
1063
void pcache_ping_received(struct gnutella_node *n)
1065
time_t now = time((time_t *) 0);
1069
g_assert(NODE_IS_CONNECTED(n));
1072
* Handle "alive" pings and "crawler" pings specially.
1073
* Besides, we always accept them.
1076
if (n->header.hops == 0 && n->header.ttl <= 2) {
1077
n->n_ping_special++;
1078
if (n->header.ttl == 1)
1079
send_personal_info(n, TRUE); /* Control message, prioritary */
1080
else if (n->header.ttl == 2) {
1081
if (current_peermode != NODE_P_LEAF)
1082
send_neighbouring_info(n);
1089
* If we get a ping with hops != 0 from a host that claims to
1090
* implement ping/pong reduction, then they are not playing
1091
* by the same rules as we are. Emit a warning.
1097
(n->attrs & (NODE_A_PONG_CACHING|NODE_A_PONG_ALIEN)) ==
1101
g_warning("node %s (%s) [%d.%d] claimed ping reduction, "
1102
"got ping with hops=%d", node_ip(n),
1104
n->proto_major, n->proto_minor, n->header.hops);
1105
n->attrs |= NODE_A_PONG_ALIEN; /* Warn only once */
1112
if (now < n->ping_accept) {
1113
n->n_ping_throttle++; /* Drop the ping */
1115
gnet_stats_count_dropped(n, MSG_DROP_THROTTLE);
1118
n->n_ping_accepted++;
1119
n->ping_accept = now + n->ping_throttle; /* Drop all until then */
1123
* Purge cache if needed.
1126
pcache_possibly_expired(now);
1128
if (!NODE_IS_CONNECTED(n)) /* Can be removed if send queue is full */
1132
* If TTL = 0, only us can reply, and we'll do that below in any case..
1133
* We call setup_pong_demultiplexing() anyway to reset the pong_needed[]
1136
* A leaf node will not demultiplex pongs, so don't bother.
1139
if (current_peermode != NODE_P_LEAF)
1140
setup_pong_demultiplexing(n, n->header.muid, n->header.ttl);
1143
* If we can accept an incoming connection, send a reply.
1145
* If we are firewalled, we nonetheless send a ping
1146
* when inet_can_answer_ping() tells us we can, irrespective
1147
* of whether we can accept a new node connection: the aim is
1148
* to trigger an incoming connection that will prove us we're
1153
(is_firewalled || node_missing() > 0) && inet_can_answer_ping()
1155
send_personal_info(n, FALSE);
1156
if (!NODE_IS_CONNECTED(n)) /* Can be removed if send queue is full */
1160
if (current_peermode == NODE_P_LEAF)
1164
* We continue here only for non-leaf nodes.
1168
* Return cached pongs if we have some and they are needed.
1169
* We first try to send pongs on a per-hop basis, based on pong_needed[].
1172
ttl = MIN(n->header.hops + 1, max_ttl);
1174
for (h = 0; n->pong_missing && h < n->header.ttl; h++) {
1175
struct cache_line *cl = &pong_cache[CACHE_HOP_IDX(h)];
1178
send_cached_pongs(n, cl, ttl, TRUE);
1179
if (!NODE_IS_CONNECTED(n))
1185
* We then re-iterate if some pongs are still needed, sending any we
1186
* did not already send.
1189
for (h = 0; n->pong_missing && h < n->header.ttl; h++) {
1190
struct cache_line *cl = &pong_cache[CACHE_HOP_IDX(h)];
1193
send_cached_pongs(n, cl, ttl, FALSE);
1194
if (!NODE_IS_CONNECTED(n))
1201
* pcache_pong_received
1203
* Called when a pong is received from a node.
1205
* + Record node in the main host catching list.
1206
* + If node is not a "new" client (i.e. flagged as NODE_A_PONG_CACHING),
1207
* cache randomly OLD_CACHE_RATIO percent of those (older clients need
1208
* to be able to get incoming connections as well).
1209
* + Cache pong in the pong.hops cache line, associated with the node ID (so we
1210
* never send back this entry to the node).
1211
* + For all nodes but `n', propagate pong if neeed, with demultiplexing.
1213
void pcache_pong_received(struct gnutella_node *n)
1217
guint32 files_count;
1218
guint32 kbytes_count;
1219
struct cached_pong *cp;
1220
hcache_type_t ptype;
1222
n->n_pong_received++;
1225
* Decompile the pong information.
1228
READ_GUINT16_LE(n->data, port);
1229
READ_GUINT32_BE(n->data + 2, ip);
1230
READ_GUINT32_LE(n->data + 6, files_count);
1231
READ_GUINT32_LE(n->data + 10, kbytes_count);
1234
* Handle replies from our neighbours specially
1237
if (n->header.hops == 0) {
1239
* For an incoming connection, we might not know the GNet IP address
1240
* of the remote node yet (we know the remote endpoint, but it could
1241
* be a proxy for a firewalled node). The information from the pong
1242
* may help us fill this gap.
1245
if (n->gnet_ip == 0 && (n->flags & NODE_F_INCOMING)) {
1247
n->gnet_ip = ip; /* Signals: we have figured it out */
1248
n->gnet_port = port;
1249
} else if (!(n->flags & NODE_F_ALIEN_IP)) {
1251
"node %s (%s) sent us a pong for itself with alien IP %s",
1252
node_ip(n), node_vendor(n), ip_to_gchar(ip));
1253
n->flags |= NODE_F_ALIEN_IP; /* Probably firewalled */
1258
* Only record library stats for the node if it is the first pong
1259
* we receive from it (likely to be a reply to our handshaking ping)
1260
* or if it comes from the node's IP.
1261
* Indeed, LimeWire suffers from a bug where it will forward foreign
1262
* pongs with hops=0 even though they are not coming from the node.
1263
* --RAM, 11/01/2004.
1266
if (n->n_pong_received == 1 || ip == n->gnet_ip) {
1267
n->gnet_files_count = files_count;
1268
n->gnet_kbytes_count = kbytes_count;
1272
* Spot any change in the pong's IP address. We try to avoid messages
1273
* about "connection pongs" by checking whether we have sent at least
1274
* 2 pings (one handshaking ping plus one another).
1277
if (n->gnet_pong_ip && ip != n->gnet_pong_ip) {
1278
if (dbg && n->n_ping_sent > 2) g_warning(
1279
"node %s (%s) sent us a pong for new IP %s (used %s before)",
1280
node_ip(n), node_vendor(n),
1281
ip_port_to_gchar(ip, port), ip_to_gchar(n->gnet_pong_ip));
1284
n->gnet_pong_ip = ip;
1287
* If it was an acknowledge for one of our alive pings, don't cache.
1290
if (alive_ack_ping(n->alive_pings, n->header.muid))
1295
* If it's not a connectible pong, discard it.
1298
if (!host_is_valid(ip, port)) {
1299
gnet_stats_count_dropped(n, MSG_DROP_PONG_UNUSABLE);
1304
* If pong points to an hostile IP address, discard it.
1307
if (hostiles_check(ip)) {
1308
gnet_stats_count_dropped(n, MSG_DROP_HOSTILE_IP);
1313
* If pong points to us, maybe we explicitly connected to ourselves
1314
* (tests) or someone is trying to fool us.
1317
if (ip == listen_ip() && port == listen_port)
1321
* Add pong to our reserve, and possibly try to connect.
1324
host_add(ip, port, TRUE);
1327
* If we got a pong from an "old" client, cache OLD_CACHE_RATIO of
1328
* its pongs, randomly. Returning from this routine means we won't
1332
if (!(n->attrs & NODE_A_PONG_CACHING)) {
1333
gint ratio = (gint) random_value(100);
1334
if (ratio >= OLD_CACHE_RATIO) {
1336
printf("NOT CACHED pong %s (hops=%d, TTL=%d) from OLD %s\n",
1337
ip_port_to_gchar(ip, port), n->header.hops, n->header.ttl,
1344
* Insert pong within our cache.
1347
ptype = pong_type((struct gnutella_init_response *) n->data);
1349
cp = record_fresh_pong(HCACHE_ANY, n, n->header.hops, ip, port,
1350
files_count, kbytes_count);
1352
if (ptype == HCACHE_ULTRA)
1353
(void) record_fresh_pong(HCACHE_ULTRA, n, n->header.hops, ip, port,
1354
files_count, kbytes_count);
1357
printf("CACHED %s pong %s (hops=%d, TTL=%d) from %s %s\n",
1358
ptype == HCACHE_ULTRA ? "ultra" : "normal",
1359
ip_port_to_gchar(ip, port), n->header.hops, n->header.ttl,
1360
(n->attrs & NODE_A_PONG_CACHING) ? "NEW" : "OLD", node_ip(n));
1363
* Demultiplex pong: send it to all the connections but the one we
1364
* received it from, provided they need more pongs of this hop count.
1367
if (current_peermode != NODE_P_LEAF)
1368
pong_all_neighbours_but_one(n,
1369
cp, ptype, CACHE_HOP_IDX(n->header.hops), MAX(1, n->header.ttl));
1372
* If we're in ultra mode, send 33% of all the ultra pongs we get
1373
* to one random leaf.
1377
current_peermode == NODE_P_ULTRA &&
1378
ptype == HCACHE_ULTRA && random_value(99) < 33
1381
cp, CACHE_HOP_IDX(n->header.hops), MAX(1, n->header.ttl));
1387
* Fake a pong for a node from which we received an incoming connection,
1388
* using the supplied IP/port.
1390
* This pong is not multiplexed to neighbours, but is used to populate our
1391
* cache, so we can return its address to others, assuming that if it is
1392
* making an incoming connection to us, it is really in need for other
1393
* connections as well.
1395
void pcache_pong_fake(struct gnutella_node *n, guint32 ip, guint16 port)
1397
if (!host_is_valid(ip, port))
1400
host_add(ip, port, FALSE);
1401
(void) record_fresh_pong(HCACHE_ANY, n, 1, ip, port, 0, 0);