コード例 #1
0
/**
 * Construct our HELLO message from all of the addresses of
 * all of the transports.
 *
 * @param cls unused
 * @param tc scheduler context
 */
static void
refresh_hello_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
{
  struct GeneratorContext gc;
  int friend_only;

  hello_task = GNUNET_SCHEDULER_NO_TASK;
  gc.addr_pos = oal_head;
  gc.expiration = GNUNET_TIME_relative_to_absolute (hello_expiration);


  friend_only = GNUNET_HELLO_is_friend_only (our_hello);
  GNUNET_free (our_hello);
  our_hello = GNUNET_HELLO_create (&GST_my_public_key, &address_generator, &gc, friend_only);
  GNUNET_assert (NULL != our_hello);
  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
              "Refreshed my %s `%s', new size is %d\n",
              (GNUNET_YES == GNUNET_HELLO_is_friend_only (our_hello)) ? "friend-only" : "public",
              "HELLO", GNUNET_HELLO_size (our_hello));
  GNUNET_STATISTICS_update (GST_stats, gettext_noop ("# refreshed my HELLO"), 1,
                            GNUNET_NO);
  if (NULL != hello_cb)
    hello_cb (hello_cb_cls, GST_hello_get ());
  GNUNET_PEERINFO_add_peer (GST_peerinfo, our_hello, NULL, NULL);
  hello_task =
      GNUNET_SCHEDULER_add_delayed (HELLO_REFRESH_PERIOD, &refresh_hello_task,
                                    NULL);

}
コード例 #2
0
/**
 * Initialize a normal client.  We got a start message from this
 * client, add him to the list of clients for broadcasting of inbound
 * messages.
 *
 * @param cls unused
 * @param client the client
 * @param message the start message that was sent
 */
static void
clients_handle_start (void *cls, struct GNUNET_SERVER_Client *client,
                      const struct GNUNET_MessageHeader *message)
{
  const struct StartMessage *start;
  struct TransportClient *tc;
  uint32_t options;

  tc = lookup_client (client);

  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK,
              "Client %p sent START\n", tc);
  if (tc != NULL)
  {
    /* got 'start' twice from the same client, not allowed */
    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG | GNUNET_ERROR_TYPE_BULK,
                "TransportClient %p ServerClient %p sent multiple START messages\n",
                tc, tc->client);
    GNUNET_break (0);
    GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
    return;
  }
  start = (const struct StartMessage *) message;
  options = ntohl (start->options);
  if ((0 != (1 & options)) &&
      (0 !=
       memcmp (&start->self, &GST_my_identity,
               sizeof (struct GNUNET_PeerIdentity))))
  {
    /* client thinks this is a different peer, reject */
    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                _
                ("Rejecting control connection from peer `%s', which is not me!\n"),
                GNUNET_i2s (&start->self));
    GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
    return;
  }
  tc = setup_client (client);
  tc->send_payload = (0 != (2 & options));
  unicast (tc, GST_hello_get (), GNUNET_NO);
  GST_neighbours_iterate (&notify_client_about_neighbour, tc);
  GNUNET_CONTAINER_DLL_insert (clients_head, clients_tail, tc);
  GNUNET_SERVER_receive_done (client, GNUNET_OK);
}
コード例 #3
0
/**
 * Initiate transport service.
 *
 * @param cls closure
 * @param server the initialized server
 * @param c configuration to use
 */
