diff options
Diffstat (limited to 'src/transport/gnunet-service-transport_neighbours.c')
-rw-r--r-- | src/transport/gnunet-service-transport_neighbours.c | 124 |
1 files changed, 111 insertions, 13 deletions
diff --git a/src/transport/gnunet-service-transport_neighbours.c b/src/transport/gnunet-service-transport_neighbours.c index c4d4677b1..e5bc5161c 100644 --- a/src/transport/gnunet-service-transport_neighbours.c +++ b/src/transport/gnunet-service-transport_neighbours.c | |||
@@ -117,6 +117,28 @@ struct SessionConnectMessage | |||
117 | 117 | ||
118 | 118 | ||
119 | /** | 119 | /** |
120 | * Message a peer sends to another when connected to indicate that a | ||
121 | * session is in use and the peer is still alive or to respond to a keep alive. | ||
122 | * A peer sends a message with type #GNUNET_MESSAGE_TYPE_TRANSPORT_SESSION_KEEPALIVE | ||
123 | * to request a message with #GNUNET_MESSAGE_TYPE_TRANSPORT_SESSION_KEEPALIVE_RESPONSE. | ||
124 | * When the keep alive response with type is received, transport service | ||
125 | * will call the respective plugin to update the session timeout | ||
126 | */ | ||
127 | struct SessionKeepAliveMessage | ||
128 | { | ||
129 | /** | ||
130 | * Header of type #GNUNET_MESSAGE_TYPE_TRANSPORT_SESSION_KEEPALIVE or | ||
131 | * #GNUNET_MESSAGE_TYPE_TRANSPORT_SESSION_KEEPALIVE_RESPONSE. | ||
132 | */ | ||
133 | struct GNUNET_MessageHeader header; | ||
134 | |||
135 | /** | ||
136 | * A nonce to identify the session the keep alive is used for | ||
137 | */ | ||
138 | uint32_t nonce GNUNET_PACKED; | ||
139 | }; | ||
140 | |||
141 | /** | ||
120 | * Message we send to the other peer to notify him that we intentionally | 142 | * Message we send to the other peer to notify him that we intentionally |
121 | * are disconnecting (to reduce timeouts). This is just a friendly | 143 | * are disconnecting (to reduce timeouts). This is just a friendly |
122 | * notification, peers must not rely on always receiving disconnect | 144 | * notification, peers must not rely on always receiving disconnect |
@@ -410,6 +432,10 @@ struct NeighbourAddress | |||
410 | */ | 432 | */ |
411 | int ats_active; | 433 | int ats_active; |
412 | 434 | ||
435 | /** | ||
436 | * The current nonce sent in the last keep alive messages | ||
437 | */ | ||
438 | uint32_t keep_alive_nonce; | ||
413 | }; | 439 | }; |
414 | 440 | ||
415 | 441 | ||
@@ -775,6 +801,7 @@ free_address (struct NeighbourAddress *na) | |||
775 | } | 801 | } |
776 | 802 | ||
777 | na->ats_active = GNUNET_NO; | 803 | na->ats_active = GNUNET_NO; |
804 | na->keep_alive_nonce = 0; | ||
778 | if (NULL != na->address) | 805 | if (NULL != na->address) |
779 | { | 806 | { |
780 | GNUNET_HELLO_address_free (na->address); | 807 | GNUNET_HELLO_address_free (na->address); |
@@ -847,6 +874,7 @@ set_address (struct NeighbourAddress *na, | |||
847 | na->bandwidth_out = bandwidth_out; | 874 | na->bandwidth_out = bandwidth_out; |
848 | na->session = session; | 875 | na->session = session; |
849 | na->ats_active = is_active; | 876 | na->ats_active = is_active; |
877 | na->keep_alive_nonce = 0; | ||
850 | if (GNUNET_YES == is_active) | 878 | if (GNUNET_YES == is_active) |
851 | { | 879 | { |
852 | /* Telling ATS about new session */ | 880 | /* Telling ATS about new session */ |
@@ -1296,16 +1324,28 @@ try_transmission_to_peer (struct NeighbourMapEntry *n) | |||
1296 | static void | 1324 | static void |
1297 | send_keepalive (struct NeighbourMapEntry *n) | 1325 | send_keepalive (struct NeighbourMapEntry *n) |
1298 | { | 1326 | { |
1299 | struct GNUNET_MessageHeader m; | 1327 | struct SessionKeepAliveMessage m; |
1300 | struct GNUNET_TIME_Relative timeout; | 1328 | struct GNUNET_TIME_Relative timeout; |
1329 | uint32_t nonce; | ||
1301 | 1330 | ||
1302 | GNUNET_assert ((S_CONNECTED == n->state) || | 1331 | GNUNET_assert ((S_CONNECTED == n->state) || |
1303 | (S_CONNECTED_SWITCHING_BLACKLIST == n->state) || | 1332 | (S_CONNECTED_SWITCHING_BLACKLIST == n->state) || |
1304 | (S_CONNECTED_SWITCHING_CONNECT_SENT)); | 1333 | (S_CONNECTED_SWITCHING_CONNECT_SENT)); |
1305 | if (GNUNET_TIME_absolute_get_remaining (n->keep_alive_time).rel_value_us > 0) | 1334 | if (GNUNET_TIME_absolute_get_remaining (n->keep_alive_time).rel_value_us > 0) |
1306 | return; /* no keepalive needed at this time */ | 1335 | return; /* no keepalive needed at this time */ |
1307 | m.size = htons (sizeof (struct GNUNET_MessageHeader)); | 1336 | |
1308 | m.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_SESSION_KEEPALIVE); | 1337 | nonce = 0; /* 0 indicates 'not set' */ |
1338 | while (0 == nonce) | ||
1339 | nonce = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_NONCE, UINT32_MAX); | ||
1340 | |||
1341 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
1342 | "Sending keep alive response to peer `%s' with nonce %u\n", | ||
1343 | GNUNET_i2s (&n->id), nonce); | ||
1344 | |||
1345 | m.header.size = htons (sizeof (struct SessionKeepAliveMessage)); | ||
1346 | m.header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_SESSION_KEEPALIVE); | ||
1347 | m.nonce = htonl (nonce); | ||
1348 | |||
1309 | timeout = send_with_session (n, | 1349 | timeout = send_with_session (n, |
1310 | (const void *) &m, sizeof (m), | 1350 | (const void *) &m, sizeof (m), |
1311 | UINT32_MAX /* priority */, | 1351 | UINT32_MAX /* priority */, |
@@ -1313,9 +1353,11 @@ send_keepalive (struct NeighbourMapEntry *n) | |||
1313 | NULL, NULL); | 1353 | NULL, NULL); |
1314 | GNUNET_STATISTICS_update (GST_stats, gettext_noop ("# keepalives sent"), 1, | 1354 | GNUNET_STATISTICS_update (GST_stats, gettext_noop ("# keepalives sent"), 1, |
1315 | GNUNET_NO); | 1355 | GNUNET_NO); |
1356 | n->primary_address.keep_alive_nonce = nonce; | ||
1316 | n->expect_latency_response = GNUNET_YES; | 1357 | n->expect_latency_response = GNUNET_YES; |
1317 | n->last_keep_alive_time = GNUNET_TIME_absolute_get (); | 1358 | n->last_keep_alive_time = GNUNET_TIME_absolute_get (); |
1318 | n->keep_alive_time = GNUNET_TIME_relative_to_absolute (timeout); | 1359 | n->keep_alive_time = GNUNET_TIME_relative_to_absolute (timeout); |
1360 | |||
1319 | } | 1361 | } |
1320 | 1362 | ||
1321 | 1363 | ||
@@ -1324,13 +1366,20 @@ send_keepalive (struct NeighbourMapEntry *n) | |||
1324 | * we received a KEEPALIVE (or equivalent); send a response. | 1366 | * we received a KEEPALIVE (or equivalent); send a response. |
1325 | * | 1367 | * |
1326 | * @param neighbour neighbour to keep alive (by sending keep alive response) | 1368 | * @param neighbour neighbour to keep alive (by sending keep alive response) |
1369 | * @param m the keep alive message containing the nonce to respond to | ||
1327 | */ | 1370 | */ |
1328 | void | 1371 | void |
1329 | GST_neighbours_keepalive (const struct GNUNET_PeerIdentity *neighbour) | 1372 | GST_neighbours_keepalive (const struct GNUNET_PeerIdentity *neighbour, |
1373 | const struct GNUNET_MessageHeader *m) | ||
1330 | { | 1374 | { |
1331 | struct NeighbourMapEntry *n; | 1375 | struct NeighbourMapEntry *n; |
1332 | struct GNUNET_MessageHeader m; | 1376 | const struct SessionKeepAliveMessage *msg_in; |
1377 | struct SessionKeepAliveMessage msg; | ||
1333 | 1378 | ||
1379 | if (sizeof (struct SessionKeepAliveMessage) != ntohs (m->size)) | ||
1380 | return; | ||
1381 | |||
1382 | msg_in = (struct SessionKeepAliveMessage *) m; | ||
1334 | if (NULL == (n = lookup_neighbour (neighbour))) | 1383 | if (NULL == (n = lookup_neighbour (neighbour))) |
1335 | { | 1384 | { |
1336 | GNUNET_STATISTICS_update (GST_stats, | 1385 | GNUNET_STATISTICS_update (GST_stats, |
@@ -1347,11 +1396,17 @@ GST_neighbours_keepalive (const struct GNUNET_PeerIdentity *neighbour) | |||
1347 | 1, GNUNET_NO); | 1396 | 1, GNUNET_NO); |
1348 | return; | 1397 | return; |
1349 | } | 1398 | } |
1399 | |||
1400 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
1401 | "Received keep alive request from peer `%s' with nonce %u\n", | ||
1402 | GNUNET_i2s (&n->id), ntohl (msg_in->nonce)); | ||
1403 | |||
1350 | /* send reply to allow neighbour to measure latency */ | 1404 | /* send reply to allow neighbour to measure latency */ |
1351 | m.size = htons (sizeof (struct GNUNET_MessageHeader)); | 1405 | msg.header.size = htons (sizeof (struct SessionKeepAliveMessage)); |
1352 | m.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_SESSION_KEEPALIVE_RESPONSE); | 1406 | msg.header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_SESSION_KEEPALIVE_RESPONSE); |
1407 | msg.nonce = msg_in->nonce; | ||
1353 | (void) send_with_session(n, | 1408 | (void) send_with_session(n, |
1354 | (const void *) &m, sizeof (m), | 1409 | (const void *) &msg, sizeof (struct SessionKeepAliveMessage), |
1355 | UINT32_MAX /* priority */, | 1410 | UINT32_MAX /* priority */, |
1356 | GNUNET_TIME_UNIT_FOREVER_REL, GNUNET_YES, | 1411 | GNUNET_TIME_UNIT_FOREVER_REL, GNUNET_YES, |
1357 | NULL, NULL); | 1412 | NULL, NULL); |
@@ -1364,14 +1419,22 @@ GST_neighbours_keepalive (const struct GNUNET_PeerIdentity *neighbour) | |||
1364 | * plus calculated latency) to ATS. | 1419 | * plus calculated latency) to ATS. |
1365 | * | 1420 | * |
1366 | * @param neighbour neighbour to keep alive | 1421 | * @param neighbour neighbour to keep alive |
1422 | * @param m the message containing the keep alive response | ||
1367 | */ | 1423 | */ |
1368 | void | 1424 | void |
1369 | GST_neighbours_keepalive_response (const struct GNUNET_PeerIdentity *neighbour) | 1425 | GST_neighbours_keepalive_response (const struct GNUNET_PeerIdentity *neighbour, |
1426 | const struct GNUNET_MessageHeader *m) | ||
1370 | { | 1427 | { |
1371 | struct NeighbourMapEntry *n; | 1428 | struct NeighbourMapEntry *n; |
1429 | const struct SessionKeepAliveMessage *msg; | ||
1430 | struct GNUNET_TRANSPORT_PluginFunctions *papi; | ||
1372 | uint32_t latency; | 1431 | uint32_t latency; |
1373 | struct GNUNET_ATS_Information ats; | 1432 | struct GNUNET_ATS_Information ats; |
1374 | 1433 | ||
1434 | if (sizeof (struct SessionKeepAliveMessage) != ntohs (m->size)) | ||
1435 | return; | ||
1436 | |||
1437 | msg = (const struct SessionKeepAliveMessage *) m; | ||
1375 | if (NULL == (n = lookup_neighbour (neighbour))) | 1438 | if (NULL == (n = lookup_neighbour (neighbour))) |
1376 | { | 1439 | { |
1377 | GNUNET_STATISTICS_update (GST_stats, | 1440 | GNUNET_STATISTICS_update (GST_stats, |
@@ -1389,6 +1452,43 @@ GST_neighbours_keepalive_response (const struct GNUNET_PeerIdentity *neighbour) | |||
1389 | 1, GNUNET_NO); | 1452 | 1, GNUNET_NO); |
1390 | return; | 1453 | return; |
1391 | } | 1454 | } |
1455 | if (NULL == n->primary_address.address) | ||
1456 | { | ||
1457 | GNUNET_STATISTICS_update (GST_stats, | ||
1458 | gettext_noop | ||
1459 | ("# KEEPALIVE_RESPONSE messages discarded (address changed)"), | ||
1460 | 1, GNUNET_NO); | ||
1461 | return; | ||
1462 | } | ||
1463 | if (n->primary_address.keep_alive_nonce != ntohl (msg->nonce)) | ||
1464 | { | ||
1465 | GNUNET_STATISTICS_update (GST_stats, | ||
1466 | gettext_noop | ||
1467 | ("# KEEPALIVE_RESPONSE messages discarded (wrong nonce)"), | ||
1468 | 1, GNUNET_NO); | ||
1469 | return; | ||
1470 | } | ||
1471 | else | ||
1472 | { | ||
1473 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
1474 | "Received keep alive response from peer `%s' for session %p\n", | ||
1475 | GNUNET_i2s (&n->id), n->primary_address.session); | ||
1476 | |||
1477 | } | ||
1478 | |||
1479 | /* Update session timeout here */ | ||
1480 | if (NULL != (papi = GST_plugins_find (n->primary_address.address->transport_name))) | ||
1481 | { | ||
1482 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
1483 | "Updating session for peer `%s' for session %p\n", | ||
1484 | GNUNET_i2s (&n->id), n->primary_address.session); | ||
1485 | papi->update_session_timeout (papi->cls, &n->id, n->primary_address.session); | ||
1486 | } | ||
1487 | else | ||
1488 | { | ||
1489 | GNUNET_break (0); | ||
1490 | } | ||
1491 | |||
1392 | n->expect_latency_response = GNUNET_NO; | 1492 | n->expect_latency_response = GNUNET_NO; |
1393 | n->latency = GNUNET_TIME_absolute_get_duration (n->last_keep_alive_time); | 1493 | n->latency = GNUNET_TIME_absolute_get_duration (n->last_keep_alive_time); |
1394 | n->timeout = GNUNET_TIME_relative_to_absolute (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT); | 1494 | n->timeout = GNUNET_TIME_relative_to_absolute (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT); |
@@ -1404,10 +1504,8 @@ GST_neighbours_keepalive_response (const struct GNUNET_PeerIdentity *neighbour) | |||
1404 | else | 1504 | else |
1405 | latency = n->latency.rel_value_us; | 1505 | latency = n->latency.rel_value_us; |
1406 | ats.value = htonl (latency); | 1506 | ats.value = htonl (latency); |
1407 | GST_ats_update_metrics (&n->id, | 1507 | GST_ats_update_metrics (&n->id, n->primary_address.address, |
1408 | n->primary_address.address, | 1508 | n->primary_address.session, &ats, 1); |
1409 | n->primary_address.session, | ||
1410 | &ats, 1); | ||
1411 | } | 1509 | } |
1412 | 1510 | ||
1413 | 1511 | ||