aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBart Polot <bart@net.in.tum.de>2012-07-26 10:35:37 +0000
committerBart Polot <bart@net.in.tum.de>2012-07-26 10:35:37 +0000
commitea920d37dbef81b9e022f3a657b90583e4499866 (patch)
tree2ba7861d631c8b0f1398241bab8bbd0f0965b106 /src
parent29b86b08086ad1cbf834c9b2ad9a5164b01e94c3 (diff)
downloadgnunet-ea920d37dbef81b9e022f3a657b90583e4499866.tar.gz
gnunet-ea920d37dbef81b9e022f3a657b90583e4499866.zip
- little refactoring
Diffstat (limited to 'src')
-rw-r--r--src/mesh/gnunet-service-mesh.c355
1 files changed, 205 insertions, 150 deletions
diff --git a/src/mesh/gnunet-service-mesh.c b/src/mesh/gnunet-service-mesh.c
index ffdbb0f86..f87e8b043 100644
--- a/src/mesh/gnunet-service-mesh.c
+++ b/src/mesh/gnunet-service-mesh.c
@@ -889,6 +889,93 @@ dht_get_string_accept_handler (void *cls, struct GNUNET_TIME_Absolute exp,
889 889
890 890
891/** 891/**
892 * Retrieve the MeshPeerInfo stucture associated with the peer, create one
893 * and insert it in the appropiate structures if the peer is not known yet.
894 *
895 * @param peer Short identity of the peer.
896 *
897 * @return Existing or newly created peer info.
898 */
899static struct MeshPeerInfo *
900peer_info_get_short (const GNUNET_PEER_Id peer);
901
902
903/**
904 * Try to establish a new connection to this peer.
905 * Use the best path for the given tunnel.
906 * If the peer doesn't have any path to it yet, try to get one.
907 * If the peer already has some path, send a CREATE PATH towards it.
908 *
909 * @param peer PeerInfo of the peer.
910 * @param t Tunnel for which to create the path, if possible.
911 */
912static void
913peer_info_connect (struct MeshPeerInfo *peer, struct MeshTunnel *t);
914
915
916/**
917 * Add a peer to a tunnel, accomodating paths accordingly and initializing all
918 * needed rescources.
919 * If peer already exists, reevaluate shortest path and change if different.
920 *
921 * @param t Tunnel we want to add a new peer to
922 * @param peer PeerInfo of the peer being added
923 *
924 */
925static void
926tunnel_add_peer (struct MeshTunnel *t, struct MeshPeerInfo *peer);
927
928
929/**
930 * Removes an explicit path from a tunnel, freeing all intermediate nodes
931 * that are no longer needed, as well as nodes of no longer reachable peers.
932 * The tunnel itself is also destoyed if results in a remote empty tunnel.
933 *
934 * @param t Tunnel from which to remove the path.
935 * @param peer Short id of the peer which should be removed.
936 */
937static void
938tunnel_delete_peer (struct MeshTunnel *t, GNUNET_PEER_Id peer);
939
940
941/**
942 * Search for a tunnel by global ID using full PeerIdentities.
943 *
944 * @param oid owner of the tunnel.
945 * @param tid global tunnel number.
946 *
947 * @return tunnel handler, NULL if doesn't exist.
948 */
949static struct MeshTunnel *
950tunnel_get (struct GNUNET_PeerIdentity *oid, MESH_TunnelNumber tid);
951
952
953/**
954 * Delete an active client from the tunnel.
955 *
956 * @param t Tunnel.
957 * @param c Client.
958 */
959static void
960tunnel_delete_active_client (struct MeshTunnel *t, const struct MeshClient *c);
961
962/**
963 * Notify a tunnel that a connection has broken that affects at least
964 * some of its peers.
965 *
966 * @param t Tunnel affected.
967 * @param p1 Peer that got disconnected from p2.
968 * @param p2 Peer that got disconnected from p1.
969 *
970 * @return Short ID of the peer disconnected (either p1 or p2).
971 * 0 if the tunnel remained unaffected.
972 */
973static GNUNET_PEER_Id
974tunnel_notify_connection_broken (struct MeshTunnel *t, GNUNET_PEER_Id p1,
975 GNUNET_PEER_Id p2);
976
977
978/**
892 * Iterator over edges in a regex block retrieved from the DHT. 979 * Iterator over edges in a regex block retrieved from the DHT.
893 * 980 *
894 * @param cls Closure. 981 * @param cls Closure.
@@ -944,8 +1031,6 @@ queue_destroy (struct MeshPeerQueue *queue, int clear_cls);
944/************************ ITERATORS ****************************/ 1031/************************ ITERATORS ****************************/
945/******************************************************************************/ 1032/******************************************************************************/
946 1033
947/* FIXME move iterators here */
948
949/** 1034/**
950 * Iterator over found existing mesh regex blocks that match an ongoing search. 1035 * Iterator over found existing mesh regex blocks that match an ongoing search.
951 * 1036 *
@@ -983,6 +1068,7 @@ regex_result_iterator (void *cls,
983 return GNUNET_YES; 1068 return GNUNET_YES;
984} 1069}
985 1070
1071
986/** 1072/**
987 * Iterator over edges in a regex block retrieved from the DHT. 1073 * Iterator over edges in a regex block retrieved from the DHT.
988 * 1074 *
@@ -1261,6 +1347,93 @@ regex_find_path (const struct GNUNET_HashCode *key,
1261} 1347}
1262 1348
1263 1349
1350/**
1351 * Function called if the connect attempt to a peer found via
1352 * connect_by_string times out. Try to connect to another peer, if any.
1353 * Otherwise try to reconnect to the same peer.
1354 *
1355 * @param cls Closure (info about regex search).
1356 * @param tc TaskContext.
1357 */
1358static void
1359regex_connect_timeout (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
1360{
1361 struct MeshRegexSearchInfo *info = cls;
1362 struct MeshPeerInfo *peer_info;
1363 GNUNET_PEER_Id id;
1364 GNUNET_PEER_Id old;
1365
1366 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Regex connect timeout\n");
1367 info->timeout = GNUNET_SCHEDULER_NO_TASK;
1368 if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
1369 {
1370 return;
1371 }
1372
1373 old = info->peer;
1374 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " timed out: %u\n", old);
1375
1376 if (0 < info->n_peers)
1377 {
1378 // Select next peer, put current in that spot.
1379 id = info->peers[info->i_peer];
1380 info->peers[info->i_peer] = info->peer;
1381 info->i_peer = (info->i_peer + 1) % info->n_peers;
1382 }
1383 else
1384 {
1385 // Try to connect to same peer again.
1386 id = info->peer;
1387 }
1388 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " trying: %u\n", id);
1389
1390 peer_info = peer_info_get_short(id);
1391 tunnel_add_peer (info->t, peer_info);
1392 if (old != id)
1393 tunnel_delete_peer (info->t, old);
1394 peer_info_connect (peer_info, info->t);
1395 info->timeout = GNUNET_SCHEDULER_add_delayed (connect_timeout,
1396 &regex_connect_timeout,
1397 info);
1398 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Regex connect timeout END\n");
1399}
1400
1401
1402/**
1403 * Cancel an ongoing regex search in the DHT and free all resources.
1404 *
1405 * @param ctx The search context.
1406 */
1407static void
1408regex_cancel_search(struct MeshRegexSearchContext *ctx)
1409{
1410 struct MeshRegexSearchInfo *info = ctx->info;
1411 int i;
1412
1413 GNUNET_free (info->description);
1414 GNUNET_CONTAINER_multihashmap_iterate (info->dht_get_handles,
1415 &regex_cancel_dht_get, NULL);
1416 GNUNET_CONTAINER_multihashmap_iterate (info->dht_get_results,
1417 &regex_free_result, NULL);
1418 GNUNET_CONTAINER_multihashmap_destroy (info->dht_get_results);
1419 GNUNET_CONTAINER_multihashmap_destroy (info->dht_get_handles);
1420 info->t->regex_ctx = NULL;
1421 for (i = 0; i < info->n_contexts; i++)
1422 {
1423 GNUNET_free (info->contexts[i]);
1424 }
1425 if (0 < info->n_contexts)
1426 GNUNET_free (info->contexts);
1427 if (0 < info->n_peers)
1428 GNUNET_free (info->peers);
1429 if (GNUNET_SCHEDULER_NO_TASK != info->timeout)
1430 {
1431 GNUNET_SCHEDULER_cancel(info->timeout);
1432 }
1433 GNUNET_free (info);
1434}
1435
1436
1264/******************************************************************************/ 1437/******************************************************************************/
1265/************************ PERIODIC FUNCTIONS ****************************/ 1438/************************ PERIODIC FUNCTIONS ****************************/
1266/******************************************************************************/ 1439/******************************************************************************/
@@ -1412,76 +1585,38 @@ announce_id (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
1412/****************** GENERAL HELPER FUNCTIONS ************************/ 1585/****************** GENERAL HELPER FUNCTIONS ************************/
1413/******************************************************************************/ 1586/******************************************************************************/
1414 1587
1588
1415/** 1589/**
1416 * Cancel an ongoing regex search in the DHT and free all resources. 1590 * Decrements the reference counter and frees all resources if needed
1417 * 1591 *
1418 * @param ctx The search context. 1592 * @param mesh_data Data Descriptor used in a multicast message.
1593 * Freed no longer needed (last message).
1419 */ 1594 */
1420static void 1595static void
1421regex_cancel_search(struct MeshRegexSearchContext *ctx) 1596data_descriptor_decrement_rc (struct MeshData *mesh_data)
1422{ 1597{
1423 struct MeshRegexSearchInfo *info = ctx->info; 1598 /* Make sure it's a multicast packet */
1424 int i; 1599 GNUNET_assert (NULL != mesh_data->reference_counter);
1425 1600
1426 GNUNET_free (info->description); 1601 if (0 == --(*(mesh_data->reference_counter)))
1427 GNUNET_CONTAINER_multihashmap_iterate (info->dht_get_handles,
1428 &regex_cancel_dht_get, NULL);
1429 GNUNET_CONTAINER_multihashmap_iterate (info->dht_get_results,
1430 &regex_free_result, NULL);
1431 GNUNET_CONTAINER_multihashmap_destroy (info->dht_get_results);
1432 GNUNET_CONTAINER_multihashmap_destroy (info->dht_get_handles);
1433 info->t->regex_ctx = NULL;
1434 for (i = 0; i < info->n_contexts; i++)
1435 {
1436 GNUNET_free (info->contexts[i]);
1437 }
1438 if (0 < info->n_contexts)
1439 GNUNET_free (info->contexts);
1440 if (0 < info->n_peers)
1441 GNUNET_free (info->peers);
1442 if (GNUNET_SCHEDULER_NO_TASK != info->timeout)
1443 { 1602 {
1444 GNUNET_SCHEDULER_cancel(info->timeout); 1603 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Last copy!\n");
1604 if (NULL != mesh_data->task)
1605 {
1606 if (GNUNET_SCHEDULER_NO_TASK != *(mesh_data->task))
1607 {
1608 GNUNET_SCHEDULER_cancel (*(mesh_data->task));
1609 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " notifying client...\n");
1610 GNUNET_SERVER_receive_done (mesh_data->t->owner->handle, GNUNET_OK);
1611 }
1612 GNUNET_free (mesh_data->task);
1613 }
1614 GNUNET_free (mesh_data->reference_counter);
1615 GNUNET_free (mesh_data->data);
1616 GNUNET_free (mesh_data);
1445 } 1617 }
1446 GNUNET_free (info);
1447} 1618}
1448 1619
1449/**
1450 * Search for a tunnel by global ID using full PeerIdentities
1451 *
1452 * @param oid owner of the tunnel
1453 * @param tid global tunnel number
1454 *
1455 * @return tunnel handler, NULL if doesn't exist
1456 */
1457static struct MeshTunnel *
1458tunnel_get (struct GNUNET_PeerIdentity *oid, MESH_TunnelNumber tid);
1459
1460
1461/**
1462 * Delete an active client from the tunnel.
1463 *
1464 * @param t Tunnel.
1465 * @param c Client.
1466 */
1467static void
1468tunnel_delete_active_client (struct MeshTunnel *t, const struct MeshClient *c);
1469
1470/**
1471 * Notify a tunnel that a connection has broken that affects at least
1472 * some of its peers.
1473 *
1474 * @param t Tunnel affected.
1475 * @param p1 Peer that got disconnected from p2.
1476 * @param p2 Peer that got disconnected from p1.
1477 *
1478 * @return Short ID of the peer disconnected (either p1 or p2).
1479 * 0 if the tunnel remained unaffected.
1480 */
1481static GNUNET_PEER_Id
1482tunnel_notify_connection_broken (struct MeshTunnel *t, GNUNET_PEER_Id p1,
1483 GNUNET_PEER_Id p2);
1484
1485 1620
1486/** 1621/**
1487 * Check if client has registered with the service and has not disconnected 1622 * Check if client has registered with the service and has not disconnected
@@ -1844,38 +1979,6 @@ send_client_tunnel_disconnect (struct MeshTunnel *t, struct MeshClient *c)
1844 1979
1845 1980
1846/** 1981/**
1847 * Decrements the reference counter and frees all resources if needed
1848 *
1849 * @param mesh_data Data Descriptor used in a multicast message.
1850 * Freed no longer needed (last message).
1851 */
1852static void
1853data_descriptor_decrement_rc (struct MeshData *mesh_data)
1854{
1855 /* Make sure it's a multicast packet */
1856 GNUNET_assert (NULL != mesh_data->reference_counter);
1857
1858 if (0 == --(*(mesh_data->reference_counter)))
1859 {
1860 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Last copy!\n");
1861 if (NULL != mesh_data->task)
1862 {
1863 if (GNUNET_SCHEDULER_NO_TASK != *(mesh_data->task))
1864 {
1865 GNUNET_SCHEDULER_cancel (*(mesh_data->task));
1866 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " notifying client...\n");
1867 GNUNET_SERVER_receive_done (mesh_data->t->owner->handle, GNUNET_OK);
1868 }
1869 GNUNET_free (mesh_data->task);
1870 }
1871 GNUNET_free (mesh_data->reference_counter);
1872 GNUNET_free (mesh_data->data);
1873 GNUNET_free (mesh_data);
1874 }
1875}
1876
1877
1878/**
1879 * Retrieve the MeshPeerInfo stucture associated with the peer, create one 1982 * Retrieve the MeshPeerInfo stucture associated with the peer, create one
1880 * and insert it in the appropiate structures if the peer is not known yet. 1983 * and insert it in the appropiate structures if the peer is not known yet.
1881 * 1984 *
@@ -2770,7 +2873,7 @@ tunnel_destroy_child (void *cls,
2770 * @param peer_id Short ID of disconnected peer. 2873 * @param peer_id Short ID of disconnected peer.
2771 */ 2874 */
2772void 2875void
2773notify_peer_disconnected (void *cls, GNUNET_PEER_Id peer_id) 2876tunnel_notify_client_peer_disconnected (void *cls, GNUNET_PEER_Id peer_id)
2774{ 2877{
2775 struct MeshTunnel *t = cls; 2878 struct MeshTunnel *t = cls;
2776 struct MeshPeerInfo *peer; 2879 struct MeshPeerInfo *peer;
@@ -2839,7 +2942,7 @@ tunnel_add_peer (struct MeshTunnel *t, struct MeshPeerInfo *peer)
2839 } 2942 }
2840 p = p->next; 2943 p = p->next;
2841 } 2944 }
2842 tree_add_path (t->tree, best_p, &notify_peer_disconnected, t); 2945 tree_add_path (t->tree, best_p, &tunnel_notify_client_peer_disconnected, t);
2843 if (GNUNET_SCHEDULER_NO_TASK == t->path_refresh_task) 2946 if (GNUNET_SCHEDULER_NO_TASK == t->path_refresh_task)
2844 t->path_refresh_task = 2947 t->path_refresh_task =
2845 GNUNET_SCHEDULER_add_delayed (refresh_path_time, &path_refresh, t); 2948 GNUNET_SCHEDULER_add_delayed (refresh_path_time, &path_refresh, t);
@@ -2900,7 +3003,8 @@ tunnel_notify_connection_broken (struct MeshTunnel *t, GNUNET_PEER_Id p1,
2900 GNUNET_PEER_Id pid; 3003 GNUNET_PEER_Id pid;
2901 3004
2902 pid = 3005 pid =
2903 tree_notify_connection_broken (t->tree, p1, p2, &notify_peer_disconnected, 3006 tree_notify_connection_broken (t->tree, p1, p2,
3007 &tunnel_notify_client_peer_disconnected,
2904 t); 3008 t);
2905 if (myid != p1 && myid != p2) 3009 if (myid != p1 && myid != p2)
2906 { 3010 {
@@ -3033,6 +3137,8 @@ tunnel_send_multicast (struct MeshTunnel *t,
3033 * @param cls Closure (ID of the peer that HAS received the message). 3137 * @param cls Closure (ID of the peer that HAS received the message).
3034 * @param key ID of the neighbor. 3138 * @param key ID of the neighbor.
3035 * @param value Information about the neighbor. 3139 * @param value Information about the neighbor.
3140 *
3141 * @return GNUNET_YES to keep iterating.
3036 */ 3142 */
3037static int 3143static int
3038tunnel_add_skip (void *cls, 3144tunnel_add_skip (void *cls,
@@ -3042,6 +3148,7 @@ tunnel_add_skip (void *cls,
3042 struct GNUNET_PeerIdentity *neighbor = cls; 3148 struct GNUNET_PeerIdentity *neighbor = cls;
3043 struct MeshTunnelChildInfo *cinfo = value; 3149 struct MeshTunnelChildInfo *cinfo = value;
3044 3150
3151 /* TODO compare only pointers? key == neighbor? */
3045 if (0 == memcmp (&neighbor->hashPubKey, key, sizeof (struct GNUNET_HashCode))) 3152 if (0 == memcmp (&neighbor->hashPubKey, key, sizeof (struct GNUNET_HashCode)))
3046 { 3153 {
3047 return GNUNET_YES; 3154 return GNUNET_YES;
@@ -4887,58 +4994,6 @@ dht_get_type_handler (void *cls, struct GNUNET_TIME_Absolute exp,
4887 4994
4888 4995
4889/** 4996/**
4890 * Function called if the connect attempt to a peer found via
4891 * connect_by_string times out. Try to connect to another peer, if any.
4892 * Otherwise try to reconnect to the same peer.
4893 *
4894 * @param cls Closure (info about regex search).
4895 * @param tc TaskContext.
4896 */
4897static void
4898regex_connect_timeout (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
4899{
4900 struct MeshRegexSearchInfo *info = cls;
4901 struct MeshPeerInfo *peer_info;
4902 GNUNET_PEER_Id id;
4903 GNUNET_PEER_Id old;
4904
4905 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Regex connect timeout\n");
4906 info->timeout = GNUNET_SCHEDULER_NO_TASK;
4907 if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
4908 {
4909 return;
4910 }
4911
4912 old = info->peer;
4913 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " timed out: %u\n", old);
4914
4915 if (0 < info->n_peers)
4916 {
4917 // Select next peer, put current in that spot.
4918 id = info->peers[info->i_peer];
4919 info->peers[info->i_peer] = info->peer;
4920 info->i_peer = (info->i_peer + 1) % info->n_peers;
4921 }
4922 else
4923 {
4924 // Try to connect to same peer again.
4925 id = info->peer;
4926 }
4927 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " trying: %u\n", id);
4928
4929 peer_info = peer_info_get_short(id);
4930 tunnel_add_peer (info->t, peer_info);
4931 if (old != id)
4932 tunnel_delete_peer (info->t, old);
4933 peer_info_connect (peer_info, info->t);
4934 info->timeout = GNUNET_SCHEDULER_add_delayed (connect_timeout,
4935 &regex_connect_timeout,
4936 info);
4937 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Regex connect timeout END\n");
4938}
4939
4940
4941/**
4942 * Function to process DHT string to regex matching. 4997 * Function to process DHT string to regex matching.
4943 * Called on each result obtained for the DHT search. 4998 * Called on each result obtained for the DHT search.
4944 * 4999 *