/**
 * Add or remove an address from this peer's HELLO message.
 *
 * @param addremove GNUNET_YES to add, GNUNET_NO to remove
 * @param address address to add or remove
 */
void
GST_hello_modify_addresses (int addremove,
                            const struct GNUNET_HELLO_Address *address)
{
  struct OwnAddressList *al;

  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
              (addremove ==
               GNUNET_YES) ? "Adding `%s' to the set of our addresses\n" :
              "Removing `%s' from the set of our addresses\n",
              GST_plugins_a2s (address));
  GNUNET_assert (address != NULL);
  if (GNUNET_NO == addremove)
  {
    for (al = oal_head; al != NULL; al = al->next)
      if (0 == GNUNET_HELLO_address_cmp (address, al->address))
      {
        GNUNET_CONTAINER_DLL_remove (oal_head, oal_tail, al);
        GNUNET_HELLO_address_free (al->address);
        GNUNET_free (al);
        refresh_hello ();
        return;
      }
    /* address to be removed not found!? */
    GNUNET_break (0);
    return;
  }
  al = GNUNET_malloc (sizeof (struct OwnAddressList));
  GNUNET_CONTAINER_DLL_insert (oal_head, oal_tail, al);
  al->address = GNUNET_HELLO_address_copy (address);
  refresh_hello ();
}
Пример #2
0
static void
resolve_validation_address (const struct GNUNET_PeerIdentity *id,
    const struct GNUNET_HELLO_Address *address, int numeric,
    struct GNUNET_TIME_Absolute last_validation,
    struct GNUNET_TIME_Absolute valid_until,
    struct GNUNET_TIME_Absolute next_validation,
    enum GNUNET_TRANSPORT_ValidationState state)
{
  struct ValidationResolutionContext *vc;

  vc = GNUNET_new (struct ValidationResolutionContext);
  GNUNET_assert(NULL != vc);
  GNUNET_CONTAINER_DLL_insert(vc_head, vc_tail, vc);
  address_resolutions++;

  vc->id = (*id);
  vc->transport = GNUNET_strdup(address->transport_name);
  vc->addrcp = GNUNET_HELLO_address_copy (address);
  vc->printed = GNUNET_NO;
  vc->state = state;
  vc->last_validation = last_validation;
  vc->valid_until = valid_until;
  vc->next_validation = next_validation;

  /* Resolve address to string */
  vc->asc = GNUNET_TRANSPORT_address_to_string (cfg, address, numeric,
      RESOLUTION_TIMEOUT, &process_validation_string, vc);
}
/**
 * Find a ValidationEntry entry for the given neighbour that matches
 * the given address and transport.  If none exists, create one (but
 * without starting any validation).
 *
 * @param public_key public key of the peer, NULL for unknown
 * @param address address to find
 * @return validation entry matching the given specifications, NULL
 *         if we don't have an existing entry and no public key was given
 */
