aboutsummaryrefslogtreecommitdiff
path: root/src/dht/gnunet-service-dht_routing.c
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2022-01-02 20:24:02 +0100
committerChristian Grothoff <christian@grothoff.org>2022-01-02 20:24:02 +0100
commite3ff017054eb35dedd95ae4fe66c82b88e3bbdc3 (patch)
treeabb821d63f09d0982d6f6802ec1c55234dcc0f5c /src/dht/gnunet-service-dht_routing.c
parent329f0458fa1fce45ce1c31e86771ffefb22e941e (diff)
downloadgnunet-e3ff017054eb35dedd95ae4fe66c82b88e3bbdc3.tar.gz
gnunet-e3ff017054eb35dedd95ae4fe66c82b88e3bbdc3.zip
-non-trivial refactoring/cleanup of the DHT code
Diffstat (limited to 'src/dht/gnunet-service-dht_routing.c')
-rw-r--r--src/dht/gnunet-service-dht_routing.c200
1 files changed, 74 insertions, 126 deletions
diff --git a/src/dht/gnunet-service-dht_routing.c b/src/dht/gnunet-service-dht_routing.c
index ef3aded77..8ba0c70ad 100644
--- a/src/dht/gnunet-service-dht_routing.c
+++ b/src/dht/gnunet-service-dht_routing.c
@@ -1,6 +1,6 @@
1/* 1/*
2 This file is part of GNUnet. 2 This file is part of GNUnet.
3 Copyright (C) 2011 GNUnet e.V. 3 Copyright (C) 2011, 2022 GNUnet e.V.
4 4
5 GNUnet is free software: you can redistribute it and/or modify it 5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published 6 under the terms of the GNU Affero General Public License as published
@@ -31,8 +31,9 @@
31 31
32/** 32/**
33 * Number of requests we track at most (for routing replies). 33 * Number of requests we track at most (for routing replies).
34 * TODO: make configurable!
34 */ 35 */
35#define DHT_MAX_RECENT (1024 * 16) 36#define DHT_MAX_RECENT (1024 * 128)
36 37
37 38
38/** 39/**
@@ -96,14 +97,14 @@ static struct GNUNET_CONTAINER_MultiHashMap *recent_map;
96 97
97 98
98/** 99/**
99 * Closure for the 'process' function. 100 * Closure for the process() function.
100 */ 101 */
101struct ProcessContext 102struct ProcessContext
102{ 103{
103 /** 104 /**
104 * Path of the original PUT 105 * Block data.
105 */ 106 */
106 const struct GNUNET_PeerIdentity *put_path; 107 const struct GDS_DATACACHE_BlockData *bd;
107 108
108 /** 109 /**
109 * Path of the reply. 110 * Path of the reply.
@@ -111,34 +112,10 @@ struct ProcessContext
111 const struct GNUNET_PeerIdentity *get_path; 112 const struct GNUNET_PeerIdentity *get_path;
112 113
113 /** 114 /**
114 * Payload of the reply.
115 */
116 const void *data;
117
118 /**
119 * Expiration time of the result.
120 */
121 struct GNUNET_TIME_Absolute expiration_time;
122
123 /**
124 * Number of entries in @e put_path.
125 */
126 unsigned int put_path_length;
127
128 /**
129 * Number of entries in @e get_path. 115 * Number of entries in @e get_path.
130 */ 116 */
131 unsigned int get_path_length; 117 unsigned int get_path_length;
132 118
133 /**
134 * Number of bytes in @e data.
135 */
136 size_t data_size;
137
138 /**
139 * Type of the reply.
140 */
141 enum GNUNET_BLOCK_Type type;
142}; 119};
143 120
144 121
@@ -146,71 +123,56 @@ struct ProcessContext
146 * Forward the result to the given peer if it matches the request. 123 * Forward the result to the given peer if it matches the request.
147 * 124 *
148 * @param cls the `struct ProcessContext` with the result 125 * @param cls the `struct ProcessContext` with the result
149 * @param key the query 126 * @param query_hash the hash from the original query
150 * @param value the `struct RecentRequest` with the request 127 * @param value the `struct RecentRequest` with the request
151 * @return #GNUNET_OK (continue to iterate) 128 * @return #GNUNET_OK (continue to iterate)
152 */ 129 */
153static enum GNUNET_GenericReturnValue 130static enum GNUNET_GenericReturnValue
154process (void *cls, 131process (void *cls,
155 const struct GNUNET_HashCode *key, 132 const struct GNUNET_HashCode *query_hash,
156 void *value) 133 void *value)
157{ 134{
158 struct ProcessContext *pc = cls; 135 struct ProcessContext *pc = cls;
159 struct RecentRequest *rr = value; 136 struct RecentRequest *rr = value;
160 enum GNUNET_BLOCK_ReplyEvaluationResult eval; 137 enum GNUNET_BLOCK_ReplyEvaluationResult eval;
161 unsigned int gpl; 138 unsigned int get_path_length;
162 unsigned int ppl; 139 struct GDS_DATACACHE_BlockData bdx = *pc->bd;
163 struct GNUNET_HashCode hc;
164 const struct GNUNET_HashCode *eval_key;
165 140
166 if ((rr->type != GNUNET_BLOCK_TYPE_ANY) && 141 if ( (rr->type != GNUNET_BLOCK_TYPE_ANY) &&
167 (rr->type != pc->type)) 142 (rr->type != pc->bd->type) )
168 return GNUNET_OK; /* type mismatch */ 143 return GNUNET_OK; /* type mismatch */
169
170 if (0 != (rr->options & GNUNET_DHT_RO_RECORD_ROUTE)) 144 if (0 != (rr->options & GNUNET_DHT_RO_RECORD_ROUTE))
171 { 145 {
172 gpl = pc->get_path_length; 146 get_path_length = pc->get_path_length;
173 ppl = pc->put_path_length;
174 } 147 }
175 else 148 else
176 { 149 {
177 gpl = 0; 150 get_path_length = 0;
178 ppl = 0; 151 bdx.put_path_length = 0;
152 bdx.put_path = NULL;
179 } 153 }
180 /* FIXME-SCHANZEN: should we modify FIND_PEER to 154 if ( (0 == (rr->options & GNUNET_DHT_RO_FIND_PEER)) &&
181 be a generic approximate search and not check 155 (0 != GNUNET_memcmp (query_hash,
182 for the DHT_HELLO type here? */ 156 &bdx.key)) )
183 if ( (0 != (rr->options & GNUNET_DHT_RO_FIND_PEER)) &&
184 (pc->type == GNUNET_BLOCK_TYPE_DHT_HELLO) )
185 { 157 {
186 /* key may not match HELLO, which is OK since 158 GNUNET_STATISTICS_update (GDS_stats,
187 * the search is approximate. Still, the evaluation 159 "# Inexact matches discarded in exact search",
188 * would fail since the match is not exact. So 160 1,
189 * we fake it by changing the key to the actual PID ... */ 161 GNUNET_NO);
190 GNUNET_BLOCK_get_key (GDS_block_context, 162 return GNUNET_OK; /* exact search, but inexact match */
191 GNUNET_BLOCK_TYPE_DHT_HELLO,
192 pc->data,
193 pc->data_size,
194 &hc);
195 eval_key = &hc;
196 }
197 else
198 {
199 eval_key = key;
200 } 163 }
201 eval 164 eval = GNUNET_BLOCK_check_reply (GDS_block_context,
202 = GNUNET_BLOCK_check_reply (GDS_block_context, 165 bdx.type,
203 pc->type, 166 rr->bg,
204 rr->bg, 167 &bdx.key,
205 eval_key, 168 rr->xquery,
206 rr->xquery, 169 rr->xquery_size,
207 rr->xquery_size, 170 bdx.data,
208 pc->data, 171 bdx.data_size);
209 pc->data_size);
210 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 172 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
211 "Result for %s of type %d was evaluated as %d\n", 173 "Result for %s of type %d was evaluated as %d\n",
212 GNUNET_h2s (key), 174 GNUNET_h2s (&bdx.key),
213 pc->type, 175 bdx.type,
214 eval); 176 eval);
215 switch (eval) 177 switch (eval)
216 { 178 {
@@ -222,13 +184,9 @@ process (void *cls,
222 1, 184 1,
223 GNUNET_NO); 185 GNUNET_NO);
224 GDS_NEIGHBOURS_handle_reply (&rr->peer, 186 GDS_NEIGHBOURS_handle_reply (&rr->peer,
225 pc->type, 187 &bdx,
226 pc->expiration_time, 188 query_hash,
227 key, 189 get_path_length, pc->get_path);
228 ppl, pc->put_path,
229 gpl, pc->get_path,
230 pc->data,
231 pc->data_size);
232 break; 190 break;
233 case GNUNET_BLOCK_REPLY_OK_DUPLICATE: 191 case GNUNET_BLOCK_REPLY_OK_DUPLICATE:
234 GNUNET_STATISTICS_update (GDS_stats, 192 GNUNET_STATISTICS_update (GDS_stats,
@@ -264,39 +222,25 @@ process (void *cls,
264 * GDS_NEIGHBOURS_handle_reply() for all peers that sent us a matching 222 * GDS_NEIGHBOURS_handle_reply() for all peers that sent us a matching
265 * request recently. 223 * request recently.
266 * 224 *
267 * @param type type of the block 225 * @param bd block details
268 * @param expiration_time when does the content expire 226 * @param query_hash query used in the inquiry
269 * @param key key for the content
270 * @param put_path_length number of entries in @a put_path
271 * @param put_path peers the original PUT traversed (if tracked)
272 * @param get_path_length number of entries in @a get_path 227 * @param get_path_length number of entries in @a get_path
273 * @param get_path peers this reply has traversed so far (if tracked) 228 * @param get_path peers this reply has traversed so far (if tracked)
274 * @param data payload of the reply
275 * @param data_size number of bytes in data
276 */ 229 */
277void 230void
278GDS_ROUTING_process (enum GNUNET_BLOCK_Type type, 231GDS_ROUTING_process (const struct GDS_DATACACHE_BlockData *bd,
279 struct GNUNET_TIME_Absolute expiration_time, 232 const struct GNUNET_HashCode *query_hash,
280 const struct GNUNET_HashCode *key,
281 unsigned int put_path_length,
282 const struct GNUNET_PeerIdentity *put_path,
283 unsigned int get_path_length, 233 unsigned int get_path_length,
284 const struct GNUNET_PeerIdentity *get_path, 234 const struct GNUNET_PeerIdentity *get_path)
285 const void *data,
286 size_t data_size)
287{ 235{
288 struct ProcessContext pc; 236 struct ProcessContext pc = {
289 237 .bd = bd,
290 pc.type = type; 238 .get_path = get_path,
291 pc.expiration_time = expiration_time; 239 .get_path_length = get_path_length
292 pc.put_path_length = put_path_length; 240 };
293 pc.put_path = put_path; 241
294 pc.get_path_length = get_path_length;
295 pc.get_path = get_path;
296 pc.data = data;
297 pc.data_size = data_size;
298 GNUNET_CONTAINER_multihashmap_get_multiple (recent_map, 242 GNUNET_CONTAINER_multihashmap_get_multiple (recent_map,
299 key, 243 query_hash,
300 &process, 244 &process,
301 &pc); 245 &pc);
302} 246}
@@ -313,7 +257,7 @@ expire_oldest_entry (void)
313 struct RecentRequest *recent_req; 257 struct RecentRequest *recent_req;
314 258
315 GNUNET_STATISTICS_update (GDS_stats, 259 GNUNET_STATISTICS_update (GDS_stats,
316 "# Entries removed from routing table", 260 "# Old entries removed from routing table",
317 1, 261 1,
318 GNUNET_NO); 262 GNUNET_NO);
319 recent_req = GNUNET_CONTAINER_heap_peek (recent_heap); 263 recent_req = GNUNET_CONTAINER_heap_peek (recent_heap);
@@ -334,7 +278,7 @@ expire_oldest_entry (void)
334 * 278 *
335 * @param cls the new `struct RecentRequest` (to discard upon successful combination) 279 * @param cls the new `struct RecentRequest` (to discard upon successful combination)
336 * @param key the query 280 * @param key the query
337 * @param value the existing 'struct RecentRequest' (to update upon successful combination) 281 * @param value the existing `struct RecentRequest` (to update upon successful combination)
338 * @return #GNUNET_OK (continue to iterate), 282 * @return #GNUNET_OK (continue to iterate),
339 * #GNUNET_SYSERR if the request was successfully combined 283 * #GNUNET_SYSERR if the request was successfully combined
340 */ 284 */
@@ -346,13 +290,13 @@ try_combine_recent (void *cls,
346 struct RecentRequest *in = cls; 290 struct RecentRequest *in = cls;
347 struct RecentRequest *rr = value; 291 struct RecentRequest *rr = value;
348 292
349 if ((0 != GNUNET_memcmp (&in->peer, 293 if ( (0 != GNUNET_memcmp (&in->peer,
350 &rr->peer)) || 294 &rr->peer)) ||
351 (in->type != rr->type) || 295 (in->type != rr->type) ||
352 (in->xquery_size != rr->xquery_size) || 296 (in->xquery_size != rr->xquery_size) ||
353 (0 != memcmp (in->xquery, 297 (0 != memcmp (in->xquery,
354 rr->xquery, 298 rr->xquery,
355 in->xquery_size))) 299 in->xquery_size) ) )
356 return GNUNET_OK; 300 return GNUNET_OK;
357 GNUNET_break (GNUNET_SYSERR != 301 GNUNET_break (GNUNET_SYSERR !=
358 GNUNET_BLOCK_group_merge (in->bg, 302 GNUNET_BLOCK_group_merge (in->bg,
@@ -410,19 +354,21 @@ GDS_ROUTING_add (const struct GNUNET_PeerIdentity *sender,
410 recent_req)) 354 recent_req))
411 { 355 {
412 GNUNET_STATISTICS_update (GDS_stats, 356 GNUNET_STATISTICS_update (GDS_stats,
413 gettext_noop 357 "# DHT requests combined",
414 ("# DHT requests combined"), 358 1,
415 1, GNUNET_NO); 359 GNUNET_NO);
416 return; 360 return;
417 } 361 }
418 recent_req->heap_node 362 recent_req->heap_node
419 = GNUNET_CONTAINER_heap_insert (recent_heap, 363 = GNUNET_CONTAINER_heap_insert (
420 recent_req, 364 recent_heap,
421 GNUNET_TIME_absolute_get ().abs_value_us); 365 recent_req,
422 GNUNET_CONTAINER_multihashmap_put (recent_map, 366 GNUNET_TIME_absolute_get ().abs_value_us);
423 key, 367 (void) GNUNET_CONTAINER_multihashmap_put (
424 recent_req, 368 recent_map,
425 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); 369 key,
370 recent_req,
371 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
426} 372}
427 373
428 374
@@ -446,10 +392,12 @@ GDS_ROUTING_done ()
446{ 392{
447 while (GNUNET_CONTAINER_heap_get_size (recent_heap) > 0) 393 while (GNUNET_CONTAINER_heap_get_size (recent_heap) > 0)
448 expire_oldest_entry (); 394 expire_oldest_entry ();
449 GNUNET_assert (0 == GNUNET_CONTAINER_heap_get_size (recent_heap)); 395 GNUNET_assert (0 ==
396 GNUNET_CONTAINER_heap_get_size (recent_heap));
450 GNUNET_CONTAINER_heap_destroy (recent_heap); 397 GNUNET_CONTAINER_heap_destroy (recent_heap);
451 recent_heap = NULL; 398 recent_heap = NULL;
452 GNUNET_assert (0 == GNUNET_CONTAINER_multihashmap_size (recent_map)); 399 GNUNET_assert (0 ==
400 GNUNET_CONTAINER_multihashmap_size (recent_map));
453 GNUNET_CONTAINER_multihashmap_destroy (recent_map); 401 GNUNET_CONTAINER_multihashmap_destroy (recent_map);
454 recent_map = NULL; 402 recent_map = NULL;
455} 403}