/**
 * Queues a message in send queue of the logger handle
 *
 * @param h the logger handle
 * @param msg the message to queue
 */
static void
queue_message (struct GNUNET_TESTBED_LOGGER_Handle *h,
               struct GNUNET_MessageHeader *msg)
{
  struct MessageQueue *mq;
  uint16_t type;
  uint16_t size;

  type = ntohs (msg->type);
  size = ntohs (msg->size);
  mq = GNUNET_new (struct MessageQueue);
  mq->msg = msg;
  LOG (GNUNET_ERROR_TYPE_DEBUG,
       "Queueing message of type %u, size %u for sending\n", type,
       ntohs (msg->size));
  GNUNET_CONTAINER_DLL_insert_tail (h->mq_head, h->mq_tail, mq);
  if (NULL == h->th)
  {
    h->retry_backoff = GNUNET_TIME_STD_BACKOFF (h->retry_backoff);
    h->th =
        GNUNET_CLIENT_notify_transmit_ready (h->client, size,
                                             h->retry_backoff, GNUNET_YES,
                                             &transmit_ready_notify,
                                             h);
  }
}
Exemple #2
0
/**
 * Close down any existing connection to the ARM service and
 * try re-establishing it later.
 *
 * @param h our handle
 */
static void
reconnect_arm_later (struct GNUNET_ARM_Handle *h)
{
  if (GNUNET_NO != h->currently_down)
    return;
  if (NULL != h->cth)
  {
    GNUNET_CLIENT_notify_transmit_ready_cancel (h->cth);
    h->cth = NULL;
  }
  if (NULL != h->client)
  {
    GNUNET_CLIENT_disconnect (h->client);
    h->client = NULL;
  }
  h->currently_down = GNUNET_YES;
  GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == h->reconnect_task);
  h->reconnect_task =
      GNUNET_SCHEDULER_add_delayed (h->retry_backoff, &reconnect_arm_task, h);
  /* Don't clear pending messages on disconnection, deliver them later
  clear_pending_messages (h, GNUNET_ARM_REQUEST_DISCONNECTED);
  GNUNET_assert (NULL == h->control_pending_head);
  */
  h->retry_backoff = GNUNET_TIME_STD_BACKOFF (h->retry_backoff);
  if (NULL != h->conn_status)
    h->conn_status (h->conn_status_cls, GNUNET_NO);
}
Exemple #3
0
/**
 * Close down any existing connection to the ARM service and
 * try re-establishing it later.
 *
 * @param h our handle
 */
static void
reconnect_arm_monitor_later (struct GNUNET_ARM_MonitorHandle *h)
{
  if (NULL != h->cth)
  {
    GNUNET_CLIENT_notify_transmit_ready_cancel (h->cth);
    h->cth = NULL;
  }

  if (NULL != h->monitor)
  {
    GNUNET_CLIENT_disconnect (h->monitor);
    h->monitor = NULL;
  }

  if (NULL != h->init_timeout_task_id)
  {
    GNUNET_SCHEDULER_cancel (h->init_timeout_task_id);
    h->init_timeout_task_id = NULL;
  }

  GNUNET_assert (NULL == h->reconnect_task);
  h->reconnect_task =
      GNUNET_SCHEDULER_add_delayed (h->retry_backoff, &reconnect_arm_monitor_task, h);

  h->retry_backoff = GNUNET_TIME_STD_BACKOFF (h->retry_backoff);
}
/**
 * Transmit our current typemap message to the other peer.
 * (Done periodically until the typemap is confirmed).
 *
 * @param cls the `struct Session *`
 * @param tc unused
 */
static void
transmit_typemap_task (void *cls,
                       const struct GNUNET_SCHEDULER_TaskContext *tc)
{
  struct Session *session = cls;
  struct GNUNET_MessageHeader *hdr;
  struct GNUNET_TIME_Relative delay;

  session->typemap_delay = GNUNET_TIME_STD_BACKOFF (session->typemap_delay);
  delay = session->typemap_delay;
  /* randomize a bit to avoid spont. sync */
  delay.rel_value_us +=
      GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK, 1000 * 1000);
  session->typemap_task =
      GNUNET_SCHEDULER_add_delayed (delay,
                                    &transmit_typemap_task, session);
  GNUNET_STATISTICS_update (GSC_stats,
                            gettext_noop ("# type map refreshes sent"),
                            1,
                            GNUNET_NO);
  hdr = GSC_TYPEMAP_compute_type_map_message ();
  GSC_KX_encrypt_and_transmit (session->kxinfo,
                               hdr,
                               ntohs (hdr->size));
  GNUNET_free (hdr);
}
/**
 * Route the given request via the DHT.  This includes updating
 * the bloom filter and retransmission times, building the P2P
 * message and initiating the routing operation.
 */
