diff options
author | Bart Polot <bart@net.in.tum.de> | 2013-05-10 09:40:23 +0000 |
---|---|---|
committer | Bart Polot <bart@net.in.tum.de> | 2013-05-10 09:40:23 +0000 |
commit | 714190bb8feb1933a4e5bf4f06944f91a6a19c92 (patch) | |
tree | 8b5a63191937a20dc253258fdbed4228c70c2cd9 | |
parent | bb9966e197621f0c118201553474df06083d93e1 (diff) | |
download | gnunet-714190bb8feb1933a4e5bf4f06944f91a6a19c92.tar.gz gnunet-714190bb8feb1933a4e5bf4f06944f91a6a19c92.zip |
- remove trees from tunnels
-rw-r--r-- | src/mesh/gnunet-service-mesh-new.c | 314 |
1 files changed, 94 insertions, 220 deletions
diff --git a/src/mesh/gnunet-service-mesh-new.c b/src/mesh/gnunet-service-mesh-new.c index e34fb9c0e..82d551b82 100644 --- a/src/mesh/gnunet-service-mesh-new.c +++ b/src/mesh/gnunet-service-mesh-new.c | |||
@@ -424,15 +424,9 @@ struct MeshTunnel | |||
424 | unsigned int nignore; | 424 | unsigned int nignore; |
425 | 425 | ||
426 | /** | 426 | /** |
427 | * Bloomfilter (for peer identities) to stop circular routes | 427 | * Path being used for the tunnel. |
428 | */ | 428 | */ |
429 | char bloomfilter[MESH_BLOOM_SIZE]; | 429 | struct MeshPeerPath *path; |
430 | |||
431 | /** | ||
432 | * Tunnel paths | ||
433 | * FIXME just a path | ||
434 | */ | ||
435 | struct MeshTunnelTree *tree; | ||
436 | 430 | ||
437 | /** | 431 | /** |
438 | * Task to keep the used paths alive | 432 | * Task to keep the used paths alive |
@@ -901,7 +895,7 @@ tunnel_add_client (struct MeshTunnel *t, struct MeshClient *c); | |||
901 | * @param p Path to use. | 895 | * @param p Path to use. |
902 | */ | 896 | */ |
903 | static void | 897 | static void |
904 | tunnel_use_path (struct MeshTunnel *t, const struct MeshPeerPath *p); | 898 | tunnel_use_path (struct MeshTunnel *t, struct MeshPeerPath *p); |
905 | 899 | ||
906 | /** | 900 | /** |
907 | * @brief Queue and pass message to core when possible. | 901 | * @brief Queue and pass message to core when possible. |
@@ -1633,18 +1627,19 @@ send_create_path (struct MeshPeerInfo *peer, struct MeshPeerPath *p, | |||
1633 | 1627 | ||
1634 | 1628 | ||
1635 | /** | 1629 | /** |
1636 | * Sends a DESTROY PATH message to free resources for a path in a tunnel | 1630 | * Sends a DESTROY PATH message to free resources for a path in a tunnel. |
1631 | * Does not free the path itself. | ||
1637 | * | 1632 | * |
1638 | * @param t Tunnel whose path to destroy. | 1633 | * @param t Tunnel whose path to destroy. |
1639 | * @param destination Short ID of the peer to whom the path to destroy. | 1634 | * @param destination Short ID of the peer to whom the path to destroy. |
1640 | */ | 1635 | */ |
1641 | static void | 1636 | static void |
1642 | send_destroy_path (struct MeshTunnel *t, GNUNET_PEER_Id destination) | 1637 | send_destroy_path (struct MeshTunnel *t) |
1643 | { | 1638 | { |
1644 | struct MeshPeerPath *p; | 1639 | struct MeshPeerPath *p; |
1645 | size_t size; | 1640 | size_t size; |
1646 | 1641 | ||
1647 | p = tree_get_path_to_peer (t->tree, destination); | 1642 | p = t->path; |
1648 | if (NULL == p) | 1643 | if (NULL == p) |
1649 | { | 1644 | { |
1650 | GNUNET_break (0); | 1645 | GNUNET_break (0); |
@@ -1655,6 +1650,7 @@ send_destroy_path (struct MeshTunnel *t, GNUNET_PEER_Id destination) | |||
1655 | { | 1650 | { |
1656 | struct GNUNET_MESH_ManipulatePath *msg; | 1651 | struct GNUNET_MESH_ManipulatePath *msg; |
1657 | struct GNUNET_PeerIdentity *pi; | 1652 | struct GNUNET_PeerIdentity *pi; |
1653 | struct GNUNET_PeerIdentity id; | ||
1658 | char cbuf[size]; | 1654 | char cbuf[size]; |
1659 | unsigned int i; | 1655 | unsigned int i; |
1660 | 1656 | ||
@@ -1667,9 +1663,9 @@ send_destroy_path (struct MeshTunnel *t, GNUNET_PEER_Id destination) | |||
1667 | { | 1663 | { |
1668 | GNUNET_PEER_resolve (p->peers[i], &pi[i]); | 1664 | GNUNET_PEER_resolve (p->peers[i], &pi[i]); |
1669 | } | 1665 | } |
1670 | send_prebuilt_message (&msg->header, tree_get_first_hop (t->tree, destination), t); | 1666 | GNUNET_PEER_resolve (t->next_hop, &id); |
1667 | send_prebuilt_message (&msg->header, &id, t); | ||
1671 | } | 1668 | } |
1672 | path_destroy (p); | ||
1673 | } | 1669 | } |
1674 | 1670 | ||
1675 | 1671 | ||
@@ -1683,10 +1679,8 @@ send_path_ack (struct MeshTunnel *t) | |||
1683 | { | 1679 | { |
1684 | struct MeshTransmissionDescriptor *info; | 1680 | struct MeshTransmissionDescriptor *info; |
1685 | struct GNUNET_PeerIdentity id; | 1681 | struct GNUNET_PeerIdentity id; |
1686 | GNUNET_PEER_Id peer; | ||
1687 | 1682 | ||
1688 | peer = tree_get_predecessor (t->tree); | 1683 | GNUNET_PEER_resolve (t->prev_hop, &id); |
1689 | GNUNET_PEER_resolve (peer, &id); | ||
1690 | info = GNUNET_malloc (sizeof (struct MeshTransmissionDescriptor)); | 1684 | info = GNUNET_malloc (sizeof (struct MeshTransmissionDescriptor)); |
1691 | info->origin = &t->id; | 1685 | info->origin = &t->id; |
1692 | info->peer = GNUNET_CONTAINER_multihashmap_get (peers, &id.hashPubKey); | 1686 | info->peer = GNUNET_CONTAINER_multihashmap_get (peers, &id.hashPubKey); |
@@ -1832,20 +1826,17 @@ peer_info_remove_path (struct MeshPeerInfo *peer, GNUNET_PEER_Id p1, | |||
1832 | GNUNET_PEER_Id p2) | 1826 | GNUNET_PEER_Id p2) |
1833 | { | 1827 | { |
1834 | struct MeshPeerPath *p; | 1828 | struct MeshPeerPath *p; |
1835 | struct MeshPeerPath *aux; | 1829 | struct MeshPeerPath *next; |
1836 | struct MeshPeerInfo *peer_d; | 1830 | struct MeshPeerInfo *peer_d; |
1837 | GNUNET_PEER_Id d; | 1831 | GNUNET_PEER_Id d; |
1838 | unsigned int destroyed; | 1832 | unsigned int destroyed; |
1839 | unsigned int best; | ||
1840 | unsigned int cost; | ||
1841 | unsigned int i; | 1833 | unsigned int i; |
1842 | 1834 | ||
1843 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "peer_info_remove_path\n"); | 1835 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "peer_info_remove_path\n"); |
1844 | destroyed = 0; | 1836 | destroyed = 0; |
1845 | p = peer->path_head; | 1837 | for (p = peer->path_head; NULL != p; p = next) |
1846 | while (NULL != p) | ||
1847 | { | 1838 | { |
1848 | aux = p->next; | 1839 | next = p->next; |
1849 | for (i = 0; i < (p->length - 1); i++) | 1840 | for (i = 0; i < (p->length - 1); i++) |
1850 | { | 1841 | { |
1851 | if ((p->peers[i] == p1 && p->peers[i + 1] == p2) || | 1842 | if ((p->peers[i] == p1 && p->peers[i + 1] == p2) || |
@@ -1857,7 +1848,6 @@ peer_info_remove_path (struct MeshPeerInfo *peer, GNUNET_PEER_Id p1, | |||
1857 | break; | 1848 | break; |
1858 | } | 1849 | } |
1859 | } | 1850 | } |
1860 | p = aux; | ||
1861 | } | 1851 | } |
1862 | if (0 == destroyed) | 1852 | if (0 == destroyed) |
1863 | return; | 1853 | return; |
@@ -1867,39 +1857,11 @@ peer_info_remove_path (struct MeshPeerInfo *peer, GNUNET_PEER_Id p1, | |||
1867 | d = tunnel_notify_connection_broken (peer->tunnels[i], p1, p2); | 1857 | d = tunnel_notify_connection_broken (peer->tunnels[i], p1, p2); |
1868 | if (0 == d) | 1858 | if (0 == d) |
1869 | continue; | 1859 | continue; |
1870 | /* TODO | 1860 | |
1871 | * Problem: one or more peers have been deleted from the tunnel tree. | ||
1872 | * We don't know who they are to try to add them again. | ||
1873 | * We need to try to find a new path for each of the disconnected peers. | ||
1874 | * Some of them might already have a path to reach them that does not | ||
1875 | * involve p1 and p2. Adding all anew might render in a better tree than | ||
1876 | * the trivial immediate fix. | ||
1877 | * | ||
1878 | * Trivial immiediate fix: try to reconnect to the disconnected node. All | ||
1879 | * its children will be reachable trough him. | ||
1880 | */ | ||
1881 | peer_d = peer_get_short (d); | 1861 | peer_d = peer_get_short (d); |
1882 | best = UINT_MAX; | 1862 | next = peer_get_best_path (peer_d, peer->tunnels[i]); |
1883 | aux = NULL; | 1863 | tunnel_use_path (peer->tunnels[i], next); |
1884 | for (p = peer_d->path_head; NULL != p; p = p->next) | 1864 | peer_connect (peer_d, peer->tunnels[i]); |
1885 | { | ||
1886 | if ((cost = tree_get_path_cost (peer->tunnels[i]->tree, p)) < best) | ||
1887 | { | ||
1888 | best = cost; | ||
1889 | aux = p; | ||
1890 | } | ||
1891 | } | ||
1892 | if (NULL != aux) | ||
1893 | { | ||
1894 | /* No callback, as peer will be already disconnected and a connection | ||
1895 | * scheduled by tunnel_notify_connection_broken. | ||
1896 | */ | ||
1897 | tree_add_path (peer->tunnels[i]->tree, aux, NULL, NULL); | ||
1898 | } | ||
1899 | else | ||
1900 | { | ||
1901 | peer_connect (peer_d, peer->tunnels[i]); | ||
1902 | } | ||
1903 | } | 1865 | } |
1904 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "peer_info_remove_path END\n"); | 1866 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "peer_info_remove_path END\n"); |
1905 | } | 1867 | } |
@@ -2338,7 +2300,7 @@ tunnel_add_client (struct MeshTunnel *t, struct MeshClient *c) | |||
2338 | 2300 | ||
2339 | 2301 | ||
2340 | static void | 2302 | static void |
2341 | tunnel_use_path (struct MeshTunnel *t, const struct MeshPeerPath *p) | 2303 | tunnel_use_path (struct MeshTunnel *t, struct MeshPeerPath *p) |
2342 | { | 2304 | { |
2343 | unsigned int i; | 2305 | unsigned int i; |
2344 | 2306 | ||
@@ -2360,6 +2322,9 @@ tunnel_use_path (struct MeshTunnel *t, const struct MeshPeerPath *p) | |||
2360 | t->prev_hop = p->peers[i - 1]; | 2322 | t->prev_hop = p->peers[i - 1]; |
2361 | else | 2323 | else |
2362 | t->prev_hop = 0; | 2324 | t->prev_hop = 0; |
2325 | if (NULL != t->path) | ||
2326 | path_destroy (t->path); | ||
2327 | t->path = path_duplicate (p); | ||
2363 | } | 2328 | } |
2364 | 2329 | ||
2365 | 2330 | ||
@@ -2677,7 +2642,7 @@ tunnel_send_fwd_ack (struct MeshTunnel *t, uint16_t type) | |||
2677 | } | 2642 | } |
2678 | 2643 | ||
2679 | t->last_fwd_ack = ack; | 2644 | t->last_fwd_ack = ack; |
2680 | GNUNET_PEER_resolve (tree_get_predecessor (t->tree), &id); | 2645 | GNUNET_PEER_resolve (t->prev_hop, &id); |
2681 | send_ack (t, &id, ack); | 2646 | send_ack (t, &id, ack); |
2682 | debug_fwd_ack++; | 2647 | debug_fwd_ack++; |
2683 | t->force_ack = GNUNET_NO; | 2648 | t->force_ack = GNUNET_NO; |
@@ -2685,17 +2650,15 @@ tunnel_send_fwd_ack (struct MeshTunnel *t, uint16_t type) | |||
2685 | 2650 | ||
2686 | 2651 | ||
2687 | /** | 2652 | /** |
2688 | * Iterator to send a child node a BCK ACK to allow him to send more | 2653 | * Send a child node a BCK ACK to allow him to send more to_origin data. |
2689 | * to_origin data. | ||
2690 | * | 2654 | * |
2691 | * @param cls Closure (tunnel). | 2655 | * @param t Tunnel. |
2692 | * @param id Id of the child node. | 2656 | * @param id Id of the child node. |
2693 | */ | 2657 | */ |
2694 | static void | 2658 | static void |
2695 | tunnel_send_child_bck_ack (void *cls, | 2659 | tunnel_send_child_bck_ack (struct MeshTunnel *t, |
2696 | GNUNET_PEER_Id id) | 2660 | GNUNET_PEER_Id id) |
2697 | { | 2661 | { |
2698 | struct MeshTunnel *t = cls; | ||
2699 | struct GNUNET_PeerIdentity peer; | 2662 | struct GNUNET_PeerIdentity peer; |
2700 | uint32_t ack = 0; // FIXME | 2663 | uint32_t ack = 0; // FIXME |
2701 | 2664 | ||
@@ -2816,7 +2779,7 @@ tunnel_send_bck_ack (struct MeshTunnel *t, uint16_t type) | |||
2816 | } | 2779 | } |
2817 | 2780 | ||
2818 | tunnel_send_clients_bck_ack (t); | 2781 | tunnel_send_clients_bck_ack (t); |
2819 | tree_iterate_children (t->tree, &tunnel_send_child_bck_ack, t); | 2782 | tunnel_send_child_bck_ack (t, t->next_hop); |
2820 | t->force_ack = GNUNET_NO; | 2783 | t->force_ack = GNUNET_NO; |
2821 | } | 2784 | } |
2822 | 2785 | ||
@@ -2828,18 +2791,17 @@ tunnel_send_bck_ack (struct MeshTunnel *t, uint16_t type) | |||
2828 | * and the core transmit handle is NULL (traffic was stalled). | 2791 | * and the core transmit handle is NULL (traffic was stalled). |
2829 | * If so, call core tmt rdy. | 2792 | * If so, call core tmt rdy. |
2830 | * | 2793 | * |
2831 | * @param cls Closure (unused) | ||
2832 | * @param peer_id Short ID of peer to which initiate traffic. | 2794 | * @param peer_id Short ID of peer to which initiate traffic. |
2833 | */ | 2795 | */ |
2834 | static void | 2796 | static void |
2835 | peer_unlock_queue(void *cls, GNUNET_PEER_Id peer_id) | 2797 | peer_unlock_queue(GNUNET_PEER_Id peer_id) |
2836 | { | 2798 | { |
2837 | struct MeshPeerInfo *peer; | 2799 | struct MeshPeerInfo *peer; |
2838 | struct GNUNET_PeerIdentity id; | 2800 | struct GNUNET_PeerIdentity id; |
2839 | struct MeshPeerQueue *q; | 2801 | struct MeshPeerQueue *q; |
2840 | size_t size; | 2802 | size_t size; |
2841 | 2803 | ||
2842 | peer = peer_get_short(peer_id); | 2804 | peer = peer_get_short (peer_id); |
2843 | if (NULL != peer->core_transmit) | 2805 | if (NULL != peer->core_transmit) |
2844 | return; | 2806 | return; |
2845 | 2807 | ||
@@ -2869,50 +2831,13 @@ peer_unlock_queue(void *cls, GNUNET_PEER_Id peer_id) | |||
2869 | 2831 | ||
2870 | 2832 | ||
2871 | /** | 2833 | /** |
2872 | * @brief Allow transmission of FWD traffic on this tunnel | ||
2873 | * | ||
2874 | * Check if there is traffic queued towards any children | ||
2875 | * and the core transmit handle is NULL, and if so, call core tmt rdy. | ||
2876 | * | ||
2877 | * @param t Tunnel on which to unlock FWD traffic. | ||
2878 | */ | ||
2879 | static void | ||
2880 | tunnel_unlock_fwd_queues (struct MeshTunnel *t) | ||
2881 | { | ||
2882 | if (0 == t->fwd_queue_n) | ||
2883 | return; | ||
2884 | |||
2885 | tree_iterate_children (t->tree, &peer_unlock_queue, NULL); | ||
2886 | } | ||
2887 | |||
2888 | |||
2889 | /** | ||
2890 | * @brief Allow transmission of BCK traffic on this tunnel | ||
2891 | * | ||
2892 | * Check if there is traffic queued towards the root of the tree | ||
2893 | * and the core transmit handle is NULL, and if so, call core tmt rdy. | ||
2894 | * | ||
2895 | * @param t Tunnel on which to unlock BCK traffic. | ||
2896 | */ | ||
2897 | static void | ||
2898 | tunnel_unlock_bck_queue (struct MeshTunnel *t) | ||
2899 | { | ||
2900 | if (0 == t->bck_queue_n) | ||
2901 | return; | ||
2902 | |||
2903 | peer_unlock_queue(NULL, tree_get_predecessor(t->tree)); | ||
2904 | } | ||
2905 | |||
2906 | |||
2907 | /** | ||
2908 | * Send a message to all peers in this tunnel that the tunnel is no longer | 2834 | * Send a message to all peers in this tunnel that the tunnel is no longer |
2909 | * valid. | 2835 | * valid. |
2910 | * | 2836 | * |
2911 | * @param t The tunnel whose peers to notify. | 2837 | * @param t The tunnel whose peers to notify. |
2912 | * @param parent ID of the parent, in case the tree is already destroyed. | ||
2913 | */ | 2838 | */ |
2914 | static void | 2839 | static void |
2915 | tunnel_send_destroy (struct MeshTunnel *t, GNUNET_PEER_Id parent) | 2840 | tunnel_send_destroy (struct MeshTunnel *t) |
2916 | { | 2841 | { |
2917 | struct GNUNET_MESH_TunnelDestroy msg; | 2842 | struct GNUNET_MESH_TunnelDestroy msg; |
2918 | struct GNUNET_PeerIdentity id; | 2843 | struct GNUNET_PeerIdentity id; |
@@ -2925,38 +2850,41 @@ tunnel_send_destroy (struct MeshTunnel *t, GNUNET_PEER_Id parent) | |||
2925 | " sending tunnel destroy for tunnel: %s [%X]\n", | 2850 | " sending tunnel destroy for tunnel: %s [%X]\n", |
2926 | GNUNET_i2s (&msg.oid), t->id.tid); | 2851 | GNUNET_i2s (&msg.oid), t->id.tid); |
2927 | 2852 | ||
2928 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " sending multicast to child\n"); | 2853 | if (0 != t->next_hop) |
2929 | /* FIXME tunnel_send_multicast (t, &msg.header); */ | 2854 | { |
2930 | 2855 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " child: %u\n", t->next_hop); | |
2931 | if (0 == parent) | 2856 | GNUNET_PEER_resolve (t->next_hop, &id); |
2932 | parent = tree_get_predecessor (t->tree); | 2857 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
2933 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " parent: %u\n", parent); | 2858 | " sending back to %s\n", |
2934 | if (0 == parent) | 2859 | GNUNET_i2s (&id)); |
2935 | return; | 2860 | send_prebuilt_message (&msg.header, &id, t); |
2936 | 2861 | } | |
2937 | GNUNET_PEER_resolve (parent, &id); | 2862 | if (0 != t->prev_hop) |
2938 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 2863 | { |
2939 | " sending back to %s\n", | 2864 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " parent: %u\n", t->prev_hop); |
2940 | GNUNET_i2s (&id)); | 2865 | GNUNET_PEER_resolve (t->prev_hop, &id); |
2941 | send_prebuilt_message (&msg.header, &id, t); | 2866 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
2867 | " sending back to %s\n", | ||
2868 | GNUNET_i2s (&id)); | ||
2869 | send_prebuilt_message (&msg.header, &id, t); | ||
2870 | } | ||
2942 | } | 2871 | } |
2943 | 2872 | ||
2944 | 2873 | ||
2945 | /** | 2874 | /** |
2946 | * Cancel all transmissions towards a neighbor that belong to a certain tunnel. | 2875 | * Cancel all transmissions towards a neighbor that belongs to a certain tunnel. |
2947 | * | 2876 | * |
2948 | * @param cls Closure (Tunnel which to cancel). | 2877 | * @param t Tunnel which to cancel. |
2949 | * @param neighbor_id Short ID of the neighbor to whom cancel the transmissions. | 2878 | * @param neighbor Short ID of the neighbor to whom cancel the transmissions. |
2950 | */ | 2879 | */ |
2951 | static void | 2880 | static void |
2952 | tunnel_cancel_queues (void *cls, GNUNET_PEER_Id neighbor_id) | 2881 | peer_cancel_queues (GNUNET_PEER_Id neighbor, struct MeshTunnel *t) |
2953 | { | 2882 | { |
2954 | struct MeshTunnel *t = cls; | ||
2955 | struct MeshPeerInfo *peer_info; | 2883 | struct MeshPeerInfo *peer_info; |
2956 | struct MeshPeerQueue *pq; | 2884 | struct MeshPeerQueue *pq; |
2957 | struct MeshPeerQueue *next; | 2885 | struct MeshPeerQueue *next; |
2958 | 2886 | ||
2959 | peer_info = peer_get_short (neighbor_id); | 2887 | peer_info = peer_get_short (neighbor); |
2960 | for (pq = peer_info->queue_head; NULL != pq; pq = next) | 2888 | for (pq = peer_info->queue_head; NULL != pq; pq = next) |
2961 | { | 2889 | { |
2962 | next = pq->next; | 2890 | next = pq->next; |
@@ -2978,6 +2906,7 @@ tunnel_cancel_queues (void *cls, GNUNET_PEER_Id neighbor_id) | |||
2978 | } | 2906 | } |
2979 | } | 2907 | } |
2980 | 2908 | ||
2909 | |||
2981 | /** | 2910 | /** |
2982 | * Destroy the tunnel and free any allocated resources linked to it. | 2911 | * Destroy the tunnel and free any allocated resources linked to it. |
2983 | * | 2912 | * |
@@ -3055,8 +2984,8 @@ tunnel_destroy (struct MeshTunnel *t) | |||
3055 | GNUNET_free_non_null (t->ignore); | 2984 | GNUNET_free_non_null (t->ignore); |
3056 | GNUNET_free_non_null (t->clients_fc); | 2985 | GNUNET_free_non_null (t->clients_fc); |
3057 | 2986 | ||
3058 | tree_iterate_children (t->tree, &tunnel_cancel_queues, t); | 2987 | peer_cancel_queues (t->next_hop, t); |
3059 | tree_destroy (t->tree); | 2988 | peer_cancel_queues (t->prev_hop, t); |
3060 | 2989 | ||
3061 | if (GNUNET_SCHEDULER_NO_TASK != t->timeout_task) | 2990 | if (GNUNET_SCHEDULER_NO_TASK != t->timeout_task) |
3062 | GNUNET_SCHEDULER_cancel (t->timeout_task); | 2991 | GNUNET_SCHEDULER_cancel (t->timeout_task); |
@@ -3087,8 +3016,7 @@ tunnel_destroy_empty_delayed (void *cls, | |||
3087 | if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) | 3016 | if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) |
3088 | return; | 3017 | return; |
3089 | 3018 | ||
3090 | if (0 != t->nclients || | 3019 | if (0 != t->nclients) |
3091 | 0 != tree_count_children (t->tree)) | ||
3092 | return; | 3020 | return; |
3093 | 3021 | ||
3094 | #if MESH_DEBUG | 3022 | #if MESH_DEBUG |
@@ -3102,7 +3030,7 @@ tunnel_destroy_empty_delayed (void *cls, | |||
3102 | } | 3030 | } |
3103 | #endif | 3031 | #endif |
3104 | 3032 | ||
3105 | tunnel_send_destroy (t, 0); | 3033 | tunnel_send_destroy (t); |
3106 | if (0 == t->pending_messages) | 3034 | if (0 == t->pending_messages) |
3107 | tunnel_destroy (t); | 3035 | tunnel_destroy (t); |
3108 | else | 3036 | else |
@@ -3119,12 +3047,10 @@ static void | |||
3119 | tunnel_destroy_empty (struct MeshTunnel *t) | 3047 | tunnel_destroy_empty (struct MeshTunnel *t) |
3120 | { | 3048 | { |
3121 | if (GNUNET_SCHEDULER_NO_TASK != t->delayed_destroy || | 3049 | if (GNUNET_SCHEDULER_NO_TASK != t->delayed_destroy || |
3122 | 0 != t->nclients || | 3050 | 0 != t->nclients) |
3123 | 0 != tree_count_children (t->tree)) | ||
3124 | { | 3051 | { |
3125 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 3052 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "%u %u\n", |
3126 | "%u %u %u\n", | 3053 | t->delayed_destroy, t->nclients); |
3127 | t->delayed_destroy, t->nclients, tree_count_children(t->tree)); | ||
3128 | return; | 3054 | return; |
3129 | } | 3055 | } |
3130 | 3056 | ||
@@ -3173,7 +3099,6 @@ tunnel_new (GNUNET_PEER_Id owner, | |||
3173 | t->id.tid = tid; | 3099 | t->id.tid = tid; |
3174 | t->fwd_queue_max = (max_msgs_queue / max_tunnels) + 1; | 3100 | t->fwd_queue_max = (max_msgs_queue / max_tunnels) + 1; |
3175 | t->bck_queue_max = t->fwd_queue_max; | 3101 | t->bck_queue_max = t->fwd_queue_max; |
3176 | t->tree = tree_new (owner); | ||
3177 | t->owner = client; | 3102 | t->owner = client; |
3178 | t->fwd_pid = (uint32_t) -1; // Next (expected) = 0 | 3103 | t->fwd_pid = (uint32_t) -1; // Next (expected) = 0 |
3179 | t->bck_pid = (uint32_t) -1; // Next (expected) = 0 | 3104 | t->bck_pid = (uint32_t) -1; // Next (expected) = 0 |
@@ -3246,7 +3171,7 @@ tunnel_destroy_iterator (void *cls, | |||
3246 | tunnel_destroy_empty (t); | 3171 | tunnel_destroy_empty (t); |
3247 | return GNUNET_OK; | 3172 | return GNUNET_OK; |
3248 | } | 3173 | } |
3249 | tunnel_send_destroy (t, 0); | 3174 | tunnel_send_destroy (t); |
3250 | t->owner = NULL; | 3175 | t->owner = NULL; |
3251 | t->destroy = GNUNET_YES; | 3176 | t->destroy = GNUNET_YES; |
3252 | 3177 | ||
@@ -3587,15 +3512,6 @@ queue_get_next (const struct MeshPeerInfo *peer) | |||
3587 | } | 3512 | } |
3588 | 3513 | ||
3589 | 3514 | ||
3590 | /** | ||
3591 | * Core callback to write a queued packet to core buffer | ||
3592 | * | ||
3593 | * @param cls Closure (peer info). | ||
3594 | * @param size Number of bytes available in buf. | ||
3595 | * @param buf Where the to write the message. | ||
3596 | * | ||
3597 | * @return number of bytes written to buf | ||
3598 | */ | ||
3599 | static size_t | 3515 | static size_t |
3600 | queue_send (void *cls, size_t size, void *buf) | 3516 | queue_send (void *cls, size_t size, void *buf) |
3601 | { | 3517 | { |
@@ -3788,8 +3704,8 @@ queue_send (void *cls, size_t size, void *buf) | |||
3788 | /** | 3704 | /** |
3789 | * @brief Queue and pass message to core when possible. | 3705 | * @brief Queue and pass message to core when possible. |
3790 | * | 3706 | * |
3791 | * If type is payload (UNICAST, TO_ORIGIN, MULTICAST) checks for queue status | 3707 | * If type is payload (UNICAST, TO_ORIGIN) checks for queue status and |
3792 | * and accounts for it. In case the queue is full, the message is dropped and | 3708 | * accounts for it. In case the queue is full, the message is dropped and |
3793 | * a break issued. | 3709 | * a break issued. |
3794 | * | 3710 | * |
3795 | * Otherwise, message is treated as internal and allowed to go regardless of | 3711 | * Otherwise, message is treated as internal and allowed to go regardless of |
@@ -3841,42 +3757,20 @@ queue_add (void *cls, uint16_t type, size_t size, | |||
3841 | queue->peer = dst; | 3757 | queue->peer = dst; |
3842 | queue->tunnel = t; | 3758 | queue->tunnel = t; |
3843 | GNUNET_CONTAINER_DLL_insert_tail (dst->queue_head, dst->queue_tail, queue); | 3759 | GNUNET_CONTAINER_DLL_insert_tail (dst->queue_head, dst->queue_tail, queue); |
3844 | GNUNET_PEER_resolve (dst->id, &id); | ||
3845 | if (NULL == dst->core_transmit) | 3760 | if (NULL == dst->core_transmit) |
3846 | { | 3761 | { |
3847 | dst->core_transmit = | 3762 | GNUNET_PEER_resolve (dst->id, &id); |
3848 | GNUNET_CORE_notify_transmit_ready (core_handle, | 3763 | dst->core_transmit = |
3849 | 0, | 3764 | GNUNET_CORE_notify_transmit_ready (core_handle, |
3850 | 0, | 3765 | 0, |
3851 | GNUNET_TIME_UNIT_FOREVER_REL, | 3766 | 0, |
3852 | &id, | 3767 | GNUNET_TIME_UNIT_FOREVER_REL, |
3853 | size, | 3768 | &id, |
3854 | &queue_send, | 3769 | size, |
3855 | dst); | 3770 | &queue_send, |
3771 | dst); | ||
3856 | } | 3772 | } |
3857 | t->pending_messages++; | 3773 | t->pending_messages++; |
3858 | if (NULL == n) // Is this internal mesh traffic? | ||
3859 | return; | ||
3860 | |||
3861 | // It's payload, keep track of buffer per peer. FIXME | ||
3862 | // i = (cinfo->send_buffer_start + cinfo->send_buffer_n) % t->fwd_queue_max; | ||
3863 | // if (NULL != cinfo->send_buffer[i]) | ||
3864 | // { | ||
3865 | // GNUNET_break (cinfo->send_buffer_n == t->fwd_queue_max); // aka i == start | ||
3866 | // queue_destroy (cinfo->send_buffer[cinfo->send_buffer_start], GNUNET_YES); | ||
3867 | // cinfo->send_buffer_start++; | ||
3868 | // cinfo->send_buffer_start %= t->fwd_queue_max; | ||
3869 | // } | ||
3870 | // else | ||
3871 | // { | ||
3872 | // cinfo->send_buffer_n++; | ||
3873 | // } | ||
3874 | // cinfo->send_buffer[i] = queue; | ||
3875 | // if (cinfo->send_buffer_n > t->fwd_queue_max) | ||
3876 | // { | ||
3877 | // GNUNET_break (0); | ||
3878 | // cinfo->send_buffer_n = t->fwd_queue_max; | ||
3879 | // } | ||
3880 | } | 3774 | } |
3881 | 3775 | ||
3882 | 3776 | ||
@@ -4190,7 +4084,6 @@ handle_mesh_tunnel_destroy (void *cls, const struct GNUNET_PeerIdentity *peer, | |||
4190 | { | 4084 | { |
4191 | struct GNUNET_MESH_TunnelDestroy *msg; | 4085 | struct GNUNET_MESH_TunnelDestroy *msg; |
4192 | struct MeshTunnel *t; | 4086 | struct MeshTunnel *t; |
4193 | GNUNET_PEER_Id parent; | ||
4194 | GNUNET_PEER_Id pid; | 4087 | GNUNET_PEER_Id pid; |
4195 | 4088 | ||
4196 | msg = (struct GNUNET_MESH_TunnelDestroy *) message; | 4089 | msg = (struct GNUNET_MESH_TunnelDestroy *) message; |
@@ -4212,21 +4105,13 @@ handle_mesh_tunnel_destroy (void *cls, const struct GNUNET_PeerIdentity *peer, | |||
4212 | 1, GNUNET_NO); | 4105 | 1, GNUNET_NO); |
4213 | return GNUNET_OK; | 4106 | return GNUNET_OK; |
4214 | } | 4107 | } |
4215 | parent = tree_get_predecessor (t->tree); | ||
4216 | pid = GNUNET_PEER_search (peer); | 4108 | pid = GNUNET_PEER_search (peer); |
4217 | if (pid != parent) | 4109 | if (pid != t->prev_hop && 0 < t->nclients) |
4218 | { | 4110 | { |
4219 | unsigned int nc; | 4111 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
4220 | 4112 | "still in use by %u clients\n", | |
4221 | // tree_del_peer (t->tree, pid, &tunnel_child_removed, t); | 4113 | t->nclients); |
4222 | nc = tree_count_children (t->tree); | 4114 | return GNUNET_OK; |
4223 | if (nc > 0 || NULL != t->owner || t->nclients > 0) | ||
4224 | { | ||
4225 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
4226 | "still in use: %u cl, %u ch\n", | ||
4227 | t->nclients, nc); | ||
4228 | return GNUNET_OK; | ||
4229 | } | ||
4230 | } | 4115 | } |
4231 | if (t->local_tid_dest >= GNUNET_MESH_LOCAL_TUNNEL_ID_SERV) | 4116 | if (t->local_tid_dest >= GNUNET_MESH_LOCAL_TUNNEL_ID_SERV) |
4232 | { | 4117 | { |
@@ -4235,7 +4120,7 @@ handle_mesh_tunnel_destroy (void *cls, const struct GNUNET_PeerIdentity *peer, | |||
4235 | t->local_tid, t->local_tid_dest); | 4120 | t->local_tid, t->local_tid_dest); |
4236 | send_clients_tunnel_destroy (t); | 4121 | send_clients_tunnel_destroy (t); |
4237 | } | 4122 | } |
4238 | tunnel_send_destroy (t, parent); | 4123 | tunnel_send_destroy (t); |
4239 | t->destroy = GNUNET_YES; | 4124 | t->destroy = GNUNET_YES; |
4240 | // TODO: add timeout to destroy the tunnel anyway | 4125 | // TODO: add timeout to destroy the tunnel anyway |
4241 | return GNUNET_OK; | 4126 | return GNUNET_OK; |
@@ -4256,7 +4141,7 @@ handle_mesh_data_unicast (void *cls, const struct GNUNET_PeerIdentity *peer, | |||
4256 | const struct GNUNET_MessageHeader *message) | 4141 | const struct GNUNET_MessageHeader *message) |
4257 | { | 4142 | { |
4258 | struct GNUNET_MESH_Unicast *msg; | 4143 | struct GNUNET_MESH_Unicast *msg; |
4259 | struct GNUNET_PeerIdentity *neighbor; | 4144 | struct GNUNET_PeerIdentity neighbor; |
4260 | struct MeshTunnel *t; | 4145 | struct MeshTunnel *t; |
4261 | GNUNET_PEER_Id dest_id; | 4146 | GNUNET_PEER_Id dest_id; |
4262 | uint32_t pid; | 4147 | uint32_t pid; |
@@ -4335,7 +4220,7 @@ handle_mesh_data_unicast (void *cls, const struct GNUNET_PeerIdentity *peer, | |||
4335 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 4220 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
4336 | " not for us, retransmitting...\n"); | 4221 | " not for us, retransmitting...\n"); |
4337 | 4222 | ||
4338 | neighbor = tree_get_first_hop (t->tree, dest_id); | 4223 | GNUNET_PEER_resolve (t->next_hop, &neighbor); |
4339 | 4224 | ||
4340 | /* cinfo->fwd_pid = pid; FIXME | 4225 | /* cinfo->fwd_pid = pid; FIXME |
4341 | 4226 | ||
@@ -4347,7 +4232,7 @@ handle_mesh_data_unicast (void *cls, const struct GNUNET_PeerIdentity *peer, | |||
4347 | GNUNET_break_op (0); | 4232 | GNUNET_break_op (0); |
4348 | return GNUNET_OK; | 4233 | return GNUNET_OK; |
4349 | }*/ | 4234 | }*/ |
4350 | send_prebuilt_message (message, neighbor, t); | 4235 | send_prebuilt_message (message, &neighbor, t); |
4351 | GNUNET_STATISTICS_update (stats, "# unicast forwarded", 1, GNUNET_NO); | 4236 | GNUNET_STATISTICS_update (stats, "# unicast forwarded", 1, GNUNET_NO); |
4352 | return GNUNET_OK; | 4237 | return GNUNET_OK; |
4353 | } | 4238 | } |
@@ -4371,7 +4256,6 @@ handle_mesh_data_to_orig (void *cls, const struct GNUNET_PeerIdentity *peer, | |||
4371 | struct GNUNET_PeerIdentity id; | 4256 | struct GNUNET_PeerIdentity id; |
4372 | struct MeshPeerInfo *peer_info; | 4257 | struct MeshPeerInfo *peer_info; |
4373 | struct MeshTunnel *t; | 4258 | struct MeshTunnel *t; |
4374 | GNUNET_PEER_Id predecessor; | ||
4375 | size_t size; | 4259 | size_t size; |
4376 | uint32_t pid; | 4260 | uint32_t pid; |
4377 | 4261 | ||
@@ -4444,8 +4328,7 @@ handle_mesh_data_to_orig (void *cls, const struct GNUNET_PeerIdentity *peer, | |||
4444 | GNUNET_break (0); | 4328 | GNUNET_break (0); |
4445 | return GNUNET_OK; | 4329 | return GNUNET_OK; |
4446 | } | 4330 | } |
4447 | predecessor = tree_get_predecessor (t->tree); | 4331 | if (0 == t->prev_hop) |
4448 | if (0 == predecessor) | ||
4449 | { | 4332 | { |
4450 | if (GNUNET_YES == t->destroy) | 4333 | if (GNUNET_YES == t->destroy) |
4451 | { | 4334 | { |
@@ -4463,12 +4346,9 @@ handle_mesh_data_to_orig (void *cls, const struct GNUNET_PeerIdentity *peer, | |||
4463 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 4346 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, |
4464 | "for tunnel %s [%X]\n", | 4347 | "for tunnel %s [%X]\n", |
4465 | GNUNET_i2s (&msg->oid), ntohl(msg->tid)); | 4348 | GNUNET_i2s (&msg->oid), ntohl(msg->tid)); |
4466 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
4467 | "current tree:\n"); | ||
4468 | tree_debug (t->tree); | ||
4469 | return GNUNET_OK; | 4349 | return GNUNET_OK; |
4470 | } | 4350 | } |
4471 | GNUNET_PEER_resolve (predecessor, &id); | 4351 | GNUNET_PEER_resolve (t->prev_hop, &id); |
4472 | send_prebuilt_message (message, &id, t); | 4352 | send_prebuilt_message (message, &id, t); |
4473 | GNUNET_STATISTICS_update (stats, "# to origin forwarded", 1, GNUNET_NO); | 4353 | GNUNET_STATISTICS_update (stats, "# to origin forwarded", 1, GNUNET_NO); |
4474 | 4354 | ||
@@ -4510,14 +4390,14 @@ handle_mesh_ack (void *cls, const struct GNUNET_PeerIdentity *peer, | |||
4510 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " ACK %u\n", ack); | 4390 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " ACK %u\n", ack); |
4511 | 4391 | ||
4512 | /* Is this a forward or backward ACK? */ | 4392 | /* Is this a forward or backward ACK? */ |
4513 | if (tree_get_predecessor(t->tree) != GNUNET_PEER_search(peer)) | 4393 | if (t->prev_hop != GNUNET_PEER_search(peer)) |
4514 | { | 4394 | { |
4515 | 4395 | ||
4516 | debug_bck_ack++; | 4396 | debug_bck_ack++; |
4517 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " FWD ACK\n"); | 4397 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " FWD ACK\n"); |
4518 | // cinfo->fwd_ack = ack; FIXME | 4398 | // cinfo->fwd_ack = ack; FIXME |
4519 | tunnel_send_fwd_ack (t, GNUNET_MESSAGE_TYPE_MESH_ACK); | 4399 | tunnel_send_fwd_ack (t, GNUNET_MESSAGE_TYPE_MESH_ACK); |
4520 | tunnel_unlock_fwd_queues (t); | 4400 | peer_unlock_queue (t->next_hop); |
4521 | // if (GNUNET_SCHEDULER_NO_TASK != cinfo->fc_poll) FIXME | 4401 | // if (GNUNET_SCHEDULER_NO_TASK != cinfo->fc_poll) FIXME |
4522 | // { | 4402 | // { |
4523 | // GNUNET_SCHEDULER_cancel (cinfo->fc_poll); | 4403 | // GNUNET_SCHEDULER_cancel (cinfo->fc_poll); |
@@ -4530,7 +4410,7 @@ handle_mesh_ack (void *cls, const struct GNUNET_PeerIdentity *peer, | |||
4530 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " BCK ACK\n"); | 4410 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " BCK ACK\n"); |
4531 | t->bck_ack = ack; | 4411 | t->bck_ack = ack; |
4532 | tunnel_send_bck_ack (t, GNUNET_MESSAGE_TYPE_MESH_ACK); | 4412 | tunnel_send_bck_ack (t, GNUNET_MESSAGE_TYPE_MESH_ACK); |
4533 | tunnel_unlock_bck_queue (t); | 4413 | peer_unlock_queue (t->prev_hop); |
4534 | } | 4414 | } |
4535 | return GNUNET_OK; | 4415 | return GNUNET_OK; |
4536 | } | 4416 | } |
@@ -4569,7 +4449,7 @@ handle_mesh_poll (void *cls, const struct GNUNET_PeerIdentity *peer, | |||
4569 | } | 4449 | } |
4570 | 4450 | ||
4571 | /* Is this a forward or backward ACK? */ | 4451 | /* Is this a forward or backward ACK? */ |
4572 | if (tree_get_predecessor(t->tree) != GNUNET_PEER_search(peer)) | 4452 | if (t->prev_hop != GNUNET_PEER_search(peer)) |
4573 | { | 4453 | { |
4574 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " from FWD\n"); | 4454 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " from FWD\n"); |
4575 | /* FIXME cinfo->bck_ack = cinfo->fwd_pid; // mark as ready to send */ | 4455 | /* FIXME cinfo->bck_ack = cinfo->fwd_pid; // mark as ready to send */ |
@@ -4625,12 +4505,11 @@ handle_mesh_path_ack (void *cls, const struct GNUNET_PeerIdentity *peer, | |||
4625 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " via peer %s\n", | 4505 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " via peer %s\n", |
4626 | GNUNET_i2s (peer)); | 4506 | GNUNET_i2s (peer)); |
4627 | 4507 | ||
4628 | /* Add paths to peers? */ | 4508 | /* Add path to peers? */ |
4629 | p = tree_get_path_to_peer (t->tree, peer_info->id); | 4509 | p = t->path; |
4630 | if (NULL != p) | 4510 | if (NULL != p) |
4631 | { | 4511 | { |
4632 | path_add_to_peers (p, GNUNET_YES); | 4512 | path_add_to_peers (p, GNUNET_YES); |
4633 | path_destroy (p); | ||
4634 | } | 4513 | } |
4635 | else | 4514 | else |
4636 | { | 4515 | { |
@@ -4646,11 +4525,6 @@ handle_mesh_path_ack (void *cls, const struct GNUNET_PeerIdentity *peer, | |||
4646 | GNUNET_break_op (0); | 4525 | GNUNET_break_op (0); |
4647 | return GNUNET_OK; | 4526 | return GNUNET_OK; |
4648 | } | 4527 | } |
4649 | if (tree_get_status (t->tree, peer_info->id) != MESH_PEER_READY) | ||
4650 | { | ||
4651 | tree_set_status (t->tree, peer_info->id, MESH_PEER_READY); | ||
4652 | // send_client_peer_connected (t, peer_info->id); | ||
4653 | } | ||
4654 | if (NULL != peer_info->dhtget) | 4528 | if (NULL != peer_info->dhtget) |
4655 | { | 4529 | { |
4656 | GNUNET_DHT_get_stop (peer_info->dhtget); | 4530 | GNUNET_DHT_get_stop (peer_info->dhtget); |
@@ -4661,7 +4535,7 @@ handle_mesh_path_ack (void *cls, const struct GNUNET_PeerIdentity *peer, | |||
4661 | 4535 | ||
4662 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 4536 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
4663 | " not for us, retransmitting...\n"); | 4537 | " not for us, retransmitting...\n"); |
4664 | GNUNET_PEER_resolve (tree_get_predecessor (t->tree), &id); | 4538 | GNUNET_PEER_resolve (t->prev_hop, &id); |
4665 | peer_info = peer_get (&msg->oid); | 4539 | peer_info = peer_get (&msg->oid); |
4666 | send_prebuilt_message (message, &id, t); | 4540 | send_prebuilt_message (message, &id, t); |
4667 | return GNUNET_OK; | 4541 | return GNUNET_OK; |
@@ -4780,7 +4654,7 @@ notify_client_connection_failure (void *cls, size_t size, void *buf) | |||
4780 | 4654 | ||
4781 | 4655 | ||
4782 | /** | 4656 | /** |
4783 | * Send keepalive packets for a peer | 4657 | * Send keepalive packets for a tunnel. |
4784 | * | 4658 | * |
4785 | * @param cls Closure (tunnel for which to send the keepalive). | 4659 | * @param cls Closure (tunnel for which to send the keepalive). |
4786 | * @param tc Notification context. | 4660 | * @param tc Notification context. |
@@ -5134,7 +5008,7 @@ handle_local_tunnel_destroy (void *cls, struct GNUNET_SERVER_Client *client, | |||
5134 | 5008 | ||
5135 | /* Don't try to ACK the client about the tunnel_destroy multicast packet */ | 5009 | /* Don't try to ACK the client about the tunnel_destroy multicast packet */ |
5136 | t->owner = NULL; | 5010 | t->owner = NULL; |
5137 | tunnel_send_destroy (t, 0); | 5011 | tunnel_send_destroy (t); |
5138 | t->destroy = GNUNET_YES; | 5012 | t->destroy = GNUNET_YES; |
5139 | /* The tunnel will be destroyed when the last message is transmitted. */ | 5013 | /* The tunnel will be destroyed when the last message is transmitted. */ |
5140 | GNUNET_SERVER_receive_done (client, GNUNET_OK); | 5014 | GNUNET_SERVER_receive_done (client, GNUNET_OK); |