예제 #1
0
/**
 * Copy an address struct.
 *
 * @param address address to copy
 * @return a copy of the address struct
 */
struct GNUNET_HELLO_Address *
GNUNET_HELLO_address_copy (const struct GNUNET_HELLO_Address *address)
{
  return GNUNET_HELLO_address_allocate (&address->peer, address->transport_name,
                                        address->address,
                                        address->address_length,
                                        address->local_info);
}
예제 #2
0
/**
 * Generate a fake address based on the given parameters.
 *
 * @param pid number of the peer
 * @param num number of the address at peer @a pid
 * @param addr_flags flags to use for the address
 * @return the address
 */
static struct GNUNET_HELLO_Address *
make_address (uint32_t pid,
              uint32_t num,
              enum GNUNET_HELLO_AddressInfo addr_flags)
{
  struct GNUNET_PeerIdentity pk;
  uint32_t nbo;

  nbo = htonl (num);
  make_peer (pid,
             &pk);
  return GNUNET_HELLO_address_allocate (&pk,
                                        "test",
                                        &nbo,
                                        sizeof (nbo),
                                        addr_flags);
}
/**
 * Parse broadcast message received.
 *
 * @param cls the `struct Plugin`
 * @param client the `struct MstContext` with sender address
 * @param message the message we received
 * @return #GNUNET_OK (always)
 */
static int
broadcast_mst_cb (void *cls,
                  void *client,
                  const struct GNUNET_MessageHeader *message)
{
  struct Plugin *plugin = cls;
  struct MstContext *mc = client;
  struct GNUNET_HELLO_Address *address;
  const struct GNUNET_MessageHeader *hello;
  const struct UDP_Beacon_Message *msg;

  msg = (const struct UDP_Beacon_Message *) message;

  if (GNUNET_MESSAGE_TYPE_TRANSPORT_BROADCAST_BEACON !=
      ntohs (msg->header.type))
    return GNUNET_OK;
  LOG (GNUNET_ERROR_TYPE_DEBUG,
       "Received beacon with %u bytes from peer `%s' via address `%s'\n",
       ntohs (msg->header.size),
       GNUNET_i2s (&msg->sender),
       udp_address_to_string (NULL,
                              mc->udp_addr,
                              mc->udp_addr_len));
  hello = (struct GNUNET_MessageHeader *) &msg[1];
  address = GNUNET_HELLO_address_allocate (&msg->sender,
                                           PLUGIN_NAME,
                                           mc->udp_addr,
                                           mc->udp_addr_len,
                                           GNUNET_HELLO_ADDRESS_INFO_NONE);
  plugin->env->receive (plugin->env->cls,
                        address,
                        NULL,
                        hello);
  GNUNET_HELLO_address_free (address);
  GNUNET_STATISTICS_update (plugin->env->stats,
                            _("# Multicast HELLO beacons received via UDP"),
                            1, GNUNET_NO);
  return GNUNET_OK;
}
/**
 * Function called with responses from the service.
 *
 * @param cls our `struct GNUNET_TRANSPORT_ValidationMonitoringContext *`
 * @param msg NULL on timeout or error, otherwise presumably a
 *        message with the human-readable address
 */