static void
run (void *cls, struct GNUNET_SERVER_Handle *server,
     const struct GNUNET_CONFIGURATION_Handle *c)
{
  char *keyfile;
  struct GNUNET_CRYPTO_RsaPublicKeyBinaryEncoded tmp;
  /* setup globals */
  GST_cfg = c;
  if (GNUNET_OK !=
      GNUNET_CONFIGURATION_get_value_filename (c, "GNUNETD", "HOSTKEY",
                                               &keyfile))
  {
    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                _
                ("Transport service is lacking key configuration settings.  Exiting.\n"));
    GNUNET_SCHEDULER_shutdown ();
    return;
  }
  GST_my_private_key = GNUNET_CRYPTO_rsa_key_create_from_file (keyfile);
  GNUNET_free (keyfile);
  if (GST_my_private_key == NULL)
  {
    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                _("Transport service could not access hostkey.  Exiting.\n"));
    GNUNET_SCHEDULER_shutdown ();
    return;
  }
  GST_stats = GNUNET_STATISTICS_create ("transport", c);
  GST_peerinfo = GNUNET_PEERINFO_connect (c);
  memset (&GST_my_public_key, '\0', sizeof (GST_my_public_key));
  memset (&tmp, '\0', sizeof (tmp));
  GNUNET_CRYPTO_rsa_key_get_public (GST_my_private_key, &GST_my_public_key);
  GNUNET_CRYPTO_hash (&GST_my_public_key, sizeof (GST_my_public_key),
                      &GST_my_identity.hashPubKey);

  GNUNET_assert (NULL != GST_my_private_key);
  GNUNET_assert (0 != memcmp (&GST_my_public_key, &tmp, sizeof (GST_my_public_key)));

  GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &shutdown_task,
                                NULL);
  if (GST_peerinfo == NULL)
  {
    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                _("Could not access PEERINFO service.  Exiting.\n"));
    GNUNET_SCHEDULER_shutdown ();
    return;
  }

  /* start subsystems */
  GST_hello_start (&process_hello_update, NULL);
  GNUNET_assert (NULL != GST_hello_get());
  GST_blacklist_start (server);
  GST_ats =
      GNUNET_ATS_scheduling_init (GST_cfg, &ats_request_address_change, NULL);
  GST_plugins_load (&plugin_env_receive_callback,
                    &plugin_env_address_change_notification,
                    &plugin_env_session_end,
                    &plugin_env_address_to_type);
  GST_neighbours_start (NULL,
                        &neighbours_connect_notification,
                        &neighbours_disconnect_notification,
                        &neighbours_address_notification);
  GST_clients_start (server);
  GST_validation_start ();
}
コード例 #4
0
/**
 * Function called with the result from blacklisting.
 * Send a PING to the other peer if a communication is allowed.
 *
 * @param cls our 'struct ValidationEntry'
 * @param pid identity of the other peer
 * @param result GNUNET_OK if the connection is allowed, GNUNET_NO if not
 */
static void
transmit_ping_if_allowed (void *cls, const struct GNUNET_PeerIdentity *pid,
                          int result)
{
  struct ValidationEntry *ve = cls;
  struct TransportPingMessage ping;
  struct GNUNET_TRANSPORT_PluginFunctions *papi;
  const struct GNUNET_MessageHeader *hello;
  ssize_t ret;
  size_t tsize;
  size_t slen;
  uint16_t hsize;

  ve->bc = NULL;
  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Transmitting plain PING to `%s' %s\n",
              GNUNET_i2s (pid), GST_plugins_a2s (ve->address));

  slen = strlen (ve->address->transport_name) + 1;
  hello = GST_hello_get ();
  hsize = ntohs (hello->size);
  tsize =
      sizeof (struct TransportPingMessage) + ve->address->address_length +
      slen + hsize;

  ping.header.size =
      htons (sizeof (struct TransportPingMessage) +
             ve->address->address_length + slen);
  ping.header.type = htons (GNUNET_MESSAGE_TYPE_TRANSPORT_PING);
  ping.challenge = htonl (ve->challenge);
  ping.target = *pid;

  if (tsize >= GNUNET_SERVER_MAX_MESSAGE_SIZE)
  {
    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                _
                ("Not transmitting `%s' with `%s', message too big (%u bytes!). This should not happen.\n"),
                "HELLO", "PING", (unsigned int) tsize);
    /* message too big (!?), get rid of HELLO */
    hsize = 0;
    tsize =
        sizeof (struct TransportPingMessage) + ve->address->address_length +
        slen + hsize;
  }
  {
    char message_buf[tsize];

    /* build message with structure:
     *  [HELLO][TransportPingMessage][Transport name][Address] */
    memcpy (message_buf, hello, hsize);
    memcpy (&message_buf[hsize], &ping, sizeof (struct TransportPingMessage));
    memcpy (&message_buf[sizeof (struct TransportPingMessage) + hsize],
            ve->address->transport_name, slen);
    memcpy (&message_buf[sizeof (struct TransportPingMessage) + slen + hsize],
            ve->address, ve->address->address_length);
    papi = GST_plugins_find (ve->address->transport_name);
    if (papi == NULL)
      ret = -1;
    else
    {
      GNUNET_assert (papi->send != NULL);
      GNUNET_assert (papi->get_session != NULL);
      struct Session * session = papi->get_session(papi->cls, ve->address);

      if (session != NULL)
      {
        ret = papi->send (papi->cls, session,
                          message_buf, tsize,
                          PING_PRIORITY, ACCEPTABLE_PING_DELAY,
                          NULL, NULL);
      }
      else
      {
        /* Could not get a valid session */
        GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Could not get a valid session for `%s' %s\n",
                    GNUNET_i2s (pid), GST_plugins_a2s (ve->address));
        ret = -1;
      }
    }
  }
  if (-1 != ret)
  {
    ve->send_time = GNUNET_TIME_absolute_get ();
    GNUNET_STATISTICS_update (GST_stats,
                              gettext_noop
                              ("# PING without HELLO messages sent"), 1,
                              GNUNET_NO);
    ve->expecting_pong = GNUNET_YES;
  }
}