diff options
author | Christian Grothoff <christian@grothoff.org> | 2011-08-30 12:57:50 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2011-08-30 12:57:50 +0000 |
commit | 1fd0d8e9c5bafc23a99cec96d105298210733d5c (patch) | |
tree | ee3d8f97ff4e386af06001f2a93793bfdf6a85ca | |
parent | 1fda0ae02a745bc47b830482ae3224320f931497 (diff) | |
download | gnunet-1fd0d8e9c5bafc23a99cec96d105298210733d5c.tar.gz gnunet-1fd0d8e9c5bafc23a99cec96d105298210733d5c.zip |
include message overheads in size request, handle change in message size at queue head
-rw-r--r-- | src/mesh/mesh_api_new.c | 146 |
1 files changed, 69 insertions, 77 deletions
diff --git a/src/mesh/mesh_api_new.c b/src/mesh/mesh_api_new.c index 83ddc8659..e4b407d32 100644 --- a/src/mesh/mesh_api_new.c +++ b/src/mesh/mesh_api_new.c | |||
@@ -512,103 +512,93 @@ send_raw (void *cls, size_t size, void *buf) | |||
512 | { | 512 | { |
513 | struct GNUNET_MESH_Handle *h = cls; | 513 | struct GNUNET_MESH_Handle *h = cls; |
514 | struct GNUNET_MESH_TransmitHandle *q; | 514 | struct GNUNET_MESH_TransmitHandle *q; |
515 | char *cbuf = buf; | ||
516 | size_t ret; | ||
517 | size_t psize; | ||
515 | 518 | ||
516 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "mesh: Send packet() Buffer %u\n", size); | 519 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "mesh: Send packet() Buffer %u\n", size); |
517 | h->th = NULL; | 520 | h->th = NULL; |
518 | if (0 == size || NULL == buf) | 521 | if ( (0 == size) || (NULL == buf) ) |
519 | { | 522 | { |
520 | // FIXME: disconnect, reconnect, retry? | 523 | // FIXME: disconnect, reconnect, retry? |
521 | // do_reconnect (); | 524 | // do_reconnect (); |
522 | return 0; | 525 | return 0; |
523 | } | 526 | } |
524 | q = h->queue_head; | 527 | ret = 0; |
525 | GNUNET_assert (NULL != q); | 528 | while ( (NULL != (q = h->queue_head)) && |
526 | if (sizeof (struct GNUNET_MessageHeader) > size) | 529 | (size >= q->size) ) |
527 | { | ||
528 | GNUNET_break (0); | ||
529 | GNUNET_assert (sizeof (struct GNUNET_MessageHeader) > ntohs (q->data->size)); | ||
530 | h->th = | ||
531 | GNUNET_CLIENT_notify_transmit_ready (h->client, q->size, | ||
532 | GNUNET_TIME_UNIT_FOREVER_REL, | ||
533 | GNUNET_YES, &send_raw, h); | ||
534 | return 0; | ||
535 | } | ||
536 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "mesh: type: %i\n", | ||
537 | ntohs (q->data->type)); | ||
538 | if (NULL == q->data) | ||
539 | { | 530 | { |
540 | GNUNET_assert (NULL != q->notify); | 531 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, |
541 | if (q->target == 0) | 532 | "mesh-api", |
533 | "type: %u\n", | ||
534 | ntohs (q->data->type)); | ||
535 | if (NULL == q->data) | ||
542 | { | 536 | { |
543 | /* multicast */ | 537 | GNUNET_assert (NULL != q->notify); |
544 | struct GNUNET_MESH_Multicast mc; | 538 | if (q->target == 0) |
545 | char *cbuf; | ||
546 | |||
547 | GNUNET_assert (size >= sizeof (mc) + q->size); | ||
548 | cbuf = buf; | ||
549 | q->size = q->notify (q->notify_cls, | ||
550 | size - sizeof (mc), | ||
551 | &cbuf[sizeof(mc)]); | ||
552 | if (q->size == 0) | ||
553 | { | 539 | { |
554 | size = 0; | 540 | /* multicast */ |
541 | struct GNUNET_MESH_Multicast mc; | ||
542 | |||
543 | GNUNET_assert (size >= sizeof (mc) + q->size); | ||
544 | psize = q->notify (q->notify_cls, | ||
545 | size - sizeof (mc), | ||
546 | &cbuf[sizeof(mc)]); | ||
547 | if (psize > 0) | ||
548 | { | ||
549 | mc.header.size = htons (sizeof (mc) + q->size); | ||
550 | mc.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_MULTICAST); | ||
551 | mc.tid = htonl (q->tunnel->tid); | ||
552 | memset (&mc.oid, 0, sizeof (struct GNUNET_PeerIdentity)); /* myself */ | ||
553 | memcpy (cbuf, &mc, sizeof (mc)); | ||
554 | psize = q->size + sizeof (mc); | ||
555 | } | ||
555 | } | 556 | } |
556 | else | 557 | else |
557 | { | 558 | { |
558 | mc.header.size = htons (sizeof (mc) + q->size); | 559 | /* unicast */ |
559 | mc.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_MULTICAST); | 560 | struct GNUNET_MESH_Unicast uc; |
560 | mc.tid = htonl (q->tunnel->tid); | 561 | |
561 | memset (&mc.oid, 0, sizeof (struct GNUNET_PeerIdentity)); /* myself */ | 562 | GNUNET_assert (size >= sizeof (uc) + q->size); |
562 | memcpy (buf, &mc, sizeof (mc)); | 563 | psize = q->notify (q->notify_cls, |
563 | size = q->size + sizeof (mc); | 564 | size - sizeof (uc), |
565 | &cbuf[sizeof(uc)]); | ||
566 | if (psize > 0) | ||
567 | { | ||
568 | uc.header.size = htons (sizeof (uc) + q->size); | ||
569 | uc.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_UNICAST); | ||
570 | uc.tid = htonl (q->tunnel->tid); | ||
571 | memset (&uc.oid, 0, sizeof (struct GNUNET_PeerIdentity)); /* myself */ | ||
572 | GNUNET_PEER_resolve (q->target, &uc.destination); | ||
573 | memcpy (cbuf, &uc, sizeof (uc)); | ||
574 | psize = q->size + sizeof (uc); | ||
575 | } | ||
564 | } | 576 | } |
565 | } | 577 | } |
566 | else | 578 | else |
567 | { | 579 | { |
568 | /* unicast */ | 580 | memcpy (cbuf, q->data, q->size); |
569 | struct GNUNET_MESH_Unicast uc; | 581 | psize = q->size; |
570 | char *cbuf; | ||
571 | |||
572 | GNUNET_assert (size >= sizeof (uc) + q->size); | ||
573 | cbuf = buf; | ||
574 | q->size = q->notify (q->notify_cls, | ||
575 | size - sizeof (uc), | ||
576 | &cbuf[sizeof(uc)]); | ||
577 | if (q->size == 0) | ||
578 | { | ||
579 | size = 0; | ||
580 | } | ||
581 | else | ||
582 | { | ||
583 | uc.header.size = htons (sizeof (uc) + q->size); | ||
584 | uc.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_UNICAST); | ||
585 | uc.tid = htonl (q->tunnel->tid); | ||
586 | memset (&uc.oid, 0, sizeof (struct GNUNET_PeerIdentity)); /* myself */ | ||
587 | GNUNET_PEER_resolve (q->target, &uc.destination); | ||
588 | memcpy (buf, &uc, sizeof (uc)); | ||
589 | size = q->size + sizeof (uc); | ||
590 | } | ||
591 | } | 582 | } |
583 | if (q->timeout_task != GNUNET_SCHEDULER_NO_TASK) | ||
584 | GNUNET_SCHEDULER_cancel (q->timeout_task); | ||
585 | GNUNET_CONTAINER_DLL_remove (h->queue_head, h->queue_tail, q); | ||
586 | GNUNET_free (q); | ||
587 | cbuf += psize; | ||
588 | size -= psize; | ||
589 | ret += psize; | ||
592 | } | 590 | } |
593 | else | ||
594 | { | ||
595 | memcpy (buf, q->data, q->size); | ||
596 | size = q->size; | ||
597 | } | ||
598 | if (q->timeout_task != GNUNET_SCHEDULER_NO_TASK) | ||
599 | GNUNET_SCHEDULER_cancel (q->timeout_task); | ||
600 | GNUNET_CONTAINER_DLL_remove (h->queue_head, h->queue_tail, q); | ||
601 | GNUNET_free (q); | ||
602 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "mesh: size: %u\n", size); | ||
603 | 591 | ||
604 | if (NULL != h->queue_head) | 592 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "mesh: size: %u\n", ret); |
593 | |||
594 | if (NULL != (q = h->queue_head)) | ||
605 | { | 595 | { |
606 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "mesh: next size: %u\n", | 596 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "mesh: next size: %u\n", |
607 | h->queue_head->size); | 597 | q->size); |
608 | h->th = | 598 | h->th = |
609 | GNUNET_CLIENT_notify_transmit_ready (h->client, h->queue_head->size, | 599 | GNUNET_CLIENT_notify_transmit_ready (h->client, q->size, |
610 | GNUNET_TIME_UNIT_FOREVER_REL, | 600 | GNUNET_TIME_UNIT_FOREVER_REL, |
611 | GNUNET_YES, &send_raw, h); | 601 | GNUNET_YES, &send_raw, h); |
612 | } | 602 | } |
613 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "mesh: Send packet() END\n"); | 603 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "mesh: Send packet() END\n"); |
614 | if (GNUNET_NO == h->in_receive) | 604 | if (GNUNET_NO == h->in_receive) |
@@ -617,7 +607,7 @@ send_raw (void *cls, size_t size, void *buf) | |||
617 | GNUNET_CLIENT_receive (h->client, &msg_received, h, | 607 | GNUNET_CLIENT_receive (h->client, &msg_received, h, |
618 | GNUNET_TIME_UNIT_FOREVER_REL); | 608 | GNUNET_TIME_UNIT_FOREVER_REL); |
619 | } | 609 | } |
620 | return size; | 610 | return ret; |
621 | } | 611 | } |
622 | 612 | ||
623 | 613 | ||
@@ -1011,6 +1001,7 @@ GNUNET_MESH_notify_transmit_ready (struct GNUNET_MESH_Tunnel *tunnel, int cork, | |||
1011 | void *notify_cls) | 1001 | void *notify_cls) |
1012 | { | 1002 | { |
1013 | struct GNUNET_MESH_TransmitHandle *q; | 1003 | struct GNUNET_MESH_TransmitHandle *q; |
1004 | size_t overhead; | ||
1014 | 1005 | ||
1015 | if (get_queue_length (tunnel->mesh) >= tunnel->mesh->max_queue_size) | 1006 | if (get_queue_length (tunnel->mesh) >= tunnel->mesh->max_queue_size) |
1016 | return NULL; /* queue full */ | 1007 | return NULL; /* queue full */ |
@@ -1020,7 +1011,8 @@ GNUNET_MESH_notify_transmit_ready (struct GNUNET_MESH_Tunnel *tunnel, int cork, | |||
1020 | q->priority = priority; | 1011 | q->priority = priority; |
1021 | q->timeout = GNUNET_TIME_relative_to_absolute (maxdelay); | 1012 | q->timeout = GNUNET_TIME_relative_to_absolute (maxdelay); |
1022 | q->target = GNUNET_PEER_intern (target); | 1013 | q->target = GNUNET_PEER_intern (target); |
1023 | q->size = notify_size; | 1014 | overhead = (NULL == target) ? sizeof (struct GNUNET_MESH_Multicast) : sizeof (struct GNUNET_MESH_Unicast); |
1015 | q->size = notify_size + overhead; | ||
1024 | q->notify = notify; | 1016 | q->notify = notify; |
1025 | q->notify_cls = notify_cls; | 1017 | q->notify_cls = notify_cls; |
1026 | queue_transmit_handle (tunnel->mesh, q); | 1018 | queue_transmit_handle (tunnel->mesh, q); |
@@ -1039,8 +1031,8 @@ GNUNET_MESH_notify_transmit_ready_cancel (struct GNUNET_MESH_TransmitHandle *th) | |||
1039 | struct GNUNET_MESH_Handle *mesh; | 1031 | struct GNUNET_MESH_Handle *mesh; |
1040 | 1032 | ||
1041 | mesh = th->tunnel->mesh; | 1033 | mesh = th->tunnel->mesh; |
1042 | if (q->timeout_task != GNUNET_SCHEDULER_NO_TASK) | 1034 | if (th->timeout_task != GNUNET_SCHEDULER_NO_TASK) |
1043 | GNUNET_SCHEDULER_cancel (q->timeout_task); | 1035 | GNUNET_SCHEDULER_cancel (th->timeout_task); |
1044 | GNUNET_CONTAINER_DLL_remove (mesh->queue_head, | 1036 | GNUNET_CONTAINER_DLL_remove (mesh->queue_head, |
1045 | mesh->queue_tail, | 1037 | mesh->queue_tail, |
1046 | th); | 1038 | th); |