static struct ValidationEntry *
find_validation_entry (const struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded
                       *public_key, const struct GNUNET_HELLO_Address *address)
{
  struct ValidationEntryMatchContext vemc;
  struct ValidationEntry *ve;

  vemc.ve = NULL;
  vemc.address = address;
  GNUNET_CONTAINER_multihashmap_get_multiple (validation_map,
                                              &address->peer.hashPubKey,
                                              &validation_entry_match, &vemc);
  if (NULL != (ve = vemc.ve))
    return ve;
  if (public_key == NULL)
    return NULL;
  ve = GNUNET_malloc (sizeof (struct ValidationEntry));
  ve->in_use = GNUNET_SYSERR; /* not defined */
  ve->last_line_set_to_no  = 0;
  ve->last_line_set_to_yes  = 0;
  ve->address = GNUNET_HELLO_address_copy (address);
  ve->public_key = *public_key;
  ve->pid = address->peer;
  ve->latency = GNUNET_TIME_UNIT_FOREVER_REL;
  ve->challenge =
      GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_NONCE, UINT32_MAX);
  ve->timeout_task =
      GNUNET_SCHEDULER_add_delayed (UNVALIDATED_PING_KEEPALIVE,
                                    &timeout_hello_validation, ve);
  GNUNET_CONTAINER_multihashmap_put (validation_map, &address->peer.hashPubKey,
                                     ve,
                                     GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE);
  ve->expecting_pong = GNUNET_NO;
  return ve;
}
static void
address_suggest_cb (void *cls, const struct GNUNET_HELLO_Address *address,
                    struct Session *session,
                    struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out,
                    struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in,
                    const struct GNUNET_ATS_Information *ats,
                    uint32_t ats_count)
{
  static int suggest_p0 = GNUNET_NO;
  static int suggest_p1 = GNUNET_NO;
  static int running = GNUNET_NO;

  if (0 == memcmp (&address->peer, &p[0].id,
                   sizeof (struct GNUNET_PeerIdentity)))
  {
    suggest_p0 = GNUNET_YES;;

    if (s_ha[0] != NULL)
      GNUNET_free (s_ha[0]);
    s_ha[0] = GNUNET_HELLO_address_copy (address);

    GNUNET_ATS_suggest_address_cancel (atsh, &p[0].id);
  }
  if (0 == memcmp (&address->peer, &p[1].id,
                   sizeof (struct GNUNET_PeerIdentity)))
  {
    suggest_p1 = GNUNET_YES;

    if (s_ha[1] != NULL)
      GNUNET_free (s_ha[1]);
    s_ha[1] = GNUNET_HELLO_address_copy (address);

    GNUNET_ATS_suggest_address_cancel (atsh, &p[1].id);
  }


  if ((GNUNET_NO == running) && (GNUNET_YES == suggest_p0) && (GNUNET_YES == suggest_p1))
  {
      running = GNUNET_YES;
      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Have address suggestion for both peers\n");
      GNUNET_SCHEDULER_add_now (&test_performance_api, NULL);
  }

}
/**
 * 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 ();
}
Пример #6
0
/**
 * We have a new address ATS should know. Addresses have to be added
 * with this function before they can be: updated, set in use and
 * destroyed.
 *
 * @param sh handle
 * @param address the address
 * @param session session handle, can be NULL
 * @param prop performance data for the address
 * @return handle to the address representation inside ATS, NULL
 *         on error (i.e. ATS knows this exact address already)
 */
struct GNUNET_ATS_AddressRecord *
GNUNET_ATS_address_add (struct GNUNET_ATS_SchedulingHandle *sh,
                        const struct GNUNET_HELLO_Address *address,
                        struct GNUNET_ATS_Session *session,
                        const struct GNUNET_ATS_Properties *prop)
{
  struct GNUNET_ATS_AddressRecord *ar;
  size_t namelen;
  size_t msize;
  uint32_t s;

  if (NULL == address)
  {
    /* we need a valid address */
    GNUNET_break (0);
    return NULL;
  }
  GNUNET_break (GNUNET_ATS_NET_UNSPECIFIED != prop->scope);
  namelen = strlen (address->transport_name) + 1;
  msize = address->address_length + namelen;
  if ((msize + sizeof (struct AddressUpdateMessage) >= GNUNET_SERVER_MAX_MESSAGE_SIZE) ||
      (address->address_length >= GNUNET_SERVER_MAX_MESSAGE_SIZE) ||
      (namelen >= GNUNET_SERVER_MAX_MESSAGE_SIZE) )
  {
    /* address too large for us, this should not happen */
    GNUNET_break (0);
    return NULL;
  }

  if (NOT_FOUND !=
      find_session_id (sh,
                       session,
                       address))
  {
    /* Already existing, nothing todo, but this should not happen */
    GNUNET_break (0);
    return NULL;
  }
  s = find_empty_session_slot (sh);
  ar = GNUNET_new (struct GNUNET_ATS_AddressRecord);
  ar->sh = sh;
  ar->slot = s;
  ar->session = session;
  ar->address = GNUNET_HELLO_address_copy (address);
  GNUNET_ATS_properties_hton (&ar->properties,
                              prop);
  sh->session_array[s] = ar;
  send_add_address_message (sh, ar);
  return ar;
}
Пример #7
0
void ats_perf_cb (void *cls,
                  const struct
                  GNUNET_HELLO_Address *
                  address,
                  struct
                  GNUNET_BANDWIDTH_Value32NBO
                  bandwidth_out,
                  struct
                  GNUNET_BANDWIDTH_Value32NBO
                  bandwidth_in,
                  const struct
                  GNUNET_ATS_Information *
                  ats, uint32_t ats_count)
{
  struct PendingResolutions * pr;


  if (NULL != address)
  {
    pr = GNUNET_malloc (sizeof (struct PendingResolutions) +
                        ats_count * sizeof (struct GNUNET_ATS_Information));

    pr->ats_count = ats_count;
    pr->ats = (struct GNUNET_ATS_Information *) &pr[1];
    if (ats_count > 0)
      memcpy (pr->ats, ats, ats_count * sizeof (struct GNUNET_ATS_Information));
    pr->address = GNUNET_HELLO_address_copy (address);
    pr->bandwidth_in = bandwidth_in;
    pr->bandwidth_out = bandwidth_out;
    pr->tats_ctx = GNUNET_TRANSPORT_address_to_string(cfg, address,
                      resolve_addresses_numeric, GNUNET_TIME_UNIT_FOREVER_REL, transport_addr_to_str_cb, pr);
    GNUNET_CONTAINER_DLL_insert (head, tail, pr);
    results++;
    pending++;
  }
  else
  {
    /* All messages received */
    receive_done = GNUNET_YES;
    alh = NULL;
    if (0 == pending)
    {
      /* All messages received and no resolutions pending*/
      if (end_task != GNUNET_SCHEDULER_NO_TASK)
        GNUNET_SCHEDULER_cancel (end_task);
      end_task = GNUNET_SCHEDULER_add_now (end, NULL);
    }
  }
}
/**
 * Add or remove an address from this peer's HELLO message.
 *
 * @param addremove #GNUNET_YES to add, #GNUNET_NO to remove
 * @param address address to add or remove
 */
