aboutsummaryrefslogtreecommitdiff
path: root/src/transport/gnunet-service-transport_ats.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/transport/gnunet-service-transport_ats.c')
-rw-r--r--src/transport/gnunet-service-transport_ats.c117
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 */
252static void
253unblock_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 */
276void
277GST_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;