diff options
author | Christian Grothoff <christian@grothoff.org> | 2015-02-03 16:11:15 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2015-02-03 16:11:15 +0000 |
commit | d9b68f30f930830b455eea95d0bc619553180136 (patch) | |
tree | ca3b084bac4c5b52a8b90f916b51d8ea9619510d /src | |
parent | f0b02e3444d7653f2c1dabab449825b80e390855 (diff) | |
download | gnunet-d9b68f30f930830b455eea95d0bc619553180136.tar.gz gnunet-d9b68f30f930830b455eea95d0bc619553180136.zip |
add internal API to enable telling ATS about 'failed' suggestions
Diffstat (limited to 'src')
-rw-r--r-- | src/transport/gnunet-service-transport.c | 11 | ||||
-rw-r--r-- | src/transport/gnunet-service-transport_ats.c | 117 | ||||
-rw-r--r-- | src/transport/gnunet-service-transport_ats.h | 19 | ||||
-rw-r--r-- | src/transport/gnunet-service-transport_validation.c | 35 |
4 files changed, 160 insertions, 22 deletions
diff --git a/src/transport/gnunet-service-transport.c b/src/transport/gnunet-service-transport.c index ef05739c5..e3bbf7167 100644 --- a/src/transport/gnunet-service-transport.c +++ b/src/transport/gnunet-service-transport.c | |||
@@ -831,6 +831,14 @@ ats_request_address_change (void *cls, | |||
831 | uint32_t bw_in = ntohl (bandwidth_in.value__); | 831 | uint32_t bw_in = ntohl (bandwidth_in.value__); |
832 | uint32_t bw_out = ntohl (bandwidth_out.value__); | 832 | uint32_t bw_out = ntohl (bandwidth_out.value__); |
833 | 833 | ||
834 | if (NULL == peer) | ||
835 | { | ||
836 | /* ATS service died, all suggestions become invalid! | ||
837 | (but we'll keep using the allocations for a little | ||
838 | while, to keep going while ATS restarts) */ | ||
839 | // FIXME: do something? | ||
840 | return; | ||
841 | } | ||
834 | /* ATS tells me to disconnect from peer */ | 842 | /* ATS tells me to disconnect from peer */ |
835 | if ((0 == bw_in) && (0 == bw_out)) | 843 | if ((0 == bw_in) && (0 == bw_out)) |
836 | { | 844 | { |
@@ -847,7 +855,8 @@ ats_request_address_change (void *cls, | |||
847 | GNUNET_NO); | 855 | GNUNET_NO); |
848 | GST_neighbours_switch_to_address (address, | 856 | GST_neighbours_switch_to_address (address, |
849 | session, | 857 | session, |
850 | bandwidth_in, bandwidth_out); | 858 | bandwidth_in, |
859 | bandwidth_out); | ||
851 | } | 860 | } |
852 | 861 | ||
853 | 862 | ||
diff --git a/src/transport/gnunet-service-transport_ats.c b/src/transport/gnunet-service-transport_ats.c index 0d61365d8..0b864f3fb 100644 --- a/src/transport/gnunet-service-transport_ats.c +++ b/src/transport/gnunet-service-transport_ats.c | |||
@@ -50,6 +50,29 @@ struct AddressInfo | |||
50 | * Record with ATS API for the address. | 50 | * Record with ATS API for the address. |
51 | */ | 51 | */ |
52 | struct GNUNET_ATS_AddressRecord *ar; | 52 | struct GNUNET_ATS_AddressRecord *ar; |
53 | |||
54 | /** | ||
55 | * Time until when this address is blocked and should thus not be | ||
56 | * made available to ATS (@e ar should be NULL until this time). | ||
57 | * Used when transport determines that for some reason it | ||
58 | * (temporarily) cannot use an address, even though it has been | ||
59 | * validated. | ||
60 | */ | ||
61 | struct GNUNET_TIME_Absolute blocked; | ||
62 | |||
63 | /** | ||
64 | * If an address is blocked as part of an exponential back-off, | ||
65 | * we track the current size of the backoff here. | ||
66 | */ | ||
67 | struct GNUNET_TIME_Relative back_off; | ||
68 | |||
69 | /** | ||
70 | * Task scheduled to unblock an ATS-blocked address at | ||
71 | * @e blocked time, or NULL if the address is not blocked | ||
72 | * (and thus @e ar is non-NULL). | ||
73 | */ | ||
74 | struct GNUNET_SCHEDULER_Task *unblock_task; | ||
75 | |||
53 | }; | 76 | }; |
54 | 77 | ||
55 | 78 | ||
@@ -220,6 +243,65 @@ GST_ats_is_known (const struct GNUNET_HELLO_Address *address, | |||
220 | 243 | ||
221 | 244 | ||
222 | /** | 245 | /** |
246 | * The blocking time for an address has expired, allow ATS to | ||
247 | * suggest it again. | ||
248 | * | ||
249 | * @param cls the `struct AddressInfo` of the address to unblock | ||
250 | * @param tc unused | ||
251 | */ | ||
252 | static void | ||
253 | unblock_address (void *cls, | ||
254 | const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
255 | { | ||
256 | struct AddressInfo *ai = cls; | ||
257 | |||
258 | ai->unblock_task = NULL; | ||
259 | ai->ar = GNUNET_ATS_address_add (GST_ats, | ||
260 | ai->address, | ||
261 | ai->session, | ||
262 | NULL, 0); | ||
263 | /* FIXME: should pass ATS information here! */ | ||
264 | } | ||
265 | |||
266 | |||
267 | /** | ||
268 | * Temporarily block a valid address for use by ATS for address | ||
269 | * suggestions. This function should be called if an address was | ||
270 | * suggested by ATS but failed to perform (i.e. failure to establish a | ||
271 | * session or to exchange the PING/PONG). | ||
272 | * | ||
273 | * @param address the address to block | ||
274 | * @param session the session (can be NULL) | ||
275 | */ | ||
276 | void | ||
277 | GST_ats_block_address (const struct GNUNET_HELLO_Address *address, | ||
278 | struct Session *session) | ||
279 | { | ||
280 | struct AddressInfo *ai; | ||
281 | |||
282 | ai = find_ai (address, session); | ||
283 | if (NULL == ai) | ||
284 | { | ||
285 | GNUNET_break (0); | ||
286 | return; | ||
287 | } | ||
288 | if (NULL == ai->ar) | ||
289 | { | ||
290 | /* already blocked, how did it get used!? */ | ||
291 | GNUNET_break (0); | ||
292 | return; | ||
293 | } | ||
294 | GNUNET_ATS_address_destroy (ai->ar); | ||
295 | ai->ar = NULL; | ||
296 | ai->back_off = GNUNET_TIME_STD_BACKOFF (ai->back_off); | ||
297 | ai->blocked = GNUNET_TIME_relative_to_absolute (ai->back_off); | ||
298 | ai->unblock_task = GNUNET_SCHEDULER_add_delayed (ai->back_off, | ||
299 | &unblock_address, | ||
300 | ai); | ||
301 | } | ||
302 | |||
303 | |||
304 | /** | ||
223 | * Notify ATS about the new address including the network this address is | 305 | * Notify ATS about the new address including the network this address is |
224 | * located in. | 306 | * located in. |
225 | * | 307 | * |
@@ -349,8 +431,9 @@ GST_ats_new_session (const struct GNUNET_HELLO_Address *address, | |||
349 | "Telling ATS about new session %p for peer %s\n", | 431 | "Telling ATS about new session %p for peer %s\n", |
350 | session, | 432 | session, |
351 | GNUNET_i2s (&address->peer)); | 433 | GNUNET_i2s (&address->peer)); |
352 | GNUNET_ATS_address_add_session (ai->ar, | 434 | if (NULL != ai->ar) |
353 | session); | 435 | GNUNET_ATS_address_add_session (ai->ar, |
436 | session); | ||
354 | } | 437 | } |
355 | 438 | ||
356 | 439 | ||
@@ -392,6 +475,11 @@ GST_ats_del_session (const struct GNUNET_HELLO_Address *address, | |||
392 | "Telling ATS to destroy session %p from peer %s\n", | 475 | "Telling ATS to destroy session %p from peer %s\n", |
393 | session, | 476 | session, |
394 | GNUNET_i2s (&address->peer)); | 477 | GNUNET_i2s (&address->peer)); |
478 | if (NULL == ai->ar) | ||
479 | { | ||
480 | GST_ats_expire_address (address); | ||
481 | return; | ||
482 | } | ||
395 | if (GNUNET_YES == | 483 | if (GNUNET_YES == |
396 | GNUNET_ATS_address_del_session (ai->ar, session)) | 484 | GNUNET_ATS_address_del_session (ai->ar, session)) |
397 | { | 485 | { |
@@ -444,8 +532,10 @@ GST_ats_update_metrics (const struct GNUNET_HELLO_Address *address, | |||
444 | session, | 532 | session, |
445 | ats, | 533 | ats, |
446 | ats_count); | 534 | ats_count); |
447 | GNUNET_ATS_address_update (ai->ar, | 535 | if (NULL != ai->ar) |
448 | ats_new, ats_count); | 536 | GNUNET_ATS_address_update (ai->ar, |
537 | ats_new, | ||
538 | ats_count); | ||
449 | GNUNET_free_non_null (ats_new); | 539 | GNUNET_free_non_null (ats_new); |
450 | } | 540 | } |
451 | 541 | ||
@@ -470,6 +560,7 @@ GST_ats_set_in_use (const struct GNUNET_HELLO_Address *address, | |||
470 | GNUNET_break (0); | 560 | GNUNET_break (0); |
471 | return; | 561 | return; |
472 | } | 562 | } |
563 | GNUNET_assert (NULL != ai->ar); | ||
473 | GNUNET_ATS_address_set_in_use (ai->ar, in_use); | 564 | GNUNET_ATS_address_set_in_use (ai->ar, in_use); |
474 | } | 565 | } |
475 | 566 | ||
@@ -503,7 +594,15 @@ GST_ats_expire_address (const struct GNUNET_HELLO_Address *address) | |||
503 | "Telling ATS to destroy address from peer %s\n", | 594 | "Telling ATS to destroy address from peer %s\n", |
504 | GNUNET_i2s (&address->peer)); | 595 | GNUNET_i2s (&address->peer)); |
505 | if (NULL != ai->ar) | 596 | if (NULL != ai->ar) |
597 | { | ||
506 | GNUNET_ATS_address_destroy (ai->ar); | 598 | GNUNET_ATS_address_destroy (ai->ar); |
599 | ai->ar = NULL; | ||
600 | } | ||
601 | if (NULL != ai->unblock_task) | ||
602 | { | ||
603 | GNUNET_SCHEDULER_cancel (ai->unblock_task); | ||
604 | ai->unblock_task = NULL; | ||
605 | } | ||
507 | GNUNET_HELLO_address_free (ai->address); | 606 | GNUNET_HELLO_address_free (ai->address); |
508 | GNUNET_free (ai); | 607 | GNUNET_free (ai); |
509 | } | 608 | } |
@@ -538,6 +637,16 @@ destroy_ai (void *cls, | |||
538 | GNUNET_CONTAINER_multipeermap_remove (p2a, | 637 | GNUNET_CONTAINER_multipeermap_remove (p2a, |
539 | key, | 638 | key, |
540 | ai)); | 639 | ai)); |
640 | if (NULL != ai->unblock_task) | ||
641 | { | ||
642 | GNUNET_SCHEDULER_cancel (ai->unblock_task); | ||
643 | ai->unblock_task = NULL; | ||
644 | } | ||
645 | if (NULL != ai->ar) | ||
646 | { | ||
647 | GNUNET_ATS_address_destroy (ai->ar); | ||
648 | ai->ar = NULL; | ||
649 | } | ||
541 | GNUNET_HELLO_address_free (ai->address); | 650 | GNUNET_HELLO_address_free (ai->address); |
542 | GNUNET_free (ai); | 651 | GNUNET_free (ai); |
543 | return GNUNET_OK; | 652 | return GNUNET_OK; |
diff --git a/src/transport/gnunet-service-transport_ats.h b/src/transport/gnunet-service-transport_ats.h index b203cc323..53c4caa68 100644 --- a/src/transport/gnunet-service-transport_ats.h +++ b/src/transport/gnunet-service-transport_ats.h | |||
@@ -26,10 +26,6 @@ | |||
26 | * - add API to give ATS feedback about an address that was | 26 | * - add API to give ATS feedback about an address that was |
27 | * suggested but did not work out (without fully 'deleting' | 27 | * suggested but did not work out (without fully 'deleting' |
28 | * it forever) | 28 | * it forever) |
29 | * - improve ATS API to take advantage of this new subsystem | ||
30 | * when calling ATS functions, make ATS API match this API | ||
31 | * more closely | ||
32 | * - combine with API to tell ATS about address "use" | ||
33 | */ | 29 | */ |
34 | #ifndef GNUNET_SERVICE_TRANSPORT_ATS_H | 30 | #ifndef GNUNET_SERVICE_TRANSPORT_ATS_H |
35 | #define GNUNET_SERVICE_TRANSPORT_ATS_H | 31 | #define GNUNET_SERVICE_TRANSPORT_ATS_H |
@@ -61,6 +57,21 @@ int | |||
61 | GST_ats_is_known (const struct GNUNET_HELLO_Address *address, | 57 | GST_ats_is_known (const struct GNUNET_HELLO_Address *address, |
62 | struct Session *session); | 58 | struct Session *session); |
63 | 59 | ||
60 | |||
61 | /** | ||
62 | * Temporarily block a valid address for use by ATS for address | ||
63 | * suggestions. This function should be called if an address was | ||
64 | * suggested by ATS but failed to perform (i.e. failure to establish a | ||
65 | * session or to exchange the PING/PONG). | ||
66 | * | ||
67 | * @param address the address to block | ||
68 | * @param session the session (can be NULL) | ||
69 | */ | ||
70 | void | ||
71 | GST_ats_block_address (const struct GNUNET_HELLO_Address *address, | ||
72 | struct Session *session); | ||
73 | |||
74 | |||
64 | /** | 75 | /** |
65 | * Notify ATS about the new address including the network this address is | 76 | * Notify ATS about the new address including the network this address is |
66 | * located in. | 77 | * located in. |
diff --git a/src/transport/gnunet-service-transport_validation.c b/src/transport/gnunet-service-transport_validation.c index f0b8d9466..fb2791eba 100644 --- a/src/transport/gnunet-service-transport_validation.c +++ b/src/transport/gnunet-service-transport_validation.c | |||
@@ -1519,21 +1519,30 @@ GST_validation_handle_hello (const struct GNUNET_MessageHeader *hello) | |||
1519 | memcmp (&GST_my_identity, | 1519 | memcmp (&GST_my_identity, |
1520 | &pid, | 1520 | &pid, |
1521 | sizeof (struct GNUNET_PeerIdentity))) | 1521 | sizeof (struct GNUNET_PeerIdentity))) |
1522 | { | ||
1523 | /* got our own HELLO, how boring */ | ||
1522 | return GNUNET_OK; | 1524 | return GNUNET_OK; |
1523 | /* Add peer identity without addresses to peerinfo service */ | 1525 | } |
1524 | h = GNUNET_HELLO_create (&pid.public_key, NULL, NULL, friend); | 1526 | if (GNUNET_NO == |
1525 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | 1527 | GNUNET_CONTAINER_multipeermap_contains (validation_map, |
1526 | _("Validation received new %s message for peer `%s' with size %u\n"), | 1528 | &pid)) |
1527 | "HELLO", | 1529 | { |
1528 | GNUNET_i2s (&pid), | 1530 | /* Add peer identity without addresses to peerinfo service */ |
1529 | ntohs (hello->size)); | 1531 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1530 | GNUNET_PEERINFO_add_peer (GST_peerinfo, h, NULL, NULL); | 1532 | "Adding HELLO without addresses for peer `%s'\n", |
1531 | 1533 | GNUNET_i2s (&pid)); | |
1532 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1534 | h = GNUNET_HELLO_create (&pid.public_key, NULL, NULL, friend); |
1533 | _("Adding `%s' without addresses for peer `%s'\n"), "HELLO", | 1535 | GNUNET_PEERINFO_add_peer (GST_peerinfo, h, NULL, NULL); |
1534 | GNUNET_i2s (&pid)); | ||
1535 | 1536 | ||
1536 | GNUNET_free (h); | 1537 | GNUNET_free (h); |
1538 | } | ||
1539 | else | ||
1540 | { | ||
1541 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
1542 | "Validation received HELLO message for peer `%s' with size %u, checking for new addresses\n", | ||
1543 | GNUNET_i2s (&pid), | ||
1544 | ntohs (hello->size)); | ||
1545 | } | ||
1537 | GNUNET_assert (NULL == | 1546 | GNUNET_assert (NULL == |
1538 | GNUNET_HELLO_iterate_addresses (hm, | 1547 | GNUNET_HELLO_iterate_addresses (hm, |
1539 | GNUNET_NO, | 1548 | GNUNET_NO, |