diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/transport/gnunet-service-transport.c | 3 | ||||
-rw-r--r-- | src/transport/gnunet-service-transport_neighbours.c | 133 | ||||
-rw-r--r-- | src/transport/gnunet-service-transport_neighbours.h | 11 | ||||
-rw-r--r-- | src/transport/gnunet-service-transport_validation.c | 2 |
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 | */ | ||
1814 | void | ||
1815 | GST_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 | |||
124 | void | 124 | void |
125 | GST_neighbours_keepalive (const struct GNUNET_PeerIdentity *neighbour); | 125 | GST_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 | */ | ||
133 | void | ||
134 | GST_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 | { |