From a98b548418bd0dcb8882ef913bcc2fbb516e0f2c Mon Sep 17 00:00:00 2001 From: Christian Grothoff Date: Sat, 15 Jan 2022 20:13:59 +0100 Subject: -add hold/drop logic --- src/dht/gnunet-service-dht.c | 45 ++++++++++++++++-------- src/dht/gnunet-service-dht.h | 26 ++++++++++++-- src/dht/gnunet-service-dht_neighbours.c | 61 +++++++++++++++++++++++++++++---- src/dht/gnunet-service-dht_neighbours.h | 2 +- 4 files changed, 111 insertions(+), 23 deletions(-) (limited to 'src/dht') diff --git a/src/dht/gnunet-service-dht.c b/src/dht/gnunet-service-dht.c index 35e219926..ae2ff6f7a 100644 --- a/src/dht/gnunet-service-dht.c +++ b/src/dht/gnunet-service-dht.c @@ -46,18 +46,18 @@ /** * Information we keep per underlay. */ -struct Underlay +struct GDS_Underlay { /** * Kept in a DLL. */ - struct Underlay *next; + struct GDS_Underlay *next; /** * Kept in a DLL. */ - struct Underlay *prev; + struct GDS_Underlay *prev; /** * Environment for this underlay. @@ -109,7 +109,7 @@ struct MyAddress /** * Underlay of this address. */ - struct Underlay *u; + struct GDS_Underlay *u; }; @@ -141,12 +141,12 @@ static struct GNUNET_SCHEDULER_Task *hello_task; /** * Handles for the DHT underlays. */ -static struct Underlay *u_head; +static struct GDS_Underlay *u_head; /** * Handles for the DHT underlays. */ -static struct Underlay *u_tail; +static struct GDS_Underlay *u_tail; /** * Head of addresses of this peer. @@ -168,7 +168,7 @@ static double log_of_network_size_estimate; /** * Callback that is called when network size estimate is updated. * - * @param cls a `struct Underlay` + * @param cls a `struct GDS_Underlay` * @param timestamp time when the estimate was received from the server (or created by the server) * @param logestimate the log(Base 2) value of the current network size estimate * @param std_dev standard deviation for the estimate @@ -180,7 +180,7 @@ update_network_size_estimate (void *cls, double logestimate, double std_dev) { - struct Underlay *u = cls; + struct GDS_Underlay *u = cls; double sum = 0.0; GNUNET_STATISTICS_update (GDS_stats, @@ -191,7 +191,7 @@ update_network_size_estimate (void *cls, u->network_size_estimate = pow (2.0, GNUNET_MAX (0.5, logestimate)); - for (struct Underlay *p; NULL != p; p = p->next) + for (struct GDS_Underlay *p; NULL != p; p = p->next) sum += p->network_size_estimate; if (sum <= 2.0) log_of_network_size_estimate = 0.5; @@ -257,7 +257,7 @@ u_address_add (void *cls, struct GNUNET_DHTU_Source *source, void **ctx) { - struct Underlay *u = cls; + struct GDS_Underlay *u = cls; struct MyAddress *a; a = GNUNET_new (struct MyAddress); @@ -305,7 +305,7 @@ void GDS_u_try_connect (const struct GNUNET_PeerIdentity *pid, const char *address) { - for (struct Underlay *u = u_head; + for (struct GDS_Underlay *u = u_head; NULL != u; u = u->next) u->dhtu->try_connect (u->dhtu->cls, @@ -315,7 +315,7 @@ GDS_u_try_connect (const struct GNUNET_PeerIdentity *pid, void -GDS_u_send (struct Underlay *u, +GDS_u_send (struct GDS_Underlay *u, struct GNUNET_DHTU_Target *target, const void *msg, size_t msg_size, @@ -331,6 +331,23 @@ GDS_u_send (struct Underlay *u, } +void +GDS_u_drop (struct GDS_Underlay *u, + struct GNUNET_DHTU_PreferenceHandle *ph) +{ + u->dhtu->drop (ph); +} + + +struct GNUNET_DHTU_PreferenceHandle * +GDS_u_hold (struct GDS_Underlay *u, + struct GNUNET_DHTU_Target *target) +{ + return u->dhtu->hold (u->dhtu->cls, + target); +} + + /** * Task run during shutdown. * @@ -370,7 +387,7 @@ static void load_underlay (void *cls, const char *section) { - struct Underlay *u; + struct GDS_Underlay *u; char *libname; (void) cls; @@ -384,7 +401,7 @@ load_underlay (void *cls, "ENABLED")) return; section += strlen ("dhtu-"); - u = GNUNET_new (struct Underlay); + u = GNUNET_new (struct GDS_Underlay); u->env.cls = u; u->env.address_add_cb = &u_address_add; u->env.address_del_cb = &u_address_del; diff --git a/src/dht/gnunet-service-dht.h b/src/dht/gnunet-service-dht.h index 403b3f5a1..d3bb39455 100644 --- a/src/dht/gnunet-service-dht.h +++ b/src/dht/gnunet-service-dht.h @@ -37,7 +37,7 @@ /** * Information we keep per underlay. */ -struct Underlay; +struct GDS_Underlay; /** * Configuration we use. @@ -107,7 +107,7 @@ GDS_u_try_connect (const struct GNUNET_PeerIdentity *pid, * @param finished_cb_cls closure for @a finished_cb */ void -GDS_u_send (struct Underlay *u, +GDS_u_send (struct GDS_Underlay *u, struct GNUNET_DHTU_Target *target, const void *msg, size_t msg_size, @@ -115,6 +115,28 @@ GDS_u_send (struct Underlay *u, void *finished_cb_cls); +/** + * Drop a hold @a ph from underlay @a u. + * + * @param u the underlay controlling the hold + * @param ph the preference handle + */ +void +GDS_u_drop (struct GDS_Underlay *u, + struct GNUNET_DHTU_PreferenceHandle *ph); + + +/** + * Create a hold on @a target at underlay @a u. + * + * @param u the underlay controlling the target + * @param target the peer to hold the connection to + */ +struct GNUNET_DHTU_PreferenceHandle * +GDS_u_hold (struct GDS_Underlay *u, + struct GNUNET_DHTU_Target *target); + + /** * Handle a reply we've received from another peer. If the reply * matches any of our pending queries, forward it to the respective diff --git a/src/dht/gnunet-service-dht_neighbours.c b/src/dht/gnunet-service-dht_neighbours.c index b7b5e8097..213308ca6 100644 --- a/src/dht/gnunet-service-dht_neighbours.c +++ b/src/dht/gnunet-service-dht_neighbours.c @@ -281,13 +281,18 @@ struct Target /** * Underlay providing this target. */ - struct Underlay *u; + struct GDS_Underlay *u; /** * Peer this is a target for. */ struct PeerInfo *pi; + /** + * Handle used to 'hold' the connection to this peer. + */ + struct GNUNET_DHTU_PreferenceHandle *ph; + /** * Set to number of messages are waiting for the transmission to finish. */ @@ -686,15 +691,48 @@ send_find_peer_message (void *cls) } +/** + * The list of the first #bucket_size peers of @a bucket + * changed. We should thus make sure we have called 'hold' + * all of the first bucket_size peers! + * + * @param[in,out] bucket the bucket where the peer set changed + */ +static void +update_hold (struct PeerBucket *bucket) +{ + unsigned int off = 0; + + /* find the peer -- we just go over all of them, should + be hardly any more expensive than just finding the 'right' + one. */ + for (struct PeerInfo *pos = bucket->head; + NULL != pos; + pos = pos->next) + { + if (off > bucket_size) + break; /* We only hold up to #bucket_size peers per bucket */ + bucket_size++; + for (struct Target *tp = pos->t_head; + NULL != tp; + tp = tp->next) + if (NULL == tp->ph) + tp->ph = GDS_u_hold (tp->u, + tp->utarget); + } +} + + void GDS_u_connect (void *cls, struct GNUNET_DHTU_Target *target, const struct GNUNET_PeerIdentity *pid, void **ctx) { - struct Underlay *u = cls; + struct GDS_Underlay *u = cls; struct PeerInfo *pi; struct PeerBucket *bucket; + bool do_hold = false; /* Check for connect to self message */ if (0 == GNUNET_memcmp (&GDS_my_identity, @@ -734,7 +772,7 @@ GDS_u_connect (void *cls, if (bucket->peers_size <= bucket_size) { newly_found_peers++; - // FIXME: call 'hold'! + do_hold = true; } if ( (1 == GNUNET_CONTAINER_multipeermap_size (all_connected_peers)) && (GNUNET_YES != disable_try_connect) ) @@ -758,6 +796,8 @@ GDS_u_connect (void *cls, *ctx = t; } + if (do_hold) + update_hold (bucket); } @@ -767,6 +807,7 @@ GDS_u_disconnect (void *ctx) struct Target *t = ctx; struct PeerInfo *pi; struct PeerBucket *bucket; + bool was_held = false; /* Check for disconnect from self message (on shutdown) */ if (NULL == t) @@ -775,6 +816,13 @@ GDS_u_disconnect (void *ctx) GNUNET_CONTAINER_DLL_remove (pi->t_head, pi->t_tail, t); + if (NULL != t->ph) + { + GDS_u_drop (t->u, + t->ph); + t->ph = NULL; + was_held = true; + } if (t->load > 0) { t->dropped = true; @@ -810,8 +858,9 @@ GDS_u_disconnect (void *ctx) pi); GNUNET_assert (bucket->peers_size > 0); bucket->peers_size--; - // FIXME: check if this peer was in one of the first 'bucket_size' - // peers, and call 'hold' on the next peer if there is any! + if ( (was_held) && + (bucket->peers_size >= bucket_size - 1) ) + update_hold (bucket); while ( (closest_bucket > 0) && (0 == k_buckets[closest_bucket - 1].peers_size)) closest_bucket--; @@ -2426,7 +2475,7 @@ GDS_u_receive (void *cls, }; const struct GNUNET_MessageHeader *mh = message; - (void) cls; /* the 'struct Underlay' */ + (void) cls; /* the 'struct GDS_Underlay' */ (void) sctx; /* our receiver address */ if (message_size < sizeof (*mh)) { diff --git a/src/dht/gnunet-service-dht_neighbours.h b/src/dht/gnunet-service-dht_neighbours.h index 5a4c8c620..fecdbe9f1 100644 --- a/src/dht/gnunet-service-dht_neighbours.h +++ b/src/dht/gnunet-service-dht_neighbours.h @@ -136,7 +136,7 @@ GDS_am_closest_peer (const struct GNUNET_HashCode *key, * Function to call when we connect to a peer and can henceforth transmit to * that peer. * - * @param cls the closure, must be a `struct Underlay` + * @param cls the closure, must be a `struct GDS_Underlay` * @param target handle to the target, * pointer will remain valid until @e disconnect_cb is called * @para pid peer identity, -- cgit v1.2.3