diff options
author | Bart Polot <bart@net.in.tum.de> | 2011-10-19 18:04:01 +0000 |
---|---|---|
committer | Bart Polot <bart@net.in.tum.de> | 2011-10-19 18:04:01 +0000 |
commit | e3bb58c8e0f73697c22397165d0ff24424e32839 (patch) | |
tree | 52a21b36147b6ee576a7d5b44cd33e4a390cfe2c /src | |
parent | 0d32b44a3762cd8861505c031e054cbca8e80bb4 (diff) | |
download | gnunet-e3bb58c8e0f73697c22397165d0ff24424e32839.tar.gz gnunet-e3bb58c8e0f73697c22397165d0ff24424e32839.zip |
Added code to manage deletion of individual paths
Diffstat (limited to 'src')
-rw-r--r-- | src/mesh/gnunet-service-mesh.c | 191 |
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 | */ | ||
1011 | static void | ||
1012 | send_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 | */ | ||
1095 | static void | ||
1096 | send_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 | */ | ||
1155 | static void | ||
1156 | send_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 | */ |
1897 | static void | 1935 | static void |
1898 | tunnel_delete_path (struct MeshTunnel *t, | 1936 | tunnel_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 | } |