Beispiel #1
0
static void
check (void *cls, char *const *args, const char *cfgfile,
       const  struct GNUNET_CONFIGURATION_Handle *cfg)
{
  unsigned int c = 0;
  unsigned int c2 = 0;
  unsigned int ca = 0;
  int update = GNUNET_NO;
  int range = GNUNET_NO;
  int res;

#if !HAVE_LIBGLPK
  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "GLPK not installed!");
  ret = 1;
  return;
#endif

  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Setting up %u peers with %u addresses per peer\n", peers, addresses);

  mlp = GAS_mlp_init (cfg, NULL, MLP_MAX_EXEC_DURATION, MLP_MAX_ITERATIONS);
  if (NULL == mlp)
  {
    GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Failed to init MLP\n");
    ret = 1;
    if (GNUNET_SCHEDULER_NO_TASK != shutdown_task)
      GNUNET_SCHEDULER_cancel(shutdown_task);
    shutdown_task = GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);
  }

  if (peers == 0)
    peers = DEF_PEERS;
  if (addresses == 0)
    addresses = DEF_ADDRESSES_PER_PEER;

  p = GNUNET_malloc (peers * sizeof (struct ATS_Peer));
  a = GNUNET_malloc (peers * addresses * sizeof (struct ATS_Address));

  amap = GNUNET_CONTAINER_multihashmap_create(addresses * peers, GNUNET_NO);

  mlp->auto_solve = GNUNET_NO;
  if (start == 0)
      start = 0;
  if (end == 0)
      end = -1;
  if ((start != -1) && (end != -1))
  {
    GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Solving problem starting from %u to %u\n", start , end);
    range = GNUNET_YES;
  }
  else
    GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Solving problem for %u peers\n", peers);

  if ((update_percentage >= 0) && (update_percentage <= 100))
  {
    update = GNUNET_YES;
    GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Benchmarking with existing presolution and %u%% updated addresses\n", update_percentage);
  }
  else if ((update_percentage > 100) && (update_percentage != UINT_MAX))
  {
    GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Invalid percentage: %u\n", update_percentage);
    ret = 1;
    return;
  }

  for (c=0; c < peers; c++)
  {
    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Setting up peer %u\n", c);
    GNUNET_CRYPTO_hash_create_random(GNUNET_CRYPTO_QUALITY_NONCE, &p[c].id.hashPubKey);

    for (c2=0; c2 < addresses; c2++)
    {
      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Setting up address %u for peer %u\n", c2, c);
      /* Setting required information */
      a[ca].mlp_information = NULL;
      a[ca].prev = NULL;
      a[ca].next = NULL;

      /* Setting address */
      a[ca].peer = p[c].id;
      a[ca].plugin = GNUNET_strdup("test");
      a[ca].atsp_network_type = GNUNET_ATS_NET_LOOPBACK;

      a[ca].ats = GNUNET_malloc (DEF_ATS_VALUES * sizeof (struct GNUNET_ATS_Information));
      a[ca].ats[0].type = GNUNET_ATS_QUALITY_NET_DELAY;
      a[ca].ats[0].value = GNUNET_CRYPTO_random_u32(GNUNET_CRYPTO_QUALITY_WEAK, DEF_ATS_MAX_DELAY);
      a[ca].ats[1].type = GNUNET_ATS_QUALITY_NET_DISTANCE;
      a[ca].ats[1].value = GNUNET_CRYPTO_random_u32(GNUNET_CRYPTO_QUALITY_WEAK, DEF_ATS_MAX_DISTANCE);
      a[ca].ats_count = 2;
      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Setting up address %u\n", ca);
      GNUNET_CONTAINER_multihashmap_put (amap, &a[ca].peer.hashPubKey, &a[ca], GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
      GAS_mlp_address_update(mlp, amap, &a[ca]);
      ca++;
    }

    GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Problem contains %u peers and %u adresses\n", mlp->c_p, mlp->addr_in_problem);

    if (((GNUNET_YES == range) && (((start >= 0) && ((c+1) >= start)) && (c <= end))) || ((c+1) == peers))
    {
      GNUNET_assert ((c+1) == mlp->c_p);
      GNUNET_assert ((c+1) * addresses == mlp->addr_in_problem);

      /* Solving the problem */
      struct GAS_MLP_SolutionContext ctx;

      res = GAS_mlp_solve_problem(mlp, &ctx);

      if (GNUNET_NO == update)
      {
        if (GNUNET_OK == res)
        {
          GNUNET_assert (GNUNET_OK == ctx.lp_result);
          GNUNET_assert (GNUNET_OK == ctx.mlp_result);
          if (GNUNET_YES == numeric)
            printf ("%u;%u;%llu;%llu\n",mlp->c_p, mlp->addr_in_problem, (unsigned long long) ctx.lp_duration.rel_value, (unsigned long long) ctx.mlp_duration.rel_value);
          else
            GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Problem solved for %u peers with %u address successfully (LP: %llu ms / MLP: %llu ms)\n",
                mlp->c_p, mlp->addr_in_problem, ctx.lp_duration.rel_value, ctx.mlp_duration.rel_value);
        }
        else
          GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Solving problem with %u peers and %u addresses failed\n", c, c2);
      }
      else
      {
        struct GAS_MLP_SolutionContext uctx;
        /* Update addresses */
        update_addresses (a, (c+1) * c2, update_percentage);

        /* Solve again */
        res = GAS_mlp_solve_problem(mlp, &uctx);

        if (GNUNET_OK == res)
        {
          GNUNET_assert (GNUNET_OK == uctx.lp_result);
          GNUNET_assert (GNUNET_OK == uctx.mlp_result);
          if (GNUNET_YES == numeric)
            printf ("%u;%u;%llu;%llu;%llu;%llu\n",mlp->c_p, mlp->addr_in_problem,
                (unsigned long long) ctx.lp_duration.rel_value, (unsigned long long) ctx.mlp_duration.rel_value,
                (unsigned long long) uctx.lp_duration.rel_value, (unsigned long long) uctx.mlp_duration.rel_value);
          else
            GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Updated problem solved for %u peers with %u address successfully (Initial: LP/MLP: %llu/%llu ms, Update: %llu/%llu ms)\n",
                mlp->c_p, mlp->addr_in_problem,
                (unsigned long long) ctx.lp_duration.rel_value, (unsigned long long) ctx.mlp_duration.rel_value,
                (unsigned long long) uctx.lp_duration.rel_value, (unsigned long long) uctx.mlp_duration.rel_value);
        }
        else
          GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Solving updated problem with %u peers and %u addresses failed\n", c, c2);
      }
    }
  }

  if (GNUNET_SCHEDULER_NO_TASK != shutdown_task)
    GNUNET_SCHEDULER_cancel(shutdown_task);
  shutdown_task = GNUNET_SCHEDULER_add_now (&do_shutdown, NULL);

}
static void
check (void *cls, char *const *args, const char *cfgfile,
       const struct GNUNET_CONFIGURATION_Handle *cfg)
{
#if !HAVE_LIBGLPK
  GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "GLPK not installed!");
  ret = 1;
  return;
