Exemple #1
0
/**
 * Listen for incoming messages on this chat room.  Also, support servers going
 * away/coming back (i.e. rejoin chat room to keep server state up to date).
 *
 * @param cls closure, pointer to the 'struct GNUNET_CHAT_Room'
 * @param msg message received, NULL on timeout or fatal error
 */
static void
receive_results (void *cls, const struct GNUNET_MessageHeader *msg)
{
  struct GNUNET_CHAT_Room *chat_room = cls;

#if DEBUG_CHAT
  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Got a message from the service\n");
#endif
  if (0 != (GNUNET_SCHEDULER_REASON_SHUTDOWN & GNUNET_SCHEDULER_get_reason ()))
    return;
  if (NULL == msg)
  {
    GNUNET_break (0);
    rejoin_room (chat_room);
    return;
  }
  process_result (chat_room, msg);
  if (NULL == chat_room->client)
    return;                     /* fatal error */
  /* continue receiving */
  GNUNET_CLIENT_receive (chat_room->client, &receive_results, chat_room,
                         GNUNET_TIME_UNIT_FOREVER_REL);
}
Exemple #2
0
/**
 * Connection notifies us about failure or success of a transmission
 * request.  Either pass it on to our user or, if possible, retry.
 *
 * @param cls our `struct GNUNET_CLIENT_TransmissionHandle`
 * @param size number of bytes available for transmission
 * @param buf where to write them
 * @return number of bytes written to @a buf
 */
static size_t
client_notify (void *cls,
               size_t size,
               void *buf)
{
  struct GNUNET_CLIENT_TransmitHandle *th = cls;
  struct GNUNET_CLIENT_Connection *client = th->client;
  size_t ret;
  struct GNUNET_TIME_Relative delay;

  LOG (GNUNET_ERROR_TYPE_DEBUG,
       "client_notify is running\n");
  th->th = NULL;
  client->th = NULL;
  if (NULL == buf)
  {
    delay = GNUNET_TIME_absolute_get_remaining (th->timeout);
    delay.rel_value_us /= 2;
    if ( (GNUNET_YES != th->auto_retry) ||
         (0 == --th->attempts_left) ||
         (delay.rel_value_us < 1)||
         (0 != (GNUNET_SCHEDULER_get_reason() & GNUNET_SCHEDULER_REASON_SHUTDOWN)))
    {
      LOG (GNUNET_ERROR_TYPE_DEBUG,
           "Transmission failed %u times, giving up.\n",
           MAX_ATTEMPTS - th->attempts_left);
      GNUNET_break (0 ==
                    th->notify (th->notify_cls, 0, NULL));
      GNUNET_free (th);
      return 0;
    }
    /* auto-retry */
    LOG (GNUNET_ERROR_TYPE_DEBUG,
         "Failed to connect to `%s', automatically trying again.\n",
         client->service_name);
    if (GNUNET_YES == client->in_receive)
    {
      GNUNET_CONNECTION_receive_cancel (client->connection);
      client->in_receive = GNUNET_NO;
    }
    GNUNET_CONNECTION_destroy (client->connection);
    client->connection = NULL;
    delay = GNUNET_TIME_relative_min (delay, client->back_off);
    client->back_off =
        GNUNET_TIME_relative_min (GNUNET_TIME_relative_multiply
                                  (client->back_off, 2),
                                  GNUNET_TIME_UNIT_SECONDS);
    LOG (GNUNET_ERROR_TYPE_DEBUG,
         "Transmission failed %u times, trying again in %s.\n",
         MAX_ATTEMPTS - th->attempts_left,
         GNUNET_STRINGS_relative_time_to_string (delay, GNUNET_YES));
    client->th = th;
    GNUNET_assert (NULL == th->reconnect_task);
    GNUNET_assert (NULL == th->th);
    th->reconnect_task =
        GNUNET_SCHEDULER_add_delayed (delay, &client_delayed_retry, th);
    return 0;
  }
  GNUNET_assert (size >= th->size);
  ret = th->notify (th->notify_cls, size, buf);
  GNUNET_free (th);
  if (sizeof (struct GNUNET_MessageHeader) <= ret)
  {
    LOG (GNUNET_ERROR_TYPE_DEBUG,
         "Transmitting message of type %u and size %u to %s service.\n",
         ntohs (((struct GNUNET_MessageHeader *) buf)->type),
         ntohs (((struct GNUNET_MessageHeader *) buf)->size),
         client->service_name);
  }
  return ret;
}