Ejemplo n.º 1
0
static void
receive_check (void *cls, const void *buf, size_t available,
               const struct sockaddr *addr, socklen_t addrlen, int errCode)
{
  int *ok = cls;

  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Receive validates incoming data\n");
  GNUNET_assert (buf != NULL);  /* no timeout */
  if (0 == memcmp (&"Hello World"[sofar], buf, available))
    sofar += available;
  if (sofar < 12)
  {
    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Receive needs more data\n");
    GNUNET_CONNECTION_receive (asock, 1024,
                               GNUNET_TIME_relative_multiply
                               (GNUNET_TIME_UNIT_SECONDS, 5), &receive_check,
                               cls);
  }
  else
  {
    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Receive closes accepted socket\n");
    *ok = 0;
    GNUNET_CONNECTION_destroy (asock);
    GNUNET_CONNECTION_destroy (csock);
  }
}
static void
run_accept (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
{
  void *addr;
  size_t alen;
  struct sockaddr_in *v4;
  struct sockaddr_in expect;

  asock = GNUNET_CONNECTION_create_from_accept (NULL, NULL, ls);
  GNUNET_assert (asock != NULL);
  GNUNET_assert (GNUNET_YES == GNUNET_CONNECTION_check (asock));
  GNUNET_assert (GNUNET_OK ==
                 GNUNET_CONNECTION_get_address (asock, &addr, &alen));
  GNUNET_assert (alen == sizeof (struct sockaddr_in));
  v4 = addr;
  memset (&expect, 0, sizeof (expect));
#if HAVE_SOCKADDR_IN_SIN_LEN
  expect.sin_len = sizeof (expect);
#endif
  expect.sin_family = AF_INET;
  expect.sin_port = v4->sin_port;
  expect.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
  GNUNET_assert (0 == memcmp (&expect, v4, alen));
  GNUNET_free (addr);
  GNUNET_CONNECTION_destroy (lsock);
  GNUNET_CONNECTION_receive (asock, 1024,
                             GNUNET_TIME_relative_multiply
                             (GNUNET_TIME_UNIT_SECONDS, 5), &receive_check,
                             cls);
}
Ejemplo n.º 3
0
/**
 * Destroy connection with the service.  This will automatically
 * cancel any pending "receive" request (however, the handler will
 * *NOT* be called, not even with a NULL message).  Any pending
 * transmission request will also be cancelled UNLESS the callback for
 * the transmission request has already been called, in which case the
 * transmission 'finish_pending_write' argument determines whether or
 * not the write is guaranteed to complete before the socket is fully
 * destroyed (unless, of course, there is an error with the server in
 * which case the message may still be lost).
 *
 * @param client handle to the service connection
 */
void
GNUNET_CLIENT_disconnect (struct GNUNET_CLIENT_Connection *client)
{
  if (GNUNET_YES == client->in_receive)
  {
    GNUNET_CONNECTION_receive_cancel (client->connection);
    client->in_receive = GNUNET_NO;
  }
  if (NULL != client->th)
  {
    GNUNET_CLIENT_notify_transmit_ready_cancel (client->th);
    client->th = NULL;
  }
  if (NULL != client->connection)
  {
    GNUNET_CONNECTION_destroy (client->connection);
    client->connection = NULL;
  }
  if (GNUNET_SCHEDULER_NO_TASK != client->receive_task)
  {
    GNUNET_SCHEDULER_cancel (client->receive_task);
    client->receive_task = GNUNET_SCHEDULER_NO_TASK;
  }
  if (NULL != client->tag)
  {
    GNUNET_free (client->tag);
    client->tag = NULL;
  }
  client->receiver_handler = NULL;
  GNUNET_array_grow (client->received_buf, client->received_size, 0);
  GNUNET_free (client->service_name);
  GNUNET_free (client);
}
Ejemplo n.º 4
0
/**
 * We've failed for good to establish a connection (timeout or
 * no more addresses to try).
 *
 * @param connection the connection we tried to establish
 */
static void
connect_fail_continuation (struct GNUNET_CONNECTION_Handle *connection)
{
  LOG (GNUNET_ERROR_TYPE_INFO,
       _("Failed to establish TCP connection to `%s:%u', no further addresses to try.\n"),
       connection->hostname, connection->port);
  GNUNET_break (NULL == connection->ap_head);
  GNUNET_break (NULL == connection->ap_tail);
  GNUNET_break (GNUNET_NO == connection->dns_active);
  GNUNET_break (NULL == connection->sock);
  GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == connection->write_task);

  /* signal errors for jobs that used to wait on the connection */
  connection->destroy_later = 1;
  if (NULL != connection->receiver)
    signal_receive_error (connection, ECONNREFUSED);
  if (NULL != connection->nth.notify_ready)
  {
    GNUNET_assert (connection->nth.timeout_task != GNUNET_SCHEDULER_NO_TASK);
    GNUNET_SCHEDULER_cancel (connection->nth.timeout_task);
    connection->nth.timeout_task = GNUNET_SCHEDULER_NO_TASK;
    signal_transmit_error (connection, ECONNREFUSED);
  }
  if (-1 == connection->destroy_later)
  {
    /* do it now */
    connection->destroy_later = 0;
    GNUNET_CONNECTION_destroy (connection);
    return;
  }
  connection->destroy_later = 0;
}
Ejemplo n.º 5
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 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;

  th->th = NULL;
  client->th = NULL;
  if (NULL == buf)
  {
    delay = GNUNET_TIME_absolute_get_remaining (th->timeout);
    delay.rel_value /= 2;
    if ((GNUNET_YES != th->auto_retry) || (0 == --th->attempts_left) ||
        (delay.rel_value < 1))
    {
      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;
    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);
  return ret;
}
static void
receive_check (void *cls, const void *buf, size_t available,
               const struct sockaddr *addr, socklen_t addrlen, int errCode)
{
  int *ok = cls;

  GNUNET_assert (buf != NULL);  /* no timeout */
  if (0 == memcmp (&"Hello World"[sofar], buf, available))
    sofar += available;
  if (sofar < 12)
  {
    GNUNET_CONNECTION_receive (asock, 1024,
                               GNUNET_TIME_relative_multiply
                               (GNUNET_TIME_UNIT_SECONDS, 5), &receive_check,
                               cls);
  }
  else
  {
    *ok = 0;
    GNUNET_CONNECTION_destroy (csock);
    GNUNET_CONNECTION_destroy (asock);
  }
}
Ejemplo n.º 7
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;
}
Ejemplo n.º 8
0
static void
run_accept (void *cls)
{
  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Test accepts connection\n");
  asock = GNUNET_CONNECTION_create_from_accept (NULL, NULL, ls);
  GNUNET_assert (asock != NULL);
  GNUNET_assert (GNUNET_YES == GNUNET_CONNECTION_check (asock));
  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Test destroys listen socket\n");
  GNUNET_CONNECTION_destroy (lsock);
  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
              "Test asks to receive on accepted socket\n");
  GNUNET_CONNECTION_receive (asock, 1024,
                             GNUNET_TIME_relative_multiply
                             (GNUNET_TIME_UNIT_SECONDS, 5), &receive_check,
                             cls);
}