aboutsummaryrefslogtreecommitdiff
path: root/src/core/core_api.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/core_api.c')
-rw-r--r--src/core/core_api.c1640
1 files changed, 769 insertions, 871 deletions
diff --git a/src/core/core_api.c b/src/core/core_api.c
index 7f7928fd3..c6fcc0b47 100644
--- a/src/core/core_api.c
+++ b/src/core/core_api.c
@@ -116,7 +116,7 @@ struct PeerRecord
116 * SendMessageRequest ID generator for this peer. 116 * SendMessageRequest ID generator for this peer.
117 */ 117 */
118 uint16_t smr_id_gen; 118 uint16_t smr_id_gen;
119 119
120}; 120};
121 121
122 122
@@ -143,7 +143,7 @@ struct ControlMessage
143 * Function to run after transmission failed/succeeded. 143 * Function to run after transmission failed/succeeded.
144 */ 144 */
145 GNUNET_CORE_ControlContinuation cont; 145 GNUNET_CORE_ControlContinuation cont;
146 146
147 /** 147 /**
148 * Closure for 'cont'. 148 * Closure for 'cont'.
149 */ 149 */
@@ -190,9 +190,9 @@ struct GNUNET_CORE_Handle
190 190
191 /** 191 /**
192 * Function to call whenever we're notified about a peer changing status. 192 * Function to call whenever we're notified about a peer changing status.
193 */ 193 */
194 GNUNET_CORE_PeerStatusEventHandler status_events; 194 GNUNET_CORE_PeerStatusEventHandler status_events;
195 195
196 /** 196 /**
197 * Function to call whenever we receive an inbound message. 197 * Function to call whenever we receive an inbound message.
198 */ 198 */
@@ -371,8 +371,7 @@ struct GNUNET_CORE_TransmitHandle
371 * 371 *
372 * @param h our handle to the core service 372 * @param h our handle to the core service
373 */ 373 */
374static void 374static void reconnect (struct GNUNET_CORE_Handle *h);
375reconnect (struct GNUNET_CORE_Handle *h);
376 375
377 376
378/** 377/**
@@ -382,15 +381,14 @@ reconnect (struct GNUNET_CORE_Handle *h);
382 * @param tc task context 381 * @param tc task context
383 */ 382 */
384static void 383static void
385reconnect_task (void *cls, 384reconnect_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
386 const struct GNUNET_SCHEDULER_TaskContext *tc)
387{ 385{
388 struct GNUNET_CORE_Handle *h = cls; 386 struct GNUNET_CORE_Handle *h = cls;
389 387
390 h->reconnect_task = GNUNET_SCHEDULER_NO_TASK; 388 h->reconnect_task = GNUNET_SCHEDULER_NO_TASK;
391#if DEBUG_CORE 389#if DEBUG_CORE
392 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 390 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
393 "Connecting to CORE service after delay\n"); 391 "Connecting to CORE service after delay\n");
394#endif 392#endif
395 reconnect (h); 393 reconnect (h);
396} 394}
@@ -407,8 +405,7 @@ reconnect_task (void *cls,
407 */ 405 */
408static int 406static int
409disconnect_and_free_peer_entry (void *cls, 407disconnect_and_free_peer_entry (void *cls,
410 const GNUNET_HashCode *key, 408 const GNUNET_HashCode * key, void *value)
411 void *value)
412{ 409{
413 static struct GNUNET_BANDWIDTH_Value32NBO zero; 410 static struct GNUNET_BANDWIDTH_Value32NBO zero;
414 struct GNUNET_CORE_Handle *h = cls; 411 struct GNUNET_CORE_Handle *h = cls;
@@ -418,61 +415,47 @@ disconnect_and_free_peer_entry (void *cls,
418 void *pcic_cls; 415 void *pcic_cls;
419 416
420 if (pr->timeout_task != GNUNET_SCHEDULER_NO_TASK) 417 if (pr->timeout_task != GNUNET_SCHEDULER_NO_TASK)
421 { 418 {
422 GNUNET_SCHEDULER_cancel (pr->timeout_task); 419 GNUNET_SCHEDULER_cancel (pr->timeout_task);
423 pr->timeout_task = GNUNET_SCHEDULER_NO_TASK; 420 pr->timeout_task = GNUNET_SCHEDULER_NO_TASK;
424 } 421 }
425 if (pr->ntr_task != GNUNET_SCHEDULER_NO_TASK) 422 if (pr->ntr_task != GNUNET_SCHEDULER_NO_TASK)
426 { 423 {
427 GNUNET_SCHEDULER_cancel (pr->ntr_task); 424 GNUNET_SCHEDULER_cancel (pr->ntr_task);
428 pr->ntr_task = GNUNET_SCHEDULER_NO_TASK; 425 pr->ntr_task = GNUNET_SCHEDULER_NO_TASK;
429 } 426 }
430 if ( (pr->prev != NULL) || 427 if ((pr->prev != NULL) || (pr->next != NULL) || (h->ready_peer_head == pr))
431 (pr->next != NULL) || 428 GNUNET_CONTAINER_DLL_remove (h->ready_peer_head, h->ready_peer_tail, pr);
432 (h->ready_peer_head == pr) )
433 GNUNET_CONTAINER_DLL_remove (h->ready_peer_head,
434 h->ready_peer_tail,
435 pr);
436 if (h->disconnects != NULL) 429 if (h->disconnects != NULL)
437 h->disconnects (h->cls, 430 h->disconnects (h->cls, &pr->peer);
438 &pr->peer);
439 /* all requests should have been cancelled, clean up anyway, just in case */ 431 /* all requests should have been cancelled, clean up anyway, just in case */
440 GNUNET_break (pr->queue_size == 0); 432 GNUNET_break (pr->queue_size == 0);
441 if (NULL != (pcic = pr->pcic)) 433 if (NULL != (pcic = pr->pcic))
442 { 434 {
443 GNUNET_break (0); 435 GNUNET_break (0);
444 pcic_cls = pr->pcic_cls; 436 pcic_cls = pr->pcic_cls;
445 GNUNET_CORE_peer_change_preference_cancel (pr->pcic_ptr); 437 GNUNET_CORE_peer_change_preference_cancel (pr->pcic_ptr);
446 pcic (pcic_cls, 438 pcic (pcic_cls, &pr->peer, zero, 0, GNUNET_TIME_UNIT_FOREVER_REL, 0);
447 &pr->peer, 439 }
448 zero,
449 0,
450 GNUNET_TIME_UNIT_FOREVER_REL,
451 0);
452 }
453 while (NULL != (th = pr->pending_head)) 440 while (NULL != (th = pr->pending_head))
454 { 441 {
455 GNUNET_break (0); 442 GNUNET_break (0);
456 GNUNET_CONTAINER_DLL_remove (pr->pending_head, 443 GNUNET_CONTAINER_DLL_remove (pr->pending_head, pr->pending_tail, th);
457 pr->pending_tail, 444 pr->queue_size--;
458 th); 445 if (th->cm != NULL)
459 pr->queue_size--; 446 th->cm->th = NULL;
460 if (th->cm != NULL) 447 GNUNET_free (th);
461 th->cm->th = NULL; 448 }
462 GNUNET_free (th);
463 }
464 /* done with 'voluntary' cleanups, now on to normal freeing */ 449 /* done with 'voluntary' cleanups, now on to normal freeing */
465 GNUNET_assert (GNUNET_YES == 450 GNUNET_assert (GNUNET_YES ==
466 GNUNET_CONTAINER_multihashmap_remove (h->peers, 451 GNUNET_CONTAINER_multihashmap_remove (h->peers, key, pr));
467 key,
468 pr));
469 GNUNET_assert (pr->pending_head == NULL); 452 GNUNET_assert (pr->pending_head == NULL);
470 GNUNET_assert (pr->pending_tail == NULL); 453 GNUNET_assert (pr->pending_tail == NULL);
471 GNUNET_assert (pr->ch = h); 454 GNUNET_assert (pr->ch = h);
472 GNUNET_assert (pr->queue_size == 0); 455 GNUNET_assert (pr->queue_size == 0);
473 GNUNET_assert (pr->timeout_task == GNUNET_SCHEDULER_NO_TASK); 456 GNUNET_assert (pr->timeout_task == GNUNET_SCHEDULER_NO_TASK);
474 GNUNET_assert (pr->ntr_task == GNUNET_SCHEDULER_NO_TASK); 457 GNUNET_assert (pr->ntr_task == GNUNET_SCHEDULER_NO_TASK);
475 GNUNET_free (pr); 458 GNUNET_free (pr);
476 return GNUNET_YES; 459 return GNUNET_YES;
477} 460}
478 461
@@ -491,41 +474,36 @@ reconnect_later (struct GNUNET_CORE_Handle *h)
491 474
492 GNUNET_assert (h->reconnect_task == GNUNET_SCHEDULER_NO_TASK); 475 GNUNET_assert (h->reconnect_task == GNUNET_SCHEDULER_NO_TASK);
493 if (NULL != h->cth) 476 if (NULL != h->cth)
494 { 477 {
495 GNUNET_CLIENT_notify_transmit_ready_cancel (h->cth); 478 GNUNET_CLIENT_notify_transmit_ready_cancel (h->cth);
496 h->cth = NULL; 479 h->cth = NULL;
497 } 480 }
498 if (h->client != NULL) 481 if (h->client != NULL)
499 { 482 {
500 GNUNET_CLIENT_disconnect (h->client, GNUNET_NO); 483 GNUNET_CLIENT_disconnect (h->client, GNUNET_NO);
501 h->client = NULL; 484 h->client = NULL;
502 } 485 }
503 h->currently_down = GNUNET_YES; 486 h->currently_down = GNUNET_YES;
504 GNUNET_assert (h->reconnect_task == GNUNET_SCHEDULER_NO_TASK); 487 GNUNET_assert (h->reconnect_task == GNUNET_SCHEDULER_NO_TASK);
505 h->reconnect_task = GNUNET_SCHEDULER_add_delayed (h->retry_backoff, 488 h->reconnect_task = GNUNET_SCHEDULER_add_delayed (h->retry_backoff,
506 &reconnect_task, 489 &reconnect_task, h);
507 h);
508 while (NULL != (cm = h->control_pending_head)) 490 while (NULL != (cm = h->control_pending_head))
509 { 491 {
510 GNUNET_CONTAINER_DLL_remove (h->control_pending_head, 492 GNUNET_CONTAINER_DLL_remove (h->control_pending_head,
511 h->control_pending_tail, 493 h->control_pending_tail, cm);
512 cm); 494 if (cm->th != NULL)
513 if (cm->th != NULL) 495 cm->th->cm = NULL;
514 cm->th->cm = NULL; 496 if (cm->cont != NULL)
515 if (cm->cont != NULL) 497 cm->cont (cm->cont_cls, GNUNET_NO);
516 cm->cont (cm->cont_cls, GNUNET_NO); 498 GNUNET_free (cm);
517 GNUNET_free (cm); 499 }
518 }
519 GNUNET_CONTAINER_multihashmap_iterate (h->peers, 500 GNUNET_CONTAINER_multihashmap_iterate (h->peers,
520 &disconnect_and_free_peer_entry, 501 &disconnect_and_free_peer_entry, h);
521 h); 502 while (NULL != (pr = h->ready_peer_head))
522 while (NULL != (pr = h->ready_peer_head)) 503 GNUNET_CONTAINER_DLL_remove (h->ready_peer_head, h->ready_peer_tail, pr);
523 GNUNET_CONTAINER_DLL_remove (h->ready_peer_head,
524 h->ready_peer_tail,
525 pr);
526 GNUNET_assert (h->control_pending_head == NULL); 504 GNUNET_assert (h->control_pending_head == NULL);
527 h->retry_backoff = GNUNET_TIME_relative_min (GNUNET_TIME_UNIT_SECONDS, 505 h->retry_backoff = GNUNET_TIME_relative_min (GNUNET_TIME_UNIT_SECONDS,
528 h->retry_backoff); 506 h->retry_backoff);
529 h->retry_backoff = GNUNET_TIME_relative_multiply (h->retry_backoff, 2); 507 h->retry_backoff = GNUNET_TIME_relative_multiply (h->retry_backoff, 2);
530} 508}
531 509
@@ -538,8 +516,7 @@ reconnect_later (struct GNUNET_CORE_Handle *h)
538 * @param ignore_currently_down transmit message even if not initialized? 516 * @param ignore_currently_down transmit message even if not initialized?
539 */ 517 */
540static void 518static void
541trigger_next_request (struct GNUNET_CORE_Handle *h, 519trigger_next_request (struct GNUNET_CORE_Handle *h, int ignore_currently_down);
542 int ignore_currently_down);
543 520
544 521
545/** 522/**
@@ -550,8 +527,7 @@ trigger_next_request (struct GNUNET_CORE_Handle *h,
550 * @param tc context, can be NULL (!) 527 * @param tc context, can be NULL (!)
551 */ 528 */
552static void 529static void
553transmission_timeout (void *cls, 530transmission_timeout (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc);
554 const struct GNUNET_SCHEDULER_TaskContext *tc);
555 531
556 532
557/** 533/**
@@ -569,27 +545,27 @@ request_next_transmission (struct PeerRecord *pr)
569 struct GNUNET_CORE_TransmitHandle *th; 545 struct GNUNET_CORE_TransmitHandle *th;
570 546
571 if (pr->timeout_task != GNUNET_SCHEDULER_NO_TASK) 547 if (pr->timeout_task != GNUNET_SCHEDULER_NO_TASK)
572 { 548 {
573 GNUNET_SCHEDULER_cancel (pr->timeout_task); 549 GNUNET_SCHEDULER_cancel (pr->timeout_task);
574 pr->timeout_task = GNUNET_SCHEDULER_NO_TASK; 550 pr->timeout_task = GNUNET_SCHEDULER_NO_TASK;
575 } 551 }
576 if (NULL == (th = pr->pending_head)) 552 if (NULL == (th = pr->pending_head))
577 { 553 {
578 trigger_next_request (h, GNUNET_NO); 554 trigger_next_request (h, GNUNET_NO);
579 return; 555 return;
580 } 556 }
581 if (th->cm != NULL) 557 if (th->cm != NULL)
582 return; /* already done */ 558 return; /* already done */
583 GNUNET_assert (pr->prev == NULL); 559 GNUNET_assert (pr->prev == NULL);
584 GNUNET_assert (pr->next == NULL); 560 GNUNET_assert (pr->next == NULL);
585 pr->timeout_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_absolute_get_remaining (th->timeout), 561 pr->timeout_task =
586 &transmission_timeout, 562 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_absolute_get_remaining
587 pr); 563 (th->timeout), &transmission_timeout, pr);
588 cm = GNUNET_malloc (sizeof (struct ControlMessage) + 564 cm = GNUNET_malloc (sizeof (struct ControlMessage) +
589 sizeof (struct SendMessageRequest)); 565 sizeof (struct SendMessageRequest));
590 th->cm = cm; 566 th->cm = cm;
591 cm->th = th; 567 cm->th = th;
592 smr = (struct SendMessageRequest*) &cm[1]; 568 smr = (struct SendMessageRequest *) &cm[1];
593 smr->header.type = htons (GNUNET_MESSAGE_TYPE_CORE_SEND_REQUEST); 569 smr->header.type = htons (GNUNET_MESSAGE_TYPE_CORE_SEND_REQUEST);
594 smr->header.size = htons (sizeof (struct SendMessageRequest)); 570 smr->header.size = htons (sizeof (struct SendMessageRequest));
595 smr->priority = htonl (th->priority); 571 smr->priority = htonl (th->priority);
@@ -599,12 +575,11 @@ request_next_transmission (struct PeerRecord *pr)
599 smr->size = htons (th->msize); 575 smr->size = htons (th->msize);
600 smr->smr_id = htons (th->smr_id = pr->smr_id_gen++); 576 smr->smr_id = htons (th->smr_id = pr->smr_id_gen++);
601 GNUNET_CONTAINER_DLL_insert_tail (h->control_pending_head, 577 GNUNET_CONTAINER_DLL_insert_tail (h->control_pending_head,
602 h->control_pending_tail, 578 h->control_pending_tail, cm);
603 cm);
604#if DEBUG_CORE 579#if DEBUG_CORE
605 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 580 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
606 "Adding SEND REQUEST for peer `%s' to message queue\n", 581 "Adding SEND REQUEST for peer `%s' to message queue\n",
607 GNUNET_i2s (&pr->peer)); 582 GNUNET_i2s (&pr->peer));
608#endif 583#endif
609 trigger_next_request (h, GNUNET_NO); 584 trigger_next_request (h, GNUNET_NO);
610} 585}
@@ -618,33 +593,26 @@ request_next_transmission (struct PeerRecord *pr)
618 * @param tc context, can be NULL (!) 593 * @param tc context, can be NULL (!)
619 */ 594 */
620static void 595static void
621transmission_timeout (void *cls, 596transmission_timeout (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
622 const struct GNUNET_SCHEDULER_TaskContext *tc)
623{ 597{
624 struct PeerRecord *pr = cls; 598 struct PeerRecord *pr = cls;
625 struct GNUNET_CORE_Handle *h = pr->ch; 599 struct GNUNET_CORE_Handle *h = pr->ch;
626 struct GNUNET_CORE_TransmitHandle *th; 600 struct GNUNET_CORE_TransmitHandle *th;
627 601
628 pr->timeout_task = GNUNET_SCHEDULER_NO_TASK; 602 pr->timeout_task = GNUNET_SCHEDULER_NO_TASK;
629 th = pr->pending_head; 603 th = pr->pending_head;
630 GNUNET_CONTAINER_DLL_remove (pr->pending_head, 604 GNUNET_CONTAINER_DLL_remove (pr->pending_head, pr->pending_tail, th);
631 pr->pending_tail,
632 th);
633 pr->queue_size--; 605 pr->queue_size--;
634 if ( (pr->prev != NULL) || 606 if ((pr->prev != NULL) || (pr->next != NULL) || (pr == h->ready_peer_head))
635 (pr->next != NULL) || 607 {
636 (pr == h->ready_peer_head) ) 608 /* the request that was 'approved' by core was
637 { 609 * canceled before it could be transmitted; remove
638 /* the request that was 'approved' by core was 610 * us from the 'ready' list */
639 canceled before it could be transmitted; remove 611 GNUNET_CONTAINER_DLL_remove (h->ready_peer_head, h->ready_peer_tail, pr);
640 us from the 'ready' list */ 612 }
641 GNUNET_CONTAINER_DLL_remove (h->ready_peer_head,
642 h->ready_peer_tail,
643 pr);
644 }
645#if DEBUG_CORE 613#if DEBUG_CORE
646 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 614 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
647 "Signalling timeout of request for transmission to CORE service\n"); 615 "Signalling timeout of request for transmission to CORE service\n");
648#endif 616#endif
649 request_next_transmission (pr); 617 request_next_transmission (pr);
650 GNUNET_assert (0 == th->get_message (th->get_message_cls, 0, NULL)); 618 GNUNET_assert (0 == th->get_message (th->get_message_cls, 0, NULL));
@@ -656,9 +624,7 @@ transmission_timeout (void *cls,
656 * Transmit the next message to the core service. 624 * Transmit the next message to the core service.
657 */ 625 */
658static size_t 626static size_t
659transmit_message (void *cls, 627transmit_message (void *cls, size_t size, void *buf)
660 size_t size,
661 void *buf)
662{ 628{
663 struct GNUNET_CORE_Handle *h = cls; 629 struct GNUNET_CORE_Handle *h = cls;
664 struct ControlMessage *cm; 630 struct ControlMessage *cm;
@@ -672,117 +638,108 @@ transmit_message (void *cls,
672 GNUNET_assert (h->reconnect_task == GNUNET_SCHEDULER_NO_TASK); 638 GNUNET_assert (h->reconnect_task == GNUNET_SCHEDULER_NO_TASK);
673 h->cth = NULL; 639 h->cth = NULL;
674 if (buf == NULL) 640 if (buf == NULL)
675 { 641 {
676#if DEBUG_CORE 642#if DEBUG_CORE
677 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 643 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
678 "Transmission failed, initiating reconnect\n"); 644 "Transmission failed, initiating reconnect\n");
679#endif 645#endif
680 reconnect_later (h); 646 reconnect_later (h);
681 return 0; 647 return 0;
682 } 648 }
683 /* first check for control messages */ 649 /* first check for control messages */
684 if (NULL != (cm = h->control_pending_head)) 650 if (NULL != (cm = h->control_pending_head))
651 {
652 hdr = (const struct GNUNET_MessageHeader *) &cm[1];
653 msize = ntohs (hdr->size);
654 if (size < msize)
685 { 655 {
686 hdr = (const struct GNUNET_MessageHeader*) &cm[1];
687 msize = ntohs (hdr->size);
688 if (size < msize)
689 {
690 trigger_next_request (h, GNUNET_NO);
691 return 0;
692 }
693#if DEBUG_CORE
694 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
695 "Transmitting control message with %u bytes of type %u to core.\n",
696 (unsigned int) msize,
697 (unsigned int) ntohs (hdr->type));
698#endif
699 memcpy (buf, hdr, msize);
700 GNUNET_CONTAINER_DLL_remove (h->control_pending_head,
701 h->control_pending_tail,
702 cm);
703 if (cm->th != NULL)
704 cm->th->cm = NULL;
705 if (NULL != cm->cont)
706 cm->cont (cm->cont_cls, GNUNET_OK);
707 GNUNET_free (cm);
708 trigger_next_request (h, GNUNET_NO); 656 trigger_next_request (h, GNUNET_NO);
709 return msize; 657 return 0;
710 } 658 }
659#if DEBUG_CORE
660 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
661 "Transmitting control message with %u bytes of type %u to core.\n",
662 (unsigned int) msize, (unsigned int) ntohs (hdr->type));
663#endif
664 memcpy (buf, hdr, msize);
665 GNUNET_CONTAINER_DLL_remove (h->control_pending_head,
666 h->control_pending_tail, cm);
667 if (cm->th != NULL)
668 cm->th->cm = NULL;
669 if (NULL != cm->cont)
670 cm->cont (cm->cont_cls, GNUNET_OK);
671 GNUNET_free (cm);
672 trigger_next_request (h, GNUNET_NO);
673 return msize;
674 }
711 /* now check for 'ready' P2P messages */ 675 /* now check for 'ready' P2P messages */
712 if (NULL != (pr = h->ready_peer_head)) 676 if (NULL != (pr = h->ready_peer_head))
677 {
678 GNUNET_assert (pr->pending_head != NULL);
679 th = pr->pending_head;
680 if (size < th->msize + sizeof (struct SendMessage))
681 {
682 trigger_next_request (h, GNUNET_NO);
683 return 0;
684 }
685 GNUNET_CONTAINER_DLL_remove (h->ready_peer_head, h->ready_peer_tail, pr);
686 GNUNET_CONTAINER_DLL_remove (pr->pending_head, pr->pending_tail, th);
687 pr->queue_size--;
688 if (pr->timeout_task != GNUNET_SCHEDULER_NO_TASK)
713 { 689 {
714 GNUNET_assert (pr->pending_head != NULL); 690 GNUNET_SCHEDULER_cancel (pr->timeout_task);
715 th = pr->pending_head; 691 pr->timeout_task = GNUNET_SCHEDULER_NO_TASK;
716 if (size < th->msize + sizeof (struct SendMessage)) 692 }
717 {
718 trigger_next_request (h, GNUNET_NO);
719 return 0;
720 }
721 GNUNET_CONTAINER_DLL_remove (h->ready_peer_head,
722 h->ready_peer_tail,
723 pr);
724 GNUNET_CONTAINER_DLL_remove (pr->pending_head,
725 pr->pending_tail,
726 th);
727 pr->queue_size--;
728 if (pr->timeout_task != GNUNET_SCHEDULER_NO_TASK)
729 {
730 GNUNET_SCHEDULER_cancel (pr->timeout_task);
731 pr->timeout_task = GNUNET_SCHEDULER_NO_TASK;
732 }
733#if DEBUG_CORE 693#if DEBUG_CORE
734 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 694 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
735 "Transmitting SEND request to `%s' with %u bytes.\n", 695 "Transmitting SEND request to `%s' with %u bytes.\n",
736 GNUNET_i2s (&pr->peer), 696 GNUNET_i2s (&pr->peer), (unsigned int) th->msize);
737 (unsigned int) th->msize);
738#endif 697#endif
739 sm = (struct SendMessage *) buf; 698 sm = (struct SendMessage *) buf;
740 sm->header.type = htons (GNUNET_MESSAGE_TYPE_CORE_SEND); 699 sm->header.type = htons (GNUNET_MESSAGE_TYPE_CORE_SEND);
741 sm->priority = htonl (th->priority); 700 sm->priority = htonl (th->priority);
742 sm->deadline = GNUNET_TIME_absolute_hton (th->timeout); 701 sm->deadline = GNUNET_TIME_absolute_hton (th->timeout);
743 sm->peer = pr->peer; 702 sm->peer = pr->peer;
744 sm->cork = htonl ((uint32_t) th->cork); 703 sm->cork = htonl ((uint32_t) th->cork);
745 sm->reserved = htonl (0); 704 sm->reserved = htonl (0);
746 ret = th->get_message (th->get_message_cls, 705 ret = th->get_message (th->get_message_cls,
747 size - sizeof (struct SendMessage), 706 size - sizeof (struct SendMessage), &sm[1]);
748 &sm[1]); 707
749
750#if DEBUG_CORE 708#if DEBUG_CORE
751 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 709 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
752 "Transmitting SEND request to `%s' yielded %u bytes.\n", 710 "Transmitting SEND request to `%s' yielded %u bytes.\n",
753 GNUNET_i2s (&pr->peer), 711 GNUNET_i2s (&pr->peer), ret);
754 ret);
755#endif 712#endif
756 GNUNET_free (th); 713 GNUNET_free (th);
757 if (0 == ret) 714 if (0 == ret)
758 { 715 {
759#if DEBUG_CORE 716#if DEBUG_CORE
760 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 717 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
761 "Size of clients message to peer %s is 0!\n", 718 "Size of clients message to peer %s is 0!\n",
762 GNUNET_i2s(&pr->peer)); 719 GNUNET_i2s (&pr->peer));
763#endif 720#endif
764 /* client decided to send nothing! */ 721 /* client decided to send nothing! */
765 request_next_transmission (pr); 722 request_next_transmission (pr);
766 return 0; 723 return 0;
767 } 724 }
768#if DEBUG_CORE 725#if DEBUG_CORE
769 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 726 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
770 "Produced SEND message to core with %u bytes payload\n", 727 "Produced SEND message to core with %u bytes payload\n",
771 (unsigned int) ret); 728 (unsigned int) ret);
772#endif 729#endif
773 GNUNET_assert (ret >= sizeof (struct GNUNET_MessageHeader)); 730 GNUNET_assert (ret >= sizeof (struct GNUNET_MessageHeader));
774 if (ret + sizeof (struct SendMessage) >= GNUNET_SERVER_MAX_MESSAGE_SIZE) 731 if (ret + sizeof (struct SendMessage) >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
775 { 732 {
776 GNUNET_break (0); 733 GNUNET_break (0);
777 request_next_transmission (pr);
778 return 0;
779 }
780 ret += sizeof (struct SendMessage);
781 sm->header.size = htons (ret);
782 GNUNET_assert (ret <= size);
783 request_next_transmission (pr); 734 request_next_transmission (pr);
784 return ret; 735 return 0;
785 } 736 }
737 ret += sizeof (struct SendMessage);
738 sm->header.size = htons (ret);
739 GNUNET_assert (ret <= size);
740 request_next_transmission (pr);
741 return ret;
742 }
786 return 0; 743 return 0;
787} 744}
788 745
@@ -795,45 +752,46 @@ transmit_message (void *cls,
795 * @param ignore_currently_down transmit message even if not initialized? 752 * @param ignore_currently_down transmit message even if not initialized?
796 */ 753 */
797static void 754static void
798trigger_next_request (struct GNUNET_CORE_Handle *h, 755trigger_next_request (struct GNUNET_CORE_Handle *h, int ignore_currently_down)
799 int ignore_currently_down)
800{ 756{
801 uint16_t msize; 757 uint16_t msize;
802 758
803 if ( (GNUNET_YES == h->currently_down) && 759 if ((GNUNET_YES == h->currently_down) && (ignore_currently_down == GNUNET_NO))
804 (ignore_currently_down == GNUNET_NO) ) 760 {
805 {
806#if DEBUG_CORE 761#if DEBUG_CORE
807 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 762 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
808 "Core connection down, not processing queue\n"); 763 "Core connection down, not processing queue\n");
809#endif 764#endif
810 return; 765 return;
811 } 766 }
812 if (NULL != h->cth) 767 if (NULL != h->cth)
813 { 768 {
814#if DEBUG_CORE 769#if DEBUG_CORE
815 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 770 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
816 "Request pending, not processing queue\n"); 771 "Request pending, not processing queue\n");
817#endif 772#endif
818 return; 773 return;
819 } 774 }
820 if (h->control_pending_head != NULL) 775 if (h->control_pending_head != NULL)
821 msize = ntohs (((struct GNUNET_MessageHeader*) &h->control_pending_head[1])->size); 776 msize =
822 else if (h->ready_peer_head != NULL) 777 ntohs (((struct GNUNET_MessageHeader *) &h->
823 msize = h->ready_peer_head->pending_head->msize + sizeof (struct SendMessage); 778 control_pending_head[1])->size);
779 else if (h->ready_peer_head != NULL)
780 msize =
781 h->ready_peer_head->pending_head->msize + sizeof (struct SendMessage);
824 else 782 else
825 { 783 {
826#if DEBUG_CORE 784#if DEBUG_CORE
827 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 785 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
828 "Request queue empty, not processing queue\n"); 786 "Request queue empty, not processing queue\n");
829#endif 787#endif
830 return; /* no pending message */ 788 return; /* no pending message */
831 } 789 }
832 h->cth = GNUNET_CLIENT_notify_transmit_ready (h->client, 790 h->cth = GNUNET_CLIENT_notify_transmit_ready (h->client,
833 msize, 791 msize,
834 GNUNET_TIME_UNIT_FOREVER_REL, 792 GNUNET_TIME_UNIT_FOREVER_REL,
835 GNUNET_NO, 793 GNUNET_NO,
836 &transmit_message, h); 794 &transmit_message, h);
837} 795}
838 796
839 797
@@ -844,8 +802,7 @@ trigger_next_request (struct GNUNET_CORE_Handle *h,
844 * @param msg the message received from the core service 802 * @param msg the message received from the core service
845 */ 803 */
846static void 804static void
847main_notify_handler (void *cls, 805main_notify_handler (void *cls, const struct GNUNET_MessageHeader *msg)
848 const struct GNUNET_MessageHeader *msg)
849{ 806{
850 struct GNUNET_CORE_Handle *h = cls; 807 struct GNUNET_CORE_Handle *h = cls;
851 const struct InitReplyMessage *m; 808 const struct InitReplyMessage *m;
@@ -868,13 +825,13 @@ main_notify_handler (void *cls,
868 uint32_t ats_count; 825 uint32_t ats_count;
869 826
870 if (msg == NULL) 827 if (msg == NULL)
871 { 828 {
872 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 829 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
873 _ 830 _
874 ("Client was disconnected from core service, trying to reconnect.\n")); 831 ("Client was disconnected from core service, trying to reconnect.\n"));
875 reconnect_later (h); 832 reconnect_later (h);
876 return; 833 return;
877 } 834 }
878 msize = ntohs (msg->size); 835 msize = ntohs (msg->size);
879#if DEBUG_CORE > 2 836#if DEBUG_CORE > 2
880 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 837 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
@@ -882,425 +839,401 @@ main_notify_handler (void *cls,
882 ntohs (msg->type), msize); 839 ntohs (msg->type), msize);
883#endif 840#endif
884 switch (ntohs (msg->type)) 841 switch (ntohs (msg->type))
842 {
843 case GNUNET_MESSAGE_TYPE_CORE_INIT_REPLY:
844 if (ntohs (msg->size) != sizeof (struct InitReplyMessage))
885 { 845 {
886 case GNUNET_MESSAGE_TYPE_CORE_INIT_REPLY: 846 GNUNET_break (0);
887 if (ntohs (msg->size) != sizeof (struct InitReplyMessage)) 847 reconnect_later (h);
888 { 848 return;
889 GNUNET_break (0); 849 }
890 reconnect_later (h); 850 m = (const struct InitReplyMessage *) msg;
891 return; 851 GNUNET_break (0 == ntohl (m->reserved));
892 } 852 /* start our message processing loop */
893 m = (const struct InitReplyMessage *) msg; 853 if (GNUNET_YES == h->currently_down)
894 GNUNET_break (0 == ntohl (m->reserved)); 854 {
895 /* start our message processing loop */ 855 h->currently_down = GNUNET_NO;
896 if (GNUNET_YES == h->currently_down) 856 trigger_next_request (h, GNUNET_NO);
897 { 857 }
898 h->currently_down = GNUNET_NO; 858 h->retry_backoff = GNUNET_TIME_UNIT_MILLISECONDS;
899 trigger_next_request (h, GNUNET_NO); 859 GNUNET_CRYPTO_hash (&m->publicKey,
900 } 860 sizeof (struct
901 h->retry_backoff = GNUNET_TIME_UNIT_MILLISECONDS; 861 GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded),
902 GNUNET_CRYPTO_hash (&m->publicKey, 862 &h->me.hashPubKey);
903 sizeof (struct 863 if (NULL != (init = h->init))
904 GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded), 864 {
905 &h->me.hashPubKey); 865 /* mark so we don't call init on reconnect */
906 if (NULL != (init = h->init)) 866 h->init = NULL;
907 {
908 /* mark so we don't call init on reconnect */
909 h->init = NULL;
910#if DEBUG_CORE 867#if DEBUG_CORE
911 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 868 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
912 "Connected to core service of peer `%s'.\n", 869 "Connected to core service of peer `%s'.\n",
913 GNUNET_i2s (&h->me)); 870 GNUNET_i2s (&h->me));
914#endif 871#endif
915 init (h->cls, h, &h->me, &m->publicKey); 872 init (h->cls, h, &h->me, &m->publicKey);
916 } 873 }
917 else 874 else
918 { 875 {
919#if DEBUG_CORE 876#if DEBUG_CORE
920 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 877 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
921 "Successfully reconnected to core service.\n"); 878 "Successfully reconnected to core service.\n");
922#endif 879#endif
923 } 880 }
924 /* fake 'connect to self' */ 881 /* fake 'connect to self' */
925 pr = GNUNET_CONTAINER_multihashmap_get (h->peers, 882 pr = GNUNET_CONTAINER_multihashmap_get (h->peers, &h->me.hashPubKey);
926 &h->me.hashPubKey); 883 GNUNET_assert (pr == NULL);
927 GNUNET_assert (pr == NULL); 884 pr = GNUNET_malloc (sizeof (struct PeerRecord));
928 pr = GNUNET_malloc (sizeof (struct PeerRecord)); 885 pr->peer = h->me;
929 pr->peer = h->me; 886 pr->ch = h;
930 pr->ch = h; 887 GNUNET_assert (GNUNET_YES ==
931 GNUNET_assert (GNUNET_YES == 888 GNUNET_CONTAINER_multihashmap_put (h->peers,
932 GNUNET_CONTAINER_multihashmap_put (h->peers, 889 &h->me.hashPubKey,
933 &h->me.hashPubKey, 890 pr,
934 pr, 891 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST));
935 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST)); 892 if (NULL != h->connects)
936 if (NULL != h->connects) 893 h->connects (h->cls, &h->me, NULL);
937 h->connects (h->cls, 894 break;
938 &h->me, 895 case GNUNET_MESSAGE_TYPE_CORE_NOTIFY_CONNECT:
939 NULL); 896 if (msize < sizeof (struct ConnectNotifyMessage))
940 break; 897 {
941 case GNUNET_MESSAGE_TYPE_CORE_NOTIFY_CONNECT: 898 GNUNET_break (0);
942 if (msize < sizeof (struct ConnectNotifyMessage)) 899 reconnect_later (h);
943 { 900 return;
944 GNUNET_break (0); 901 }
945 reconnect_later (h); 902 cnm = (const struct ConnectNotifyMessage *) msg;
946 return; 903 ats_count = ntohl (cnm->ats_count);
947 } 904 if ((msize !=
948 cnm = (const struct ConnectNotifyMessage *) msg; 905 sizeof (struct ConnectNotifyMessage) +
949 ats_count = ntohl (cnm->ats_count); 906 ats_count * sizeof (struct GNUNET_TRANSPORT_ATS_Information)) ||
950 if ( (msize != sizeof (struct ConnectNotifyMessage) + ats_count * sizeof (struct GNUNET_TRANSPORT_ATS_Information)) || 907 (GNUNET_TRANSPORT_ATS_ARRAY_TERMINATOR !=
951 (GNUNET_TRANSPORT_ATS_ARRAY_TERMINATOR != ntohl ((&cnm->ats)[ats_count].type)) ) 908 ntohl ((&cnm->ats)[ats_count].type)))
952 { 909 {
953 GNUNET_break (0); 910 GNUNET_break (0);
954 reconnect_later (h); 911 reconnect_later (h);
955 return; 912 return;
956 } 913 }
957#if DEBUG_CORE 914#if DEBUG_CORE
958 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 915 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
959 "Received notification about connection from `%s'.\n", 916 "Received notification about connection from `%s'.\n",
960 GNUNET_i2s (&cnm->peer)); 917 GNUNET_i2s (&cnm->peer));
961#endif 918#endif
962 if (0 == memcmp (&h->me, 919 if (0 == memcmp (&h->me, &cnm->peer, sizeof (struct GNUNET_PeerIdentity)))
963 &cnm->peer, 920 {
964 sizeof (struct GNUNET_PeerIdentity))) 921 /* connect to self!? */
965 { 922 GNUNET_break (0);
966 /* connect to self!? */ 923 return;
967 GNUNET_break (0); 924 }
968 return; 925 pr = GNUNET_CONTAINER_multihashmap_get (h->peers, &cnm->peer.hashPubKey);
969 } 926 if (pr != NULL)
970 pr = GNUNET_CONTAINER_multihashmap_get (h->peers, 927 {
971 &cnm->peer.hashPubKey); 928 GNUNET_break (0);
972 if (pr != NULL) 929 reconnect_later (h);
973 { 930 return;
974 GNUNET_break (0); 931 }
975 reconnect_later (h); 932 pr = GNUNET_malloc (sizeof (struct PeerRecord));
976 return; 933 pr->peer = cnm->peer;
977 } 934 pr->ch = h;
978 pr = GNUNET_malloc (sizeof (struct PeerRecord)); 935 GNUNET_assert (GNUNET_YES ==
979 pr->peer = cnm->peer; 936 GNUNET_CONTAINER_multihashmap_put (h->peers,
980 pr->ch = h; 937 &cnm->peer.hashPubKey,
981 GNUNET_assert (GNUNET_YES == 938 pr,
982 GNUNET_CONTAINER_multihashmap_put (h->peers, 939 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST));
983 &cnm->peer.hashPubKey, 940 if (NULL != h->connects)
984 pr, 941 h->connects (h->cls, &cnm->peer, &cnm->ats);
985 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST)); 942 break;
986 if (NULL != h->connects) 943 case GNUNET_MESSAGE_TYPE_CORE_NOTIFY_DISCONNECT:
987 h->connects (h->cls, 944 if (msize != sizeof (struct DisconnectNotifyMessage))
988 &cnm->peer, 945 {
989 &cnm->ats); 946 GNUNET_break (0);
990 break; 947 reconnect_later (h);
991 case GNUNET_MESSAGE_TYPE_CORE_NOTIFY_DISCONNECT: 948 return;
992 if (msize != sizeof (struct DisconnectNotifyMessage)) 949 }
993 { 950 dnm = (const struct DisconnectNotifyMessage *) msg;
994 GNUNET_break (0); 951 if (0 == memcmp (&h->me, &dnm->peer, sizeof (struct GNUNET_PeerIdentity)))
995 reconnect_later (h); 952 {
996 return; 953 /* connection to self!? */
997 } 954 GNUNET_break (0);
998 dnm = (const struct DisconnectNotifyMessage *) msg; 955 return;
999 if (0 == memcmp (&h->me, 956 }
1000 &dnm->peer, 957 GNUNET_break (0 == ntohl (dnm->reserved));
1001 sizeof (struct GNUNET_PeerIdentity)))
1002 {
1003 /* connection to self!? */
1004 GNUNET_break (0);
1005 return;
1006 }
1007 GNUNET_break (0 == ntohl (dnm->reserved));
1008#if DEBUG_CORE 958#if DEBUG_CORE
1009 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 959 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1010 "Received notification about disconnect from `%s'.\n", 960 "Received notification about disconnect from `%s'.\n",
1011 GNUNET_i2s (&dnm->peer)); 961 GNUNET_i2s (&dnm->peer));
1012#endif 962#endif
1013 pr = GNUNET_CONTAINER_multihashmap_get (h->peers, 963 pr = GNUNET_CONTAINER_multihashmap_get (h->peers, &dnm->peer.hashPubKey);
1014 &dnm->peer.hashPubKey); 964 if (pr == NULL)
1015 if (pr == NULL) 965 {
1016 { 966 GNUNET_break (0);
1017 GNUNET_break (0); 967 reconnect_later (h);
1018 reconnect_later (h); 968 return;
1019 return; 969 }
1020 } 970 trigger = ((pr->prev != NULL) ||
1021 trigger = ( (pr->prev != NULL) || 971 (pr->next != NULL) || (h->ready_peer_head == pr));
1022 (pr->next != NULL) || 972 disconnect_and_free_peer_entry (h, &dnm->peer.hashPubKey, pr);
1023 (h->ready_peer_head == pr) ); 973 if (trigger)
1024 disconnect_and_free_peer_entry (h, &dnm->peer.hashPubKey, pr); 974 trigger_next_request (h, GNUNET_NO);
1025 if (trigger) 975 break;
1026 trigger_next_request (h, GNUNET_NO); 976 case GNUNET_MESSAGE_TYPE_CORE_NOTIFY_STATUS_CHANGE:
1027 break; 977 if (NULL == h->status_events)
1028 case GNUNET_MESSAGE_TYPE_CORE_NOTIFY_STATUS_CHANGE: 978 {
1029 if (NULL == h->status_events) 979 GNUNET_break (0);
1030 { 980 return;
1031 GNUNET_break (0); 981 }
1032 return; 982 if (msize < sizeof (struct PeerStatusNotifyMessage))
1033 } 983 {
1034 if (msize < sizeof (struct PeerStatusNotifyMessage)) 984 GNUNET_break (0);
1035 { 985 reconnect_later (h);
1036 GNUNET_break (0); 986 return;
1037 reconnect_later (h); 987 }
1038 return; 988 psnm = (const struct PeerStatusNotifyMessage *) msg;
1039 } 989 if (0 == memcmp (&h->me, &psnm->peer, sizeof (struct GNUNET_PeerIdentity)))
1040 psnm = (const struct PeerStatusNotifyMessage *) msg; 990 {
1041 if (0 == memcmp (&h->me, 991 /* self-change!? */
1042 &psnm->peer, 992 GNUNET_break (0);
1043 sizeof (struct GNUNET_PeerIdentity))) 993 return;
1044 { 994 }
1045 /* self-change!? */ 995 ats_count = ntohl (psnm->ats_count);
1046 GNUNET_break (0); 996 if ((msize !=
1047 return; 997 sizeof (struct PeerStatusNotifyMessage) +
1048 } 998 ats_count * sizeof (struct GNUNET_TRANSPORT_ATS_Information)) ||
1049 ats_count = ntohl (psnm->ats_count); 999 (GNUNET_TRANSPORT_ATS_ARRAY_TERMINATOR !=
1050 if ( (msize != sizeof (struct PeerStatusNotifyMessage) + ats_count * sizeof (struct GNUNET_TRANSPORT_ATS_Information)) || 1000 ntohl ((&psnm->ats)[ats_count].type)))
1051 (GNUNET_TRANSPORT_ATS_ARRAY_TERMINATOR != ntohl ((&psnm->ats)[ats_count].type)) ) 1001 {
1052 { 1002 GNUNET_break (0);
1053 GNUNET_break (0); 1003 reconnect_later (h);
1054 reconnect_later (h); 1004 return;
1055 return; 1005 }
1056 }
1057#if DEBUG_CORE > 1 1006#if DEBUG_CORE > 1
1058 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1007 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1059 "Received notification about status change by `%s'.\n", 1008 "Received notification about status change by `%s'.\n",
1060 GNUNET_i2s (&psnm->peer)); 1009 GNUNET_i2s (&psnm->peer));
1061#endif 1010#endif
1062 pr = GNUNET_CONTAINER_multihashmap_get (h->peers, 1011 pr = GNUNET_CONTAINER_multihashmap_get (h->peers, &psnm->peer.hashPubKey);
1063 &psnm->peer.hashPubKey); 1012 if (pr == NULL)
1064 if (pr == NULL) 1013 {
1065 { 1014 GNUNET_break (0);
1066 GNUNET_break (0); 1015 reconnect_later (h);
1067 reconnect_later (h); 1016 return;
1068 return; 1017 }
1069 } 1018 h->status_events (h->cls,
1070 h->status_events (h->cls, 1019 &psnm->peer,
1071 &psnm->peer, 1020 psnm->bandwidth_in,
1072 psnm->bandwidth_in, 1021 psnm->bandwidth_out,
1073 psnm->bandwidth_out, 1022 GNUNET_TIME_absolute_ntoh (psnm->timeout), &psnm->ats);
1074 GNUNET_TIME_absolute_ntoh (psnm->timeout), 1023 break;
1075 &psnm->ats); 1024 case GNUNET_MESSAGE_TYPE_CORE_NOTIFY_INBOUND:
1076 break; 1025 if (msize < sizeof (struct NotifyTrafficMessage))
1077 case GNUNET_MESSAGE_TYPE_CORE_NOTIFY_INBOUND: 1026 {
1078 if (msize < sizeof (struct NotifyTrafficMessage)) 1027 GNUNET_break (0);
1079 { 1028 reconnect_later (h);
1080 GNUNET_break (0); 1029 return;
1081 reconnect_later (h); 1030 }
1082 return; 1031 ntm = (const struct NotifyTrafficMessage *) msg;
1083 } 1032
1084 ntm = (const struct NotifyTrafficMessage *) msg; 1033 ats_count = ntohl (ntm->ats_count);
1085 1034 if ((msize <
1086 ats_count = ntohl (ntm->ats_count); 1035 sizeof (struct NotifyTrafficMessage) +
1087 if ( (msize < sizeof (struct NotifyTrafficMessage) + ats_count * sizeof (struct GNUNET_TRANSPORT_ATS_Information) 1036 ats_count * sizeof (struct GNUNET_TRANSPORT_ATS_Information) +
1088 + sizeof (struct GNUNET_MessageHeader)) || 1037 sizeof (struct GNUNET_MessageHeader)) ||
1089 (GNUNET_TRANSPORT_ATS_ARRAY_TERMINATOR != ntohl ((&ntm->ats)[ats_count].type)) ) 1038 (GNUNET_TRANSPORT_ATS_ARRAY_TERMINATOR !=
1090 { 1039 ntohl ((&ntm->ats)[ats_count].type)))
1091 GNUNET_break (0); 1040 {
1092 reconnect_later (h); 1041 GNUNET_break (0);
1093 return; 1042 reconnect_later (h);
1094 } 1043 return;
1095 em = (const struct GNUNET_MessageHeader *) &(&ntm->ats)[ats_count+1]; 1044 }
1045 em = (const struct GNUNET_MessageHeader *) &(&ntm->ats)[ats_count + 1];
1096#if DEBUG_CORE 1046#if DEBUG_CORE
1097 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1047 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1098 "Received message of type %u and size %u from peer `%4s'\n", 1048 "Received message of type %u and size %u from peer `%4s'\n",
1099 ntohs (em->type), 1049 ntohs (em->type), ntohs (em->size), GNUNET_i2s (&ntm->peer));
1100 ntohs (em->size),
1101 GNUNET_i2s (&ntm->peer));
1102#endif 1050#endif
1103 pr = GNUNET_CONTAINER_multihashmap_get (h->peers, 1051 pr = GNUNET_CONTAINER_multihashmap_get (h->peers, &ntm->peer.hashPubKey);
1104 &ntm->peer.hashPubKey); 1052 if (pr == NULL)
1105 if (pr == NULL) 1053 {
1106 { 1054 GNUNET_break (0);
1107 GNUNET_break (0); 1055 reconnect_later (h);
1108 reconnect_later (h); 1056 return;
1109 return; 1057 }
1110 } 1058 if ((GNUNET_NO == h->inbound_hdr_only) &&
1111 if ((GNUNET_NO == h->inbound_hdr_only) && 1059 (msize != ntohs (em->size) + sizeof (struct NotifyTrafficMessage) +
1112 (msize != ntohs (em->size) + sizeof (struct NotifyTrafficMessage) + 1060 +ats_count * sizeof (struct GNUNET_TRANSPORT_ATS_Information)))
1113 + ats_count * sizeof (struct GNUNET_TRANSPORT_ATS_Information)) ) 1061 {
1114 { 1062 GNUNET_break (0);
1115 GNUNET_break (0); 1063 reconnect_later (h);
1116 reconnect_later (h); 1064 return;
1117 return; 1065 }
1118 } 1066 et = ntohs (em->type);
1119 et = ntohs (em->type); 1067 for (hpos = 0; hpos < h->hcnt; hpos++)
1120 for (hpos = 0; hpos < h->hcnt; hpos++) 1068 {
1121 { 1069 mh = &h->handlers[hpos];
1122 mh = &h->handlers[hpos]; 1070 if (mh->type != et)
1123 if (mh->type != et) 1071 continue;
1124 continue; 1072 if ((mh->expected_size != ntohs (em->size)) && (mh->expected_size != 0))
1125 if ((mh->expected_size != ntohs (em->size)) && 1073 {
1126 (mh->expected_size != 0)) 1074 GNUNET_break (0);
1127 { 1075 continue;
1128 GNUNET_break (0); 1076 }
1129 continue; 1077 if (GNUNET_OK !=
1130 } 1078 h->handlers[hpos].callback (h->cls, &ntm->peer, em, &ntm->ats))
1131 if (GNUNET_OK != 1079 {
1132 h->handlers[hpos].callback (h->cls, &ntm->peer, em, 1080 /* error in processing, do not process other messages! */
1133 &ntm->ats)) 1081 break;
1134 { 1082 }
1135 /* error in processing, do not process other messages! */ 1083 }
1136 break; 1084 if (NULL != h->inbound_notify)
1137 } 1085 h->inbound_notify (h->cls, &ntm->peer, em, &ntm->ats);
1138 } 1086 break;
1139 if (NULL != h->inbound_notify) 1087 case GNUNET_MESSAGE_TYPE_CORE_NOTIFY_OUTBOUND:
1140 h->inbound_notify (h->cls, &ntm->peer, em, 1088 if (msize < sizeof (struct NotifyTrafficMessage))
1141 &ntm->ats); 1089 {
1142 break; 1090 GNUNET_break (0);
1143 case GNUNET_MESSAGE_TYPE_CORE_NOTIFY_OUTBOUND: 1091 reconnect_later (h);
1144 if (msize < sizeof (struct NotifyTrafficMessage)) 1092 return;
1145 { 1093 }
1146 GNUNET_break (0); 1094 ntm = (const struct NotifyTrafficMessage *) msg;
1147 reconnect_later (h); 1095 if (0 == memcmp (&h->me, &ntm->peer, sizeof (struct GNUNET_PeerIdentity)))
1148 return; 1096 {
1149 } 1097 /* self-change!? */
1150 ntm = (const struct NotifyTrafficMessage *) msg; 1098 GNUNET_break (0);
1151 if (0 == memcmp (&h->me, 1099 return;
1152 &ntm->peer, 1100 }
1153 sizeof (struct GNUNET_PeerIdentity))) 1101 ats_count = ntohl (ntm->ats_count);
1154 { 1102 if ((msize <
1155 /* self-change!? */ 1103 sizeof (struct NotifyTrafficMessage) +
1156 GNUNET_break (0); 1104 ats_count * sizeof (struct GNUNET_TRANSPORT_ATS_Information) +
1157 return; 1105 sizeof (struct GNUNET_MessageHeader)) ||
1158 } 1106 (GNUNET_TRANSPORT_ATS_ARRAY_TERMINATOR !=
1159 ats_count = ntohl (ntm->ats_count); 1107 ntohl ((&ntm->ats)[ats_count].type)))
1160 if ( (msize < sizeof (struct NotifyTrafficMessage) + ats_count * sizeof (struct GNUNET_TRANSPORT_ATS_Information) 1108 {
1161 + sizeof (struct GNUNET_MessageHeader)) || 1109 GNUNET_break (0);
1162 (GNUNET_TRANSPORT_ATS_ARRAY_TERMINATOR != ntohl ((&ntm->ats)[ats_count].type)) ) 1110 reconnect_later (h);
1163 { 1111 return;
1164 GNUNET_break (0); 1112 }
1165 reconnect_later (h); 1113 em = (const struct GNUNET_MessageHeader *) &(&ntm->ats)[ats_count + 1];
1166 return; 1114 pr = GNUNET_CONTAINER_multihashmap_get (h->peers, &ntm->peer.hashPubKey);
1167 } 1115 if (pr == NULL)
1168 em = (const struct GNUNET_MessageHeader *) &(&ntm->ats)[ats_count+1]; 1116 {
1169 pr = GNUNET_CONTAINER_multihashmap_get (h->peers, 1117 GNUNET_break (0);
1170 &ntm->peer.hashPubKey); 1118 reconnect_later (h);
1171 if (pr == NULL) 1119 return;
1172 { 1120 }
1173 GNUNET_break (0);
1174 reconnect_later (h);
1175 return;
1176 }
1177#if DEBUG_CORE 1121#if DEBUG_CORE
1178 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1122 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1179 "Received notification about transmission to `%s'.\n", 1123 "Received notification about transmission to `%s'.\n",
1180 GNUNET_i2s (&ntm->peer)); 1124 GNUNET_i2s (&ntm->peer));
1181#endif 1125#endif
1182 if ((GNUNET_NO == h->outbound_hdr_only) && 1126 if ((GNUNET_NO == h->outbound_hdr_only) &&
1183 (msize != ntohs (em->size) + sizeof (struct NotifyTrafficMessage) 1127 (msize != ntohs (em->size) + sizeof (struct NotifyTrafficMessage)
1184 + ats_count * sizeof (struct GNUNET_TRANSPORT_ATS_Information)) ) 1128 + ats_count * sizeof (struct GNUNET_TRANSPORT_ATS_Information)))
1185 { 1129 {
1186 GNUNET_break (0); 1130 GNUNET_break (0);
1187 reconnect_later (h); 1131 reconnect_later (h);
1188 return; 1132 return;
1189 } 1133 }
1190 if (NULL == h->outbound_notify) 1134 if (NULL == h->outbound_notify)
1191 { 1135 {
1192 GNUNET_break (0); 1136 GNUNET_break (0);
1193 break;
1194 }
1195 h->outbound_notify (h->cls, &ntm->peer, em,
1196 &ntm->ats);
1197 break; 1137 break;
1198 case GNUNET_MESSAGE_TYPE_CORE_SEND_READY: 1138 }
1199 if (msize != sizeof (struct SendMessageReady)) 1139 h->outbound_notify (h->cls, &ntm->peer, em, &ntm->ats);
1200 { 1140 break;
1201 GNUNET_break (0); 1141 case GNUNET_MESSAGE_TYPE_CORE_SEND_READY:
1202 reconnect_later (h); 1142 if (msize != sizeof (struct SendMessageReady))
1203 return; 1143 {
1204 } 1144 GNUNET_break (0);
1205 smr = (const struct SendMessageReady *) msg; 1145 reconnect_later (h);
1206 pr = GNUNET_CONTAINER_multihashmap_get (h->peers, 1146 return;
1207 &smr->peer.hashPubKey); 1147 }
1208 if (pr == NULL) 1148 smr = (const struct SendMessageReady *) msg;
1209 { 1149 pr = GNUNET_CONTAINER_multihashmap_get (h->peers, &smr->peer.hashPubKey);
1210 GNUNET_break (0); 1150 if (pr == NULL)
1211 reconnect_later (h); 1151 {
1212 return; 1152 GNUNET_break (0);
1213 } 1153 reconnect_later (h);
1154 return;
1155 }
1214#if DEBUG_CORE 1156#if DEBUG_CORE
1215 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1157 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1216 "Received notification about transmission readiness to `%s'.\n", 1158 "Received notification about transmission readiness to `%s'.\n",
1217 GNUNET_i2s (&smr->peer)); 1159 GNUNET_i2s (&smr->peer));
1218#endif 1160#endif
1219 if (pr->pending_head == NULL) 1161 if (pr->pending_head == NULL)
1220 { 1162 {
1221 /* request must have been cancelled between the original request 1163 /* request must have been cancelled between the original request
1222 and the response from core, ignore core's readiness */ 1164 * and the response from core, ignore core's readiness */
1223 break; 1165 break;
1224 } 1166 }
1225 1167
1226 th = pr->pending_head; 1168 th = pr->pending_head;
1227 if (ntohs (smr->smr_id) != th->smr_id) 1169 if (ntohs (smr->smr_id) != th->smr_id)
1228 { 1170 {
1229 /* READY message is for expired or cancelled message, 1171 /* READY message is for expired or cancelled message,
1230 ignore! (we should have already sent another request) */ 1172 * ignore! (we should have already sent another request) */
1231 break;
1232 }
1233 if ( (pr->prev != NULL) ||
1234 (pr->next != NULL) ||
1235 (h->ready_peer_head == pr) )
1236 {
1237 /* we should not already be on the ready list... */
1238 GNUNET_break (0);
1239 reconnect_later (h);
1240 return;
1241 }
1242 GNUNET_CONTAINER_DLL_insert (h->ready_peer_head,
1243 h->ready_peer_tail,
1244 pr);
1245 trigger_next_request (h, GNUNET_NO);
1246 break; 1173 break;
1247 case GNUNET_MESSAGE_TYPE_CORE_CONFIGURATION_INFO: 1174 }
1248 if (ntohs (msg->size) != sizeof (struct ConfigurationInfoMessage)) 1175 if ((pr->prev != NULL) || (pr->next != NULL) || (h->ready_peer_head == pr))
1249 { 1176 {
1250 GNUNET_break (0); 1177 /* we should not already be on the ready list... */
1251 reconnect_later (h); 1178 GNUNET_break (0);
1252 return; 1179 reconnect_later (h);
1253 } 1180 return;
1254 cim = (const struct ConfigurationInfoMessage*) msg; 1181 }
1255 if (0 == memcmp (&h->me, 1182 GNUNET_CONTAINER_DLL_insert (h->ready_peer_head, h->ready_peer_tail, pr);
1256 &cim->peer, 1183 trigger_next_request (h, GNUNET_NO);
1257 sizeof (struct GNUNET_PeerIdentity))) 1184 break;
1258 { 1185 case GNUNET_MESSAGE_TYPE_CORE_CONFIGURATION_INFO:
1259 /* self-change!? */ 1186 if (ntohs (msg->size) != sizeof (struct ConfigurationInfoMessage))
1260 GNUNET_break (0); 1187 {
1261 return; 1188 GNUNET_break (0);
1262 } 1189 reconnect_later (h);
1190 return;
1191 }
1192 cim = (const struct ConfigurationInfoMessage *) msg;
1193 if (0 == memcmp (&h->me, &cim->peer, sizeof (struct GNUNET_PeerIdentity)))
1194 {
1195 /* self-change!? */
1196 GNUNET_break (0);
1197 return;
1198 }
1263#if DEBUG_CORE 1199#if DEBUG_CORE
1264 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1200 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1265 "Received notification about configuration update for `%s' with RIM %u.\n", 1201 "Received notification about configuration update for `%s' with RIM %u.\n",
1266 GNUNET_i2s (&cim->peer), 1202 GNUNET_i2s (&cim->peer), (unsigned int) ntohl (cim->rim_id));
1267 (unsigned int) ntohl (cim->rim_id));
1268#endif 1203#endif
1269 pr = GNUNET_CONTAINER_multihashmap_get (h->peers, 1204 pr = GNUNET_CONTAINER_multihashmap_get (h->peers, &cim->peer.hashPubKey);
1270 &cim->peer.hashPubKey); 1205 if (pr == NULL)
1271 if (pr == NULL) 1206 {
1272 { 1207 GNUNET_break (0);
1273 GNUNET_break (0); 1208 reconnect_later (h);
1274 reconnect_later (h); 1209 return;
1275 return; 1210 }
1276 } 1211 if (pr->rim_id != ntohl (cim->rim_id))
1277 if (pr->rim_id != ntohl (cim->rim_id)) 1212 {
1278 {
1279#if DEBUG_CORE 1213#if DEBUG_CORE
1280 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1214 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1281 "Reservation ID mismatch in notification...\n"); 1215 "Reservation ID mismatch in notification...\n");
1282#endif 1216#endif
1283 break;
1284 }
1285 pcic = pr->pcic;
1286 pr->pcic = NULL;
1287 GNUNET_free_non_null (pr->pcic_ptr);
1288 pr->pcic_ptr = NULL;
1289 if (pcic != NULL)
1290 pcic (pr->pcic_cls,
1291 &pr->peer,
1292 cim->bw_out,
1293 ntohl (cim->reserved_amount),
1294 GNUNET_TIME_relative_ntoh (cim->reserve_delay),
1295 GNUNET_ntohll (cim->preference));
1296 break; 1217 break;
1297 default:
1298 reconnect_later (h);
1299 return;
1300 } 1218 }
1219 pcic = pr->pcic;
1220 pr->pcic = NULL;
1221 GNUNET_free_non_null (pr->pcic_ptr);
1222 pr->pcic_ptr = NULL;
1223 if (pcic != NULL)
1224 pcic (pr->pcic_cls,
1225 &pr->peer,
1226 cim->bw_out,
1227 ntohl (cim->reserved_amount),
1228 GNUNET_TIME_relative_ntoh (cim->reserve_delay),
1229 GNUNET_ntohll (cim->preference));
1230 break;
1231 default:
1232 reconnect_later (h);
1233 return;
1234 }
1301 GNUNET_CLIENT_receive (h->client, 1235 GNUNET_CLIENT_receive (h->client,
1302 &main_notify_handler, h, 1236 &main_notify_handler, h, GNUNET_TIME_UNIT_FOREVER_REL);
1303 GNUNET_TIME_UNIT_FOREVER_REL);
1304} 1237}
1305 1238
1306 1239
@@ -1312,27 +1245,24 @@ main_notify_handler (void *cls,
1312 * @param success were we successful 1245 * @param success were we successful
1313 */ 1246 */
1314static void 1247static void
1315init_done_task (void *cls, 1248init_done_task (void *cls, int success)
1316 int success)
1317{ 1249{
1318 struct GNUNET_CORE_Handle *h = cls; 1250 struct GNUNET_CORE_Handle *h = cls;
1319 1251
1320 if (success == GNUNET_SYSERR) 1252 if (success == GNUNET_SYSERR)
1321 return; /* shutdown */ 1253 return; /* shutdown */
1322 if (success == GNUNET_NO) 1254 if (success == GNUNET_NO)
1323 { 1255 {
1324#if DEBUG_CORE 1256#if DEBUG_CORE
1325 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1257 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1326 "Failed to exchange INIT with core, retrying\n"); 1258 "Failed to exchange INIT with core, retrying\n");
1327#endif 1259#endif
1328 if (h->reconnect_task == GNUNET_SCHEDULER_NO_TASK) 1260 if (h->reconnect_task == GNUNET_SCHEDULER_NO_TASK)
1329 reconnect_later (h); 1261 reconnect_later (h);
1330 return; 1262 return;
1331 } 1263 }
1332 GNUNET_CLIENT_receive (h->client, 1264 GNUNET_CLIENT_receive (h->client,
1333 &main_notify_handler, 1265 &main_notify_handler, h, GNUNET_TIME_UNIT_FOREVER_REL);
1334 h,
1335 GNUNET_TIME_UNIT_FOREVER_REL);
1336} 1266}
1337 1267
1338 1268
@@ -1353,49 +1283,46 @@ reconnect (struct GNUNET_CORE_Handle *h)
1353 unsigned int hpos; 1283 unsigned int hpos;
1354 1284
1355#if DEBUG_CORE 1285#if DEBUG_CORE
1356 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1286 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Reconnecting to CORE service\n");
1357 "Reconnecting to CORE service\n");
1358#endif 1287#endif
1359 GNUNET_assert (h->client == NULL); 1288 GNUNET_assert (h->client == NULL);
1360 GNUNET_assert (h->currently_down == GNUNET_YES); 1289 GNUNET_assert (h->currently_down == GNUNET_YES);
1361 h->client = GNUNET_CLIENT_connect ("core", h->cfg); 1290 h->client = GNUNET_CLIENT_connect ("core", h->cfg);
1362 if (h->client == NULL) 1291 if (h->client == NULL)
1363 { 1292 {
1364 reconnect_later (h); 1293 reconnect_later (h);
1365 return; 1294 return;
1366 } 1295 }
1367 msize = h->hcnt * sizeof (uint16_t) + sizeof (struct InitMessage); 1296 msize = h->hcnt * sizeof (uint16_t) + sizeof (struct InitMessage);
1368 cm = GNUNET_malloc (sizeof (struct ControlMessage) + 1297 cm = GNUNET_malloc (sizeof (struct ControlMessage) + msize);
1369 msize);
1370 cm->cont = &init_done_task; 1298 cm->cont = &init_done_task;
1371 cm->cont_cls = h; 1299 cm->cont_cls = h;
1372 init = (struct InitMessage*) &cm[1]; 1300 init = (struct InitMessage *) &cm[1];
1373 init->header.type = htons (GNUNET_MESSAGE_TYPE_CORE_INIT); 1301 init->header.type = htons (GNUNET_MESSAGE_TYPE_CORE_INIT);
1374 init->header.size = htons (msize); 1302 init->header.size = htons (msize);
1375 opt = GNUNET_CORE_OPTION_SEND_CONNECT | GNUNET_CORE_OPTION_SEND_DISCONNECT; 1303 opt = GNUNET_CORE_OPTION_SEND_CONNECT | GNUNET_CORE_OPTION_SEND_DISCONNECT;
1376 if (h->status_events != NULL) 1304 if (h->status_events != NULL)
1377 opt |= GNUNET_CORE_OPTION_SEND_STATUS_CHANGE; 1305 opt |= GNUNET_CORE_OPTION_SEND_STATUS_CHANGE;
1378 if (h->inbound_notify != NULL) 1306 if (h->inbound_notify != NULL)
1379 { 1307 {
1380 if (h->inbound_hdr_only) 1308 if (h->inbound_hdr_only)
1381 opt |= GNUNET_CORE_OPTION_SEND_HDR_INBOUND; 1309 opt |= GNUNET_CORE_OPTION_SEND_HDR_INBOUND;
1382 else 1310 else
1383 opt |= GNUNET_CORE_OPTION_SEND_FULL_INBOUND; 1311 opt |= GNUNET_CORE_OPTION_SEND_FULL_INBOUND;
1384 } 1312 }
1385 if (h->outbound_notify != NULL) 1313 if (h->outbound_notify != NULL)
1386 { 1314 {
1387 if (h->outbound_hdr_only) 1315 if (h->outbound_hdr_only)
1388 opt |= GNUNET_CORE_OPTION_SEND_HDR_OUTBOUND; 1316 opt |= GNUNET_CORE_OPTION_SEND_HDR_OUTBOUND;
1389 else 1317 else
1390 opt |= GNUNET_CORE_OPTION_SEND_FULL_OUTBOUND; 1318 opt |= GNUNET_CORE_OPTION_SEND_FULL_OUTBOUND;
1391 } 1319 }
1392 init->options = htonl (opt); 1320 init->options = htonl (opt);
1393 ts = (uint16_t *) &init[1]; 1321 ts = (uint16_t *) & init[1];
1394 for (hpos = 0; hpos < h->hcnt; hpos++) 1322 for (hpos = 0; hpos < h->hcnt; hpos++)
1395 ts[hpos] = htons (h->handlers[hpos].type); 1323 ts[hpos] = htons (h->handlers[hpos].type);
1396 GNUNET_CONTAINER_DLL_insert (h->control_pending_head, 1324 GNUNET_CONTAINER_DLL_insert (h->control_pending_head,
1397 h->control_pending_tail, 1325 h->control_pending_tail, cm);
1398 cm);
1399 trigger_next_request (h, GNUNET_YES); 1326 trigger_next_request (h, GNUNET_YES);
1400} 1327}
1401 1328
@@ -1427,12 +1354,12 @@ reconnect (struct GNUNET_CORE_Handle *h)
1427 */ 1354 */
1428struct GNUNET_CORE_Handle * 1355struct GNUNET_CORE_Handle *
1429GNUNET_CORE_connect (const struct GNUNET_CONFIGURATION_Handle *cfg, 1356GNUNET_CORE_connect (const struct GNUNET_CONFIGURATION_Handle *cfg,
1430 unsigned int queue_size, 1357 unsigned int queue_size,
1431 void *cls, 1358 void *cls,
1432 GNUNET_CORE_StartupCallback init, 1359 GNUNET_CORE_StartupCallback init,
1433 GNUNET_CORE_ConnectEventHandler connects, 1360 GNUNET_CORE_ConnectEventHandler connects,
1434 GNUNET_CORE_DisconnectEventHandler disconnects, 1361 GNUNET_CORE_DisconnectEventHandler disconnects,
1435 GNUNET_CORE_PeerStatusEventHandler status_events, 1362 GNUNET_CORE_PeerStatusEventHandler status_events,
1436 GNUNET_CORE_MessageCallback inbound_notify, 1363 GNUNET_CORE_MessageCallback inbound_notify,
1437 int inbound_hdr_only, 1364 int inbound_hdr_only,
1438 GNUNET_CORE_MessageCallback outbound_notify, 1365 GNUNET_CORE_MessageCallback outbound_notify,
@@ -1464,8 +1391,7 @@ GNUNET_CORE_connect (const struct GNUNET_CONFIGURATION_Handle *cfg,
1464 (GNUNET_SERVER_MAX_MESSAGE_SIZE - 1391 (GNUNET_SERVER_MAX_MESSAGE_SIZE -
1465 sizeof (struct InitMessage)) / sizeof (uint16_t)); 1392 sizeof (struct InitMessage)) / sizeof (uint16_t));
1466#if DEBUG_CORE 1393#if DEBUG_CORE
1467 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1394 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Connecting to CORE service\n");
1468 "Connecting to CORE service\n");
1469#endif 1395#endif
1470 reconnect (h); 1396 reconnect (h);
1471 return h; 1397 return h;
@@ -1483,40 +1409,38 @@ void
1483GNUNET_CORE_disconnect (struct GNUNET_CORE_Handle *handle) 1409GNUNET_CORE_disconnect (struct GNUNET_CORE_Handle *handle)
1484{ 1410{
1485 struct ControlMessage *cm; 1411 struct ControlMessage *cm;
1486 1412
1487#if DEBUG_CORE 1413#if DEBUG_CORE
1488 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1414 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Disconnecting from CORE service\n");
1489 "Disconnecting from CORE service\n");
1490#endif 1415#endif
1491 if (handle->cth != NULL) 1416 if (handle->cth != NULL)
1492 { 1417 {
1493 GNUNET_CLIENT_notify_transmit_ready_cancel (handle->cth); 1418 GNUNET_CLIENT_notify_transmit_ready_cancel (handle->cth);
1494 handle->cth = NULL; 1419 handle->cth = NULL;
1495 } 1420 }
1496 while (NULL != (cm = handle->control_pending_head)) 1421 while (NULL != (cm = handle->control_pending_head))
1497 { 1422 {
1498 GNUNET_CONTAINER_DLL_remove (handle->control_pending_head, 1423 GNUNET_CONTAINER_DLL_remove (handle->control_pending_head,
1499 handle->control_pending_tail, 1424 handle->control_pending_tail, cm);
1500 cm); 1425 if (cm->th != NULL)
1501 if (cm->th != NULL) 1426 cm->th->cm = NULL;
1502 cm->th->cm = NULL; 1427 if (cm->cont != NULL)
1503 if (cm->cont != NULL) 1428 cm->cont (cm->cont_cls, GNUNET_SYSERR);
1504 cm->cont (cm->cont_cls, GNUNET_SYSERR); 1429 GNUNET_free (cm);
1505 GNUNET_free (cm); 1430 }
1506 }
1507 if (handle->client != NULL) 1431 if (handle->client != NULL)
1508 { 1432 {
1509 GNUNET_CLIENT_disconnect (handle->client, GNUNET_NO); 1433 GNUNET_CLIENT_disconnect (handle->client, GNUNET_NO);
1510 handle->client = NULL; 1434 handle->client = NULL;
1511 } 1435 }
1512 GNUNET_CONTAINER_multihashmap_iterate (handle->peers, 1436 GNUNET_CONTAINER_multihashmap_iterate (handle->peers,
1513 &disconnect_and_free_peer_entry, 1437 &disconnect_and_free_peer_entry,
1514 handle); 1438 handle);
1515 if (handle->reconnect_task != GNUNET_SCHEDULER_NO_TASK) 1439 if (handle->reconnect_task != GNUNET_SCHEDULER_NO_TASK)
1516 { 1440 {
1517 GNUNET_SCHEDULER_cancel (handle->reconnect_task); 1441 GNUNET_SCHEDULER_cancel (handle->reconnect_task);
1518 handle->reconnect_task = GNUNET_SCHEDULER_NO_TASK; 1442 handle->reconnect_task = GNUNET_SCHEDULER_NO_TASK;
1519 } 1443 }
1520 GNUNET_CONTAINER_multihashmap_destroy (handle->peers); 1444 GNUNET_CONTAINER_multihashmap_destroy (handle->peers);
1521 handle->peers = NULL; 1445 handle->peers = NULL;
1522 GNUNET_break (handle->ready_peer_head == NULL); 1446 GNUNET_break (handle->ready_peer_head == NULL);
@@ -1532,7 +1456,7 @@ GNUNET_CORE_disconnect (struct GNUNET_CORE_Handle *handle)
1532 */ 1456 */
1533static void 1457static void
1534run_request_next_transmission (void *cls, 1458run_request_next_transmission (void *cls,
1535 const struct GNUNET_SCHEDULER_TaskContext *tc) 1459 const struct GNUNET_SCHEDULER_TaskContext *tc)
1536{ 1460{
1537 struct PeerRecord *pr = cls; 1461 struct PeerRecord *pr = cls;
1538 1462
@@ -1562,7 +1486,7 @@ run_request_next_transmission (void *cls,
1562 */ 1486 */
1563struct GNUNET_CORE_TransmitHandle * 1487struct GNUNET_CORE_TransmitHandle *
1564GNUNET_CORE_notify_transmit_ready (struct GNUNET_CORE_Handle *handle, 1488GNUNET_CORE_notify_transmit_ready (struct GNUNET_CORE_Handle *handle,
1565 int cork, 1489 int cork,
1566 uint32_t priority, 1490 uint32_t priority,
1567 struct GNUNET_TIME_Relative maxdelay, 1491 struct GNUNET_TIME_Relative maxdelay,
1568 const struct GNUNET_PeerIdentity *target, 1492 const struct GNUNET_PeerIdentity *target,
@@ -1576,22 +1500,21 @@ GNUNET_CORE_notify_transmit_ready (struct GNUNET_CORE_Handle *handle,
1576 struct GNUNET_CORE_TransmitHandle *prev; 1500 struct GNUNET_CORE_TransmitHandle *prev;
1577 struct GNUNET_CORE_TransmitHandle *minp; 1501 struct GNUNET_CORE_TransmitHandle *minp;
1578 1502
1579 pr = GNUNET_CONTAINER_multihashmap_get (handle->peers, 1503 pr = GNUNET_CONTAINER_multihashmap_get (handle->peers, &target->hashPubKey);
1580 &target->hashPubKey);
1581 if (NULL == pr) 1504 if (NULL == pr)
1582 { 1505 {
1583 /* attempt to send to peer that is not connected */ 1506 /* attempt to send to peer that is not connected */
1584 GNUNET_log(GNUNET_ERROR_TYPE_WARNING, 1507 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
1585 "Attempting to send to peer `%s' from peer `%s', but not connected!\n", 1508 "Attempting to send to peer `%s' from peer `%s', but not connected!\n",
1586 GNUNET_i2s(target), GNUNET_h2s(&handle->me.hashPubKey)); 1509 GNUNET_i2s (target), GNUNET_h2s (&handle->me.hashPubKey));
1587 GNUNET_break (0); 1510 GNUNET_break (0);
1588 return NULL; 1511 return NULL;
1589 } 1512 }
1590 GNUNET_assert (notify_size + sizeof (struct SendMessage) < 1513 GNUNET_assert (notify_size + sizeof (struct SendMessage) <
1591 GNUNET_SERVER_MAX_MESSAGE_SIZE); 1514 GNUNET_SERVER_MAX_MESSAGE_SIZE);
1592 th = GNUNET_malloc (sizeof (struct GNUNET_CORE_TransmitHandle)); 1515 th = GNUNET_malloc (sizeof (struct GNUNET_CORE_TransmitHandle));
1593 th->peer = pr; 1516 th->peer = pr;
1594 GNUNET_assert(NULL != notify); 1517 GNUNET_assert (NULL != notify);
1595 th->get_message = notify; 1518 th->get_message = notify;
1596 th->get_message_cls = notify_cls; 1519 th->get_message_cls = notify_cls;
1597 th->timeout = GNUNET_TIME_relative_to_absolute (maxdelay); 1520 th->timeout = GNUNET_TIME_relative_to_absolute (maxdelay);
@@ -1600,81 +1523,72 @@ GNUNET_CORE_notify_transmit_ready (struct GNUNET_CORE_Handle *handle,
1600 th->cork = cork; 1523 th->cork = cork;
1601 /* bound queue size */ 1524 /* bound queue size */
1602 if (pr->queue_size == handle->queue_size) 1525 if (pr->queue_size == handle->queue_size)
1526 {
1527 /* find lowest-priority entry, but skip the head of the list */
1528 minp = pr->pending_head->next;
1529 prev = minp;
1530 while (prev != NULL)
1531 {
1532 if (prev->priority < minp->priority)
1533 minp = prev;
1534 prev = prev->next;
1535 }
1536 if (minp == NULL)
1603 { 1537 {
1604 /* find lowest-priority entry, but skip the head of the list */ 1538 GNUNET_break (handle->queue_size != 0);
1605 minp = pr->pending_head->next; 1539 GNUNET_break (pr->queue_size == 1);
1606 prev = minp; 1540 GNUNET_free (th);
1607 while (prev != NULL)
1608 {
1609 if (prev->priority < minp->priority)
1610 minp = prev;
1611 prev = prev->next;
1612 }
1613 if (minp == NULL)
1614 {
1615 GNUNET_break (handle->queue_size != 0);
1616 GNUNET_break (pr->queue_size == 1);
1617 GNUNET_free(th);
1618#if DEBUG_CORE 1541#if DEBUG_CORE
1619 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1542 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1620 "Dropping transmission request: cannot drop queue head and limit is one\n"); 1543 "Dropping transmission request: cannot drop queue head and limit is one\n");
1621#endif 1544#endif
1622 return NULL; 1545 return NULL;
1623 } 1546 }
1624 if (priority <= minp->priority) 1547 if (priority <= minp->priority)
1625 { 1548 {
1626#if DEBUG_CORE 1549#if DEBUG_CORE
1627 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1550 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1628 "Dropping transmission request: priority too low\n"); 1551 "Dropping transmission request: priority too low\n");
1629#endif 1552#endif
1630 GNUNET_free(th); 1553 GNUNET_free (th);
1631 return NULL; /* priority too low */ 1554 return NULL; /* priority too low */
1632 }
1633 GNUNET_CONTAINER_DLL_remove (pr->pending_head,
1634 pr->pending_tail,
1635 minp);
1636 pr->queue_size--;
1637 GNUNET_assert (0 ==
1638 minp->get_message (minp->get_message_cls,
1639 0, NULL));
1640 GNUNET_free (minp);
1641 } 1555 }
1556 GNUNET_CONTAINER_DLL_remove (pr->pending_head, pr->pending_tail, minp);
1557 pr->queue_size--;
1558 GNUNET_assert (0 == minp->get_message (minp->get_message_cls, 0, NULL));
1559 GNUNET_free (minp);
1560 }
1642 1561
1643 /* Order entries by deadline, but SKIP 'HEAD' if 1562 /* Order entries by deadline, but SKIP 'HEAD' if
1644 we're in the 'ready_peer_*' DLL */ 1563 * we're in the 'ready_peer_*' DLL */
1645 pos = pr->pending_head; 1564 pos = pr->pending_head;
1646 if ( (pr->prev != NULL) || 1565 if ((pr->prev != NULL) ||
1647 (pr->next != NULL) || 1566 (pr->next != NULL) || (pr == handle->ready_peer_head))
1648 (pr == handle->ready_peer_head) ) 1567 {
1649 { 1568 GNUNET_assert (pos != NULL);
1650 GNUNET_assert (pos != NULL); 1569 pos = pos->next; /* skip head */
1651 pos = pos->next; /* skip head */ 1570 }
1652 }
1653 1571
1654 /* insertion sort */ 1572 /* insertion sort */
1655 prev = pos; 1573 prev = pos;
1656 while ( (pos != NULL) && 1574 while ((pos != NULL) && (pos->timeout.abs_value < th->timeout.abs_value))
1657 (pos->timeout.abs_value < th->timeout.abs_value) ) 1575 {
1658 { 1576 prev = pos;
1659 prev = pos; 1577 pos = pos->next;
1660 pos = pos->next; 1578 }
1661 }
1662 GNUNET_CONTAINER_DLL_insert_after (pr->pending_head, 1579 GNUNET_CONTAINER_DLL_insert_after (pr->pending_head,
1663 pr->pending_tail, 1580 pr->pending_tail, prev, th);
1664 prev,
1665 th);
1666 pr->queue_size++; 1581 pr->queue_size++;
1667 /* was the request queue previously empty? */ 1582 /* was the request queue previously empty? */
1668#if DEBUG_CORE 1583#if DEBUG_CORE
1669 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1584 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Transmission request added to queue\n");
1670 "Transmission request added to queue\n");
1671#endif 1585#endif
1672 if ( (pr->pending_head == th) && 1586 if ((pr->pending_head == th) &&
1673 (pr->ntr_task == GNUNET_SCHEDULER_NO_TASK) && 1587 (pr->ntr_task == GNUNET_SCHEDULER_NO_TASK) &&
1674 (pr->next == NULL) && 1588 (pr->next == NULL) &&
1675 (pr->prev == NULL) && 1589 (pr->prev == NULL) && (handle->ready_peer_head != pr))
1676 (handle->ready_peer_head != pr) ) 1590 pr->ntr_task =
1677 pr->ntr_task = GNUNET_SCHEDULER_add_now (&run_request_next_transmission, pr); 1591 GNUNET_SCHEDULER_add_now (&run_request_next_transmission, pr);
1678 return th; 1592 return th;
1679} 1593}
1680 1594
@@ -1685,42 +1599,34 @@ GNUNET_CORE_notify_transmit_ready (struct GNUNET_CORE_Handle *handle,
1685 * @param th handle that was returned by "notify_transmit_ready". 1599 * @param th handle that was returned by "notify_transmit_ready".
1686 */ 1600 */
1687void 1601void
1688GNUNET_CORE_notify_transmit_ready_cancel (struct GNUNET_CORE_TransmitHandle 1602GNUNET_CORE_notify_transmit_ready_cancel (struct GNUNET_CORE_TransmitHandle *th)
1689 *th)
1690{ 1603{
1691 struct PeerRecord *pr = th->peer; 1604 struct PeerRecord *pr = th->peer;
1692 struct GNUNET_CORE_Handle *h = pr->ch; 1605 struct GNUNET_CORE_Handle *h = pr->ch;
1693 int was_head; 1606 int was_head;
1694 1607
1695 was_head = (pr->pending_head == th); 1608 was_head = (pr->pending_head == th);
1696 GNUNET_CONTAINER_DLL_remove (pr->pending_head, 1609 GNUNET_CONTAINER_DLL_remove (pr->pending_head, pr->pending_tail, th);
1697 pr->pending_tail,
1698 th);
1699 pr->queue_size--; 1610 pr->queue_size--;
1700 if (th->cm != NULL) 1611 if (th->cm != NULL)
1701 { 1612 {
1702 /* we're currently in the control queue, remove */ 1613 /* we're currently in the control queue, remove */
1703 GNUNET_CONTAINER_DLL_remove (h->control_pending_head, 1614 GNUNET_CONTAINER_DLL_remove (h->control_pending_head,
1704 h->control_pending_tail, 1615 h->control_pending_tail, th->cm);
1705 th->cm); 1616 GNUNET_free (th->cm);
1706 GNUNET_free (th->cm); 1617 }
1707 }
1708 GNUNET_free (th); 1618 GNUNET_free (th);
1709 if (was_head) 1619 if (was_head)
1620 {
1621 if ((pr->prev != NULL) || (pr->next != NULL) || (pr == h->ready_peer_head))
1710 { 1622 {
1711 if ( (pr->prev != NULL) || 1623 /* the request that was 'approved' by core was
1712 (pr->next != NULL) || 1624 * canceled before it could be transmitted; remove
1713 (pr == h->ready_peer_head) ) 1625 * us from the 'ready' list */
1714 { 1626 GNUNET_CONTAINER_DLL_remove (h->ready_peer_head, h->ready_peer_tail, pr);
1715 /* the request that was 'approved' by core was
1716 canceled before it could be transmitted; remove
1717 us from the 'ready' list */
1718 GNUNET_CONTAINER_DLL_remove (h->ready_peer_head,
1719 h->ready_peer_tail,
1720 pr);
1721 }
1722 request_next_transmission (pr);
1723 } 1627 }
1628 request_next_transmission (pr);
1629 }
1724} 1630}
1725 1631
1726 1632
@@ -1766,13 +1672,12 @@ struct GNUNET_CORE_PeerRequestHandle
1766 * @param success was the request transmitted? 1672 * @param success was the request transmitted?
1767 */ 1673 */
1768static void 1674static void
1769peer_request_connect_cont (void *cls, 1675peer_request_connect_cont (void *cls, int success)
1770 int success)
1771{ 1676{
1772 struct GNUNET_CORE_PeerRequestHandle *ret = cls; 1677 struct GNUNET_CORE_PeerRequestHandle *ret = cls;
1773 1678
1774 if (ret->cont != NULL) 1679 if (ret->cont != NULL)
1775 ret->cont (ret->cont_cls, success); 1680 ret->cont (ret->cont_cls, success);
1776 GNUNET_free (ret); 1681 GNUNET_free (ret);
1777} 1682}
1778 1683
@@ -1798,34 +1703,31 @@ peer_request_connect_cont (void *cls,
1798 */ 1703 */
1799struct GNUNET_CORE_PeerRequestHandle * 1704struct GNUNET_CORE_PeerRequestHandle *
1800GNUNET_CORE_peer_request_connect (struct GNUNET_CORE_Handle *h, 1705GNUNET_CORE_peer_request_connect (struct GNUNET_CORE_Handle *h,
1801 const struct GNUNET_PeerIdentity * peer, 1706 const struct GNUNET_PeerIdentity *peer,
1802 GNUNET_CORE_ControlContinuation cont, 1707 GNUNET_CORE_ControlContinuation cont,
1803 void *cont_cls) 1708 void *cont_cls)
1804{ 1709{
1805 struct GNUNET_CORE_PeerRequestHandle *ret; 1710 struct GNUNET_CORE_PeerRequestHandle *ret;
1806 struct ControlMessage *cm; 1711 struct ControlMessage *cm;
1807 struct ConnectMessage *msg; 1712 struct ConnectMessage *msg;
1808 1713
1809 if (NULL != GNUNET_CONTAINER_multihashmap_get (h->peers, 1714 if (NULL != GNUNET_CONTAINER_multihashmap_get (h->peers, &peer->hashPubKey))
1810 &peer->hashPubKey)) 1715 {
1811 {
1812#if DEBUG_CORE 1716#if DEBUG_CORE
1813 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, 1717 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Peers are already connected!\n");
1814 "Peers are already connected!\n");
1815#endif 1718#endif
1816 return NULL; 1719 return NULL;
1817 } 1720 }
1818 1721
1819 cm = GNUNET_malloc (sizeof (struct ControlMessage) + 1722 cm = GNUNET_malloc (sizeof (struct ControlMessage) +
1820 sizeof (struct ConnectMessage)); 1723 sizeof (struct ConnectMessage));
1821 msg = (struct ConnectMessage*) &cm[1]; 1724 msg = (struct ConnectMessage *) &cm[1];
1822 msg->header.type = htons (GNUNET_MESSAGE_TYPE_CORE_REQUEST_CONNECT); 1725 msg->header.type = htons (GNUNET_MESSAGE_TYPE_CORE_REQUEST_CONNECT);
1823 msg->header.size = htons (sizeof (struct ConnectMessage)); 1726 msg->header.size = htons (sizeof (struct ConnectMessage));
1824 msg->reserved = htonl (0); 1727 msg->reserved = htonl (0);
1825 msg->peer = *peer; 1728 msg->peer = *peer;
1826 GNUNET_CONTAINER_DLL_insert_tail (h->control_pending_head, 1729 GNUNET_CONTAINER_DLL_insert_tail (h->control_pending_head,
1827 h->control_pending_tail, 1730 h->control_pending_tail, cm);
1828 cm);
1829 ret = GNUNET_malloc (sizeof (struct GNUNET_CORE_PeerRequestHandle)); 1731 ret = GNUNET_malloc (sizeof (struct GNUNET_CORE_PeerRequestHandle));
1830 ret->h = h; 1732 ret->h = h;
1831 ret->cm = cm; 1733 ret->cm = cm;
@@ -1834,8 +1736,7 @@ GNUNET_CORE_peer_request_connect (struct GNUNET_CORE_Handle *h,
1834 cm->cont = &peer_request_connect_cont; 1736 cm->cont = &peer_request_connect_cont;
1835 cm->cont_cls = ret; 1737 cm->cont_cls = ret;
1836#if DEBUG_CORE 1738#if DEBUG_CORE
1837 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1739 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Queueing REQUEST_CONNECT request\n");
1838 "Queueing REQUEST_CONNECT request\n");
1839#endif 1740#endif
1840 trigger_next_request (h, GNUNET_NO); 1741 trigger_next_request (h, GNUNET_NO);
1841 return ret; 1742 return ret;
@@ -1849,18 +1750,18 @@ GNUNET_CORE_peer_request_connect (struct GNUNET_CORE_Handle *h,
1849 * @param req request handle that was returned for the original request 1750 * @param req request handle that was returned for the original request
1850 */ 1751 */
1851void 1752void
1852GNUNET_CORE_peer_request_connect_cancel (struct GNUNET_CORE_PeerRequestHandle *req) 1753GNUNET_CORE_peer_request_connect_cancel (struct GNUNET_CORE_PeerRequestHandle
1754 *req)
1853{ 1755{
1854 struct GNUNET_CORE_Handle *h = req->h; 1756 struct GNUNET_CORE_Handle *h = req->h;
1855 struct ControlMessage *cm = req->cm; 1757 struct ControlMessage *cm = req->cm;
1856 1758
1857#if DEBUG_CORE 1759#if DEBUG_CORE
1858 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1760 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1859 "A CHANGE PREFERENCE request was cancelled!\n"); 1761 "A CHANGE PREFERENCE request was cancelled!\n");
1860#endif 1762#endif
1861 GNUNET_CONTAINER_DLL_remove (h->control_pending_head, 1763 GNUNET_CONTAINER_DLL_remove (h->control_pending_head,
1862 h->control_pending_tail, 1764 h->control_pending_tail, cm);
1863 cm);
1864 GNUNET_free (cm); 1765 GNUNET_free (cm);
1865 GNUNET_free (req); 1766 GNUNET_free (req);
1866} 1767}
@@ -1869,9 +1770,9 @@ GNUNET_CORE_peer_request_connect_cancel (struct GNUNET_CORE_PeerRequestHandle *r
1869/* ****************** GNUNET_CORE_peer_change_preference ******************** */ 1770/* ****************** GNUNET_CORE_peer_change_preference ******************** */
1870 1771
1871 1772
1872struct GNUNET_CORE_InformationRequestContext 1773struct GNUNET_CORE_InformationRequestContext
1873{ 1774{
1874 1775
1875 /** 1776 /**
1876 * Our connection to the service. 1777 * Our connection to the service.
1877 */ 1778 */
@@ -1879,7 +1780,7 @@ struct GNUNET_CORE_InformationRequestContext
1879 1780
1880 /** 1781 /**
1881 * Link to control message, NULL if CM was sent. 1782 * Link to control message, NULL if CM was sent.
1882 */ 1783 */
1883 struct ControlMessage *cm; 1784 struct ControlMessage *cm;
1884 1785
1885 /** 1786 /**
@@ -1896,8 +1797,7 @@ struct GNUNET_CORE_InformationRequestContext
1896 * @param success were we successful? 1797 * @param success were we successful?
1897 */ 1798 */
1898static void 1799static void
1899change_preference_send_continuation (void *cls, 1800change_preference_send_continuation (void *cls, int success)
1900 int success)
1901{ 1801{
1902 struct GNUNET_CORE_InformationRequestContext *irc = cls; 1802 struct GNUNET_CORE_InformationRequestContext *irc = cls;
1903 1803
@@ -1931,61 +1831,58 @@ change_preference_send_continuation (void *cls,
1931 */ 1831 */
1932struct GNUNET_CORE_InformationRequestContext * 1832struct GNUNET_CORE_InformationRequestContext *
1933GNUNET_CORE_peer_change_preference (struct GNUNET_CORE_Handle *h, 1833GNUNET_CORE_peer_change_preference (struct GNUNET_CORE_Handle *h,
1934 const struct GNUNET_PeerIdentity *peer, 1834 const struct GNUNET_PeerIdentity *peer,
1935 struct GNUNET_TIME_Relative timeout, 1835 struct GNUNET_TIME_Relative timeout,
1936 struct GNUNET_BANDWIDTH_Value32NBO bw_out, 1836 struct GNUNET_BANDWIDTH_Value32NBO bw_out,
1937 int32_t amount, 1837 int32_t amount,
1938 uint64_t preference, 1838 uint64_t preference,
1939 GNUNET_CORE_PeerConfigurationInfoCallback info, 1839 GNUNET_CORE_PeerConfigurationInfoCallback
1940 void *info_cls) 1840 info, void *info_cls)
1941{ 1841{
1942 struct GNUNET_CORE_InformationRequestContext *irc; 1842 struct GNUNET_CORE_InformationRequestContext *irc;
1943 struct PeerRecord *pr; 1843 struct PeerRecord *pr;
1944 struct RequestInfoMessage *rim; 1844 struct RequestInfoMessage *rim;
1945 struct ControlMessage *cm; 1845 struct ControlMessage *cm;
1946 1846
1947 pr = GNUNET_CONTAINER_multihashmap_get (h->peers, 1847 pr = GNUNET_CONTAINER_multihashmap_get (h->peers, &peer->hashPubKey);
1948 &peer->hashPubKey);
1949 if (NULL == pr) 1848 if (NULL == pr)
1950 { 1849 {
1951 /* attempt to change preference on peer that is not connected */ 1850 /* attempt to change preference on peer that is not connected */
1952 GNUNET_assert (0); 1851 GNUNET_assert (0);
1953 return NULL; 1852 return NULL;
1954 } 1853 }
1955 if (pr->pcic != NULL) 1854 if (pr->pcic != NULL)
1956 { 1855 {
1957 /* second change before first one is done */ 1856 /* second change before first one is done */
1958 GNUNET_break (0); 1857 GNUNET_break (0);
1959 return NULL; 1858 return NULL;
1960 } 1859 }
1961 irc = GNUNET_malloc (sizeof (struct GNUNET_CORE_InformationRequestContext)); 1860 irc = GNUNET_malloc (sizeof (struct GNUNET_CORE_InformationRequestContext));
1962 irc->h = h; 1861 irc->h = h;
1963 irc->pr = pr; 1862 irc->pr = pr;
1964 cm = GNUNET_malloc (sizeof (struct ControlMessage) + 1863 cm = GNUNET_malloc (sizeof (struct ControlMessage) +
1965 sizeof (struct RequestInfoMessage)); 1864 sizeof (struct RequestInfoMessage));
1966 cm->cont = &change_preference_send_continuation; 1865 cm->cont = &change_preference_send_continuation;
1967 cm->cont_cls = irc; 1866 cm->cont_cls = irc;
1968 irc->cm = cm; 1867 irc->cm = cm;
1969 rim = (struct RequestInfoMessage*) &cm[1]; 1868 rim = (struct RequestInfoMessage *) &cm[1];
1970 rim->header.size = htons (sizeof (struct RequestInfoMessage)); 1869 rim->header.size = htons (sizeof (struct RequestInfoMessage));
1971 rim->header.type = htons (GNUNET_MESSAGE_TYPE_CORE_REQUEST_INFO); 1870 rim->header.type = htons (GNUNET_MESSAGE_TYPE_CORE_REQUEST_INFO);
1972 rim->rim_id = htonl (pr->rim_id = h->rim_id_gen++); 1871 rim->rim_id = htonl (pr->rim_id = h->rim_id_gen++);
1973 rim->limit_outbound = bw_out; 1872 rim->limit_outbound = bw_out;
1974 rim->reserve_inbound = htonl (amount); 1873 rim->reserve_inbound = htonl (amount);
1975 rim->preference_change = GNUNET_htonll(preference); 1874 rim->preference_change = GNUNET_htonll (preference);
1976 rim->peer = *peer; 1875 rim->peer = *peer;
1977#if DEBUG_CORE 1876#if DEBUG_CORE
1978 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1877 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1979 "Queueing CHANGE PREFERENCE request for peer `%s' with RIM %u\n", 1878 "Queueing CHANGE PREFERENCE request for peer `%s' with RIM %u\n",
1980 GNUNET_i2s (peer), 1879 GNUNET_i2s (peer), (unsigned int) pr->rim_id);
1981 (unsigned int) pr->rim_id);
1982#endif 1880#endif
1983 GNUNET_CONTAINER_DLL_insert_tail (h->control_pending_head, 1881 GNUNET_CONTAINER_DLL_insert_tail (h->control_pending_head,
1984 h->control_pending_tail, 1882 h->control_pending_tail, cm);
1985 cm);
1986 pr->pcic = info; 1883 pr->pcic = info;
1987 pr->pcic_cls = info_cls; 1884 pr->pcic_cls = info_cls;
1988 pr->pcic_ptr = irc; /* for free'ing irc */ 1885 pr->pcic_ptr = irc; /* for free'ing irc */
1989 if (NULL != h->client) 1886 if (NULL != h->client)
1990 trigger_next_request (h, GNUNET_NO); 1887 trigger_next_request (h, GNUNET_NO);
1991 return irc; 1888 return irc;
@@ -2004,19 +1901,20 @@ GNUNET_CORE_peer_change_preference (struct GNUNET_CORE_Handle *h,
2004 * @param irc context returned by the original GNUNET_CORE_peer_get_info call 1901 * @param irc context returned by the original GNUNET_CORE_peer_get_info call
2005 */ 1902 */
2006void 1903void
2007GNUNET_CORE_peer_change_preference_cancel (struct GNUNET_CORE_InformationRequestContext *irc) 1904GNUNET_CORE_peer_change_preference_cancel (struct
1905 GNUNET_CORE_InformationRequestContext
1906 *irc)
2008{ 1907{
2009 struct GNUNET_CORE_Handle *h = irc->h; 1908 struct GNUNET_CORE_Handle *h = irc->h;
2010 struct PeerRecord *pr = irc->pr; 1909 struct PeerRecord *pr = irc->pr;
2011 1910
2012 GNUNET_assert (pr->pcic_ptr == irc); 1911 GNUNET_assert (pr->pcic_ptr == irc);
2013 if (irc->cm != NULL) 1912 if (irc->cm != NULL)
2014 { 1913 {
2015 GNUNET_CONTAINER_DLL_remove (h->control_pending_head, 1914 GNUNET_CONTAINER_DLL_remove (h->control_pending_head,
2016 h->control_pending_tail, 1915 h->control_pending_tail, irc->cm);
2017 irc->cm); 1916 GNUNET_free (irc->cm);
2018 GNUNET_free (irc->cm); 1917 }
2019 }
2020 pr->pcic = NULL; 1918 pr->pcic = NULL;
2021 pr->pcic_cls = NULL; 1919 pr->pcic_cls = NULL;
2022 pr->pcic_ptr = NULL; 1920 pr->pcic_ptr = NULL;