#endif
  struct ATS_Address addr[10];
  struct ATS_PreferedAddress *res[10];
  struct MLP_information *mlpi;
  struct GAS_MLP_SolutionContext ctx;

  stats = GNUNET_STATISTICS_create("ats", cfg);

  addresses = GNUNET_CONTAINER_multihashmap_create (10);

  mlp = GAS_mlp_init (cfg, NULL, MLP_MAX_EXEC_DURATION, MLP_MAX_ITERATIONS);
  mlp->auto_solve = GNUNET_NO;

  struct GNUNET_PeerIdentity p[10];

  /* Creating peer 1 */
  GNUNET_CRYPTO_hash_create_random(GNUNET_CRYPTO_QUALITY_WEAK, &p[0].hashPubKey);

  /* Creating peer 1 address 1 */
  addr[0].peer.hashPubKey = p[0].hashPubKey;
  struct GNUNET_ATS_Information a1_ats[3];
  set_ats (&a1_ats[0], GNUNET_ATS_QUALITY_NET_DISTANCE, 1);
  set_ats (&a1_ats[1], GNUNET_ATS_QUALITY_NET_DELAY, 0);
  set_ats (&a1_ats[2], GNUNET_ATS_ARRAY_TERMINATOR, 0);
  create_address (&addr[0], "dummy", 3, &a1_ats[0]);
  addr[0].atsp_network_type = GNUNET_ATS_NET_LAN;

  GNUNET_CONTAINER_multihashmap_put(addresses, &addr[0].peer.hashPubKey, &addr[0], GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);

  /* Add peer 1 address 1 */
  GAS_mlp_address_update (mlp, addresses, &addr[0]);
  mlpi = addr[0].mlp_information;

  GNUNET_assert (mlp != NULL);
  GNUNET_assert (mlp->addr_in_problem == 1);

  /* Update an peer 1 address 1  */
  set_ats (&a1_ats[1], GNUNET_ATS_QUALITY_NET_DELAY, 20);
  GAS_mlp_address_update (mlp, addresses, &addr[0]);
  GNUNET_assert (mlp->addr_in_problem == 1);


  /* Update an peer 1 address 1  */
  set_ats (&a1_ats[1], GNUNET_ATS_QUALITY_NET_DELAY, 10);
  GAS_mlp_address_update (mlp, addresses, &addr[0]);
  GNUNET_assert (mlp->addr_in_problem == 1);

  /* Update an peer 1 address 1  */
  set_ats (&a1_ats[1], GNUNET_ATS_QUALITY_NET_DELAY, 10);
  GAS_mlp_address_update (mlp, addresses, &addr[0]);
  GNUNET_assert (mlp->addr_in_problem == 1);

  /* Update an peer 1 address 1  */
  set_ats (&a1_ats[1], GNUNET_ATS_QUALITY_NET_DELAY, 30);
  GAS_mlp_address_update (mlp, addresses, &addr[0]);
  GNUNET_assert (mlp->addr_in_problem == 1);


  GNUNET_assert (GNUNET_OK == GAS_mlp_solve_problem(mlp, &ctx));
  GNUNET_assert (GNUNET_OK == ctx.lp_result);
  GNUNET_assert (GNUNET_OK == ctx.mlp_result);

  res[0] = GAS_mlp_get_preferred_address(mlp, addresses, &p[0]);
  GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Preferred address `%s' outbound bandwidth: %u Bps\n",res[0]->address->plugin, res[0]->bandwidth_out);
  GNUNET_free (res[0]);

  /* Delete an address */
  GNUNET_CONTAINER_multihashmap_remove (addresses, &addr[0].peer.hashPubKey, &addr[0]);
  GAS_mlp_address_delete (mlp, addresses, &addr[0]);

  GNUNET_assert (mlp->addr_in_problem == 0);

  GAS_mlp_done (mlp);

  GNUNET_free (addr[0].plugin);
  GNUNET_CONTAINER_multihashmap_destroy (addresses);
  GNUNET_STATISTICS_destroy(stats, GNUNET_NO);

  ret = 0;
  return;
}
/**
 * Initialize address subsystem.
 *
 * @param cfg configuration to use
 * @param stats the statistics handle to use
 */
void
GAS_addresses_init (const struct GNUNET_CONFIGURATION_Handle *cfg,
                    const struct GNUNET_STATISTICS_Handle *stats)
{
  int mode;

  char *quota_wan_in_str;
  char *quota_wan_out_str;

  running = GNUNET_NO;

  addresses = GNUNET_CONTAINER_multihashmap_create (128);
  GNUNET_assert (NULL != addresses);

  if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_string(cfg, "ats", "WAN_QUOTA_IN", &quota_wan_in_str))
  {
    if (0 == strcmp(quota_wan_in_str, "unlimited") ||
        (GNUNET_SYSERR == GNUNET_STRINGS_fancy_size_to_bytes (quota_wan_in_str, &wan_quota_in)))
      wan_quota_in = (UINT32_MAX) /10;

    GNUNET_free (quota_wan_in_str);
    quota_wan_in_str = NULL;
  }
  else
  {
    wan_quota_in = (UINT32_MAX) /10;
  }

  if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_string(cfg, "ats", "WAN_QUOTA_OUT", &quota_wan_out_str))
  {
    if (0 == strcmp(quota_wan_out_str, "unlimited") ||
        (GNUNET_SYSERR == GNUNET_STRINGS_fancy_size_to_bytes (quota_wan_out_str, &wan_quota_out)))
      wan_quota_out = (UINT32_MAX) /10;

    GNUNET_free (quota_wan_out_str);
    quota_wan_out_str = NULL;
  }
  else
  {
    wan_quota_out = (UINT32_MAX) /10;
  }

  mode = GNUNET_CONFIGURATION_get_value_yesno (cfg, "ats", "MLP");
  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "MLP mode %u", mode);
  switch (mode)
  {
    /* MLP = YES */
    case GNUNET_YES:
#if HAVE_LIBGLPK
      ats_mode = MLP;
      /* Init the MLP solver with default values */
      mlp = GAS_mlp_init (cfg, stats, MLP_MAX_EXEC_DURATION, MLP_MAX_ITERATIONS);
      if (NULL == mlp)
      {
        GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "MLP mode was configured, but libglpk is not installed, switching to simple mode\n");
        GNUNET_STATISTICS_update (GSA_stats, "MLP mode enabled", 0, GNUNET_NO);
        break;
      }
      else
      {
        GNUNET_STATISTICS_update (GSA_stats, "MLP enabled", 1, GNUNET_NO);
        break;
      }
#else
      GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "MLP mode was configured, but libglpk is not installed, switching to simple mode");
      GNUNET_STATISTICS_update (GSA_stats, "MLP enabled", 0, GNUNET_NO);
      ats_mode = SIMPLE;
      break;
#endif
    /* MLP = NO */
    case GNUNET_NO:
      GNUNET_STATISTICS_update (GSA_stats, "MLP enabled", 0, GNUNET_NO);
      ats_mode = SIMPLE;
      break;
    /* No configuration value */
    case GNUNET_SYSERR:
      GNUNET_STATISTICS_update (GSA_stats, "MLP enabled", 0, GNUNET_NO);
      ats_mode = SIMPLE;
      break;
    default:
      break;
  }
  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "ATS started with %s mode\n", (SIMPLE == ats_mode) ? "SIMPLE" : "MLP");
  running = GNUNET_YES;
}