void
GST_hello_modify_addresses (int addremove,
                            const struct GNUNET_HELLO_Address *address)
{
  struct OwnAddressList *al;

  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
              (GNUNET_YES == addremove)
              ? "Adding `%s' to the set of our addresses\n"
              : "Removing `%s' from the set of our addresses\n",
              GST_plugins_a2s (address));
  GNUNET_assert (NULL != address);
  for (al = oal_head; al != NULL; al = al->next)
    if (0 == GNUNET_HELLO_address_cmp (address, al->address))
      break;
  if (GNUNET_NO == addremove)
  {
    if (NULL == al)
    {
      /* address to be removed not found!? */
      GNUNET_break (0);
      return;
    }
    al->rc--;
    if (0 != al->rc)
      return; /* RC not yet zero */
    GNUNET_CONTAINER_DLL_remove (oal_head,
                                 oal_tail,
                                 al);
    GNUNET_HELLO_address_free (al->address);
    GNUNET_free (al);
    refresh_hello ();
    return;
  }
  if (NULL != al)
  {
    /* address added twice or more */
    al->rc++;
    return;
  }
  al = GNUNET_new (struct OwnAddressList);
  al->rc = 1;
  GNUNET_CONTAINER_DLL_insert (oal_head,
                               oal_tail,
                               al);
  al->address = GNUNET_HELLO_address_copy (address);
  refresh_hello ();
}
Пример #9
0
static void resolve_address (const struct GNUNET_HELLO_Address *address,
														 int numeric)
{
  struct ResolutionContext *rc;

  rc = GNUNET_malloc(sizeof (struct ResolutionContext));
  GNUNET_assert (NULL != rc);
  GNUNET_CONTAINER_DLL_insert (rc_head, rc_tail, rc);
  address_resolutions ++;

  rc->addrcp = GNUNET_HELLO_address_copy(address);
  rc->printed = GNUNET_NO;
  /* Resolve address to string */
  rc->asc = GNUNET_TRANSPORT_address_to_string (cfg, address, numeric,
                                      RESOLUTION_TIMEOUT, &process_string,
                                      rc);
}
/**
 * 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 ();
}
Пример #11
0
static void
resolve_peer_address (const struct GNUNET_PeerIdentity *id,
    const struct GNUNET_HELLO_Address *address, int numeric,
    enum GNUNET_TRANSPORT_PeerState state,
    struct GNUNET_TIME_Absolute state_timeout)
{
  struct PeerResolutionContext *rc;

  rc = GNUNET_new (struct PeerResolutionContext);
  GNUNET_assert(NULL != rc);
  GNUNET_CONTAINER_DLL_insert(rc_head, rc_tail, rc);
  address_resolutions++;

  rc->id = (*id);
  rc->transport = GNUNET_strdup(address->transport_name);
  rc->addrcp = GNUNET_HELLO_address_copy (address);
  rc->printed = GNUNET_NO;
  rc->state = state;
  rc->state_timeout = state_timeout;
  /* Resolve address to string */
  rc->asc = GNUNET_TRANSPORT_address_to_string (cfg, address, numeric,
      RESOLUTION_TIMEOUT, &process_peer_string, rc);
}