diff options
author | Bart Polot <bart@net.in.tum.de> | 2013-07-15 14:09:07 +0000 |
---|---|---|
committer | Bart Polot <bart@net.in.tum.de> | 2013-07-15 14:09:07 +0000 |
commit | 53ad2e450d066cf0f00e1f0f6e2a83b09698f2ea (patch) | |
tree | 5f5b1d4d2b2534761714eb1067fd40114f6fcc75 | |
parent | 494e4832ac3f3bcf65146e7ce1e6083c79bfb6a8 (diff) | |
download | gnunet-53ad2e450d066cf0f00e1f0f6e2a83b09698f2ea.tar.gz gnunet-53ad2e450d066cf0f00e1f0f6e2a83b09698f2ea.zip |
- fix polling in the presence of lost data
-rw-r--r-- | src/mesh/gnunet-service-mesh.c | 106 |
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 | */ | ||
1159 | static uint32_t | ||
1160 | peer_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 | */ | ||
2465 | static void | ||
2466 | tunnel_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) |