diff options
author | Bart Polot <bart@net.in.tum.de> | 2012-09-28 18:18:00 +0000 |
---|---|---|
committer | Bart Polot <bart@net.in.tum.de> | 2012-09-28 18:18:00 +0000 |
commit | 78c80235606b0c7a251a7a167e51f5db3e96434b (patch) | |
tree | e4310f994e4ee77a10fce39e2668d3af74e2e009 /src | |
parent | 80e7be69a94c34840aca8f1bb7ec62ca3db95c4d (diff) | |
download | gnunet-78c80235606b0c7a251a7a167e51f5db3e96434b.tar.gz gnunet-78c80235606b0c7a251a7a167e51f5db3e96434b.zip |
- fix mesh fc when buffering is off
Diffstat (limited to 'src')
-rw-r--r-- | src/mesh/gnunet-service-mesh.c | 40 | ||||
-rw-r--r-- | src/mesh/mesh.h | 5 | ||||
-rw-r--r-- | src/mesh/mesh_api.c | 13 |
3 files changed, 49 insertions, 9 deletions
diff --git a/src/mesh/gnunet-service-mesh.c b/src/mesh/gnunet-service-mesh.c index 4169c41f1..6d0648d28 100644 --- a/src/mesh/gnunet-service-mesh.c +++ b/src/mesh/gnunet-service-mesh.c | |||
@@ -2085,6 +2085,11 @@ send_subscribed_clients (const struct GNUNET_MessageHeader *msg, | |||
2085 | tmsg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_LOCAL_TUNNEL_CREATE); | 2085 | tmsg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_LOCAL_TUNNEL_CREATE); |
2086 | GNUNET_PEER_resolve (t->id.oid, &tmsg.peer); | 2086 | GNUNET_PEER_resolve (t->id.oid, &tmsg.peer); |
2087 | tmsg.tunnel_id = htonl (t->local_tid_dest); | 2087 | tmsg.tunnel_id = htonl (t->local_tid_dest); |
2088 | tmsg.opt = 0; | ||
2089 | if (GNUNET_YES == t->speed_min) | ||
2090 | tmsg.opt |= MESH_TUNNEL_OPT_SPEED_MIN; | ||
2091 | if (GNUNET_YES == t->nobuffer) | ||
2092 | tmsg.opt |= MESH_TUNNEL_OPT_NOBUFFER; | ||
2088 | GNUNET_SERVER_notification_context_unicast (nc, c->handle, | 2093 | GNUNET_SERVER_notification_context_unicast (nc, c->handle, |
2089 | &tmsg.header, GNUNET_NO); | 2094 | &tmsg.header, GNUNET_NO); |
2090 | tunnel_add_client (t, c); | 2095 | tunnel_add_client (t, c); |
@@ -3701,9 +3706,23 @@ tunnel_get_fwd_ack (struct MeshTunnel *t) | |||
3701 | 3706 | ||
3702 | count = t->fwd_pid - t->skip; | 3707 | count = t->fwd_pid - t->skip; |
3703 | buffer_free = t->fwd_queue_max - t->fwd_queue_n; | 3708 | buffer_free = t->fwd_queue_max - t->fwd_queue_n; |
3704 | ack = count + buffer_free; | ||
3705 | child_ack = tunnel_get_children_fwd_ack (t); | 3709 | child_ack = tunnel_get_children_fwd_ack (t); |
3706 | client_ack = tunnel_get_clients_fwd_ack (t); | 3710 | client_ack = tunnel_get_clients_fwd_ack (t); |
3711 | if (GNUNET_YES == t->nobuffer) | ||
3712 | { | ||
3713 | ack = count; | ||
3714 | if (-1LL == child_ack) | ||
3715 | child_ack = client_ack; | ||
3716 | if (-1LL == child_ack) | ||
3717 | { | ||
3718 | GNUNET_break (0); | ||
3719 | client_ack = child_ack = ack; | ||
3720 | } | ||
3721 | } | ||
3722 | else | ||
3723 | { | ||
3724 | ack = count + buffer_free; // Overflow? OK! | ||
3725 | } | ||
3707 | if (-1LL == child_ack) | 3726 | if (-1LL == child_ack) |
3708 | { | 3727 | { |
3709 | // Node has no children, child_ack AND core buffer are irrelevant. | 3728 | // Node has no children, child_ack AND core buffer are irrelevant. |
@@ -3712,20 +3731,18 @@ tunnel_get_fwd_ack (struct MeshTunnel *t) | |||
3712 | } | 3731 | } |
3713 | if (-1LL == client_ack) | 3732 | if (-1LL == client_ack) |
3714 | { | 3733 | { |
3715 | client_ack = ack; // Might overflow 32 bits, it's ok! | 3734 | client_ack = ack; |
3716 | } | 3735 | } |
3717 | if (GNUNET_YES == t->speed_min) | 3736 | if (GNUNET_YES == t->speed_min) |
3718 | { | 3737 | { |
3719 | ack = GMC_min_pid ((uint32_t) child_ack, ack); // Might overflow 32 bits, it's ok!; | 3738 | ack = GMC_min_pid ((uint32_t) child_ack, ack); |
3720 | ack = GMC_min_pid ((uint32_t) client_ack, ack); | 3739 | ack = GMC_min_pid ((uint32_t) client_ack, ack); |
3721 | } | 3740 | } |
3722 | else | 3741 | else |
3723 | { | 3742 | { |
3724 | ack = GMC_max_pid ((uint32_t) child_ack, ack); // Might overflow 32 bits, it's ok!; | 3743 | ack = GMC_max_pid ((uint32_t) child_ack, ack); |
3725 | ack = GMC_max_pid ((uint32_t) client_ack, ack); | 3744 | ack = GMC_max_pid ((uint32_t) client_ack, ack); |
3726 | } | 3745 | } |
3727 | if (GNUNET_YES == t->nobuffer && GMC_is_pid_bigger(ack, t->fwd_pid)) | ||
3728 | ack = t->fwd_pid + 1; // Might overflow 32 bits, it's ok! | ||
3729 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 3746 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
3730 | "c %u, bf %u, ch %lld, cl %lld, ACK: %u\n", | 3747 | "c %u, bf %u, ch %lld, cl %lld, ACK: %u\n", |
3731 | count, buffer_free, child_ack, client_ack, ack); | 3748 | count, buffer_free, child_ack, client_ack, ack); |
@@ -3796,7 +3813,10 @@ tunnel_send_client_fwd_ack (struct MeshTunnel *t) | |||
3796 | 3813 | ||
3797 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " ack %u\n", ack); | 3814 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " ack %u\n", ack); |
3798 | if (t->last_fwd_ack == ack) | 3815 | if (t->last_fwd_ack == ack) |
3816 | { | ||
3817 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " same as last, not sending!\n"); | ||
3799 | return; | 3818 | return; |
3819 | } | ||
3800 | 3820 | ||
3801 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " sending!\n"); | 3821 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " sending!\n"); |
3802 | t->last_fwd_ack = ack; | 3822 | t->last_fwd_ack = ack; |
@@ -5111,8 +5131,11 @@ handle_mesh_path_create (void *cls, const struct GNUNET_PeerIdentity *peer, | |||
5111 | opt = ntohl (msg->opt); | 5131 | opt = ntohl (msg->opt); |
5112 | t->speed_min = (0 != (opt & MESH_TUNNEL_OPT_SPEED_MIN)) ? | 5132 | t->speed_min = (0 != (opt & MESH_TUNNEL_OPT_SPEED_MIN)) ? |
5113 | GNUNET_YES : GNUNET_NO; | 5133 | GNUNET_YES : GNUNET_NO; |
5114 | t->nobuffer = (0 != (opt & MESH_TUNNEL_OPT_NOBUFFER)) ? | 5134 | if (0 != (opt & MESH_TUNNEL_OPT_NOBUFFER)) |
5115 | GNUNET_YES : GNUNET_NO; | 5135 | { |
5136 | t->nobuffer = GNUNET_YES; | ||
5137 | t->last_fwd_ack = t->fwd_pid + 1; | ||
5138 | } | ||
5116 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 5139 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
5117 | " speed_min: %d, nobuffer:%d\n", | 5140 | " speed_min: %d, nobuffer:%d\n", |
5118 | t->speed_min, t->nobuffer); | 5141 | t->speed_min, t->nobuffer); |
@@ -5509,6 +5532,7 @@ handle_mesh_data_unicast (void *cls, const struct GNUNET_PeerIdentity *peer, | |||
5509 | GNUNET_YES == GMC_is_pid_bigger (pid, cinfo->fwd_ack)) | 5532 | GNUNET_YES == GMC_is_pid_bigger (pid, cinfo->fwd_ack)) |
5510 | { | 5533 | { |
5511 | GNUNET_STATISTICS_update (stats, "# unsolicited unicast", 1, GNUNET_NO); | 5534 | GNUNET_STATISTICS_update (stats, "# unsolicited unicast", 1, GNUNET_NO); |
5535 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, " %u > %u\n", pid, cinfo->fwd_ack); | ||
5512 | GNUNET_break_op (0); | 5536 | GNUNET_break_op (0); |
5513 | return GNUNET_OK; | 5537 | return GNUNET_OK; |
5514 | } | 5538 | } |
diff --git a/src/mesh/mesh.h b/src/mesh/mesh.h index 86e824807..27f2238bf 100644 --- a/src/mesh/mesh.h +++ b/src/mesh/mesh.h | |||
@@ -169,6 +169,11 @@ struct GNUNET_MESH_TunnelNotification | |||
169 | * Peer at the other end, if any | 169 | * Peer at the other end, if any |
170 | */ | 170 | */ |
171 | struct GNUNET_PeerIdentity peer; | 171 | struct GNUNET_PeerIdentity peer; |
172 | |||
173 | /** | ||
174 | * Tunnel options (speed, buffering) | ||
175 | */ | ||
176 | uint32_t opt; | ||
172 | }; | 177 | }; |
173 | 178 | ||
174 | /** | 179 | /** |
diff --git a/src/mesh/mesh_api.c b/src/mesh/mesh_api.c index 347b68aec..4fb46a26e 100644 --- a/src/mesh/mesh_api.c +++ b/src/mesh/mesh_api.c | |||
@@ -467,6 +467,7 @@ create_tunnel (struct GNUNET_MESH_Handle *h, MESH_TunnelNumber tid) | |||
467 | } | 467 | } |
468 | t->max_send_pid = INITIAL_WINDOW_SIZE - 1; | 468 | t->max_send_pid = INITIAL_WINDOW_SIZE - 1; |
469 | t->last_recv_pid = (uint32_t) -1; | 469 | t->last_recv_pid = (uint32_t) -1; |
470 | t->buffering = GNUNET_YES; | ||
470 | return t; | 471 | return t; |
471 | } | 472 | } |
472 | 473 | ||
@@ -707,7 +708,10 @@ send_ack (struct GNUNET_MESH_Handle *h, struct GNUNET_MESH_Tunnel *t) | |||
707 | t->tid, t->max_recv_pid, t->last_recv_pid, delta); | 708 | t->tid, t->max_recv_pid, t->last_recv_pid, delta); |
708 | return; | 709 | return; |
709 | } | 710 | } |
710 | t->max_recv_pid = t->last_recv_pid + INITIAL_WINDOW_SIZE; | 711 | if (GNUNET_YES == t->buffering) |
712 | t->max_recv_pid = t->last_recv_pid + INITIAL_WINDOW_SIZE; | ||
713 | else | ||
714 | t->max_recv_pid = t->last_recv_pid + 1; | ||
711 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 715 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
712 | "Sending ACK on tunnel %X: %u\n", | 716 | "Sending ACK on tunnel %X: %u\n", |
713 | t->tid, t->max_recv_pid); | 717 | t->tid, t->max_recv_pid); |
@@ -970,6 +974,12 @@ process_tunnel_created (struct GNUNET_MESH_Handle *h, | |||
970 | GNUNET_PEER_change_rc (t->owner, 1); | 974 | GNUNET_PEER_change_rc (t->owner, 1); |
971 | t->mesh = h; | 975 | t->mesh = h; |
972 | t->tid = tid; | 976 | t->tid = tid; |
977 | if ((msg->opt & MESH_TUNNEL_OPT_NOBUFFER) != 0) | ||
978 | t->buffering = GNUNET_NO; | ||
979 | else | ||
980 | t->buffering = GNUNET_YES; | ||
981 | if ((msg->opt & MESH_TUNNEL_OPT_SPEED_MIN) != 0) | ||
982 | t->speed_min = GNUNET_YES; | ||
973 | atsi.type = 0; | 983 | atsi.type = 0; |
974 | atsi.value = 0; | 984 | atsi.value = 0; |
975 | LOG (GNUNET_ERROR_TYPE_DEBUG, " created tunnel %p\n", t); | 985 | LOG (GNUNET_ERROR_TYPE_DEBUG, " created tunnel %p\n", t); |
@@ -1817,6 +1827,7 @@ GNUNET_MESH_tunnel_buffer (struct GNUNET_MESH_Tunnel *tunnel, int buffer) | |||
1817 | 1827 | ||
1818 | h = tunnel->mesh; | 1828 | h = tunnel->mesh; |
1819 | tunnel->buffering = buffer; | 1829 | tunnel->buffering = buffer; |
1830 | tunnel->max_send_pid = tunnel->next_send_pid; | ||
1820 | 1831 | ||
1821 | if (GNUNET_YES == buffer) | 1832 | if (GNUNET_YES == buffer) |
1822 | msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_LOCAL_TUNNEL_BUFFER); | 1833 | msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_LOCAL_TUNNEL_BUFFER); |