aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBart Polot <bart@net.in.tum.de>2013-08-25 14:39:27 +0000
committerBart Polot <bart@net.in.tum.de>2013-08-25 14:39:27 +0000
commit0c1cae8b83245547b43344bec3dd383284026379 (patch)
treeb70bb02dc1d520544da87593a2f7984cebce35cd /src
parent35552c0580f234b24bfeba9ed70b969d0a4665ee (diff)
downloadgnunet-0c1cae8b83245547b43344bec3dd383284026379.tar.gz
gnunet-0c1cae8b83245547b43344bec3dd383284026379.zip
- make a generic ack function
Diffstat (limited to 'src')
-rw-r--r--src/mesh/gnunet-service-mesh-enc.c370
1 files changed, 210 insertions, 160 deletions
diff --git a/src/mesh/gnunet-service-mesh-enc.c b/src/mesh/gnunet-service-mesh-enc.c
index 22849bc6b..41d4f570e 100644
--- a/src/mesh/gnunet-service-mesh-enc.c
+++ b/src/mesh/gnunet-service-mesh-enc.c
@@ -1478,11 +1478,13 @@ send_local_channel_destroy (struct MeshChannel *ch, int fwd)
1478 1478
1479 1479
1480/** 1480/**
1481 * Build a local ACK message and send it to a local client. 1481 * Build a local ACK message and send it to a local client, if needed.
1482 *
1483 * If the client was already allowed to send data, do nothing.
1482 * 1484 *
1483 * @param ch Channel on which to send the ACK. 1485 * @param ch Channel on which to send the ACK.
1484 * @param c Client to whom send the ACK. 1486 * @param c Client to whom send the ACK.
1485 * @param fwd Set to GNUNET_YES for FWD ACK (dest->owner) 1487 * @param fwd Set to GNUNET_YES for FWD ACK (dest->root)
1486 */ 1488 */
1487static void 1489static void
1488send_local_ack (struct MeshChannel *ch, int fwd) 1490send_local_ack (struct MeshChannel *ch, int fwd)
@@ -1491,7 +1493,14 @@ send_local_ack (struct MeshChannel *ch, int fwd)
1491 struct MeshChannelReliability *rel; 1493 struct MeshChannelReliability *rel;
1492 struct MeshClient *c; 1494 struct MeshClient *c;
1493 1495
1494 c = fwd ? ch->root : ch->dest; 1496 c = fwd ? ch->root : ch->dest;
1497 rel = fwd ? ch->root_rel : ch->dest_rel;
1498
1499 if (GNUNET_YES == rel->client_ready)
1500 return; /* don't send double ACKs to client */
1501
1502 rel->client_ready = GNUNET_YES;
1503
1495 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1504 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1496 "send local %s ack on %s:%X towards %p\n", 1505 "send local %s ack on %s:%X towards %p\n",
1497 fwd ? "FWD" : "BCK", peer2s (ch->t->peer), ch->gid, c); 1506 fwd ? "FWD" : "BCK", peer2s (ch->t->peer), ch->gid, c);
@@ -1510,8 +1519,7 @@ send_local_ack (struct MeshChannel *ch, int fwd)
1510 c->handle, 1519 c->handle,
1511 &msg.header, 1520 &msg.header,
1512 GNUNET_NO); 1521 GNUNET_NO);
1513 rel = fwd ? ch->root_rel : ch->dest_rel; 1522
1514 rel->client_ready = GNUNET_YES;
1515} 1523}
1516 1524
1517 1525
@@ -3084,7 +3092,7 @@ tunnel_notify_connection_broken (struct MeshTunnel2* t,
3084 3092
3085 3093
3086/** 3094/**
3087 * Send an end-to-end FWD ACK message for the most recent in-sequence payload. 3095 * Send an end-to-end ACK message for the most recent in-sequence payload.
3088 * 3096 *
3089 * If channel is not reliable, do nothing. 3097 * If channel is not reliable, do nothing.
3090 * 3098 *
@@ -3143,10 +3151,11 @@ channel_send_data_ack (struct MeshChannel *ch, int fwd)
3143 * the ACK itself goes "back" (dest->root). 3151 * the ACK itself goes "back" (dest->root).
3144 * 3152 *
3145 * @param c Connection on which to send the ACK. 3153 * @param c Connection on which to send the ACK.
3154 * @param buffer How much space free to advertise?
3146 * @param fwd Is this FWD ACK? (Going dest->owner) 3155 * @param fwd Is this FWD ACK? (Going dest->owner)
3147 */ 3156 */
3148static void 3157static void
3149connection_send_ack (struct MeshConnection *c, int fwd) 3158connection_send_ack (struct MeshConnection *c, unsigned int buffer, int fwd)
3150{ 3159{
3151 struct MeshFlowControl *next_fc; 3160 struct MeshFlowControl *next_fc;
3152 struct MeshFlowControl *prev_fc; 3161 struct MeshFlowControl *prev_fc;
@@ -3233,6 +3242,55 @@ channel_send_client_to_tid (struct MeshChannel *ch,
3233 &copy->header, GNUNET_NO); 3242 &copy->header, GNUNET_NO);
3234} 3243}
3235 3244
3245
3246/**
3247 * We have received a message out of order, or the client is not ready.
3248 * Buffer it until we receive an ACK from the client or the missing
3249 * message from the channel.
3250 *
3251 * @param msg Message to buffer (MUST be of type MESH_DATA).
3252 * @param rel Reliability data to the corresponding direction.
3253 */
3254static void
3255channel_rel_add_buffered_data (const struct GNUNET_MESH_Data *msg,
3256 struct MeshChannelReliability *rel)
3257{
3258 struct MeshReliableMessage *copy;
3259 struct MeshReliableMessage *prev;
3260 uint32_t mid;
3261 uint16_t size;
3262
3263 size = ntohs (msg->header.size);
3264 mid = ntohl (msg->mid);
3265
3266 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "add_buffered_data %u\n", mid);
3267
3268 copy = GNUNET_malloc (sizeof (*copy) + size);
3269 copy->mid = mid;
3270 copy->rel = rel;
3271 memcpy (&copy[1], msg, size);
3272
3273 rel->n_recv++;
3274
3275 // FIXME do something better than O(n), although n < 64...
3276 // FIXME start from the end (most messages are the latest ones)
3277 for (prev = rel->head_recv; NULL != prev; prev = prev->next)
3278 {
3279 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " prev %u\n", prev->mid);
3280 if (GMC_is_pid_bigger (prev->mid, mid))
3281 {
3282 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " bingo!\n");
3283 GNUNET_CONTAINER_DLL_insert_before (rel->head_recv, rel->tail_recv,
3284 prev, copy);
3285 return;
3286 }
3287 }
3288 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " insert at tail!\n");
3289 GNUNET_CONTAINER_DLL_insert_tail (rel->head_recv, rel->tail_recv, copy);
3290 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "add_buffered_data END\n");
3291}
3292
3293
3236/** 3294/**
3237 * Modify the data message ID from global to local and send to client. 3295 * Modify the data message ID from global to local and send to client.
3238 * 3296 *
@@ -3246,9 +3304,19 @@ channel_send_client_data (struct MeshChannel *ch,
3246 int fwd) 3304 int fwd)
3247{ 3305{
3248 if (fwd) 3306 if (fwd)
3249 channel_send_client_to_tid (ch, msg, ch->dest, ch->lid_dest); 3307 {
3308 if (ch->dest_rel->client_ready)
3309 channel_send_client_to_tid (ch, msg, ch->dest, ch->lid_dest);
3310 else
3311 channel_rel_add_buffered_data (msg, ch->dest_rel);
3312 }
3250 else 3313 else
3251 channel_send_client_to_tid (ch, msg, ch->root, ch->lid_root); 3314 {
3315 if (ch->root_rel->client_ready)
3316 channel_send_client_to_tid (ch, msg, ch->root, ch->lid_root);
3317 else
3318 channel_rel_add_buffered_data (msg, ch->root_rel);
3319 }
3252} 3320}
3253 3321
3254 3322
@@ -3308,54 +3376,6 @@ channel_send_client_buffered_data (struct MeshChannel *ch,
3308 3376
3309 3377
3310/** 3378/**
3311 * We have received a message out of order, or the client is not ready.
3312 * Buffer it until we receive an ACK from the client or the missing
3313 * message from the channel.
3314 *
3315 * @param msg Message to buffer (MUST be of type MESH_DATA).
3316 * @param rel Reliability data to the corresponding direction.
3317 */
3318static void
3319channel_rel_add_buffered_data (const struct GNUNET_MESH_Data *msg,
3320 struct MeshChannelReliability *rel)
3321{
3322 struct MeshReliableMessage *copy;
3323 struct MeshReliableMessage *prev;
3324 uint32_t mid;
3325 uint16_t size;
3326
3327 size = ntohs (msg->header.size);
3328 mid = ntohl (msg->mid);
3329
3330 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "add_buffered_data %u\n", mid);
3331
3332 copy = GNUNET_malloc (sizeof (*copy) + size);
3333 copy->mid = mid;
3334 copy->rel = rel;
3335 memcpy (&copy[1], msg, size);
3336
3337 rel->n_recv++;
3338
3339 // FIXME do something better than O(n), although n < 64...
3340 // FIXME start from the end (most messages are the latest ones)
3341 for (prev = rel->head_recv; NULL != prev; prev = prev->next)
3342 {
3343 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " prev %u\n", prev->mid);
3344 if (GMC_is_pid_bigger (prev->mid, mid))
3345 {
3346 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " bingo!\n");
3347 GNUNET_CONTAINER_DLL_insert_before (rel->head_recv, rel->tail_recv,
3348 prev, copy);
3349 return;
3350 }
3351 }
3352 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " insert at tail!\n");
3353 GNUNET_CONTAINER_DLL_insert_tail (rel->head_recv, rel->tail_recv, copy);
3354 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "add_buffered_data END\n");
3355}
3356
3357
3358/**
3359 * Destroy a reliable message after it has been acknowledged, either by 3379 * Destroy a reliable message after it has been acknowledged, either by
3360 * direct mid ACK or bitfield. Updates the appropriate data structures and 3380 * direct mid ACK or bitfield. Updates the appropriate data structures and
3361 * timers and frees all memory. 3381 * timers and frees all memory.
@@ -3569,37 +3589,6 @@ channel_retransmit_message (void *cls,
3569 3589
3570 3590
3571/** 3591/**
3572 * Send an ACK to a client if needed.
3573 *
3574 * @param ch Channel this is regarding.
3575 * @param fwd Is this about fwd traffic? (ACK goes the opposite direction).
3576 */
3577static void
3578channel_send_client_ack (struct MeshChannel *ch, int fwd)
3579{
3580 struct MeshChannelReliability *rel;
3581
3582 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3583 "Channel send client %s ack on %s:%X\n",
3584 fwd ? "FWD" : "BCK", peer2s (ch->t->peer), ch->gid);
3585
3586 /* Check for buffer space */
3587 if (0 >= tunnel_get_buffer (ch->t, fwd))
3588 {
3589 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " No buffer :(\n");
3590 return;
3591 }
3592
3593 /* Send ACK (fwd indicates traffic to be ACK'd) to client */
3594 rel = fwd ? ch->root_rel : ch->dest_rel;
3595 if (GNUNET_NO == rel->client_ready)
3596 send_local_ack (ch, fwd);
3597 else
3598 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Client was ready\n");
3599}
3600
3601
3602/**
3603 * Send ACK on one or more connections due to buffer space to the client. 3592 * Send ACK on one or more connections due to buffer space to the client.
3604 * 3593 *
3605 * Iterates all connections of the tunnel and sends ACKs appropriately. 3594 * Iterates all connections of the tunnel and sends ACKs appropriately.
@@ -3608,30 +3597,22 @@ channel_send_client_ack (struct MeshChannel *ch, int fwd)
3608 * @param fwd Is this in for FWD traffic? (ACK goes dest->root) 3597 * @param fwd Is this in for FWD traffic? (ACK goes dest->root)
3609 */ 3598 */
3610static void 3599static void
3611channel_send_connection_ack (struct MeshChannel *ch, int fwd) 3600channel_send_connections_ack (struct MeshChannel *ch,
3601 unsigned int buffer,
3602 int fwd)
3612{ 3603{
3613 struct MeshTunnel2 *t = ch->t; 3604 struct MeshTunnel2 *t = ch->t;
3614 struct MeshConnection *c; 3605 struct MeshConnection *c;
3615 struct MeshFlowControl *fc; 3606 struct MeshFlowControl *fc;
3616 struct MeshChannelReliability *rel;
3617 uint32_t allowed; 3607 uint32_t allowed;
3618 uint32_t to_allow; 3608 uint32_t to_allow;
3609 uint32_t allow_per_connection;
3619 unsigned int cs; 3610 unsigned int cs;
3620 uint32_t buffer;
3621 3611
3622 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 3612 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3623 "Channel send connection %s ack on %s:%X\n", 3613 "Channel send connection %s ack on %s:%X\n",
3624 fwd ? "FWD" : "BCK", peer2s (ch->t->peer), ch->gid); 3614 fwd ? "FWD" : "BCK", peer2s (ch->t->peer), ch->gid);
3625 3615
3626 /* Check */
3627 rel = fwd ? ch->root_rel : ch->dest_rel;
3628 if (NULL == rel)
3629 {
3630 GNUNET_break (0);
3631 return;
3632 }
3633 buffer = 64 - rel->n_sent;
3634
3635 /* Count connections, how many messages are already allowed */ 3616 /* Count connections, how many messages are already allowed */
3636 for (cs = 0, allowed = 0, c = t->connection_head; NULL != c; c = c->next) 3617 for (cs = 0, allowed = 0, c = t->connection_head; NULL != c; c = c->next)
3637 { 3618 {
@@ -3654,22 +3635,66 @@ channel_send_connection_ack (struct MeshChannel *ch, int fwd)
3654 3635
3655 /* Authorize connections to send more data */ 3636 /* Authorize connections to send more data */
3656 to_allow = buffer - allowed; 3637 to_allow = buffer - allowed;
3638
3657 for (c = t->connection_head; NULL != c && to_allow > 0; c = c->next) 3639 for (c = t->connection_head; NULL != c && to_allow > 0; c = c->next)
3658 { 3640 {
3641 allow_per_connection = to_allow/cs;
3642 to_allow -= allow_per_connection;
3643 cs--;
3659 fc = fwd ? &c->fwd_fc : &c->bck_fc; 3644 fc = fwd ? &c->fwd_fc : &c->bck_fc;
3660 if (fc->last_ack_sent - fc->last_pid_recv > 64 / 3) 3645 if (fc->last_ack_sent - fc->last_pid_recv > 64 / 3)
3661 { 3646 {
3662 continue; 3647 continue;
3663 } 3648 }
3664 connection_send_ack (c, fwd); 3649 connection_send_ack (c, allow_per_connection, fwd);
3665 to_allow--;
3666 } 3650 }
3667 3651
3652 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3653 "Channel send connection %s ack on %s:%X\n",
3654 fwd ? "FWD" : "BCK", peer2s (ch->t->peer), ch->gid);
3668 GNUNET_break (to_allow == 0); 3655 GNUNET_break (to_allow == 0);
3669} 3656}
3670 3657
3671 3658
3672/** 3659/**
3660 * Get free buffer space towards the client on a specific channel.
3661 *
3662 * @param ch Channel.
3663 * @param fwd Is query about FWD traffic?
3664 *
3665 * @return Free buffer space [0 - 64]
3666 */
3667static unsigned int
3668channel_get_buffer (struct MeshChannel *ch, int fwd)
3669{
3670 struct MeshChannelReliability *rel;
3671
3672 rel = fwd ? ch->dest_rel : ch->root_rel;
3673
3674 return (64 - rel->n_recv);
3675}
3676
3677
3678/**
3679 * Get free buffer space in a connection.
3680 *
3681 * @param c Connection.
3682 * @param fwd Is query about FWD traffic?
3683 *
3684 * @return Free buffer space [0 - max_msgs_queue/max_connections]
3685 */
3686static unsigned int
3687connection_get_buffer (struct MeshConnection *c, int fwd)
3688{
3689 struct MeshFlowControl *fc;
3690
3691 fc = fwd ? &c->fwd_fc : &c->bck_fc;
3692
3693 return (fc->queue_max - fc->queue_n);
3694}
3695
3696
3697/**
3673 * Send an ACK on the appropriate connection/channel, depending on 3698 * Send an ACK on the appropriate connection/channel, depending on
3674 * the direction and the position of the peer. 3699 * the direction and the position of the peer.
3675 * 3700 *
@@ -3680,12 +3705,36 @@ channel_send_connection_ack (struct MeshChannel *ch, int fwd)
3680static void 3705static void
3681send_ack (struct MeshConnection *c, struct MeshChannel *ch, int fwd) 3706send_ack (struct MeshConnection *c, struct MeshChannel *ch, int fwd)
3682{ 3707{
3683 if (NULL == ch) 3708 unsigned int buffer;
3709
3710 if (NULL == c || connection_is_terminal (c, fwd))
3684 { 3711 {
3685 connection_send_ack (c, fwd); 3712 GNUNET_assert (NULL != ch);
3686 return; 3713 buffer = channel_get_buffer (ch, fwd);
3714 }
3715 else
3716 {
3717 GNUNET_assert (NULL != c);
3718 buffer = connection_get_buffer (c, fwd);
3719 }
3720
3721 if (NULL == c)
3722 {
3723 GNUNET_assert (NULL != ch);
3724 channel_send_connections_ack (ch, buffer, fwd);
3725 }
3726 else if (connection_is_origin (c, fwd))
3727 {
3728 if (0 < buffer)
3729 {
3730 GNUNET_assert (NULL != ch);
3731 send_local_ack (ch, fwd);
3732 }
3733 }
3734 else
3735 {
3736 connection_send_ack (c, buffer, fwd);
3687 } 3737 }
3688 channel_send_connection_ack (ch, fwd);
3689} 3738}
3690 3739
3691 3740
@@ -4689,10 +4738,7 @@ queue_send (void *cls, size_t size, void *buf)
4689 case GNUNET_MESSAGE_TYPE_MESH_BCK: 4738 case GNUNET_MESSAGE_TYPE_MESH_BCK:
4690 pid = ntohl ( ((struct GNUNET_MESH_Encrypted *) buf)->pid ); 4739 pid = ntohl ( ((struct GNUNET_MESH_Encrypted *) buf)->pid );
4691 fc->last_pid_sent = pid; 4740 fc->last_pid_sent = pid;
4692 if (NULL != ch) 4741 send_ack (c, ch, fwd);
4693 channel_send_client_ack (ch, fwd);
4694 else
4695 connection_send_ack (c, fwd);
4696 break; 4742 break;
4697 default: 4743 default:
4698 break; 4744 break;
@@ -4875,10 +4921,9 @@ queue_add (void *cls, uint16_t type, size_t size,
4875 * @param message Unencryted data message. 4921 * @param message Unencryted data message.
4876 * @param fwd Is this FWD traffic? GNUNET_YES : GNUNET_NO; 4922 * @param fwd Is this FWD traffic? GNUNET_YES : GNUNET_NO;
4877 * 4923 *
4878 * @return GNUNET_OK to keep the connection open, 4924 * @return channel which this message was on.
4879 * GNUNET_SYSERR to close it (signal serious error)
4880 */ 4925 */
4881static int 4926static struct MeshChannel *
4882handle_data (struct MeshTunnel2 *t, const struct GNUNET_MESH_Data *msg, int fwd) 4927handle_data (struct MeshTunnel2 *t, const struct GNUNET_MESH_Data *msg, int fwd)
4883{ 4928{
4884 struct MeshChannelReliability *rel; 4929 struct MeshChannelReliability *rel;
@@ -4895,7 +4940,7 @@ handle_data (struct MeshTunnel2 *t, const struct GNUNET_MESH_Data *msg, int fwd)
4895 sizeof (struct GNUNET_MessageHeader)) 4940 sizeof (struct GNUNET_MessageHeader))
4896 { 4941 {
4897 GNUNET_break (0); 4942 GNUNET_break (0);
4898 return GNUNET_OK; 4943 return NULL;
4899 } 4944 }
4900 type = ntohs (msg->header.type); 4945 type = ntohs (msg->header.type);
4901 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "got a %s message\n", 4946 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "got a %s message\n",
@@ -4909,7 +4954,7 @@ handle_data (struct MeshTunnel2 *t, const struct GNUNET_MESH_Data *msg, int fwd)
4909 { 4954 {
4910 GNUNET_STATISTICS_update (stats, "# data on unknown channel", 1, GNUNET_NO); 4955 GNUNET_STATISTICS_update (stats, "# data on unknown channel", 1, GNUNET_NO);
4911 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "WARNING channel unknown\n"); 4956 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "WARNING channel unknown\n");
4912 return GNUNET_OK; 4957 return NULL;
4913 } 4958 }
4914 4959
4915 /* Initialize FWD/BCK data */ 4960 /* Initialize FWD/BCK data */
@@ -4919,7 +4964,7 @@ handle_data (struct MeshTunnel2 *t, const struct GNUNET_MESH_Data *msg, int fwd)
4919 if (NULL == c) 4964 if (NULL == c)
4920 { 4965 {
4921 GNUNET_break (0); 4966 GNUNET_break (0);
4922 return GNUNET_OK; 4967 return NULL;
4923 } 4968 }
4924 4969
4925 tunnel_change_state (t, MESH_TUNNEL_READY); 4970 tunnel_change_state (t, MESH_TUNNEL_READY);
@@ -4966,7 +5011,7 @@ handle_data (struct MeshTunnel2 *t, const struct GNUNET_MESH_Data *msg, int fwd)
4966 } 5011 }
4967 5012
4968 channel_send_data_ack (ch, fwd); 5013 channel_send_data_ack (ch, fwd);
4969 return GNUNET_OK; 5014 return ch;
4970} 5015}
4971 5016
4972/** 5017/**
@@ -4976,10 +5021,9 @@ handle_data (struct MeshTunnel2 *t, const struct GNUNET_MESH_Data *msg, int fwd)
4976 * @param message Data message. 5021 * @param message Data message.
4977 * @param fwd Is this a fwd ACK? (dest->orig) 5022 * @param fwd Is this a fwd ACK? (dest->orig)
4978 * 5023 *
4979 * @return GNUNET_OK to keep the connection open, 5024 * @return channel this message was on.
4980 * GNUNET_SYSERR to close it (signal serious error)
4981 */ 5025 */
4982static int 5026static struct MeshChannel *
4983handle_data_ack (struct MeshTunnel2 *t, 5027handle_data_ack (struct MeshTunnel2 *t,
4984 const struct GNUNET_MESH_DataACK *msg, int fwd) 5028 const struct GNUNET_MESH_DataACK *msg, int fwd)
4985{ 5029{
@@ -4998,7 +5042,7 @@ handle_data_ack (struct MeshTunnel2 *t,
4998 if (NULL == ch) 5042 if (NULL == ch)
4999 { 5043 {
5000 GNUNET_STATISTICS_update (stats, "# ack on unknown channel", 1, GNUNET_NO); 5044 GNUNET_STATISTICS_update (stats, "# ack on unknown channel", 1, GNUNET_NO);
5001 return GNUNET_OK; 5045 return NULL;
5002 } 5046 }
5003 ack = ntohl (msg->mid); 5047 ack = ntohl (msg->mid);
5004 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "!!! %s ACK %u\n", 5048 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "!!! %s ACK %u\n",
@@ -5014,7 +5058,8 @@ handle_data_ack (struct MeshTunnel2 *t,
5014 } 5058 }
5015 if (NULL == rel) 5059 if (NULL == rel)
5016 { 5060 {
5017 return GNUNET_OK; 5061 GNUNET_break (0);
5062 return NULL;
5018 } 5063 }
5019 5064
5020 for (work = GNUNET_NO, copy = rel->head_sent; copy != NULL; copy = next) 5065 for (work = GNUNET_NO, copy = rel->head_sent; copy != NULL; copy = next)
@@ -5062,7 +5107,7 @@ handle_data_ack (struct MeshTunnel2 *t,
5062 else 5107 else
5063 GNUNET_break (0); 5108 GNUNET_break (0);
5064 } 5109 }
5065 return GNUNET_OK; 5110 return ch;
5066} 5111}
5067 5112
5068 5113
@@ -5363,10 +5408,9 @@ handle_mesh_connection_destroy (void *cls,
5363 * @param msg Message. 5408 * @param msg Message.
5364 * @param fwd Is this FWD traffic? GNUNET_YES : GNUNET_NO; 5409 * @param fwd Is this FWD traffic? GNUNET_YES : GNUNET_NO;
5365 * 5410 *
5366 * @return GNUNET_OK to keep the connection open, 5411 * @return channel this message was on.
5367 * GNUNET_SYSERR to close it (signal serious error)
5368 */ 5412 */
5369static int 5413static struct MeshChannel *
5370handle_channel_create (struct MeshTunnel2 *t, 5414handle_channel_create (struct MeshTunnel2 *t,
5371 struct GNUNET_MESH_ChannelCreate *msg, 5415 struct GNUNET_MESH_ChannelCreate *msg,
5372 int fwd) 5416 int fwd)
@@ -5381,7 +5425,7 @@ handle_channel_create (struct MeshTunnel2 *t,
5381 if (ntohs (msg->header.size) != sizeof (struct GNUNET_MESH_ChannelCreate)) 5425 if (ntohs (msg->header.size) != sizeof (struct GNUNET_MESH_ChannelCreate))
5382 { 5426 {
5383 GNUNET_break_op (0); 5427 GNUNET_break_op (0);
5384 return GNUNET_OK; 5428 return NULL;
5385 } 5429 }
5386 5430
5387 /* Check if channel exists */ 5431 /* Check if channel exists */
@@ -5395,7 +5439,7 @@ handle_channel_create (struct MeshTunnel2 *t,
5395 { 5439 {
5396 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " duplicate CC!!\n"); 5440 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " duplicate CC!!\n");
5397 channel_send_ack (ch, !fwd); 5441 channel_send_ack (ch, !fwd);
5398 return GNUNET_OK; 5442 return NULL;
5399 } 5443 }
5400 } 5444 }
5401 else 5445 else
@@ -5413,7 +5457,8 @@ handle_channel_create (struct MeshTunnel2 *t,
5413 { 5457 {
5414 /* TODO send reject */ 5458 /* TODO send reject */
5415 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " no client has port registered\n"); 5459 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " no client has port registered\n");
5416 return GNUNET_OK; 5460 /* TODO free ch */
5461 return NULL;
5417 } 5462 }
5418 5463
5419 channel_add_client (ch, c); 5464 channel_add_client (ch, c);
@@ -5423,7 +5468,7 @@ handle_channel_create (struct MeshTunnel2 *t,
5423 send_local_channel_create (ch); 5468 send_local_channel_create (ch);
5424 channel_send_ack (ch, !fwd); 5469 channel_send_ack (ch, !fwd);
5425 5470
5426 return GNUNET_OK; 5471 return ch;
5427} 5472}
5428 5473
5429 5474
@@ -5434,10 +5479,9 @@ handle_channel_create (struct MeshTunnel2 *t,
5434 * @param msg Message. 5479 * @param msg Message.
5435 * @param fwd Is this FWD traffic? GNUNET_YES : GNUNET_NO; 5480 * @param fwd Is this FWD traffic? GNUNET_YES : GNUNET_NO;
5436 * 5481 *
5437 * @return GNUNET_OK to keep the connection open, 5482 * @return channel this message was on.
5438 * GNUNET_SYSERR to close it (signal serious error)
5439 */ 5483 */
5440static int 5484static struct MeshChannel *
5441handle_channel_ack (struct MeshTunnel2 *t, 5485handle_channel_ack (struct MeshTunnel2 *t,
5442 struct GNUNET_MESH_ChannelManage *msg, 5486 struct GNUNET_MESH_ChannelManage *msg,
5443 int fwd) 5487 int fwd)
@@ -5450,7 +5494,7 @@ handle_channel_ack (struct MeshTunnel2 *t,
5450 if (ntohs (msg->header.size) != sizeof (struct GNUNET_MESH_ChannelManage)) 5494 if (ntohs (msg->header.size) != sizeof (struct GNUNET_MESH_ChannelManage))
5451 { 5495 {
5452 GNUNET_break_op (0); 5496 GNUNET_break_op (0);
5453 return GNUNET_OK; 5497 return NULL;
5454 } 5498 }
5455 5499
5456 /* Check if channel exists */ 5500 /* Check if channel exists */
@@ -5460,11 +5504,11 @@ handle_channel_ack (struct MeshTunnel2 *t,
5460 { 5504 {
5461 GNUNET_break_op (0); 5505 GNUNET_break_op (0);
5462 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " channel %u unknown!!\n", chid); 5506 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " channel %u unknown!!\n", chid);
5463 return GNUNET_OK; 5507 return NULL;
5464 } 5508 }
5465 5509
5466 channel_confirm (ch, !fwd); 5510 channel_confirm (ch, !fwd);
5467 return GNUNET_OK; 5511 return ch;
5468} 5512}
5469 5513
5470 5514
@@ -5475,10 +5519,9 @@ handle_channel_ack (struct MeshTunnel2 *t,
5475 * @param msg Message. 5519 * @param msg Message.
5476 * @param fwd Is this FWD traffic? GNUNET_YES : GNUNET_NO; 5520 * @param fwd Is this FWD traffic? GNUNET_YES : GNUNET_NO;
5477 * 5521 *
5478 * @return GNUNET_OK to keep the connection open, 5522 * @return channel this message was on.
5479 * GNUNET_SYSERR to close it (signal serious error)
5480 */ 5523 */
5481static int 5524static struct MeshChannel *
5482handle_channel_destroy (struct MeshTunnel2 *t, 5525handle_channel_destroy (struct MeshTunnel2 *t,
5483 struct GNUNET_MESH_ChannelManage *msg, 5526 struct GNUNET_MESH_ChannelManage *msg,
5484 int fwd) 5527 int fwd)
@@ -5490,7 +5533,7 @@ handle_channel_destroy (struct MeshTunnel2 *t,
5490 if (ntohs (msg->header.size) != sizeof (struct GNUNET_MESH_ChannelManage)) 5533 if (ntohs (msg->header.size) != sizeof (struct GNUNET_MESH_ChannelManage))
5491 { 5534 {
5492 GNUNET_break_op (0); 5535 GNUNET_break_op (0);
5493 return GNUNET_OK; 5536 return NULL;
5494 } 5537 }
5495 5538
5496 /* Check if channel exists */ 5539 /* Check if channel exists */
@@ -5499,13 +5542,13 @@ handle_channel_destroy (struct MeshTunnel2 *t,
5499 if (NULL == ch) 5542 if (NULL == ch)
5500 { 5543 {
5501 /* Probably a retransmission, safe to ignore */ 5544 /* Probably a retransmission, safe to ignore */
5502 return GNUNET_OK; 5545 return NULL;
5503 } 5546 }
5504 5547
5505 send_local_channel_destroy (ch, fwd); 5548 send_local_channel_destroy (ch, fwd);
5506 channel_destroy (ch); 5549 channel_destroy (ch);
5507 5550
5508 return GNUNET_OK; 5551 return ch;
5509} 5552}
5510 5553
5511 5554
@@ -5595,7 +5638,7 @@ handle_mesh_encrypted (const struct GNUNET_PeerIdentity *peer,
5595 size_t dsize = size - sizeof (struct GNUNET_MESH_Encrypted); 5638 size_t dsize = size - sizeof (struct GNUNET_MESH_Encrypted);
5596 char cbuf[dsize]; 5639 char cbuf[dsize];
5597 struct GNUNET_MessageHeader *msgh; 5640 struct GNUNET_MessageHeader *msgh;
5598 int r; 5641 struct MeshChannel *ch;
5599 5642
5600 /* TODO signature verification */ 5643 /* TODO signature verification */
5601 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " message for us!\n"); 5644 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " message for us!\n");
@@ -5608,39 +5651,40 @@ handle_mesh_encrypted (const struct GNUNET_PeerIdentity *peer,
5608 { 5651 {
5609 case GNUNET_MESSAGE_TYPE_MESH_DATA: 5652 case GNUNET_MESSAGE_TYPE_MESH_DATA:
5610 /* Don't send hop ACK, wait for client to ACK */ 5653 /* Don't send hop ACK, wait for client to ACK */
5611 return handle_data (t, (struct GNUNET_MESH_Data *) msgh, fwd); 5654 ch = handle_data (t, (struct GNUNET_MESH_Data *) msgh, fwd);
5655 break;
5612 5656
5613 case GNUNET_MESSAGE_TYPE_MESH_DATA_ACK: 5657 case GNUNET_MESSAGE_TYPE_MESH_DATA_ACK:
5614 r = handle_data_ack (t, (struct GNUNET_MESH_DataACK *) msgh, fwd); 5658 ch = handle_data_ack (t, (struct GNUNET_MESH_DataACK *) msgh, fwd);
5615 break; 5659 break;
5616 5660
5617 case GNUNET_MESSAGE_TYPE_MESH_CHANNEL_CREATE: 5661 case GNUNET_MESSAGE_TYPE_MESH_CHANNEL_CREATE:
5618 r = handle_channel_create (t, 5662 ch = handle_channel_create (t,
5619 (struct GNUNET_MESH_ChannelCreate *) msgh, 5663 (struct GNUNET_MESH_ChannelCreate *) msgh,
5620 fwd); 5664 fwd);
5621 break; 5665 break;
5622 5666
5623 case GNUNET_MESSAGE_TYPE_MESH_CHANNEL_ACK: 5667 case GNUNET_MESSAGE_TYPE_MESH_CHANNEL_ACK:
5624 r = handle_channel_ack (t, 5668 ch = handle_channel_ack (t,
5625 (struct GNUNET_MESH_ChannelManage *) msgh, 5669 (struct GNUNET_MESH_ChannelManage *) msgh,
5626 fwd); 5670 fwd);
5627 break; 5671 break;
5628 5672
5629 case GNUNET_MESSAGE_TYPE_MESH_CHANNEL_DESTROY: 5673 case GNUNET_MESSAGE_TYPE_MESH_CHANNEL_DESTROY:
5630 r = handle_channel_destroy (t, 5674 ch = handle_channel_destroy (t,
5631 (struct GNUNET_MESH_ChannelManage *) msgh, 5675 (struct GNUNET_MESH_ChannelManage *) msgh,
5632 fwd); 5676 fwd);
5633 break; 5677 break;
5634 5678
5635 default: 5679 default:
5636 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 5680 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
5637 "end-to-end message not known (%u)\n", 5681 "end-to-end message not known (%u)\n",
5638 ntohs (msgh->type)); 5682 ntohs (msgh->type));
5639 r = GNUNET_OK; 5683 ch = NULL;
5640 } 5684 }
5641 5685
5642 connection_send_ack (c, fwd); 5686 send_ack (c, ch, fwd);
5643 return r; 5687 return GNUNET_OK;
5644 } 5688 }
5645 5689
5646 /* Message not for us: forward to next hop */ 5690 /* Message not for us: forward to next hop */
@@ -5651,7 +5695,7 @@ handle_mesh_encrypted (const struct GNUNET_PeerIdentity *peer,
5651 { 5695 {
5652 GNUNET_STATISTICS_update (stats, "# TTL drops", 1, GNUNET_NO); 5696 GNUNET_STATISTICS_update (stats, "# TTL drops", 1, GNUNET_NO);
5653 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, " TTL is 0, DROPPING!\n"); 5697 GNUNET_log (GNUNET_ERROR_TYPE_WARNING, " TTL is 0, DROPPING!\n");
5654 connection_send_ack (c, fwd); 5698 connection_send_ack (c, connection_get_buffer (c, fwd), fwd);
5655 return GNUNET_OK; 5699 return GNUNET_OK;
5656 } 5700 }
5657 GNUNET_STATISTICS_update (stats, "# messages forwarded", 1, GNUNET_NO); 5701 GNUNET_STATISTICS_update (stats, "# messages forwarded", 1, GNUNET_NO);
@@ -5792,6 +5836,7 @@ handle_mesh_poll (void *cls, const struct GNUNET_PeerIdentity *peer,
5792 struct MeshFlowControl *fc; 5836 struct MeshFlowControl *fc;
5793 GNUNET_PEER_Id id; 5837 GNUNET_PEER_Id id;
5794 uint32_t pid; 5838 uint32_t pid;
5839 int fwd;
5795 5840
5796 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "\n\n"); 5841 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "\n\n");
5797 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Got a POLL packet from %s!\n", 5842 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Got a POLL packet from %s!\n",
@@ -5809,7 +5854,11 @@ handle_mesh_poll (void *cls, const struct GNUNET_PeerIdentity *peer,
5809 return GNUNET_OK; 5854 return GNUNET_OK;
5810 } 5855 }
5811 5856
5812 /* Is this a forward or backward ACK? */ 5857 /* Is this a forward or backward ACK?
5858 * Note: a poll should never be needed in a loopback case,
5859 * since there is no possiblility of packet loss there, so
5860 * this way of discerining FWD/BCK should not be a problem.
5861 */
5813 id = GNUNET_PEER_search (peer); 5862 id = GNUNET_PEER_search (peer);
5814 if (connection_get_next_hop (c)->id == id) 5863 if (connection_get_next_hop (c)->id == id)
5815 { 5864 {
@@ -5831,7 +5880,8 @@ handle_mesh_poll (void *cls, const struct GNUNET_PeerIdentity *peer,
5831 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " PID %u, OLD %u\n", 5880 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " PID %u, OLD %u\n",
5832 pid, fc->last_pid_recv); 5881 pid, fc->last_pid_recv);
5833 fc->last_pid_recv = pid; 5882 fc->last_pid_recv = pid;
5834 connection_send_ack (c, fc == &c->fwd_fc); 5883 fwd = fc == &c->fwd_fc;
5884 connection_send_ack (c, connection_get_buffer(c, fwd), fwd);
5835 5885
5836 return GNUNET_OK; 5886 return GNUNET_OK;
5837} 5887}