aboutsummaryrefslogtreecommitdiff
path: root/src/dht/gnunet-service-dht_routing.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/dht/gnunet-service-dht_routing.c')
-rw-r--r--src/dht/gnunet-service-dht_routing.c144
1 files changed, 61 insertions, 83 deletions
diff --git a/src/dht/gnunet-service-dht_routing.c b/src/dht/gnunet-service-dht_routing.c
index 607c756c6..a880bf7cd 100644
--- a/src/dht/gnunet-service-dht_routing.c
+++ b/src/dht/gnunet-service-dht_routing.c
@@ -66,7 +66,7 @@ struct RecentRequest
66 * Type of the requested block. 66 * Type of the requested block.
67 */ 67 */
68 enum GNUNET_BLOCK_Type type; 68 enum GNUNET_BLOCK_Type type;
69 69
70 /** 70 /**
71 * extended query (see gnunet_block_lib.h). Allocated at the 71 * extended query (see gnunet_block_lib.h). Allocated at the
72 * end of this struct. 72 * end of this struct.
@@ -114,7 +114,7 @@ struct ProcessContext
114 114
115 /** 115 /**
116 * Path of the reply. 116 * Path of the reply.
117 */ 117 */
118 const struct GNUNET_PeerIdentity *get_path; 118 const struct GNUNET_PeerIdentity *get_path;
119 119
120 /** 120 /**
@@ -156,13 +156,11 @@ struct ProcessContext
156 * @param cls the 'struct ProcessContext' with the result 156 * @param cls the 'struct ProcessContext' with the result
157 * @param key the query 157 * @param key the query
158 * @param value the 'struct RecentRequest' with the request 158 * @param value the 'struct RecentRequest' with the request
159 * @return GNUNET_OK (continue to iterate), 159 * @return GNUNET_OK (continue to iterate),
160 * GNUNET_SYSERR if the result is malformed or type unsupported 160 * GNUNET_SYSERR if the result is malformed or type unsupported
161 */ 161 */
162static int 162static int
163process (void *cls, 163process (void *cls, const GNUNET_HashCode * key, void *value)
164 const GNUNET_HashCode *key,
165 void *value)
166{ 164{
167 struct ProcessContext *pc = cls; 165 struct ProcessContext *pc = cls;
168 struct RecentRequest *rr = value; 166 struct RecentRequest *rr = value;
@@ -172,9 +170,8 @@ process (void *cls,
172 GNUNET_HashCode hc; 170 GNUNET_HashCode hc;
173 const GNUNET_HashCode *eval_key; 171 const GNUNET_HashCode *eval_key;
174 172
175 if ( (rr->type != GNUNET_BLOCK_TYPE_ANY) && 173 if ((rr->type != GNUNET_BLOCK_TYPE_ANY) && (rr->type != pc->type))
176 (rr->type != pc->type) ) 174 return GNUNET_OK; /* type missmatch */
177 return GNUNET_OK; /* type missmatch */
178 175
179 if (0 != (rr->options & GNUNET_DHT_RO_RECORD_ROUTE)) 176 if (0 != (rr->options & GNUNET_DHT_RO_RECORD_ROUTE))
180 { 177 {
@@ -186,59 +183,48 @@ process (void *cls,
186 gpl = 0; 183 gpl = 0;
187 ppl = 0; 184 ppl = 0;
188 } 185 }
189 if ( (0 != (rr->options & GNUNET_DHT_RO_FIND_PEER)) && 186 if ((0 != (rr->options & GNUNET_DHT_RO_FIND_PEER)) &&
190 (pc->type == GNUNET_BLOCK_TYPE_DHT_HELLO) ) 187 (pc->type == GNUNET_BLOCK_TYPE_DHT_HELLO))
191 { 188 {
192 /* key may not match HELLO, which is OK since 189 /* key may not match HELLO, which is OK since
193 the search is approximate. Still, the evaluation 190 * the search is approximate. Still, the evaluation
194 would fail since the match is not exact. So 191 * would fail since the match is not exact. So
195 we fake it by changing the key to the actual PID ... */ 192 * we fake it by changing the key to the actual PID ... */
196 GNUNET_BLOCK_get_key (GDS_block_context, 193 GNUNET_BLOCK_get_key (GDS_block_context, GNUNET_BLOCK_TYPE_DHT_HELLO,
197 GNUNET_BLOCK_TYPE_DHT_HELLO, 194 pc->data, pc->data_size, &hc);
198 pc->data, pc->data_size,
199 &hc);
200 eval_key = &hc; 195 eval_key = &hc;
201 } 196 }
202 else 197 else
203 { 198 {
204 eval_key = key; 199 eval_key = key;
205 } 200 }
206 eval = GNUNET_BLOCK_evaluate (GDS_block_context, 201 eval =
207 pc->type, 202 GNUNET_BLOCK_evaluate (GDS_block_context, pc->type, eval_key,
208 eval_key, 203 &rr->reply_bf, rr->reply_bf_mutator, rr->xquery,
209 &rr->reply_bf, 204 rr->xquery_size, pc->data, pc->data_size);
210 rr->reply_bf_mutator,
211 rr->xquery,
212 rr->xquery_size,
213 pc->data,
214 pc->data_size);
215 switch (eval) 205 switch (eval)
216 { 206 {
217 case GNUNET_BLOCK_EVALUATION_OK_MORE: 207 case GNUNET_BLOCK_EVALUATION_OK_MORE:
218 case GNUNET_BLOCK_EVALUATION_OK_LAST: 208 case GNUNET_BLOCK_EVALUATION_OK_LAST:
219 GNUNET_STATISTICS_update (GDS_stats, 209 GNUNET_STATISTICS_update (GDS_stats,
220 gettext_noop ("# Good REPLIES matched against routing table"), 1, 210 gettext_noop
221 GNUNET_NO); 211 ("# Good REPLIES matched against routing table"),
222 GDS_NEIGHBOURS_handle_reply (&rr->peer, 212 1, GNUNET_NO);
223 pc->type, 213 GDS_NEIGHBOURS_handle_reply (&rr->peer, pc->type, pc->expiration_time, key,
224 pc->expiration_time, 214 ppl, pc->put_path, gpl, pc->get_path, pc->data,
225 key, 215 pc->data_size);
226 ppl,
227 pc->put_path,
228 gpl,
229 pc->get_path,
230 pc->data,
231 pc->data_size);
232 break; 216 break;
233 case GNUNET_BLOCK_EVALUATION_OK_DUPLICATE: 217 case GNUNET_BLOCK_EVALUATION_OK_DUPLICATE:
234 GNUNET_STATISTICS_update (GDS_stats, 218 GNUNET_STATISTICS_update (GDS_stats,
235 gettext_noop ("# Duplicate REPLIES matched against routing table"), 1, 219 gettext_noop
236 GNUNET_NO); 220 ("# Duplicate REPLIES matched against routing table"),
221 1, GNUNET_NO);
237 return GNUNET_OK; 222 return GNUNET_OK;
238 case GNUNET_BLOCK_EVALUATION_RESULT_INVALID: 223 case GNUNET_BLOCK_EVALUATION_RESULT_INVALID:
239 GNUNET_STATISTICS_update (GDS_stats, 224 GNUNET_STATISTICS_update (GDS_stats,
240 gettext_noop ("# Invalid REPLIES matched against routing table"), 1, 225 gettext_noop
241 GNUNET_NO); 226 ("# Invalid REPLIES matched against routing table"),
227 1, GNUNET_NO);
242 return GNUNET_SYSERR; 228 return GNUNET_SYSERR;
243 case GNUNET_BLOCK_EVALUATION_REQUEST_VALID: 229 case GNUNET_BLOCK_EVALUATION_REQUEST_VALID:
244 case GNUNET_BLOCK_EVALUATION_REQUEST_INVALID: 230 case GNUNET_BLOCK_EVALUATION_REQUEST_INVALID:
@@ -246,12 +232,13 @@ process (void *cls,
246 return GNUNET_OK; 232 return GNUNET_OK;
247 case GNUNET_BLOCK_EVALUATION_TYPE_NOT_SUPPORTED: 233 case GNUNET_BLOCK_EVALUATION_TYPE_NOT_SUPPORTED:
248 GNUNET_STATISTICS_update (GDS_stats, 234 GNUNET_STATISTICS_update (GDS_stats,
249 gettext_noop ("# Unsupported REPLIES matched against routing table"), 1, 235 gettext_noop
250 GNUNET_NO); 236 ("# Unsupported REPLIES matched against routing table"),
237 1, GNUNET_NO);
251 return GNUNET_SYSERR; 238 return GNUNET_SYSERR;
252 default: 239 default:
253 GNUNET_break (0); 240 GNUNET_break (0);
254 return GNUNET_SYSERR; 241 return GNUNET_SYSERR;
255 } 242 }
256 return GNUNET_OK; 243 return GNUNET_OK;
257} 244}
@@ -276,14 +263,12 @@ process (void *cls,
276 */ 263 */
277void 264void
278GDS_ROUTING_process (enum GNUNET_BLOCK_Type type, 265GDS_ROUTING_process (enum GNUNET_BLOCK_Type type,
279 struct GNUNET_TIME_Absolute expiration_time, 266 struct GNUNET_TIME_Absolute expiration_time,
280 const GNUNET_HashCode *key, 267 const GNUNET_HashCode * key, unsigned int put_path_length,
281 unsigned int put_path_length, 268 const struct GNUNET_PeerIdentity *put_path,
282 const struct GNUNET_PeerIdentity *put_path, 269 unsigned int get_path_length,
283 unsigned int get_path_length, 270 const struct GNUNET_PeerIdentity *get_path,
284 const struct GNUNET_PeerIdentity *get_path, 271 const void *data, size_t data_size)
285 const void *data,
286 size_t data_size)
287{ 272{
288 struct ProcessContext pc; 273 struct ProcessContext pc;
289 274
@@ -295,10 +280,7 @@ GDS_ROUTING_process (enum GNUNET_BLOCK_Type type,
295 pc.get_path = get_path; 280 pc.get_path = get_path;
296 pc.data = data; 281 pc.data = data;
297 pc.data_size = data_size; 282 pc.data_size = data_size;
298 GNUNET_CONTAINER_multihashmap_get_multiple (recent_map, 283 GNUNET_CONTAINER_multihashmap_get_multiple (recent_map, key, &process, &pc);
299 key,
300 &process,
301 &pc);
302} 284}
303 285
304 286
@@ -316,21 +298,21 @@ GDS_ROUTING_process (enum GNUNET_BLOCK_Type type,
316*/ 298*/
317void 299void
318GDS_ROUTING_add (const struct GNUNET_PeerIdentity *sender, 300GDS_ROUTING_add (const struct GNUNET_PeerIdentity *sender,
319 enum GNUNET_BLOCK_Type type, 301 enum GNUNET_BLOCK_Type type,
320 enum GNUNET_DHT_RouteOption options, 302 enum GNUNET_DHT_RouteOption options,
321 const GNUNET_HashCode *key, 303 const GNUNET_HashCode * key, const void *xquery,
322 const void *xquery, 304 size_t xquery_size,
323 size_t xquery_size, 305 const struct GNUNET_CONTAINER_BloomFilter *reply_bf,
324 const struct GNUNET_CONTAINER_BloomFilter *reply_bf, 306 uint32_t reply_bf_mutator)
325 uint32_t reply_bf_mutator)
326{ 307{
327 struct RecentRequest *recent_req; 308 struct RecentRequest *recent_req;
328 309
329 while (GNUNET_CONTAINER_heap_get_size (recent_heap) >= DHT_MAX_RECENT) 310 while (GNUNET_CONTAINER_heap_get_size (recent_heap) >= DHT_MAX_RECENT)
330 { 311 {
331 GNUNET_STATISTICS_update (GDS_stats, 312 GNUNET_STATISTICS_update (GDS_stats,
332 gettext_noop ("# Entries removed from routing table"), 1, 313 gettext_noop
333 GNUNET_NO); 314 ("# Entries removed from routing table"), 1,
315 GNUNET_NO);
334 recent_req = GNUNET_CONTAINER_heap_peek (recent_heap); 316 recent_req = GNUNET_CONTAINER_heap_peek (recent_heap);
335 GNUNET_assert (recent_req != NULL); 317 GNUNET_assert (recent_req != NULL);
336 GNUNET_CONTAINER_heap_remove_node (recent_req->heap_node); 318 GNUNET_CONTAINER_heap_remove_node (recent_req->heap_node);
@@ -339,25 +321,22 @@ GDS_ROUTING_add (const struct GNUNET_PeerIdentity *sender,
339 } 321 }
340 322
341 GNUNET_STATISTICS_update (GDS_stats, 323 GNUNET_STATISTICS_update (GDS_stats,
342 gettext_noop ("# Entries added to routing table"), 1, 324 gettext_noop ("# Entries added to routing table"),
343 GNUNET_NO); 325 1, GNUNET_NO);
344 recent_req = GNUNET_malloc (sizeof (struct RecentRequest) + xquery_size); 326 recent_req = GNUNET_malloc (sizeof (struct RecentRequest) + xquery_size);
345 recent_req->peer = *sender; 327 recent_req->peer = *sender;
346 recent_req->key = *key; 328 recent_req->key = *key;
347 recent_req->heap_node = 329 recent_req->heap_node =
348 GNUNET_CONTAINER_heap_insert (recent_heap, recent_req, 330 GNUNET_CONTAINER_heap_insert (recent_heap, recent_req,
349 GNUNET_TIME_absolute_get ().abs_value); 331 GNUNET_TIME_absolute_get ().abs_value);
350 recent_req->reply_bf = 332 recent_req->reply_bf = GNUNET_CONTAINER_bloomfilter_copy (reply_bf);
351 GNUNET_CONTAINER_bloomfilter_copy (reply_bf);
352 recent_req->type = type; 333 recent_req->type = type;
353 recent_req->options = options; 334 recent_req->options = options;
354 recent_req->xquery = &recent_req[1]; 335 recent_req->xquery = &recent_req[1];
355 recent_req->xquery_size = xquery_size; 336 recent_req->xquery_size = xquery_size;
356 recent_req->reply_bf_mutator = reply_bf_mutator; 337 recent_req->reply_bf_mutator = reply_bf_mutator;
357 GNUNET_CONTAINER_multihashmap_put (recent_map, 338 GNUNET_CONTAINER_multihashmap_put (recent_map, key, recent_req,
358 key, 339 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
359 recent_req,
360 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
361 340
362 341
363} 342}
@@ -369,10 +348,8 @@ GDS_ROUTING_add (const struct GNUNET_PeerIdentity *sender,
369void 348void
370GDS_ROUTING_init () 349GDS_ROUTING_init ()
371{ 350{
372 recent_heap = 351 recent_heap = GNUNET_CONTAINER_heap_create (GNUNET_CONTAINER_HEAP_ORDER_MIN);
373 GNUNET_CONTAINER_heap_create (GNUNET_CONTAINER_HEAP_ORDER_MIN); 352 recent_map = GNUNET_CONTAINER_multihashmap_create (DHT_MAX_RECENT * 4 / 3);
374 recent_map =
375 GNUNET_CONTAINER_multihashmap_create (DHT_MAX_RECENT * 4 / 3);
376} 353}
377 354
378 355
@@ -387,8 +364,9 @@ GDS_ROUTING_done ()
387 while (GNUNET_CONTAINER_heap_get_size (recent_heap) > 0) 364 while (GNUNET_CONTAINER_heap_get_size (recent_heap) > 0)
388 { 365 {
389 GNUNET_STATISTICS_update (GDS_stats, 366 GNUNET_STATISTICS_update (GDS_stats,
390 gettext_noop ("# Entries removed from routing table"), 1, 367 gettext_noop
391 GNUNET_NO); 368 ("# Entries removed from routing table"), 1,
369 GNUNET_NO);
392 recent_req = GNUNET_CONTAINER_heap_peek (recent_heap); 370 recent_req = GNUNET_CONTAINER_heap_peek (recent_heap);
393 GNUNET_assert (recent_req != NULL); 371 GNUNET_assert (recent_req != NULL);
394 GNUNET_CONTAINER_heap_remove_node (recent_req->heap_node); 372 GNUNET_CONTAINER_heap_remove_node (recent_req->heap_node);