aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBart Polot <bart@net.in.tum.de>2013-05-10 07:49:16 +0000
committerBart Polot <bart@net.in.tum.de>2013-05-10 07:49:16 +0000
commit1f73e29d92ecdc14c5dd46ff6a6b80b6626db198 (patch)
treeb209c68bf469f79e0b6b2d093d86dcbbea8f24ba /src
parent428d535013f44be1d1389b333b4f95560414b27b (diff)
downloadgnunet-1f73e29d92ecdc14c5dd46ff6a6b80b6626db198.tar.gz
gnunet-1f73e29d92ecdc14c5dd46ff6a6b80b6626db198.zip
- simplify adding path to tunnel
Diffstat (limited to 'src')
-rw-r--r--src/mesh/gnunet-service-mesh-new.c240
1 files changed, 94 insertions, 146 deletions
diff --git a/src/mesh/gnunet-service-mesh-new.c b/src/mesh/gnunet-service-mesh-new.c
index 97b9a9f25..b3d0f9936 100644
--- a/src/mesh/gnunet-service-mesh-new.c
+++ b/src/mesh/gnunet-service-mesh-new.c
@@ -796,7 +796,7 @@ dht_get_id_handler (void *cls, struct GNUNET_TIME_Absolute exp,
796 * @return Existing or newly created peer info. 796 * @return Existing or newly created peer info.
797 */ 797 */
798static struct MeshPeerInfo * 798static struct MeshPeerInfo *
799peer_info_get (const struct GNUNET_PeerIdentity *peer); 799peer_get (const struct GNUNET_PeerIdentity *peer);
800 800
801 801
802/** 802/**
@@ -808,20 +808,7 @@ peer_info_get (const struct GNUNET_PeerIdentity *peer);
808 * @return Existing or newly created peer info. 808 * @return Existing or newly created peer info.
809 */ 809 */
810static struct MeshPeerInfo * 810static struct MeshPeerInfo *
811peer_info_get_short (const GNUNET_PEER_Id peer); 811peer_get_short (const GNUNET_PEER_Id peer);
812
813
814/**
815 * Try to establish a new connection to this peer.
816 * Use the best path for the given tunnel.
817 * If the peer doesn't have any path to it yet, try to get one.
818 * If the peer already has some path, send a CREATE PATH towards it.
819 *
820 * @param peer PeerInfo of the peer.
821 * @param t Tunnel for which to create the path, if possible.
822 */
823static void
824peer_info_connect (struct MeshPeerInfo *peer, struct MeshTunnel *t);
825 812
826 813
827/** 814/**
@@ -908,6 +895,15 @@ tunnel_add_client (struct MeshTunnel *t, struct MeshClient *c);
908 895
909 896
910/** 897/**
898 * .Use the given path for the tunnel.
899 *
900 * @param t Tunnel to update.
901 * @param p Path to use.
902 */
903static void
904tunnel_use_path (struct MeshTunnel *t, const struct MeshPeerPath *p);
905
906/**
911 * @brief Queue and pass message to core when possible. 907 * @brief Queue and pass message to core when possible.
912 * 908 *
913 * If type is payload (UNICAST, TO_ORIGIN, MULTICAST) checks for queue status 909 * If type is payload (UNICAST, TO_ORIGIN, MULTICAST) checks for queue status
@@ -1362,7 +1358,7 @@ peer_info_timeout (void *cls,
1362 * @return Existing or newly created peer info. 1358 * @return Existing or newly created peer info.
1363 */ 1359 */
1364static struct MeshPeerInfo * 1360static struct MeshPeerInfo *
1365peer_info_get (const struct GNUNET_PeerIdentity *peer) 1361peer_get (const struct GNUNET_PeerIdentity *peer)
1366{ 1362{
1367 struct MeshPeerInfo *peer_info; 1363 struct MeshPeerInfo *peer_info;
1368 1364
@@ -1396,12 +1392,43 @@ peer_info_get (const struct GNUNET_PeerIdentity *peer)
1396 * @return Existing or newly created peer info. 1392 * @return Existing or newly created peer info.
1397 */ 1393 */
1398static struct MeshPeerInfo * 1394static struct MeshPeerInfo *
1399peer_info_get_short (const GNUNET_PEER_Id peer) 1395peer_get_short (const GNUNET_PEER_Id peer)
1400{ 1396{
1401 struct GNUNET_PeerIdentity id; 1397 struct GNUNET_PeerIdentity id;
1402 1398
1403 GNUNET_PEER_resolve (peer, &id); 1399 GNUNET_PEER_resolve (peer, &id);
1404 return peer_info_get (&id); 1400 return peer_get (&id);
1401}
1402
1403
1404/**
1405 * Choose the best path towards a peer considering the tunnel properties.
1406 *
1407 * @param peer The destination peer.
1408 * @param t The tunnel the path is for.
1409 *
1410 * @return Best current known path towards the peer, if any.
1411 */
1412static struct MeshPeerPath *
1413peer_get_best_path (const struct MeshPeerInfo *peer, const struct MeshTunnel *t)
1414{
1415 struct MeshPeerPath *best_p;
1416 struct MeshPeerPath *p;
1417 unsigned int best_cost;
1418 unsigned int cost;
1419
1420 best_p = p = peer->path_head;
1421 best_cost = cost = p->length;
1422 while (NULL != p)
1423 {
1424 if ((cost = p->length) < best_cost)
1425 {
1426 best_cost = cost;
1427 best_p = p;
1428 }
1429 p = p->next;
1430 }
1431 return best_p;
1405} 1432}
1406 1433
1407 1434
@@ -1516,7 +1543,7 @@ send_prebuilt_message (const struct GNUNET_MessageHeader *message,
1516 info->mesh_data->data_len = size; 1543 info->mesh_data->data_len = size;
1517 info->mesh_data->reference_counter = 1; 1544 info->mesh_data->reference_counter = 1;
1518 info->mesh_data->total_out = 1; 1545 info->mesh_data->total_out = 1;
1519 neighbor = peer_info_get (peer); 1546 neighbor = peer_get (peer);
1520 for (p = neighbor->path_head; NULL != p; p = p->next) 1547 for (p = neighbor->path_head; NULL != p; p = p->next)
1521 { 1548 {
1522 if (2 >= p->length) 1549 if (2 >= p->length)
@@ -1582,38 +1609,19 @@ static void
1582send_create_path (struct MeshPeerInfo *peer, struct MeshPeerPath *p, 1609send_create_path (struct MeshPeerInfo *peer, struct MeshPeerPath *p,
1583 struct MeshTunnel *t) 1610 struct MeshTunnel *t)
1584{ 1611{
1585 struct GNUNET_PeerIdentity id;
1586 struct MeshPathInfo *path_info; 1612 struct MeshPathInfo *path_info;
1587 struct MeshPeerInfo *neighbor; 1613 struct MeshPeerInfo *neighbor;
1588 1614
1589 unsigned int i;
1590
1591 if (NULL == p) 1615 if (NULL == p)
1592 { 1616 {
1593 p = tree_get_path_to_peer (t->tree, peer->id);
1594 if (NULL == p)
1595 {
1596 GNUNET_break (0);
1597 return;
1598 }
1599 }
1600 for (i = 0; i < p->length; i++)
1601 {
1602 if (p->peers[i] == myid)
1603 break;
1604 }
1605 if (i >= p->length - 1)
1606 {
1607 path_destroy (p);
1608 GNUNET_break (0); 1617 GNUNET_break (0);
1609 return; 1618 return;
1610 } 1619 }
1611 GNUNET_PEER_resolve (p->peers[i + 1], &id);
1612 1620
1613 path_info = GNUNET_malloc (sizeof (struct MeshPathInfo)); 1621 path_info = GNUNET_malloc (sizeof (struct MeshPathInfo));
1614 path_info->path = p; 1622 path_info->path = p;
1615 path_info->t = t; 1623 path_info->t = t;
1616 neighbor = peer_info_get (&id); 1624 neighbor = peer_get_short (t->next_hop);
1617 path_info->peer = neighbor; 1625 path_info->peer = neighbor;
1618 queue_add (path_info, 1626 queue_add (path_info,
1619 GNUNET_MESSAGE_TYPE_MESH_PATH_CREATE, 1627 GNUNET_MESSAGE_TYPE_MESH_PATH_CREATE,
@@ -1693,8 +1701,7 @@ send_path_ack (struct MeshTunnel *t)
1693 1701
1694 1702
1695/** 1703/**
1696 * Try to establish a new connection to this peer. 1704 * Try to establish a new connection to this peer in the fiven tunnel.
1697 * Use the best path for the given tunnel.
1698 * If the peer doesn't have any path to it yet, try to get one. 1705 * If the peer doesn't have any path to it yet, try to get one.
1699 * If the peer already has some path, send a CREATE PATH towards it. 1706 * If the peer already has some path, send a CREATE PATH towards it.
1700 * 1707 *
@@ -1702,41 +1709,16 @@ send_path_ack (struct MeshTunnel *t)
1702 * @param t Tunnel for which to create the path, if possible. 1709 * @param t Tunnel for which to create the path, if possible.
1703 */ 1710 */
1704static void 1711static void
1705peer_info_connect (struct MeshPeerInfo *peer, struct MeshTunnel *t) 1712peer_connect (struct MeshPeerInfo *peer, struct MeshTunnel *t)
1706{ 1713{
1707 struct MeshPeerPath *p;
1708 struct MeshPathInfo *path_info; 1714 struct MeshPathInfo *path_info;
1715 struct MeshPeerPath *p;
1709 1716
1710 if (NULL != peer->path_head) 1717 if (NULL != peer->path_head)
1711 { 1718 {
1712 p = tree_get_path_to_peer (t->tree, peer->id); 1719 p = peer_get_best_path (peer, t);
1713 if (NULL == p) 1720 tunnel_use_path (t, p);
1714 { 1721 send_create_path (peer, p, t);
1715 GNUNET_break (0);
1716 return;
1717 }
1718
1719 // FIXME always send create path to self
1720 if (p->length > 1)
1721 {
1722 send_create_path (peer, p, t);
1723 }
1724 else
1725 {
1726 struct GNUNET_HashCode hash;
1727
1728 path_destroy (p);
1729 t->local_tid_dest = next_local_tid++;
1730 GNUNET_CRYPTO_hash (&t->local_tid_dest, sizeof (MESH_TunnelNumber),
1731 &hash);
1732 if (GNUNET_OK !=
1733 GNUNET_CONTAINER_multihashmap_put (incoming_tunnels, &hash, t,
1734 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_FAST))
1735 {
1736 GNUNET_break (0);
1737 return;
1738 }
1739 }
1740 } 1722 }
1741 else if (NULL == peer->dhtget) 1723 else if (NULL == peer->dhtget)
1742 { 1724 {
@@ -1783,7 +1765,7 @@ peer_info_connect_task (void *cls,
1783 GNUNET_free (cls); 1765 GNUNET_free (cls);
1784 return; 1766 return;
1785 } 1767 }
1786 peer_info_connect (path_info->peer, path_info->t); 1768 peer_connect (path_info->peer, path_info->t);
1787 GNUNET_free (cls); 1769 GNUNET_free (cls);
1788} 1770}
1789 1771
@@ -1896,7 +1878,7 @@ peer_info_remove_path (struct MeshPeerInfo *peer, GNUNET_PEER_Id p1,
1896 * Trivial immiediate fix: try to reconnect to the disconnected node. All 1878 * Trivial immiediate fix: try to reconnect to the disconnected node. All
1897 * its children will be reachable trough him. 1879 * its children will be reachable trough him.
1898 */ 1880 */
1899 peer_d = peer_info_get_short (d); 1881 peer_d = peer_get_short (d);
1900 best = UINT_MAX; 1882 best = UINT_MAX;
1901 aux = NULL; 1883 aux = NULL;
1902 for (p = peer_d->path_head; NULL != p; p = p->next) 1884 for (p = peer_d->path_head; NULL != p; p = p->next)
@@ -1916,7 +1898,7 @@ peer_info_remove_path (struct MeshPeerInfo *peer, GNUNET_PEER_Id p1,
1916 } 1898 }
1917 else 1899 else
1918 { 1900 {
1919 peer_info_connect (peer_d, peer->tunnels[i]); 1901 peer_connect (peer_d, peer->tunnels[i]);
1920 } 1902 }
1921 } 1903 }
1922 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "peer_info_remove_path END\n"); 1904 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "peer_info_remove_path END\n");
@@ -2176,7 +2158,7 @@ path_add_to_peers (struct MeshPeerPath *p, int confirmed)
2176 struct MeshPeerInfo *aux; 2158 struct MeshPeerInfo *aux;
2177 struct MeshPeerPath *copy; 2159 struct MeshPeerPath *copy;
2178 2160
2179 aux = peer_info_get_short (p->peers[i]); 2161 aux = peer_get_short (p->peers[i]);
2180 copy = path_duplicate (p); 2162 copy = path_duplicate (p);
2181 copy->length = i + 1; 2163 copy->length = i + 1;
2182 peer_info_add_path (aux, copy, GNUNET_NO); 2164 peer_info_add_path (aux, copy, GNUNET_NO);
@@ -2340,65 +2322,6 @@ tunnel_delete_client (struct MeshTunnel *t, const struct MeshClient *c)
2340} 2322}
2341 2323
2342 2324
2343/**
2344 * Add a peer to a tunnel, accomodating paths accordingly and initializing all
2345 * needed rescources.
2346 * If peer already exists, reevaluate shortest path and change if different.
2347 *
2348 * @param t Tunnel we want to add a new peer to
2349 * @param peer PeerInfo of the peer being added
2350 *
2351 */
2352static void
2353tunnel_add_peer (struct MeshTunnel *t, struct MeshPeerInfo *peer)
2354{
2355 struct MeshPeerPath *best_p;
2356 struct MeshPeerPath *p;
2357 unsigned int best_cost;
2358 unsigned int cost;
2359
2360 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "tunnel_add_peer\n");
2361
2362 if (t->peer != peer->id)
2363 {
2364 GNUNET_array_append (peer->tunnels, peer->ntunnels, t);
2365 t->peer = peer->id;
2366 }
2367
2368 /* FIXME */
2369 if (NULL != (p = peer->path_head))
2370 {
2371 best_p = p;
2372 best_cost = tree_get_path_cost (t->tree, p);
2373 while (NULL != p)
2374 {
2375 if ((cost = tree_get_path_cost (t->tree, p)) < best_cost)
2376 {
2377 best_cost = cost;
2378 best_p = p;
2379 }
2380 p = p->next;
2381 }
2382 tree_add_path (t->tree, best_p, NULL, NULL); // FIXME
2383 if (GNUNET_SCHEDULER_NO_TASK == t->path_refresh_task)
2384 t->path_refresh_task =
2385 GNUNET_SCHEDULER_add_delayed (refresh_path_time, &path_refresh, t);
2386 }
2387 else
2388 {
2389 /* Start a DHT get */
2390 peer_info_connect (peer, t);
2391 }
2392 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "tunnel_add_peer END\n");
2393}
2394
2395
2396/**
2397 * Add a client to a tunnel, initializing all needed data structures.
2398 *
2399 * @param t Tunnel to which add the client.
2400 * @param c Client which to add to the tunnel.
2401 */
2402static void 2325static void
2403tunnel_add_client (struct MeshTunnel *t, struct MeshClient *c) 2326tunnel_add_client (struct MeshTunnel *t, struct MeshClient *c)
2404{ 2327{
@@ -2414,6 +2337,32 @@ tunnel_add_client (struct MeshTunnel *t, struct MeshClient *c)
2414} 2337}
2415 2338
2416 2339
2340static void
2341tunnel_use_path (struct MeshTunnel *t, const struct MeshPeerPath *p)
2342{
2343 unsigned int i;
2344
2345 for (i = 0; i < p->length; i++)
2346 {
2347 if (p->peers[i] == myid)
2348 break;
2349 }
2350 if (i > p->length - 1)
2351 {
2352 GNUNET_break (0);
2353 return;
2354 }
2355 if (i < p->length - 1)
2356 t->next_hop = p->peers[i + 1];
2357 else
2358 t->next_hop = 0;
2359 if (0 < i)
2360 t->prev_hop = p->peers[i - 1];
2361 else
2362 t->prev_hop = 0;
2363}
2364
2365
2417/** 2366/**
2418 * Notifies a tunnel that a connection has broken that affects at least 2367 * Notifies a tunnel that a connection has broken that affects at least
2419 * some of its peers. Sends a notification towards the root of the tree. 2368 * some of its peers. Sends a notification towards the root of the tree.
@@ -2891,7 +2840,7 @@ peer_unlock_queue(void *cls, GNUNET_PEER_Id peer_id)
2891 struct MeshPeerQueue *q; 2840 struct MeshPeerQueue *q;
2892 size_t size; 2841 size_t size;
2893 2842
2894 peer = peer_info_get_short(peer_id); 2843 peer = peer_get_short(peer_id);
2895 if (NULL != peer->core_transmit) 2844 if (NULL != peer->core_transmit)
2896 return; 2845 return;
2897 2846
@@ -3008,7 +2957,7 @@ tunnel_cancel_queues (void *cls, GNUNET_PEER_Id neighbor_id)
3008 struct MeshPeerQueue *pq; 2957 struct MeshPeerQueue *pq;
3009 struct MeshPeerQueue *next; 2958 struct MeshPeerQueue *next;
3010 2959
3011 peer_info = peer_info_get_short (neighbor_id); 2960 peer_info = peer_get_short (neighbor_id);
3012 for (pq = peer_info->queue_head; NULL != pq; pq = next) 2961 for (pq = peer_info->queue_head; NULL != pq; pq = next)
3013 { 2962 {
3014 next = pq->next; 2963 next = pq->next;
@@ -4491,7 +4440,7 @@ handle_mesh_data_to_orig (void *cls, const struct GNUNET_PeerIdentity *peer,
4491 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 4440 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
4492 " not for us, retransmitting...\n"); 4441 " not for us, retransmitting...\n");
4493 4442
4494 peer_info = peer_info_get (&msg->oid); 4443 peer_info = peer_get (&msg->oid);
4495 if (NULL == peer_info) 4444 if (NULL == peer_info)
4496 { 4445 {
4497 /* unknown origin of tunnel */ 4446 /* unknown origin of tunnel */
@@ -4673,7 +4622,7 @@ handle_mesh_path_ack (void *cls, const struct GNUNET_PeerIdentity *peer,
4673 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " on tunnel %s [%X]\n", 4622 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " on tunnel %s [%X]\n",
4674 GNUNET_i2s (&msg->oid), ntohl(msg->tid)); 4623 GNUNET_i2s (&msg->oid), ntohl(msg->tid));
4675 4624
4676 peer_info = peer_info_get (&msg->peer_id); 4625 peer_info = peer_get (&msg->peer_id);
4677 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " by peer %s\n", 4626 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " by peer %s\n",
4678 GNUNET_i2s (&msg->peer_id)); 4627 GNUNET_i2s (&msg->peer_id));
4679 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " via peer %s\n", 4628 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " via peer %s\n",
@@ -4716,7 +4665,7 @@ handle_mesh_path_ack (void *cls, const struct GNUNET_PeerIdentity *peer,
4716 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 4665 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
4717 " not for us, retransmitting...\n"); 4666 " not for us, retransmitting...\n");
4718 GNUNET_PEER_resolve (tree_get_predecessor (t->tree), &id); 4667 GNUNET_PEER_resolve (tree_get_predecessor (t->tree), &id);
4719 peer_info = peer_info_get (&msg->oid); 4668 peer_info = peer_get (&msg->oid);
4720 send_prebuilt_message (message, &id, t); 4669 send_prebuilt_message (message, &id, t);
4721 return GNUNET_OK; 4670 return GNUNET_OK;
4722} 4671}
@@ -4911,8 +4860,7 @@ dht_get_id_handler (void *cls, struct GNUNET_TIME_Absolute exp,
4911 path_destroy (p); 4860 path_destroy (p);
4912 for (i = 0; i < path_info->peer->ntunnels; i++) 4861 for (i = 0; i < path_info->peer->ntunnels; i++)
4913 { 4862 {
4914 tunnel_add_peer (path_info->peer->tunnels[i], path_info->peer); 4863 peer_connect (path_info->peer, path_info->t);
4915 peer_info_connect (path_info->peer, path_info->t);
4916 } 4864 }
4917 4865
4918 return; 4866 return;
@@ -5122,9 +5070,9 @@ handle_local_tunnel_create (void *cls, struct GNUNET_SERVER_Client *client,
5122 GNUNET_i2s (&my_full_id), t->id.tid, t->local_tid); 5070 GNUNET_i2s (&my_full_id), t->id.tid, t->local_tid);
5123 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "new tunnel created\n"); 5071 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "new tunnel created\n");
5124 5072
5125 peer_info = peer_info_get (&t_msg->peer); 5073 peer_info = peer_get (&t_msg->peer);
5126 tunnel_add_peer (t, peer_info); 5074 GNUNET_array_append (peer_info->tunnels, peer_info->ntunnels, t);
5127 peer_info_connect (peer_info, t); 5075 peer_connect (peer_info, t);
5128 GNUNET_SERVER_receive_done (client, GNUNET_OK); 5076 GNUNET_SERVER_receive_done (client, GNUNET_OK);
5129 return; 5077 return;
5130} 5078}
@@ -5732,7 +5680,7 @@ core_connect (void *cls, const struct GNUNET_PeerIdentity *peer)
5732 5680
5733 DEBUG_CONN ("Peer connected\n"); 5681 DEBUG_CONN ("Peer connected\n");
5734 DEBUG_CONN (" %s\n", GNUNET_i2s (&my_full_id)); 5682 DEBUG_CONN (" %s\n", GNUNET_i2s (&my_full_id));
5735 peer_info = peer_info_get (peer); 5683 peer_info = peer_get (peer);
5736 if (myid == peer_info->id) 5684 if (myid == peer_info->id)
5737 { 5685 {
5738 DEBUG_CONN (" (self)\n"); 5686 DEBUG_CONN (" (self)\n");
@@ -5960,7 +5908,7 @@ key_generation_cb (void *cls,
5960 announce_id_task = GNUNET_SCHEDULER_add_now (&announce_id, cls); 5908 announce_id_task = GNUNET_SCHEDULER_add_now (&announce_id, cls);
5961 5909
5962 /* Create a peer_info for the local peer */ 5910 /* Create a peer_info for the local peer */
5963 peer = peer_info_get (&my_full_id); 5911 peer = peer_get (&my_full_id);
5964 p = path_new (1); 5912 p = path_new (1);
5965 p->peers[0] = myid; 5913 p->peers[0] = myid;
5966 GNUNET_PEER_change_rc (myid, 1); 5914 GNUNET_PEER_change_rc (myid, 1);