diff options
author | Bart Polot <bart@net.in.tum.de> | 2011-10-17 11:05:05 +0000 |
---|---|---|
committer | Bart Polot <bart@net.in.tum.de> | 2011-10-17 11:05:05 +0000 |
commit | 469571975ea9114c835789caf3f4951984374000 (patch) | |
tree | 997073234a9e1ff8bd9113f9f2d218409dc101d0 /src/mesh/gnunet-service-mesh.c | |
parent | 522e801284ab0a8b39f6e8cc96c0609a0f28e6a8 (diff) | |
download | gnunet-469571975ea9114c835789caf3f4951984374000.tar.gz gnunet-469571975ea9114c835789caf3f4951984374000.zip |
Refactored multicast code to allow sending any message as multicast, added multicast testcase copied from unicast
Diffstat (limited to 'src/mesh/gnunet-service-mesh.c')
-rw-r--r-- | src/mesh/gnunet-service-mesh.c | 154 |
1 files changed, 96 insertions, 58 deletions
diff --git a/src/mesh/gnunet-service-mesh.c b/src/mesh/gnunet-service-mesh.c index 434e448af..da0af99b1 100644 --- a/src/mesh/gnunet-service-mesh.c +++ b/src/mesh/gnunet-service-mesh.c | |||
@@ -813,6 +813,21 @@ static size_t | |||
813 | send_core_create_path (void *cls, size_t size, void *buf); | 813 | send_core_create_path (void *cls, size_t size, void *buf); |
814 | 814 | ||
815 | /** | 815 | /** |
816 | * Function called to notify a client about the socket | ||
817 | * being ready to queue more data. "buf" will be | ||
818 | * NULL and "size" zero if the socket was closed for | ||
819 | * writing in the meantime. | ||
820 | * | ||
821 | * @param cls closure (data itself) | ||
822 | * @param size number of bytes available in buf | ||
823 | * @param buf where the callee should write the message | ||
824 | * | ||
825 | * @return number of bytes written to buf | ||
826 | */ | ||
827 | static size_t | ||
828 | send_core_data_multicast (void *cls, size_t size, void *buf); | ||
829 | |||
830 | /** | ||
816 | * Cancel a core transmission that was already requested and free all resources | 831 | * Cancel a core transmission that was already requested and free all resources |
817 | * associated to the request. | 832 | * associated to the request. |
818 | * | 833 | * |
@@ -1601,6 +1616,82 @@ tunnel_notify_connection_broken (struct MeshTunnel *t, | |||
1601 | 1616 | ||
1602 | 1617 | ||
1603 | /** | 1618 | /** |
1619 | * Send a message in a tunnel in multicast, sending a copy to each child node | ||
1620 | * down the local one in the tunnel tree. | ||
1621 | * | ||
1622 | * @param t Tunnel in which to send the data. | ||
1623 | * @param msg Message to be sent | ||
1624 | * | ||
1625 | * @return Number of copies sent. | ||
1626 | */ | ||
1627 | static int | ||
1628 | tunnel_send_multicast (struct MeshTunnel *t, | ||
1629 | const struct GNUNET_MessageHeader *msg) | ||
1630 | { | ||
1631 | struct GNUNET_PeerIdentity *neighbor; | ||
1632 | struct MeshDataDescriptor *info; | ||
1633 | struct MeshTunnelTreeNode *n; | ||
1634 | unsigned int *copies; | ||
1635 | unsigned int i; | ||
1636 | size_t size; | ||
1637 | void *data; | ||
1638 | |||
1639 | size = ntohs (msg->size); | ||
1640 | GNUNET_assert (NULL != t->tree->me); | ||
1641 | n = t->tree->me->children_head; | ||
1642 | if (NULL == n) | ||
1643 | return 0; | ||
1644 | copies = GNUNET_malloc (sizeof (unsigned int)); | ||
1645 | for (*copies = 0; NULL != n; n = n->next) | ||
1646 | (*copies)++; | ||
1647 | n = t->tree->me->children_head; | ||
1648 | data = GNUNET_malloc (size); | ||
1649 | memcpy (data, &msg, size); | ||
1650 | while (NULL != n) | ||
1651 | { | ||
1652 | info = GNUNET_malloc (sizeof (struct MeshDataDescriptor)); | ||
1653 | info->origin = &t->id; | ||
1654 | info->data = data; | ||
1655 | info->size = size; | ||
1656 | info->copies = copies; | ||
1657 | if (NULL != t->client->handle) | ||
1658 | { | ||
1659 | info->client = t->client->handle; | ||
1660 | |||
1661 | info->timeout_task = GNUNET_SCHEDULER_add_delayed (UNACKNOWLEDGED_WAIT, | ||
1662 | &client_allow_send, | ||
1663 | t->client->handle); | ||
1664 | } | ||
1665 | info->destination = n->peer; | ||
1666 | neighbor = path_get_first_hop(t->tree, n->peer); | ||
1667 | info->peer = peer_info_get(neighbor); | ||
1668 | GNUNET_assert (NULL != info->peer); | ||
1669 | for (i = 0; NULL != info->peer->core_transmit[i]; i++) | ||
1670 | { | ||
1671 | if (i == (CORE_QUEUE_SIZE - 1)) | ||
1672 | { | ||
1673 | GNUNET_free (info); | ||
1674 | GNUNET_break (0); | ||
1675 | return GNUNET_OK; | ||
1676 | } | ||
1677 | } | ||
1678 | info->handler_n = i; | ||
1679 | info->peer->infos[i] = info; | ||
1680 | info->peer->types[i] = GNUNET_MESSAGE_TYPE_MESH_MULTICAST; | ||
1681 | info->peer->core_transmit[i] = | ||
1682 | GNUNET_CORE_notify_transmit_ready (core_handle, | ||
1683 | 0, | ||
1684 | 0, | ||
1685 | GNUNET_TIME_UNIT_FOREVER_REL, | ||
1686 | neighbor, | ||
1687 | size, | ||
1688 | &send_core_data_multicast, info); | ||
1689 | } | ||
1690 | return *copies; | ||
1691 | } | ||
1692 | |||
1693 | |||
1694 | /** | ||
1604 | * Destroy the tunnel and free any allocated resources linked to it | 1695 | * Destroy the tunnel and free any allocated resources linked to it |
1605 | * | 1696 | * |
1606 | * @param t the tunnel to destroy | 1697 | * @param t the tunnel to destroy |
@@ -1846,12 +1937,12 @@ static size_t | |||
1846 | send_core_data_multicast (void *cls, size_t size, void *buf) | 1937 | send_core_data_multicast (void *cls, size_t size, void *buf) |
1847 | { | 1938 | { |
1848 | struct MeshDataDescriptor *info = cls; | 1939 | struct MeshDataDescriptor *info = cls; |
1849 | struct GNUNET_MESH_Multicast *msg = buf; | 1940 | struct GNUNET_MessageHeader *msg = buf; |
1850 | size_t total_size; | 1941 | size_t total_size; |
1851 | 1942 | ||
1852 | GNUNET_assert (NULL != info); | 1943 | GNUNET_assert (NULL != info); |
1853 | GNUNET_assert (NULL != info->peer); | 1944 | GNUNET_assert (NULL != info->peer); |
1854 | total_size = info->size + sizeof (struct GNUNET_MESH_Multicast); | 1945 | total_size = info->size; |
1855 | GNUNET_assert (total_size < GNUNET_SERVER_MAX_MESSAGE_SIZE); | 1946 | GNUNET_assert (total_size < GNUNET_SERVER_MAX_MESSAGE_SIZE); |
1856 | 1947 | ||
1857 | if (total_size > size) | 1948 | if (total_size > size) |
@@ -1860,8 +1951,6 @@ send_core_data_multicast (void *cls, size_t size, void *buf) | |||
1860 | struct GNUNET_PeerIdentity id; | 1951 | struct GNUNET_PeerIdentity id; |
1861 | 1952 | ||
1862 | GNUNET_PEER_resolve(info->peer->id, &id); | 1953 | GNUNET_PEER_resolve(info->peer->id, &id); |
1863 | info->peer->infos[info->handler_n] = info; | ||
1864 | info->peer->types[info->handler_n] = GNUNET_MESSAGE_TYPE_MESH_MULTICAST; | ||
1865 | info->peer->core_transmit[info->handler_n] = | 1954 | info->peer->core_transmit[info->handler_n] = |
1866 | GNUNET_CORE_notify_transmit_ready (core_handle, | 1955 | GNUNET_CORE_notify_transmit_ready (core_handle, |
1867 | 0, | 1956 | 0, |
@@ -1875,11 +1964,7 @@ send_core_data_multicast (void *cls, size_t size, void *buf) | |||
1875 | } | 1964 | } |
1876 | info->peer->core_transmit[info->handler_n] = NULL; | 1965 | info->peer->core_transmit[info->handler_n] = NULL; |
1877 | info->peer->infos[info->handler_n] = NULL; | 1966 | info->peer->infos[info->handler_n] = NULL; |
1878 | msg->header.type = htons (GNUNET_MESSAGE_TYPE_MESH_MULTICAST); | 1967 | memcpy (&msg, info->data, total_size); |
1879 | msg->header.size = htons (total_size); | ||
1880 | GNUNET_PEER_resolve (info->origin->oid, &msg->oid); | ||
1881 | msg->tid = htonl (info->origin->tid); | ||
1882 | memcpy (&msg[1], info->data, info->size); | ||
1883 | if (0 == --(*info->copies)) | 1968 | if (0 == --(*info->copies)) |
1884 | { | 1969 | { |
1885 | if (NULL != info->client) | 1970 | if (NULL != info->client) |
@@ -2273,14 +2358,8 @@ handle_mesh_data_multicast (void *cls, const struct GNUNET_PeerIdentity *peer, | |||
2273 | const struct GNUNET_ATS_Information *atsi) | 2358 | const struct GNUNET_ATS_Information *atsi) |
2274 | { | 2359 | { |
2275 | struct GNUNET_MESH_Multicast *msg; | 2360 | struct GNUNET_MESH_Multicast *msg; |
2276 | struct GNUNET_PeerIdentity *id; | ||
2277 | struct MeshDataDescriptor *info; | ||
2278 | struct MeshTunnelTreeNode *n; | ||
2279 | struct MeshTunnel *t; | 2361 | struct MeshTunnel *t; |
2280 | unsigned int *copies; | ||
2281 | unsigned int i; | ||
2282 | size_t size; | 2362 | size_t size; |
2283 | void *data; | ||
2284 | 2363 | ||
2285 | size = ntohs (message->size) - sizeof (struct GNUNET_MESH_Multicast); | 2364 | size = ntohs (message->size) - sizeof (struct GNUNET_MESH_Multicast); |
2286 | if (size < sizeof (struct GNUNET_MessageHeader)) | 2365 | if (size < sizeof (struct GNUNET_MessageHeader)) |
@@ -2303,48 +2382,7 @@ handle_mesh_data_multicast (void *cls, const struct GNUNET_PeerIdentity *peer, | |||
2303 | { | 2382 | { |
2304 | send_subscribed_clients (message, (struct GNUNET_MessageHeader *) &msg[1]); | 2383 | send_subscribed_clients (message, (struct GNUNET_MessageHeader *) &msg[1]); |
2305 | } | 2384 | } |
2306 | n = t->tree->me->children_head; | 2385 | tunnel_send_multicast(t, message); |
2307 | if (NULL == n) | ||
2308 | return GNUNET_OK; | ||
2309 | copies = GNUNET_malloc (sizeof (unsigned int)); | ||
2310 | for (*copies = 0; NULL != n; n = n->next) | ||
2311 | (*copies)++; | ||
2312 | n = t->tree->me->children_head; | ||
2313 | data = GNUNET_malloc (size); | ||
2314 | memcpy (data, &msg[1], size); | ||
2315 | while (NULL != n) | ||
2316 | { | ||
2317 | info = GNUNET_malloc (sizeof (struct MeshDataDescriptor)); | ||
2318 | info->origin = &t->id; | ||
2319 | info->data = data; | ||
2320 | info->size = size; | ||
2321 | info->copies = copies; | ||
2322 | info->client = t->client->handle; | ||
2323 | info->timeout_task = GNUNET_SCHEDULER_add_delayed(UNACKNOWLEDGED_WAIT, | ||
2324 | &client_allow_send, | ||
2325 | t->client->handle); | ||
2326 | info->destination = n->peer; | ||
2327 | id = path_get_first_hop(t->tree, n->peer); | ||
2328 | info->peer = peer_info_get(id); | ||
2329 | GNUNET_assert (NULL != info->peer); | ||
2330 | for (i = 0; NULL != info->peer->core_transmit[i]; i++) | ||
2331 | { | ||
2332 | if (i == (CORE_QUEUE_SIZE - 1)) | ||
2333 | { | ||
2334 | GNUNET_free (info); | ||
2335 | GNUNET_break (0); | ||
2336 | return GNUNET_OK; | ||
2337 | } | ||
2338 | } | ||
2339 | info->handler_n = i; | ||
2340 | info->peer->infos[i] = info; | ||
2341 | info->peer->types[i] = GNUNET_MESSAGE_TYPE_MESH_MULTICAST; | ||
2342 | info->peer->core_transmit[i] = | ||
2343 | GNUNET_CORE_notify_transmit_ready (core_handle, 0, 0, | ||
2344 | GNUNET_TIME_UNIT_FOREVER_REL, id, | ||
2345 | ntohs (msg->header.size), | ||
2346 | &send_core_data_multicast, info); | ||
2347 | } | ||
2348 | 2386 | ||
2349 | return GNUNET_OK; | 2387 | return GNUNET_OK; |
2350 | } | 2388 | } |
@@ -3083,7 +3121,7 @@ handle_local_tunnel_destroy (void *cls, struct GNUNET_SERVER_Client *client, | |||
3083 | t = GNUNET_CONTAINER_multihashmap_get (c->tunnels, &hash); | 3121 | t = GNUNET_CONTAINER_multihashmap_get (c->tunnels, &hash); |
3084 | GNUNET_CONTAINER_multihashmap_remove (c->tunnels, &hash, t); | 3122 | GNUNET_CONTAINER_multihashmap_remove (c->tunnels, &hash, t); |
3085 | 3123 | ||
3086 | // notify_tunnel_destroy(t); FIXME | 3124 | // notify_tunnel_destroy(t); |
3087 | tunnel_destroy(t); | 3125 | tunnel_destroy(t); |
3088 | GNUNET_SERVER_receive_done (client, GNUNET_OK); | 3126 | GNUNET_SERVER_receive_done (client, GNUNET_OK); |
3089 | return; | 3127 | return; |