static void
transmit_request (struct ClientQueryRecord *cqr)
{
  int32_t reply_bf_mutator;
  struct GNUNET_CONTAINER_BloomFilter *reply_bf;
  struct GNUNET_CONTAINER_BloomFilter *peer_bf;

  GNUNET_STATISTICS_update (GDS_stats,
                            gettext_noop
                            ("# GET requests from clients injected"), 1,
                            GNUNET_NO);
  reply_bf_mutator =
      (int32_t) GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK,
                                          UINT32_MAX);
  reply_bf =
      GNUNET_BLOCK_construct_bloomfilter (reply_bf_mutator, cqr->seen_replies,
                                          cqr->seen_replies_count);
  peer_bf =
      GNUNET_CONTAINER_bloomfilter_init (NULL, DHT_BLOOM_SIZE,
                                         GNUNET_CONSTANTS_BLOOMFILTER_K);
  LOG (GNUNET_ERROR_TYPE_DEBUG,
       "Initiating GET for %s, replication %u, already have %u replies\n",
       GNUNET_h2s(&cqr->key), cqr->replication, cqr->seen_replies_count);
  GDS_NEIGHBOURS_handle_get (cqr->type, cqr->msg_options, cqr->replication,
                             0 /* hop count */ ,
                             &cqr->key, cqr->xquery, cqr->xquery_size, reply_bf,
                             reply_bf_mutator, peer_bf);
  GNUNET_CONTAINER_bloomfilter_free (reply_bf);
  GNUNET_CONTAINER_bloomfilter_free (peer_bf);

  /* exponential back-off for retries.
   * max GNUNET_TIME_STD_EXPONENTIAL_BACKOFF_THRESHOLD (15 min) */
  cqr->retry_frequency = GNUNET_TIME_STD_BACKOFF (cqr->retry_frequency);
  cqr->retry_time = GNUNET_TIME_relative_to_absolute (cqr->retry_frequency);
}
/**
 * Function called to notify a client about the connection begin ready to queue
 * more data.  "buf" will be NULL and "size" zero if the connection was closed
 * for writing in the meantime.
 *
 * @param cls closure
 * @param size number of bytes available in buf
 * @param buf where the callee should write the message
 * @return number of bytes written to buf
 */
static size_t
transmit_ready_notify (void *cls, size_t size, void *buf)
{
  struct GNUNET_TESTBED_LOGGER_Handle *h = cls;
  struct MessageQueue *mq;

  h->th = NULL;
  mq = h->mq_head;
  GNUNET_assert (NULL != mq);
  if ((0 == size) && (NULL == buf))     /* Timeout */
  {
    LOG_DEBUG ("Message sending timed out -- retrying\n");
    h->retry_backoff = GNUNET_TIME_STD_BACKOFF (h->retry_backoff);
    h->th =
        GNUNET_CLIENT_notify_transmit_ready (h->client,
                                             ntohs (mq->msg->size),
                                             h->retry_backoff, GNUNET_YES,
                                             &transmit_ready_notify, h);
    return 0;
  }
  h->retry_backoff = GNUNET_TIME_UNIT_ZERO;
  GNUNET_assert (ntohs (mq->msg->size) <= size);
  size = ntohs (mq->msg->size);
  memcpy (buf, mq->msg, size);
  LOG_DEBUG ("Message of type: %u and size: %u sent\n",
             ntohs (mq->msg->type), size);
  GNUNET_free (mq->msg);
  GNUNET_CONTAINER_DLL_remove (h->mq_head, h->mq_tail, mq);
  GNUNET_free (mq);
  h->bwrote += (size - sizeof (struct GNUNET_MessageHeader));
  mq = h->mq_head;
  if (NULL != mq)
  {
    h->retry_backoff = GNUNET_TIME_STD_BACKOFF (h->retry_backoff);
    h->th =
        GNUNET_CLIENT_notify_transmit_ready (h->client,
                                             ntohs (mq->msg->size),
                                             h->retry_backoff, GNUNET_YES,
                                             &transmit_ready_notify, h);
    return size;
  }
  if (NULL != h->cb)
    trigger_flush_notification (h);       /* Call the flush completion callback */
  return size;
}
/**
 * Cut the existing connection and reconnect.
 *
 * @param val_ctx our context
 */
