aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBart Polot <bart@net.in.tum.de>2013-10-04 15:08:12 +0000
committerBart Polot <bart@net.in.tum.de>2013-10-04 15:08:12 +0000
commit32c6b50f5c00042069e563ca238080ac4b6f309e (patch)
treee2dc4226df6446fce55e8e5babcab51ffc0fa310 /src
parented9c614f78b9a53d1c0a928a47e6f07f8470adfa (diff)
downloadgnunet-32c6b50f5c00042069e563ca238080ac4b6f309e.tar.gz
gnunet-32c6b50f5c00042069e563ca238080ac4b6f309e.zip
- sync
Diffstat (limited to 'src')
-rw-r--r--src/mesh/gnunet-service-mesh-enc.c260
-rw-r--r--src/mesh/gnunet-service-mesh_connection.c153
-rw-r--r--src/mesh/gnunet-service-mesh_dht.c196
-rw-r--r--src/mesh/gnunet-service-mesh_local.c67
-rw-r--r--src/mesh/gnunet-service-mesh_peer.c176
5 files changed, 469 insertions, 383 deletions
diff --git a/src/mesh/gnunet-service-mesh-enc.c b/src/mesh/gnunet-service-mesh-enc.c
index 4fef1905e..18b6460b7 100644
--- a/src/mesh/gnunet-service-mesh-enc.c
+++ b/src/mesh/gnunet-service-mesh-enc.c
@@ -496,31 +496,6 @@ GNUNET_MESH_DEBUG_TS2S (enum MeshTunnelState s)
496} 496}
497 497
498 498
499/**
500 * Get string description for tunnel state.
501 *
502 * @param s Tunnel state.
503 *
504 * @return String representation.
505 */
506static const char *
507GNUNET_MESH_DEBUG_CS2S (enum MeshTunnelState s)
508{
509 switch (s)
510 {
511 case MESH_CONNECTION_NEW:
512 return "MESH_CONNECTION_NEW";
513 case MESH_CONNECTION_SENT:
514 return "MESH_CONNECTION_SENT";
515 case MESH_CONNECTION_ACK:
516 return "MESH_CONNECTION_ACK";
517 case MESH_CONNECTION_READY:
518 return "MESH_CONNECTION_READY";
519 default:
520 return "MESH_CONNECTION_STATE_ERROR";
521 }
522}
523
524 499
525 500
526/******************************************************************************/ 501/******************************************************************************/
@@ -913,91 +888,6 @@ send_core_connection_ack (struct MeshConnection *c, size_t size, void *buf)
913 return sizeof (struct GNUNET_MESH_ConnectionACK); 888 return sizeof (struct GNUNET_MESH_ConnectionACK);
914} 889}
915 890
916/**
917 * Build a PeerPath from the paths returned from the DHT, reversing the paths
918 * to obtain a local peer -> destination path and interning the peer ids.
919 *
920 * @return Newly allocated and created path
921 */
922static struct MeshPeerPath *
923path_build_from_dht (const struct GNUNET_PeerIdentity *get_path,
924 unsigned int get_path_length,
925 const struct GNUNET_PeerIdentity *put_path,
926 unsigned int put_path_length)
927{
928 struct MeshPeerPath *p;
929 GNUNET_PEER_Id id;
930 int i;
931
932 p = path_new (1);
933 p->peers[0] = myid;
934 GNUNET_PEER_change_rc (myid, 1);
935 i = get_path_length;
936 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " GET has %d hops.\n", i);
937 for (i--; i >= 0; i--)
938 {
939 id = GNUNET_PEER_intern (&get_path[i]);
940 if (p->length > 0 && id == p->peers[p->length - 1])
941 {
942 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " Optimizing 1 hop out.\n");
943 GNUNET_PEER_change_rc (id, -1);
944 }
945 else
946 {
947 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " Adding from GET: %s.\n",
948 GNUNET_i2s (&get_path[i]));
949 p->length++;
950 p->peers = GNUNET_realloc (p->peers, sizeof (GNUNET_PEER_Id) * p->length);
951 p->peers[p->length - 1] = id;
952 }
953 }
954 i = put_path_length;
955 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " PUT has %d hops.\n", i);
956 for (i--; i >= 0; i--)
957 {
958 id = GNUNET_PEER_intern (&put_path[i]);
959 if (id == myid)
960 {
961 /* PUT path went through us, so discard the path up until now and start
962 * from here to get a much shorter (and loop-free) path.
963 */
964 path_destroy (p);
965 p = path_new (0);
966 }
967 if (p->length > 0 && id == p->peers[p->length - 1])
968 {
969 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " Optimizing 1 hop out.\n");
970 GNUNET_PEER_change_rc (id, -1);
971 }
972 else
973 {
974 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " Adding from PUT: %s.\n",
975 GNUNET_i2s (&put_path[i]));
976 p->length++;
977 p->peers = GNUNET_realloc (p->peers, sizeof (GNUNET_PEER_Id) * p->length);
978 p->peers[p->length - 1] = id;
979 }
980 }
981#if MESH_DEBUG
982 if (get_path_length > 0)
983 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " (first of GET: %s)\n",
984 GNUNET_i2s (&get_path[0]));
985 if (put_path_length > 0)
986 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " (first of PUT: %s)\n",
987 GNUNET_i2s (&put_path[0]));
988 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " In total: %d hops\n",
989 p->length);
990 for (i = 0; i < p->length; i++)
991 {
992 struct GNUNET_PeerIdentity peer_id;
993
994 GNUNET_PEER_resolve (p->peers[i], &peer_id);
995 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " %u: %s\n", p->peers[i],
996 GNUNET_i2s (&peer_id));
997 }
998#endif
999 return p;
1000}
1001 891
1002 892
1003/** 893/**
@@ -1907,39 +1797,15 @@ handle_decrypted (struct MeshTunnel2 *t,
1907 * Called on each result obtained for the DHT search. 1797 * Called on each result obtained for the DHT search.
1908 * 1798 *
1909 * @param cls closure 1799 * @param cls closure
1910 * @param exp when will this value expire 1800 * @param path
1911 * @param key key of the result
1912 * @param get_path path of the get request
1913 * @param get_path_length lenght of get_path
1914 * @param put_path path of the put request
1915 * @param put_path_length length of the put_path
1916 * @param type type of the result
1917 * @param size number of bytes in data
1918 * @param data pointer to the result data
1919 */ 1801 */
1920static void 1802static void
1921dht_get_id_handler (void *cls, struct GNUNET_TIME_Absolute exp, 1803search_handler (void *cls, struct MeshPeerPath *path)
1922 const struct GNUNET_HashCode * key,
1923 const struct GNUNET_PeerIdentity *get_path,
1924 unsigned int get_path_length,
1925 const struct GNUNET_PeerIdentity *put_path,
1926 unsigned int put_path_length, enum GNUNET_BLOCK_Type type,
1927 size_t size, const void *data)
1928{ 1804{
1929 struct MeshPeer *peer = cls;
1930 struct MeshPeerPath *p;
1931 struct MeshConnection *c; 1805 struct MeshConnection *c;
1932 struct GNUNET_PeerIdentity pi;
1933 unsigned int connection_count; 1806 unsigned int connection_count;
1934 1807
1935 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Got results from DHT!\n"); 1808 path_add_to_peers (path, GNUNET_NO);
1936 GNUNET_PEER_resolve (peer->id, &pi);
1937 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " for %s\n", GNUNET_i2s (&pi));
1938
1939 p = path_build_from_dht (get_path, get_path_length,
1940 put_path, put_path_length);
1941 path_add_to_peers (p, GNUNET_NO);
1942 path_destroy (p);
1943 1809
1944 /* Count connections */ 1810 /* Count connections */
1945 connection_count = GMC_count (peer->tunnel->connection_head); 1811 connection_count = GMC_count (peer->tunnel->connection_head);
@@ -1957,126 +1823,6 @@ dht_get_id_handler (void *cls, struct GNUNET_TIME_Absolute exp,
1957} 1823}
1958 1824
1959 1825
1960
1961/**
1962 * Method called whenever a given peer connects.
1963 *
1964 * @param cls closure
1965 * @param peer peer identity this notification is about
1966 */
1967static void
1968core_connect (void *cls, const struct GNUNET_PeerIdentity *peer)
1969{
1970 struct MeshPeer *pi;
1971 struct MeshPeerPath *path;
1972
1973 DEBUG_CONN ("Peer connected\n");
1974 DEBUG_CONN (" %s\n", GNUNET_i2s (&my_full_id));
1975 pi = peer_get (peer);
1976 if (myid == pi->id)
1977 {
1978 DEBUG_CONN (" (self)\n");
1979 path = path_new (1);
1980 }
1981 else
1982 {
1983 DEBUG_CONN (" %s\n", GNUNET_i2s (peer));
1984 path = path_new (2);
1985 path->peers[1] = pi->id;
1986 GNUNET_PEER_change_rc (pi->id, 1);
1987 GNUNET_STATISTICS_update (stats, "# peers", 1, GNUNET_NO);
1988 }
1989 path->peers[0] = myid;
1990 GNUNET_PEER_change_rc (myid, 1);
1991 peer_add_path (pi, path, GNUNET_YES);
1992
1993 pi->connections = GNUNET_CONTAINER_multihashmap_create (32, GNUNET_YES);
1994 return;
1995}
1996
1997
1998/**
1999 * Method called whenever a peer disconnects.
2000 *
2001 * @param cls closure
2002 * @param peer peer identity this notification is about
2003 */
2004static void
2005core_disconnect (void *cls, const struct GNUNET_PeerIdentity *peer)
2006{
2007 struct MeshPeer *pi;
2008
2009 DEBUG_CONN ("Peer disconnected\n");
2010 pi = GNUNET_CONTAINER_multipeermap_get (peers, peer);
2011 if (NULL == pi)
2012 {
2013 GNUNET_break (0);
2014 return;
2015 }
2016
2017 GNUNET_CONTAINER_multihashmap_iterate (pi->connections,
2018 GMC_notify_broken,
2019 pi);
2020 GNUNET_CONTAINER_multihashmap_destroy (pi->connections);
2021 pi->connections = NULL;
2022 if (NULL != pi->core_transmit)
2023 {
2024 GNUNET_CORE_notify_transmit_ready_cancel (pi->core_transmit);
2025 pi->core_transmit = NULL;
2026 }
2027 if (myid == pi->id)
2028 {
2029 DEBUG_CONN (" (self)\n");
2030 }
2031 GNUNET_STATISTICS_update (stats, "# peers", -1, GNUNET_NO);
2032
2033 return;
2034}
2035
2036
2037
2038/**
2039 * To be called on core init/fail.
2040 *
2041 * @param cls Closure (config)
2042 * @param identity the public identity of this peer
2043 */
2044static void
2045core_init (void *cls,
2046 const struct GNUNET_PeerIdentity *identity)
2047{
2048 const struct GNUNET_CONFIGURATION_Handle *c = cls;
2049 static int i = 0;
2050
2051 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Core init\n");
2052 if (0 != memcmp (identity, &my_full_id, sizeof (my_full_id)))
2053 {
2054 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Wrong CORE service\n"));
2055 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2056 " core id %s\n",
2057 GNUNET_i2s (identity));
2058 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
2059 " my id %s\n",
2060 GNUNET_i2s (&my_full_id));
2061 GNUNET_CORE_disconnect (core_handle);
2062 core_handle = GNUNET_CORE_connect (c, /* Main configuration */
2063 NULL, /* Closure passed to MESH functions */
2064 &core_init, /* Call core_init once connected */
2065 &core_connect, /* Handle connects */
2066 &core_disconnect, /* remove peers on disconnects */
2067 NULL, /* Don't notify about all incoming messages */
2068 GNUNET_NO, /* For header only in notification */
2069 NULL, /* Don't notify about all outbound messages */
2070 GNUNET_NO, /* For header-only out notification */
2071 core_handlers); /* Register these handlers */
2072 if (10 < i++)
2073 GNUNET_abort();
2074 }
2075 server_init ();
2076 return;
2077}
2078
2079
2080/******************************************************************************/ 1826/******************************************************************************/
2081/************************ MAIN FUNCTIONS ****************************/ 1827/************************ MAIN FUNCTIONS ****************************/
2082/******************************************************************************/ 1828/******************************************************************************/
diff --git a/src/mesh/gnunet-service-mesh_connection.c b/src/mesh/gnunet-service-mesh_connection.c
index b4bb8b279..dfe4fa953 100644
--- a/src/mesh/gnunet-service-mesh_connection.c
+++ b/src/mesh/gnunet-service-mesh_connection.c
@@ -31,6 +31,7 @@
31 31
32#include "gnunet-service-mesh_connection.h" 32#include "gnunet-service-mesh_connection.h"
33#include "gnunet-service-mesh_peer.h" 33#include "gnunet-service-mesh_peer.h"
34#include "gnunet-service-mesh_local.h"
34#include "mesh_protocol_enc.h" 35#include "mesh_protocol_enc.h"
35#include "mesh_path.h" 36#include "mesh_path.h"
36 37
@@ -286,6 +287,34 @@ static struct GNUNET_TIME_Relative refresh_connection_time;
286static struct GNUNET_CORE_Handle *core_handle; 287static struct GNUNET_CORE_Handle *core_handle;
287 288
288 289
290
291/**
292 * Get string description for tunnel state.
293 *
294 * @param s Tunnel state.
295 *
296 * @return String representation.
297 */
298static const char *
299GMC_DEBUG_state2s (enum MeshTunnelState s)
300{
301 switch (s)
302 {
303 case MESH_CONNECTION_NEW:
304 return "MESH_CONNECTION_NEW";
305 case MESH_CONNECTION_SENT:
306 return "MESH_CONNECTION_SENT";
307 case MESH_CONNECTION_ACK:
308 return "MESH_CONNECTION_ACK";
309 case MESH_CONNECTION_READY:
310 return "MESH_CONNECTION_READY";
311 default:
312 return "MESH_CONNECTION_STATE_ERROR";
313 }
314}
315
316
317
289/** 318/**
290 * Initialize a Flow Control structure to the initial state. 319 * Initialize a Flow Control structure to the initial state.
291 * 320 *
@@ -1483,6 +1512,130 @@ connection_reset_timeout (struct MeshConnection *c, int fwd)
1483 1512
1484 1513
1485 1514
1515
1516
1517/**
1518 * Method called whenever a given peer connects.
1519 *
1520 * @param cls closure
1521 * @param peer peer identity this notification is about
1522 */
1523static void
1524core_connect (void *cls, const struct GNUNET_PeerIdentity *peer)
1525{
1526 struct MeshPeer *pi;
1527 struct MeshPeerPath *path;
1528
1529 DEBUG_CONN ("Peer connected\n");
1530 DEBUG_CONN (" %s\n", GNUNET_i2s (&my_full_id));
1531 pi = peer_get (peer);
1532 if (myid == pi->id)
1533 {
1534 DEBUG_CONN (" (self)\n");
1535 path = path_new (1);
1536 }
1537 else
1538 {
1539 DEBUG_CONN (" %s\n", GNUNET_i2s (peer));
1540 path = path_new (2);
1541 path->peers[1] = pi->id;
1542 GNUNET_PEER_change_rc (pi->id, 1);
1543 GNUNET_STATISTICS_update (stats, "# peers", 1, GNUNET_NO);
1544 }
1545 path->peers[0] = myid;
1546 GNUNET_PEER_change_rc (myid, 1);
1547 peer_add_path (pi, path, GNUNET_YES);
1548
1549 pi->connections = GNUNET_CONTAINER_multihashmap_create (32, GNUNET_YES);
1550 return;
1551}
1552
1553
1554/**
1555 * Method called whenever a peer disconnects.
1556 *
1557 * @param cls closure
1558 * @param peer peer identity this notification is about
1559 */
1560static void
1561core_disconnect (void *cls, const struct GNUNET_PeerIdentity *peer)
1562{
1563 struct MeshPeer *pi;
1564
1565 DEBUG_CONN ("Peer disconnected\n");
1566 pi = GNUNET_CONTAINER_multipeermap_get (peers, peer);
1567 if (NULL == pi)
1568 {
1569 GNUNET_break (0);
1570 return;
1571 }
1572
1573 GNUNET_CONTAINER_multihashmap_iterate (pi->connections,
1574 GMC_notify_broken,
1575 pi);
1576 GNUNET_CONTAINER_multihashmap_destroy (pi->connections);
1577 pi->connections = NULL;
1578 if (NULL != pi->core_transmit)
1579 {
1580 GNUNET_CORE_notify_transmit_ready_cancel (pi->core_transmit);
1581 pi->core_transmit = NULL;
1582 }
1583 if (myid == pi->id)
1584 {
1585 DEBUG_CONN (" (self)\n");
1586 }
1587 GNUNET_STATISTICS_update (stats, "# peers", -1, GNUNET_NO);
1588
1589 return;
1590}
1591
1592
1593
1594/**
1595 * To be called on core init/fail.
1596 *
1597 * @param cls Closure (config)
1598 * @param identity the public identity of this peer
1599 */
1600static void
1601core_init (void *cls,
1602 const struct GNUNET_PeerIdentity *identity)
1603{
1604 const struct GNUNET_CONFIGURATION_Handle *c = cls;
1605 static int i = 0;
1606
1607 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Core init\n");
1608 if (0 != memcmp (identity, &my_full_id, sizeof (my_full_id)))
1609 {
1610 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, _("Wrong CORE service\n"));
1611 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1612 " core id %s\n",
1613 GNUNET_i2s (identity));
1614 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1615 " my id %s\n",
1616 GNUNET_i2s (&my_full_id));
1617 GNUNET_CORE_disconnect (core_handle);
1618 core_handle = GNUNET_CORE_connect (c, /* Main configuration */
1619 NULL, /* Closure passed to MESH functions */
1620 &core_init, /* Call core_init once connected */
1621 &core_connect, /* Handle connects */
1622 &core_disconnect, /* remove peers on disconnects */
1623 NULL, /* Don't notify about all incoming messages */
1624 GNUNET_NO, /* For header only in notification */
1625 NULL, /* Don't notify about all outbound messages */
1626 GNUNET_NO, /* For header-only out notification */
1627 core_handlers); /* Register these handlers */
1628 if (10 < i++)
1629 GNUNET_abort();
1630 }
1631 GML_start ();
1632 return;
1633}
1634
1635
1636
1637
1638
1486/** 1639/**
1487 * Core handler for connection creation. 1640 * Core handler for connection creation.
1488 * 1641 *
diff --git a/src/mesh/gnunet-service-mesh_dht.c b/src/mesh/gnunet-service-mesh_dht.c
index 7f8450637..a194bd0b7 100644
--- a/src/mesh/gnunet-service-mesh_dht.c
+++ b/src/mesh/gnunet-service-mesh_dht.c
@@ -24,6 +24,7 @@
24 24
25#include "gnunet_dht_service.h" 25#include "gnunet_dht_service.h"
26 26
27#include "mesh_path.h"
27#include "gnunet-service-mesh_dht.h" 28#include "gnunet-service-mesh_dht.h"
28#include "gnunet-service-mesh_peer.h" 29#include "gnunet-service-mesh_peer.h"
29 30
@@ -35,11 +36,38 @@
35#define DEBUG_DHT(...) 36#define DEBUG_DHT(...)
36#endif 37#endif
37 38
39#define LOG (level, ...) GNUNET_log_from ("mesh-dht", level, __VA_ARGS__)
40
41
42
43/**
44 * Callback called on each path found over the DHT.
45 *
46 * @param cls Closure.
47 * @param path An unchecked, unoptimized path to the target node.
48 * After callback will no longer be valid!
49 */
50typedef void (*GMD_search_callback) (void *cls,
51 const struct MeshPeerPath *path);
52
38/******************************************************************************/ 53/******************************************************************************/
39/******************************** STRUCTS **********************************/ 54/******************************** STRUCTS **********************************/
40/******************************************************************************/ 55/******************************************************************************/
41 56
57/**
58 * Handle for DHT searches.
59 */
60struct GMD_search_handle
61{
62 /** DHT_GET handle. */
63 struct GNUNET_DHT_GetHandle *dhtget;
64
65 /** Provided callback to call when a path is found. */
66 GMD_search_callback callback;
42 67
68 /** Provided closure. */
69 void *cls;
70};
43 71
44 72
45/******************************************************************************/ 73/******************************************************************************/
@@ -67,9 +95,14 @@ static unsigned long long dht_replication_level;
67static GNUNET_SCHEDULER_TaskIdentifier announce_id_task; 95static GNUNET_SCHEDULER_TaskIdentifier announce_id_task;
68 96
69/** 97/**
98 * Own ID (short value).
99 */
100static GNUNET_PEER_Id short_id;
101
102/**
70 * Own ID (full value). 103 * Own ID (full value).
71 */ 104 */
72static struct GNUNET_PeerIdentity *id; 105static struct GNUNET_PeerIdentity *full_id;
73 106
74/** 107/**
75 * Own private key. 108 * Own private key.
@@ -83,6 +116,130 @@ static struct GNUNET_CRYPTO_EccPrivateKey *private_key;
83 116
84 117
85/** 118/**
119 * Build a PeerPath from the paths returned from the DHT, reversing the paths
120 * to obtain a local peer -> destination path and interning the peer ids.
121 *
122 * @return Newly allocated and created path
123 */
124static struct MeshPeerPath *
125path_build_from_dht (const struct GNUNET_PeerIdentity *get_path,
126 unsigned int get_path_length,
127 const struct GNUNET_PeerIdentity *put_path,
128 unsigned int put_path_length)
129{
130 struct MeshPeerPath *p;
131 GNUNET_PEER_Id id;
132 int i;
133
134 p = path_new (1);
135 p->peers[0] = myid;
136 GNUNET_PEER_change_rc (myid, 1);
137 i = get_path_length;
138 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " GET has %d hops.\n", i);
139 for (i--; i >= 0; i--)
140 {
141 id = GNUNET_PEER_intern (&get_path[i]);
142 if (p->length > 0 && id == p->peers[p->length - 1])
143 {
144 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " Optimizing 1 hop out.\n");
145 GNUNET_PEER_change_rc (id, -1);
146 }
147 else
148 {
149 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " Adding from GET: %s.\n",
150 GNUNET_i2s (&get_path[i]));
151 p->length++;
152 p->peers = GNUNET_realloc (p->peers, sizeof (GNUNET_PEER_Id) * p->length);
153 p->peers[p->length - 1] = id;
154 }
155 }
156 i = put_path_length;
157 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " PUT has %d hops.\n", i);
158 for (i--; i >= 0; i--)
159 {
160 id = GNUNET_PEER_intern (&put_path[i]);
161 if (id == myid)
162 {
163 /* PUT path went through us, so discard the path up until now and start
164 * from here to get a much shorter (and loop-free) path.
165 */
166 path_destroy (p);
167 p = path_new (0);
168 }
169 if (p->length > 0 && id == p->peers[p->length - 1])
170 {
171 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " Optimizing 1 hop out.\n");
172 GNUNET_PEER_change_rc (id, -1);
173 }
174 else
175 {
176 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " Adding from PUT: %s.\n",
177 GNUNET_i2s (&put_path[i]));
178 p->length++;
179 p->peers = GNUNET_realloc (p->peers, sizeof (GNUNET_PEER_Id) * p->length);
180 p->peers[p->length - 1] = id;
181 }
182 }
183#if MESH_DEBUG
184 if (get_path_length > 0)
185 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " (first of GET: %s)\n",
186 GNUNET_i2s (&get_path[0]));
187 if (put_path_length > 0)
188 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " (first of PUT: %s)\n",
189 GNUNET_i2s (&put_path[0]));
190 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " In total: %d hops\n",
191 p->length);
192 for (i = 0; i < p->length; i++)
193 {
194 struct GNUNET_PeerIdentity peer_id;
195
196 GNUNET_PEER_resolve (p->peers[i], &peer_id);
197 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " %u: %s\n", p->peers[i],
198 GNUNET_i2s (&peer_id));
199 }
200#endif
201 return p;
202}
203
204
205/**
206 * Function to process paths received for a new peer addition. The recorded
207 * paths form the initial tunnel, which can be optimized later.
208 * Called on each result obtained for the DHT search.
209 *
210 * @param cls closure
211 * @param exp when will this value expire
212 * @param key key of the result
213 * @param get_path path of the get request
214 * @param get_path_length lenght of get_path
215 * @param put_path path of the put request
216 * @param put_path_length length of the put_path
217 * @param type type of the result
218 * @param size number of bytes in data
219 * @param data pointer to the result data
220 */
221static void
222dht_get_id_handler (void *cls, struct GNUNET_TIME_Absolute exp,
223 const struct GNUNET_HashCode * key,
224 const struct GNUNET_PeerIdentity *get_path,
225 unsigned int get_path_length,
226 const struct GNUNET_PeerIdentity *put_path,
227 unsigned int put_path_length, enum GNUNET_BLOCK_Type type,
228 size_t size, const void *data)
229{
230 struct GMD_search_handle *h = cls;
231 struct MeshPeerPath *p;
232
233 LOG (GNUNET_ERROR_TYPE_DEBUG, "Got results!\n");
234 p = path_build_from_dht (get_path, get_path_length,
235 put_path, put_path_length);
236 h->callback (h->cls, p);
237 path_destroy (p);
238 return;
239}
240
241
242/**
86 * Periodically announce self id in the DHT 243 * Periodically announce self id in the DHT
87 * 244 *
88 * @param cls closure 245 * @param cls closure
@@ -105,8 +262,8 @@ announce_id (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
105 */ 262 */
106 DEBUG_DHT ("DHT_put for ID %s started.\n", GNUNET_i2s (id)); 263 DEBUG_DHT ("DHT_put for ID %s started.\n", GNUNET_i2s (id));
107 264
108 block.id = *id; 265 block.id = *full_id;
109 GNUNET_CRYPTO_hash (id, sizeof (struct GNUNET_PeerIdentity), &phash); 266 GNUNET_CRYPTO_hash (full_id, sizeof (struct GNUNET_PeerIdentity), &phash);
110 GNUNET_DHT_put (dht_handle, /* DHT handle */ 267 GNUNET_DHT_put (dht_handle, /* DHT handle */
111 &phash, /* Key to use */ 268 &phash, /* Key to use */
112 dht_replication_level, /* Replication level */ 269 dht_replication_level, /* Replication level */
@@ -137,7 +294,7 @@ void
137GMD_init (const struct GNUNET_CONFIGURATION_Handle *c, 294GMD_init (const struct GNUNET_CONFIGURATION_Handle *c,
138 struct GNUNET_PeerIdentity *peer_id) 295 struct GNUNET_PeerIdentity *peer_id)
139{ 296{
140 id = peer_id; 297 full_id = peer_id;
141 if (GNUNET_OK != 298 if (GNUNET_OK !=
142 GNUNET_CONFIGURATION_get_value_number (c, "MESH", "DHT_REPLICATION_LEVEL", 299 GNUNET_CONFIGURATION_get_value_number (c, "MESH", "DHT_REPLICATION_LEVEL",
143 &dht_replication_level)) 300 &dht_replication_level))
@@ -184,3 +341,34 @@ GMD_shutdown(void )
184 announce_id_task = GNUNET_SCHEDULER_NO_TASK; 341 announce_id_task = GNUNET_SCHEDULER_NO_TASK;
185 } 342 }
186} 343}
344
345struct GMD_search_handle *
346GMD_search (const struct GNUNET_PeerIdentity *peer_id,
347 GMD_search_callback callback, void *cls)
348{
349 struct GNUNET_HashCode phash;
350 struct GMD_search_handle *h;
351
352 LOG (GNUNET_ERROR_TYPE_DEBUG,
353 " Starting DHT GET for peer %s\n", GNUNET_i2s (peer_id));
354 GNUNET_CRYPTO_hash (peer_id, sizeof (struct GNUNET_PeerIdentity), &phash);
355 h = GNUNET_new (struct GMD_search_handle);
356 h->cls = cls;
357 h->dhtget = GNUNET_DHT_get_start (dht_handle, /* handle */
358 GNUNET_BLOCK_TYPE_MESH_PEER, /* type */
359 &phash, /* key to search */
360 dht_replication_level, /* replication level */
361 GNUNET_DHT_RO_RECORD_ROUTE |
362 GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE,
363 NULL, /* xquery */
364 0, /* xquery bits */
365 &dht_get_id_handler, h);
366 return h;
367}
368
369void
370GMD_search_stop (struct GMD_search_handle *h)
371{
372 GNUNET_DHT_get_stop (h->dhtget);
373 GNUNET_free (h);
374} \ No newline at end of file
diff --git a/src/mesh/gnunet-service-mesh_local.c b/src/mesh/gnunet-service-mesh_local.c
index 989def211..764ebd68f 100644
--- a/src/mesh/gnunet-service-mesh_local.c
+++ b/src/mesh/gnunet-service-mesh_local.c
@@ -157,8 +157,8 @@ client_release_ports (void *cls,
157 * @param cls Closure (unused). 157 * @param cls Closure (unused).
158 * @param client Client handler. 158 * @param client Client handler.
159 */ 159 */
160void 160static void
161GMLH_client_connect (void *cls, struct GNUNET_SERVER_Client *client) 161handle_client_connect (void *cls, struct GNUNET_SERVER_Client *client)
162{ 162{
163 struct MeshClient *c; 163 struct MeshClient *c;
164 164
@@ -180,8 +180,8 @@ GMLH_client_connect (void *cls, struct GNUNET_SERVER_Client *client)
180 * @param client identification of the client; NULL 180 * @param client identification of the client; NULL
181 * for the last call when the server is destroyed 181 * for the last call when the server is destroyed
182 */ 182 */
183void 183static void
184GMLH_client_disconnect (void *cls, struct GNUNET_SERVER_Client *client) 184handle_client_disconnect (void *cls, struct GNUNET_SERVER_Client *client)
185{ 185{
186 struct MeshClient *c; 186 struct MeshClient *c;
187 187
@@ -240,9 +240,9 @@ GMLH_client_disconnect (void *cls, struct GNUNET_SERVER_Client *client)
240 * @param client identification of the client 240 * @param client identification of the client
241 * @param message the actual message, which includes messages the client wants 241 * @param message the actual message, which includes messages the client wants
242 */ 242 */
243void 243static void
244GMLH_new_client (void *cls, struct GNUNET_SERVER_Client *client, 244handle_new_client (void *cls, struct GNUNET_SERVER_Client *client,
245 const struct GNUNET_MessageHeader *message) 245 const struct GNUNET_MessageHeader *message)
246{ 246{
247 struct GNUNET_MESH_ClientConnect *cc_msg; 247 struct GNUNET_MESH_ClientConnect *cc_msg;
248 struct MeshClient *c; 248 struct MeshClient *c;
@@ -306,9 +306,9 @@ GMLH_new_client (void *cls, struct GNUNET_SERVER_Client *client,
306 * @param client Identification of the client. 306 * @param client Identification of the client.
307 * @param message The actual message. 307 * @param message The actual message.
308 */ 308 */
309void 309static void
310GMLH_channel_create (void *cls, struct GNUNET_SERVER_Client *client, 310handle_channel_create (void *cls, struct GNUNET_SERVER_Client *client,
311 const struct GNUNET_MessageHeader *message) 311 const struct GNUNET_MessageHeader *message)
312{ 312{
313 struct GNUNET_MESH_ChannelMessage *msg; 313 struct GNUNET_MESH_ChannelMessage *msg;
314 struct MeshPeer *peer; 314 struct MeshPeer *peer;
@@ -409,9 +409,9 @@ GMLH_channel_create (void *cls, struct GNUNET_SERVER_Client *client,
409 * @param client identification of the client 409 * @param client identification of the client
410 * @param message the actual message 410 * @param message the actual message
411 */ 411 */
412void 412static void
413GMLH_channel_destroy (void *cls, struct GNUNET_SERVER_Client *client, 413handle_channel_destroy (void *cls, struct GNUNET_SERVER_Client *client,
414 const struct GNUNET_MessageHeader *message) 414 const struct GNUNET_MessageHeader *message)
415{ 415{
416 struct GNUNET_MESH_ChannelMessage *msg; 416 struct GNUNET_MESH_ChannelMessage *msg;
417 struct MeshClient *c; 417 struct MeshClient *c;
@@ -486,9 +486,9 @@ GMLH_channel_destroy (void *cls, struct GNUNET_SERVER_Client *client,
486 * @param client identification of the client 486 * @param client identification of the client
487 * @param message the actual message 487 * @param message the actual message
488 */ 488 */
489void 489static void
490GMLH_data (void *cls, struct GNUNET_SERVER_Client *client, 490handle_data (void *cls, struct GNUNET_SERVER_Client *client,
491 const struct GNUNET_MessageHeader *message) 491 const struct GNUNET_MessageHeader *message)
492{ 492{
493 struct GNUNET_MESH_LocalData *msg; 493 struct GNUNET_MESH_LocalData *msg;
494 struct MeshClient *c; 494 struct MeshClient *c;
@@ -584,9 +584,9 @@ GMLH_data (void *cls, struct GNUNET_SERVER_Client *client,
584 * @param client Identification of the client. 584 * @param client Identification of the client.
585 * @param message The actual message. 585 * @param message The actual message.
586 */ 586 */
587void 587static void
588GMLH_ack (void *cls, struct GNUNET_SERVER_Client *client, 588handle_ack (void *cls, struct GNUNET_SERVER_Client *client,
589 const struct GNUNET_MessageHeader *message) 589 const struct GNUNET_MessageHeader *message)
590{ 590{
591 struct GNUNET_MESH_LocalAck *msg; 591 struct GNUNET_MESH_LocalAck *msg;
592 struct MeshChannelReliability *rel; 592 struct MeshChannelReliability *rel;
@@ -677,9 +677,9 @@ GMLH_ack (void *cls, struct GNUNET_SERVER_Client *client,
677 * @param client Identification of the client. 677 * @param client Identification of the client.
678 * @param message The actual message. 678 * @param message The actual message.
679 */ 679 */
680void 680static void
681GMLH_get_tunnels (void *cls, struct GNUNET_SERVER_Client *client, 681handle_get_tunnels (void *cls, struct GNUNET_SERVER_Client *client,
682 const struct GNUNET_MessageHeader *message) 682 const struct GNUNET_MessageHeader *message)
683{ 683{
684 struct MeshClient *c; 684 struct MeshClient *c;
685 685
@@ -712,8 +712,8 @@ GMLH_get_tunnels (void *cls, struct GNUNET_SERVER_Client *client,
712 * @param message The actual message. 712 * @param message The actual message.
713 */ 713 */
714void 714void
715GMLH_show_tunnel (void *cls, struct GNUNET_SERVER_Client *client, 715handle_show_tunnel (void *cls, struct GNUNET_SERVER_Client *client,
716 const struct GNUNET_MessageHeader *message) 716 const struct GNUNET_MessageHeader *message)
717{ 717{
718 const struct GNUNET_MESH_LocalMonitor *msg; 718 const struct GNUNET_MESH_LocalMonitor *msg;
719 struct GNUNET_MESH_LocalMonitor *resp; 719 struct GNUNET_MESH_LocalMonitor *resp;
@@ -768,17 +768,17 @@ GMLH_show_tunnel (void *cls, struct GNUNET_SERVER_Client *client,
768 * Functions to handle messages from clients 768 * Functions to handle messages from clients
769 */ 769 */
770static struct GNUNET_SERVER_MessageHandler client_handlers[] = { 770static struct GNUNET_SERVER_MessageHandler client_handlers[] = {
771 {&GMLH_new_client, NULL, GNUNET_MESSAGE_TYPE_MESH_LOCAL_CONNECT, 0}, 771 {&handle_new_client, NULL, GNUNET_MESSAGE_TYPE_MESH_LOCAL_CONNECT, 0},
772 {&GMLH_channel_create, NULL, GNUNET_MESSAGE_TYPE_MESH_CHANNEL_CREATE, 772 {&handle_channel_create, NULL, GNUNET_MESSAGE_TYPE_MESH_CHANNEL_CREATE,
773 sizeof (struct GNUNET_MESH_ChannelMessage)}, 773 sizeof (struct GNUNET_MESH_ChannelMessage)},
774 {&GMLH_channel_destroy, NULL, GNUNET_MESSAGE_TYPE_MESH_CHANNEL_DESTROY, 774 {&handle_channel_destroy, NULL, GNUNET_MESSAGE_TYPE_MESH_CHANNEL_DESTROY,
775 sizeof (struct GNUNET_MESH_ChannelMessage)}, 775 sizeof (struct GNUNET_MESH_ChannelMessage)},
776 {&GMLH_data, NULL, GNUNET_MESSAGE_TYPE_MESH_LOCAL_DATA, 0}, 776 {&handle_data, NULL, GNUNET_MESSAGE_TYPE_MESH_LOCAL_DATA, 0},
777 {&GMLH_ack, NULL, GNUNET_MESSAGE_TYPE_MESH_LOCAL_ACK, 777 {&handle_ack, NULL, GNUNET_MESSAGE_TYPE_MESH_LOCAL_ACK,
778 sizeof (struct GNUNET_MESH_LocalAck)}, 778 sizeof (struct GNUNET_MESH_LocalAck)},
779 {&GMLH_get_tunnels, NULL, GNUNET_MESSAGE_TYPE_MESH_LOCAL_INFO_TUNNELS, 779 {&handle_get_tunnels, NULL, GNUNET_MESSAGE_TYPE_MESH_LOCAL_INFO_TUNNELS,
780 sizeof (struct GNUNET_MessageHeader)}, 780 sizeof (struct GNUNET_MessageHeader)},
781 {&GMLH_show_tunnel, NULL, GNUNET_MESSAGE_TYPE_MESH_LOCAL_INFO_TUNNEL, 781 {&handle_show_tunnel, NULL, GNUNET_MESSAGE_TYPE_MESH_LOCAL_INFO_TUNNEL,
782 sizeof (struct GNUNET_MESH_LocalMonitor)}, 782 sizeof (struct GNUNET_MESH_LocalMonitor)},
783 {NULL, NULL, 0, 0} 783 {NULL, NULL, 0, 0}
784}; 784};
@@ -802,6 +802,7 @@ GML_init (struct GNUNET_SERVER_Handle *handle)
802 ports = GNUNET_CONTAINER_multihashmap32_create (32); 802 ports = GNUNET_CONTAINER_multihashmap32_create (32);
803} 803}
804 804
805
805/** 806/**
806 * Install server (service) handlers and start listening to clients. 807 * Install server (service) handlers and start listening to clients.
807 */ 808 */
@@ -809,8 +810,8 @@ void
809GML_start (void) 810GML_start (void)
810{ 811{
811 GNUNET_SERVER_add_handlers (server_handle, client_handlers); 812 GNUNET_SERVER_add_handlers (server_handle, client_handlers);
812 GNUNET_SERVER_connect_notify (server_handle, &GMLH_client_connect, NULL); 813 GNUNET_SERVER_connect_notify (server_handle, &handle_client_connect, NULL);
813 GNUNET_SERVER_disconnect_notify (server_handle, &GMLH_client_disconnect, 814 GNUNET_SERVER_disconnect_notify (server_handle, &handle_client_disconnect,
814 NULL); 815 NULL);
815 nc = GNUNET_SERVER_notification_context_create (server_handle, 1); 816 nc = GNUNET_SERVER_notification_context_create (server_handle, 1);
816 817
diff --git a/src/mesh/gnunet-service-mesh_peer.c b/src/mesh/gnunet-service-mesh_peer.c
index 13dc05c65..75decd3bb 100644
--- a/src/mesh/gnunet-service-mesh_peer.c
+++ b/src/mesh/gnunet-service-mesh_peer.c
@@ -23,6 +23,7 @@
23#include "gnunet_util_lib.h" 23#include "gnunet_util_lib.h"
24 24
25#include "gnunet-service-mesh_peer.h" 25#include "gnunet-service-mesh_peer.h"
26#include "gnunet-service-mesh_dht.h"
26#include "mesh_path.h" 27#include "mesh_path.h"
27 28
28/******************************************************************************/ 29/******************************************************************************/
@@ -393,95 +394,6 @@ peer_get_best_path (const struct MeshPeer *peer)
393} 394}
394 395
395 396
396
397/**
398 * Try to establish a new connection to this peer in the given tunnel.
399 * If the peer doesn't have any path to it yet, try to get one.
400 * If the peer already has some path, send a CREATE CONNECTION towards it.
401 *
402 * @param peer PeerInfo of the peer.
403 */
404static void
405peer_connect (struct MeshPeer *peer)
406{
407 struct MeshTunnel2 *t;
408 struct MeshPeerPath *p;
409 struct MeshConnection *c;
410 int rerun_dhtget;
411
412 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
413 "peer_connect towards %s\n",
414 peer2s (peer));
415 t = peer->tunnel;
416 c = NULL;
417 rerun_dhtget = GNUNET_NO;
418
419 if (NULL != peer->path_head)
420 {
421 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "path exists\n");
422 p = peer_get_best_path (peer);
423 if (NULL != p)
424 {
425 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " %u hops\n", p->length);
426 c = tunnel_use_path (t, p);
427 if (NULL == c)
428 {
429 /* This case can happen when the path includes a first hop that is
430 * not yet known to be connected.
431 *
432 * This happens quite often during testing when running mesh
433 * under valgrind: core connect notifications come very late and the
434 * DHT result has already come and created a valid path.
435 * In this case, the peer->connections hashmap will be NULL and
436 * tunnel_use_path will not be able to create a connection from that
437 * path.
438 *
439 * Re-running the DHT GET should give core time to callback.
440 */
441 GNUNET_break(0);
442 rerun_dhtget = GNUNET_YES;
443 }
444 else
445 {
446 send_connection_create (c);
447 return;
448 }
449 }
450 }
451
452 if (NULL != peer->dhtget && GNUNET_YES == rerun_dhtget)
453 {
454 GNUNET_DHT_get_stop (peer->dhtget);
455 peer->dhtget = NULL;
456 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
457 " Stopping DHT GET for peer %s\n", peer2s (peer));
458 }
459
460 if (NULL == peer->dhtget)
461 {
462 const struct GNUNET_PeerIdentity *id;
463 struct GNUNET_HashCode phash;
464
465 id = GNUNET_PEER_resolve2 (peer->id);
466 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
467 " Starting DHT GET for peer %s\n", peer2s (peer));
468 GNUNET_CRYPTO_hash (&id, sizeof (struct GNUNET_PeerIdentity), &phash);
469 peer->dhtget = GNUNET_DHT_get_start (dht_handle, /* handle */
470 GNUNET_BLOCK_TYPE_MESH_PEER, /* type */
471 &phash, /* key to search */
472 dht_replication_level, /* replication level */
473 GNUNET_DHT_RO_RECORD_ROUTE |
474 GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE,
475 NULL, /* xquery */
476 0, /* xquery bits */
477 &dht_get_id_handler, peer);
478 if (MESH_TUNNEL_NEW == t->state)
479 tunnel_change_state (t, MESH_TUNNEL_SEARCHING);
480 }
481}
482
483
484
485/** 397/**
486 * Add the path to the peer and update the path used to reach it in case this 398 * Add the path to the peer and update the path used to reach it in case this
487 * is the shortest. 399 * is the shortest.
@@ -622,3 +534,89 @@ GMP_shutdown (void)
622 GNUNET_CONTAINER_multipeermap_iterate (peers, &shutdown_tunnel, NULL); 534 GNUNET_CONTAINER_multipeermap_iterate (peers, &shutdown_tunnel, NULL);
623} 535}
624 536
537
538/**
539 * Try to establish a new connection to this peer in the given tunnel.
540 * If the peer doesn't have any path to it yet, try to get one.
541 * If the peer already has some path, send a CREATE CONNECTION towards it.
542 *
543 * @param peer PeerInfo of the peer.
544 */
545void
546GMP_connect (struct MeshPeer *peer)
547{
548 struct MeshTunnel2 *t;
549 struct MeshPeerPath *p;
550 struct MeshConnection *c;
551 int rerun_dhtget;
552
553 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
554 "peer_connect towards %s\n",
555 peer2s (peer));
556 t = peer->tunnel;
557 c = NULL;
558 rerun_dhtget = GNUNET_NO;
559
560 if (NULL != peer->path_head)
561 {
562 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "path exists\n");
563 p = peer_get_best_path (peer);
564 if (NULL != p)
565 {
566 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, " %u hops\n", p->length);
567 c = tunnel_use_path (t, p);
568 if (NULL == c)
569 {
570 /* This case can happen when the path includes a first hop that is
571 * not yet known to be connected.
572 *
573 * This happens quite often during testing when running mesh
574 * under valgrind: core connect notifications come very late and the
575 * DHT result has already come and created a valid path.
576 * In this case, the peer->connections hashmap will be NULL and
577 * tunnel_use_path will not be able to create a connection from that
578 * path.
579 *
580 * Re-running the DHT GET should give core time to callback.
581 */
582 GNUNET_break(0);
583 rerun_dhtget = GNUNET_YES;
584 }
585 else
586 {
587 send_connection_create (c);
588 return;
589 }
590 }
591 }
592
593 if (NULL != peer->dhtget && GNUNET_YES == rerun_dhtget)
594 {
595 GNUNET_DHT_get_stop (peer->dhtget);
596 peer->dhtget = NULL;
597 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
598 " Stopping DHT GET for peer %s\n", peer2s (peer));
599 }
600
601 if (NULL == peer->dhtget)
602 {
603 const struct GNUNET_PeerIdentity *id;
604 struct GNUNET_HashCode phash;
605
606 id = GNUNET_PEER_resolve2 (peer->id);
607 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
608 " Starting DHT GET for peer %s\n", peer2s (peer));
609 GNUNET_CRYPTO_hash (&id, sizeof (struct GNUNET_PeerIdentity), &phash);
610 peer->dhtget = GNUNET_DHT_get_start (dht_handle, /* handle */
611 GNUNET_BLOCK_TYPE_MESH_PEER, /* type */
612 &phash, /* key to search */
613 dht_replication_level, /* replication level */
614 GNUNET_DHT_RO_RECORD_ROUTE |
615 GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE,
616 NULL, /* xquery */
617 0, /* xquery bits */
618 &dht_get_id_handler, peer);
619 if (MESH_TUNNEL_NEW == t->state)
620 tunnel_change_state (t, MESH_TUNNEL_SEARCHING);
621 }
622} \ No newline at end of file