aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBart Polot <bart@net.in.tum.de>2013-07-15 14:09:07 +0000
committerBart Polot <bart@net.in.tum.de>2013-07-15 14:09:07 +0000
commit53ad2e450d066cf0f00e1f0f6e2a83b09698f2ea (patch)
tree5f5b1d4d2b2534761714eb1067fd40114f6fcc75
parent494e4832ac3f3bcf65146e7ce1e6083c79bfb6a8 (diff)
downloadgnunet-53ad2e450d066cf0f00e1f0f6e2a83b09698f2ea.tar.gz
gnunet-53ad2e450d066cf0f00e1f0f6e2a83b09698f2ea.zip
- fix polling in the presence of lost data
-rw-r--r--src/mesh/gnunet-service-mesh.c106
1 files changed, 79 insertions, 27 deletions
diff --git a/src/mesh/gnunet-service-mesh.c b/src/mesh/gnunet-service-mesh.c
index 5885df403..9bd1bf183 100644
--- a/src/mesh/gnunet-service-mesh.c
+++ b/src/mesh/gnunet-service-mesh.c
@@ -1149,6 +1149,44 @@ peer_get_short (const GNUNET_PEER_Id peer)
1149 1149
1150 1150
1151/** 1151/**
1152 * Select which PID to POLL for, to compensate for lost messages.
1153 *
1154 * @param pi Peer we want to poll.
1155 * @param t Tunnel about which we want to poll.
1156 *
1157 * @return PID to use, either last sent or first_in_queue - 1
1158 */
1159static uint32_t
1160peer_get_first_payload_pid (struct MeshPeerInfo *pi, struct MeshTunnel *t)
1161{
1162 struct MeshPeerQueue *q;
1163 uint16_t type;
1164
1165 type = pi->id == t->next_hop ? GNUNET_MESSAGE_TYPE_MESH_UNICAST :
1166 GNUNET_MESSAGE_TYPE_MESH_TO_ORIGIN;
1167
1168 for (q = pi->queue_head; NULL != q; q = q->next)
1169 {
1170 if (q->type == type && q->tunnel == t)
1171 {
1172 struct GNUNET_MESH_Data *msg = q->cls;
1173
1174 /* Pretend that the last one sent was the previous to this */
1175 return ntohl (msg->pid) - 1;
1176 }
1177 }
1178
1179 /* No data in queue, use last sent */
1180 {
1181 struct MeshFlowControl *fc;
1182
1183 fc = pi->id == t->next_hop ? &t->next_fc : &t->prev_fc;
1184 return fc->last_pid_sent;
1185 }
1186}
1187
1188
1189/**
1152 * Choose the best path towards a peer considering the tunnel properties. 1190 * Choose the best path towards a peer considering the tunnel properties.
1153 * 1191 *
1154 * @param peer The destination peer. 1192 * @param peer The destination peer.
@@ -1670,10 +1708,6 @@ tunnel_poll (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
1670 1708
1671 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " *** Polling!\n"); 1709 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " *** Polling!\n");
1672 1710
1673 msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_POLL);
1674 msg.header.size = htons (sizeof (msg));
1675 msg.tid = htonl (t->id.tid);
1676 msg.pid = htonl (fc->last_pid_sent);
1677 GNUNET_PEER_resolve (t->id.oid, &msg.oid); 1711 GNUNET_PEER_resolve (t->id.oid, &msg.oid);
1678 1712
1679 if (fc == &t->prev_fc) 1713 if (fc == &t->prev_fc)
@@ -1691,6 +1725,10 @@ tunnel_poll (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
1691 GNUNET_break (0); 1725 GNUNET_break (0);
1692 return; 1726 return;
1693 } 1727 }
1728 msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_POLL);
1729 msg.header.size = htons (sizeof (msg));
1730 msg.tid = htonl (t->id.tid);
1731 msg.pid = htonl (peer_get_first_payload_pid (peer_get_short (peer), t));
1694 send_prebuilt_message (&msg.header, peer, t); 1732 send_prebuilt_message (&msg.header, peer, t);
1695 fc->poll_time = GNUNET_TIME_STD_BACKOFF (fc->poll_time); 1733 fc->poll_time = GNUNET_TIME_STD_BACKOFF (fc->poll_time);
1696 fc->poll_task = GNUNET_SCHEDULER_add_delayed (fc->poll_time, 1734 fc->poll_task = GNUNET_SCHEDULER_add_delayed (fc->poll_time,
@@ -2068,7 +2106,6 @@ tunnel_send_fwd_data_ack (struct MeshTunnel *t)
2068 struct MeshTunnelReliability *rel; 2106 struct MeshTunnelReliability *rel;
2069 struct MeshReliableMessage *copy; 2107 struct MeshReliableMessage *copy;
2070 uint64_t mask; 2108 uint64_t mask;
2071 unsigned int i;
2072 unsigned int delta; 2109 unsigned int delta;
2073 2110
2074 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 2111 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
@@ -2087,12 +2124,12 @@ tunnel_send_fwd_data_ack (struct MeshTunnel *t)
2087 msg.mid = GNUNET_htonll (t->bck_rel->mid_recv - 1); 2124 msg.mid = GNUNET_htonll (t->bck_rel->mid_recv - 1);
2088 msg.futures = 0; 2125 msg.futures = 0;
2089 rel = t->bck_rel; 2126 rel = t->bck_rel;
2090 for (i = 0, copy = rel->head_recv; 2127 for (copy = rel->head_recv; NULL != copy; copy = copy->next)
2091 i < 64 && NULL != copy;
2092 i++, copy = copy->next)
2093 { 2128 {
2094 delta = copy->mid - t->bck_rel->mid_recv; 2129 delta = copy->mid - t->bck_rel->mid_recv;
2095 mask = 0x1 << delta; 2130 if (63 < delta)
2131 break;
2132 mask = 0x1LL << delta;
2096 msg.futures |= mask; 2133 msg.futures |= mask;
2097 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 2134 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2098 " setting bit for %u (delta %u) (%llX) -> %llX\n", 2135 " setting bit for %u (delta %u) (%llX) -> %llX\n",
@@ -2419,8 +2456,37 @@ tunnel_add_buffer_ucast (struct MeshTunnel *t,
2419 2456
2420 2457
2421/** 2458/**
2422 * Mark future messages as ACK'd. 2459 * Destroy a reliable message after it has been acknowledged, either by
2460 * direct mid ACK or bitfield. Updates the appropriate data structures and
2461 * timers and frees all memory.
2423 * 2462 *
2463 * @param copy Message that is no longer needed: remote peer got it.
2464 */
2465static void
2466tunnel_free_reliable_message (struct MeshReliableMessage *copy)
2467{
2468 struct MeshTunnelReliability *rel;
2469 struct GNUNET_TIME_Relative time;
2470
2471 rel = copy->rel;
2472 time = GNUNET_TIME_absolute_get_duration (copy->timestamp);
2473 rel->expected_delay.rel_value += time.rel_value;
2474 rel->expected_delay.rel_value /= 2;
2475 rel->n_sent--;
2476 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "!!! Freeing %llu\n", copy->mid);
2477 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " n_sent %u\n", rel->n_sent);
2478 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "!!! new expected delay %s\n",
2479 GNUNET_STRINGS_relative_time_to_string (rel->expected_delay,
2480 GNUNET_NO));
2481 rel->retry_timer = rel->expected_delay;
2482 GNUNET_CONTAINER_DLL_remove (rel->head_sent, rel->tail_sent, copy);
2483 GNUNET_free (copy);
2484}
2485
2486
2487/**
2488 * Mark future messages as ACK'd.
2489 *
2424 * @param t Tunnel whose sent buffer to clean. 2490 * @param t Tunnel whose sent buffer to clean.
2425 * @param msg DataACK message with a bitfield of future ACK'd messages. 2491 * @param msg DataACK message with a bitfield of future ACK'd messages.
2426 */ 2492 */
@@ -2483,10 +2549,8 @@ tunnel_free_buffer_ucast (struct MeshTunnel *t,
2483 } 2549 }
2484 2550
2485 /* Now copy->mid == target, free it */ 2551 /* Now copy->mid == target, free it */
2486 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "!!! Freeing %llu\n", target);
2487 next = copy->next; 2552 next = copy->next;
2488 GNUNET_CONTAINER_DLL_remove (rel->head_sent, rel->tail_sent, copy); 2553 tunnel_free_reliable_message (copy);
2489 GNUNET_free (copy);
2490 copy = next; 2554 copy = next;
2491 } 2555 }
2492 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "free_sent_buffer END\n"); 2556 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "free_sent_buffer END\n");
@@ -4228,9 +4292,7 @@ handle_mesh_data_ack (void *cls, const struct GNUNET_PeerIdentity *peer,
4228 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "!!! ACK %llu\n", ack); 4292 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "!!! ACK %llu\n", ack);
4229 for (work = GNUNET_NO, copy = rel->head_sent; copy != NULL; copy = next) 4293 for (work = GNUNET_NO, copy = rel->head_sent; copy != NULL; copy = next)
4230 { 4294 {
4231 struct GNUNET_TIME_Relative time; 4295 if (copy->mid > ack)
4232
4233 if (copy->mid > ack)
4234 { 4296 {
4235 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "!!! head %llu, out!\n", copy->mid); 4297 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "!!! head %llu, out!\n", copy->mid);
4236 tunnel_free_buffer_ucast (t, msg); 4298 tunnel_free_buffer_ucast (t, msg);
@@ -4239,17 +4301,7 @@ handle_mesh_data_ack (void *cls, const struct GNUNET_PeerIdentity *peer,
4239 work = GNUNET_YES; 4301 work = GNUNET_YES;
4240 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "!!! id %llu\n", copy->mid); 4302 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "!!! id %llu\n", copy->mid);
4241 next = copy->next; 4303 next = copy->next;
4242 time = GNUNET_TIME_absolute_get_duration (copy->timestamp); 4304 tunnel_free_reliable_message (copy);
4243 rel->expected_delay.rel_value += time.rel_value;
4244 rel->expected_delay.rel_value /= 2;
4245 rel->n_sent--;
4246 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " n_sent %u\n", rel->n_sent);
4247 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "!!! new expected delay %s\n",
4248 GNUNET_STRINGS_relative_time_to_string (rel->expected_delay,
4249 GNUNET_NO));
4250 rel->retry_timer = rel->expected_delay;
4251 GNUNET_CONTAINER_DLL_remove (rel->head_sent, rel->tail_sent, copy);
4252 GNUNET_free (copy);
4253 } 4305 }
4254 4306
4255 if (GNUNET_YES == work) 4307 if (GNUNET_YES == work)