static void
reconnect_val_ctx (struct GNUNET_TRANSPORT_ValidationMonitoringContext *val_ctx)
{
  GNUNET_assert (GNUNET_NO == val_ctx->one_shot);
  GNUNET_CLIENT_disconnect (val_ctx->client);
  val_ctx->client = NULL;
  val_ctx->backoff = GNUNET_TIME_STD_BACKOFF (val_ctx->backoff);
  val_ctx->reconnect_task = GNUNET_SCHEDULER_add_delayed (val_ctx->backoff,
                                                          &do_val_connect,
                                                          val_ctx);
}
/**
 * Cut the existing connection and reconnect.
 *
 * @param pal_ctx our context
 */
static void
reconnect_peer_ctx (struct GNUNET_TRANSPORT_PeerMonitoringContext *pal_ctx)
{
  GNUNET_assert (GNUNET_NO == pal_ctx->one_shot);
  GNUNET_CLIENT_disconnect (pal_ctx->client);
  pal_ctx->client = NULL;
  pal_ctx->backoff = GNUNET_TIME_STD_BACKOFF (pal_ctx->backoff);
  pal_ctx->reconnect_task = GNUNET_SCHEDULER_add_delayed (pal_ctx->backoff,
							  &do_peer_connect,
							  pal_ctx);
}
Exemple #9
0
/**
 * Disconnect from service and then reconnect.
 *
 * @param handle our handle
 */
static void
force_reconnect (struct GNUNET_GNS_Handle *handle)
{
    GNUNET_MQ_destroy (handle->mq);
    handle->mq = NULL;
    handle->reconnect_backoff
        = GNUNET_TIME_STD_BACKOFF (handle->reconnect_backoff);
    handle->reconnect_task
        = GNUNET_SCHEDULER_add_delayed (handle->reconnect_backoff,
                                        &reconnect_task,
                                        handle);
}
Exemple #10
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 = NULL;
  if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
  {
    /* give up, was shutdown */
    th->client->th = NULL;
    th->notify (th->notify_cls, 0, NULL);
    GNUNET_free (th);
    return;
  }
  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_STD_BACKOFF (th->client->back_off);
    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));
    GNUNET_assert (NULL == th->th);
    GNUNET_assert (NULL == th->reconnect_task);
    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;
  }
}
Exemple #11
0
/**
 * Checks whether a host can be used to start testbed service
 *
 * @param host the host to check
 * @param config the configuration handle to lookup the path of the testbed
 *          helper
 * @param cb the callback to call to inform about habitability of the given host
 * @param cb_cls the closure for the callback
 * @return NULL upon any error or a handle which can be passed to
 *           GNUNET_TESTBED_is_host_habitable_cancel()
 */
struct GNUNET_TESTBED_HostHabitableCheckHandle *
GNUNET_TESTBED_is_host_habitable (const struct GNUNET_TESTBED_Host *host,
                                  const struct GNUNET_CONFIGURATION_Handle
                                  *config,
                                  GNUNET_TESTBED_HostHabitableCallback cb,
                                  void *cb_cls)
{
  struct GNUNET_TESTBED_HostHabitableCheckHandle *h;
  char **rsh_args;
  char **rsh_suffix_args;
  char *stat_args[3];
  const char *hostname;
  char *port;

  h = GNUNET_new (struct GNUNET_TESTBED_HostHabitableCheckHandle);
  h->cb = cb;
  h->cb_cls = cb_cls;
  h->host = host;
  hostname = (NULL == host->hostname) ? "127.0.0.1" : host->hostname;
  if (GNUNET_OK !=
      GNUNET_CONFIGURATION_get_value_filename (config, "testbed",
                                             "HELPER_BINARY_PATH",
                                             &stat_args[1]))
    stat_args[1] =
        GNUNET_OS_get_libexec_binary_path (HELPER_TESTBED_BINARY);
  GNUNET_asprintf (&port, "%u", host->port);
  rsh_args = gen_rsh_args (port, hostname, host->username);
  GNUNET_free (port);
  port = NULL;
  stat_args[0] = "stat";
  stat_args[2] = NULL;
  rsh_suffix_args = gen_rsh_suffix_args ((const char **) stat_args);
  GNUNET_free (stat_args[1]);
  h->helper_argv = join_argv ((const char **) rsh_args,
                              (const char **) rsh_suffix_args);
  free_argv (rsh_suffix_args);
  free_argv (rsh_args);
  h->auxp =
      GNUNET_OS_start_process_vap (GNUNET_NO, GNUNET_OS_INHERIT_STD_ERR, NULL,
                                   NULL, NULL, h->helper_argv[0], h->helper_argv);
  if (NULL == h->auxp)
  {
    GNUNET_break (0);           /* Cannot exec SSH? */
    GNUNET_free (h);
    return NULL;
  }
  h->wait_time = GNUNET_TIME_STD_BACKOFF (h->wait_time);
  h->habitability_check_task =
      GNUNET_SCHEDULER_add_delayed (h->wait_time, &habitability_check, h);
  return h;
}
/**
 * Cut the existing connection and reconnect.
 *
 * @param val_ctx our context
 */
