aboutsummaryrefslogtreecommitdiff
path: root/src/dht
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2022-01-15 20:13:59 +0100
committerChristian Grothoff <christian@grothoff.org>2022-02-19 12:41:01 +0100
commita98b548418bd0dcb8882ef913bcc2fbb516e0f2c (patch)
treecc01a85acc08d4e01cd6c26e07ec9cd12fb36c94 /src/dht
parent4c3b6b2197ba4fb8d9d696c2a8ca9a170ad12529 (diff)
downloadgnunet-a98b548418bd0dcb8882ef913bcc2fbb516e0f2c.tar.gz
gnunet-a98b548418bd0dcb8882ef913bcc2fbb516e0f2c.zip
-add hold/drop logic
Diffstat (limited to 'src/dht')
-rw-r--r--src/dht/gnunet-service-dht.c45
-rw-r--r--src/dht/gnunet-service-dht.h26
-rw-r--r--src/dht/gnunet-service-dht_neighbours.c61
-rw-r--r--src/dht/gnunet-service-dht_neighbours.h2
4 files changed, 111 insertions, 23 deletions
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 @@
46/** 46/**
47 * Information we keep per underlay. 47 * Information we keep per underlay.
48 */ 48 */
49struct Underlay 49struct GDS_Underlay
50{ 50{
51 51
52 /** 52 /**
53 * Kept in a DLL. 53 * Kept in a DLL.
54 */ 54 */
55 struct Underlay *next; 55 struct GDS_Underlay *next;
56 56
57 /** 57 /**
58 * Kept in a DLL. 58 * Kept in a DLL.
59 */ 59 */
60 struct Underlay *prev; 60 struct GDS_Underlay *prev;
61 61
62 /** 62 /**
63 * Environment for this underlay. 63 * Environment for this underlay.
@@ -109,7 +109,7 @@ struct MyAddress
109 /** 109 /**
110 * Underlay of this address. 110 * Underlay of this address.
111 */ 111 */
112 struct Underlay *u; 112 struct GDS_Underlay *u;
113}; 113};
114 114
115 115
@@ -141,12 +141,12 @@ static struct GNUNET_SCHEDULER_Task *hello_task;
141/** 141/**
142 * Handles for the DHT underlays. 142 * Handles for the DHT underlays.
143 */ 143 */
144static struct Underlay *u_head; 144static struct GDS_Underlay *u_head;
145 145
146/** 146/**
147 * Handles for the DHT underlays. 147 * Handles for the DHT underlays.
148 */ 148 */
149static struct Underlay *u_tail; 149static struct GDS_Underlay *u_tail;
150 150
151/** 151/**
152 * Head of addresses of this peer. 152 * Head of addresses of this peer.
@@ -168,7 +168,7 @@ static double log_of_network_size_estimate;
168/** 168/**
169 * Callback that is called when network size estimate is updated. 169 * Callback that is called when network size estimate is updated.
170 * 170 *
171 * @param cls a `struct Underlay` 171 * @param cls a `struct GDS_Underlay`
172 * @param timestamp time when the estimate was received from the server (or created by the server) 172 * @param timestamp time when the estimate was received from the server (or created by the server)
173 * @param logestimate the log(Base 2) value of the current network size estimate 173 * @param logestimate the log(Base 2) value of the current network size estimate
174 * @param std_dev standard deviation for the estimate 174 * @param std_dev standard deviation for the estimate
@@ -180,7 +180,7 @@ update_network_size_estimate (void *cls,
180 double logestimate, 180 double logestimate,
181 double std_dev) 181 double std_dev)
182{ 182{
183 struct Underlay *u = cls; 183 struct GDS_Underlay *u = cls;
184 double sum = 0.0; 184 double sum = 0.0;
185 185
186 GNUNET_STATISTICS_update (GDS_stats, 186 GNUNET_STATISTICS_update (GDS_stats,
@@ -191,7 +191,7 @@ update_network_size_estimate (void *cls,
191 u->network_size_estimate = pow (2.0, 191 u->network_size_estimate = pow (2.0,
192 GNUNET_MAX (0.5, 192 GNUNET_MAX (0.5,
193 logestimate)); 193 logestimate));
194 for (struct Underlay *p; NULL != p; p = p->next) 194 for (struct GDS_Underlay *p; NULL != p; p = p->next)
195 sum += p->network_size_estimate; 195 sum += p->network_size_estimate;
196 if (sum <= 2.0) 196 if (sum <= 2.0)
197 log_of_network_size_estimate = 0.5; 197 log_of_network_size_estimate = 0.5;
@@ -257,7 +257,7 @@ u_address_add (void *cls,
257 struct GNUNET_DHTU_Source *source, 257 struct GNUNET_DHTU_Source *source,
258 void **ctx) 258 void **ctx)
259{ 259{
260 struct Underlay *u = cls; 260 struct GDS_Underlay *u = cls;
261 struct MyAddress *a; 261 struct MyAddress *a;
262 262
263 a = GNUNET_new (struct MyAddress); 263 a = GNUNET_new (struct MyAddress);
@@ -305,7 +305,7 @@ void
305GDS_u_try_connect (const struct GNUNET_PeerIdentity *pid, 305GDS_u_try_connect (const struct GNUNET_PeerIdentity *pid,
306 const char *address) 306 const char *address)
307{ 307{
308 for (struct Underlay *u = u_head; 308 for (struct GDS_Underlay *u = u_head;
309 NULL != u; 309 NULL != u;
310 u = u->next) 310 u = u->next)
311 u->dhtu->try_connect (u->dhtu->cls, 311 u->dhtu->try_connect (u->dhtu->cls,
@@ -315,7 +315,7 @@ GDS_u_try_connect (const struct GNUNET_PeerIdentity *pid,
315 315
316 316
317void 317void
318GDS_u_send (struct Underlay *u, 318GDS_u_send (struct GDS_Underlay *u,
319 struct GNUNET_DHTU_Target *target, 319 struct GNUNET_DHTU_Target *target,
320 const void *msg, 320 const void *msg,
321 size_t msg_size, 321 size_t msg_size,
@@ -331,6 +331,23 @@ GDS_u_send (struct Underlay *u,
331} 331}
332 332
333 333
334void
335GDS_u_drop (struct GDS_Underlay *u,
336 struct GNUNET_DHTU_PreferenceHandle *ph)
337{
338 u->dhtu->drop (ph);
339}
340
341
342struct GNUNET_DHTU_PreferenceHandle *
343GDS_u_hold (struct GDS_Underlay *u,
344 struct GNUNET_DHTU_Target *target)
345{
346 return u->dhtu->hold (u->dhtu->cls,
347 target);
348}
349
350
334/** 351/**
335 * Task run during shutdown. 352 * Task run during shutdown.
336 * 353 *
@@ -370,7 +387,7 @@ static void
370load_underlay (void *cls, 387load_underlay (void *cls,
371 const char *section) 388 const char *section)
372{ 389{
373 struct Underlay *u; 390 struct GDS_Underlay *u;
374 char *libname; 391 char *libname;
375 392
376 (void) cls; 393 (void) cls;
@@ -384,7 +401,7 @@ load_underlay (void *cls,
384 "ENABLED")) 401 "ENABLED"))
385 return; 402 return;
386 section += strlen ("dhtu-"); 403 section += strlen ("dhtu-");
387 u = GNUNET_new (struct Underlay); 404 u = GNUNET_new (struct GDS_Underlay);
388 u->env.cls = u; 405 u->env.cls = u;
389 u->env.address_add_cb = &u_address_add; 406 u->env.address_add_cb = &u_address_add;
390 u->env.address_del_cb = &u_address_del; 407 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 @@
37/** 37/**
38 * Information we keep per underlay. 38 * Information we keep per underlay.
39 */ 39 */
40struct Underlay; 40struct GDS_Underlay;
41 41
42/** 42/**
43 * Configuration we use. 43 * Configuration we use.
@@ -107,7 +107,7 @@ GDS_u_try_connect (const struct GNUNET_PeerIdentity *pid,
107 * @param finished_cb_cls closure for @a finished_cb 107 * @param finished_cb_cls closure for @a finished_cb
108 */ 108 */
109void 109void
110GDS_u_send (struct Underlay *u, 110GDS_u_send (struct GDS_Underlay *u,
111 struct GNUNET_DHTU_Target *target, 111 struct GNUNET_DHTU_Target *target,
112 const void *msg, 112 const void *msg,
113 size_t msg_size, 113 size_t msg_size,
@@ -116,6 +116,28 @@ GDS_u_send (struct Underlay *u,
116 116
117 117
118/** 118/**
119 * Drop a hold @a ph from underlay @a u.
120 *
121 * @param u the underlay controlling the hold
122 * @param ph the preference handle
123 */
124void
125GDS_u_drop (struct GDS_Underlay *u,
126 struct GNUNET_DHTU_PreferenceHandle *ph);
127
128
129/**
130 * Create a hold on @a target at underlay @a u.
131 *
132 * @param u the underlay controlling the target
133 * @param target the peer to hold the connection to
134 */
135struct GNUNET_DHTU_PreferenceHandle *
136GDS_u_hold (struct GDS_Underlay *u,
137 struct GNUNET_DHTU_Target *target);
138
139
140/**
119 * Handle a reply we've received from another peer. If the reply 141 * Handle a reply we've received from another peer. If the reply
120 * matches any of our pending queries, forward it to the respective 142 * matches any of our pending queries, forward it to the respective
121 * client(s). 143 * client(s).
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,7 +281,7 @@ struct Target
281 /** 281 /**
282 * Underlay providing this target. 282 * Underlay providing this target.
283 */ 283 */
284 struct Underlay *u; 284 struct GDS_Underlay *u;
285 285
286 /** 286 /**
287 * Peer this is a target for. 287 * Peer this is a target for.
@@ -289,6 +289,11 @@ struct Target
289 struct PeerInfo *pi; 289 struct PeerInfo *pi;
290 290
291 /** 291 /**
292 * Handle used to 'hold' the connection to this peer.
293 */
294 struct GNUNET_DHTU_PreferenceHandle *ph;
295
296 /**
292 * Set to number of messages are waiting for the transmission to finish. 297 * Set to number of messages are waiting for the transmission to finish.
293 */ 298 */
294 unsigned int load; 299 unsigned int load;
@@ -686,15 +691,48 @@ send_find_peer_message (void *cls)
686} 691}
687 692
688 693
694/**
695 * The list of the first #bucket_size peers of @a bucket
696 * changed. We should thus make sure we have called 'hold'
697 * all of the first bucket_size peers!
698 *
699 * @param[in,out] bucket the bucket where the peer set changed
700 */
701static void
702update_hold (struct PeerBucket *bucket)
703{
704 unsigned int off = 0;
705
706 /* find the peer -- we just go over all of them, should
707 be hardly any more expensive than just finding the 'right'
708 one. */
709 for (struct PeerInfo *pos = bucket->head;
710 NULL != pos;
711 pos = pos->next)
712 {
713 if (off > bucket_size)
714 break; /* We only hold up to #bucket_size peers per bucket */
715 bucket_size++;
716 for (struct Target *tp = pos->t_head;
717 NULL != tp;
718 tp = tp->next)
719 if (NULL == tp->ph)
720 tp->ph = GDS_u_hold (tp->u,
721 tp->utarget);
722 }
723}
724
725
689void 726void
690GDS_u_connect (void *cls, 727GDS_u_connect (void *cls,
691 struct GNUNET_DHTU_Target *target, 728 struct GNUNET_DHTU_Target *target,
692 const struct GNUNET_PeerIdentity *pid, 729 const struct GNUNET_PeerIdentity *pid,
693 void **ctx) 730 void **ctx)
694{ 731{
695 struct Underlay *u = cls; 732 struct GDS_Underlay *u = cls;
696 struct PeerInfo *pi; 733 struct PeerInfo *pi;
697 struct PeerBucket *bucket; 734 struct PeerBucket *bucket;
735 bool do_hold = false;
698 736
699 /* Check for connect to self message */ 737 /* Check for connect to self message */
700 if (0 == GNUNET_memcmp (&GDS_my_identity, 738 if (0 == GNUNET_memcmp (&GDS_my_identity,
@@ -734,7 +772,7 @@ GDS_u_connect (void *cls,
734 if (bucket->peers_size <= bucket_size) 772 if (bucket->peers_size <= bucket_size)
735 { 773 {
736 newly_found_peers++; 774 newly_found_peers++;
737 // FIXME: call 'hold'! 775 do_hold = true;
738 } 776 }
739 if ( (1 == GNUNET_CONTAINER_multipeermap_size (all_connected_peers)) && 777 if ( (1 == GNUNET_CONTAINER_multipeermap_size (all_connected_peers)) &&
740 (GNUNET_YES != disable_try_connect) ) 778 (GNUNET_YES != disable_try_connect) )
@@ -758,6 +796,8 @@ GDS_u_connect (void *cls,
758 *ctx = t; 796 *ctx = t;
759 797
760 } 798 }
799 if (do_hold)
800 update_hold (bucket);
761} 801}
762 802
763 803
@@ -767,6 +807,7 @@ GDS_u_disconnect (void *ctx)
767 struct Target *t = ctx; 807 struct Target *t = ctx;
768 struct PeerInfo *pi; 808 struct PeerInfo *pi;
769 struct PeerBucket *bucket; 809 struct PeerBucket *bucket;
810 bool was_held = false;
770 811
771 /* Check for disconnect from self message (on shutdown) */ 812 /* Check for disconnect from self message (on shutdown) */
772 if (NULL == t) 813 if (NULL == t)
@@ -775,6 +816,13 @@ GDS_u_disconnect (void *ctx)
775 GNUNET_CONTAINER_DLL_remove (pi->t_head, 816 GNUNET_CONTAINER_DLL_remove (pi->t_head,
776 pi->t_tail, 817 pi->t_tail,
777 t); 818 t);
819 if (NULL != t->ph)
820 {
821 GDS_u_drop (t->u,
822 t->ph);
823 t->ph = NULL;
824 was_held = true;
825 }
778 if (t->load > 0) 826 if (t->load > 0)
779 { 827 {
780 t->dropped = true; 828 t->dropped = true;
@@ -810,8 +858,9 @@ GDS_u_disconnect (void *ctx)
810 pi); 858 pi);
811 GNUNET_assert (bucket->peers_size > 0); 859 GNUNET_assert (bucket->peers_size > 0);
812 bucket->peers_size--; 860 bucket->peers_size--;
813 // FIXME: check if this peer was in one of the first 'bucket_size' 861 if ( (was_held) &&
814 // peers, and call 'hold' on the next peer if there is any! 862 (bucket->peers_size >= bucket_size - 1) )
863 update_hold (bucket);
815 while ( (closest_bucket > 0) && 864 while ( (closest_bucket > 0) &&
816 (0 == k_buckets[closest_bucket - 1].peers_size)) 865 (0 == k_buckets[closest_bucket - 1].peers_size))
817 closest_bucket--; 866 closest_bucket--;
@@ -2426,7 +2475,7 @@ GDS_u_receive (void *cls,
2426 }; 2475 };
2427 const struct GNUNET_MessageHeader *mh = message; 2476 const struct GNUNET_MessageHeader *mh = message;
2428 2477
2429 (void) cls; /* the 'struct Underlay' */ 2478 (void) cls; /* the 'struct GDS_Underlay' */
2430 (void) sctx; /* our receiver address */ 2479 (void) sctx; /* our receiver address */
2431 if (message_size < sizeof (*mh)) 2480 if (message_size < sizeof (*mh))
2432 { 2481 {
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,
136 * Function to call when we connect to a peer and can henceforth transmit to 136 * Function to call when we connect to a peer and can henceforth transmit to
137 * that peer. 137 * that peer.
138 * 138 *
139 * @param cls the closure, must be a `struct Underlay` 139 * @param cls the closure, must be a `struct GDS_Underlay`
140 * @param target handle to the target, 140 * @param target handle to the target,
141 * pointer will remain valid until @e disconnect_cb is called 141 * pointer will remain valid until @e disconnect_cb is called
142 * @para pid peer identity, 142 * @para pid peer identity,