aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2015-02-03 16:11:15 +0000
committerChristian Grothoff <christian@grothoff.org>2015-02-03 16:11:15 +0000
commitd9b68f30f930830b455eea95d0bc619553180136 (patch)
treeca3b084bac4c5b52a8b90f916b51d8ea9619510d /src
parentf0b02e3444d7653f2c1dabab449825b80e390855 (diff)
downloadgnunet-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.c11
-rw-r--r--src/transport/gnunet-service-transport_ats.c117
-rw-r--r--src/transport/gnunet-service-transport_ats.h19
-rw-r--r--src/transport/gnunet-service-transport_validation.c35
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 */
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;
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
61GST_ats_is_known (const struct GNUNET_HELLO_Address *address, 57GST_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 */
70void
71GST_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,