static void
reconnect_val_ctx (struct GNUNET_TRANSPORT_ValidationMonitoringContext *val_ctx)
{
  GNUNET_assert (GNUNET_NO == val_ctx->one_shot);
  GNUNET_CLIENT_disconnect (val_ctx->client);
  val_ctx->client = NULL;
  /* notify clients about (re)connect */
  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);
  val_ctx->backoff = GNUNET_TIME_STD_BACKOFF (val_ctx->backoff);
  val_ctx->reconnect_task = GNUNET_SCHEDULER_add_delayed (val_ctx->backoff,
                                                          &do_val_connect,
                                                          val_ctx);
}
Exemple #13
0
/**
 * Handle request message for a listen operation
 *
 * @param cls the listen handle
 * @param mh the message
 */
static void
handle_request (void *cls,
                const struct GNUNET_MessageHeader *mh)
{
  struct GNUNET_SET_ListenHandle *lh = cls;
  const struct GNUNET_SET_RequestMessage *msg;
  struct GNUNET_SET_Request req;
  const struct GNUNET_MessageHeader *context_msg;
  uint16_t msize;
  struct GNUNET_MQ_Envelope *mqm;
  struct GNUNET_SET_RejectMessage *rmsg;

  LOG (GNUNET_ERROR_TYPE_DEBUG,
       "Processing incoming operation request\n");
  msize = ntohs (mh->size);
  if (msize < sizeof (struct GNUNET_SET_RequestMessage))
  {
    GNUNET_break (0);
    GNUNET_CLIENT_disconnect (lh->client);
    lh->client = NULL;
    GNUNET_MQ_destroy (lh->mq);
    lh->mq = NULL;
    lh->reconnect_task = GNUNET_SCHEDULER_add_delayed (lh->reconnect_backoff,
                                                       &listen_connect, lh);
    lh->reconnect_backoff = GNUNET_TIME_STD_BACKOFF (lh->reconnect_backoff);
    return;
  }
  /* we got another valid request => reset the backoff */
  lh->reconnect_backoff = GNUNET_TIME_UNIT_MILLISECONDS;
  msg = (const struct GNUNET_SET_RequestMessage *) mh;
  req.accept_id = ntohl (msg->accept_id);
  req.accepted = GNUNET_NO;
  context_msg = GNUNET_MQ_extract_nested_mh (msg);
  /* calling #GNUNET_SET_accept() in the listen cb will set req->accepted */
  lh->listen_cb (lh->listen_cls,
                 &msg->peer_id,
                 context_msg,
                 &req);
  if (GNUNET_YES == req.accepted)
    return; /* the accept-case is handled in #GNUNET_SET_accept() */
  LOG (GNUNET_ERROR_TYPE_DEBUG,
       "Rejecting request\n");
  mqm = GNUNET_MQ_msg (rmsg,
                       GNUNET_MESSAGE_TYPE_SET_REJECT);
  rmsg->accept_reject_id = msg->accept_id;
  GNUNET_MQ_send (lh->mq, mqm);
}
Exemple #14
0
/**
 * Disconnect from service and then reconnect.
 *
 * @param handle our handle
 */
