aboutsummaryrefslogtreecommitdiff
path: root/src/mesh/gnunet-service-mesh.c
diff options
context:
space:
mode:
authorBart Polot <bart@net.in.tum.de>2011-10-17 11:05:05 +0000
committerBart Polot <bart@net.in.tum.de>2011-10-17 11:05:05 +0000
commit469571975ea9114c835789caf3f4951984374000 (patch)
tree997073234a9e1ff8bd9113f9f2d218409dc101d0 /src/mesh/gnunet-service-mesh.c
parent522e801284ab0a8b39f6e8cc96c0609a0f28e6a8 (diff)
downloadgnunet-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.c154
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
813send_core_create_path (void *cls, size_t size, void *buf); 813send_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 */
827static size_t
828send_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 */
1627static int
1628tunnel_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
1846send_core_data_multicast (void *cls, size_t size, void *buf) 1937send_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;