aboutsummaryrefslogtreecommitdiff
path: root/src/mesh
diff options
context:
space:
mode:
authorBart Polot <bart@net.in.tum.de>2011-10-07 13:05:48 +0000
committerBart Polot <bart@net.in.tum.de>2011-10-07 13:05:48 +0000
commit2dd4ee49cb5718ebc55e28ae93d21f2aeb5ad7da (patch)
treebd374275d92b865586032281c11971cc80dc200f /src/mesh
parentd5417c5b080c8fb66b9117adf815dd1953bc012a (diff)
downloadgnunet-2dd4ee49cb5718ebc55e28ae93d21f2aeb5ad7da.tar.gz
gnunet-2dd4ee49cb5718ebc55e28ae93d21f2aeb5ad7da.zip
Refactored connection to peers, cancelation of transmissions
Diffstat (limited to 'src/mesh')
-rw-r--r--src/mesh/gnunet-service-mesh.c536
1 files changed, 324 insertions, 212 deletions
diff --git a/src/mesh/gnunet-service-mesh.c b/src/mesh/gnunet-service-mesh.c
index a35ef9a66..612cade81 100644
--- a/src/mesh/gnunet-service-mesh.c
+++ b/src/mesh/gnunet-service-mesh.c
@@ -320,6 +320,11 @@ struct MeshPathInfo
320 * Path itself 320 * Path itself
321 */ 321 */
322 struct MeshPeerPath *path; 322 struct MeshPeerPath *path;
323
324 /**
325 * Position in peer's transmit queue
326 */
327 unsigned int pos;
323}; 328};
324 329
325 330
@@ -621,12 +626,167 @@ dht_get_id_handler (void *cls, struct GNUNET_TIME_Absolute exp,
621/******************************************************************************/ 626/******************************************************************************/
622 627
623/** 628/**
629 * Check if client has registered with the service and has not disconnected
630 *
631 * @param client the client to check
632 *
633 * @return non-NULL if client exists in the global DLL
634 */
635static struct MeshClient *
636client_get (struct GNUNET_SERVER_Client *client)
637{
638 struct MeshClient *c;
639
640 c = clients;
641 while (NULL != c)
642 {
643 if (c->handle == client)
644 return c;
645 c = c->next;
646 }
647 return NULL;
648}
649
650
651/**
652 * Checks if a given client has subscribed to certain message type
653 *
654 * @param message_type Type of message to check
655 * @param c Client to check
656 *
657 * @return GNUNET_YES or GNUNET_NO, depending on subscription status
658 *
659 * TODO inline?
660 */
661static int
662client_is_subscribed (uint16_t message_type, struct MeshClient *c)
663{
664 GNUNET_HashCode hc;
665
666 GNUNET_CRYPTO_hash (&message_type, sizeof (uint16_t), &hc);
667 return GNUNET_CONTAINER_multihashmap_contains (c->types, &hc);
668}
669
670
671/**
672 * Send the message to all clients that have subscribed to its type
673 *
674 * @param msg Pointer to the message itself
675 * @return number of clients this message was sent to
676 */
677static unsigned int
678send_subscribed_clients (struct GNUNET_MessageHeader *msg)
679{
680 struct MeshClient *c;
681 unsigned int count;
682 uint16_t type;
683
684 type = ntohs (msg->type);
685 for (count = 0, c = clients; c != NULL; c = c->next)
686 {
687 if (client_is_subscribed (type, c))
688 {
689 count++;
690 GNUNET_SERVER_notification_context_unicast (nc, c->handle, msg,
691 GNUNET_YES);
692 }
693 }
694 return count;
695}
696
697
698/**
699 * Notify the client that owns the tunnel that a peer has connected to it
700 *
701 * @param t Tunnel whose owner to notify
702 * @param id Short id of the peer that has connected
703 */
704static void
705send_client_peer_connected (const struct MeshTunnel *t, const GNUNET_PEER_Id id)
706{
707 struct GNUNET_MESH_PeerControl pc;
708
709 pc.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_LOCAL_PEER_ADD);
710 pc.header.size = htons (sizeof (struct GNUNET_MESH_PeerControl));
711 pc.tunnel_id = htonl (t->local_tid);
712 GNUNET_PEER_resolve (id, &pc.peer);
713 GNUNET_SERVER_notification_context_unicast (nc, t->client->handle,
714 &pc.header, GNUNET_NO);
715}
716
717
718/**
719 * Cancel a core transmission that was already requested and free all resources
720 * associated to the request.
721 *
722 * @param peer PeeInfo of the peer whose transmission is cancelled.
723 * @param i Position of the transmission to be cancelled.
724 */
725static void
726peer_info_cancel_transmission(struct MeshPeerInfo *peer, unsigned int i)
727{
728 if (peer->core_transmit[i])
729 {
730 struct MeshDataDescriptor *dd;
731 struct MeshPathInfo *path_info;
732 GNUNET_CORE_notify_transmit_ready_cancel (peer->core_transmit[i]);
733 /* TODO: notify that tranmission has failed */
734 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
735 "MESH: Cancelled data transmission at %u\n",
736 i);
737 switch (peer->types[i])
738 {
739 case GNUNET_MESSAGE_TYPE_MESH_MULTICAST:
740 case GNUNET_MESSAGE_TYPE_MESH_UNICAST:
741 case GNUNET_MESSAGE_TYPE_MESH_TO_ORIGIN:
742 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "MESH: type payload\n");
743 dd = peer->infos[i];
744 if (0 == --(*dd->copies))
745 {
746 GNUNET_free (dd->copies);
747 GNUNET_free (dd->data);
748 }
749 break;
750 case GNUNET_MESSAGE_TYPE_MESH_PATH_CREATE:
751 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "MESH: type create path\n");
752 path_info = peer->infos[i];
753 path_destroy(path_info->path);
754 break;
755 }
756 GNUNET_free (peer->infos[i]);
757 }
758}
759
760
761/**
762 *
763 */
764static unsigned int
765peer_info_transmit_position (struct MeshPeerInfo *peer)
766{
767 unsigned int i;
768
769 for (i = 0; peer->core_transmit[i]; i++)
770 {
771 if (i == (CORE_QUEUE_SIZE - 1))
772 {
773 /* All positions are taken! Overwriting! */
774 GNUNET_break (0);
775 peer_info_cancel_transmission(peer, 0);
776 return 0;
777 }
778 }
779 return i;
780}
781
782
783/**
624 * Retrieve the MeshPeerInfo stucture associated with the peer, create one 784 * Retrieve the MeshPeerInfo stucture associated with the peer, create one
625 * and insert it in the appropiate structures if the peer is not known yet. 785 * and insert it in the appropiate structures if the peer is not known yet.
626 * 786 *
627 * @param peer Identity of the peer 787 * @param peer Full identity of the peer.
628 * 788 *
629 * @return Existing or newly created peer info 789 * @return Existing or newly created peer info.
630 */ 790 */
631static struct MeshPeerInfo * 791static struct MeshPeerInfo *
632peer_info_get (const struct GNUNET_PeerIdentity *peer) 792peer_info_get (const struct GNUNET_PeerIdentity *peer)
@@ -647,6 +807,113 @@ peer_info_get (const struct GNUNET_PeerIdentity *peer)
647} 807}
648 808
649 809
810/**
811 * Retrieve the MeshPeerInfo stucture associated with the peer, create one
812 * and insert it in the appropiate structures if the peer is not known yet.
813 *
814 * @param peer Short identity of the peer.
815 *
816 * @return Existing or newly created peer info.
817 */
818static struct MeshPeerInfo *
819peer_info_get_short (const GNUNET_PEER_Id peer)
820{
821 struct GNUNET_PeerIdentity id;
822
823 GNUNET_PEER_resolve(peer, &id);
824 return peer_info_get(&id);
825}
826
827
828/**
829 * Function called to notify a client about the socket
830 * being ready to queue more data. "buf" will be
831 * NULL and "size" zero if the socket was closed for
832 * writing in the meantime.
833 *
834 * @param cls closure
835 * @param size number of bytes available in buf
836 * @param buf where the callee should write the message
837 * @return number of bytes written to buf
838 */
839static size_t
840send_core_create_path (void *cls, size_t size, void *buf);
841
842
843/**
844 * Try to establish a new connection to this peer.
845 * Use the best path for the given tunnel.
846 * If the peer doesn't have any path to it yet, try to get one.
847 * If the peer already has some path, send a CREATE PATH towards it.
848 *
849 * @param peer PeerInfo of the peer.
850 * @param t Tunnel for which to create the path, if possible.
851 */
852static void
853peer_info_connect (struct MeshPeerInfo *peer, struct MeshTunnel *t)
854{
855 struct MeshPeerPath *p;
856 struct MeshPathInfo *path_info;
857 struct MeshPeerInfo *neighbor;
858
859 if (NULL != peer->path_head)
860 {
861 p = tree_get_path_to_peer(t->tree, peer->id);
862 if (p->length > 1)
863 {
864 struct GNUNET_PeerIdentity *id;
865
866 path_info = GNUNET_malloc (sizeof (struct MeshPathInfo));
867 path_info->path = p;
868 path_info->peer = peer;
869 path_info->t = t;
870 id = path_get_first_hop(t->tree, peer->id);
871 neighbor = peer_info_get(id);
872 path_info->pos = peer_info_transmit_position(neighbor);
873 neighbor->types[path_info->pos] = GNUNET_MESSAGE_TYPE_MESH_PATH_CREATE;
874 neighbor->infos[path_info->pos] = path_info;
875 neighbor->core_transmit[path_info->pos] =
876 GNUNET_CORE_notify_transmit_ready (
877 core_handle, /* handle */
878 0, /* cork */
879 0, /* priority */
880 GNUNET_TIME_UNIT_FOREVER_REL, /* timeout */
881 id, /* target */
882 sizeof (struct GNUNET_MESH_ManipulatePath)
883 + (p->length * sizeof (struct GNUNET_PeerIdentity)), /*size */
884 &send_core_create_path, /* callback */
885 path_info); /* cls */
886 }
887 else
888 {
889 send_client_peer_connected(t, myid);
890 }
891 }
892 else if (NULL == peer->dhtget)
893 {
894 struct GNUNET_PeerIdentity id;
895
896 GNUNET_PEER_resolve(peer->id, &id);
897 path_info = GNUNET_malloc(sizeof(struct MeshPathInfo));
898 path_info->peer = peer;
899 path_info->t = t;
900 peer->dhtget =
901 GNUNET_DHT_get_start(dht_handle, /* handle */
902 GNUNET_TIME_UNIT_FOREVER_REL, /* timeout */
903 GNUNET_BLOCK_TYPE_TEST, /* type */
904 &id.hashPubKey, /* key to search */
905 4, /* replication level */
906 GNUNET_DHT_RO_RECORD_ROUTE |
907 GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE,
908 NULL, /* xquery */
909 0, /* xquery bits */
910 &dht_get_id_handler,
911 path_info);
912 }
913 /* Otherwise, there is no path but the DHT get is already started. */
914}
915
916
650#if LATER 917#if LATER
651/** 918/**
652 * Destroy the peer_info and free any allocated resources linked to it 919 * Destroy the peer_info and free any allocated resources linked to it
@@ -749,8 +1016,7 @@ path_remove_from_peer (struct MeshPeerInfo *peer,
749 * Trivial immiediate fix: try to reconnect to the disconnected node. All 1016 * Trivial immiediate fix: try to reconnect to the disconnected node. All
750 * its children will be reachable trough him. 1017 * its children will be reachable trough him.
751 */ 1018 */
752 GNUNET_PEER_resolve(d, &id); 1019 peer_d = peer_info_get_short(d);
753 peer_d = peer_info_get(&id);
754 best = UINT_MAX; 1020 best = UINT_MAX;
755 aux = NULL; 1021 aux = NULL;
756 for (p = peer_d->path_head; NULL != p; p = p->next) 1022 for (p = peer_d->path_head; NULL != p; p = p->next)
@@ -817,6 +1083,11 @@ path_add_to_peer (struct MeshPeerInfo *peer_info, struct MeshPeerPath *path)
817 } 1083 }
818 1084
819 l = path_get_length (path); 1085 l = path_get_length (path);
1086 if (0 == l)
1087 {
1088 GNUNET_free (path);
1089 return;
1090 }
820 1091
821 for (aux = peer_info->path_head; aux != NULL; aux = aux->next) 1092 for (aux = peer_info->path_head; aux != NULL; aux = aux->next)
822 { 1093 {
@@ -963,49 +1234,6 @@ path_refresh (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc);
963 1234
964 1235
965/** 1236/**
966 * Check if client has registered with the service and has not disconnected
967 *
968 * @param client the client to check
969 *
970 * @return non-NULL if client exists in the global DLL
971 */
972static struct MeshClient *
973client_get (struct GNUNET_SERVER_Client *client)
974{
975 struct MeshClient *c;
976
977 c = clients;
978 while (NULL != c)
979 {
980 if (c->handle == client)
981 return c;
982 c = c->next;
983 }
984 return NULL;
985}
986
987
988/**
989 * Checks if a given client has subscribed to certain message type
990 *
991 * @param message_type Type of message to check
992 * @param c Client to check
993 *
994 * @return GNUNET_YES or GNUNET_NO, depending on subscription status
995 *
996 * TODO inline?
997 */
998static int
999client_is_subscribed (uint16_t message_type, struct MeshClient *c)
1000{
1001 GNUNET_HashCode hc;
1002
1003 GNUNET_CRYPTO_hash (&message_type, sizeof (uint16_t), &hc);
1004 return GNUNET_CONTAINER_multihashmap_contains (c->types, &hc);
1005}
1006
1007
1008/**
1009 * Search for a tunnel among the tunnels for a client 1237 * Search for a tunnel among the tunnels for a client
1010 * 1238 *
1011 * @param c the client whose tunnels to search in 1239 * @param c the client whose tunnels to search in
@@ -1069,24 +1297,27 @@ tunnel_get (struct GNUNET_PeerIdentity *oid, MESH_TunnelNumber tid)
1069void 1297void
1070notify_peer_disconnected (const struct MeshTunnelTreeNode *n) 1298notify_peer_disconnected (const struct MeshTunnelTreeNode *n)
1071{ 1299{
1072 struct GNUNET_MESH_PeerControl msg; 1300 struct MeshPeerInfo *peer;
1073
1074 if (NULL == n->t->client || NULL == nc)
1075 return;
1076 1301
1077 msg.header.size = htons (sizeof (msg)); 1302 if (NULL != n->t->client && NULL != nc)
1078 msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_LOCAL_PEER_DEL); 1303 {
1079 msg.tunnel_id = htonl (n->t->local_tid); 1304 struct GNUNET_MESH_PeerControl msg;
1080 GNUNET_PEER_resolve (n->peer, &msg.peer); 1305 msg.header.size = htons (sizeof (msg));
1081 GNUNET_SERVER_notification_context_unicast (nc, n->t->client->handle, 1306 msg.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_LOCAL_PEER_DEL);
1082 &msg.header, GNUNET_NO); 1307 msg.tunnel_id = htonl (n->t->local_tid);
1308 GNUNET_PEER_resolve (n->peer, &msg.peer);
1309 GNUNET_SERVER_notification_context_unicast (nc, n->t->client->handle,
1310 &msg.header, GNUNET_NO);
1311 }
1312 peer = peer_info_get_short(n->peer);
1313 peer_info_connect(peer, n->t);
1083} 1314}
1084 1315
1085 1316
1086/** 1317/**
1087 * Add a peer to a tunnel, accomodating paths accordingly and initializing all 1318 * Add a peer to a tunnel, accomodating paths accordingly and initializing all
1088 * needed rescources. 1319 * needed rescources.
1089 * If peer already exists, do nothing. 1320 * If peer already exists, reevaluate shortest path and change if different.
1090 * 1321 *
1091 * @param t Tunnel we want to add a new peer to 1322 * @param t Tunnel we want to add a new peer to
1092 * @param peer PeerInfo of the peer being added 1323 * @param peer PeerInfo of the peer being added
@@ -1095,40 +1326,48 @@ notify_peer_disconnected (const struct MeshTunnelTreeNode *n)
1095static void 1326static void
1096tunnel_add_peer (struct MeshTunnel *t, struct MeshPeerInfo *peer) 1327tunnel_add_peer (struct MeshTunnel *t, struct MeshPeerInfo *peer)
1097{ 1328{
1098 struct MeshPeerPath *p; 1329 struct GNUNET_PeerIdentity id;
1099 struct MeshPeerPath *best_p; 1330 struct MeshPeerPath *best_p;
1331 struct MeshPeerPath *p;
1100 unsigned int best_cost; 1332 unsigned int best_cost;
1101 unsigned int cost; 1333 unsigned int cost;
1102 1334
1103 if (NULL != tree_find_peer(t->tree->root, peer->id)) 1335 GNUNET_PEER_resolve(peer->id, &id);
1104 { 1336 if (GNUNET_NO ==
1105 /* Already have it, nothing to do. */ 1337 GNUNET_CONTAINER_multihashmap_contains(t->peers, &id.hashPubKey))
1106 return;
1107 }
1108
1109 t->peers_total++;
1110 GNUNET_array_append (peer->tunnels, peer->ntunnels, t);
1111 if (NULL == (p = peer->path_head))
1112 { 1338 {
1113 GNUNET_break (0); 1339 t->peers_total++;
1114 return; 1340 GNUNET_array_append (peer->tunnels, peer->ntunnels, t);
1341 GNUNET_CONTAINER_multihashmap_put(
1342 t->peers,
1343 &id.hashPubKey,
1344 peer,
1345 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST);
1115 } 1346 }
1116 1347
1117 best_p = p; 1348 if (NULL != (p = peer->path_head))
1118 best_cost = UINT_MAX;
1119 while (NULL != p)
1120 { 1349 {
1121 if ((cost = path_get_cost (t->tree, p)) < best_cost) 1350 best_p = p;
1351 best_cost = UINT_MAX;
1352 while (NULL != p)
1122 { 1353 {
1123 best_cost = cost; 1354 if ((cost = path_get_cost (t->tree, p)) < best_cost)
1124 best_p = p; 1355 {
1356 best_cost = cost;
1357 best_p = p;
1358 }
1359 p = p->next;
1125 } 1360 }
1126 p = p->next; 1361 tree_add_path (t->tree, best_p, &notify_peer_disconnected);
1362 if (GNUNET_SCHEDULER_NO_TASK == t->path_refresh_task)
1363 t->path_refresh_task =
1364 GNUNET_SCHEDULER_add_delayed (t->tree->refresh, &path_refresh, t);
1365 }
1366 else
1367 {
1368 /* Start a DHT get if necessary */
1369 peer_info_connect(peer, t);
1127 } 1370 }
1128 tree_add_path (t->tree, best_p, &notify_peer_disconnected);
1129 if (GNUNET_SCHEDULER_NO_TASK == t->path_refresh_task)
1130 t->path_refresh_task =
1131 GNUNET_SCHEDULER_add_delayed (t->tree->refresh, &path_refresh, t);
1132} 1371}
1133 1372
1134 1373
@@ -1240,7 +1479,6 @@ tunnel_destroy_iterator (void *cls, const GNUNET_HashCode * key, void *value)
1240/**************** MESH NETWORK HANDLER HELPERS ***********************/ 1479/**************** MESH NETWORK HANDLER HELPERS ***********************/
1241/******************************************************************************/ 1480/******************************************************************************/
1242 1481
1243
1244/** 1482/**
1245 * Function called to notify a client about the socket 1483 * Function called to notify a client about the socket
1246 * being ready to queue more data. "buf" will be 1484 * being ready to queue more data. "buf" will be
@@ -1519,54 +1757,6 @@ send_p2p_tunnel_destroy (void *cls, size_t size, void *buf)
1519#endif 1757#endif
1520 1758
1521 1759
1522/**
1523 * Send the message to all clients that have subscribed to its type
1524 *
1525 * @param msg Pointer to the message itself
1526 * @return number of clients this message was sent to
1527 */
1528static unsigned int
1529send_subscribed_clients (struct GNUNET_MessageHeader *msg)
1530{
1531 struct MeshClient *c;
1532 unsigned int count;
1533 uint16_t type;
1534
1535 type = ntohs (msg->type);
1536 for (count = 0, c = clients; c != NULL; c = c->next)
1537 {
1538 if (client_is_subscribed (type, c))
1539 {
1540 count++;
1541 GNUNET_SERVER_notification_context_unicast (nc, c->handle, msg,
1542 GNUNET_YES);
1543 }
1544 }
1545 return count;
1546}
1547
1548
1549
1550/**
1551 * Notify the client that owns the tunnel that a peer has connected to it
1552 *
1553 * @param t Tunnel whose owner to notify
1554 * @param id Short id of the peer that has connected
1555 */
1556static void
1557send_client_peer_connected (const struct MeshTunnel *t, const GNUNET_PEER_Id id)
1558{
1559 struct GNUNET_MESH_PeerControl pc;
1560
1561 pc.header.type = htons (GNUNET_MESSAGE_TYPE_MESH_LOCAL_PEER_ADD);
1562 pc.header.size = htons (sizeof (struct GNUNET_MESH_PeerControl));
1563 pc.tunnel_id = htonl (t->local_tid);
1564 GNUNET_PEER_resolve (id, &pc.peer);
1565 GNUNET_SERVER_notification_context_unicast (nc, t->client->handle,
1566 &pc.header, GNUNET_NO);
1567}
1568
1569
1570/******************************************************************************/ 1760/******************************************************************************/
1571/******************** MESH NETWORK HANDLERS **************************/ 1761/******************** MESH NETWORK HANDLERS **************************/
1572/******************************************************************************/ 1762/******************************************************************************/
@@ -2185,9 +2375,7 @@ dht_get_id_handler (void *cls, struct GNUNET_TIME_Absolute exp,
2185 enum GNUNET_BLOCK_Type type, size_t size, const void *data) 2375 enum GNUNET_BLOCK_Type type, size_t size, const void *data)
2186{ 2376{
2187 struct MeshPathInfo *path_info = cls; 2377 struct MeshPathInfo *path_info = cls;
2188 struct MeshPathInfo *path_info_aux;
2189 struct MeshPeerPath *p; 2378 struct MeshPeerPath *p;
2190 struct MeshPeerPath *aux;
2191 struct GNUNET_PeerIdentity pi; 2379 struct GNUNET_PeerIdentity pi;
2192 int i; 2380 int i;
2193 2381
@@ -2197,63 +2385,14 @@ dht_get_id_handler (void *cls, struct GNUNET_TIME_Absolute exp,
2197 GNUNET_h2s_full(&pi.hashPubKey)); 2385 GNUNET_h2s_full(&pi.hashPubKey));
2198 GNUNET_DHT_get_stop(path_info->peer->dhtget); 2386 GNUNET_DHT_get_stop(path_info->peer->dhtget);
2199 path_info->peer->dhtget = NULL; 2387 path_info->peer->dhtget = NULL;
2200 if (NULL == get_path || NULL == put_path)
2201 {
2202 if (NULL == path_info->peer->path_head)
2203 {
2204 // Find ourselves some alternate initial path to the destination: retry
2205 GNUNET_PEER_resolve(path_info->peer->id, &pi);
2206 path_info->peer->dhtget =
2207 GNUNET_DHT_get_start(dht_handle, /* handle */
2208 GNUNET_TIME_UNIT_FOREVER_REL, /* timeout */
2209 GNUNET_BLOCK_TYPE_TEST, /* type */
2210 &pi.hashPubKey, /*key to search */
2211 4, /* replication level */
2212 GNUNET_DHT_RO_RECORD_ROUTE |
2213 GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE,
2214 NULL, /* xquery */
2215 0, /* xquery bits */
2216 &dht_get_id_handler,
2217 (void *) path_info);
2218 return;
2219 }
2220 }
2221 2388
2222 p = path_build_from_dht (get_path, get_path_length, put_path, put_path_length); 2389 p = path_build_from_dht (get_path, get_path_length,
2390 put_path, put_path_length);
2223 path_add_to_peer (path_info->peer, p); 2391 path_add_to_peer (path_info->peer, p);
2224 for (i = 0; i < path_info->peer->ntunnels; i++) 2392 for (i = 0; i < path_info->peer->ntunnels; i++)
2225 { 2393 {
2226 tunnel_add_peer (path_info->peer->tunnels[i], path_info->peer); 2394 tunnel_add_peer (path_info->peer->tunnels[i], path_info->peer);
2227 aux = tree_get_path_to_peer(path_info->peer->tunnels[i]->tree, 2395 peer_info_connect(path_info->peer, path_info->t);
2228 path_info->peer->id);
2229 if (aux->length > 1)
2230 {
2231 struct GNUNET_PeerIdentity id;
2232
2233 path_info_aux = GNUNET_malloc (sizeof (struct MeshPathInfo));
2234 path_info_aux->path = aux;
2235 path_info_aux->peer = path_info->peer;
2236 path_info_aux->t = path_info->t;
2237 GNUNET_PEER_resolve (p->peers[1], &id);
2238 GNUNET_CORE_notify_transmit_ready (core_handle, /* handle */
2239 0, /* cork */
2240 0, /* priority */
2241 GNUNET_TIME_UNIT_FOREVER_REL,
2242 /* timeout */
2243 &id, /* target */
2244 sizeof (struct GNUNET_MESH_ManipulatePath)
2245 +
2246 (aux->length *
2247 sizeof (struct GNUNET_PeerIdentity)),
2248 /*size */
2249 &send_core_create_path,
2250 /* callback */
2251 path_info_aux); /* cls */
2252 }
2253 else
2254 {
2255 send_client_peer_connected(path_info->t, myid);
2256 }
2257 } 2396 }
2258 GNUNET_free (path_info); 2397 GNUNET_free (path_info);
2259 2398
@@ -3214,34 +3353,7 @@ core_disconnect (void *cls, const struct GNUNET_PeerIdentity *peer)
3214 } 3353 }
3215 for (i = 0; i < CORE_QUEUE_SIZE; i++) 3354 for (i = 0; i < CORE_QUEUE_SIZE; i++)
3216 { 3355 {
3217 if (pi->core_transmit[i]) 3356 peer_info_cancel_transmission(pi, i);
3218 {
3219 struct MeshDataDescriptor *dd;
3220 struct MeshPathInfo *path_info;
3221 GNUNET_CORE_notify_transmit_ready_cancel (pi->core_transmit[i]);
3222 /* TODO: notify that tranmission has failed */
3223 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "MESH: data at %u\n", i);
3224 switch (pi->types[i])
3225 {
3226 case GNUNET_MESSAGE_TYPE_MESH_MULTICAST:
3227 case GNUNET_MESSAGE_TYPE_MESH_UNICAST:
3228 case GNUNET_MESSAGE_TYPE_MESH_TO_ORIGIN:
3229 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "MESH: type payload\n");
3230 dd = pi->infos[i];
3231 if (0 == --(*dd->copies))
3232 {
3233 GNUNET_free (dd->copies);
3234 GNUNET_free (dd->data);
3235 }
3236 break;
3237 case GNUNET_MESSAGE_TYPE_MESH_PATH_CREATE:
3238 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "MESH: type create path\n");
3239 path_info = pi->infos[i];
3240 path_destroy(path_info->path);
3241 break;
3242 }
3243 GNUNET_free (pi->infos[i]);
3244 }
3245 } 3357 }
3246 path_remove_from_peer (pi, pi->id, myid); 3358 path_remove_from_peer (pi, pi->id, myid);
3247 if (myid == pi->id) 3359 if (myid == pi->id)