static void
force_reconnect (struct GNUNET_GNS_Handle *handle)
{
  struct GNUNET_GNS_ShortenRequest *st;
  struct GNUNET_GNS_LookupRequest *lh;
  struct GNUNET_GNS_GetAuthRequest *ga;
  struct PendingMessage *p;

  GNUNET_CLIENT_disconnect (handle->client);
  handle->client = NULL;
  handle->in_receive = GNUNET_NO;
  for (st = handle->shorten_head; NULL != st; st = st->next)
  {
    p = (struct PendingMessage *) &st[1];
    if (GNUNET_NO == p->transmitted)
      continue;
    p->transmitted = GNUNET_NO;
    GNUNET_CONTAINER_DLL_insert (handle->pending_head,
				 handle->pending_tail,
				 p);  
  }
  for (lh = handle->lookup_head; NULL != lh; lh = lh->next)
  {
    p = (struct PendingMessage *) &lh[1];
    if (GNUNET_NO == p->transmitted)
      continue;
    p->transmitted = GNUNET_NO;
    GNUNET_CONTAINER_DLL_insert (handle->pending_head,
				 handle->pending_tail,
				 p);  
  }
  for (ga = handle->get_auth_head; NULL != ga; ga = ga->next)
  {
    p = (struct PendingMessage *) &ga[1];
    if (GNUNET_NO == p->transmitted)
      continue;
    p->transmitted = GNUNET_NO;
    GNUNET_CONTAINER_DLL_insert (handle->pending_head,
				 handle->pending_tail,
				 p);  
  }
  handle->reconnect_backoff = GNUNET_TIME_STD_BACKOFF (handle->reconnect_backoff);
  handle->reconnect_task = GNUNET_SCHEDULER_add_delayed (handle->reconnect_backoff,
                                                    &reconnect_task,
                                                    handle);
}
Exemple #15
0
/**
 * Our connection with the set service encountered an error,
 * re-initialize with exponential back-off.
 *
 * @param cls the `struct GNUNET_SET_ListenHandle *`
 * @param error reason for the disconnect
 */
static void
handle_client_listener_error (void *cls,
                              enum GNUNET_MQ_Error error)
{
  struct GNUNET_SET_ListenHandle *lh = cls;

  LOG (GNUNET_ERROR_TYPE_DEBUG,
       "Listener broke down (%d), re-connecting\n",
       (int) error);
  GNUNET_CLIENT_disconnect (lh->client);
  lh->client = NULL;
  GNUNET_MQ_destroy (lh->mq);
  lh->mq = NULL;
  lh->reconnect_task = GNUNET_SCHEDULER_add_delayed (lh->reconnect_backoff,
                                                     &listen_connect, lh);
  lh->reconnect_backoff = GNUNET_TIME_STD_BACKOFF (lh->reconnect_backoff);
}
Exemple #16
0
/**
 * Try reconnecting to the dht service.
 *
 * @param cls a `struct GNUNET_DHT_Handle`
 * @param tc scheduler context
 */
static void
try_reconnect (void *cls,
	       const struct GNUNET_SCHEDULER_TaskContext *tc)
{
  struct GNUNET_DHT_Handle *handle = cls;

  LOG (GNUNET_ERROR_TYPE_DEBUG, "Reconnecting with DHT %p\n", handle);
  handle->retry_time = GNUNET_TIME_STD_BACKOFF (handle->retry_time);
  handle->reconnect_task = NULL;
  if (GNUNET_YES != try_connect (handle))
  {
    LOG (GNUNET_ERROR_TYPE_DEBUG, "dht reconnect failed(!)\n");
    return;
  }
  GNUNET_CONTAINER_multihashmap_iterate (handle->active_requests,
                                         &add_request_to_pending, handle);
  process_pending_messages (handle);
}
Exemple #17
0
/**
 * Try reconnecting to the datastore service.
 *
 * @param cls the 'struct GNUNET_DATASTORE_Handle'
 * @param tc scheduler context
 */
