diff options
Diffstat (limited to 'src/dht/gnunet-service-dht_routing.c')
-rw-r--r-- | src/dht/gnunet-service-dht_routing.c | 200 |
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 | */ |
101 | struct ProcessContext | 102 | struct 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 | */ |
153 | static enum GNUNET_GenericReturnValue | 130 | static enum GNUNET_GenericReturnValue |
154 | process (void *cls, | 131 | process (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 | */ |
277 | void | 230 | void |
278 | GDS_ROUTING_process (enum GNUNET_BLOCK_Type type, | 231 | GDS_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 | } |