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/transport/gnunet-service-transport_ats.c | |
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/transport/gnunet-service-transport_ats.c')
-rw-r--r-- | src/transport/gnunet-service-transport_ats.c | 117 |
1 files changed, 113 insertions, 4 deletions
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; |