aboutsummaryrefslogtreecommitdiff
path: root/src/transport/gnunet-service-transport_neighbours.c
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2015-02-03 13:14:07 +0000
committerChristian Grothoff <christian@grothoff.org>2015-02-03 13:14:07 +0000
commit764e5806e7b905d7c2babef0eced934cc6c48f1e (patch)
treeb6c52889c20f9fd2ce6fe46b2e69a15a64109c2e /src/transport/gnunet-service-transport_neighbours.c
parentbee9a02b062e1869f2a0f6f6e6b0739f7cb2174d (diff)
downloadgnunet-764e5806e7b905d7c2babef0eced934cc6c48f1e.tar.gz
gnunet-764e5806e7b905d7c2babef0eced934cc6c48f1e.zip
when ATS suggests an address that neighbours does not have a peer for, do not ignore it, setup the neighbour record instead
Diffstat (limited to 'src/transport/gnunet-service-transport_neighbours.c')
-rw-r--r--src/transport/gnunet-service-transport_neighbours.c241
1 files changed, 118 insertions, 123 deletions
diff --git a/src/transport/gnunet-service-transport_neighbours.c b/src/transport/gnunet-service-transport_neighbours.c
index 7df23c2c2..1ecf71517 100644
--- a/src/transport/gnunet-service-transport_neighbours.c
+++ b/src/transport/gnunet-service-transport_neighbours.c
@@ -2178,7 +2178,6 @@ try_connect_bl_check_cont (void *cls,
2178} 2178}
2179 2179
2180 2180
2181
2182/** 2181/**
2183 * Try to create a connection to the given target (eventually). 2182 * Try to create a connection to the given target (eventually).
2184 * 2183 *
@@ -2248,10 +2247,15 @@ GST_neighbours_try_connect (const struct GNUNET_PeerIdentity *target)
2248 2247
2249 /* Do blacklist check if connecting to this peer is allowed */ 2248 /* Do blacklist check if connecting to this peer is allowed */
2250 blc_ctx = GNUNET_new (struct BlacklistCheckSwitchContext); 2249 blc_ctx = GNUNET_new (struct BlacklistCheckSwitchContext);
2251 GNUNET_CONTAINER_DLL_insert (pending_bc_head, pending_bc_tail, blc_ctx); 2250 GNUNET_CONTAINER_DLL_insert (pending_bc_head,
2251 pending_bc_tail,
2252 blc_ctx);
2252 2253
2253 if (NULL != (blc = GST_blacklist_test_allowed (target, NULL, 2254 if (NULL !=
2254 &try_connect_bl_check_cont, blc_ctx))) 2255 (blc = GST_blacklist_test_allowed (target,
2256 NULL,
2257 &try_connect_bl_check_cont,
2258 blc_ctx)))
2255 { 2259 {
2256 blc_ctx->blc = blc; 2260 blc_ctx->blc = blc;
2257 } 2261 }
@@ -2391,9 +2395,66 @@ GST_neighbours_handle_session_syn (const struct GNUNET_MessageHeader *message,
2391 2395
2392 2396
2393/** 2397/**
2394 * We've been asked to switch addresses, and just now 2398 * Check if the given @a address is the same that we are already
2395 * got the result from the blacklist check to see if this 2399 * using for the respective neighbour. If so, update the bandwidth
2396 * is allowed. 2400 * assignment and possibly the session and return #GNUNET_OK.
2401 * If the new address is different from what the neighbour is
2402 * using right now, return #GNUNET_NO.
2403 *
2404 * @param address address of the other peer,
2405 * @param session session to use or NULL if transport should initiate a session
2406 * @param bandwidth_in inbound quota to be used when connection is up,
2407 * 0 to disconnect from peer
2408 * @param bandwidth_out outbound quota to be used when connection is up,
2409 * 0 to disconnect from peer
2410 * @return #GNUNET_OK if we were able to just update the bandwidth and session,
2411 * #GNUNET_NO if more extensive changes are required (address changed)
2412 */
2413static int
2414try_run_fast_ats_update (const struct GNUNET_HELLO_Address *address,
2415 struct Session *session,
2416 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in,
2417 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out)
2418{
2419 struct NeighbourMapEntry *n;
2420 int connected;
2421
2422 n = lookup_neighbour (&address->peer);
2423 if ( (NULL == n) ||
2424 (NULL == n->primary_address.address) ||
2425 (0 != GNUNET_HELLO_address_cmp (address,
2426 n->primary_address.address)) )
2427 return GNUNET_NO;
2428 /* We are not really switching addresses, but merely adjusting
2429 session and/or bandwidth, can do fast ATS update! */
2430 if (session != n->primary_address.session)
2431 {
2432 /* switch to a different session, but keeping same address; could
2433 happen if there is a 2nd inbound connection */
2434 connected = GNUNET_TRANSPORT_is_connected (n->state);
2435 if (GNUNET_YES == connected)
2436 GST_ats_set_in_use (n->primary_address.address,
2437 n->primary_address.session,
2438 GNUNET_NO);
2439 n->primary_address.session = session;
2440 if (GNUNET_YES == connected)
2441 GST_ats_set_in_use (n->primary_address.address,
2442 n->primary_address.session,
2443 GNUNET_YES);
2444 }
2445 n->primary_address.bandwidth_in = bandwidth_in;
2446 n->primary_address.bandwidth_out = bandwidth_out;
2447 GST_neighbours_set_incoming_quota (&address->peer,
2448 bandwidth_in);
2449 send_outbound_quota (&address->peer,
2450 bandwidth_out);
2451 return GNUNET_OK;
2452}
2453
2454
2455/**
2456 * We've been asked to switch addresses, and just now got the result
2457 * from the blacklist check to see if this is allowed.
2397 * 2458 *
2398 * @param cls the `struct BlacklistCheckSwitchContext` with 2459 * @param cls the `struct BlacklistCheckSwitchContext` with
2399 * the information about the future address 2460 * the information about the future address
@@ -2410,62 +2471,28 @@ switch_address_bl_check_cont (void *cls,
2410 struct GNUNET_TRANSPORT_PluginFunctions *papi; 2471 struct GNUNET_TRANSPORT_PluginFunctions *papi;
2411 struct NeighbourMapEntry *n; 2472 struct NeighbourMapEntry *n;
2412 2473
2413 papi = GST_plugins_find (blc_ctx->address->transport_name); 2474 if (result == GNUNET_NO)
2414
2415 if ( (NULL == (n = lookup_neighbour (peer))) ||
2416 (result == GNUNET_NO) ||
2417 (NULL == papi) )
2418 { 2475 {
2419 if (NULL == n) 2476 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2420 { 2477 "Blacklist denied to switch to suggested address `%s' session %p for peer `%s'\n",
2421 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 2478 GST_plugins_a2s (blc_ctx->address),
2422 "Peer %s is unknown, suggestion ignored\n", 2479 blc_ctx->session,
2423 GNUNET_i2s (peer)); 2480 GNUNET_i2s (&blc_ctx->address->peer));
2424 GNUNET_STATISTICS_update (GST_stats, 2481 GNUNET_STATISTICS_update (GST_stats,
2425 "# ATS suggestions ignored (neighbour unknown)", 2482 "# ATS suggestions ignored (blacklist denied)",
2426 1, 2483 1,
2427 GNUNET_NO); 2484 GNUNET_NO);
2428 }
2429 if (result == GNUNET_NO)
2430 {
2431 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2432 "Blacklist denied to switch to suggested address `%s' session %p for peer `%s'\n",
2433 GST_plugins_a2s (blc_ctx->address),
2434 blc_ctx->session,
2435 GNUNET_i2s (&blc_ctx->address->peer));
2436 GNUNET_STATISTICS_update (GST_stats,
2437 "# ATS suggestions ignored (blacklist denied)",
2438 1,
2439 GNUNET_NO);
2440 }
2441 if (NULL == papi)
2442 {
2443 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2444 "Plugin `%s' for suggested address `%s' session %p for peer `%s' is not available\n",
2445 blc_ctx->address->transport_name,
2446 GST_plugins_a2s (blc_ctx->address),
2447 blc_ctx->session,
2448 GNUNET_i2s (&blc_ctx->address->peer));
2449 GNUNET_STATISTICS_update (GST_stats,
2450 "# ATS suggestions ignored (plugin unknown)",
2451 1,
2452 GNUNET_NO);
2453 }
2454
2455 /* This address is blacklisted, delete session */
2456 /* FIXME: tell plugin to force killing session here and now! */ 2485 /* FIXME: tell plugin to force killing session here and now! */
2457 2486 /* FIXME: Let ATS know that the suggested address did not work! */
2458 /* Remove blacklist check and clean up */ 2487 goto cleanup;
2459 GNUNET_CONTAINER_DLL_remove (pending_bc_head,
2460 pending_bc_tail,
2461 blc_ctx);
2462 GNUNET_HELLO_address_free (blc_ctx->address);
2463 GNUNET_free (blc_ctx);
2464 return;
2465 } 2488 }
2466 2489
2490 papi = GST_plugins_find (blc_ctx->address->transport_name);
2491 GNUNET_assert (NULL != papi);
2492
2467 if (NULL == blc_ctx->session) 2493 if (NULL == blc_ctx->session)
2468 { 2494 {
2495 /* need to create a session, ATS only gave us an address */
2469 blc_ctx->session = papi->get_session (papi->cls, 2496 blc_ctx->session = papi->get_session (papi->cls,
2470 blc_ctx->address); 2497 blc_ctx->address);
2471 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 2498 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
@@ -2476,10 +2503,10 @@ switch_address_bl_check_cont (void *cls,
2476 if (NULL != blc_ctx->session) 2503 if (NULL != blc_ctx->session)
2477 GST_ats_new_session (blc_ctx->address, 2504 GST_ats_new_session (blc_ctx->address,
2478 blc_ctx->session); 2505 blc_ctx->session);
2479
2480 } 2506 }
2481 if (NULL == blc_ctx->session) 2507 if (NULL == blc_ctx->session)
2482 { 2508 {
2509 /* session creation failed, bad!, fail! */
2483 GNUNET_STATISTICS_update (GST_stats, 2510 GNUNET_STATISTICS_update (GST_stats,
2484 "# ATS suggestions ignored (failed to create session)", 2511 "# ATS suggestions ignored (failed to create session)",
2485 1, 2512 1,
@@ -2489,47 +2516,25 @@ switch_address_bl_check_cont (void *cls,
2489 "Failed to obtain new session for peer `%s' and address '%s'\n", 2516 "Failed to obtain new session for peer `%s' and address '%s'\n",
2490 GNUNET_i2s (&blc_ctx->address->peer), 2517 GNUNET_i2s (&blc_ctx->address->peer),
2491 GST_plugins_a2s (blc_ctx->address)); 2518 GST_plugins_a2s (blc_ctx->address));
2492 /* FIXME: Delete address in ATS!? */ 2519 /* FIXME: Let ATS know that the suggested address did not work! */
2493 GNUNET_CONTAINER_DLL_remove (pending_bc_head, 2520 goto cleanup;
2494 pending_bc_tail,
2495 blc_ctx);
2496 GNUNET_HELLO_address_free (blc_ctx->address);
2497 GNUNET_free (blc_ctx);
2498 return;
2499 } 2521 }
2500 2522
2501 if ( (NULL != n->primary_address.address) && 2523 /* We did this check already before going into blacklist, but
2502 (0 == GNUNET_HELLO_address_cmp (blc_ctx->address, 2524 it is theoretically possible that the situation changed in
2503 n->primary_address.address)) ) 2525 the meantime, hence we check again here */
2504 { 2526 if (GNUNET_OK ==
2505 if (blc_ctx->session == n->primary_address.session) 2527 try_run_fast_ats_update (blc_ctx->address,
2506 { 2528 blc_ctx->session,
2507 // FIXME: handle this before blacklist check! 2529 blc_ctx->bandwidth_in,
2508 /* This address is already primary, update only quotas */ 2530 blc_ctx->bandwidth_out))
2509 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 2531 goto cleanup; /* was just a minor update, we're done */
2510 "Updating quota for peer `%s' address `%s' session %p\n",
2511 GNUNET_i2s (&blc_ctx->address->peer),
2512 GST_plugins_a2s (blc_ctx->address),
2513 blc_ctx->session);
2514 set_primary_address (n,
2515 blc_ctx->address,
2516 blc_ctx->session,
2517 blc_ctx->bandwidth_in,
2518 blc_ctx->bandwidth_out,
2519 GNUNET_NO);
2520 2532
2521 GNUNET_CONTAINER_DLL_remove (pending_bc_head, 2533 /* check if we also need to setup the neighbour entry */
2522 pending_bc_tail, 2534 if (NULL == (n = lookup_neighbour (peer)))
2523 blc_ctx); 2535 {
2524 GNUNET_HELLO_address_free (blc_ctx->address); 2536 n = setup_neighbour (peer);
2525 GNUNET_free (blc_ctx); 2537 n->state = GNUNET_TRANSPORT_PS_INIT_ATS;
2526 return;
2527 }
2528 // FIXME: is this really OK?
2529 GNUNET_STATISTICS_update (GST_stats,
2530 "# ATS suggestion oddity (address match, session missmatch)",
2531 1,
2532 GNUNET_NO);
2533 } 2538 }
2534 2539
2535 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 2540 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
@@ -2553,7 +2558,7 @@ switch_address_bl_check_cont (void *cls,
2553 blc_ctx->bandwidth_in, 2558 blc_ctx->bandwidth_in,
2554 blc_ctx->bandwidth_out, 2559 blc_ctx->bandwidth_out,
2555 GNUNET_NO); 2560 GNUNET_NO);
2556 if ( (ACK_SEND_SYN_ACK == n->ack_state) ) 2561 if (ACK_SEND_SYN_ACK == n->ack_state)
2557 { 2562 {
2558 /* Send pending SYN_ACK message */ 2563 /* Send pending SYN_ACK message */
2559 n->ack_state = ACK_SEND_ACK; 2564 n->ack_state = ACK_SEND_ACK;
@@ -2731,7 +2736,7 @@ switch_address_bl_check_cont (void *cls,
2731 GNUNET_break (0); 2736 GNUNET_break (0);
2732 break; 2737 break;
2733 } 2738 }
2734 2739 cleanup:
2735 GNUNET_CONTAINER_DLL_remove (pending_bc_head, 2740 GNUNET_CONTAINER_DLL_remove (pending_bc_head,
2736 pending_bc_tail, 2741 pending_bc_tail,
2737 blc_ctx); 2742 blc_ctx);
@@ -2759,7 +2764,6 @@ GST_neighbours_switch_to_address (const struct GNUNET_HELLO_Address *address,
2759 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in, 2764 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in,
2760 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out) 2765 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out)
2761{ 2766{
2762 struct NeighbourMapEntry *n;
2763 struct GST_BlacklistCheck *blc; 2767 struct GST_BlacklistCheck *blc;
2764 struct BlacklistCheckSwitchContext *blc_ctx; 2768 struct BlacklistCheckSwitchContext *blc_ctx;
2765 2769
@@ -2767,17 +2771,12 @@ GST_neighbours_switch_to_address (const struct GNUNET_HELLO_Address *address,
2767 "ATS has decided on an address for peer %s\n", 2771 "ATS has decided on an address for peer %s\n",
2768 GNUNET_i2s (&address->peer)); 2772 GNUNET_i2s (&address->peer));
2769 GNUNET_assert (NULL != address->transport_name); 2773 GNUNET_assert (NULL != address->transport_name);
2770 if (NULL == (n = lookup_neighbour (&address->peer))) 2774 if (GNUNET_OK ==
2771 { 2775 try_run_fast_ats_update (address,
2772 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 2776 session,
2773 "Peer %s is unknown, suggestion ignored\n", 2777 bandwidth_in,
2774 GNUNET_i2s (&address->peer)); 2778 bandwidth_out))
2775 GNUNET_STATISTICS_update (GST_stats,
2776 "# ATS suggestions ignored (neighbour unknown)",
2777 1,
2778 GNUNET_NO);
2779 return; 2779 return;
2780 }
2781 2780
2782 /* Check if plugin is available */ 2781 /* Check if plugin is available */
2783 if (NULL == (GST_plugins_find (address->transport_name))) 2782 if (NULL == (GST_plugins_find (address->transport_name)))
@@ -2796,18 +2795,12 @@ GST_neighbours_switch_to_address (const struct GNUNET_HELLO_Address *address,
2796 } 2795 }
2797 2796
2798 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 2797 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2799 "ATS suggests %s address '%s' session %p for " 2798 "ATS suggests %s address '%s' for peer `%s'\n",
2800 "peer `%s' in state %s/%s \n",
2801 GNUNET_HELLO_address_check_option (address, 2799 GNUNET_HELLO_address_check_option (address,
2802 GNUNET_HELLO_ADDRESS_INFO_INBOUND) ? "inbound" : "outbound", 2800 GNUNET_HELLO_ADDRESS_INFO_INBOUND)
2801 ? "inbound" : "outbound",
2803 GST_plugins_a2s (address), 2802 GST_plugins_a2s (address),
2804 session, 2803 GNUNET_i2s (&address->peer));
2805 GNUNET_i2s (&address->peer),
2806 GNUNET_TRANSPORT_ps2s (n->state),
2807 print_ack_state (n->ack_state));
2808
2809 // FIXME: definitively do NOT do this if the
2810 // suggested address did not change!!!
2811 2804
2812 /* Perform blacklist check */ 2805 /* Perform blacklist check */
2813 blc_ctx = GNUNET_new (struct BlacklistCheckSwitchContext); 2806 blc_ctx = GNUNET_new (struct BlacklistCheckSwitchContext);
@@ -2897,7 +2890,7 @@ send_utilization_data (void *cls,
2897 n->util_payload_bytes_sent = 0; 2890 n->util_payload_bytes_sent = 0;
2898 n->util_total_bytes_recv = 0; 2891 n->util_total_bytes_recv = 0;
2899 n->util_total_bytes_sent = 0; 2892 n->util_total_bytes_sent = 0;
2900 n->last_util_transmission = GNUNET_TIME_absolute_get(); 2893 n->last_util_transmission = GNUNET_TIME_absolute_get ();
2901 return GNUNET_OK; 2894 return GNUNET_OK;
2902} 2895}
2903 2896
@@ -2933,7 +2926,7 @@ GST_neighbours_notify_data_recv (const struct GNUNET_HELLO_Address *address,
2933 n = lookup_neighbour (&address->peer); 2926 n = lookup_neighbour (&address->peer);
2934 if (NULL == n) 2927 if (NULL == n)
2935 return; 2928 return;
2936 n->util_total_bytes_recv += ntohs(message->size); 2929 n->util_total_bytes_recv += ntohs (message->size);
2937} 2930}
2938 2931
2939 2932
@@ -2947,7 +2940,7 @@ GST_neighbours_notify_payload_recv (const struct GNUNET_HELLO_Address *address,
2947 n = lookup_neighbour (&address->peer); 2940 n = lookup_neighbour (&address->peer);
2948 if (NULL == n) 2941 if (NULL == n)
2949 return; 2942 return;
2950 n->util_payload_bytes_recv += ntohs(message->size); 2943 n->util_payload_bytes_recv += ntohs (message->size);
2951} 2944}
2952 2945
2953 2946
@@ -2972,6 +2965,7 @@ GST_neighbours_notify_payload_sent (const struct GNUNET_PeerIdentity *peer,
2972 size_t size) 2965 size_t size)
2973{ 2966{
2974 struct NeighbourMapEntry *n; 2967 struct NeighbourMapEntry *n;
2968
2975 n = lookup_neighbour (peer); 2969 n = lookup_neighbour (peer);
2976 if (NULL == n) 2970 if (NULL == n)
2977 return; 2971 return;
@@ -3850,7 +3844,8 @@ GST_neighbours_start (unsigned int max_fds)
3850{ 3844{
3851 neighbours = GNUNET_CONTAINER_multipeermap_create (NEIGHBOUR_TABLE_SIZE, GNUNET_NO); 3845 neighbours = GNUNET_CONTAINER_multipeermap_create (NEIGHBOUR_TABLE_SIZE, GNUNET_NO);
3852 util_transmission_tk = GNUNET_SCHEDULER_add_delayed (UTIL_TRANSMISSION_INTERVAL, 3846 util_transmission_tk = GNUNET_SCHEDULER_add_delayed (UTIL_TRANSMISSION_INTERVAL,
3853 utilization_transmission, NULL); 3847 &utilization_transmission,
3848 NULL);
3854} 3849}
3855 3850
3856 3851