aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBart Polot <bart@net.in.tum.de>2011-10-19 18:04:01 +0000
committerBart Polot <bart@net.in.tum.de>2011-10-19 18:04:01 +0000
commite3bb58c8e0f73697c22397165d0ff24424e32839 (patch)
tree52a21b36147b6ee576a7d5b44cd33e4a390cfe2c
parent0d32b44a3762cd8861505c031e054cbca8e80bb4 (diff)
downloadgnunet-e3bb58c8e0f73697c22397165d0ff24424e32839.tar.gz
gnunet-e3bb58c8e0f73697c22397165d0ff24424e32839.zip
Added code to manage deletion of individual paths
-rw-r--r--src/mesh/gnunet-service-mesh.c191
1 files changed, 122 insertions, 69 deletions
diff --git a/src/mesh/gnunet-service-mesh.c b/src/mesh/gnunet-service-mesh.c
index 5163e8be4..cb7602b90 100644
--- a/src/mesh/gnunet-service-mesh.c
+++ b/src/mesh/gnunet-service-mesh.c
@@ -1001,67 +1001,6 @@ peer_info_delete_tunnel (void* cls, const GNUNET_HashCode* key, void* value)
1001 1001
1002 1002
1003/** 1003/**
1004 * Sends a CREATE PATH message for a path to a peer, properly registrating
1005 * all used resources.
1006 *
1007 * @param peer PeerInfo of the final peer for whom this path is being created.
1008 * @param p Path itself.
1009 * @param t Tunnel for which the path is created.
1010 */
1011static void
1012send_create_path (struct MeshPeerInfo *peer,
1013 struct MeshPeerPath *p,
1014 struct MeshTunnel *t)
1015{
1016 struct GNUNET_PeerIdentity id;
1017 struct MeshPathInfo *path_info;
1018 struct MeshPeerInfo *neighbor;
1019 unsigned int i;
1020
1021 if (NULL == p)
1022 {
1023 p = tree_get_path_to_peer(t->tree, peer->id);
1024 if (NULL == p)
1025 {
1026 GNUNET_break (0);
1027 return;
1028 }
1029 }
1030 for (i = 0; i < p->length; i++)
1031 {
1032 if (p->peers[i] == myid)
1033 break;
1034 }
1035 if (i >= p->length - 1)
1036 {
1037 path_destroy(p);
1038 GNUNET_break (0);
1039 return;
1040 }
1041 GNUNET_PEER_resolve(p->peers[i + 1], &id);
1042
1043 path_info = GNUNET_malloc (sizeof (struct MeshPathInfo));
1044 path_info->path = p;
1045 path_info->t = t;
1046 neighbor = peer_info_get(&id);
1047 path_info->peer = neighbor;
1048 path_info->pos = peer_info_transmit_slot(neighbor);
1049 neighbor->types[path_info->pos] = GNUNET_MESSAGE_TYPE_MESH_PATH_CREATE;
1050 neighbor->infos[path_info->pos] = path_info;
1051 neighbor->core_transmit[path_info->pos] =
1052 GNUNET_CORE_notify_transmit_ready (
1053 core_handle, /* handle */
1054 0, /* cork */
1055 0, /* priority */
1056 GNUNET_TIME_UNIT_FOREVER_REL, /* timeout */
1057 &id, /* target */
1058 sizeof (struct GNUNET_MESH_ManipulatePath)
1059 + (p->length * sizeof (struct GNUNET_PeerIdentity)), /*size */
1060 &send_core_create_path, /* callback */
1061 path_info); /* cls */
1062}
1063
1064/**
1065 * Core callback to write a 1004 * Core callback to write a
1066 * 1005 *
1067 * @param cls Closure (MeshDataDescriptor with data in "data" member). 1006 * @param cls Closure (MeshDataDescriptor with data in "data" member).
@@ -1146,6 +1085,105 @@ send_message (const struct GNUNET_MessageHeader *message,
1146 1085
1147 1086
1148/** 1087/**
1088 * Sends a CREATE PATH message for a path to a peer, properly registrating
1089 * all used resources.
1090 *
1091 * @param peer PeerInfo of the final peer for whom this path is being created.
1092 * @param p Path itself.
1093 * @param t Tunnel for which the path is created.
1094 */
1095static void
1096send_create_path (struct MeshPeerInfo *peer,
1097 struct MeshPeerPath *p,
1098 struct MeshTunnel *t)
1099{
1100 struct GNUNET_PeerIdentity id;
1101 struct MeshPathInfo *path_info;
1102 struct MeshPeerInfo *neighbor;
1103 unsigned int i;
1104
1105 if (NULL == p)
1106 {
1107 p = tree_get_path_to_peer(t->tree, peer->id);
1108 if (NULL == p)
1109 {
1110 GNUNET_break (0);
1111 return;
1112 }
1113 }
1114 for (i = 0; i < p->length; i++)
1115 {
1116 if (p->peers[i] == myid)
1117 break;
1118 }
1119 if (i >= p->length - 1)
1120 {
1121 path_destroy(p);
1122 GNUNET_break (0);
1123 return;
1124 }
1125 GNUNET_PEER_resolve(p->peers[i + 1], &id);
1126
1127 path_info = GNUNET_malloc (sizeof (struct MeshPathInfo));
1128 path_info->path = p;
1129 path_info->t = t;
1130 neighbor = peer_info_get(&id);
1131 path_info->peer = neighbor;
1132 path_info->pos = peer_info_transmit_slot(neighbor);
1133 neighbor->types[path_info->pos] = GNUNET_MESSAGE_TYPE_MESH_PATH_CREATE;
1134 neighbor->infos[path_info->pos] = path_info;
1135 neighbor->core_transmit[path_info->pos] =
1136 GNUNET_CORE_notify_transmit_ready (
1137 core_handle, /* handle */
1138 0, /* cork */
1139 0, /* priority */
1140 GNUNET_TIME_UNIT_FOREVER_REL, /* timeout */
1141 &id, /* target */
1142 sizeof (struct GNUNET_MESH_ManipulatePath)
1143 + (p->length * sizeof (struct GNUNET_PeerIdentity)), /*size */
1144 &send_core_create_path, /* callback */
1145 path_info); /* cls */
1146}
1147
1148
1149/**
1150 * Sends a DESTROY PATH message to free resources for a path in a tunnel
1151 *
1152 * @param t Tunnel whose path to destroy.
1153 * @param destination Short ID of the peer to whom the path to destroy.
1154 */
1155static void
1156send_destroy_path (struct MeshTunnel *t, GNUNET_PEER_Id destination)
1157{
1158 struct GNUNET_MESH_ManipulatePath *msg;
1159 struct GNUNET_PeerIdentity *pi;
1160 struct MeshPeerPath *p;
1161 unsigned int i;
1162 size_t size;
1163
1164 p = tree_get_path_to_peer(t->tree, destination);
1165 if (NULL == p)
1166 {
1167 GNUNET_break (0);
1168 return;
1169 }
1170 size = sizeof (struct GNUNET_MESH_ManipulatePath);
1171 size += p->length * sizeof (struct GNUNET_PeerIdentity);
1172 msg = GNUNET_malloc (size);
1173 msg->header.size = htons (size);
1174 msg->header.type = htons (GNUNET_MESSAGE_TYPE_MESH_PATH_DESTROY);
1175 msg->tid = htonl (t->id.tid);
1176 pi = (struct GNUNET_PeerIdentity *) &msg[1];
1177 for (i = 0; i < p->length; i++)
1178 {
1179 GNUNET_PEER_resolve(p->peers[i], &pi[i]);
1180 }
1181 send_message (&msg->header, path_get_first_hop(t->tree, destination));
1182 path_destroy (p);
1183}
1184
1185
1186/**
1149 * Try to establish a new connection to this peer. 1187 * Try to establish a new connection to this peer.
1150 * Use the best path for the given tunnel. 1188 * Use the best path for the given tunnel.
1151 * If the peer doesn't have any path to it yet, try to get one. 1189 * If the peer doesn't have any path to it yet, try to get one.
@@ -1892,16 +1930,13 @@ tunnel_destroy (struct MeshTunnel *t)
1892 * The tunnel itself is also destoyed if results in a remote empty tunnel. 1930 * The tunnel itself is also destoyed if results in a remote empty tunnel.
1893 * 1931 *
1894 * @param t Tunnel from which to remove the path. 1932 * @param t Tunnel from which to remove the path.
1895 * @param p Path which should be removed. 1933 * @param p Peer which should be removed.
1896 */ 1934 */
1897static void 1935static void
1898tunnel_delete_path (struct MeshTunnel *t, 1936tunnel_delete_peer (struct MeshTunnel *t,
1899 struct MeshPeerPath *p) 1937 GNUNET_PEER_Id peer)
1900{ 1938{
1901 GNUNET_break (GNUNET_OK == 1939 GNUNET_break (GNUNET_OK == tree_del_peer (t->tree, peer, NULL));
1902 tree_del_peer (t->tree,
1903 p->peers[p->length - 1],
1904 NULL));
1905 if (NULL == t->tree->root) 1940 if (NULL == t->tree->root)
1906 tunnel_destroy (t); 1941 tunnel_destroy (t);
1907} 1942}
@@ -2495,7 +2530,7 @@ handle_mesh_path_destroy (void *cls, const struct GNUNET_PeerIdentity *peer,
2495 "MESH: Own position: %u\n", own_pos); 2530 "MESH: Own position: %u\n", own_pos);
2496 if (own_pos < path->length - 1) 2531 if (own_pos < path->length - 1)
2497 send_message (message, &pi[own_pos + 1]); 2532 send_message (message, &pi[own_pos + 1]);
2498 tunnel_delete_path (t, path); 2533 tunnel_delete_peer (t, path->peers[path->length - 1]);
2499 return GNUNET_OK; 2534 return GNUNET_OK;
2500} 2535}
2501 2536
@@ -3454,10 +3489,12 @@ handle_local_connect_del (void *cls, struct GNUNET_SERVER_Client *client,
3454 const struct GNUNET_MessageHeader *message) 3489 const struct GNUNET_MessageHeader *message)
3455{ 3490{
3456 struct GNUNET_MESH_PeerControl *peer_msg; 3491 struct GNUNET_MESH_PeerControl *peer_msg;
3492 struct MeshPeerInfo *peer_info;
3457 struct MeshClient *c; 3493 struct MeshClient *c;
3458 struct MeshTunnel *t; 3494 struct MeshTunnel *t;
3459 MESH_TunnelNumber tid; 3495 MESH_TunnelNumber tid;
3460 3496
3497 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "MESH: Got a PEER DEL request\n");
3461 /* Sanity check for client registration */ 3498 /* Sanity check for client registration */
3462 if (NULL == (c = client_get (client))) 3499 if (NULL == (c = client_get (client)))
3463 { 3500 {
@@ -3483,6 +3520,7 @@ handle_local_connect_del (void *cls, struct GNUNET_SERVER_Client *client,
3483 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR); 3520 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
3484 return; 3521 return;
3485 } 3522 }
3523 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "MESH: on tunnel %X\n", t->id.tid);
3486 3524
3487 /* Does client own tunnel? */ 3525 /* Does client own tunnel? */
3488 if (t->client->handle != client) 3526 if (t->client->handle != client)
@@ -3492,10 +3530,25 @@ handle_local_connect_del (void *cls, struct GNUNET_SERVER_Client *client,
3492 return; 3530 return;
3493 } 3531 }
3494 3532
3533 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
3534 "MESH: for peer %s\n",
3535 GNUNET_i2s(&peer_msg->peer));
3536 /* Is the peer in the tunnel? */
3537 peer_info = GNUNET_CONTAINER_multihashmap_get(t->peers,
3538 &peer_msg->peer.hashPubKey);
3539 if (NULL == peer_info)
3540 {
3541 GNUNET_break (0);
3542 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
3543 return;
3544 }
3545
3495 /* Ok, delete peer from tunnel */ 3546 /* Ok, delete peer from tunnel */
3496 GNUNET_CONTAINER_multihashmap_remove_all (t->peers, 3547 GNUNET_CONTAINER_multihashmap_remove_all (t->peers,
3497 &peer_msg->peer.hashPubKey); 3548 &peer_msg->peer.hashPubKey);
3498 3549
3550 send_destroy_path (t, peer_info->id);
3551 tunnel_delete_peer(t, peer_info->id);
3499 GNUNET_SERVER_receive_done (client, GNUNET_OK); 3552 GNUNET_SERVER_receive_done (client, GNUNET_OK);
3500 return; 3553 return;
3501} 3554}