aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2011-08-30 12:57:50 +0000
committerChristian Grothoff <christian@grothoff.org>2011-08-30 12:57:50 +0000
commit1fd0d8e9c5bafc23a99cec96d105298210733d5c (patch)
treeee3d8f97ff4e386af06001f2a93793bfdf6a85ca
parent1fda0ae02a745bc47b830482ae3224320f931497 (diff)
downloadgnunet-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.c146
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);