static void
try_reconnect (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
{
  struct GNUNET_DATASTORE_Handle *h = cls;

  h->retry_time = GNUNET_TIME_STD_BACKOFF (h->retry_time);
  h->reconnect_task = GNUNET_SCHEDULER_NO_TASK;
  h->client = GNUNET_CLIENT_connect ("datastore", h->cfg);
  if (h->client == NULL)
  {
    LOG (GNUNET_ERROR_TYPE_ERROR, "DATASTORE reconnect failed (fatally)\n");
    return;
  }
  GNUNET_STATISTICS_update (h->stats,
                            gettext_noop
                            ("# datastore connections (re)created"), 1,
                            GNUNET_NO);
  LOG (GNUNET_ERROR_TYPE_DEBUG, "Reconnected to DATASTORE\n");
  process_queue (h);
}
Exemple #18
0
/**
 * Task for checking whether a host is habitable or not
 *
 * @param cls GNUNET_TESTBED_HostHabitableCheckHandle
 * @param tc the scheduler task context
 */
static void
habitability_check (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
{
  struct GNUNET_TESTBED_HostHabitableCheckHandle *h = cls;
  void *cb_cls;
  GNUNET_TESTBED_HostHabitableCallback cb;
  const struct GNUNET_TESTBED_Host *host;
  unsigned long code;
  enum GNUNET_OS_ProcessStatusType type;
  int ret;

  h->habitability_check_task = NULL;
  ret = GNUNET_OS_process_status (h->auxp, &type, &code);
  if (GNUNET_SYSERR == ret)
  {
    GNUNET_break (0);
    ret = GNUNET_NO;
    goto call_cb;
  }
  if (GNUNET_NO == ret)
  {
    h->wait_time = GNUNET_TIME_STD_BACKOFF (h->wait_time);
    h->habitability_check_task =
        GNUNET_SCHEDULER_add_delayed (h->wait_time, &habitability_check, h);
    return;
  }
  GNUNET_OS_process_destroy (h->auxp);
  h->auxp = NULL;
  ret = (0 != code) ? GNUNET_NO : GNUNET_YES;

call_cb:
  if (NULL != h->auxp)
    GNUNET_OS_process_destroy (h->auxp);
  cb = h->cb;
  cb_cls = h->cb_cls;
  host = h->host;
  free_argv (h->helper_argv);
  GNUNET_free (h);
  if (NULL != cb)
    cb (cb_cls, host, ret);
}
Exemple #19
0
/**
 * Disconnect from ATS and then reconnect.
 *
 * @param sh our handle
 */
static void
force_reconnect (struct GNUNET_ATS_SchedulingHandle *sh)
{
  if (NULL != sh->mq)
  {
    GNUNET_MQ_destroy (sh->mq);
    sh->mq = NULL;
  }
  if (NULL != sh->client)
  {
    GNUNET_CLIENT_disconnect (sh->client);
    sh->client = NULL;
  }
  sh->suggest_cb (sh->suggest_cb_cls,
                  NULL, NULL, NULL,
                  GNUNET_BANDWIDTH_ZERO,
                  GNUNET_BANDWIDTH_ZERO);
  sh->backoff = GNUNET_TIME_STD_BACKOFF (sh->backoff);
  sh->task = GNUNET_SCHEDULER_add_delayed (sh->backoff,
                                           &reconnect_task,
                                           sh);
}
Exemple #20
0
/**
 * Close down any existing connection to the CORE service and
 * try re-establishing it later.
 *
 * @param h our handle
 */
static void
reconnect_later (struct GNUNET_CORE_Handle *h)
{
  struct ControlMessage *cm;
  struct PeerRecord *pr;

  GNUNET_assert (GNUNET_SCHEDULER_NO_TASK == h->reconnect_task);
  if (NULL != h->cth)
  {
    GNUNET_CLIENT_notify_transmit_ready_cancel (h->cth);
    h->cth = NULL;
  }
  if (NULL != h->client)
  {
    GNUNET_CLIENT_disconnect (h->client);
    h->client = NULL;
  }
  h->currently_down = GNUNET_YES;
  GNUNET_assert (h->reconnect_task == GNUNET_SCHEDULER_NO_TASK);
  h->reconnect_task =
      GNUNET_SCHEDULER_add_delayed (h->retry_backoff,
                                    &reconnect_task, h);
  while (NULL != (cm = h->control_pending_head))
  {
    GNUNET_CONTAINER_DLL_remove (h->control_pending_head,
                                 h->control_pending_tail, cm);
    if (NULL != cm->th)
      cm->th->cm = NULL;
    if (NULL != cm->cont)
      cm->cont (cm->cont_cls, GNUNET_NO);
    GNUNET_free (cm);
  }
  GNUNET_CONTAINER_multipeermap_iterate (h->peers,
                                         &disconnect_and_free_peer_entry, h);
  while (NULL != (pr = h->ready_peer_head))
    GNUNET_CONTAINER_DLL_remove (h->ready_peer_head, h->ready_peer_tail, pr);
  GNUNET_assert (h->control_pending_head == NULL);
  h->retry_backoff = GNUNET_TIME_STD_BACKOFF (h->retry_backoff);
}
Exemple #21
0
/**
 * Adjust exponential back-off and reconnect to the service.
 */
static void
reconnect ()
{
    struct GNUNET_RESOLVER_RequestHandle *rh;

    if (NULL != r_task)
        return;
    GNUNET_assert (NULL == client);
    if (NULL != (rh = req_head))
    {
        switch (rh->was_transmitted)
        {
        case GNUNET_NO:
            /* nothing more to do */
            break;
        case GNUNET_YES:
            /* disconnected, transmit again! */
            rh->was_transmitted = GNUNET_NO;
            break;
        case GNUNET_SYSERR:
            /* request was cancelled, remove entirely */
            GNUNET_CONTAINER_DLL_remove (req_head, req_tail, rh);
            GNUNET_free (rh);
            break;
        default:
            GNUNET_assert (0);
            break;
        }
    }
    LOG (GNUNET_ERROR_TYPE_DEBUG,
         "Will try to connect to DNS service in %s\n",
         GNUNET_STRINGS_relative_time_to_string (backoff,
                 GNUNET_YES));
    GNUNET_assert (NULL != resolver_cfg);
    r_task = GNUNET_SCHEDULER_add_delayed (backoff,
                                           &reconnect_task,
                                           NULL);
    backoff = GNUNET_TIME_STD_BACKOFF (backoff);
}
Exemple #22
0
/**
 * Reschedule a connect attempt to the service.
 *
 * @param h transport service to reconnect
 */
static void
reschedule_connect (struct GNUNET_NSE_Handle *h)
{
    GNUNET_assert (h->reconnect_task == GNUNET_SCHEDULER_NO_TASK);

    if (NULL != h->th)
    {
        GNUNET_CLIENT_notify_transmit_ready_cancel (h->th);
        h->th = NULL;
    }
    if (NULL != h->client)
    {
        GNUNET_CLIENT_disconnect (h->client);
        h->client = NULL;
    }

    LOG (GNUNET_ERROR_TYPE_DEBUG,
         "Scheduling task to reconnect to nse service in %llu ms.\n",
         h->reconnect_delay.rel_value);
    h->reconnect_task =
        GNUNET_SCHEDULER_add_delayed (h->reconnect_delay, &reconnect, h);
    h->reconnect_delay = GNUNET_TIME_STD_BACKOFF (h->reconnect_delay);
}
Exemple #23
0
/**
 * Reschedule a connect attempt to the service.
 *
 * @param h transport service to reconnect
 */
static void
reschedule_connect (struct GNUNET_PSYCSTORE_Handle *h)
{
  GNUNET_assert (h->reconnect_task == NULL);

  if (NULL != h->th)
  {
    GNUNET_CLIENT_notify_transmit_ready_cancel (h->th);
    h->th = NULL;
  }
  if (NULL != h->client)
  {
    GNUNET_CLIENT_disconnect (h->client);
    h->client = NULL;
  }
  h->in_receive = GNUNET_NO;
  LOG (GNUNET_ERROR_TYPE_DEBUG,
       "Scheduling task to reconnect to PSYCstore service in %s.\n",
       GNUNET_STRINGS_relative_time_to_string (h->reconnect_delay, GNUNET_YES));
  h->reconnect_task =
      GNUNET_SCHEDULER_add_delayed (h->reconnect_delay, &reconnect, h);
  h->reconnect_delay = GNUNET_TIME_STD_BACKOFF (h->reconnect_delay);
}
/**
 * Temporarily block a valid address for use by ATS for address
 * suggestions.  This function should be called if an address was
 * suggested by ATS but failed to perform (i.e. failure to establish a
 * session or to exchange the PING/PONG).
 *
 * @param address the address to block
 * @param session the session (can be NULL)
 */
void
GST_ats_block_address (const struct GNUNET_HELLO_Address *address,
                       struct GNUNET_ATS_Session *session)
{
  struct AddressInfo *ai;

  if (0 ==
      memcmp (&GST_my_identity,
              &address->peer,
              sizeof (struct GNUNET_PeerIdentity)))
    return; /* our own, ignore! */
  ai = find_ai (address,
                session);
  if (NULL == ai)
  {
    GNUNET_assert (0);
    return;
  }
  if (NULL == ai->ar)
  {
    /* already blocked, how did it get used!? */
    GNUNET_break (0);
    return;
  }
  ai->back_off = GNUNET_TIME_STD_BACKOFF (ai->back_off);
  if (GNUNET_YES ==
      GNUNET_HELLO_address_check_option (address,
                                         GNUNET_HELLO_ADDRESS_INFO_INBOUND))
    LOG (GNUNET_ERROR_TYPE_DEBUG,
         "Removing address %s of peer %s from use (inbound died)\n",
         GST_plugins_a2s (address),
         GNUNET_i2s (&address->peer));
  else
    LOG (GNUNET_ERROR_TYPE_INFO,
         "Blocking address %s of peer %s from use for %s\n",
         GST_plugins_a2s (address),
         GNUNET_i2s (&address->peer),
         GNUNET_STRINGS_relative_time_to_string (ai->back_off,
                                                 GNUNET_YES));
  /* destroy session and address */
  if ( (NULL == session) ||
       (GNUNET_NO ==
        GNUNET_ATS_address_del_session (ai->ar,
                                        session)) )
  {
    GNUNET_ATS_address_destroy (ai->ar);
  }
  /* "ar" has been freed, regardless how the branch
     above played out: it was either freed in
     #GNUNET_ATS_address_del_session() because it was
     incoming, or explicitly in
     #GNUNET_ATS_address_del_session(). */
  ai->ar = NULL;

  /* determine when the address should come back to life */
  ai->blocked = GNUNET_TIME_relative_to_absolute (ai->back_off);
  ai->unblock_task = GNUNET_SCHEDULER_add_delayed (ai->back_off,
                                                   &unblock_address,
                                                   ai);
  num_blocked++;
  publish_p2a_stat_update ();
}
/**
 * Periodically announce self id in the DHT
 *
 * @param cls closure
 */
static void
announce_id (void *cls)
{
  struct GNUNET_HashCode phash;
  const struct GNUNET_HELLO_Message *hello;
  size_t size;
  struct GNUNET_TIME_Absolute expiration;
  struct GNUNET_TIME_Relative next_put;

  hello = GCH_get_mine ();
  size = (NULL != hello) ? GNUNET_HELLO_size (hello) : 0;
  if (0 == size)
  {
    expiration = GNUNET_TIME_absolute_add (GNUNET_TIME_absolute_get (),
                                           announce_delay);
    announce_delay = GNUNET_TIME_STD_BACKOFF (announce_delay);
  }
  else
  {
    expiration = GNUNET_HELLO_get_last_expiration (hello);
    announce_delay = GNUNET_TIME_UNIT_SECONDS;
  }

  /* Call again in id_announce_time, unless HELLO expires first,
   * but wait at least 1s. */
  next_put
    = GNUNET_TIME_absolute_get_remaining (expiration);
  next_put
    = GNUNET_TIME_relative_min (next_put,
                                id_announce_time);
  next_put
    = GNUNET_TIME_relative_max (next_put,
                                GNUNET_TIME_UNIT_SECONDS);
  announce_id_task
    = GNUNET_SCHEDULER_add_delayed (next_put,
                                    &announce_id,
                                    cls);
  GNUNET_STATISTICS_update (stats,
                            "# DHT announce",
                            1,
                            GNUNET_NO);
  memset (&phash,
          0,
          sizeof (phash));
  GNUNET_memcpy (&phash,
                 &my_full_id,
                 sizeof (my_full_id));
  LOG (GNUNET_ERROR_TYPE_DEBUG,
       "Announcing my HELLO (%u bytes) in the DHT\n",
       size);
  GNUNET_DHT_put (dht_handle,   /* DHT handle */
                  &phash,       /* Key to use */
                  dht_replication_level,     /* Replication level */
                  GNUNET_DHT_RO_RECORD_ROUTE
                  | GNUNET_DHT_RO_DEMULTIPLEX_EVERYWHERE,    /* DHT options */
                  GNUNET_BLOCK_TYPE_DHT_HELLO,       /* Block type */
                  size,  /* Size of the data */
                  (const char *) hello, /* Data itself */
                  expiration,  /* Data expiration */
                  NULL,         /* Continuation */
                  NULL);        /* Continuation closure */
}