aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMatthias Wachs <wachs@net.in.tum.de>2011-11-10 12:58:35 +0000
committerMatthias Wachs <wachs@net.in.tum.de>2011-11-10 12:58:35 +0000
commita74166876d91f823b86ddad9894d0b0a0f50ee46 (patch)
tree9012f6593f6c47bb65db4c1ebe6eb36e44a1d74f /src
parentbeda377f4ab06a563f8f91768196e1858939e5ec (diff)
downloadgnunet-a74166876d91f823b86ddad9894d0b0a0f50ee46.tar.gz
gnunet-a74166876d91f823b86ddad9894d0b0a0f50ee46.zip
latency measurement with neighbour_keep_alive_task
Diffstat (limited to 'src')
-rw-r--r--src/transport/gnunet-service-transport.c3
-rw-r--r--src/transport/gnunet-service-transport_neighbours.c133
-rw-r--r--src/transport/gnunet-service-transport_neighbours.h11
-rw-r--r--src/transport/gnunet-service-transport_validation.c2
4 files changed, 134 insertions, 15 deletions
diff --git a/src/transport/gnunet-service-transport.c b/src/transport/gnunet-service-transport.c
index 46c18f212..b9f4dc30f 100644
--- a/src/transport/gnunet-service-transport.c
+++ b/src/transport/gnunet-service-transport.c
@@ -264,6 +264,9 @@ plugin_env_receive_callback (void *cls,
264 case GNUNET_MESSAGE_TYPE_TRANSPORT_SESSION_KEEPALIVE: 264 case GNUNET_MESSAGE_TYPE_TRANSPORT_SESSION_KEEPALIVE:
265 GST_neighbours_keepalive (peer); 265 GST_neighbours_keepalive (peer);
266 break; 266 break;
267 case GNUNET_MESSAGE_TYPE_TRANSPORT_SESSION_KEEPALIVE_RESPONSE:
268 GST_neighbours_keepalive_response (peer, ats, ats_count);
269 break;
267 default: 270 default:
268 /* should be payload */ 271 /* should be payload */
269 ret = process_payload (peer, message, ats, ats_count); 272 ret = process_payload (peer, message, ats, ats_count);
diff --git a/src/transport/gnunet-service-transport_neighbours.c b/src/transport/gnunet-service-transport_neighbours.c
index 54e5c61bc..c9e8e1624 100644
--- a/src/transport/gnunet-service-transport_neighbours.c
+++ b/src/transport/gnunet-service-transport_neighbours.c
@@ -48,12 +48,13 @@
48#define QUOTA_VIOLATION_DROP_THRESHOLD 10 48#define QUOTA_VIOLATION_DROP_THRESHOLD 10
49 49
50/** 50/**
51 * How often do we send KEEPALIVE messages to each of our neighbours? 51 * How often do we send KEEPALIVE messages to each of our neighbours and measure
52 * (idle timeout is 5 minutes or 300 seconds, so with 90s interval we 52 * the latency with this neighbour?
53 * send 3 keepalives in each interval, so 3 messages would need to be 53 * (idle timeout is 5 minutes or 300 seconds, so with 30s interval we
54 * send 10 keepalives in each interval, so 10 messages would need to be
54 * lost in a row for a disconnect). 55 * lost in a row for a disconnect).
55 */ 56 */
56#define KEEPALIVE_FREQUENCY GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 90) 57#define KEEPALIVE_FREQUENCY GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 30)
57 58
58 59
59#define ATS_RESPONSE_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 3) 60#define ATS_RESPONSE_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 3)
@@ -300,6 +301,16 @@ struct NeighbourMapEntry
300 struct GNUNET_TIME_Absolute connect_ts; 301 struct GNUNET_TIME_Absolute connect_ts;
301 302
302 /** 303 /**
304 * When did we sent the last keep-alive message?
305 */
306 struct GNUNET_TIME_Absolute keep_alive_sent;
307
308 /**
309 * Latest calculated latency value
310 */
311 struct GNUNET_TIME_Relative latency;
312
313 /**
303 * Timeout for ATS 314 * Timeout for ATS
304 * We asked ATS for a new address for this peer 315 * We asked ATS for a new address for this peer
305 */ 316 */
@@ -325,6 +336,10 @@ struct NeighbourMapEntry
325 */ 336 */
326 int state; 337 int state;
327 338
339 /**
340 * Did we sent an KEEP_ALIVE message and are we expecting a response?
341 */
342 int expect_latency_response;
328}; 343};
329 344
330 345
@@ -971,20 +986,32 @@ neighbour_keepalive_task (void *cls,
971{ 986{
972 struct NeighbourMapEntry *n = cls; 987 struct NeighbourMapEntry *n = cls;
973 struct GNUNET_MessageHeader m; 988 struct GNUNET_MessageHeader m;
989 int ret;
974 990
975 n->keepalive_task = 991 n->keepalive_task =
976 GNUNET_SCHEDULER_add_delayed (KEEPALIVE_FREQUENCY, 992 GNUNET_SCHEDULER_add_delayed (KEEPALIVE_FREQUENCY,
977 &neighbour_keepalive_task, n); 993 &neighbour_keepalive_task, n);
994
978 GNUNET_assert (S_CONNECTED == n->state); 995 GNUNET_assert (S_CONNECTED == n->state);
979 GNUNET_STATISTICS_update (GST_stats, gettext_noop ("# keepalives sent"), 1, 996 GNUNET_STATISTICS_update (GST_stats, gettext_noop ("# keepalives sent"), 1,
980 GNUNET_NO); 997 GNUNET_NO);
981 m.size = htons (sizeof (struct GNUNET_MessageHeader)); 998 m.size = htons (sizeof (struct GNUNET_MessageHeader));
982 m.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_SESSION_KEEPALIVE); 999 m.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_SESSION_KEEPALIVE);
983 1000
984 send_with_plugin (&n->id, (const void *) &m, sizeof (m), 1001
1002 ret = send_with_plugin (&n->id, (const void *) &m, sizeof (m),
985 UINT32_MAX /* priority */ , 1003 UINT32_MAX /* priority */ ,
986 GNUNET_TIME_UNIT_FOREVER_REL, n->session, n->address, 1004 GNUNET_TIME_UNIT_FOREVER_REL, n->session, n->address,
987 GNUNET_YES, NULL, NULL); 1005 GNUNET_YES, NULL, NULL);
1006
1007 n->expect_latency_response = GNUNET_NO;
1008 n->keep_alive_sent = GNUNET_TIME_absolute_get_zero();
1009 if (ret != GNUNET_SYSERR)
1010 {
1011 n->expect_latency_response = GNUNET_YES;
1012 n->keep_alive_sent = GNUNET_TIME_absolute_get();
1013 }
1014
988} 1015}
989 1016
990 1017
@@ -1375,9 +1402,8 @@ GST_neighbour_get_latency (const struct GNUNET_PeerIdentity *peer)
1375 if ( (NULL == n) || 1402 if ( (NULL == n) ||
1376 ( (n->address == NULL) && (n->session == NULL) ) ) 1403 ( (n->address == NULL) && (n->session == NULL) ) )
1377 return GNUNET_TIME_UNIT_FOREVER_REL; 1404 return GNUNET_TIME_UNIT_FOREVER_REL;
1378 return GST_validation_get_address_latency (peer, 1405
1379 n->address, 1406 return n->latency;
1380 n->session);
1381} 1407}
1382 1408
1383 1409
@@ -1399,6 +1425,7 @@ setup_neighbour (const struct GNUNET_PeerIdentity *peer)
1399 n = GNUNET_malloc (sizeof (struct NeighbourMapEntry)); 1425 n = GNUNET_malloc (sizeof (struct NeighbourMapEntry));
1400 n->id = *peer; 1426 n->id = *peer;
1401 n->state = S_NOT_CONNECTED; 1427 n->state = S_NOT_CONNECTED;
1428 n->latency = GNUNET_TIME_relative_get_forever();
1402 GNUNET_BANDWIDTH_tracker_init (&n->in_tracker, 1429 GNUNET_BANDWIDTH_tracker_init (&n->in_tracker,
1403 GNUNET_CONSTANTS_DEFAULT_BW_IN_OUT, 1430 GNUNET_CONSTANTS_DEFAULT_BW_IN_OUT,
1404 MAX_BANDWIDTH_CARRY_S); 1431 MAX_BANDWIDTH_CARRY_S);
@@ -1763,6 +1790,88 @@ GST_neighbours_keepalive (const struct GNUNET_PeerIdentity *neighbour)
1763 n->timeout_task = 1790 n->timeout_task =
1764 GNUNET_SCHEDULER_add_delayed (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT, 1791 GNUNET_SCHEDULER_add_delayed (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT,
1765 &neighbour_timeout_task, n); 1792 &neighbour_timeout_task, n);
1793
1794 /* send reply to measure latency */
1795 if (S_CONNECTED != n->state)
1796 return;
1797
1798 struct GNUNET_MessageHeader m;
1799 m.size = htons (sizeof (struct GNUNET_MessageHeader));
1800 m.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_SESSION_KEEPALIVE_RESPONSE);
1801
1802 send_with_plugin (&n->id, (const void *) &m, sizeof (m),
1803 UINT32_MAX /* priority */ ,
1804 GNUNET_TIME_UNIT_FOREVER_REL, n->session, n->address,
1805 GNUNET_YES, NULL, NULL);
1806}
1807
1808/**
1809 * We received a KEEP_ALIVE_RESPONSE message and use this to calculate latency
1810 * to this peer
1811 *
1812 * @param neighbour neighbour to keep alive
1813 */
1814void
1815GST_neighbours_keepalive_response (const struct GNUNET_PeerIdentity *neighbour,
1816 const struct GNUNET_ATS_Information * ats,
1817 uint32_t ats_count)
1818{
1819 struct NeighbourMapEntry *n;
1820 struct GNUNET_ATS_Information * ats_new;
1821 uint32_t latency;
1822
1823 if (neighbours == NULL)
1824 {
1825 // This can happen during shutdown
1826 return;
1827 }
1828
1829 n = lookup_neighbour (neighbour);
1830 if (NULL == n)
1831 {
1832 GNUNET_STATISTICS_update (GST_stats,
1833 gettext_noop
1834 ("# KEEPALIVE_RESPONSE messages discarded (not connected)"),
1835 1, GNUNET_NO);
1836 return;
1837 }
1838 if (n->expect_latency_response != GNUNET_YES)
1839 {
1840 GNUNET_STATISTICS_update (GST_stats,
1841 gettext_noop
1842 ("# KEEPALIVE_RESPONSE messages discarded (not expected)"),
1843 1, GNUNET_NO);
1844 return;
1845 }
1846 n->expect_latency_response = GNUNET_NO;
1847
1848 GNUNET_assert (n->keep_alive_sent.abs_value != GNUNET_TIME_absolute_get_zero().abs_value);
1849 n->latency = GNUNET_TIME_absolute_get_difference(n->keep_alive_sent, GNUNET_TIME_absolute_get());
1850#if DEBUG_TRANSPORT
1851 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1852 "Latency for peer `%s' is %llu ms\n",
1853 GNUNET_i2s (&n->id), n->latency.rel_value);
1854#endif
1855
1856
1857 if (n->latency.rel_value == GNUNET_TIME_relative_get_forever().rel_value)
1858 GNUNET_ATS_address_update (GST_ats, n->address, n->session, ats, ats_count);
1859 else
1860 {
1861 ats_new = GNUNET_malloc (sizeof (struct GNUNET_ATS_Information) * (ats_count + 1));
1862 memcpy (ats_new, ats, sizeof (struct GNUNET_ATS_Information) * ats_count);
1863
1864 /* add latency */
1865 ats_new[ats_count].type = htonl (GNUNET_ATS_QUALITY_NET_DELAY);
1866 if (n->latency.rel_value > UINT32_MAX)
1867 latency = UINT32_MAX;
1868 else
1869 latency = n->latency.rel_value;
1870 ats_new[ats_count].value = htonl (latency);
1871
1872 GNUNET_ATS_address_update (GST_ats, n->address, n->session, ats_new, ats_count + 1);
1873 GNUNET_free (ats_new);
1874 }
1766} 1875}
1767 1876
1768 1877
@@ -2069,9 +2178,7 @@ GST_neighbours_handle_connect_ack (const struct GNUNET_MessageHeader *message,
2069 2178
2070 2179
2071 if (n->keepalive_task == GNUNET_SCHEDULER_NO_TASK) 2180 if (n->keepalive_task == GNUNET_SCHEDULER_NO_TASK)
2072 n->keepalive_task = 2181 n->keepalive_task = GNUNET_SCHEDULER_add_now (&neighbour_keepalive_task, n);
2073 GNUNET_SCHEDULER_add_delayed (KEEPALIVE_FREQUENCY,
2074 &neighbour_keepalive_task, n);
2075 2182
2076 neighbours_connected++; 2183 neighbours_connected++;
2077 GNUNET_STATISTICS_update (GST_stats, gettext_noop ("# peers connected"), 1, 2184 GNUNET_STATISTICS_update (GST_stats, gettext_noop ("# peers connected"), 1,
@@ -2150,9 +2257,7 @@ GST_neighbours_handle_ack (const struct GNUNET_MessageHeader *message,
2150 GST_neighbours_set_incoming_quota (&n->id, n->bandwidth_in); 2257 GST_neighbours_set_incoming_quota (&n->id, n->bandwidth_in);
2151 2258
2152 if (n->keepalive_task == GNUNET_SCHEDULER_NO_TASK) 2259 if (n->keepalive_task == GNUNET_SCHEDULER_NO_TASK)
2153 n->keepalive_task = 2260 n->keepalive_task = GNUNET_SCHEDULER_add_now (&neighbour_keepalive_task, n);
2154 GNUNET_SCHEDULER_add_delayed (KEEPALIVE_FREQUENCY,
2155 &neighbour_keepalive_task, n);
2156 GST_validation_set_address_use (&n->id, 2261 GST_validation_set_address_use (&n->id,
2157 n->address, 2262 n->address,
2158 n->session, 2263 n->session,
diff --git a/src/transport/gnunet-service-transport_neighbours.h b/src/transport/gnunet-service-transport_neighbours.h
index 72ced636d..7a79d5113 100644
--- a/src/transport/gnunet-service-transport_neighbours.h
+++ b/src/transport/gnunet-service-transport_neighbours.h
@@ -124,6 +124,17 @@ GST_neighbours_calculate_receive_delay (const struct GNUNET_PeerIdentity
124void 124void
125GST_neighbours_keepalive (const struct GNUNET_PeerIdentity *neighbour); 125GST_neighbours_keepalive (const struct GNUNET_PeerIdentity *neighbour);
126 126
127/**
128 * We received a KEEP_ALIVE_RESPONSE message and use this to calculate latency
129 * to this peer
130 *
131 * @param neighbour neighbour to keep alive
132 */
133void
134GST_neighbours_keepalive_response (const struct GNUNET_PeerIdentity *neighbour,
135 const struct GNUNET_ATS_Information * ats,
136 uint32_t ats_count);
137
127 138
128/** 139/**
129 * Change the incoming quota for the given peer. 140 * Change the incoming quota for the given peer.
diff --git a/src/transport/gnunet-service-transport_validation.c b/src/transport/gnunet-service-transport_validation.c
index 7e0803a9d..cab5af882 100644
--- a/src/transport/gnunet-service-transport_validation.c
+++ b/src/transport/gnunet-service-transport_validation.c
@@ -1025,7 +1025,6 @@ GST_validation_handle_pong (const struct GNUNET_PeerIdentity *sender,
1025 return; 1025 return;
1026 } 1026 }
1027 1027
1028 ve->expecting_pong = GNUNET_NO;
1029 if (GNUNET_TIME_absolute_get_remaining 1028 if (GNUNET_TIME_absolute_get_remaining
1030 (GNUNET_TIME_absolute_ntoh (pong->expiration)).rel_value == 0) 1029 (GNUNET_TIME_absolute_ntoh (pong->expiration)).rel_value == 0)
1031 { 1030 {
@@ -1043,6 +1042,7 @@ GST_validation_handle_pong (const struct GNUNET_PeerIdentity *sender,
1043#endif 1042#endif
1044 1043
1045 /* validity achieved, remember it! */ 1044 /* validity achieved, remember it! */
1045 ve->expecting_pong = GNUNET_NO;
1046 ve->valid_until = GNUNET_TIME_relative_to_absolute (HELLO_ADDRESS_EXPIRATION); 1046 ve->valid_until = GNUNET_TIME_relative_to_absolute (HELLO_ADDRESS_EXPIRATION);
1047 ve->latency = GNUNET_TIME_absolute_get_duration (ve->send_time); 1047 ve->latency = GNUNET_TIME_absolute_get_duration (ve->send_time);
1048 { 1048 {