static void
val_response_processor (void *cls,
                        const struct GNUNET_MessageHeader *msg)
{
  struct GNUNET_TRANSPORT_ValidationMonitoringContext *val_ctx = cls;
  struct ValidationIterateResponseMessage *vr_msg;
  struct GNUNET_HELLO_Address *address;
  const char *addr;
  const char *transport_name;
  size_t size;
  size_t tlen;
  size_t alen;

  if (NULL == msg)
  {
    if (val_ctx->one_shot)
    {
      /* Disconnect */
      val_ctx->cb (val_ctx->cb_cls, NULL,
          GNUNET_TIME_UNIT_ZERO_ABS, GNUNET_TIME_UNIT_ZERO_ABS,
          GNUNET_TIME_UNIT_ZERO_ABS, GNUNET_TRANSPORT_VS_TIMEOUT);
      GNUNET_TRANSPORT_monitor_validation_entries_cancel (val_ctx);
    }
    else
    {
      reconnect_val_ctx (val_ctx);
    }
    return;
  }
  size = ntohs (msg->size);
  GNUNET_break (ntohs (msg->type) ==
      GNUNET_MESSAGE_TYPE_TRANSPORT_MONITOR_VALIDATION_RESPONSE);

  if (size == sizeof (struct GNUNET_MessageHeader))
  {
    /* Done! */
    if (val_ctx->one_shot)
    {
      val_ctx->cb (val_ctx->cb_cls, NULL,
          GNUNET_TIME_UNIT_ZERO_ABS, GNUNET_TIME_UNIT_ZERO_ABS,
          GNUNET_TIME_UNIT_ZERO_ABS, GNUNET_TRANSPORT_VS_NONE);
      GNUNET_TRANSPORT_monitor_validation_entries_cancel (val_ctx);
    }
    else
    {
      reconnect_val_ctx (val_ctx);
    }
    return;
  }

  if ((size < sizeof (struct ValidationIterateResponseMessage)) ||
      (ntohs (msg->type) != GNUNET_MESSAGE_TYPE_TRANSPORT_MONITOR_VALIDATION_RESPONSE))
  {
    GNUNET_break (0);
    if (val_ctx->one_shot)
    {
      val_ctx->cb (val_ctx->cb_cls, NULL,
          GNUNET_TIME_UNIT_ZERO_ABS, GNUNET_TIME_UNIT_ZERO_ABS,
          GNUNET_TIME_UNIT_ZERO_ABS, GNUNET_TRANSPORT_VS_NONE);
      GNUNET_TRANSPORT_monitor_validation_entries_cancel (val_ctx);
    }
    else
    {
      reconnect_val_ctx (val_ctx);
    }
    return;
  }

  vr_msg = (struct ValidationIterateResponseMessage *) msg;
  tlen = ntohl (vr_msg->pluginlen);
  alen = ntohl (vr_msg->addrlen);

  if (size != sizeof (struct ValidationIterateResponseMessage) + tlen + alen)
  {
    GNUNET_break (0);
    if (val_ctx->one_shot)
    {
      val_ctx->cb (val_ctx->cb_cls, NULL,
          GNUNET_TIME_UNIT_ZERO_ABS, GNUNET_TIME_UNIT_ZERO_ABS,
          GNUNET_TIME_UNIT_ZERO_ABS, GNUNET_TRANSPORT_VS_NONE);
      GNUNET_TRANSPORT_monitor_validation_entries_cancel (val_ctx);
    }
    else
    {
      reconnect_val_ctx (val_ctx);
    }
    return;
  }
  if (0 == tlen)
  {
    GNUNET_break (0); /* This must not happen: address without plugin */
    return;
  }
  addr = (const char *) &vr_msg[1];
  transport_name = &addr[alen];
  
  if (transport_name[tlen - 1] != '\0')
  {
    /* Corrupt plugin name */
    GNUNET_break (0);
    if (val_ctx->one_shot)
    {
      val_ctx->cb (val_ctx->cb_cls,
		   NULL,
		   GNUNET_TIME_UNIT_ZERO_ABS,
		   GNUNET_TIME_UNIT_ZERO_ABS,
		   GNUNET_TIME_UNIT_ZERO_ABS,
		   GNUNET_TRANSPORT_VS_NONE);
      GNUNET_TRANSPORT_monitor_validation_entries_cancel (val_ctx);
    }
    else
    {
      reconnect_val_ctx (val_ctx);
    }
    return;
  }
  
  /* notify client */
  address = GNUNET_HELLO_address_allocate (&vr_msg->peer,
					   transport_name,
					   addr, alen,
					   ntohl (vr_msg->local_address_info));
  val_ctx->cb (val_ctx->cb_cls,
	       address,
	       GNUNET_TIME_absolute_ntoh (vr_msg->last_validation),
	       GNUNET_TIME_absolute_ntoh (vr_msg->valid_until),
	       GNUNET_TIME_absolute_ntoh (vr_msg->next_validation),
	       ntohl(vr_msg->state));
  GNUNET_HELLO_address_free (address);
  /* expect more replies */
  GNUNET_CLIENT_receive (val_ctx->client,
                         &val_response_processor,
                         val_ctx,
                         GNUNET_TIME_absolute_get_remaining (val_ctx->timeout));
}
/**
 * Function called with responses from the service.
 *
 * @param cls our 'struct GNUNET_TRANSPORT_PeerMonitoringContext*'
 * @param msg NULL on timeout or error, otherwise presumably a
 *        message with the human-readable address
 */
