Ejemplo n.º 1
0
/**
 * Ask the client to call us once the specified number of bytes
 * are free in the transmission buffer.  May call the notify
 * method immediately if enough space is available.
 *
 * @param client connection to the service
 * @param size number of bytes to send
 * @param timeout after how long should we give up (and call
 *        notify with buf NULL and size 0)?
 * @param auto_retry if the connection to the service dies, should we
 *        automatically re-connect and retry (within the timeout period)
 *        or should we immediately fail in this case?  Pass GNUNET_YES
 *        if the caller does not care about temporary connection errors,
 *        for example because the protocol is stateless
 * @param notify function to call
 * @param notify_cls closure for notify
 * @return NULL if our buffer will never hold size bytes,
 *         a handle if the notify callback was queued (can be used to cancel)
 */
struct GNUNET_CLIENT_TransmitHandle *
GNUNET_CLIENT_notify_transmit_ready (struct GNUNET_CLIENT_Connection *client,
                                     size_t size,
                                     struct GNUNET_TIME_Relative timeout,
                                     int auto_retry,
                                     GNUNET_CONNECTION_TransmitReadyNotify
                                     notify, void *notify_cls)
{
  struct GNUNET_CLIENT_TransmitHandle *th;

  if (NULL != client->th)
  {
    /* If this breaks, you most likley called this function twice without waiting
     * for completion or canceling the request */
    GNUNET_break (0);
    return NULL;
  }
  th = GNUNET_malloc (sizeof (struct GNUNET_CLIENT_TransmitHandle));
  th->client = client;
  th->size = size;
  th->timeout = GNUNET_TIME_relative_to_absolute (timeout);
  /* always auto-retry on first message to service */
  th->auto_retry = (GNUNET_YES == client->first_message) ? GNUNET_YES : auto_retry;
  client->first_message = GNUNET_NO;
  th->notify = notify;
  th->notify_cls = notify_cls;
  th->attempts_left = MAX_ATTEMPTS;
  client->th = th;
  if (NULL == client->connection)
  {
    th->reconnect_task =
        GNUNET_SCHEDULER_add_delayed (client->back_off, &client_delayed_retry,
                                      th);

  }
  else
  {
    th->th =
        GNUNET_CONNECTION_notify_transmit_ready (client->connection, size, timeout,
                                                 &client_notify, th);
    if (NULL == th->th)
    {
      GNUNET_break (0);
      GNUNET_free (th);
      client->th = NULL;
      return NULL;
    }
  }
  return th;
}
Ejemplo n.º 2
0
static void
task_timeout (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
{

  ls = open_listen_socket ();
  lsock = GNUNET_CONNECTION_create_from_existing (ls);
  GNUNET_assert (lsock != NULL);
  csock = GNUNET_CONNECTION_create_from_connect (cfg, "localhost", PORT);
  GNUNET_assert (csock != NULL);
  GNUNET_assert (NULL !=
                 GNUNET_CONNECTION_notify_transmit_ready (csock, 1024,
                                                          GNUNET_TIME_UNIT_SECONDS,
                                                          &send_kilo, cls));
}
Ejemplo n.º 3
0
static void
task (void *cls)
{
  ls = open_listen_socket ();
  lsock = GNUNET_CONNECTION_create_from_existing (ls);
  GNUNET_assert (lsock != NULL);
  csock = GNUNET_CONNECTION_create_from_connect (cfg, "localhost", PORT);
  GNUNET_assert (csock != NULL);
  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Test asks for write notification\n");
  GNUNET_assert (NULL !=
                 GNUNET_CONNECTION_notify_transmit_ready (csock, 12,
                                                          GNUNET_TIME_UNIT_SECONDS,
                                                          &make_hello, NULL));
  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Test prepares to accept\n");
  GNUNET_SCHEDULER_add_read_net (GNUNET_TIME_UNIT_FOREVER_REL, ls, &run_accept,
                                 cls);
}
Ejemplo n.º 4
0
/**
 * Register SOCKS5 handshake sender
 *
 * @param ih handshake
 * @return non-NULL if the notify callback was queued,
 *         NULL if we are already going to notify someone else (busy)
 */
struct GNUNET_CONNECTION_TransmitHandle *
register_sender (struct GNUNET_SOCKS_Handshake *ih)
{
  struct GNUNET_TIME_Relative timeout = GNUNET_TIME_UNIT_MINUTES;

  GNUNET_assert (SOCKS5_step_done > ih->step);
  GNUNET_assert (ih->step >= 0);
  if (0 == ih->step)
    timeout = GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 3);
  unsigned char * b = ih->outstep[ih->step];
  unsigned char * e = ih->outstep[ih->step+1];
  GNUNET_assert (ih->outbuf <= b && b < e && e < &ih->outbuf[1024]);
  ih->th = GNUNET_CONNECTION_notify_transmit_ready (ih->socks5_connection,
                                                    e - b,
                                                    timeout,
                                                    &transmit_ready,
                                                    ih);
  return ih->th;
}
Ejemplo n.º 5
0
/**
 * This task is run if we should re-try connection to the
 * service after a while.
 *
 * @param cls our "struct GNUNET_CLIENT_TransmitHandle" of the request
 * @param tc unused
 */
static void
client_delayed_retry (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
{
  struct GNUNET_CLIENT_TransmitHandle *th = cls;
  struct GNUNET_TIME_Relative delay;

  th->reconnect_task = GNUNET_SCHEDULER_NO_TASK;
  th->client->connection =
      do_connect (th->client->service_name, th->client->cfg, th->client->attempts++);
  th->client->first_message = GNUNET_YES;
  if (NULL == th->client->connection)
  {
    /* could happen if we're out of sockets */
    delay =
        GNUNET_TIME_relative_min (GNUNET_TIME_absolute_get_remaining
                                  (th->timeout), th->client->back_off);
    th->client->back_off =
        GNUNET_TIME_relative_min (GNUNET_TIME_relative_multiply
                                  (th->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));
    th->reconnect_task =
        GNUNET_SCHEDULER_add_delayed (delay, &client_delayed_retry, th);
    return;
  }
  th->th =
      GNUNET_CONNECTION_notify_transmit_ready (th->client->connection, th->size,
                                               GNUNET_TIME_absolute_get_remaining
                                               (th->timeout), &client_notify,
                                               th);
  if (NULL == th->th)
  {
    GNUNET_break (0);
    th->client->th = NULL;
    th->notify (th->notify_cls, 0, NULL);
    GNUNET_free (th);
    return;
  }
}
Ejemplo n.º 6
0
static size_t
send_kilo (void *cls, size_t size, void *buf)
{
  int *ok = cls;

  if (size == 0)
  {
    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Got the desired timeout!\n");
    GNUNET_assert (buf == NULL);
    *ok = 0;
    GNUNET_CONNECTION_destroy (lsock);
    GNUNET_CONNECTION_destroy (csock);
    return 0;
  }
  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Sending kilo to fill buffer.\n");
  GNUNET_assert (size >= 1024);
  memset (buf, 42, 1024);

  GNUNET_assert (NULL !=
                 GNUNET_CONNECTION_notify_transmit_ready (csock, 1024,
                                                          GNUNET_TIME_UNIT_SECONDS,
                                                          &send_kilo, cls));
  return 1024;
}