/**
 * Notify ATS about a new inbound @a address. The @a address in
 * combination with the @a session must be new, but this function will
 * perform a santiy check.  If the @a address is indeed new, make it
 * available to ATS.
 *
 * @param address the address
 * @param session the session
 * @param prop performance information
 */
void
GST_ats_add_inbound_address (const struct GNUNET_HELLO_Address *address,
                             struct GNUNET_ATS_Session *session,
                             const struct GNUNET_ATS_Properties *prop)
{
  struct GNUNET_ATS_AddressRecord *ar;
  struct AddressInfo *ai;

  if (0 ==
      memcmp (&GST_my_identity,
              &address->peer,
              sizeof (struct GNUNET_PeerIdentity)))
    return; /* our own, ignore! */

  /* Sanity checks for a valid inbound address */
  if (NULL == address->transport_name)
  {
    GNUNET_break(0);
    return;
  }
  GNUNET_break (GNUNET_ATS_NET_UNSPECIFIED != prop->scope);
  GNUNET_assert (GNUNET_YES ==
                 GNUNET_HELLO_address_check_option (address,
                                                    GNUNET_HELLO_ADDRESS_INFO_INBOUND));
  GNUNET_assert (NULL != session);
  ai = find_ai (address, session);
  if (NULL != ai)
  {
    /* This should only be called for new sessions, and thus
       we should not already have the address */
    GNUNET_break (0);
    return;
  }
  /* Is indeed new, let's tell ATS */
  LOG (GNUNET_ERROR_TYPE_DEBUG,
       "Notifying ATS about peer `%s''s new inbound address `%s' session %p in network %s\n",
       GNUNET_i2s (&address->peer),
       GST_plugins_a2s (address),
       session,
       GNUNET_ATS_print_network_type (prop->scope));
  ar = GNUNET_ATS_address_add (GST_ats,
                               address,
                               session,
                               prop);
  GNUNET_assert (NULL != ar);
  ai = GNUNET_new (struct AddressInfo);
  ai->address = GNUNET_HELLO_address_copy (address);
  ai->session = session;
  ai->properties = *prop;
  ai->ar = ar;
  (void) GNUNET_CONTAINER_multipeermap_put (p2a,
                                            &ai->address->peer,
                                            ai,
                                            GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
  publish_p2a_stat_update ();
}
static void
run (void *cls,
     const struct GNUNET_CONFIGURATION_Handle *cfg,
     struct GNUNET_TESTING_Peer *peer)
{
  die_task = GNUNET_SCHEDULER_add_delayed (TIMEOUT, &end_badly, NULL);

  /* Connect to ATS scheduling */
  sched_ats = GNUNET_ATS_scheduling_init (cfg, &address_suggest_cb, NULL);
  if (sched_ats == NULL)
  {
    GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Could not connect to ATS scheduling!\n");
    ret = 1;
    end ();
    return;
  }

  /* Set up peer */
  if (GNUNET_SYSERR == GNUNET_CRYPTO_hash_from_string(PEERID0, &p.id.hashPubKey))
  {
      GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Could not setup peer!\n");
      ret = GNUNET_SYSERR;
      end ();
      return;
  }

  GNUNET_assert (0 == strcmp (PEERID0, GNUNET_i2s_full (&p.id)));

  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Created peer `%s'\n",
              GNUNET_i2s_full(&p.id));

  /* Prepare ATS Information */
  test_ats_info[0].type = htonl (GNUNET_ATS_NETWORK_TYPE);
  test_ats_info[0].value = htonl(GNUNET_ATS_NET_WAN);
  test_ats_info[1].type = htonl (GNUNET_ATS_QUALITY_NET_DISTANCE);
  test_ats_info[1].value = htonl(1);
  test_ats_info[1].type = htonl (GNUNET_ATS_QUALITY_NET_DELAY);
  test_ats_info[1].value = htonl(10);
  test_ats_count = 2;

  /* Adding address without session */
  test_session = &test_addr;
  create_test_address (&test_addr, "test", &test_addr, "test", strlen ("test") + 1);
  test_hello_address.peer = p.id;
  test_hello_address.transport_name = test_addr.plugin;
  test_hello_address.address = test_addr.addr;
  test_hello_address.address_length = test_addr.addr_len;
  GNUNET_ATS_address_add (sched_ats, &test_hello_address, test_session, test_ats_info, test_ats_count);

  /* Request address */
  GNUNET_ATS_suggest_address (sched_ats, &p.id);
}
/**
 * Notify ATS about the new address including the network this address is
 * located in.  The address must NOT be inbound and must be new to ATS.
 *
 * @param address the address
 * @param prop performance information
 */
void
GST_ats_add_address (const struct GNUNET_HELLO_Address *address,
                     const struct GNUNET_ATS_Properties *prop)
{
  struct GNUNET_ATS_AddressRecord *ar;
  struct AddressInfo *ai;

  if (0 ==
      memcmp (&GST_my_identity,
              &address->peer,
              sizeof (struct GNUNET_PeerIdentity)))
    return; /* our own, ignore! */
  /* validadte address */
  if (NULL == address->transport_name)
  {
    GNUNET_break(0);
    return;
  }
  GNUNET_assert (GNUNET_YES !=
                 GNUNET_HELLO_address_check_option (address,
                                                    GNUNET_HELLO_ADDRESS_INFO_INBOUND));
  ai = find_ai_no_session (address);
  GNUNET_assert (NULL == ai);
  GNUNET_break (GNUNET_ATS_NET_UNSPECIFIED != prop->scope);

  /* address seems sane, let's tell ATS */
  LOG (GNUNET_ERROR_TYPE_INFO,
       "Notifying ATS about peer %s's new address `%s'\n",
       GNUNET_i2s (&address->peer),
       GST_plugins_a2s (address));
  ar = GNUNET_ATS_address_add (GST_ats,
                               address,
                               NULL,
                               prop);
  GNUNET_assert (NULL != ar);
  ai = GNUNET_new (struct AddressInfo);
  ai->address = GNUNET_HELLO_address_copy (address);
  ai->ar = ar;
  ai->properties = *prop;
  (void) GNUNET_CONTAINER_multipeermap_put (p2a,
                                            &ai->address->peer,
                                            ai,
                                            GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
  publish_p2a_stat_update ();
}
/**
 * The blocking time for an address has expired, allow ATS to
 * suggest it again.
 *
 * @param cls the `struct AddressInfo` of the address to unblock
 * @param tc unused
 */
static void
unblock_address (void *cls,
                 const struct GNUNET_SCHEDULER_TaskContext *tc)
{
  struct AddressInfo *ai = cls;

  ai->unblock_task = NULL;
  LOG (GNUNET_ERROR_TYPE_DEBUG,
       "Unblocking address %s of peer %s\n",
       GST_plugins_a2s (ai->address),
       GNUNET_i2s (&ai->address->peer));
  ai->ar = GNUNET_ATS_address_add (GST_ats,
                                   ai->address,
                                   ai->session,
                                   &ai->properties);
  GNUNET_break (NULL != ai->ar);
  num_blocked--;
  publish_p2a_stat_update ();
}
static void
run (void *cls, const struct GNUNET_CONFIGURATION_Handle *mycfg,
    struct GNUNET_TESTING_Peer *peer)
{
  die_task = GNUNET_SCHEDULER_add_delayed (TIMEOUT, &end_badly, NULL);
  stats = GNUNET_STATISTICS_create ("ats", mycfg);
  GNUNET_STATISTICS_watch (stats, "ats", "# addresses", &stat_cb, NULL);


  /* Connect to ATS scheduling */
  sched_ats = GNUNET_ATS_scheduling_init (mycfg, &address_suggest_cb, NULL);
  if (sched_ats == NULL)
  {
    GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Could not connect to ATS scheduling!\n");
    GNUNET_SCHEDULER_add_now (&end_badly, NULL);
    return;
  }

  /* Set up peer */
  memset (&p.id, '1', sizeof (p.id));
  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Created peer `%s'\n",
              GNUNET_i2s_full(&p.id));

  /* Prepare ATS Information */
  test_ats_info[0].type = htonl (GNUNET_ATS_NETWORK_TYPE);
  test_ats_info[0].value = htonl(GNUNET_ATS_NET_WAN);
  test_ats_info[1].type = htonl (GNUNET_ATS_QUALITY_NET_DISTANCE);
  test_ats_info[1].value = htonl(1);
  test_ats_count = 2;

  /* Adding address without session */
  test_session = NULL;
  create_test_address (&test_addr, "test", test_session, "test", strlen ("test") + 1);
  test_hello_address.peer = p.id;
  test_hello_address.transport_name = test_addr.plugin;
  test_hello_address.address = test_addr.addr;
  test_hello_address.address_length = test_addr.addr_len;

  /* Adding address */
  GNUNET_ATS_address_add (sched_ats, &test_hello_address, NULL, test_ats_info, test_ats_count);
}
static void
run (void *cls, 
     const struct GNUNET_CONFIGURATION_Handle *mycfg,
     struct GNUNET_TESTING_Peer *peer)
{
  ret = 1;
  cfg = (struct GNUNET_CONFIGURATION_Handle *) mycfg;
  die_task = GNUNET_SCHEDULER_add_delayed (TIMEOUT, &end_badly, NULL);


  /* set up peer 0 */
  GNUNET_CRYPTO_hash_create_random (GNUNET_CRYPTO_QUALITY_WEAK,
                                    &p[0].id.hashPubKey);

  p0_addresses[0].plugin = "test";
  p0_addresses[0].session = NULL;
  p0_addresses[0].addr = GNUNET_strdup ("test_p0_a0");
  p0_addresses[0].addr_len = strlen (p0_addresses[0].addr) + 1;

  p0_ha[0].address = p0_addresses[0].addr;
  p0_ha[0].address_length = p0_addresses[0].addr_len;
  p0_ha[0].peer = p[0].id;
  p0_ha[0].transport_name = p0_addresses[0].plugin;

  p0_addresses[1].plugin = "test";
  p0_addresses[1].session = NULL;
  p0_addresses[1].addr = GNUNET_strdup ("test_p0_a1");
  p0_addresses[1].addr_len = strlen(p0_addresses[1].addr) + 1;

  p0_ha[1].address = p0_addresses[1].addr;
  p0_ha[1].address_length = p0_addresses[1].addr_len;
  p0_ha[1].peer = p[0].id;
  p0_ha[1].transport_name = p0_addresses[1].plugin;

  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Created peer 0: `%s'\n",
              GNUNET_i2s (&p[0].id));

  GNUNET_CRYPTO_hash_create_random (GNUNET_CRYPTO_QUALITY_WEAK,
                                    &p[1].id.hashPubKey);

  p1_addresses[0].plugin = "test";
  p1_addresses[0].session = NULL;
  p1_addresses[0].addr = GNUNET_strdup ("test_p1_a0");
  p1_addresses[0].addr_len = strlen(p1_addresses[0].addr) + 1;

  p1_ha[0].address = p1_addresses[0].addr;
  p1_ha[0].address_length = p1_addresses[0].addr_len;
  p1_ha[0].peer = p[1].id;
  p1_ha[0].transport_name = p1_addresses[0].plugin;

  p1_addresses[1].plugin = "test";
  p1_addresses[1].session = NULL;
  p1_addresses[1].addr = GNUNET_strdup ("test_p1_a1");
  p1_addresses[1].addr_len = strlen(p1_addresses[1].addr) + 1;

  p1_ha[1].address = p1_addresses[1].addr;
  p1_ha[1].address_length = p1_addresses[1].addr_len;
  p1_ha[1].peer = p[1].id;
  p1_ha[1].transport_name = p1_addresses[1].plugin;


  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Created peer 1: `%s'\n",
              GNUNET_i2s (&p[1].id));


  /* Add addresses */
  atsh = GNUNET_ATS_scheduling_init (cfg, &address_suggest_cb, NULL);
  if (atsh == NULL)
  {
    ret = GNUNET_SYSERR;
    end ();
    return;
  }

  GNUNET_ATS_address_add (atsh, &p0_ha[0], NULL, NULL, 0);
  GNUNET_ATS_address_add (atsh, &p0_ha[1], NULL, NULL, 0);

  GNUNET_ATS_address_add (atsh, &p1_ha[0], NULL, NULL, 0);
  GNUNET_ATS_address_add (atsh, &p1_ha[1], NULL, NULL, 0);


  GNUNET_ATS_suggest_address (atsh, &p[0].id);
  GNUNET_ATS_suggest_address (atsh, &p[1].id);
}
Esempio n. 7
0
/**
 * Main interpreter loop. Runs the steps of the test.
 *
 * @param cls NULL
 * @param tc unused
 */
static void
interpreter (void *cls,
             const struct GNUNET_SCHEDULER_TaskContext *tc)

{
  struct Command *cmd;

  interpreter_task = NULL;
  while (1)
  {
    cmd = &test_commands[off];
    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                "#%u: %d %s\n",
                off,
                (int) cmd->code,
                (NULL != cmd->label) ? cmd->label : "");
    switch (cmd->code)
    {
    case CMD_END_PASS:
      ret = 0;
      GNUNET_SCHEDULER_shutdown ();
      return;
    case CMD_ADD_ADDRESS:
      {
        struct GNUNET_HELLO_Address *addr;
        struct GNUNET_ATS_Session *session;

        addr = make_address (cmd->details.add_address.pid,
                             cmd->details.add_address.addr_num,
                             cmd->details.add_address.addr_flags);
        session = make_session (cmd->details.add_address.session);
        if (cmd->details.add_address.expect_fail)
          GNUNET_log_skip (1, GNUNET_NO);
        cmd->details.add_address.ar
          = GNUNET_ATS_address_add (sched_ats,
                                    addr,
                                    session,
                                    &cmd->details.add_address.properties);
        GNUNET_free (addr);
        if (cmd->details.add_address.expect_fail)
        {
          GNUNET_log_skip (0, GNUNET_YES);
        }
        else if (NULL == cmd->details.add_address.ar)
        {
          GNUNET_break (0);
          GNUNET_SCHEDULER_shutdown ();
          return;
        }
        off++;
        break;
      }
    case CMD_DEL_ADDRESS:
      {
        struct Command *add;

        add = find_command (CMD_ADD_ADDRESS,
                            cmd->details.del_address.add_label);
        GNUNET_assert (NULL != add->details.add_address.ar);
        GNUNET_ATS_address_destroy (add->details.add_address.ar);
        add->details.add_address.ar = NULL;
        off++;
        break;
      }
    case CMD_AWAIT_ADDRESS_SUGGESTION:
      {
        struct GNUNET_PeerIdentity pid;
        struct GNUNET_HELLO_Address *addr;
        struct Command *add;
        struct AddressSuggestData *asd;
        int done;

        make_peer (cmd->details.await_address_suggestion.pid,
                   &pid);
        asd = find_address_suggestion (&pid);
        if (NULL == asd)
          return;
        if (GNUNET_NO == asd->active)
          return; /* last suggestion was to disconnect, wait longer */
        done = GNUNET_YES;
        if (NULL != cmd->details.await_address_suggestion.add_label)
        {
          done = GNUNET_NO;
          add = find_command (CMD_ADD_ADDRESS,
                              cmd->details.await_address_suggestion.add_label);
          addr = make_address (add->details.add_address.pid,
                               add->details.add_address.addr_num,
                               add->details.add_address.addr_flags);
          if ( (asd->session ==
                make_session (add->details.add_address.session)) &&
               (0 ==
                GNUNET_HELLO_address_cmp (addr,
                                          asd->address)) )
            done = GNUNET_YES;
          GNUNET_free (addr);
        }
        if (GNUNET_NO == done)
          return;
        off++;
        break;
      }
    case CMD_AWAIT_DISCONNECT_SUGGESTION:
      {
        struct GNUNET_PeerIdentity pid;
        struct AddressSuggestData *asd;

        make_peer (cmd->details.await_disconnect_suggestion.pid,
                   &pid);
        asd = find_address_suggestion (&pid);
        if (NULL == asd)
          return; /* odd, no suggestion at all yet!? */
        if (GNUNET_YES == asd->active)
          return; /* last suggestion was to activate, wait longer */
        /* last suggestion was to deactivate, condition satisfied! */
        off++;
        break;
      }
    case CMD_REQUEST_CONNECTION_START:
      {
        struct GNUNET_PeerIdentity pid;

        make_peer (cmd->details.request_connection_start.pid,
                   &pid);
        cmd->details.request_connection_start.csh
          = GNUNET_ATS_connectivity_suggest (con_ats,
                                             &pid,
                                             1);
        off++;
        break;
      }
    case CMD_REQUEST_CONNECTION_STOP:
      {
        struct Command *start;

        start = find_command (CMD_REQUEST_CONNECTION_START,
                              cmd->details.request_connection_stop.connect_label);
        GNUNET_ATS_connectivity_suggest_cancel (start->details.request_connection_start.csh);
        start->details.request_connection_start.csh = NULL;
        off++;
        break;
      }
    case CMD_AWAIT_ADDRESS_INFORMATION:
      {
        struct AddressInformationData *aid;
        struct Command *add;
        struct Command *update;
        struct GNUNET_HELLO_Address *addr;
        const struct GNUNET_ATS_Properties *cmp;

        add = find_command (CMD_ADD_ADDRESS,
                            cmd->details.await_address_information.add_label);
        update = find_command (CMD_UPDATE_ADDRESS,
                               cmd->details.await_address_information.update_label);
        addr = make_address (add->details.add_address.pid,
                             add->details.add_address.addr_num,
                             add->details.add_address.addr_flags);
        aid = find_address_information (addr);
        GNUNET_free (addr);
        if (NULL == update)
          cmp = &add->details.add_address.properties;
        else
          cmp = &update->details.update_address.properties;
        if ( (NULL != aid) &&
             (cmp->delay.rel_value_us == aid->properties.delay.rel_value_us) &&
             (cmp->utilization_out == aid->properties.utilization_out) &&
             (cmp->utilization_in == aid->properties.utilization_in) &&
             (cmp->distance == aid->properties.distance) &&
             (cmp->scope == aid->properties.scope) )
        {
          off++;
          break;
        }
        return;
      }
    case CMD_UPDATE_ADDRESS:
      {
        struct Command *add;

        add = find_command (CMD_ADD_ADDRESS,
                            cmd->details.update_address.add_label);
        GNUNET_assert (NULL != add->details.add_address.ar);
        GNUNET_ATS_address_update (add->details.add_address.ar,
                                   &cmd->details.update_address.properties);
        off++;
        break;
      }
    case CMD_ADD_SESSION:
      {
        struct Command *add;
        struct GNUNET_ATS_Session *session;

        add = find_command (CMD_ADD_ADDRESS,
                            cmd->details.add_session.add_label);
        session = make_session (cmd->details.add_session.session);
        GNUNET_assert (NULL != add->details.add_address.ar);
        GNUNET_ATS_address_add_session (add->details.add_address.ar,
                                        session);
        off++;
        break;
      }
    case CMD_DEL_SESSION:
      {
        struct Command *add_address;
        struct Command *add_session;
        struct GNUNET_ATS_Session *session;

        add_session = find_command (CMD_ADD_SESSION,
                                    cmd->details.del_session.add_session_label);
        add_address = find_command (CMD_ADD_ADDRESS,
                                    add_session->details.add_session.add_label);
        GNUNET_assert (NULL != add_address->details.add_address.ar);
        session = make_session (add_session->details.add_session.session);
        GNUNET_ATS_address_del_session (add_address->details.add_address.ar,
                                        session);
        off++;
        break;
      }
    case CMD_CHANGE_PREFERENCE:
      {
        struct GNUNET_PeerIdentity pid;

        make_peer (cmd->details.change_preference.pid,
                   &pid);
        GNUNET_ATS_performance_change_preference (perf_ats,
                                                  &pid,
                                                  GNUNET_ATS_PREFERENCE_END);
        off++;
        break;
      }
    case CMD_PROVIDE_FEEDBACK:
      {
        struct GNUNET_PeerIdentity pid;

        make_peer (cmd->details.provide_feedback.pid,
                   &pid);
        GNUNET_ATS_performance_give_feedback (perf_ats,
                                              &pid,
                                              cmd->details.provide_feedback.scope,
                                              GNUNET_ATS_PREFERENCE_END);
        off++;
        break;
      }
    case CMD_LIST_ADDRESSES:
      {
        struct GNUNET_PeerIdentity pid;

        make_peer (cmd->details.list_addresses.pid,
                   &pid);
        cmd->details.list_addresses.alh
          = GNUNET_ATS_performance_list_addresses (perf_ats,
                                                   &pid,
                                                   cmd->details.list_addresses.all,
                                                   &info_cb,
                                                   cmd);
        return;
      }
    case CMD_RESERVE_BANDWIDTH:
      {
        struct GNUNET_PeerIdentity pid;

        make_peer (cmd->details.reserve_bandwidth.pid,
                   &pid);
        cmd->details.reserve_bandwidth.rc
          = GNUNET_ATS_reserve_bandwidth (perf_ats,
                                          &pid,
                                          cmd->details.reserve_bandwidth.amount,
                                          &reservation_cb,
                                          cmd);
        return;
      }
    case CMD_SLEEP:
      off++;
      interpreter_task = GNUNET_SCHEDULER_add_delayed (cmd->details.sleep.delay,
                                                       &interpreter,
                                                       NULL);
      return;
    } /* end switch */
  } /* end while(1) */
}
static void
run (void *cls, const struct GNUNET_CONFIGURATION_Handle *mycfg,
    struct GNUNET_TESTING_Peer *peer)
{
  ret = 1;
  cfg = (struct GNUNET_CONFIGURATION_Handle *) mycfg;
  die_task = GNUNET_SCHEDULER_add_delayed (TIMEOUT, &end_badly, NULL );

  if (NULL == (perf_ats = GNUNET_ATS_performance_init (cfg, &ats_perf_cb, NULL)))
  {
    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
        "Failed to connect to performance API\n");
    GNUNET_SCHEDULER_add_now (end_badly, NULL);
  }


  stats = GNUNET_STATISTICS_create ("ats", cfg);
  GNUNET_STATISTICS_watch (stats, "ats", "# addresses", &stat_cb, NULL);

  /* set up peer 0 */
  memset (&p[0].id, '1', sizeof (p[0].id));
  p0_addresses[0].plugin = "test";
  p0_addresses[0].session = NULL;
  p0_addresses[0].addr = GNUNET_strdup ("test_p0_a0");
  p0_addresses[0].addr_len = strlen (p0_addresses[0].addr) + 1;

  p0_ha[0].address = p0_addresses[0].addr;
  p0_ha[0].address_length = p0_addresses[0].addr_len;
  p0_ha[0].peer = p[0].id;
  p0_ha[0].transport_name = p0_addresses[0].plugin;

  p0_addresses[1].plugin = "test";
  p0_addresses[1].session = NULL;
  p0_addresses[1].addr = GNUNET_strdup ("test_p0_a1");
  p0_addresses[1].addr_len = strlen (p0_addresses[1].addr) + 1;

  p0_ha[1].address = p0_addresses[1].addr;
  p0_ha[1].address_length = p0_addresses[1].addr_len;
  p0_ha[1].peer = p[0].id;
  p0_ha[1].transport_name = p0_addresses[1].plugin;

  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Created peer 0: `%s'\n",
      GNUNET_i2s (&p[0].id));

  memset (&p[1].id, '2', sizeof (p[1].id));
  p1_addresses[0].plugin = "test";
  p1_addresses[0].session = NULL;
  p1_addresses[0].addr = GNUNET_strdup ("test_p1_a0");
  p1_addresses[0].addr_len = strlen (p1_addresses[0].addr) + 1;

  p1_ha[0].address = p1_addresses[0].addr;
  p1_ha[0].address_length = p1_addresses[0].addr_len;
  p1_ha[0].peer = p[1].id;
  p1_ha[0].transport_name = p1_addresses[0].plugin;

  p1_addresses[1].plugin = "test";
  p1_addresses[1].session = NULL;
  p1_addresses[1].addr = GNUNET_strdup ("test_p1_a1");
  p1_addresses[1].addr_len = strlen (p1_addresses[1].addr) + 1;

  p1_ha[1].address = p1_addresses[1].addr;
  p1_ha[1].address_length = p1_addresses[1].addr_len;
  p1_ha[1].peer = p[1].id;
  p1_ha[1].transport_name = p1_addresses[1].plugin;

  GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Created peer 1: `%s'\n",
      GNUNET_i2s (&p[1].id));

  /* Add addresses */
  sched_ats = GNUNET_ATS_scheduling_init (cfg, &address_suggest_cb, NULL );
  if (sched_ats == NULL )
  {
    GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Could not setup peer!\n");
    GNUNET_SCHEDULER_add_now (&end_badly, NULL);
    return;
  }

  GNUNET_ATS_address_add (sched_ats, &p0_ha[0], NULL, NULL, 0);
  GNUNET_ATS_address_add (sched_ats, &p0_ha[1], NULL, NULL, 0);

  GNUNET_ATS_address_add (sched_ats, &p1_ha[0], NULL, NULL, 0);
  GNUNET_ATS_address_add (sched_ats, &p1_ha[1], NULL, NULL, 0);
}
static void
run (void *cls,
     const struct GNUNET_CONFIGURATION_Handle *cfg,
     struct GNUNET_TESTING_Peer *peer)
{
  char *quota_str;

  if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string(cfg, "ats", "WAN_QUOTA_OUT", &quota_str))
  {
      fprintf (stderr, "Cannot load WAN outbound quota from configuration, exit!\n");
      ret = 1;
      return;
  }
  if  (GNUNET_SYSERR == GNUNET_STRINGS_fancy_size_to_bytes (quota_str, &wan_quota_out))
  {
      fprintf (stderr, "Cannot load WAN outbound quota from configuration, exit!\n");
      ret = 1;
      GNUNET_free (quota_str);
      return;
  }
  GNUNET_free (quota_str);
  quota_str = NULL;

  if (GNUNET_OK != GNUNET_CONFIGURATION_get_value_string(cfg, "ats", "WAN_QUOTA_IN", &quota_str))
  {
      fprintf (stderr, "Cannot load WAN inbound quota from configuration, exit!\n");
      ret = 1;
      return;
  }
  if  (GNUNET_SYSERR == GNUNET_STRINGS_fancy_size_to_bytes (quota_str, &wan_quota_in))
  {
      fprintf (stderr, "Cannot load WAN inbound quota from configuration, exit!\n");
      GNUNET_free (quota_str);
      ret = 1;
      return;
  }
  GNUNET_free (quota_str);
  quota_str = NULL;
  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Configured WAN inbound quota: %llu\n", wan_quota_in);
  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Configured WAN outbound quota: %llu\n", wan_quota_out);


  die_task = GNUNET_SCHEDULER_add_delayed (TIMEOUT, &end_badly, NULL);

  /* Connect to ATS scheduling */
  sched_ats = GNUNET_ATS_scheduling_init (cfg, &address_suggest_cb, NULL);
  if (sched_ats == NULL)
  {
    GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Could not connect to ATS scheduling!\n");
    ret = 1;
    end ();
    return;
  }

  perf_ats = GNUNET_ATS_performance_init (cfg, NULL, NULL);
  if (perf_ats == NULL)
  {
    GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Could not connect to ATS performance!\n");
    ret = 1;
    end ();
    return;
  }

  /* Set up peer 0 */
  if (GNUNET_SYSERR == GNUNET_CRYPTO_hash_from_string(PEERID0, &p[0].id.hashPubKey))
  {
      GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Could not setup peer!\n");
      ret = GNUNET_SYSERR;
      end ();
      return;
  }

  GNUNET_assert (0 == strcmp (PEERID0, GNUNET_i2s_full (&p[0].id)));

  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Created peer `%s'\n",
              GNUNET_i2s(&p[0].id));


  /* Set up peer 0 */
  if (GNUNET_SYSERR == GNUNET_CRYPTO_hash_from_string(PEERID1, &p[1].id.hashPubKey))
  {
      GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Could not setup peer!\n");
      ret = GNUNET_SYSERR;
      end ();
      return;
  }

  GNUNET_assert (0 == strcmp (PEERID1, GNUNET_i2s_full (&p[1].id)));

  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Created peer `%s'\n",
              GNUNET_i2s(&p[1].id));

  /* Prepare ATS Information */
  test_ats_info[0].type = htonl (GNUNET_ATS_NETWORK_TYPE);
  test_ats_info[0].value = htonl(GNUNET_ATS_NET_WAN);
  test_ats_info[1].type = htonl (GNUNET_ATS_QUALITY_NET_DISTANCE);
  test_ats_info[1].value = htonl(1);
  test_ats_count = 2;

  /* Adding address with session */
  test_session[0] = &test_addr[0];
  create_test_address (&test_addr[0], "test0", test_session[0], "test0", strlen ("test0") + 1);
  test_hello_address[0].peer = p[0].id;
  test_hello_address[0].transport_name = test_addr[0].plugin;
  test_hello_address[0].address = test_addr[0].addr;
  test_hello_address[0].address_length = test_addr[0].addr_len;
  GNUNET_ATS_address_add (sched_ats, &test_hello_address[0], test_session[0], test_ats_info, test_ats_count);


  /* Adding address with session */
  test_session[1] = &test_addr[1];
  create_test_address (&test_addr[1], "test1", test_session[1], "test1", strlen ("test1") + 1);
  test_hello_address[1].peer = p[1].id;
  test_hello_address[1].transport_name = test_addr[0].plugin;
  test_hello_address[1].address = test_addr[0].addr;
  test_hello_address[1].address_length = test_addr[0].addr_len;
  GNUNET_ATS_address_add (sched_ats, &test_hello_address[1], test_session[1], test_ats_info, test_ats_count);


  /* Change bandwidth preference */
  GNUNET_ATS_change_preference (perf_ats,
      &p[0].id,
      GNUNET_ATS_PREFERENCE_BANDWIDTH,(double) 1000, GNUNET_ATS_PREFERENCE_END);
  GNUNET_ATS_change_preference (perf_ats,
      &p[1].id,
      GNUNET_ATS_PREFERENCE_BANDWIDTH,(double) 1000, GNUNET_ATS_PREFERENCE_END);


  /* Change latency preference */

  GNUNET_ATS_change_preference (perf_ats,
      &p[0].id,
      GNUNET_ATS_PREFERENCE_LATENCY,(double) 10, GNUNET_ATS_PREFERENCE_END);
  GNUNET_ATS_change_preference (perf_ats,
      &p[1].id,
      GNUNET_ATS_PREFERENCE_LATENCY,(double) 100, GNUNET_ATS_PREFERENCE_END);
  GNUNET_SCHEDULER_add_delayed (SLEEP, &sleep_task, NULL);
}