static void
peer_response_processor (void *cls, const struct GNUNET_MessageHeader *msg)
{
  struct GNUNET_TRANSPORT_PeerMonitoringContext *pal_ctx = cls;
  struct PeerIterateResponseMessage *pir_msg;
  struct GNUNET_HELLO_Address *address;
  const char *addr;
  const char *transport_name;
  uint16_t size;
  size_t alen;
  size_t tlen;

  if (msg == NULL)
  {
    if (pal_ctx->one_shot)
    {
      /* Disconnect */
      pal_ctx->cb (pal_ctx->cb_cls, NULL, NULL,
          GNUNET_TRANSPORT_PS_NOT_CONNECTED, GNUNET_TIME_UNIT_ZERO_ABS);
      GNUNET_TRANSPORT_monitor_peers_cancel (pal_ctx);
    }
    else
    {
      reconnect_peer_ctx (pal_ctx);
    }
    return;
  }
  size = ntohs (msg->size);
  GNUNET_break (ntohs (msg->type) ==
      GNUNET_MESSAGE_TYPE_TRANSPORT_MONITOR_PEER_RESPONSE);
  if (size == sizeof (struct GNUNET_MessageHeader))
  {
    /* Done! */
    if (pal_ctx->one_shot)
    {
      pal_ctx->cb (pal_ctx->cb_cls, NULL, NULL,
          GNUNET_TRANSPORT_PS_NOT_CONNECTED, GNUNET_TIME_UNIT_ZERO_ABS);
      GNUNET_TRANSPORT_monitor_peers_cancel (pal_ctx);
    }
    else
    {
      reconnect_peer_ctx (pal_ctx);
    }
    return;
  }

  if ((size < sizeof (struct PeerIterateResponseMessage)) ||
      (ntohs (msg->type) != GNUNET_MESSAGE_TYPE_TRANSPORT_MONITOR_PEER_RESPONSE))
  {
    GNUNET_break (0);
    if (pal_ctx->one_shot)
    {
      pal_ctx->cb (pal_ctx->cb_cls, NULL, NULL,
          GNUNET_TRANSPORT_PS_NOT_CONNECTED, GNUNET_TIME_UNIT_ZERO_ABS);
      GNUNET_TRANSPORT_monitor_peers_cancel (pal_ctx);
    }
    else
    {
      reconnect_peer_ctx (pal_ctx);
    }
    return;
  }

  pir_msg = (struct PeerIterateResponseMessage *) msg;
  tlen = ntohl (pir_msg->pluginlen);
  alen = ntohl (pir_msg->addrlen);

  if (size != sizeof (struct PeerIterateResponseMessage) + tlen + alen)
  {
    GNUNET_break (0);
    if (pal_ctx->one_shot)
    {
      pal_ctx->cb (pal_ctx->cb_cls, NULL, NULL,
          GNUNET_TRANSPORT_PS_NOT_CONNECTED, GNUNET_TIME_UNIT_ZERO_ABS);
      GNUNET_TRANSPORT_monitor_peers_cancel (pal_ctx);
    }
    else
    {
      reconnect_peer_ctx (pal_ctx);
    }
    return;
  }

  if ( (0 == tlen) && (0 == alen) )
  {
    /* No address available */
    pal_ctx->cb (pal_ctx->cb_cls, &pir_msg->peer, NULL,
        ntohl(pir_msg->state),
        GNUNET_TIME_absolute_ntoh (pir_msg->state_timeout));
  }
  else
  {
    if (0 == tlen)
    {
      GNUNET_break (0); /* This must not happen: address without plugin */
      return;
    }
    addr = (const char *) &pir_msg[1];
    transport_name = &addr[alen];

    if (transport_name[tlen - 1] != '\0')
    {
      /* Corrupt plugin name */
      GNUNET_break (0);
      if (pal_ctx->one_shot)
      {
        pal_ctx->cb (pal_ctx->cb_cls, NULL, NULL,
            GNUNET_TRANSPORT_PS_NOT_CONNECTED, GNUNET_TIME_UNIT_ZERO_ABS);
        GNUNET_TRANSPORT_monitor_peers_cancel (pal_ctx);
      }
      else
      {
        reconnect_peer_ctx (pal_ctx);
      }
      return;
    }

    /* notify client */
    address = GNUNET_HELLO_address_allocate (&pir_msg->peer,
        transport_name, addr, alen, ntohl(pir_msg->local_address_info));
    pal_ctx->cb (pal_ctx->cb_cls, &pir_msg->peer, address,
        ntohl(pir_msg->state),
        GNUNET_TIME_absolute_ntoh (pir_msg->state_timeout));
    GNUNET_HELLO_address_free (address);

  }

  /* expect more replies */
  GNUNET_CLIENT_receive (pal_ctx->client, &peer_response_processor,
                         pal_ctx,
                         GNUNET_TIME_absolute_get_remaining (pal_ctx->timeout));
}