aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBart Polot <bart@net.in.tum.de>2013-08-05 13:39:34 +0000
committerBart Polot <bart@net.in.tum.de>2013-08-05 13:39:34 +0000
commitf69c316b9a983cf6357801bc804d497bde5b8e50 (patch)
treecb1cf8a9518835f7f3257d1998738641602a179c
parent80e91cc2d8e19a1aeead110ac1ac813d85247fd3 (diff)
downloadgnunet-f69c316b9a983cf6357801bc804d497bde5b8e50.tar.gz
gnunet-f69c316b9a983cf6357801bc804d497bde5b8e50.zip
- change hop-by-hop ACK to be per-connection not per-peer
-rw-r--r--src/mesh/gnunet-service-mesh-enc.c245
-rw-r--r--src/mesh/mesh_protocol_enc.h20
2 files changed, 113 insertions, 152 deletions
diff --git a/src/mesh/gnunet-service-mesh-enc.c b/src/mesh/gnunet-service-mesh-enc.c
index 07c531eec..6f86d56f0 100644
--- a/src/mesh/gnunet-service-mesh-enc.c
+++ b/src/mesh/gnunet-service-mesh-enc.c
@@ -220,9 +220,9 @@ struct MeshPeerQueue
220struct MeshFlowControl 220struct MeshFlowControl
221{ 221{
222 /** 222 /**
223 * Peer 223 * Connection this controls.
224 */ 224 */
225 struct MeshPeer *peer; 225 struct MeshConnection *c;
226 226
227 /** 227 /**
228 * Transmission queue to core DLL head 228 * Transmission queue to core DLL head
@@ -297,11 +297,6 @@ struct MeshPeer
297 struct GNUNET_TIME_Absolute last_contact; 297 struct GNUNET_TIME_Absolute last_contact;
298 298
299 /** 299 /**
300 * Number of attempts to reconnect so far
301 */
302 int n_reconnect_attempts;
303
304 /**
305 * Paths to reach the peer, ordered by ascending hop count 300 * Paths to reach the peer, ordered by ascending hop count
306 */ 301 */
307 struct MeshPeerPath *path_head; 302 struct MeshPeerPath *path_head;
@@ -321,11 +316,6 @@ struct MeshPeer
321 */ 316 */
322 struct MeshTunnel2 *tunnel; 317 struct MeshTunnel2 *tunnel;
323 318
324 /**
325 * Flow control information for direct traffic.
326 */
327 struct MeshFlowControl *fc;
328
329}; 319};
330 320
331 321
@@ -508,6 +498,16 @@ struct MeshConnection
508 struct MeshTunnel2 *t; 498 struct MeshTunnel2 *t;
509 499
510 /** 500 /**
501 * Flow control information for traffic fwd.
502 */
503 struct MeshFlowControl *fwd_fc;
504
505 /**
506 * Flow control information for traffic bck.
507 */
508 struct MeshFlowControl *bck_fc;
509
510 /**
511 * Connection number. 511 * Connection number.
512 */ 512 */
513 uint32_t id; 513 uint32_t id;
@@ -1060,21 +1060,6 @@ queue_destroy (struct MeshPeerQueue *queue, int clear_cls);
1060 1060
1061 1061
1062/** 1062/**
1063 * @brief Get the next transmittable message from the queue.
1064 *
1065 * This will be the head, except in the case of being a data packet
1066 * not allowed by the destination peer.
1067 *
1068 * @param peer Destination peer.
1069 *
1070 * @return The next viable MeshPeerQueue element to send to that peer.
1071 * NULL when there are no transmittable messages.
1072 */
1073struct MeshPeerQueue *
1074queue_get_next (const struct MeshPeer *peer);
1075
1076
1077/**
1078 * Core callback to write a queued packet to core buffer 1063 * Core callback to write a queued packet to core buffer
1079 * 1064 *
1080 * @param cls Closure (peer info). 1065 * @param cls Closure (peer info).
@@ -1396,27 +1381,25 @@ tunnel_get_connection (struct MeshTunnel2 *t, int fwd)
1396{ 1381{
1397 struct MeshConnection *c; 1382 struct MeshConnection *c;
1398 struct MeshConnection *best; 1383 struct MeshConnection *best;
1399 struct MeshPeer *peer; 1384 struct MeshFlowControl *fc;
1400 unsigned int lowest_q; 1385 unsigned int lowest_q;
1401 1386
1402
1403 peer = NULL;
1404 best = NULL; 1387 best = NULL;
1405 lowest_q = UINT_MAX; 1388 lowest_q = UINT_MAX;
1406 for (c = t->connection_head; NULL != c; c = c->next) 1389 for (c = t->connection_head; NULL != c; c = c->next)
1407 { 1390 {
1408 if (MESH_CONNECTION_READY == c->state) 1391 if (MESH_CONNECTION_READY == c->state)
1409 { 1392 {
1410 peer = fwd ? connection_get_next_hop (c) : connection_get_prev_hop (c); 1393 fc = fwd ? c->fwd_fc : c->bck_fc;
1411 if (NULL == peer->fc) 1394 if (NULL == fc)
1412 { 1395 {
1413 GNUNET_break (0); 1396 GNUNET_break (0);
1414 continue; 1397 continue;
1415 } 1398 }
1416 if (peer->fc->queue_n < lowest_q) 1399 if (fc->queue_n < lowest_q)
1417 { 1400 {
1418 best = c; 1401 best = c;
1419 lowest_q = peer->fc->queue_n; 1402 lowest_q = fc->queue_n;
1420 } 1403 }
1421 } 1404 }
1422 } 1405 }
@@ -1595,41 +1578,6 @@ send_prebuilt_message_channel (const struct GNUNET_MessageHeader *message,
1595 1578
1596 1579
1597/** 1580/**
1598 * Sends an already built message directly to a peer.
1599 * Message does must not belong to a connection or channel.
1600 *
1601 * @param message Message to send. Function makes a copy of it.
1602 * @param peer Tunnel on which this message is transmitted.
1603 */
1604static void
1605send_prebuilt_message_peer (const struct GNUNET_MessageHeader *message,
1606 struct MeshPeer *peer)
1607{
1608 void *data;
1609 size_t size;
1610 uint16_t type;
1611
1612 if (NULL == peer)
1613 {
1614 GNUNET_break (0);
1615 return;
1616 }
1617
1618 size = ntohs (message->size);
1619 data = GNUNET_malloc (size);
1620 memcpy (data, message, size);
1621 type = ntohs(message->type);
1622
1623 queue_add (data,
1624 type,
1625 size,
1626 peer,
1627 NULL,
1628 NULL);
1629}
1630
1631
1632/**
1633 * Sends a CREATE CONNECTION message for a path to a peer. 1581 * Sends a CREATE CONNECTION message for a path to a peer.
1634 * Changes the connection and tunnel states if necessary. 1582 * Changes the connection and tunnel states if necessary.
1635 * 1583 *
@@ -1686,21 +1634,24 @@ send_connection_ack (struct MeshConnection *connection)
1686 1634
1687 1635
1688/** 1636/**
1689 * Build an ACK message and queue it to send to the given peer. 1637 * Build a hop-by-hop ACK message and queue it to send for the given connection.
1690 * 1638 *
1691 * @param peer Peer to whom send the ACK. 1639 * @param c Which connection to send the hop-by-hop ACK.
1692 * @param ack Value of the ACK. 1640 * @param ack Value of the ACK.
1641 * @param fwd Is this fwd?
1693 */ 1642 */
1694static void 1643static void
1695send_ack (struct MeshPeer *peer, uint32_t ack) 1644send_ack (struct MeshConnection *c, uint32_t ack, int fwd)
1696{ 1645{
1697 struct GNUNET_MESH_ACK msg; 1646 struct GNUNET_MESH_ACK msg;
1698 1647
1699 msg.header.size = htons (sizeof (msg)); 1648 msg.header.size = htons (sizeof (msg));
1700 msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_ACK); 1649 msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_ACK);
1701 msg.ack = htonl (ack); 1650 msg.ack = htonl (ack);
1651 msg.tid = c->t->id;
1652 msg.cid = htonl (c->id);
1702 1653
1703 send_prebuilt_message_peer (&msg.header, peer); 1654 send_prebuilt_message_connection (&msg.header, c, NULL, fwd);
1704} 1655}
1705 1656
1706 1657
@@ -2009,31 +1960,35 @@ peer_connect (struct MeshPeer *peer)
2009 1960
2010 1961
2011/** 1962/**
2012 * @brief Re-initiate traffic to this peer if necessary. 1963 * @brief Re-initiate traffic on this connection if necessary.
2013 * 1964 *
2014 * Check if there is traffic queued towards this peer 1965 * Check if there is traffic queued towards this peer
2015 * and the core transmit handle is NULL (traffic was stalled). 1966 * and the core transmit handle is NULL (traffic was stalled).
2016 * If so, call core tmt rdy. 1967 * If so, call core tmt rdy.
2017 * 1968 *
2018 * @param peer_id Short ID of peer to which initiate traffic. 1969 * @param c Connection on which initiate traffic.
1970 * @param fwd Is this about fwd traffic?
2019 */ 1971 */
2020static void 1972static void
2021peer_unlock_queue (GNUNET_PEER_Id peer_id) 1973connection_unlock_queue (struct MeshConnection *c, int fwd)
2022{ 1974{
1975 struct MeshFlowControl *fc;
2023 struct MeshPeer *peer; 1976 struct MeshPeer *peer;
2024 struct MeshPeerQueue *q; 1977 struct MeshPeerQueue *q;
2025 size_t size; 1978 size_t size;
2026 1979
2027 peer = peer_get_short (peer_id); 1980 peer = fwd ? connection_get_next_hop(c) : connection_get_prev_hop(c);
2028 if (NULL != peer->fc->core_transmit) 1981 fc = fwd ? c->fwd_fc : c->bck_fc;
1982
1983 if (NULL != fc->core_transmit)
2029 return; /* Already unlocked */ 1984 return; /* Already unlocked */
2030 1985
2031 q = queue_get_next (peer); 1986 q = fc->queue_head;
2032 if (NULL == q) 1987 if (NULL == q)
2033 return; /* Nothing to transmit */ 1988 return; /* Nothing to transmit */
2034 1989
2035 size = q->size; 1990 size = q->size;
2036 peer->fc->core_transmit = 1991 fc->core_transmit =
2037 GNUNET_CORE_notify_transmit_ready (core_handle, 1992 GNUNET_CORE_notify_transmit_ready (core_handle,
2038 GNUNET_NO, 1993 GNUNET_NO,
2039 0, 1994 0,
@@ -2046,32 +2001,31 @@ peer_unlock_queue (GNUNET_PEER_Id peer_id)
2046 2001
2047 2002
2048/** 2003/**
2049 * Cancel all transmissions towards a neighbor that belong to 2004 * Cancel all transmissions that belong to a certain connection.
2050 * a certain connection.
2051 * 2005 *
2052 * @param peer Neighbor to whom cancel the transmissions.
2053 * @param c Connection which to cancel. 2006 * @param c Connection which to cancel.
2007 * @param fwd Cancel fwd traffic?
2054 */ 2008 */
2055static void 2009static void
2056peer_cancel_queues (struct MeshPeer *peer, struct MeshConnection *c) 2010connection_cancel_queues (struct MeshConnection *c, int fwd)
2057{ 2011{
2058 struct MeshPeerQueue *q; 2012 struct MeshPeerQueue *q;
2059 struct MeshPeerQueue *next; 2013 struct MeshPeerQueue *next;
2060 struct MeshFlowControl *fc; 2014 struct MeshFlowControl *fc;
2061 2015
2062 if (NULL == peer || NULL == peer->fc) 2016 if (NULL == c)
2063 { 2017 {
2064 GNUNET_break (0); 2018 GNUNET_break (0);
2065 return; 2019 return;
2066 } 2020 }
2067 fc = peer->fc; 2021 fc = fwd ? c->fwd_fc : c->bck_fc;
2068 for (q = fc->queue_head; NULL != q; q = next) 2022 for (q = fc->queue_head; NULL != q; q = next)
2069 { 2023 {
2070 next = q->next; 2024 next = q->next;
2071 if (q->c == c) 2025 if (q->c == c)
2072 { 2026 {
2073 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 2027 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2074 "peer_cancel_queue %s\n", 2028 "connection_cancel_queue %s\n",
2075 GNUNET_MESH_DEBUG_M2S (q->type)); 2029 GNUNET_MESH_DEBUG_M2S (q->type));
2076 queue_destroy (q, GNUNET_YES); 2030 queue_destroy (q, GNUNET_YES);
2077 } 2031 }
@@ -2301,18 +2255,18 @@ peer_add_path_to_origin (struct MeshPeer *peer_info,
2301 2255
2302 2256
2303/** 2257/**
2304 * Function called if the connection to the peer has been stalled for a while, 2258 * Function called if a connection has been stalled for a while,
2305 * possibly due to a missed ACK. Poll the peer about its ACK status. 2259 * possibly due to a missed ACK. Poll the neighbor about its ACK status.
2306 * 2260 *
2307 * @param cls Closure (poll ctx). 2261 * @param cls Closure (poll ctx).
2308 * @param tc TaskContext. 2262 * @param tc TaskContext.
2309 */ 2263 */
2310static void 2264static void
2311peer_poll (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) 2265connection_poll (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
2312{ 2266{
2313 struct MeshFlowControl *fc = cls; 2267 struct MeshFlowControl *fc = cls;
2314 struct GNUNET_MESH_Poll msg; 2268 struct GNUNET_MESH_Poll msg;
2315 struct MeshPeer *peer; 2269 struct MeshConnection *c;
2316 2270
2317 fc->poll_task = GNUNET_SCHEDULER_NO_TASK; 2271 fc->poll_task = GNUNET_SCHEDULER_NO_TASK;
2318 if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) 2272 if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
@@ -2320,20 +2274,19 @@ peer_poll (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
2320 return; 2274 return;
2321 } 2275 }
2322 2276
2277 c = fc->c;
2323 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " *** Polling!\n"); 2278 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " *** Polling!\n");
2324 peer = fc->peer; 2279 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " *** connection %s[%X]\n",
2325 2280 GNUNET_i2s (GNUNET_PEER_resolve2 (c->t->peer->id)), c->id);
2326 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " *** peer: %s!\n",
2327 GNUNET_i2s (GNUNET_PEER_resolve2 (peer->id)));
2328 2281
2329 msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_POLL); 2282 msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_POLL);
2330 msg.header.size = htons (sizeof (msg)); 2283 msg.header.size = htons (sizeof (msg));
2331 msg.pid = htonl (fc->last_pid_sent); 2284 msg.pid = htonl (fc->last_pid_sent);
2332 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " *** pid (%u)!\n", fc->last_pid_sent); 2285 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " *** pid (%u)!\n", fc->last_pid_sent);
2333 send_prebuilt_message_peer (&msg.header, peer); 2286 send_prebuilt_message_connection (&msg.header, c, NULL, fc == c->fwd_fc);
2334 fc->poll_time = GNUNET_TIME_STD_BACKOFF (fc->poll_time); 2287 fc->poll_time = GNUNET_TIME_STD_BACKOFF (fc->poll_time);
2335 fc->poll_task = GNUNET_SCHEDULER_add_delayed (fc->poll_time, 2288 fc->poll_task = GNUNET_SCHEDULER_add_delayed (fc->poll_time,
2336 &peer_poll, fc); 2289 &connection_poll, fc);
2337} 2290}
2338 2291
2339 2292
@@ -2689,10 +2642,8 @@ channel_send_data_ack (struct MeshChannel *ch, int fwd)
2689/** 2642/**
2690 * Send an ACK informing the predecessor about the available buffer space. 2643 * Send an ACK informing the predecessor about the available buffer space.
2691 * 2644 *
2692 * Note that although the name is fwd_ack, the FWD mean forward *traffic*, 2645 * Note that for fwd ack, the FWD mean forward *traffic* (root->dest),
2693 * the ACK itself goes "back" (towards root). 2646 * the ACK itself goes "back" (dest->root).
2694 *
2695 * FIXME: use per connection ACKs istead of per-hop.
2696 * 2647 *
2697 * @param c Connection on which to send the ACK. 2648 * @param c Connection on which to send the ACK.
2698 * @param fwd Is this FWD ACK? (Going dest->owner) 2649 * @param fwd Is this FWD ACK? (Going dest->owner)
@@ -2702,15 +2653,11 @@ connection_send_ack (struct MeshConnection *c, int fwd)
2702{ 2653{
2703 struct MeshFlowControl *next_fc; 2654 struct MeshFlowControl *next_fc;
2704 struct MeshFlowControl *prev_fc; 2655 struct MeshFlowControl *prev_fc;
2705 struct MeshPeer *next;
2706 struct MeshPeer *prev;
2707 uint32_t ack; 2656 uint32_t ack;
2708 int delta; 2657 int delta;
2709 2658
2710 next = fwd ? connection_get_next_hop (c) : connection_get_prev_hop (c); 2659 next_fc = fwd ? c->fwd_fc : c->bck_fc;
2711 prev = fwd ? connection_get_prev_hop (c) : connection_get_next_hop (c); 2660 prev_fc = fwd ? c->bck_fc : c->fwd_fc;
2712 next_fc = next->fc;
2713 prev_fc = prev->fc;
2714 2661
2715 /* Check if we need to transmit the ACK */ 2662 /* Check if we need to transmit the ACK */
2716 if (prev_fc->last_ack_sent - prev_fc->last_pid_recv > 3) 2663 if (prev_fc->last_ack_sent - prev_fc->last_pid_recv > 3)
@@ -2737,7 +2684,7 @@ connection_send_ack (struct MeshConnection *c, int fwd)
2737 } 2684 }
2738 2685
2739 prev_fc->last_ack_sent = ack; 2686 prev_fc->last_ack_sent = ack;
2740 send_ack (prev, ack); 2687 send_ack (c, ack, fwd);
2741} 2688}
2742 2689
2743 2690
@@ -3145,7 +3092,7 @@ channel_retransmit_message (void *cls,
3145 struct MeshChannelReliability *rel = cls; 3092 struct MeshChannelReliability *rel = cls;
3146 struct MeshReliableMessage *copy; 3093 struct MeshReliableMessage *copy;
3147 struct MeshPeerQueue *q; 3094 struct MeshPeerQueue *q;
3148 struct MeshPeer *pi; 3095 struct MeshFlowControl *fc;
3149 struct MeshChannel *ch; 3096 struct MeshChannel *ch;
3150 struct MeshConnection *c; 3097 struct MeshConnection *c;
3151 struct GNUNET_MESH_Data *payload; 3098 struct GNUNET_MESH_Data *payload;
@@ -3175,9 +3122,9 @@ channel_retransmit_message (void *cls,
3175 */ 3122 */
3176 payload = (struct GNUNET_MESH_Data *) &copy[1]; 3123 payload = (struct GNUNET_MESH_Data *) &copy[1];
3177 fwd = (rel == ch->fwd_rel); 3124 fwd = (rel == ch->fwd_rel);
3178 c = tunnel_get_connection(ch->t, fwd); 3125 c = tunnel_get_connection (ch->t, fwd);
3179 pi = connection_get_next_hop (c); 3126 fc = fwd ? c->fwd_fc : c->bck_fc;
3180 for (q = pi->fc->queue_head; NULL != q; q = q->next) 3127 for (q = fc->queue_head; NULL != q; q = q->next)
3181 { 3128 {
3182 if (ntohs (payload->header.type) == q->type && ch == q->ch) 3129 if (ntohs (payload->header.type) == q->type && ch == q->ch)
3183 { 3130 {
@@ -3347,6 +3294,7 @@ connection_send_destroy (struct MeshConnection *c)
3347 3294
3348 send_prebuilt_message_connection (&msg.header, c, NULL, GNUNET_YES); 3295 send_prebuilt_message_connection (&msg.header, c, NULL, GNUNET_YES);
3349 send_prebuilt_message_connection (&msg.header, c, NULL, GNUNET_NO); 3296 send_prebuilt_message_connection (&msg.header, c, NULL, GNUNET_NO);
3297 c->destroy = GNUNET_YES;
3350} 3298}
3351 3299
3352 3300
@@ -3496,8 +3444,6 @@ connection_get (const struct GNUNET_HashCode *tid, uint32_t cid)
3496static void 3444static void
3497connection_destroy (struct MeshConnection *c) 3445connection_destroy (struct MeshConnection *c)
3498{ 3446{
3499 struct MeshPeer *peer;
3500
3501 if (NULL == c) 3447 if (NULL == c)
3502 return; 3448 return;
3503 3449
@@ -3505,12 +3451,8 @@ connection_destroy (struct MeshConnection *c)
3505 GNUNET_i2s (GNUNET_PEER_resolve2 (c->t->peer->id)), 3451 GNUNET_i2s (GNUNET_PEER_resolve2 (c->t->peer->id)),
3506 c->id); 3452 c->id);
3507 3453
3508 peer = connection_get_next_hop (c); 3454 connection_cancel_queues (c, GNUNET_YES);
3509 if (NULL != peer) 3455 connection_cancel_queues (c, GNUNET_NO);
3510 peer_cancel_queues (peer, c);
3511 peer = connection_get_prev_hop (c);
3512 if (NULL != peer)
3513 peer_cancel_queues (peer, c);
3514 3456
3515 if (GNUNET_SCHEDULER_NO_TASK != c->fwd_maintenance_task) 3457 if (GNUNET_SCHEDULER_NO_TASK != c->fwd_maintenance_task)
3516 GNUNET_SCHEDULER_cancel (c->fwd_maintenance_task); 3458 GNUNET_SCHEDULER_cancel (c->fwd_maintenance_task);
@@ -3891,8 +3833,11 @@ static void
3891queue_destroy (struct MeshPeerQueue *queue, int clear_cls) 3833queue_destroy (struct MeshPeerQueue *queue, int clear_cls)
3892{ 3834{
3893 struct MeshFlowControl *fc; 3835 struct MeshFlowControl *fc;
3836 int fwd;
3837
3838 fwd = (queue->peer == connection_get_next_hop (queue->c));
3839 fc = fwd ? queue->c->fwd_fc : queue->c->bck_fc;
3894 3840
3895 fc = queue->peer->fc;
3896 if (GNUNET_YES == clear_cls) 3841 if (GNUNET_YES == clear_cls)
3897 { 3842 {
3898 switch (queue->type) 3843 switch (queue->type)
@@ -3929,6 +3874,7 @@ queue_destroy (struct MeshPeerQueue *queue, int clear_cls)
3929 GNUNET_free (queue); 3874 GNUNET_free (queue);
3930} 3875}
3931 3876
3877
3932static size_t 3878static size_t
3933queue_send (void *cls, size_t size, void *buf) 3879queue_send (void *cls, size_t size, void *buf)
3934{ 3880{
@@ -3944,7 +3890,10 @@ queue_send (void *cls, size_t size, void *buf)
3944 uint16_t type; 3890 uint16_t type;
3945 int fwd; 3891 int fwd;
3946 3892
3947 fc = peer->fc; 3893 c = queue->c;
3894 fwd = (queue->peer == connection_get_next_hop (c));
3895 fc = fwd ? c->fwd_fc : c->bck_fc;
3896
3948 if (NULL == fc) 3897 if (NULL == fc)
3949 { 3898 {
3950 GNUNET_break (0); 3899 GNUNET_break (0);
@@ -3987,7 +3936,6 @@ queue_send (void *cls, size_t size, void *buf)
3987 } 3936 }
3988 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "* size ok\n"); 3937 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "* size ok\n");
3989 3938
3990 c = queue->c;
3991 t = (NULL != c) ? c->t : NULL; 3939 t = (NULL != c) ? c->t : NULL;
3992 type = 0; 3940 type = 0;
3993 3941
@@ -4045,12 +3993,9 @@ queue_send (void *cls, size_t size, void *buf)
4045 queue_destroy (queue, GNUNET_NO); 3993 queue_destroy (queue, GNUNET_NO);
4046 3994
4047 /* Send ACK if needed, after accounting for sent ID in fc->queue_n */ 3995 /* Send ACK if needed, after accounting for sent ID in fc->queue_n */
4048 fwd = GNUNET_NO;
4049 switch (type) 3996 switch (type)
4050 { 3997 {
4051 case GNUNET_MESSAGE_TYPE_MESH_FWD: 3998 case GNUNET_MESSAGE_TYPE_MESH_FWD:
4052 fwd = GNUNET_YES;
4053 /* fall through */
4054 case GNUNET_MESSAGE_TYPE_MESH_BCK: 3999 case GNUNET_MESSAGE_TYPE_MESH_BCK:
4055 pid = ntohl ( ((struct GNUNET_MESH_Encrypted *) buf)->pid ); 4000 pid = ntohl ( ((struct GNUNET_MESH_Encrypted *) buf)->pid );
4056 fc->last_pid_sent = pid; 4001 fc->last_pid_sent = pid;
@@ -4066,7 +4011,7 @@ queue_send (void *cls, size_t size, void *buf)
4066 { 4011 {
4067 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "* more data!\n"); 4012 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "* more data!\n");
4068 if (NULL == fc->core_transmit) { 4013 if (NULL == fc->core_transmit) {
4069 peer->fc->core_transmit = 4014 fc->core_transmit =
4070 GNUNET_CORE_notify_transmit_ready(core_handle, 4015 GNUNET_CORE_notify_transmit_ready(core_handle,
4071 0, 4016 0,
4072 0, 4017 0,
@@ -4085,7 +4030,7 @@ queue_send (void *cls, size_t size, void *buf)
4085 { 4030 {
4086 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "* %s starting poll timeout\n"); 4031 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "* %s starting poll timeout\n");
4087 fc->poll_task = 4032 fc->poll_task =
4088 GNUNET_SCHEDULER_add_delayed (fc->poll_time, &peer_poll, fc); 4033 GNUNET_SCHEDULER_add_delayed (fc->poll_time, &connection_poll, fc);
4089 } 4034 }
4090 } 4035 }
4091 else 4036 else
@@ -4129,8 +4074,11 @@ queue_add (void *cls, uint16_t type, size_t size,
4129 struct MeshPeerQueue *queue; 4074 struct MeshPeerQueue *queue;
4130 struct MeshFlowControl *fc; 4075 struct MeshFlowControl *fc;
4131 int priority; 4076 int priority;
4077 int fwd;
4078
4079 fwd = (dst == connection_get_next_hop (c));
4080 fc = fwd ? c->fwd_fc : c->bck_fc;
4132 4081
4133 fc = dst->fc;
4134 if (NULL == fc) 4082 if (NULL == fc)
4135 { 4083 {
4136 GNUNET_break (0); 4084 GNUNET_break (0);
@@ -4163,7 +4111,7 @@ queue_add (void *cls, uint16_t type, size_t size,
4163 if (GMC_is_pid_bigger(fc->last_pid_sent + 1, fc->last_ack_recv) && 4111 if (GMC_is_pid_bigger(fc->last_pid_sent + 1, fc->last_ack_recv) &&
4164 GNUNET_SCHEDULER_NO_TASK == fc->poll_task) 4112 GNUNET_SCHEDULER_NO_TASK == fc->poll_task)
4165 fc->poll_task = GNUNET_SCHEDULER_add_delayed (fc->poll_time, 4113 fc->poll_task = GNUNET_SCHEDULER_add_delayed (fc->poll_time,
4166 &peer_poll, 4114 &connection_poll,
4167 dst); 4115 dst);
4168 queue = GNUNET_malloc (sizeof (struct MeshPeerQueue)); 4116 queue = GNUNET_malloc (sizeof (struct MeshPeerQueue));
4169 queue->cls = cls; 4117 queue->cls = cls;
@@ -4675,8 +4623,8 @@ handle_mesh_connection_destroy (void *cls,
4675{ 4623{
4676 struct GNUNET_MESH_ConnectionDestroy *msg; 4624 struct GNUNET_MESH_ConnectionDestroy *msg;
4677 struct MeshConnection *c; 4625 struct MeshConnection *c;
4678 struct MeshTunnel2 *t; 4626 GNUNET_PEER_Id id;
4679 struct MeshPeer *neighbor; 4627 int fwd;
4680 4628
4681 msg = (struct GNUNET_MESH_ConnectionDestroy *) message; 4629 msg = (struct GNUNET_MESH_ConnectionDestroy *) message;
4682 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 4630 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
@@ -4696,20 +4644,18 @@ handle_mesh_connection_destroy (void *cls,
4696 1, GNUNET_NO); 4644 1, GNUNET_NO);
4697 return GNUNET_OK; 4645 return GNUNET_OK;
4698 } 4646 }
4699 neighbor = peer_get (peer); 4647 id = GNUNET_PEER_search (peer);
4700 if (neighbor == connection_get_prev_hop (c)) 4648 if (id == connection_get_prev_hop (c)->id)
4701 neighbor = connection_get_next_hop (c); 4649 fwd = GNUNET_YES;
4702 else if (neighbor == connection_get_next_hop (c)) 4650 else if (id == connection_get_next_hop (c)->id)
4703 neighbor = connection_get_prev_hop (c); 4651 fwd = GNUNET_NO;
4704 else 4652 else
4705 { 4653 {
4706 GNUNET_break_op (0); 4654 GNUNET_break_op (0);
4707 return GNUNET_OK; 4655 return GNUNET_OK;
4708 } 4656 }
4709 send_prebuilt_message_peer (message, neighbor); 4657 send_prebuilt_message_connection (message, c, NULL, fwd);
4710 t = c->t; 4658 c->destroy = GNUNET_YES;
4711 connection_destroy (c);
4712 tunnel_destroy_if_empty (t);
4713 4659
4714 return GNUNET_OK; 4660 return GNUNET_OK;
4715} 4661}
@@ -4734,6 +4680,7 @@ handle_mesh_encrypted (const struct GNUNET_PeerIdentity *peer,
4734 struct MeshTunnel2 *t; 4680 struct MeshTunnel2 *t;
4735 struct MeshPeer *neighbor; 4681 struct MeshPeer *neighbor;
4736 struct MeshFlowControl *fc; 4682 struct MeshFlowControl *fc;
4683 GNUNET_PEER_Id id;
4737 uint32_t pid; 4684 uint32_t pid;
4738 uint32_t ttl; 4685 uint32_t ttl;
4739 uint16_t type; 4686 uint16_t type;
@@ -4761,13 +4708,13 @@ handle_mesh_encrypted (const struct GNUNET_PeerIdentity *peer,
4761 return GNUNET_OK; 4708 return GNUNET_OK;
4762 } 4709 }
4763 t = c->t; 4710 t = c->t;
4711 fc = fwd ? c->fwd_fc : c->bck_fc;
4764 4712
4765 /* Check neighbor status */ 4713 /* Check if origin is as expected */
4766 neighbor = peer_get (peer); 4714 neighbor = fwd ? connection_get_prev_hop (c) : connection_get_next_hop (c);
4767 fc = neighbor->fc; 4715 if (peer_get (peer)->id != neighbor->id)
4768 if (NULL == fc)
4769 { 4716 {
4770 GNUNET_break (0); 4717 GNUNET_break_op (0);
4771 return GNUNET_OK; 4718 return GNUNET_OK;
4772 } 4719 }
4773 4720
@@ -5841,12 +5788,6 @@ core_connect (void *cls, const struct GNUNET_PeerIdentity *peer)
5841 path->peers[0] = myid; 5788 path->peers[0] = myid;
5842 GNUNET_PEER_change_rc (myid, 1); 5789 GNUNET_PEER_change_rc (myid, 1);
5843 peer_add_path (peer_info, path, GNUNET_YES); 5790 peer_add_path (peer_info, path, GNUNET_YES);
5844 if (NULL == peer_info->fc)
5845 {
5846 peer_info->fc = GNUNET_new (struct MeshFlowControl);
5847 fc_init (peer_info->fc);
5848 peer_info->fc->peer = peer_info;
5849 }
5850 return; 5791 return;
5851} 5792}
5852 5793
diff --git a/src/mesh/mesh_protocol_enc.h b/src/mesh/mesh_protocol_enc.h
index ebecb087d..9661a4fd3 100644
--- a/src/mesh/mesh_protocol_enc.h
+++ b/src/mesh/mesh_protocol_enc.h
@@ -242,6 +242,16 @@ struct GNUNET_MESH_ACK
242 * Maximum packet ID authorized. 242 * Maximum packet ID authorized.
243 */ 243 */
244 uint32_t ack GNUNET_PACKED; 244 uint32_t ack GNUNET_PACKED;
245
246 /**
247 * ID of the tunnel
248 */
249 struct GNUNET_HashCode tid;
250
251 /**
252 * ID of the connection
253 */
254 uint32_t cid GNUNET_PACKED;
245}; 255};
246 256
247 257
@@ -259,6 +269,16 @@ struct GNUNET_MESH_Poll
259 * Last packet sent. 269 * Last packet sent.
260 */ 270 */
261 uint32_t pid GNUNET_PACKED; 271 uint32_t pid GNUNET_PACKED;
272
273 /**
274 * ID of the tunnel
275 */
276 struct GNUNET_HashCode tid;
277
278 /**
279 * ID of the connection
280 */
281 uint32_t cid GNUNET_PACKED;
262}; 282};
263 283
264 284