aboutsummaryrefslogtreecommitdiff
path: root/src/mesh/gnunet-service-mesh.c
diff options
context:
space:
mode:
authorBart Polot <bart@net.in.tum.de>2011-10-13 23:27:22 +0000
committerBart Polot <bart@net.in.tum.de>2011-10-13 23:27:22 +0000
commit94aa63cb17777332095a1de0a70382a49e10fecb (patch)
tree985ab88abf5f286f344e2f200e30e41b33f429bb /src/mesh/gnunet-service-mesh.c
parent2e92874cdda169f6337669d1bff9a5772aeae163 (diff)
downloadgnunet-94aa63cb17777332095a1de0a70382a49e10fecb.tar.gz
gnunet-94aa63cb17777332095a1de0a70382a49e10fecb.zip
Various fixes in data traffic, expansion of unicast testcase
Diffstat (limited to 'src/mesh/gnunet-service-mesh.c')
-rw-r--r--src/mesh/gnunet-service-mesh.c191
1 files changed, 158 insertions, 33 deletions
diff --git a/src/mesh/gnunet-service-mesh.c b/src/mesh/gnunet-service-mesh.c
index a19aa268d..bbf5679fe 100644
--- a/src/mesh/gnunet-service-mesh.c
+++ b/src/mesh/gnunet-service-mesh.c
@@ -409,6 +409,12 @@ static struct MeshClient *clients_tail;
409static struct GNUNET_CONTAINER_MultiHashMap *tunnels; 409static struct GNUNET_CONTAINER_MultiHashMap *tunnels;
410 410
411/** 411/**
412 * Tunnels incoming, indexed by MESH_TunnelNumber
413 * (which is greater than GNUNET_MESH_LOCAL_TUNNEL_ID_SERV)
414 */
415static struct GNUNET_CONTAINER_MultiHashMap *incoming_tunnels;
416
417/**
412 * Peers known, indexed by PeerIdentity (MeshPeerInfo) 418 * Peers known, indexed by PeerIdentity (MeshPeerInfo)
413 */ 419 */
414static struct GNUNET_CONTAINER_MultiHashMap *peers; 420static struct GNUNET_CONTAINER_MultiHashMap *peers;
@@ -669,26 +675,77 @@ client_is_subscribed (uint16_t message_type, struct MeshClient *c)
669 675
670 676
671/** 677/**
678 * Search for a tunnel by global ID using full PeerIdentities
679 *
680 * @param oid owner of the tunnel
681 * @param tid global tunnel number
682 *
683 * @return tunnel handler, NULL if doesn't exist
684 */
685static struct MeshTunnel *
686tunnel_get (struct GNUNET_PeerIdentity *oid, MESH_TunnelNumber tid);
687
688
689/**
672 * Send the message to all clients that have subscribed to its type 690 * Send the message to all clients that have subscribed to its type
673 * 691 *
674 * @param msg Pointer to the message itself 692 * @param msg Pointer to the message itself
675 * @return number of clients this message was sent to 693 * @return number of clients this message was sent to
676 */ 694 */
677static unsigned int 695static unsigned int
678send_subscribed_clients (struct GNUNET_MessageHeader *msg) 696send_subscribed_clients (const struct GNUNET_MessageHeader *msg,
697 const struct GNUNET_MessageHeader *payload)
679{ 698{
699 struct GNUNET_PeerIdentity *oid;
680 struct MeshClient *c; 700 struct MeshClient *c;
701 MESH_TunnelNumber *tid;
681 unsigned int count; 702 unsigned int count;
682 uint16_t type; 703 uint16_t type;
704 char cbuf[htons(msg->size)];
705
706 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "MESH: Sending to clients...\n");
707 type = ntohs (payload->type);
708 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "MESH: message of type %u\n", type);
683 709
684 type = ntohs (msg->type); 710 memcpy (cbuf, msg, sizeof(cbuf));
711 switch (htons(msg->type))
712 {
713 struct GNUNET_MESH_Unicast *uc;
714 struct GNUNET_MESH_Multicast *mc;
715 struct GNUNET_MESH_ToOrigin *to;
716
717 case GNUNET_MESSAGE_TYPE_MESH_UNICAST:
718 uc = (struct GNUNET_MESH_Unicast *) cbuf;
719 tid = &uc->tid;
720 oid = &uc->oid;
721 break;
722 case GNUNET_MESSAGE_TYPE_MESH_MULTICAST:
723 mc = (struct GNUNET_MESH_Multicast *) cbuf;
724 tid = &mc->tid;
725 oid = &mc->oid;
726 break;
727 case GNUNET_MESSAGE_TYPE_MESH_TO_ORIGIN:
728 to = (struct GNUNET_MESH_ToOrigin *) cbuf;
729 tid = &to->tid;
730 oid = &to->oid;
731 break;
732 default:
733 GNUNET_break (0);
734 return 0;
735 }
736 *tid = htonl (tunnel_get (oid, ntohl(*tid))->local_tid);
685 for (count = 0, c = clients; c != NULL; c = c->next) 737 for (count = 0, c = clients; c != NULL; c = c->next)
686 { 738 {
739 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "MESH: client %u\n", c->id);
687 if (client_is_subscribed (type, c)) 740 if (client_is_subscribed (type, c))
688 { 741 {
689 count++; 742 count++;
690 GNUNET_SERVER_notification_context_unicast (nc, c->handle, msg, 743 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "MESH: sending\n");
691 GNUNET_YES); 744 GNUNET_SERVER_notification_context_unicast (
745 nc,
746 c->handle,
747 (struct GNUNET_MessageHeader *) cbuf,
748 GNUNET_YES);
692 } 749 }
693 } 750 }
694 return count; 751 return count;
@@ -739,15 +796,17 @@ send_core_create_path (void *cls, size_t size, void *buf);
739static void 796static void
740peer_info_cancel_transmission(struct MeshPeerInfo *peer, unsigned int i) 797peer_info_cancel_transmission(struct MeshPeerInfo *peer, unsigned int i)
741{ 798{
742 if (peer->core_transmit[i]) 799 if (NULL != peer->core_transmit[i])
743 { 800 {
744 struct MeshDataDescriptor *dd; 801 struct MeshDataDescriptor *dd;
745 struct MeshPathInfo *path_info; 802 struct MeshPathInfo *path_info;
746 GNUNET_CORE_notify_transmit_ready_cancel (peer->core_transmit[i]); 803
747 /* TODO: notify that tranmission has failed */
748 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 804 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
749 "MESH: Cancelled data transmission at %u\n", 805 "MESH: Cancelling data transmission at %u\n",
750 i); 806 i);
807 GNUNET_CORE_notify_transmit_ready_cancel (peer->core_transmit[i]);
808 peer->core_transmit[i] = NULL;
809 /* TODO: notify that tranmission has failed */
751 switch (peer->types[i]) 810 switch (peer->types[i])
752 { 811 {
753 case GNUNET_MESSAGE_TYPE_MESH_MULTICAST: 812 case GNUNET_MESSAGE_TYPE_MESH_MULTICAST:
@@ -840,6 +899,39 @@ peer_info_get_short (const GNUNET_PEER_Id peer)
840 899
841 900
842/** 901/**
902 * Iterator to remove the tunnel from the list of tunnels a peer participates
903 * in.
904 *
905 * @param cls Closure (tunnel info)
906 * @param key GNUNET_PeerIdentity of the peer (unused)
907 * @param value PeerInfo of the peer
908 *
909 * @return always GNUNET_YES, to keep iterating
910 */
911static int
912peer_info_delete_tunnel (void* cls, const GNUNET_HashCode* key, void* value)
913{
914 struct MeshTunnel *t = cls;
915 struct MeshPeerInfo *peer = value;
916 unsigned int i;
917
918 for (i = 0; i < peer->ntunnels; i++)
919 {
920 if (0 == memcmp(&peer->tunnels[i]->id,
921 &t->id,
922 sizeof(struct MESH_TunnelID)))
923 {
924 peer->ntunnels--;
925 peer->tunnels[i] = peer->tunnels[peer->ntunnels];
926 peer->tunnels = GNUNET_realloc (peer->tunnels, peer->ntunnels);
927 return GNUNET_YES;
928 }
929 }
930 return GNUNET_YES;
931}
932
933
934/**
843 * Sends a CREATE PATH message for a path to a peer, properly registrating 935 * Sends a CREATE PATH message for a path to a peer, properly registrating
844 * all used resources. 936 * all used resources.
845 * 937 *
@@ -1289,6 +1381,10 @@ tunnel_get_by_local_id (struct MeshClient *c, MESH_TunnelNumber tid)
1289 GNUNET_HashCode hash; 1381 GNUNET_HashCode hash;
1290 1382
1291 GNUNET_CRYPTO_hash (&tid, sizeof (MESH_TunnelNumber), &hash); 1383 GNUNET_CRYPTO_hash (&tid, sizeof (MESH_TunnelNumber), &hash);
1384 if (tid >= GNUNET_MESH_LOCAL_TUNNEL_ID_SERV)
1385 {
1386 return GNUNET_CONTAINER_multihashmap_get (incoming_tunnels, &hash);
1387 }
1292 return GNUNET_CONTAINER_multihashmap_get (c->tunnels, &hash); 1388 return GNUNET_CONTAINER_multihashmap_get (c->tunnels, &hash);
1293} 1389}
1294 1390
@@ -1433,8 +1529,11 @@ tunnel_add_path (struct MeshTunnel *t,
1433 tree_add_path(t->tree, p, NULL); 1529 tree_add_path(t->tree, p, NULL);
1434 if (NULL == t->tree->me) 1530 if (NULL == t->tree->me)
1435 t->tree->me = tree_find_peer(t->tree->root, p->peers[own_pos]); 1531 t->tree->me = tree_find_peer(t->tree->root, p->peers[own_pos]);
1436 GNUNET_PEER_resolve (p->peers[own_pos + 1], &id); 1532 if (own_pos < p->length - 1)
1437 tree_update_first_hops(t->tree, t->tree->me, &id); 1533 {
1534 GNUNET_PEER_resolve (p->peers[own_pos + 1], &id);
1535 tree_update_first_hops(t->tree, t->tree->me, &id);
1536 }
1438} 1537}
1439 1538
1440 1539
@@ -1477,13 +1576,22 @@ tunnel_destroy (struct MeshTunnel *t)
1477 GNUNET_HashCode hash; 1576 GNUNET_HashCode hash;
1478 int r; 1577 int r;
1479 1578
1480 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "MESH: DESTROYING TUNNEL at %p\n", t);
1481 if (NULL == t) 1579 if (NULL == t)
1482 return GNUNET_OK; 1580 return GNUNET_OK;
1483 1581
1484 c = t->client; 1582 c = t->client;
1485#if MESH_DEBUG 1583#if MESH_DEBUG
1486 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "MESH: by client %u\n", c->id); 1584 {
1585 struct GNUNET_PeerIdentity id;
1586
1587 GNUNET_PEER_resolve(t->id.oid, &id);
1588 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1589 "MESH: destroying tunnel %s [%x]\n",
1590 GNUNET_i2s (&id),
1591 t->id.tid);
1592 if (NULL != c)
1593 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "MESH: by client %u\n", c->id);
1594 }
1487#endif 1595#endif
1488 1596
1489 GNUNET_CRYPTO_hash (&t->id, sizeof (struct MESH_TunnelID), &hash); 1597 GNUNET_CRYPTO_hash (&t->id, sizeof (struct MESH_TunnelID), &hash);
@@ -1493,10 +1601,18 @@ tunnel_destroy (struct MeshTunnel *t)
1493 } 1601 }
1494 1602
1495 GNUNET_CRYPTO_hash (&t->local_tid, sizeof (MESH_TunnelNumber), &hash); 1603 GNUNET_CRYPTO_hash (&t->local_tid, sizeof (MESH_TunnelNumber), &hash);
1496 if (GNUNET_YES != GNUNET_CONTAINER_multihashmap_remove (c->tunnels, &hash, t)) 1604 if (NULL != c && GNUNET_YES != GNUNET_CONTAINER_multihashmap_remove (c->tunnels, &hash, t))
1497 { 1605 {
1498 r = GNUNET_SYSERR; 1606 r = GNUNET_SYSERR;
1499 } 1607 }
1608 if (t->local_tid >= GNUNET_MESH_LOCAL_TUNNEL_ID_SERV)
1609 {
1610 GNUNET_CRYPTO_hash (&t->local_tid, sizeof (MESH_TunnelNumber), &hash);
1611 GNUNET_break (GNUNET_YES ==
1612 GNUNET_CONTAINER_multihashmap_remove (incoming_tunnels, &hash, t));
1613 }
1614
1615 GNUNET_CONTAINER_multihashmap_iterate(t->peers, &peer_info_delete_tunnel, t);
1500 GNUNET_CONTAINER_multihashmap_destroy (t->peers); 1616 GNUNET_CONTAINER_multihashmap_destroy (t->peers);
1501 q = t->queue_head; 1617 q = t->queue_head;
1502 while (NULL != q) 1618 while (NULL != q)
@@ -1511,7 +1627,6 @@ tunnel_destroy (struct MeshTunnel *t)
1511 tree_destroy(t->tree); 1627 tree_destroy(t->tree);
1512 if (NULL != t->dht_get_type) 1628 if (NULL != t->dht_get_type)
1513 GNUNET_DHT_get_stop(t->dht_get_type); 1629 GNUNET_DHT_get_stop(t->dht_get_type);
1514 t->dht_get_type = NULL;
1515 GNUNET_free (t); 1630 GNUNET_free (t);
1516 return r; 1631 return r;
1517} 1632}
@@ -1588,6 +1703,7 @@ send_core_create_path (void *cls, size_t size, void *buf)
1588 info); 1703 info);
1589 return 0; 1704 return 0;
1590 } 1705 }
1706 info->peer->core_transmit[info->pos] = NULL;
1591 1707
1592 msg = (struct GNUNET_MESH_ManipulatePath *) buf; 1708 msg = (struct GNUNET_MESH_ManipulatePath *) buf;
1593 msg->header.size = htons (size_needed); 1709 msg->header.size = htons (size_needed);
@@ -1907,9 +2023,25 @@ handle_mesh_path_create (void *cls, const struct GNUNET_PeerIdentity *peer,
1907 2023
1908 GNUNET_CRYPTO_hash (&t->id, sizeof (struct MESH_TunnelID), &hash); 2024 GNUNET_CRYPTO_hash (&t->id, sizeof (struct MESH_TunnelID), &hash);
1909 if (GNUNET_OK != 2025 if (GNUNET_OK !=
1910 GNUNET_CONTAINER_multihashmap_put (tunnels, &hash, t, 2026 GNUNET_CONTAINER_multihashmap_put (
1911 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)) 2027 tunnels,
2028 &hash,
2029 t,
2030 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY))
2031 {
2032 tunnel_destroy(t);
2033 GNUNET_break (0);
2034 return GNUNET_OK;
2035 }
2036 GNUNET_CRYPTO_hash (&t->local_tid, sizeof (MESH_TunnelNumber), &hash);
2037 if (GNUNET_OK !=
2038 GNUNET_CONTAINER_multihashmap_put (
2039 incoming_tunnels,
2040 &hash,
2041 t,
2042 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY))
1912 { 2043 {
2044 tunnel_destroy(t);
1913 GNUNET_break (0); 2045 GNUNET_break (0);
1914 return GNUNET_OK; 2046 return GNUNET_OK;
1915 } 2047 }
@@ -1975,15 +2107,7 @@ handle_mesh_path_create (void *cls, const struct GNUNET_PeerIdentity *peer,
1975 info->origin = &t->id; 2107 info->origin = &t->id;
1976 info->peer = GNUNET_CONTAINER_multihashmap_get (peers, &peer->hashPubKey); 2108 info->peer = GNUNET_CONTAINER_multihashmap_get (peers, &peer->hashPubKey);
1977 GNUNET_assert (NULL != info->peer); 2109 GNUNET_assert (NULL != info->peer);
1978 for (j = 0; info->peer->core_transmit[j]; j++) 2110 j = peer_info_transmit_slot(info->peer);
1979 {
1980 if (j == (CORE_QUEUE_SIZE - 1))
1981 {
1982 GNUNET_free (info);
1983 GNUNET_break (0);
1984 return GNUNET_OK;
1985 }
1986 }
1987 info->handler_n = j; 2111 info->handler_n = j;
1988 info->peer->types[j] = GNUNET_MESSAGE_TYPE_MESH_PATH_ACK; 2112 info->peer->types[j] = GNUNET_MESSAGE_TYPE_MESH_PATH_ACK;
1989 info->peer->infos[j] = info; 2113 info->peer->infos[j] = info;
@@ -2047,6 +2171,9 @@ handle_mesh_data_unicast (void *cls, const struct GNUNET_PeerIdentity *peer,
2047 return GNUNET_OK; 2171 return GNUNET_OK;
2048 } 2172 }
2049 msg = (struct GNUNET_MESH_Unicast *) message; 2173 msg = (struct GNUNET_MESH_Unicast *) message;
2174 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2175 "MESH: of type %u\n",
2176 ntohs (msg[1].header.type));
2050 t = tunnel_get (&msg->oid, ntohl (msg->tid)); 2177 t = tunnel_get (&msg->oid, ntohl (msg->tid));
2051 if (NULL == t) 2178 if (NULL == t)
2052 { 2179 {
@@ -2059,7 +2186,7 @@ handle_mesh_data_unicast (void *cls, const struct GNUNET_PeerIdentity *peer,
2059 { 2186 {
2060 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 2187 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2061 "MESH: it's for us! sending to clients...\n"); 2188 "MESH: it's for us! sending to clients...\n");
2062 send_subscribed_clients ((struct GNUNET_MessageHeader *) &msg[1]); 2189 send_subscribed_clients (message, (struct GNUNET_MessageHeader *) &msg[1]);
2063 return GNUNET_OK; 2190 return GNUNET_OK;
2064 } 2191 }
2065 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 2192 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
@@ -2121,7 +2248,7 @@ handle_mesh_data_multicast (void *cls, const struct GNUNET_PeerIdentity *peer,
2121 /* Transmit to locally interested clients */ 2248 /* Transmit to locally interested clients */
2122 if (GNUNET_CONTAINER_multihashmap_contains (t->peers, &my_full_id.hashPubKey)) 2249 if (GNUNET_CONTAINER_multihashmap_contains (t->peers, &my_full_id.hashPubKey))
2123 { 2250 {
2124 send_subscribed_clients ((struct GNUNET_MessageHeader *) &msg[1]); 2251 send_subscribed_clients (message, (struct GNUNET_MessageHeader *) &msg[1]);
2125 } 2252 }
2126 n = t->tree->me->children_head; 2253 n = t->tree->me->children_head;
2127 if (NULL == n) 2254 if (NULL == n)
@@ -2878,11 +3005,6 @@ handle_local_tunnel_destroy (void *cls, struct GNUNET_SERVER_Client *client,
2878 t = GNUNET_CONTAINER_multihashmap_get (c->tunnels, &hash); 3005 t = GNUNET_CONTAINER_multihashmap_get (c->tunnels, &hash);
2879 GNUNET_CONTAINER_multihashmap_remove (c->tunnels, &hash, t); 3006 GNUNET_CONTAINER_multihashmap_remove (c->tunnels, &hash, t);
2880 3007
2881 /* Remove from global id hashmap */
2882 GNUNET_CRYPTO_hash (&t->id, sizeof (struct MESH_TunnelID), &hash);
2883 GNUNET_break (GNUNET_YES ==
2884 GNUNET_CONTAINER_multihashmap_remove (tunnels, &hash, t));
2885
2886// notify_tunnel_destroy(t); FIXME 3008// notify_tunnel_destroy(t); FIXME
2887 tunnel_destroy(t); 3009 tunnel_destroy(t);
2888 GNUNET_SERVER_receive_done (client, GNUNET_OK); 3010 GNUNET_SERVER_receive_done (client, GNUNET_OK);
@@ -3161,7 +3283,9 @@ handle_local_unicast (void *cls, struct GNUNET_SERVER_Client *client,
3161 } 3283 }
3162 3284
3163 /* Is it a local tunnel? Then, does client own the tunnel? */ 3285 /* Is it a local tunnel? Then, does client own the tunnel? */
3164 if (t->client->handle != NULL && t->client->handle != client) 3286 if (NULL != t->client &&
3287 NULL != t->client->handle &&
3288 t->client->handle != client)
3165 { 3289 {
3166 GNUNET_break (0); 3290 GNUNET_break (0);
3167 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); 3291 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
@@ -3519,6 +3643,7 @@ run (void *cls, struct GNUNET_SERVER_Handle *server,
3519 next_local_tid = GNUNET_MESH_LOCAL_TUNNEL_ID_SERV; 3643 next_local_tid = GNUNET_MESH_LOCAL_TUNNEL_ID_SERV;
3520 3644
3521 tunnels = GNUNET_CONTAINER_multihashmap_create (32); 3645 tunnels = GNUNET_CONTAINER_multihashmap_create (32);
3646 incoming_tunnels = GNUNET_CONTAINER_multihashmap_create (32);
3522 peers = GNUNET_CONTAINER_multihashmap_create (32); 3647 peers = GNUNET_CONTAINER_multihashmap_create (32);
3523 applications = GNUNET_CONTAINER_multihashmap_create (32); 3648 applications = GNUNET_CONTAINER_multihashmap_create (32);
3524 types = GNUNET_CONTAINER_multihashmap_create (32); 3649 types = GNUNET_CONTAINER_multihashmap_create (32);