aboutsummaryrefslogtreecommitdiff
path: root/src/dht/dht_api.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/dht/dht_api.c')
-rw-r--r--src/dht/dht_api.c534
1 files changed, 252 insertions, 282 deletions
diff --git a/src/dht/dht_api.c b/src/dht/dht_api.c
index 11f13b184..101751487 100644
--- a/src/dht/dht_api.c
+++ b/src/dht/dht_api.c
@@ -60,12 +60,12 @@ struct PendingMessage
60 * of this struct. 60 * of this struct.
61 */ 61 */
62 const struct GNUNET_MessageHeader *msg; 62 const struct GNUNET_MessageHeader *msg;
63 63
64 /** 64 /**
65 * Handle to the DHT API context. 65 * Handle to the DHT API context.
66 */ 66 */
67 struct GNUNET_DHT_Handle *handle; 67 struct GNUNET_DHT_Handle *handle;
68 68
69 /** 69 /**
70 * Continuation to call when the request has been 70 * Continuation to call when the request has been
71 * transmitted (for the first time) to the service; can be NULL. 71 * transmitted (for the first time) to the service; can be NULL.
@@ -203,10 +203,7 @@ struct GNUNET_DHT_Handle
203/** 203/**
204 * Transmit the next pending message, called by notify_transmit_ready 204 * Transmit the next pending message, called by notify_transmit_ready
205 */ 205 */
206static size_t 206static size_t transmit_pending (void *cls, size_t size, void *buf);
207transmit_pending (void *cls,
208 size_t size,
209 void *buf);
210 207
211 208
212/** 209/**
@@ -215,8 +212,7 @@ transmit_pending (void *cls,
215 * 212 *
216 */ 213 */
217static void 214static void
218service_message_handler (void *cls, 215service_message_handler (void *cls, const struct GNUNET_MessageHeader *msg);
219 const struct GNUNET_MessageHeader *msg);
220 216
221 217
222 218
@@ -233,19 +229,18 @@ try_connect (struct GNUNET_DHT_Handle *handle)
233 return GNUNET_OK; 229 return GNUNET_OK;
234 handle->client = GNUNET_CLIENT_connect ("dht", handle->cfg); 230 handle->client = GNUNET_CLIENT_connect ("dht", handle->cfg);
235 if (handle->client == NULL) 231 if (handle->client == NULL)
236 { 232 {
237 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, 233 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
238 _("Failed to connect to the DHT service!\n")); 234 _("Failed to connect to the DHT service!\n"));
239 return GNUNET_NO; 235 return GNUNET_NO;
240 } 236 }
241#if DEBUG_DHT 237#if DEBUG_DHT
242 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 238 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
243 "Starting to process replies from DHT\n"); 239 "Starting to process replies from DHT\n");
244#endif 240#endif
245 GNUNET_CLIENT_receive (handle->client, 241 GNUNET_CLIENT_receive (handle->client,
246 &service_message_handler, 242 &service_message_handler,
247 handle, 243 handle, GNUNET_TIME_UNIT_FOREVER_REL);
248 GNUNET_TIME_UNIT_FOREVER_REL);
249 return GNUNET_YES; 244 return GNUNET_YES;
250} 245}
251 246
@@ -260,20 +255,17 @@ try_connect (struct GNUNET_DHT_Handle *handle)
260 * @return GNUNET_YES (always) 255 * @return GNUNET_YES (always)
261 */ 256 */
262static int 257static int
263add_request_to_pending (void *cls, 258add_request_to_pending (void *cls, const GNUNET_HashCode * key, void *value)
264 const GNUNET_HashCode *key,
265 void *value)
266{ 259{
267 struct GNUNET_DHT_Handle *handle = cls; 260 struct GNUNET_DHT_Handle *handle = cls;
268 struct GNUNET_DHT_RouteHandle *rh = value; 261 struct GNUNET_DHT_RouteHandle *rh = value;
269 262
270 if (GNUNET_NO == rh->message->in_pending_queue) 263 if (GNUNET_NO == rh->message->in_pending_queue)
271 { 264 {
272 GNUNET_CONTAINER_DLL_insert (handle->pending_head, 265 GNUNET_CONTAINER_DLL_insert (handle->pending_head,
273 handle->pending_tail, 266 handle->pending_tail, rh->message);
274 rh->message); 267 rh->message->in_pending_queue = GNUNET_YES;
275 rh->message->in_pending_queue = GNUNET_YES; 268 }
276 }
277 return GNUNET_YES; 269 return GNUNET_YES;
278} 270}
279 271
@@ -282,8 +274,7 @@ add_request_to_pending (void *cls,
282 * Try to send messages from list of messages to send 274 * Try to send messages from list of messages to send
283 * @param handle DHT_Handle 275 * @param handle DHT_Handle
284 */ 276 */
285static void 277static void process_pending_messages (struct GNUNET_DHT_Handle *handle);
286process_pending_messages (struct GNUNET_DHT_Handle *handle);
287 278
288 279
289/** 280/**
@@ -293,8 +284,7 @@ process_pending_messages (struct GNUNET_DHT_Handle *handle);
293 * @param tc scheduler context 284 * @param tc scheduler context
294 */ 285 */
295static void 286static void
296try_reconnect (void *cls, 287try_reconnect (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
297 const struct GNUNET_SCHEDULER_TaskContext *tc)
298{ 288{
299 struct GNUNET_DHT_Handle *handle = cls; 289 struct GNUNET_DHT_Handle *handle = cls;
300 290
@@ -308,14 +298,12 @@ try_reconnect (void *cls,
308 handle->reconnect_task = GNUNET_SCHEDULER_NO_TASK; 298 handle->reconnect_task = GNUNET_SCHEDULER_NO_TASK;
309 handle->client = GNUNET_CLIENT_connect ("dht", handle->cfg); 299 handle->client = GNUNET_CLIENT_connect ("dht", handle->cfg);
310 if (handle->client == NULL) 300 if (handle->client == NULL)
311 { 301 {
312 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 302 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "dht reconnect failed(!)\n");
313 "dht reconnect failed(!)\n"); 303 return;
314 return; 304 }
315 }
316 GNUNET_CONTAINER_multihashmap_iterate (handle->active_requests, 305 GNUNET_CONTAINER_multihashmap_iterate (handle->active_requests,
317 &add_request_to_pending, 306 &add_request_to_pending, handle);
318 handle);
319 process_pending_messages (handle); 307 process_pending_messages (handle);
320} 308}
321 309
@@ -330,7 +318,7 @@ do_disconnect (struct GNUNET_DHT_Handle *handle)
330{ 318{
331 if (handle->client == NULL) 319 if (handle->client == NULL)
332 return; 320 return;
333 GNUNET_assert(handle->reconnect_task == GNUNET_SCHEDULER_NO_TASK); 321 GNUNET_assert (handle->reconnect_task == GNUNET_SCHEDULER_NO_TASK);
334 GNUNET_CLIENT_disconnect (handle->client, GNUNET_NO); 322 GNUNET_CLIENT_disconnect (handle->client, GNUNET_NO);
335 handle->client = NULL; 323 handle->client = NULL;
336 handle->reconnect_task = GNUNET_SCHEDULER_add_delayed (handle->retry_time, 324 handle->reconnect_task = GNUNET_SCHEDULER_add_delayed (handle->retry_time,
@@ -348,25 +336,24 @@ process_pending_messages (struct GNUNET_DHT_Handle *handle)
348 struct PendingMessage *head; 336 struct PendingMessage *head;
349 337
350 if (handle->client == NULL) 338 if (handle->client == NULL)
351 { 339 {
352 do_disconnect(handle); 340 do_disconnect (handle);
353 return; 341 return;
354 } 342 }
355 if (handle->th != NULL) 343 if (handle->th != NULL)
356 return; 344 return;
357 if (NULL == (head = handle->pending_head)) 345 if (NULL == (head = handle->pending_head))
358 return; 346 return;
359 handle->th = GNUNET_CLIENT_notify_transmit_ready (handle->client, 347 handle->th = GNUNET_CLIENT_notify_transmit_ready (handle->client,
360 ntohs (head->msg->size), 348 ntohs (head->msg->size),
361 GNUNET_TIME_UNIT_FOREVER_REL, 349 GNUNET_TIME_UNIT_FOREVER_REL,
362 GNUNET_YES, 350 GNUNET_YES,
363 &transmit_pending, 351 &transmit_pending, handle);
364 handle); 352 if (NULL == handle->th)
365 if (NULL == handle->th) 353 {
366 { 354 do_disconnect (handle);
367 do_disconnect (handle); 355 return;
368 return; 356 }
369 }
370} 357}
371 358
372 359
@@ -374,9 +361,7 @@ process_pending_messages (struct GNUNET_DHT_Handle *handle)
374 * Transmit the next pending message, called by notify_transmit_ready 361 * Transmit the next pending message, called by notify_transmit_ready
375 */ 362 */
376static size_t 363static size_t
377transmit_pending (void *cls, 364transmit_pending (void *cls, size_t size, void *buf)
378 size_t size,
379 void *buf)
380{ 365{
381 struct GNUNET_DHT_Handle *handle = cls; 366 struct GNUNET_DHT_Handle *handle = cls;
382 struct PendingMessage *head; 367 struct PendingMessage *head;
@@ -384,44 +369,44 @@ transmit_pending (void *cls,
384 369
385 handle->th = NULL; 370 handle->th = NULL;
386 if (buf == NULL) 371 if (buf == NULL)
387 { 372 {
388 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Transmission to DHT service failed! Reconnecting!\n"); 373 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
389 do_disconnect (handle); 374 "Transmission to DHT service failed! Reconnecting!\n");
390 return 0; 375 do_disconnect (handle);
391 } 376 return 0;
377 }
392 if (NULL == (head = handle->pending_head)) 378 if (NULL == (head = handle->pending_head))
393 return 0; 379 return 0;
394 380
395 tsize = ntohs (head->msg->size); 381 tsize = ntohs (head->msg->size);
396 if (size < tsize) 382 if (size < tsize)
397 { 383 {
398 process_pending_messages (handle); 384 process_pending_messages (handle);
399 return 0; 385 return 0;
400 } 386 }
401 memcpy (buf, head->msg, tsize); 387 memcpy (buf, head->msg, tsize);
402 GNUNET_CONTAINER_DLL_remove (handle->pending_head, 388 GNUNET_CONTAINER_DLL_remove (handle->pending_head,
403 handle->pending_tail, 389 handle->pending_tail, head);
404 head);
405 if (head->timeout_task != GNUNET_SCHEDULER_NO_TASK) 390 if (head->timeout_task != GNUNET_SCHEDULER_NO_TASK)
406 { 391 {
407 GNUNET_SCHEDULER_cancel (head->timeout_task); 392 GNUNET_SCHEDULER_cancel (head->timeout_task);
408 head->timeout_task = GNUNET_SCHEDULER_NO_TASK; 393 head->timeout_task = GNUNET_SCHEDULER_NO_TASK;
409 } 394 }
410 if (NULL != head->cont) 395 if (NULL != head->cont)
411 { 396 {
412 GNUNET_SCHEDULER_add_continuation (head->cont, 397 GNUNET_SCHEDULER_add_continuation (head->cont,
413 head->cont_cls, 398 head->cont_cls,
414 GNUNET_SCHEDULER_REASON_PREREQ_DONE); 399 GNUNET_SCHEDULER_REASON_PREREQ_DONE);
415 head->cont = NULL; 400 head->cont = NULL;
416 head->cont_cls = NULL; 401 head->cont_cls = NULL;
417 } 402 }
418 head->in_pending_queue = GNUNET_NO; 403 head->in_pending_queue = GNUNET_NO;
419 if (GNUNET_YES == head->free_on_send) 404 if (GNUNET_YES == head->free_on_send)
420 GNUNET_free (head); 405 GNUNET_free (head);
421 process_pending_messages (handle); 406 process_pending_messages (handle);
422 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 407 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
423 "Forwarded request of %u bytes to DHT service\n", 408 "Forwarded request of %u bytes to DHT service\n",
424 (unsigned int) tsize); 409 (unsigned int) tsize);
425 return tsize; 410 return tsize;
426} 411}
427 412
@@ -431,9 +416,7 @@ transmit_pending (void *cls,
431 * request. 416 * request.
432 */ 417 */
433static int 418static int
434process_reply (void *cls, 419process_reply (void *cls, const GNUNET_HashCode * key, void *value)
435 const GNUNET_HashCode *key,
436 void *value)
437{ 420{
438 const struct GNUNET_DHT_RouteResultMessage *dht_msg = cls; 421 const struct GNUNET_DHT_RouteResultMessage *dht_msg = cls;
439 struct GNUNET_DHT_RouteHandle *rh = value; 422 struct GNUNET_DHT_RouteHandle *rh = value;
@@ -448,47 +431,46 @@ process_reply (void *cls,
448 431
449 uid = GNUNET_ntohll (dht_msg->unique_id); 432 uid = GNUNET_ntohll (dht_msg->unique_id);
450 if (uid != rh->uid) 433 if (uid != rh->uid)
451 { 434 {
452 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 435 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
453 "Reply UID did not match request UID\n"); 436 "Reply UID did not match request UID\n");
454 return GNUNET_YES; 437 return GNUNET_YES;
455 } 438 }
456 enc_msg = (const struct GNUNET_MessageHeader *)&dht_msg[1]; 439 enc_msg = (const struct GNUNET_MessageHeader *) &dht_msg[1];
457 enc_size = ntohs (enc_msg->size); 440 enc_size = ntohs (enc_msg->size);
458 if (enc_size < sizeof (struct GNUNET_MessageHeader)) 441 if (enc_size < sizeof (struct GNUNET_MessageHeader))
459 { 442 {
460 GNUNET_break (0); 443 GNUNET_break (0);
461 return GNUNET_NO; 444 return GNUNET_NO;
462 } 445 }
463 path_offset = (char *)&dht_msg[1]; 446 path_offset = (char *) &dht_msg[1];
464 path_offset += enc_size; 447 path_offset += enc_size;
465 pos = (const struct GNUNET_PeerIdentity *) path_offset; 448 pos = (const struct GNUNET_PeerIdentity *) path_offset;
466 outgoing_path_length = ntohl (dht_msg->outgoing_path_length); 449 outgoing_path_length = ntohl (dht_msg->outgoing_path_length);
467 if (outgoing_path_length * sizeof (struct GNUNET_PeerIdentity) > ntohs(dht_msg->header.size) - enc_size) 450 if (outgoing_path_length * sizeof (struct GNUNET_PeerIdentity) >
468 { 451 ntohs (dht_msg->header.size) - enc_size)
469 GNUNET_break (0); 452 {
470 return GNUNET_NO; 453 GNUNET_break (0);
471 } 454 return GNUNET_NO;
455 }
472 456
473 if (outgoing_path_length > 0) 457 if (outgoing_path_length > 0)
458 {
459 outgoing_path =
460 GNUNET_malloc ((outgoing_path_length +
461 1) * sizeof (struct GNUNET_PeerIdentity *));
462 for (i = 0; i < outgoing_path_length; i++)
474 { 463 {
475 outgoing_path = GNUNET_malloc ((outgoing_path_length + 1) * sizeof (struct GNUNET_PeerIdentity*)); 464 outgoing_path[i] = pos;
476 for (i = 0; i < outgoing_path_length; i++) 465 pos++;
477 {
478 outgoing_path[i] = pos;
479 pos++;
480 }
481 outgoing_path[outgoing_path_length] = NULL;
482 } 466 }
467 outgoing_path[outgoing_path_length] = NULL;
468 }
483 else 469 else
484 outgoing_path = NULL; 470 outgoing_path = NULL;
485 471
486 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 472 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Processing reply.\n");
487 "Processing reply.\n"); 473 rh->iter (rh->iter_cls, &rh->key, outgoing_path, enc_msg);
488 rh->iter (rh->iter_cls,
489 &rh->key,
490 outgoing_path,
491 enc_msg);
492 GNUNET_free_non_null (outgoing_path); 474 GNUNET_free_non_null (outgoing_path);
493 return GNUNET_YES; 475 return GNUNET_YES;
494} 476}
@@ -502,42 +484,40 @@ process_reply (void *cls,
502 * @param msg the incoming message 484 * @param msg the incoming message
503 */ 485 */
504static void 486static void
505service_message_handler (void *cls, 487service_message_handler (void *cls, const struct GNUNET_MessageHeader *msg)
506 const struct GNUNET_MessageHeader *msg)
507{ 488{
508 struct GNUNET_DHT_Handle *handle = cls; 489 struct GNUNET_DHT_Handle *handle = cls;
509 const struct GNUNET_DHT_RouteResultMessage *dht_msg; 490 const struct GNUNET_DHT_RouteResultMessage *dht_msg;
510 491
511 if (msg == NULL) 492 if (msg == NULL)
512 { 493 {
513 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 494 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
514 "Error receiving data from DHT service, reconnecting\n"); 495 "Error receiving data from DHT service, reconnecting\n");
515 do_disconnect (handle); 496 do_disconnect (handle);
516 return; 497 return;
517 } 498 }
518 if (ntohs (msg->type) != GNUNET_MESSAGE_TYPE_DHT_LOCAL_ROUTE_RESULT) 499 if (ntohs (msg->type) != GNUNET_MESSAGE_TYPE_DHT_LOCAL_ROUTE_RESULT)
519 { 500 {
520 GNUNET_break (0); 501 GNUNET_break (0);
521 do_disconnect (handle); 502 do_disconnect (handle);
522 return; 503 return;
523 } 504 }
524 if (ntohs (msg->size) < sizeof (struct GNUNET_DHT_RouteResultMessage)) 505 if (ntohs (msg->size) < sizeof (struct GNUNET_DHT_RouteResultMessage))
525 { 506 {
526 GNUNET_break (0); 507 GNUNET_break (0);
527 do_disconnect (handle); 508 do_disconnect (handle);
528 return; 509 return;
529 } 510 }
530 dht_msg = (const struct GNUNET_DHT_RouteResultMessage *) msg; 511 dht_msg = (const struct GNUNET_DHT_RouteResultMessage *) msg;
531 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 512 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
532 "Comparing reply `%s' against %u pending requests.\n", 513 "Comparing reply `%s' against %u pending requests.\n",
533 GNUNET_h2s (&dht_msg->key), 514 GNUNET_h2s (&dht_msg->key),
534 GNUNET_CONTAINER_multihashmap_size (handle->active_requests)); 515 GNUNET_CONTAINER_multihashmap_size (handle->active_requests));
535 GNUNET_CONTAINER_multihashmap_get_multiple (handle->active_requests, 516 GNUNET_CONTAINER_multihashmap_get_multiple (handle->active_requests,
536 &dht_msg->key, 517 &dht_msg->key,
537 &process_reply, 518 &process_reply, (void *) dht_msg);
538 (void*) dht_msg);
539 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 519 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
540 "Continuing to process replies from DHT\n"); 520 "Continuing to process replies from DHT\n");
541 GNUNET_CLIENT_receive (handle->client, 521 GNUNET_CLIENT_receive (handle->client,
542 &service_message_handler, 522 &service_message_handler,
543 handle, GNUNET_TIME_UNIT_FOREVER_REL); 523 handle, GNUNET_TIME_UNIT_FOREVER_REL);
@@ -562,13 +542,14 @@ GNUNET_DHT_connect (const struct GNUNET_CONFIGURATION_Handle *cfg,
562 542
563 handle = GNUNET_malloc (sizeof (struct GNUNET_DHT_Handle)); 543 handle = GNUNET_malloc (sizeof (struct GNUNET_DHT_Handle));
564 handle->cfg = cfg; 544 handle->cfg = cfg;
565 handle->uid_gen = GNUNET_CRYPTO_random_u64(GNUNET_CRYPTO_QUALITY_WEAK, UINT64_MAX); 545 handle->uid_gen =
546 GNUNET_CRYPTO_random_u64 (GNUNET_CRYPTO_QUALITY_WEAK, UINT64_MAX);
566 handle->active_requests = GNUNET_CONTAINER_multihashmap_create (ht_len); 547 handle->active_requests = GNUNET_CONTAINER_multihashmap_create (ht_len);
567 if (GNUNET_NO == try_connect (handle)) 548 if (GNUNET_NO == try_connect (handle))
568 { 549 {
569 GNUNET_DHT_disconnect (handle); 550 GNUNET_DHT_disconnect (handle);
570 return NULL; 551 return NULL;
571 } 552 }
572 return handle; 553 return handle;
573} 554}
574 555
@@ -582,36 +563,37 @@ void
582GNUNET_DHT_disconnect (struct GNUNET_DHT_Handle *handle) 563GNUNET_DHT_disconnect (struct GNUNET_DHT_Handle *handle)
583{ 564{
584 struct PendingMessage *pm; 565 struct PendingMessage *pm;
585 GNUNET_assert(handle != NULL); 566
586 GNUNET_assert (0 == GNUNET_CONTAINER_multihashmap_size(handle->active_requests)); 567 GNUNET_assert (handle != NULL);
568 GNUNET_assert (0 ==
569 GNUNET_CONTAINER_multihashmap_size (handle->active_requests));
587 if (handle->th != NULL) 570 if (handle->th != NULL)
588 { 571 {
589 GNUNET_CLIENT_notify_transmit_ready_cancel (handle->th); 572 GNUNET_CLIENT_notify_transmit_ready_cancel (handle->th);
590 handle->th = NULL; 573 handle->th = NULL;
591 } 574 }
592 while (NULL != (pm = handle->pending_head)) 575 while (NULL != (pm = handle->pending_head))
593 { 576 {
594 GNUNET_CONTAINER_DLL_remove (handle->pending_head, 577 GNUNET_CONTAINER_DLL_remove (handle->pending_head,
595 handle->pending_tail, 578 handle->pending_tail, pm);
596 pm); 579 GNUNET_assert (GNUNET_YES == pm->free_on_send);
597 GNUNET_assert (GNUNET_YES == pm->free_on_send); 580 if (GNUNET_SCHEDULER_NO_TASK != pm->timeout_task)
598 if (GNUNET_SCHEDULER_NO_TASK != pm->timeout_task) 581 GNUNET_SCHEDULER_cancel (pm->timeout_task);
599 GNUNET_SCHEDULER_cancel (pm->timeout_task); 582 if (NULL != pm->cont)
600 if (NULL != pm->cont) 583 GNUNET_SCHEDULER_add_continuation (pm->cont,
601 GNUNET_SCHEDULER_add_continuation (pm->cont, 584 pm->cont_cls,
602 pm->cont_cls, 585 GNUNET_SCHEDULER_REASON_TIMEOUT);
603 GNUNET_SCHEDULER_REASON_TIMEOUT); 586 pm->in_pending_queue = GNUNET_NO;
604 pm->in_pending_queue = GNUNET_NO; 587 GNUNET_free (pm);
605 GNUNET_free (pm); 588 }
606 }
607 if (handle->client != NULL) 589 if (handle->client != NULL)
608 { 590 {
609 GNUNET_CLIENT_disconnect (handle->client, GNUNET_YES); 591 GNUNET_CLIENT_disconnect (handle->client, GNUNET_YES);
610 handle->client = NULL; 592 handle->client = NULL;
611 } 593 }
612 if (handle->reconnect_task != GNUNET_SCHEDULER_NO_TASK) 594 if (handle->reconnect_task != GNUNET_SCHEDULER_NO_TASK)
613 GNUNET_SCHEDULER_cancel(handle->reconnect_task); 595 GNUNET_SCHEDULER_cancel (handle->reconnect_task);
614 GNUNET_CONTAINER_multihashmap_destroy(handle->active_requests); 596 GNUNET_CONTAINER_multihashmap_destroy (handle->active_requests);
615 GNUNET_free (handle); 597 GNUNET_free (handle);
616} 598}
617 599
@@ -628,25 +610,22 @@ GNUNET_DHT_disconnect (struct GNUNET_DHT_Handle *handle)
628 * @param tc scheduler context 610 * @param tc scheduler context
629 */ 611 */
630static void 612static void
631timeout_route_request (void *cls, 613timeout_route_request (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
632 const struct GNUNET_SCHEDULER_TaskContext *tc)
633{ 614{
634 struct PendingMessage *pending = cls; 615 struct PendingMessage *pending = cls;
635 struct GNUNET_DHT_Handle *handle; 616 struct GNUNET_DHT_Handle *handle;
636 617
637 if (pending->free_on_send != GNUNET_YES) 618 if (pending->free_on_send != GNUNET_YES)
638 { 619 {
639 /* timeouts should only apply to fire & forget requests! */ 620 /* timeouts should only apply to fire & forget requests! */
640 GNUNET_break (0); 621 GNUNET_break (0);
641 return; 622 return;
642 } 623 }
643 handle = pending->handle; 624 handle = pending->handle;
644 GNUNET_CONTAINER_DLL_remove (handle->pending_head, 625 GNUNET_CONTAINER_DLL_remove (handle->pending_head,
645 handle->pending_tail, 626 handle->pending_tail, pending);
646 pending);
647 if (pending->cont != NULL) 627 if (pending->cont != NULL)
648 pending->cont (pending->cont_cls, 628 pending->cont (pending->cont_cls, tc);
649 tc);
650 GNUNET_free (pending); 629 GNUNET_free (pending);
651} 630}
652 631
@@ -674,15 +653,14 @@ timeout_route_request (void *cls,
674 */ 653 */
675struct GNUNET_DHT_RouteHandle * 654struct GNUNET_DHT_RouteHandle *
676GNUNET_DHT_route_start (struct GNUNET_DHT_Handle *handle, 655GNUNET_DHT_route_start (struct GNUNET_DHT_Handle *handle,
677 const GNUNET_HashCode *key, 656 const GNUNET_HashCode * key,
678 uint32_t desired_replication_level, 657 uint32_t desired_replication_level,
679 enum GNUNET_DHT_RouteOption options, 658 enum GNUNET_DHT_RouteOption options,
680 const struct GNUNET_MessageHeader *enc, 659 const struct GNUNET_MessageHeader *enc,
681 struct GNUNET_TIME_Relative timeout, 660 struct GNUNET_TIME_Relative timeout,
682 GNUNET_DHT_ReplyProcessor iter, 661 GNUNET_DHT_ReplyProcessor iter,
683 void *iter_cls, 662 void *iter_cls,
684 GNUNET_SCHEDULER_Task cont, 663 GNUNET_SCHEDULER_Task cont, void *cont_cls)
685 void *cont_cls)
686{ 664{
687 struct PendingMessage *pending; 665 struct PendingMessage *pending;
688 struct GNUNET_DHT_RouteMessage *message; 666 struct GNUNET_DHT_RouteMessage *message;
@@ -691,19 +669,20 @@ GNUNET_DHT_route_start (struct GNUNET_DHT_Handle *handle,
691 uint16_t esize; 669 uint16_t esize;
692 670
693 esize = ntohs (enc->size); 671 esize = ntohs (enc->size);
694 if (sizeof (struct GNUNET_DHT_RouteMessage) + esize >= GNUNET_SERVER_MAX_MESSAGE_SIZE) 672 if (sizeof (struct GNUNET_DHT_RouteMessage) + esize >=
695 { 673 GNUNET_SERVER_MAX_MESSAGE_SIZE)
696 GNUNET_break (0); 674 {
697 return NULL; 675 GNUNET_break (0);
698 } 676 return NULL;
677 }
699 msize = sizeof (struct GNUNET_DHT_RouteMessage) + esize; 678 msize = sizeof (struct GNUNET_DHT_RouteMessage) + esize;
700 pending = GNUNET_malloc (sizeof (struct PendingMessage) + msize); 679 pending = GNUNET_malloc (sizeof (struct PendingMessage) + msize);
701 message = (struct GNUNET_DHT_RouteMessage*) &pending[1]; 680 message = (struct GNUNET_DHT_RouteMessage *) &pending[1];
702 pending->msg = &message->header; 681 pending->msg = &message->header;
703 pending->handle = handle; 682 pending->handle = handle;
704 pending->cont = cont; 683 pending->cont = cont;
705 pending->cont_cls = cont_cls; 684 pending->cont_cls = cont_cls;
706 685
707 message->header.size = htons (msize); 686 message->header.size = htons (msize);
708 message->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_LOCAL_ROUTE); 687 message->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_LOCAL_ROUTE);
709 message->options = htonl ((uint32_t) options); 688 message->options = htonl ((uint32_t) options);
@@ -715,35 +694,34 @@ GNUNET_DHT_route_start (struct GNUNET_DHT_Handle *handle,
715 memcpy (&message[1], enc, esize); 694 memcpy (&message[1], enc, esize);
716 695
717 if (iter != NULL) 696 if (iter != NULL)
718 { 697 {
719 route_handle = GNUNET_malloc (sizeof (struct GNUNET_DHT_RouteHandle)); 698 route_handle = GNUNET_malloc (sizeof (struct GNUNET_DHT_RouteHandle));
720 route_handle->key = *key; 699 route_handle->key = *key;
721 route_handle->iter = iter; 700 route_handle->iter = iter;
722 route_handle->iter_cls = iter_cls; 701 route_handle->iter_cls = iter_cls;
723 route_handle->dht_handle = handle; 702 route_handle->dht_handle = handle;
724 route_handle->uid = handle->uid_gen; 703 route_handle->uid = handle->uid_gen;
725 route_handle->message = pending; 704 route_handle->message = pending;
726 GNUNET_CONTAINER_multihashmap_put (handle->active_requests, 705 GNUNET_CONTAINER_multihashmap_put (handle->active_requests,
727 key, 706 key,
728 route_handle, 707 route_handle,
729 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); 708 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
730 } 709 }
731 else 710 else
732 { 711 {
733 route_handle = NULL; 712 route_handle = NULL;
734 pending->free_on_send = GNUNET_YES; 713 pending->free_on_send = GNUNET_YES;
735 pending->timeout_task = GNUNET_SCHEDULER_add_delayed (timeout, 714 pending->timeout_task = GNUNET_SCHEDULER_add_delayed (timeout,
736 &timeout_route_request, 715 &timeout_route_request,
737 pending); 716 pending);
738 } 717 }
739 GNUNET_CONTAINER_DLL_insert (handle->pending_head, 718 GNUNET_CONTAINER_DLL_insert (handle->pending_head,
740 handle->pending_tail, 719 handle->pending_tail, pending);
741 pending);
742 pending->in_pending_queue = GNUNET_YES; 720 pending->in_pending_queue = GNUNET_YES;
743 process_pending_messages (handle); 721 process_pending_messages (handle);
744 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 722 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
745 "DHT route start request processed, returning %p\n", 723 "DHT route start request processed, returning %p\n",
746 route_handle); 724 route_handle);
747 return route_handle; 725 return route_handle;
748} 726}
749 727
@@ -763,42 +741,38 @@ GNUNET_DHT_route_stop (struct GNUNET_DHT_RouteHandle *route_handle)
763 741
764 handle = route_handle->dht_handle; 742 handle = route_handle->dht_handle;
765 if (GNUNET_NO == route_handle->message->in_pending_queue) 743 if (GNUNET_NO == route_handle->message->in_pending_queue)
766 { 744 {
767 /* need to send stop message */ 745 /* need to send stop message */
768 msize = sizeof (struct GNUNET_DHT_StopMessage); 746 msize = sizeof (struct GNUNET_DHT_StopMessage);
769 pending = GNUNET_malloc (sizeof (struct PendingMessage) + 747 pending = GNUNET_malloc (sizeof (struct PendingMessage) + msize);
770 msize); 748 message = (struct GNUNET_DHT_StopMessage *) &pending[1];
771 message = (struct GNUNET_DHT_StopMessage*) &pending[1]; 749 pending->msg = &message->header;
772 pending->msg = &message->header; 750 message->header.size = htons (msize);
773 message->header.size = htons (msize); 751 message->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_LOCAL_ROUTE_STOP);
774 message->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_LOCAL_ROUTE_STOP); 752 message->reserved = 0;
775 message->reserved = 0; 753 message->unique_id = GNUNET_htonll (route_handle->uid);
776 message->unique_id = GNUNET_htonll (route_handle->uid); 754 message->key = route_handle->key;
777 message->key = route_handle->key; 755 pending->handle = handle;
778 pending->handle = handle; 756 pending->free_on_send = GNUNET_YES;
779 pending->free_on_send = GNUNET_YES; 757 pending->in_pending_queue = GNUNET_YES;
780 pending->in_pending_queue = GNUNET_YES; 758 GNUNET_CONTAINER_DLL_insert (handle->pending_head,
781 GNUNET_CONTAINER_DLL_insert (handle->pending_head, 759 handle->pending_tail, pending);
782 handle->pending_tail, 760 process_pending_messages (handle);
783 pending); 761 }
784 process_pending_messages (handle);
785 }
786 else 762 else
787 { 763 {
788 /* simply remove pending request from message queue before 764 /* simply remove pending request from message queue before
789 transmission, no need to transmit STOP request! */ 765 * transmission, no need to transmit STOP request! */
790 GNUNET_CONTAINER_DLL_remove (handle->pending_head, 766 GNUNET_CONTAINER_DLL_remove (handle->pending_head,
791 handle->pending_tail, 767 handle->pending_tail, route_handle->message);
792 route_handle->message); 768 }
793 }
794 GNUNET_assert (GNUNET_YES == 769 GNUNET_assert (GNUNET_YES ==
795 GNUNET_CONTAINER_multihashmap_remove (route_handle->dht_handle->active_requests, 770 GNUNET_CONTAINER_multihashmap_remove
796 &route_handle->key, 771 (route_handle->dht_handle->active_requests, &route_handle->key,
797 route_handle)); 772 route_handle));
798 GNUNET_free(route_handle->message); 773 GNUNET_free (route_handle->message);
799 GNUNET_free(route_handle); 774 GNUNET_free (route_handle);
800 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 775 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "DHT route stop request processed\n");
801 "DHT route stop request processed\n");
802} 776}
803 777
804 778
@@ -817,29 +791,27 @@ GNUNET_DHT_route_stop (struct GNUNET_DHT_RouteHandle *route_handle)
817 */ 791 */
818static void 792static void
819send_control_message (struct GNUNET_DHT_Handle *handle, 793send_control_message (struct GNUNET_DHT_Handle *handle,
820 uint16_t command, 794 uint16_t command,
821 uint16_t variable, 795 uint16_t variable,
822 GNUNET_SCHEDULER_Task cont, 796 GNUNET_SCHEDULER_Task cont, void *cont_cls)
823 void *cont_cls)
824{ 797{
825 struct GNUNET_DHT_ControlMessage *msg; 798 struct GNUNET_DHT_ControlMessage *msg;
826 struct PendingMessage *pending; 799 struct PendingMessage *pending;
827 800
828 pending = GNUNET_malloc (sizeof (struct PendingMessage) + 801 pending = GNUNET_malloc (sizeof (struct PendingMessage) +
829 sizeof(struct GNUNET_DHT_ControlMessage)); 802 sizeof (struct GNUNET_DHT_ControlMessage));
830 msg = (struct GNUNET_DHT_ControlMessage*) &pending[1]; 803 msg = (struct GNUNET_DHT_ControlMessage *) &pending[1];
831 pending->msg = &msg->header; 804 pending->msg = &msg->header;
832 msg->header.size = htons (sizeof(struct GNUNET_DHT_ControlMessage)); 805 msg->header.size = htons (sizeof (struct GNUNET_DHT_ControlMessage));
833 msg->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_CONTROL); 806 msg->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_CONTROL);
834 msg->command = htons (command); 807 msg->command = htons (command);
835 msg->variable = htons (variable); 808 msg->variable = htons (variable);
836 pending->free_on_send = GNUNET_YES; 809 pending->free_on_send = GNUNET_YES;
837 pending->cont = cont; 810 pending->cont = cont;
838 pending->cont_cls = cont_cls; 811 pending->cont_cls = cont_cls;
839 pending->in_pending_queue = GNUNET_YES; 812 pending->in_pending_queue = GNUNET_YES;
840 GNUNET_CONTAINER_DLL_insert (handle->pending_head, 813 GNUNET_CONTAINER_DLL_insert (handle->pending_head,
841 handle->pending_tail, 814 handle->pending_tail, pending);
842 pending);
843 process_pending_messages (handle); 815 process_pending_messages (handle);
844} 816}
845 817
@@ -857,12 +829,10 @@ send_control_message (struct GNUNET_DHT_Handle *handle,
857 */ 829 */
858void 830void
859GNUNET_DHT_find_peers (struct GNUNET_DHT_Handle *handle, 831GNUNET_DHT_find_peers (struct GNUNET_DHT_Handle *handle,
860 GNUNET_SCHEDULER_Task cont, 832 GNUNET_SCHEDULER_Task cont, void *cont_cls)
861 void *cont_cls)
862{ 833{
863 send_control_message (handle, 834 send_control_message (handle,
864 GNUNET_MESSAGE_TYPE_DHT_FIND_PEER, 0, 835 GNUNET_MESSAGE_TYPE_DHT_FIND_PEER, 0, cont, cont_cls);
865 cont, cont_cls);
866} 836}
867 837
868 838
@@ -880,17 +850,17 @@ GNUNET_DHT_find_peers (struct GNUNET_DHT_Handle *handle,
880 */ 850 */
881void 851void
882GNUNET_DHT_set_malicious_getter (struct GNUNET_DHT_Handle *handle, 852GNUNET_DHT_set_malicious_getter (struct GNUNET_DHT_Handle *handle,
883 struct GNUNET_TIME_Relative frequency, GNUNET_SCHEDULER_Task cont, 853 struct GNUNET_TIME_Relative frequency,
884 void *cont_cls) 854 GNUNET_SCHEDULER_Task cont, void *cont_cls)
885{ 855{
886 if (frequency.rel_value > UINT16_MAX) 856 if (frequency.rel_value > UINT16_MAX)
887 { 857 {
888 GNUNET_break (0); 858 GNUNET_break (0);
889 return; 859 return;
890 } 860 }
891 send_control_message (handle, 861 send_control_message (handle,
892 GNUNET_MESSAGE_TYPE_DHT_MALICIOUS_GET, frequency.rel_value, 862 GNUNET_MESSAGE_TYPE_DHT_MALICIOUS_GET,
893 cont, cont_cls); 863 frequency.rel_value, cont, cont_cls);
894} 864}
895 865
896/** 866/**
@@ -902,20 +872,20 @@ GNUNET_DHT_set_malicious_getter (struct GNUNET_DHT_Handle *handle,
902 * @param cont continuation to call when done (transmitting request to service) 872 * @param cont continuation to call when done (transmitting request to service)
903 * @param cont_cls closure for cont 873 * @param cont_cls closure for cont
904 */ 874 */
905void 875void
906GNUNET_DHT_set_malicious_putter (struct GNUNET_DHT_Handle *handle, 876GNUNET_DHT_set_malicious_putter (struct GNUNET_DHT_Handle *handle,
907 struct GNUNET_TIME_Relative frequency, GNUNET_SCHEDULER_Task cont, 877 struct GNUNET_TIME_Relative frequency,
908 void *cont_cls) 878 GNUNET_SCHEDULER_Task cont, void *cont_cls)
909{ 879{
910 if (frequency.rel_value > UINT16_MAX) 880 if (frequency.rel_value > UINT16_MAX)
911 { 881 {
912 GNUNET_break (0); 882 GNUNET_break (0);
913 return; 883 return;
914 } 884 }
915 885
916 send_control_message (handle, 886 send_control_message (handle,
917 GNUNET_MESSAGE_TYPE_DHT_MALICIOUS_PUT, frequency.rel_value, 887 GNUNET_MESSAGE_TYPE_DHT_MALICIOUS_PUT,
918 cont, cont_cls); 888 frequency.rel_value, cont, cont_cls);
919} 889}
920 890
921 891
@@ -928,9 +898,9 @@ GNUNET_DHT_set_malicious_putter (struct GNUNET_DHT_Handle *handle,
928 * @param cont_cls closure for cont 898 * @param cont_cls closure for cont
929 * 899 *
930 */ 900 */
931void 901void
932GNUNET_DHT_set_malicious_dropper (struct GNUNET_DHT_Handle *handle, GNUNET_SCHEDULER_Task cont, 902GNUNET_DHT_set_malicious_dropper (struct GNUNET_DHT_Handle *handle,
933 void *cont_cls) 903 GNUNET_SCHEDULER_Task cont, void *cont_cls)
934{ 904{
935 send_control_message (handle, 905 send_control_message (handle,
936 GNUNET_MESSAGE_TYPE_DHT_MALICIOUS_DROP, 0, 906 GNUNET_MESSAGE_TYPE_DHT_MALICIOUS_DROP, 0,