diff options
author | Julius Bünger <buenger@mytum.de> | 2018-07-25 17:53:31 +0200 |
---|---|---|
committer | Julius Bünger <buenger@mytum.de> | 2018-07-25 17:53:31 +0200 |
commit | 5794e80239687f6fe88311bb7156d105d30170de (patch) | |
tree | ceda9362221fbd710244ee8bcc3529eb7025baf1 | |
parent | 3430620e67bacdb1910027f29a9b83e5c251a393 (diff) | |
download | gnunet-5794e80239687f6fe88311bb7156d105d30170de.tar.gz gnunet-5794e80239687f6fe88311bb7156d105d30170de.zip |
fix rps service: better handling of cadet channels
-rw-r--r-- | src/rps/gnunet-service-rps.c | 282 |
1 files changed, 214 insertions, 68 deletions
diff --git a/src/rps/gnunet-service-rps.c b/src/rps/gnunet-service-rps.c index 12794945e..fcb68b724 100644 --- a/src/rps/gnunet-service-rps.c +++ b/src/rps/gnunet-service-rps.c | |||
@@ -164,6 +164,11 @@ struct PendingMessage | |||
164 | }; | 164 | }; |
165 | 165 | ||
166 | /** | 166 | /** |
167 | * @brief Context for a channel | ||
168 | */ | ||
169 | struct ChannelCtx; | ||
170 | |||
171 | /** | ||
167 | * Struct used to keep track of other peer's status | 172 | * Struct used to keep track of other peer's status |
168 | * | 173 | * |
169 | * This is stored in a multipeermap. | 174 | * This is stored in a multipeermap. |
@@ -181,7 +186,7 @@ struct PeerContext | |||
181 | /** | 186 | /** |
182 | * Channel open to client. | 187 | * Channel open to client. |
183 | */ | 188 | */ |
184 | struct GNUNET_CADET_Channel *send_channel; | 189 | struct ChannelCtx *send_channel_ctx; |
185 | 190 | ||
186 | /** | 191 | /** |
187 | * Flags to the sending channel | 192 | * Flags to the sending channel |
@@ -191,7 +196,7 @@ struct PeerContext | |||
191 | /** | 196 | /** |
192 | * Channel open from client. | 197 | * Channel open from client. |
193 | */ | 198 | */ |
194 | struct GNUNET_CADET_Channel *recv_channel; // unneeded? | 199 | struct ChannelCtx *recv_channel_ctx; // unneeded? |
195 | 200 | ||
196 | /** | 201 | /** |
197 | * Flags to the receiving channel | 202 | * Flags to the receiving channel |
@@ -265,6 +270,39 @@ struct PeersIteratorCls | |||
265 | }; | 270 | }; |
266 | 271 | ||
267 | /** | 272 | /** |
273 | * @brief Context for a channel | ||
274 | */ | ||
275 | struct ChannelCtx | ||
276 | { | ||
277 | /** | ||
278 | * @brief Meant to be used in a DLL | ||
279 | */ | ||
280 | struct ChannelCtx *next; | ||
281 | struct ChannelCtx *prev; | ||
282 | |||
283 | /** | ||
284 | * @brief The channel itself | ||
285 | */ | ||
286 | struct GNUNET_CADET_Channel *channel; | ||
287 | |||
288 | /** | ||
289 | * @brief The peer context associated with the channel | ||
290 | */ | ||
291 | struct PeerContext *peer_ctx; | ||
292 | |||
293 | /** | ||
294 | * @brief Scheduled task that will destroy this context | ||
295 | */ | ||
296 | struct GNUNET_SCHEDULER_Task *destruction_task; | ||
297 | }; | ||
298 | |||
299 | /** | ||
300 | * @brief The DLL of channel contexts | ||
301 | */ | ||
302 | static struct ChannelCtx *channel_ctx_head; | ||
303 | static struct ChannelCtx *channel_ctx_tail; | ||
304 | |||
305 | /** | ||
268 | * @brief Hashmap of valid peers. | 306 | * @brief Hashmap of valid peers. |
269 | */ | 307 | */ |
270 | static struct GNUNET_CONTAINER_MultiPeerMap *valid_peers; | 308 | static struct GNUNET_CONTAINER_MultiPeerMap *valid_peers; |
@@ -387,8 +425,8 @@ Peers_check_connected (const struct GNUNET_PeerIdentity *peer) | |||
387 | /* Get the context */ | 425 | /* Get the context */ |
388 | peer_ctx = get_peer_ctx (peer); | 426 | peer_ctx = get_peer_ctx (peer); |
389 | /* If we have no channel to this peer we don't know whether it's online */ | 427 | /* If we have no channel to this peer we don't know whether it's online */ |
390 | if ( (NULL == peer_ctx->send_channel) && | 428 | if ( (NULL == peer_ctx->send_channel_ctx) && |
391 | (NULL == peer_ctx->recv_channel) ) | 429 | (NULL == peer_ctx->recv_channel_ctx) ) |
392 | { | 430 | { |
393 | Peers_unset_peer_flag (peer, Peers_ONLINE); | 431 | Peers_unset_peer_flag (peer, Peers_ONLINE); |
394 | return GNUNET_NO; | 432 | return GNUNET_NO; |
@@ -575,6 +613,24 @@ handle_peer_pull_reply (void *cls, | |||
575 | 613 | ||
576 | /* End declaration of handlers */ | 614 | /* End declaration of handlers */ |
577 | 615 | ||
616 | /** | ||
617 | * @brief Allocate memory for a new channel context and insert it into DLL | ||
618 | * | ||
619 | * @param peer_ctx context of the according peer | ||
620 | * | ||
621 | * @return The channel context | ||
622 | */ | ||
623 | static struct ChannelCtx * | ||
624 | add_channel_ctx (struct PeerContext *peer_ctx); | ||
625 | |||
626 | /** | ||
627 | * @brief Remove the channel context from the DLL and free the memory. | ||
628 | * | ||
629 | * @param channel_ctx The channel context. | ||
630 | */ | ||
631 | static void | ||
632 | remove_channel_ctx (struct ChannelCtx *channel_ctx); | ||
633 | |||
578 | 634 | ||
579 | /** | 635 | /** |
580 | * @brief Get the channel of a peer. If not existing, create. | 636 | * @brief Get the channel of a peer. If not existing, create. |
@@ -610,16 +666,17 @@ get_channel (const struct GNUNET_PeerIdentity *peer) | |||
610 | 666 | ||
611 | 667 | ||
612 | peer_ctx = get_peer_ctx (peer); | 668 | peer_ctx = get_peer_ctx (peer); |
613 | if (NULL == peer_ctx->send_channel) | 669 | if (NULL == peer_ctx->send_channel_ctx) |
614 | { | 670 | { |
615 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 671 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
616 | "Trying to establish channel to peer %s\n", | 672 | "Trying to establish channel to peer %s\n", |
617 | GNUNET_i2s (peer)); | 673 | GNUNET_i2s (peer)); |
618 | ctx_peer = GNUNET_new (struct GNUNET_PeerIdentity); | 674 | ctx_peer = GNUNET_new (struct GNUNET_PeerIdentity); |
619 | *ctx_peer = *peer; | 675 | *ctx_peer = *peer; |
620 | peer_ctx->send_channel = | 676 | peer_ctx->send_channel_ctx = add_channel_ctx (peer_ctx); |
677 | peer_ctx->send_channel_ctx->channel = | ||
621 | GNUNET_CADET_channel_create (cadet_handle, | 678 | GNUNET_CADET_channel_create (cadet_handle, |
622 | (struct GNUNET_PeerIdentity *) ctx_peer, /* context */ | 679 | peer_ctx->send_channel_ctx, /* context */ |
623 | peer, | 680 | peer, |
624 | &port, | 681 | &port, |
625 | GNUNET_CADET_OPTION_RELIABLE, | 682 | GNUNET_CADET_OPTION_RELIABLE, |
@@ -627,8 +684,9 @@ get_channel (const struct GNUNET_PeerIdentity *peer) | |||
627 | cleanup_destroyed_channel, /* Disconnect handler */ | 684 | cleanup_destroyed_channel, /* Disconnect handler */ |
628 | cadet_handlers); | 685 | cadet_handlers); |
629 | } | 686 | } |
630 | GNUNET_assert (NULL != peer_ctx->send_channel); | 687 | GNUNET_assert (NULL != peer_ctx->send_channel_ctx); |
631 | return peer_ctx->send_channel; | 688 | GNUNET_assert (NULL != peer_ctx->send_channel_ctx->channel); |
689 | return peer_ctx->send_channel_ctx->channel; | ||
632 | } | 690 | } |
633 | 691 | ||
634 | 692 | ||
@@ -1199,7 +1257,7 @@ Peers_check_removable (const struct GNUNET_PeerIdentity *peer) | |||
1199 | } | 1257 | } |
1200 | 1258 | ||
1201 | peer_ctx = get_peer_ctx (peer); | 1259 | peer_ctx = get_peer_ctx (peer); |
1202 | if ( (NULL != peer_ctx->recv_channel) || | 1260 | if ( (NULL != peer_ctx->recv_channel_ctx) || |
1203 | (NULL != peer_ctx->pending_messages_head) || | 1261 | (NULL != peer_ctx->pending_messages_head) || |
1204 | (GNUNET_NO == check_peer_flag_set (peer_ctx, Peers_PULL_REPLY_PENDING)) ) | 1262 | (GNUNET_NO == check_peer_flag_set (peer_ctx, Peers_PULL_REPLY_PENDING)) ) |
1205 | { | 1263 | { |
@@ -1269,23 +1327,28 @@ Peers_remove_peer (const struct GNUNET_PeerIdentity *peer) | |||
1269 | peer_ctx->liveliness_check_pending = NULL; | 1327 | peer_ctx->liveliness_check_pending = NULL; |
1270 | } | 1328 | } |
1271 | channel_flag = Peers_get_channel_flag (peer, Peers_CHANNEL_ROLE_SENDING); | 1329 | channel_flag = Peers_get_channel_flag (peer, Peers_CHANNEL_ROLE_SENDING); |
1272 | if (NULL != peer_ctx->send_channel && | 1330 | if (NULL != peer_ctx->send_channel_ctx && |
1273 | GNUNET_YES != Peers_check_channel_flag (channel_flag, Peers_CHANNEL_DESTROING)) | 1331 | GNUNET_YES != Peers_check_channel_flag (channel_flag, Peers_CHANNEL_DESTROING)) |
1274 | { | 1332 | { |
1275 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 1333 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
1276 | "Destroying send channel\n"); | 1334 | "Destroying send channel\n"); |
1277 | GNUNET_CADET_channel_destroy (peer_ctx->send_channel); | 1335 | GNUNET_CADET_channel_destroy (peer_ctx->send_channel_ctx->channel); |
1278 | peer_ctx->send_channel = NULL; | 1336 | remove_channel_ctx (peer_ctx->send_channel_ctx); |
1337 | peer_ctx->send_channel_ctx = NULL; | ||
1279 | peer_ctx->mq = NULL; | 1338 | peer_ctx->mq = NULL; |
1280 | } | 1339 | } |
1281 | channel_flag = Peers_get_channel_flag (peer, Peers_CHANNEL_ROLE_RECEIVING); | 1340 | channel_flag = Peers_get_channel_flag (peer, Peers_CHANNEL_ROLE_RECEIVING); |
1282 | if (NULL != peer_ctx->recv_channel && | 1341 | if (NULL != peer_ctx->recv_channel_ctx && |
1283 | GNUNET_YES != Peers_check_channel_flag (channel_flag, Peers_CHANNEL_DESTROING)) | 1342 | GNUNET_YES != Peers_check_channel_flag (channel_flag, Peers_CHANNEL_DESTROING)) |
1284 | { | 1343 | { |
1285 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 1344 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
1286 | "Destroying recv channel\n"); | 1345 | "Destroying recv channel\n"); |
1287 | GNUNET_CADET_channel_destroy (peer_ctx->recv_channel); | 1346 | GNUNET_CADET_channel_destroy (peer_ctx->recv_channel_ctx->channel); |
1288 | peer_ctx->recv_channel = NULL; | 1347 | if (NULL != peer_ctx->recv_channel_ctx) |
1348 | { | ||
1349 | remove_channel_ctx (peer_ctx->recv_channel_ctx); | ||
1350 | } | ||
1351 | peer_ctx->recv_channel_ctx = NULL; | ||
1289 | } | 1352 | } |
1290 | 1353 | ||
1291 | GNUNET_free (peer_ctx->send_channel_flags); | 1354 | GNUNET_free (peer_ctx->send_channel_flags); |
@@ -1496,7 +1559,7 @@ Peers_check_peer_send_intention (const struct GNUNET_PeerIdentity *peer) | |||
1496 | const struct PeerContext *peer_ctx; | 1559 | const struct PeerContext *peer_ctx; |
1497 | 1560 | ||
1498 | peer_ctx = get_peer_ctx (peer); | 1561 | peer_ctx = get_peer_ctx (peer); |
1499 | if (NULL != peer_ctx->recv_channel) | 1562 | if (NULL != peer_ctx->recv_channel_ctx) |
1500 | { | 1563 | { |
1501 | return GNUNET_YES; | 1564 | return GNUNET_YES; |
1502 | } | 1565 | } |
@@ -1521,6 +1584,7 @@ Peers_handle_inbound_channel (void *cls, | |||
1521 | { | 1584 | { |
1522 | struct PeerContext *peer_ctx; | 1585 | struct PeerContext *peer_ctx; |
1523 | struct GNUNET_PeerIdentity *ctx_peer; | 1586 | struct GNUNET_PeerIdentity *ctx_peer; |
1587 | struct ChannelCtx *channel_ctx; | ||
1524 | 1588 | ||
1525 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 1589 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
1526 | "New channel was established to us (Peer %s).\n", | 1590 | "New channel was established to us (Peer %s).\n", |
@@ -1531,6 +1595,8 @@ Peers_handle_inbound_channel (void *cls, | |||
1531 | set_peer_live (peer_ctx); | 1595 | set_peer_live (peer_ctx); |
1532 | ctx_peer = GNUNET_new (struct GNUNET_PeerIdentity); | 1596 | ctx_peer = GNUNET_new (struct GNUNET_PeerIdentity); |
1533 | *ctx_peer = *initiator; | 1597 | *ctx_peer = *initiator; |
1598 | channel_ctx = add_channel_ctx (peer_ctx); | ||
1599 | channel_ctx->channel = channel; | ||
1534 | /* We only accept one incoming channel per peer */ | 1600 | /* We only accept one incoming channel per peer */ |
1535 | if (GNUNET_YES == Peers_check_peer_send_intention (initiator)) | 1601 | if (GNUNET_YES == Peers_check_peer_send_intention (initiator)) |
1536 | { | 1602 | { |
@@ -1540,13 +1606,14 @@ Peers_handle_inbound_channel (void *cls, | |||
1540 | set_channel_flag (peer_ctx->recv_channel_flags, | 1606 | set_channel_flag (peer_ctx->recv_channel_flags, |
1541 | Peers_CHANNEL_ESTABLISHED_TWICE); | 1607 | Peers_CHANNEL_ESTABLISHED_TWICE); |
1542 | //GNUNET_CADET_channel_destroy (channel); | 1608 | //GNUNET_CADET_channel_destroy (channel); |
1543 | GNUNET_CADET_channel_destroy (peer_ctx->recv_channel); | 1609 | GNUNET_CADET_channel_destroy (peer_ctx->recv_channel_ctx->channel); |
1544 | peer_ctx->recv_channel = channel; | 1610 | remove_channel_ctx (peer_ctx->recv_channel_ctx); |
1611 | peer_ctx->recv_channel_ctx = channel_ctx; | ||
1545 | /* return the channel context */ | 1612 | /* return the channel context */ |
1546 | return ctx_peer; | 1613 | return channel_ctx; |
1547 | } | 1614 | } |
1548 | peer_ctx->recv_channel = channel; | 1615 | peer_ctx->recv_channel_ctx = channel_ctx; |
1549 | return ctx_peer; | 1616 | return channel_ctx; |
1550 | } | 1617 | } |
1551 | 1618 | ||
1552 | 1619 | ||
@@ -1568,7 +1635,7 @@ Peers_check_sending_channel_exists (const struct GNUNET_PeerIdentity *peer) | |||
1568 | return GNUNET_NO; | 1635 | return GNUNET_NO; |
1569 | } | 1636 | } |
1570 | peer_ctx = get_peer_ctx (peer); | 1637 | peer_ctx = get_peer_ctx (peer); |
1571 | if (NULL == peer_ctx->send_channel) | 1638 | if (NULL == peer_ctx->send_channel_ctx) |
1572 | { | 1639 | { |
1573 | return GNUNET_NO; | 1640 | return GNUNET_NO; |
1574 | } | 1641 | } |
@@ -1601,12 +1668,14 @@ Peers_check_channel_role (const struct GNUNET_PeerIdentity *peer, | |||
1601 | } | 1668 | } |
1602 | peer_ctx = get_peer_ctx (peer); | 1669 | peer_ctx = get_peer_ctx (peer); |
1603 | if ( (Peers_CHANNEL_ROLE_SENDING == role) && | 1670 | if ( (Peers_CHANNEL_ROLE_SENDING == role) && |
1604 | (channel == peer_ctx->send_channel) ) | 1671 | (NULL != peer_ctx->send_channel_ctx) && |
1672 | (channel == peer_ctx->send_channel_ctx->channel) ) | ||
1605 | { | 1673 | { |
1606 | return GNUNET_YES; | 1674 | return GNUNET_YES; |
1607 | } | 1675 | } |
1608 | if ( (Peers_CHANNEL_ROLE_RECEIVING == role) && | 1676 | if ( (Peers_CHANNEL_ROLE_RECEIVING == role) && |
1609 | (channel == peer_ctx->recv_channel) ) | 1677 | (NULL != peer_ctx->recv_channel_ctx) && |
1678 | (channel == peer_ctx->recv_channel_ctx->channel) ) | ||
1610 | { | 1679 | { |
1611 | return GNUNET_YES; | 1680 | return GNUNET_YES; |
1612 | } | 1681 | } |
@@ -1636,11 +1705,11 @@ Peers_destroy_sending_channel (const struct GNUNET_PeerIdentity *peer) | |||
1636 | return GNUNET_NO; | 1705 | return GNUNET_NO; |
1637 | } | 1706 | } |
1638 | peer_ctx = get_peer_ctx (peer); | 1707 | peer_ctx = get_peer_ctx (peer); |
1639 | if (NULL != peer_ctx->send_channel) | 1708 | if (NULL != peer_ctx->send_channel_ctx) |
1640 | { | 1709 | { |
1641 | set_channel_flag (peer_ctx->send_channel_flags, Peers_CHANNEL_CLEAN); | 1710 | set_channel_flag (peer_ctx->send_channel_flags, Peers_CHANNEL_CLEAN); |
1642 | GNUNET_CADET_channel_destroy (peer_ctx->send_channel); | 1711 | GNUNET_CADET_channel_destroy (peer_ctx->send_channel_ctx->channel); |
1643 | peer_ctx->send_channel = NULL; | 1712 | peer_ctx->send_channel_ctx = NULL; |
1644 | peer_ctx->mq = NULL; | 1713 | peer_ctx->mq = NULL; |
1645 | (void) Peers_check_connected (peer); | 1714 | (void) Peers_check_connected (peer); |
1646 | return GNUNET_YES; | 1715 | return GNUNET_YES; |
@@ -1648,6 +1717,35 @@ Peers_destroy_sending_channel (const struct GNUNET_PeerIdentity *peer) | |||
1648 | return GNUNET_NO; | 1717 | return GNUNET_NO; |
1649 | } | 1718 | } |
1650 | 1719 | ||
1720 | static void | ||
1721 | destroy_channel (void *cls) | ||
1722 | { | ||
1723 | struct ChannelCtx *channel_ctx = cls; | ||
1724 | struct PeerContext *peer_ctx = channel_ctx->peer_ctx; | ||
1725 | uint32_t *channel_flag; | ||
1726 | |||
1727 | channel_ctx = NULL; | ||
1728 | GNUNET_CADET_channel_destroy (peer_ctx->send_channel_ctx->channel); | ||
1729 | channel_flag = Peers_get_channel_flag (&peer_ctx->peer_id, Peers_CHANNEL_ROLE_SENDING); | ||
1730 | Peers_set_channel_flag (channel_flag, Peers_CHANNEL_DESTROING); | ||
1731 | remove_channel_ctx (peer_ctx->send_channel_ctx); | ||
1732 | peer_ctx->send_channel_ctx = NULL; | ||
1733 | if (channel_ctx == peer_ctx->send_channel_ctx) | ||
1734 | { | ||
1735 | peer_ctx->mq = NULL; | ||
1736 | } | ||
1737 | } | ||
1738 | |||
1739 | static void | ||
1740 | schedule_channel_destruction (struct ChannelCtx *channel_ctx) | ||
1741 | { | ||
1742 | if (NULL != channel_ctx->destruction_task) | ||
1743 | { | ||
1744 | channel_ctx->destruction_task = | ||
1745 | GNUNET_SCHEDULER_add_now (destroy_channel, channel_ctx); | ||
1746 | } | ||
1747 | } | ||
1748 | |||
1651 | /** | 1749 | /** |
1652 | * This is called when a channel is destroyed. | 1750 | * This is called when a channel is destroyed. |
1653 | * | 1751 | * |
@@ -1658,9 +1756,9 @@ void | |||
1658 | Peers_cleanup_destroyed_channel (void *cls, | 1756 | Peers_cleanup_destroyed_channel (void *cls, |
1659 | const struct GNUNET_CADET_Channel *channel) | 1757 | const struct GNUNET_CADET_Channel *channel) |
1660 | { | 1758 | { |
1661 | struct GNUNET_PeerIdentity *peer = cls; | 1759 | struct ChannelCtx *channel_ctx = cls; |
1662 | struct PeerContext *peer_ctx; | 1760 | const struct GNUNET_PeerIdentity *peer = &channel_ctx->peer_ctx->peer_id; |
1663 | uint32_t *channel_flag; | 1761 | struct PeerContext *peer_ctx = channel_ctx->peer_ctx; |
1664 | 1762 | ||
1665 | if (GNUNET_NO == Peers_check_peer_known (peer)) | 1763 | if (GNUNET_NO == Peers_check_peer_known (peer)) |
1666 | {/* We don't want to implicitly create a context that we're about to kill */ | 1764 | {/* We don't want to implicitly create a context that we're about to kill */ |
@@ -1669,7 +1767,6 @@ Peers_cleanup_destroyed_channel (void *cls, | |||
1669 | GNUNET_i2s (peer)); | 1767 | GNUNET_i2s (peer)); |
1670 | return; | 1768 | return; |
1671 | } | 1769 | } |
1672 | peer_ctx = get_peer_ctx (peer); | ||
1673 | 1770 | ||
1674 | /* If our peer issued the destruction of the channel, the #Peers_TO_DESTROY | 1771 | /* If our peer issued the destruction of the channel, the #Peers_TO_DESTROY |
1675 | * flag will be set. In this case simply make sure that the channels are | 1772 | * flag will be set. In this case simply make sure that the channels are |
@@ -1679,30 +1776,23 @@ Peers_cleanup_destroyed_channel (void *cls, | |||
1679 | {/* We initiatad the destruction of this particular peer */ | 1776 | {/* We initiatad the destruction of this particular peer */ |
1680 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 1777 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
1681 | "Peer is in the process of being destroyed\n"); | 1778 | "Peer is in the process of being destroyed\n"); |
1682 | if (channel == peer_ctx->send_channel) | 1779 | if (channel == channel_ctx->channel) |
1683 | { | 1780 | { |
1684 | peer_ctx->send_channel = NULL; | 1781 | peer_ctx->send_channel_ctx = NULL; |
1685 | peer_ctx->mq = NULL; | 1782 | peer_ctx->mq = NULL; |
1686 | } | 1783 | } |
1687 | else if (channel == peer_ctx->recv_channel) | 1784 | else if (channel == peer_ctx->recv_channel_ctx->channel) |
1688 | { | 1785 | { |
1689 | peer_ctx->recv_channel = NULL; | 1786 | peer_ctx->recv_channel_ctx = NULL; |
1690 | } | 1787 | } |
1691 | 1788 | ||
1692 | if (NULL != peer_ctx->send_channel) | 1789 | if (NULL != peer_ctx->send_channel_ctx) |
1693 | { | 1790 | { |
1694 | GNUNET_CADET_channel_destroy (peer_ctx->send_channel); | 1791 | schedule_channel_destruction (peer_ctx->send_channel_ctx); |
1695 | channel_flag = Peers_get_channel_flag (&peer_ctx->peer_id, Peers_CHANNEL_ROLE_SENDING); | ||
1696 | Peers_set_channel_flag (channel_flag, Peers_CHANNEL_DESTROING); | ||
1697 | peer_ctx->send_channel = NULL; | ||
1698 | peer_ctx->mq = NULL; | ||
1699 | } | 1792 | } |
1700 | if (NULL != peer_ctx->recv_channel) | 1793 | if (NULL != peer_ctx->recv_channel_ctx) |
1701 | { | 1794 | { |
1702 | GNUNET_CADET_channel_destroy (peer_ctx->recv_channel); | 1795 | schedule_channel_destruction (peer_ctx->recv_channel_ctx); |
1703 | channel_flag = Peers_get_channel_flag (&peer_ctx->peer_id, Peers_CHANNEL_ROLE_RECEIVING); | ||
1704 | Peers_set_channel_flag (channel_flag, Peers_CHANNEL_DESTROING); | ||
1705 | peer_ctx->recv_channel = NULL; | ||
1706 | } | 1796 | } |
1707 | /* Set the #Peers_ONLINE flag accordingly */ | 1797 | /* Set the #Peers_ONLINE flag accordingly */ |
1708 | (void) Peers_check_connected (peer); | 1798 | (void) Peers_check_connected (peer); |
@@ -1713,20 +1803,22 @@ Peers_cleanup_destroyed_channel (void *cls, | |||
1713 | { /* We did not initiate the destruction of this peer */ | 1803 | { /* We did not initiate the destruction of this peer */ |
1714 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 1804 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
1715 | "Peer is NOT in the process of being destroyed\n"); | 1805 | "Peer is NOT in the process of being destroyed\n"); |
1716 | if (channel == peer_ctx->send_channel) | 1806 | if ( (NULL != peer_ctx->send_channel_ctx) && |
1807 | (channel == peer_ctx->send_channel_ctx->channel) ) | ||
1717 | { /* Something (but us) killd the channel - clean up peer */ | 1808 | { /* Something (but us) killd the channel - clean up peer */ |
1718 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 1809 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
1719 | "send channel (%s) was destroyed - cleaning up\n", | 1810 | "send channel (%s) was destroyed - cleaning up\n", |
1720 | GNUNET_i2s (peer)); | 1811 | GNUNET_i2s (peer)); |
1721 | peer_ctx->send_channel = NULL; | 1812 | peer_ctx->send_channel_ctx = NULL; |
1722 | peer_ctx->mq = NULL; | 1813 | peer_ctx->mq = NULL; |
1723 | } | 1814 | } |
1724 | else if (channel == peer_ctx->recv_channel) | 1815 | else if ( (NULL != peer_ctx->recv_channel_ctx) && |
1816 | (channel == peer_ctx->recv_channel_ctx->channel) ) | ||
1725 | { /* Other peer doesn't want to send us messages anymore */ | 1817 | { /* Other peer doesn't want to send us messages anymore */ |
1726 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 1818 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
1727 | "Peer %s destroyed recv channel - cleaning up channel\n", | 1819 | "Peer %s destroyed recv channel - cleaning up channel\n", |
1728 | GNUNET_i2s (peer)); | 1820 | GNUNET_i2s (peer)); |
1729 | peer_ctx->recv_channel = NULL; | 1821 | peer_ctx->recv_channel_ctx = NULL; |
1730 | } | 1822 | } |
1731 | else | 1823 | else |
1732 | { | 1824 | { |
@@ -1818,7 +1910,7 @@ Peers_get_recv_channel (const struct GNUNET_PeerIdentity *peer) | |||
1818 | 1910 | ||
1819 | GNUNET_assert (GNUNET_YES == Peers_check_peer_known (peer)); | 1911 | GNUNET_assert (GNUNET_YES == Peers_check_peer_known (peer)); |
1820 | peer_ctx = get_peer_ctx (peer); | 1912 | peer_ctx = get_peer_ctx (peer); |
1821 | return peer_ctx->recv_channel; | 1913 | return peer_ctx->recv_channel_ctx->channel; |
1822 | } | 1914 | } |
1823 | /*********************************************************************** | 1915 | /*********************************************************************** |
1824 | * /Old gnunet-service-rps_peers.c | 1916 | * /Old gnunet-service-rps_peers.c |
@@ -2655,6 +2747,35 @@ clean_peer (const struct GNUNET_PeerIdentity *peer) | |||
2655 | } | 2747 | } |
2656 | 2748 | ||
2657 | /** | 2749 | /** |
2750 | * @brief Allocate memory for a new channel context and insert it into DLL | ||
2751 | * | ||
2752 | * @param peer_ctx context of the according peer | ||
2753 | * | ||
2754 | * @return The channel context | ||
2755 | */ | ||
2756 | static struct ChannelCtx * | ||
2757 | add_channel_ctx (struct PeerContext *peer_ctx) | ||
2758 | { | ||
2759 | struct ChannelCtx *channel_ctx; | ||
2760 | channel_ctx = GNUNET_new (struct ChannelCtx); | ||
2761 | channel_ctx->peer_ctx = peer_ctx; | ||
2762 | GNUNET_CONTAINER_DLL_insert (channel_ctx_head, channel_ctx_tail, channel_ctx); | ||
2763 | return channel_ctx; | ||
2764 | } | ||
2765 | |||
2766 | /** | ||
2767 | * @brief Remove the channel context from the DLL and free the memory. | ||
2768 | * | ||
2769 | * @param channel_ctx The channel context. | ||
2770 | */ | ||
2771 | static void | ||
2772 | remove_channel_ctx (struct ChannelCtx *channel_ctx) | ||
2773 | { | ||
2774 | GNUNET_CONTAINER_DLL_remove (channel_ctx_head, channel_ctx_tail, channel_ctx); | ||
2775 | GNUNET_free (channel_ctx); | ||
2776 | } | ||
2777 | |||
2778 | /** | ||
2658 | * @brief This is called when a channel is destroyed. | 2779 | * @brief This is called when a channel is destroyed. |
2659 | * | 2780 | * |
2660 | * Removes peer completely from our knowledge if the send_channel was destroyed | 2781 | * Removes peer completely from our knowledge if the send_channel was destroyed |
@@ -2670,7 +2791,8 @@ static void | |||
2670 | cleanup_destroyed_channel (void *cls, | 2791 | cleanup_destroyed_channel (void *cls, |
2671 | const struct GNUNET_CADET_Channel *channel) | 2792 | const struct GNUNET_CADET_Channel *channel) |
2672 | { | 2793 | { |
2673 | struct GNUNET_PeerIdentity *peer = cls; | 2794 | struct ChannelCtx *channel_ctx = cls; |
2795 | struct GNUNET_PeerIdentity *peer = &channel_ctx->peer_ctx->peer_id; | ||
2674 | uint32_t *channel_flag; | 2796 | uint32_t *channel_flag; |
2675 | struct PeerContext *peer_ctx; | 2797 | struct PeerContext *peer_ctx; |
2676 | 2798 | ||
@@ -2681,7 +2803,7 @@ cleanup_destroyed_channel (void *cls, | |||
2681 | LOG (GNUNET_ERROR_TYPE_WARNING, | 2803 | LOG (GNUNET_ERROR_TYPE_WARNING, |
2682 | "channel (%s) without associated context was destroyed\n", | 2804 | "channel (%s) without associated context was destroyed\n", |
2683 | GNUNET_i2s (peer)); | 2805 | GNUNET_i2s (peer)); |
2684 | GNUNET_free (peer); | 2806 | remove_channel_ctx (channel_ctx); |
2685 | return; | 2807 | return; |
2686 | } | 2808 | } |
2687 | 2809 | ||
@@ -2710,7 +2832,21 @@ cleanup_destroyed_channel (void *cls, | |||
2710 | to_file (file_name_view_log, | 2832 | to_file (file_name_view_log, |
2711 | "-%s\t(cleanup channel, ourself)", | 2833 | "-%s\t(cleanup channel, ourself)", |
2712 | GNUNET_i2s_full (peer)); | 2834 | GNUNET_i2s_full (peer)); |
2713 | GNUNET_free (peer); | 2835 | remove_channel_ctx (channel_ctx); |
2836 | if (peer_ctx->send_channel_ctx == channel_ctx) | ||
2837 | { | ||
2838 | peer_ctx->send_channel_ctx = NULL; | ||
2839 | } | ||
2840 | else if (peer_ctx->recv_channel_ctx == channel_ctx) | ||
2841 | { | ||
2842 | peer_ctx->recv_channel_ctx = NULL; | ||
2843 | } | ||
2844 | else | ||
2845 | { | ||
2846 | LOG (GNUNET_ERROR_TYPE_ERROR, | ||
2847 | "Trying to remove channel_ctx that is not associated with a peer\n"); | ||
2848 | GNUNET_assert (0); | ||
2849 | } | ||
2714 | return; | 2850 | return; |
2715 | } | 2851 | } |
2716 | 2852 | ||
@@ -2726,7 +2862,7 @@ cleanup_destroyed_channel (void *cls, | |||
2726 | { /* We are about to clean the sending channel. Clean the respective | 2862 | { /* We are about to clean the sending channel. Clean the respective |
2727 | * context */ | 2863 | * context */ |
2728 | Peers_cleanup_destroyed_channel (cls, channel); | 2864 | Peers_cleanup_destroyed_channel (cls, channel); |
2729 | GNUNET_free (peer); | 2865 | remove_channel_ctx (channel_ctx); |
2730 | return; | 2866 | return; |
2731 | } | 2867 | } |
2732 | else | 2868 | else |
@@ -2734,7 +2870,7 @@ cleanup_destroyed_channel (void *cls, | |||
2734 | * open. It probably went down. Remove it from our knowledge. */ | 2870 | * open. It probably went down. Remove it from our knowledge. */ |
2735 | Peers_cleanup_destroyed_channel (cls, channel); | 2871 | Peers_cleanup_destroyed_channel (cls, channel); |
2736 | remove_peer (peer); | 2872 | remove_peer (peer); |
2737 | GNUNET_free (peer); | 2873 | remove_channel_ctx (channel_ctx); |
2738 | return; | 2874 | return; |
2739 | } | 2875 | } |
2740 | } | 2876 | } |
@@ -2751,7 +2887,7 @@ cleanup_destroyed_channel (void *cls, | |||
2751 | { /* Other peer tried to establish a channel to us twice. We do not accept | 2887 | { /* Other peer tried to establish a channel to us twice. We do not accept |
2752 | * that. Clean the context. */ | 2888 | * that. Clean the context. */ |
2753 | Peers_cleanup_destroyed_channel (cls, channel); | 2889 | Peers_cleanup_destroyed_channel (cls, channel); |
2754 | GNUNET_free (peer); | 2890 | remove_channel_ctx (channel_ctx); |
2755 | return; | 2891 | return; |
2756 | } | 2892 | } |
2757 | else | 2893 | else |
@@ -2759,7 +2895,7 @@ cleanup_destroyed_channel (void *cls, | |||
2759 | * it. */ | 2895 | * it. */ |
2760 | Peers_cleanup_destroyed_channel (cls, channel); | 2896 | Peers_cleanup_destroyed_channel (cls, channel); |
2761 | clean_peer (peer); | 2897 | clean_peer (peer); |
2762 | GNUNET_free (peer); | 2898 | remove_channel_ctx (channel_ctx); |
2763 | return; | 2899 | return; |
2764 | } | 2900 | } |
2765 | } | 2901 | } |
@@ -2768,7 +2904,7 @@ cleanup_destroyed_channel (void *cls, | |||
2768 | LOG (GNUNET_ERROR_TYPE_WARNING, | 2904 | LOG (GNUNET_ERROR_TYPE_WARNING, |
2769 | "Destroyed channel is neither sending nor receiving channel\n"); | 2905 | "Destroyed channel is neither sending nor receiving channel\n"); |
2770 | } | 2906 | } |
2771 | GNUNET_free (peer); | 2907 | remove_channel_ctx (channel_ctx); |
2772 | } | 2908 | } |
2773 | 2909 | ||
2774 | /*********************************************************************** | 2910 | /*********************************************************************** |
@@ -3163,11 +3299,12 @@ static void | |||
3163 | handle_peer_check (void *cls, | 3299 | handle_peer_check (void *cls, |
3164 | const struct GNUNET_MessageHeader *msg) | 3300 | const struct GNUNET_MessageHeader *msg) |
3165 | { | 3301 | { |
3166 | const struct GNUNET_PeerIdentity *peer = cls; | 3302 | const struct ChannelCtx *channel_ctx = cls; |
3303 | const struct GNUNET_PeerIdentity *peer = &channel_ctx->peer_ctx->peer_id; | ||
3167 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 3304 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
3168 | "Received CHECK_LIVE (%s)\n", GNUNET_i2s (peer)); | 3305 | "Received CHECK_LIVE (%s)\n", GNUNET_i2s (peer)); |
3169 | 3306 | ||
3170 | GNUNET_CADET_receive_done (Peers_get_recv_channel (peer)); | 3307 | GNUNET_CADET_receive_done (channel_ctx->channel); |
3171 | } | 3308 | } |
3172 | 3309 | ||
3173 | /** | 3310 | /** |
@@ -3183,7 +3320,8 @@ static void | |||
3183 | handle_peer_push (void *cls, | 3320 | handle_peer_push (void *cls, |
3184 | const struct GNUNET_MessageHeader *msg) | 3321 | const struct GNUNET_MessageHeader *msg) |
3185 | { | 3322 | { |
3186 | const struct GNUNET_PeerIdentity *peer = cls; | 3323 | const struct ChannelCtx *channel_ctx = cls; |
3324 | const struct GNUNET_PeerIdentity *peer = &channel_ctx->peer_ctx->peer_id; | ||
3187 | 3325 | ||
3188 | // (check the proof of work (?)) | 3326 | // (check the proof of work (?)) |
3189 | 3327 | ||
@@ -3228,7 +3366,7 @@ handle_peer_push (void *cls, | |||
3228 | CustomPeerMap_put (push_map, peer); | 3366 | CustomPeerMap_put (push_map, peer); |
3229 | 3367 | ||
3230 | GNUNET_break_op (Peers_check_peer_known (peer)); | 3368 | GNUNET_break_op (Peers_check_peer_known (peer)); |
3231 | GNUNET_CADET_receive_done (Peers_get_recv_channel (peer)); | 3369 | GNUNET_CADET_receive_done (channel_ctx->channel); |
3232 | } | 3370 | } |
3233 | 3371 | ||
3234 | 3372 | ||
@@ -3244,7 +3382,8 @@ static void | |||
3244 | handle_peer_pull_request (void *cls, | 3382 | handle_peer_pull_request (void *cls, |
3245 | const struct GNUNET_MessageHeader *msg) | 3383 | const struct GNUNET_MessageHeader *msg) |
3246 | { | 3384 | { |
3247 | struct GNUNET_PeerIdentity *peer = cls; | 3385 | const struct ChannelCtx *channel_ctx = cls; |
3386 | const struct GNUNET_PeerIdentity *peer = &channel_ctx->peer_ctx->peer_id; | ||
3248 | const struct GNUNET_PeerIdentity *view_array; | 3387 | const struct GNUNET_PeerIdentity *view_array; |
3249 | 3388 | ||
3250 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Received PULL REQUEST (%s)\n", GNUNET_i2s (peer)); | 3389 | LOG (GNUNET_ERROR_TYPE_DEBUG, "Received PULL REQUEST (%s)\n", GNUNET_i2s (peer)); |
@@ -3267,7 +3406,7 @@ handle_peer_pull_request (void *cls, | |||
3267 | #endif /* ENABLE_MALICIOUS */ | 3406 | #endif /* ENABLE_MALICIOUS */ |
3268 | 3407 | ||
3269 | GNUNET_break_op (Peers_check_peer_known (peer)); | 3408 | GNUNET_break_op (Peers_check_peer_known (peer)); |
3270 | GNUNET_CADET_receive_done (Peers_get_recv_channel (peer)); | 3409 | GNUNET_CADET_receive_done (channel_ctx->channel); |
3271 | view_array = View_get_as_array (); | 3410 | view_array = View_get_as_array (); |
3272 | send_pull_reply (peer, view_array, View_size ()); | 3411 | send_pull_reply (peer, view_array, View_size ()); |
3273 | } | 3412 | } |
@@ -3324,8 +3463,9 @@ static void | |||
3324 | handle_peer_pull_reply (void *cls, | 3463 | handle_peer_pull_reply (void *cls, |
3325 | const struct GNUNET_RPS_P2P_PullReplyMessage *msg) | 3464 | const struct GNUNET_RPS_P2P_PullReplyMessage *msg) |
3326 | { | 3465 | { |
3466 | const struct ChannelCtx *channel_ctx = cls; | ||
3467 | const struct GNUNET_PeerIdentity *sender = &channel_ctx->peer_ctx->peer_id; | ||
3327 | const struct GNUNET_PeerIdentity *peers; | 3468 | const struct GNUNET_PeerIdentity *peers; |
3328 | struct GNUNET_PeerIdentity *sender = cls; | ||
3329 | uint32_t i; | 3469 | uint32_t i; |
3330 | #ifdef ENABLE_MALICIOUS | 3470 | #ifdef ENABLE_MALICIOUS |
3331 | struct AttackedPeer *tmp_att_peer; | 3471 | struct AttackedPeer *tmp_att_peer; |
@@ -3393,7 +3533,7 @@ handle_peer_pull_reply (void *cls, | |||
3393 | clean_peer (sender); | 3533 | clean_peer (sender); |
3394 | 3534 | ||
3395 | GNUNET_break_op (Peers_check_peer_known (sender)); | 3535 | GNUNET_break_op (Peers_check_peer_known (sender)); |
3396 | GNUNET_CADET_receive_done (Peers_get_recv_channel (sender)); | 3536 | GNUNET_CADET_receive_done (channel_ctx->channel); |
3397 | } | 3537 | } |
3398 | 3538 | ||
3399 | 3539 | ||
@@ -4105,6 +4245,7 @@ shutdown_task (void *cls) | |||
4105 | { | 4245 | { |
4106 | struct ClientContext *client_ctx; | 4246 | struct ClientContext *client_ctx; |
4107 | struct ReplyCls *reply_cls; | 4247 | struct ReplyCls *reply_cls; |
4248 | struct ChannelCtx *channel_ctx; | ||
4108 | 4249 | ||
4109 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 4250 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
4110 | "RPS is going down\n"); | 4251 | "RPS is going down\n"); |
@@ -4128,6 +4269,11 @@ shutdown_task (void *cls) | |||
4128 | GNUNET_CONTAINER_DLL_remove (cli_ctx_head, cli_ctx_tail, client_ctx); | 4269 | GNUNET_CONTAINER_DLL_remove (cli_ctx_head, cli_ctx_tail, client_ctx); |
4129 | GNUNET_free (client_ctx); | 4270 | GNUNET_free (client_ctx); |
4130 | } | 4271 | } |
4272 | /* Clean all leftover channel contexts */ | ||
4273 | while (NULL != (channel_ctx = channel_ctx_head)) | ||
4274 | { | ||
4275 | remove_channel_ctx (channel_ctx); | ||
4276 | } | ||
4131 | GNUNET_PEERINFO_notify_cancel (peerinfo_notify_handle); | 4277 | GNUNET_PEERINFO_notify_cancel (peerinfo_notify_handle); |
4132 | GNUNET_PEERINFO_disconnect (peerinfo_handle); | 4278 | GNUNET_PEERINFO_disconnect (peerinfo_handle); |
4133 | 4279 | ||