예제 #1
0
static void
testNamespace ()
{
  struct GNUNET_CRYPTO_EcdsaPrivateKey *ns;
  struct GNUNET_FS_BlockOptions bo;
  struct GNUNET_CONTAINER_MetaData *meta;
  struct GNUNET_FS_Uri *ksk_uri;
  struct GNUNET_FS_Uri *sks_uri;

  ns = GNUNET_CRYPTO_ecdsa_key_create ();
  meta = GNUNET_CONTAINER_meta_data_create ();
  ksk_uri = GNUNET_FS_uri_parse ("gnunet://fs/ksk/testnsa", NULL);
  bo.content_priority = 1;
  bo.anonymity_level = 1;
  bo.replication_level = 0;
  bo.expiration_time =
      GNUNET_TIME_relative_to_absolute (GNUNET_TIME_UNIT_MINUTES);
  sks_uri = GNUNET_FS_uri_sks_create (&nsid, "root");
  GNUNET_FS_publish_ksk (fs,
			 ksk_uri, meta, sks_uri,
			 &bo, GNUNET_FS_PUBLISH_OPTION_NONE,
			 &adv_cont, NULL);
  GNUNET_FS_uri_destroy (sks_uri);
  kill_task =
      GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_MINUTES, &do_timeout,
                                    NULL);
  GNUNET_FS_uri_destroy (ksk_uri);
  GNUNET_CONTAINER_meta_data_destroy (meta);
  GNUNET_free (ns);
}
예제 #2
0
/**
 * Request a list of running services.
 *
 * @param h handle to ARM
 * @param timeout how long to wait before failing for good
 * @param cont callback to invoke after request is sent or is not sent
 * @param cont_cls closure for callback
 */
void
GNUNET_ARM_request_service_list (struct GNUNET_ARM_Handle *h,
                                 struct GNUNET_TIME_Relative timeout,
                                 GNUNET_ARM_ServiceListCallback cont,
                                 void *cont_cls)
{
  struct ARMControlMessage *cm;
  struct GNUNET_ARM_Message *msg;

  LOG (GNUNET_ERROR_TYPE_DEBUG,
       "Requesting LIST from ARM service with timeout: %s\n",
       GNUNET_STRINGS_relative_time_to_string (timeout, GNUNET_YES));
  cm = GNUNET_new (struct ARMControlMessage);
  cm->h = h;
  cm->list_cont = cont;
  cm->cont_cls = cont_cls;
  cm->timeout = GNUNET_TIME_relative_to_absolute (timeout);
  msg = GNUNET_malloc (sizeof (struct GNUNET_ARM_Message));
  msg->header.size = htons (sizeof (struct GNUNET_ARM_Message));
  msg->header.type = htons (GNUNET_MESSAGE_TYPE_ARM_LIST);
  msg->reserved = htonl (0);
  cm->msg = msg;
  GNUNET_CONTAINER_DLL_insert_tail (h->control_pending_head,
                                    h->control_pending_tail, cm);
  cm->timeout_task_id =
      GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_absolute_get_remaining
                                    (cm->timeout), &control_message_timeout, cm);
  trigger_next_request (h, GNUNET_NO);
}
예제 #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_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);
}
예제 #4
0
static void
run (void *cls,
     char *const *args,
     const char *cfgfile,
     const struct GNUNET_CONFIGURATION_Handle *cfg)
{
  die_task = GNUNET_SCHEDULER_add_delayed (TIMEOUT,
                                           &end_badly, NULL);
  test_send_timeout = GNUNET_NO;

  p1 = GNUNET_TRANSPORT_TESTING_start_peer (tth, cfg_file_p1, 1,
                                            &notify_receive, &notify_connect,
                                            &notify_disconnect, &start_cb,
                                            NULL);
  p2 = GNUNET_TRANSPORT_TESTING_start_peer (tth, cfg_file_p2, 2,
                                            &notify_receive, &notify_connect,
                                            &notify_disconnect, &start_cb,
                                            NULL);
  if ((p1 == NULL) || (p2 == NULL))
  {
    GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Fail! Could not start peers!\n");
    if (die_task != NULL)
      GNUNET_SCHEDULER_cancel (die_task);
    //die_task = GNUNET_SCHEDULER_add_now (&end_badly, NULL);
    return;
  }
}
예제 #5
0
static void
run (void *cls, char *const *args, const char *cfgfile,
     const struct GNUNET_CONFIGURATION_Handle *cfg)
{
  ret = 1;
  tth = GNUNET_TRANSPORT_TESTING_init ();
  GNUNET_assert (NULL != tth);

  timeout_task =
      GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_MINUTES, &end_badly, NULL);

  p = GNUNET_TRANSPORT_TESTING_start_peer(tth, cfgfile, 1,
                                          NULL, /* receive cb */
                                          NULL, /* connect cb */
                                          NULL, /* disconnect cb */
                                          start_cb, /* startup cb */
                                          NULL); /* closure */
  if (NULL == p)
  {
    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Failed to start peer\n");
    if (timeout_task != NULL)
      GNUNET_SCHEDULER_cancel (timeout_task);
    timeout_task = GNUNET_SCHEDULER_add_now (&end_badly, NULL);
  }
}
예제 #6
0
/**
 * peergroup_ready: start test when all peers are connected
 * @param cls closure
 * @param emsg error message
 */
static void
peergroup_ready (void *cls, const char *emsg)
{
  if (emsg != NULL)
  {
    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                "test: Peergroup callback called with error, aborting test!\n");
    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "test: Error from testing: `%s'\n",
                emsg);
    ok--;
    GNUNET_TESTING_daemons_stop (pg, TIMEOUT, &shutdown_callback, NULL);
    return;
  }
  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
              "test: Peer Group started successfully with %u connections\n",
              total_connections);
  peers_running = GNUNET_TESTING_daemons_running (pg);
  if (0 < failed_connections)
  {
    ok = GNUNET_SYSERR;
    GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "test: %u connections have FAILED!\n",
                failed_connections);
    disconnect_task = GNUNET_SCHEDULER_add_now (&disconnect_peers, NULL);

  }
  else
  {
    GNUNET_TESTING_get_topology (pg, &topo_cb, NULL);
    disconnect_task =
        GNUNET_SCHEDULER_add_delayed (SHORT_TIME, &disconnect_peers, NULL);
    ok = GNUNET_OK;
  }

}
예제 #7
0
/**
 * Callback for lock status changes
 *
 * @param cls the closure from GNUNET_LOCKMANAGER_lock call
 *
 * @param domain_name the locking domain of the lock
 *
 * @param lock the lock for which this status is relevant
 *
 * @param status GNUNET_LOCKMANAGER_SUCCESS if the lock has been successfully
 *          acquired; GNUNET_LOCKMANAGER_RELEASE when the acquired lock is lost
 */
static void
status_cb (void *cls, const char *domain_name, uint32_t lock,
           enum GNUNET_LOCKMANAGER_Status status)
{
  LOG (GNUNET_ERROR_TYPE_DEBUG,
       "Status change callback called on lock: %d of domain: %s\n", lock,
       domain_name);
  switch (result)
  {
  case LOCK1_ACQUIRE:
    GNUNET_assert (GNUNET_LOCKMANAGER_SUCCESS == status);
    GNUNET_assert (NULL != request);
    //GNUNET_LOCKMANAGER_cancel_request (request);
    //request = NULL;
    result = LOCK2_ACQUIRE;
    request2 =
        GNUNET_LOCKMANAGER_acquire_lock (handle, "GNUNET_LOCKMANAGER_TESTING",
                                         100, &status_cb, NULL);
    GNUNET_assert (NULL != request2);
    break;
  case LOCK2_ACQUIRE:
    GNUNET_assert (GNUNET_LOCKMANAGER_SUCCESS == status);
    GNUNET_assert (NULL != request);
    GNUNET_SCHEDULER_add_delayed (TIME_REL_SECONDS (1), &do_shutdown, NULL);
    break;
  default:
    GNUNET_break (0);
  }
}
/**
 * Reduce absolute preferences since they got old.
 *
 * @param cls unused
 * @param tc context
 */
static void
preference_aging (void *cls,
                  const struct GNUNET_SCHEDULER_TaskContext *tc)
{
  struct AgeContext ac;

  aging_task = NULL;
  GAS_plugin_solver_lock ();
  ac.values_to_update = 0;
  for (ac.cur_client = pc_head; NULL != ac.cur_client; ac.cur_client = ac.cur_client->next)
    GNUNET_CONTAINER_multipeermap_iterate (ac.cur_client->peer2pref,
                                           &age_values,
                                           &ac);
  GAS_plugin_solver_unlock ();
  if (ac.values_to_update > 0)
  {
    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                "Rescheduling aging task due to %u elements remaining to age\n",
                ac.values_to_update);
    if (NULL == aging_task)
      aging_task = GNUNET_SCHEDULER_add_delayed (PREF_AGING_INTERVAL,
                                                 &preference_aging,
                                                 NULL);
  }
  else
  {
    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                "No values to age left, not rescheduling aging task\n");
  }
}
예제 #9
0
/**
 * Initiate core 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;

  GSC_cfg = c;
  GSC_server = server;
  if (GNUNET_OK !=
      GNUNET_CONFIGURATION_get_value_filename (GSC_cfg, "GNUNETD", "HOSTKEY",
                                               &keyfile))
  {
    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                _
                ("Core service is lacking HOSTKEY configuration setting.  Exiting.\n"));
    GNUNET_SCHEDULER_shutdown ();
    return;
  }
  GSC_stats = GNUNET_STATISTICS_create ("core", GSC_cfg);
  GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &shutdown_task,
                                NULL);
  GNUNET_SERVER_suspend (server);
  GSC_TYPEMAP_init ();
  GST_keygen = GNUNET_CRYPTO_rsa_key_create_start (keyfile, &key_generation_cb, NULL);
  GNUNET_free (keyfile);
  if (NULL == GST_keygen)
  {
    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                _("Transport service is unable to access hostkey. Exiting.\n"));
    GNUNET_SCHEDULER_shutdown ();
  }
}
예제 #10
0
파일: test_nat.c 프로젝트: muggenhor/GNUnet
/**
 * Main function run with scheduler.
 */
static void
run (void *cls, char *const *args, const char *cfgfile,
     const struct GNUNET_CONFIGURATION_Handle *cfg)
{
  struct GNUNET_NAT_Handle *nat;
  struct addr_cls data;
  struct sockaddr *addr;

  data.addr = NULL;
  GNUNET_OS_network_interfaces_list (process_if, &data);
  if (NULL == data.addr)
  {
    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                "Could not find a valid interface address!\n");
    exit (77); /* marks test as skipped */
  }
  addr = data.addr;
  GNUNET_assert (addr->sa_family == AF_INET || addr->sa_family == AF_INET6);
  if (addr->sa_family == AF_INET)
    ((struct sockaddr_in *) addr)->sin_port = htons (2086);
  else
    ((struct sockaddr_in6 *) addr)->sin6_port = htons (2086);

  GNUNET_log (GNUNET_ERROR_TYPE_INFO,
              "Requesting NAT redirection from address %s...\n",
              GNUNET_a2s (addr, data.addrlen));

  nat = GNUNET_NAT_register (cfg, GNUNET_YES /* tcp */ ,
                             2086, 1, (const struct sockaddr **) &addr,
                             &data.addrlen, &addr_callback, NULL, NULL, NULL);
  GNUNET_free (addr);
  GNUNET_SCHEDULER_add_delayed (TIMEOUT, &stop, nat);
}
예제 #11
0
/**
 * Start mapping the given port using (mini)upnpc.  This function
 * should typically not be used directly (it is used within the
 * general-purpose #GNUNET_NAT_register() code).  However, it can be
 * used if specifically UPnP-based NAT traversal is to be used or
 * tested.
 *
 * @param port port to map
 * @param is_tcp #GNUNET_YES to map TCP, #GNUNET_NO for UDP
 * @param ac function to call with mapping result
 * @param ac_cls closure for @a ac
 * @return NULL on error (no 'upnpc' installed)
 */
struct GNUNET_NAT_MiniHandle *
GNUNET_NAT_mini_map_start (uint16_t port,
                           int is_tcp,
                           GNUNET_NAT_MiniAddressCallback ac,
                           void *ac_cls)
{
  struct GNUNET_NAT_MiniHandle *ret;

  if (GNUNET_SYSERR ==
      GNUNET_OS_check_helper_binary ("upnpc",
				     GNUNET_NO,
				     NULL))
  {
    LOG (GNUNET_ERROR_TYPE_INFO,
	 _("`upnpc' command not found\n"));
    ac (ac_cls,
        GNUNET_SYSERR,
        NULL, 0,
        GNUNET_NAT_ERROR_UPNPC_NOT_FOUND);
    return NULL;
  }
  LOG (GNUNET_ERROR_TYPE_DEBUG,
       "Running `upnpc' to install mapping\n");
  ret = GNUNET_new (struct GNUNET_NAT_MiniHandle);
  ret->ac = ac;
  ret->ac_cls = ac_cls;
  ret->is_tcp = is_tcp;
  ret->port = port;
  ret->refresh_task =
    GNUNET_SCHEDULER_add_delayed (MAP_REFRESH_FREQ,
				  &do_refresh,
				  ret);
  run_upnpc_r (ret);
  return ret;
}
예제 #12
0
/**
 * Figure out when and how to transmit to the given peer.
 *
 * @param cls the 'struct PeerPlan'
 * @param tc scheduler context
 */
static void
schedule_peer_transmission (void *cls,
                            const struct GNUNET_SCHEDULER_TaskContext *tc)
{
  struct PeerPlan *pp = cls;
  struct GSF_RequestPlan *rp;
  size_t msize;
  struct GNUNET_TIME_Relative delay;

  pp->task = GNUNET_SCHEDULER_NO_TASK;
  if (NULL != pp->pth)
  {
    GSF_peer_transmit_cancel_ (pp->pth);
    pp->pth = NULL;
  }
  /* move ready requests to priority queue */
  while ((NULL != (rp = GNUNET_CONTAINER_heap_peek (pp->delay_heap))) &&
         (GNUNET_TIME_absolute_get_remaining
          (rp->earliest_transmission).rel_value == 0))
  {
    GNUNET_assert (rp == GNUNET_CONTAINER_heap_remove_root (pp->delay_heap));
    rp->hn = GNUNET_CONTAINER_heap_insert (pp->priority_heap, rp, rp->priority);
  }
  if (0 == GNUNET_CONTAINER_heap_get_size (pp->priority_heap))
  {
    /* priority heap (still) empty, check for delay... */
    rp = GNUNET_CONTAINER_heap_peek (pp->delay_heap);
    if (NULL == rp)
    {
      GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "No active requests for plan %p.\n",
                  pp);
      return;                   /* both queues empty */
    }
    delay = GNUNET_TIME_absolute_get_remaining (rp->earliest_transmission);
    GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
                "Sleeping for %llu ms before retrying requests on plan %p.\n",
                (unsigned long long) delay.rel_value, pp);
    GNUNET_STATISTICS_set (GSF_stats, gettext_noop ("# delay heap timeout"),
                           delay.rel_value, GNUNET_NO);

    pp->task =
        GNUNET_SCHEDULER_add_delayed (delay, &schedule_peer_transmission, pp);
    return;
  }
#if INSANE_STATISTICS
  GNUNET_STATISTICS_update (GSF_stats, gettext_noop ("# query plans executed"),
                            1, GNUNET_NO);
#endif
  /* process from priority heap */
  rp = GNUNET_CONTAINER_heap_peek (pp->priority_heap);
  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Executing query plan %p\n", rp);
  GNUNET_assert (NULL != rp);
  msize = GSF_pending_request_get_message_ (get_latest (rp), 0, NULL);
  pp->pth =
      GSF_peer_transmit_ (pp->cp, GNUNET_YES, rp->priority,
                          GNUNET_TIME_UNIT_FOREVER_REL, msize,
                          &transmit_message_callback, pp);
  GNUNET_assert (NULL != pp->pth);
}
예제 #13
0
static void
srv_status (void *cls,
            const char *service,
            enum GNUNET_ARM_ServiceStatus status)
{
  if (status == GNUNET_ARM_SERVICE_MONITORING_STARTED)
  {
    LOG ("ARM monitor started, starting mock service\n");
    phase++;
    GNUNET_ARM_request_service_start (arm,
                                      SERVICE,
                                      GNUNET_OS_INHERIT_STD_OUT_AND_ERR,
                                      NULL,
                                      NULL);
    return;
  }
  if (0 != strcasecmp (service, SERVICE))
    return; /* not what we care about */
  if (phase == 1)
  {
    GNUNET_break (status == GNUNET_ARM_SERVICE_STARTING);
    GNUNET_break (phase == 1);
    LOG ("do-nothing is starting\n");
    phase++;
    ok = 1;
    GNUNET_assert (NULL == kt);
    startedWaitingAt = GNUNET_TIME_absolute_get ();
    kt = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS,
                                       &kill_task,
                                       NULL);
  }
  else if (phase == 2)
  {
    /* We passively monitor ARM for status updates. ARM should tell us
     * when do-nothing dies (no need to run a service upness test ourselves).
     */
    if (status == GNUNET_ARM_SERVICE_STARTING)
    {
      waitedFor = GNUNET_TIME_absolute_get_duration (startedWaitingAt);
      LOG ("Waited for: %s\n",
           GNUNET_STRINGS_relative_time_to_string (waitedFor,
                                                   GNUNET_YES));

      LOG ("do-nothing is starting, killing it...\n");
      GNUNET_assert (NULL == kt);
      kt = GNUNET_SCHEDULER_add_now (&kill_task, &ok);
    }
    else if ((status == GNUNET_ARM_SERVICE_STOPPED) && (trialCount == 14))
    {
      phase++;
      LOG ("do-nothing stopped working %u times, we are done here\n",
           (unsigned int) trialCount);
      GNUNET_ARM_request_service_stop (arm,
                                       "arm",
                                       &arm_stop_cb,
                                       NULL);
    }
  }
}
예제 #14
0
static void
send_test_messages (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
{
  struct TestMessageContext *pos = cls;

  if (((tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN) != 0) || (cls == NULL))
    return;

  if (die_task == GNUNET_SCHEDULER_NO_TASK)
  {
    die_task =
        GNUNET_SCHEDULER_add_delayed (TEST_TIMEOUT, &end_badly,
                                      "from create topology (timeout)");
  }

  if (total_server_connections >= MAX_OUTSTANDING_CONNECTIONS)
  {
    GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply
                                  (GNUNET_TIME_UNIT_SECONDS, 1),
                                  &send_test_messages, pos);
    return;                     /* Otherwise we'll double schedule messages here! */
  }
  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
              "Attempting to send test message from %s to %s\n",
              pos->peer1->shortname, pos->peer2->shortname);
  /*
   * Connect to the sending peer
   */
  pos->peer1handle =
      GNUNET_CORE_connect (pos->peer1->cfg, pos, &init_notify_peer1,
                           &connect_notify_peer1, NULL, NULL, GNUNET_NO, NULL,
                           GNUNET_NO, no_handlers);

  GNUNET_assert (pos->peer1handle != NULL);

  if (total_server_connections < MAX_OUTSTANDING_CONNECTIONS)
  {
    GNUNET_SCHEDULER_add_now (&send_test_messages, pos->next);
  }
  else
  {
    GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply
                                  (GNUNET_TIME_UNIT_SECONDS, 1),
                                  &send_test_messages, pos->next);
  }
}
예제 #15
0
/**
 * Task that triggers a NSE P2P transmission.
 *
 * @param cls the `struct NSEPeerEntry *`
 */
static void
transmit_task_cb (void *cls)
{
  struct NSEPeerEntry *peer_entry = cls;
  unsigned int idx;
  struct GNUNET_MQ_Envelope *env;

  peer_entry->transmit_task = NULL;
  idx = estimate_index;
  if (GNUNET_NO == peer_entry->previous_round)
  {
    idx = (idx + HISTORY_SIZE - 1) % HISTORY_SIZE;
    peer_entry->previous_round = GNUNET_YES;
    peer_entry->transmit_task
      = GNUNET_SCHEDULER_add_delayed (get_transmit_delay (0),
				      &transmit_task_cb,
				      peer_entry);
  }
  if ((0 == ntohl (size_estimate_messages[idx].hop_count)) &&
      (NULL != proof_task))
  {
    GNUNET_STATISTICS_update (stats,
                              "# flood messages not generated (no proof yet)",
                              1,
			      GNUNET_NO);
    return;
  }
  if (0 == ntohs (size_estimate_messages[idx].header.size))
  {
    GNUNET_STATISTICS_update (stats,
                              "# flood messages not generated (lack of history)",
                              1,
			      GNUNET_NO);
    return;
  }
  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
              "In round %s, sending to `%s' estimate with %u bits\n",
              GNUNET_STRINGS_absolute_time_to_string (GNUNET_TIME_absolute_ntoh (size_estimate_messages[idx].timestamp)),
              GNUNET_i2s (peer_entry->id),
              (unsigned int) ntohl (size_estimate_messages[idx].matching_bits));
  if (0 == ntohl (size_estimate_messages[idx].hop_count))
    GNUNET_STATISTICS_update (stats,
			      "# flood messages started",
			      1,
			      GNUNET_NO);
  GNUNET_STATISTICS_update (stats,
			    "# flood messages transmitted",
			    1,
                            GNUNET_NO);
#if ENABLE_NSE_HISTOGRAM
  peer_entry->transmitted_messages++;
  peer_entry->last_transmitted_size
    = ntohl(size_estimate_messages[idx].matching_bits);
#endif
  env = GNUNET_MQ_msg_copy (&size_estimate_messages[idx].header);
  GNUNET_MQ_send (peer_entry->mq,
		  env);
}
예제 #16
0
/**
 * Calculate when we would like to send the next HELLO to this
 * peer and ask for it.
 *
 * @param cls for which peer to schedule the HELLO
 */
static void
schedule_next_hello (void *cls)
{
  struct Peer *pl = cls;
  struct FindAdvHelloContext fah;
  struct GNUNET_MQ_Envelope *env;
  size_t want;
  struct GNUNET_TIME_Relative delay;
  struct GNUNET_HashCode hc;

  pl->hello_delay_task = NULL;
  GNUNET_assert (NULL != pl->mq);
  /* find applicable HELLOs */
  fah.peer = pl;
  fah.result = NULL;
  fah.max_size = GNUNET_SERVER_MAX_MESSAGE_SIZE - 1;
  fah.next_adv = GNUNET_TIME_UNIT_FOREVER_REL;
  GNUNET_CONTAINER_multipeermap_iterate (peers,
                                         &find_advertisable_hello,
                                         &fah);
  pl->hello_delay_task =
      GNUNET_SCHEDULER_add_delayed (fah.next_adv,
                                    &schedule_next_hello,
                                    pl);
  if (NULL == fah.result)
    return;
  delay = GNUNET_TIME_absolute_get_remaining (pl->next_hello_allowed);
  if (0 != delay.rel_value_us)
    return;

  want = GNUNET_HELLO_size (fah.result->hello);
  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
	      "Sending HELLO with %u bytes",
	      (unsigned int) want);
  env = GNUNET_MQ_msg_copy (&fah.result->hello->header);
  GNUNET_MQ_send (pl->mq,
		  env);

  /* avoid sending this one again soon */
  GNUNET_CRYPTO_hash (&pl->pid,
		      sizeof (struct GNUNET_PeerIdentity),
		      &hc);
  GNUNET_CONTAINER_bloomfilter_add (fah.result->filter,
				    &hc);

  GNUNET_STATISTICS_update (stats,
			    gettext_noop ("# HELLO messages gossipped"),
			    1,
			    GNUNET_NO);
  /* prepare to send the next one */
  if (NULL != pl->hello_delay_task)
    GNUNET_SCHEDULER_cancel (pl->hello_delay_task);
  pl->next_hello_allowed
    = GNUNET_TIME_relative_to_absolute (HELLO_ADVERTISEMENT_MIN_FREQUENCY);
  pl->hello_delay_task
    = GNUNET_SCHEDULER_add_now (&schedule_next_hello,
				pl);
}
static void
stop_arm (struct PeerContext *p)
{
  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
	      "Asking ARM to stop core service\n");
  GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS,
				&waitpid_task,
				p);
}
예제 #18
0
static void
run_property (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
{
  struct SysmonProperty *sp = cls;
  sp->task_id = GNUNET_SCHEDULER_NO_TASK;
  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Running continous property `%s' \n", sp->desc);
  sp->task (cls, tc);
  sp->task_id = GNUNET_SCHEDULER_add_delayed (sp->interval, &run_property, sp);
}
/**
 * Schedule a task to try to connect to the specified peer.
 *
 * @param pos peer to connect to
 */
static void
schedule_attempt_connect (struct Peer *pos)
{
  if (GNUNET_SCHEDULER_NO_TASK != pos->attempt_connect_task)
    return;
  pos->attempt_connect_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_absolute_get_remaining (next_connect_attempt),
							    &do_attempt_connect,
							    pos);
}
예제 #20
0
/**
 * This function is called *before* the DNS request has been 
 * given to a "local" DNS resolver.  Tunneling for DNS requests
 * was enabled, so we now need to send the request via some MESH
 * tunnel to a DNS EXIT for resolution.
 *
 * @param cls closure
 * @param rh request handle to user for reply
 * @param request_length number of bytes in request
 * @param request udp payload of the DNS request
 */
static void 
dns_pre_request_handler (void *cls,
			 struct GNUNET_DNS_RequestHandle *rh,
			 size_t request_length,
			 const char *request)
{
  struct RequestContext *rc;
  size_t mlen;
  struct GNUNET_MessageHeader hdr;
  struct GNUNET_TUN_DnsHeader dns;

  GNUNET_STATISTICS_update (stats,
			    gettext_noop ("# DNS requests intercepted"),
			    1, GNUNET_NO);
  if (0 == dns_exit_available)
  {
    GNUNET_STATISTICS_update (stats,
			      gettext_noop ("# DNS requests dropped (DNS mesh tunnel down)"),
			      1, GNUNET_NO);
    GNUNET_DNS_request_drop (rh);
    return;
  }
  if (request_length < sizeof (dns))
  {
    GNUNET_STATISTICS_update (stats,
			      gettext_noop ("# DNS requests dropped (malformed)"),
			      1, GNUNET_NO);
    GNUNET_DNS_request_drop (rh);
    return;
  }
  memcpy (&dns, request, sizeof (dns));
  GNUNET_assert (NULL != mesh_tunnel);
  mlen = sizeof (struct GNUNET_MessageHeader) + request_length;
  rc = GNUNET_malloc (sizeof (struct RequestContext) + mlen);
  rc->rh = rh;
  rc->mesh_message = (const struct GNUNET_MessageHeader*) &rc[1];
  rc->timeout_task = GNUNET_SCHEDULER_add_delayed (TIMEOUT,
						   &timeout_request,
						   rc);
  rc->dns_id = dns.id;
  hdr.type = htons (GNUNET_MESSAGE_TYPE_VPN_DNS_TO_INTERNET);
  hdr.size = htons (mlen);
  memcpy (&rc[1], &hdr, sizeof (struct GNUNET_MessageHeader));
  memcpy (&(((char*)&rc[1])[sizeof (struct GNUNET_MessageHeader)]),
	  request,
	  request_length);
  GNUNET_CONTAINER_DLL_insert_tail (transmit_queue_head,
				    transmit_queue_tail,
				    rc);
  if (NULL == mesh_th)
    mesh_th = GNUNET_MESH_notify_transmit_ready (mesh_tunnel,
						 GNUNET_NO, 0,
						 TIMEOUT,
						 NULL, mlen,
						 &transmit_dns_request_to_mesh,
						 NULL);
}
/**
 * Reset the timeout for the stream client (due to activity).
 *
 * @param sc client handle to reset timeout for
 */
static void
refresh_timeout_task (struct StreamClient *sc)
{
  if (GNUNET_SCHEDULER_NO_TASK != sc->timeout_task)
    GNUNET_SCHEDULER_cancel (sc->timeout_task); 
  sc->timeout_task = GNUNET_SCHEDULER_add_delayed (IDLE_TIMEOUT,
						   &timeout_stream_task,
						   sc);
}
static void
try_connect (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
{
  connect_task =
      GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS, &try_connect,
                                    NULL);
  GNUNET_TRANSPORT_try_connect (p1.th, &p2.id, NULL, NULL); /*FIXME TRY_CONNECT change */
  GNUNET_TRANSPORT_try_connect (p2.th, &p1.id, NULL, NULL); /*FIXME TRY_CONNECT change */
}
예제 #23
0
/**
 * Perform a PUT operation storing data in the DHT.  FIXME: we should
 * change the protocol to get a confirmation for the PUT from the DHT
 * and call 'cont' only after getting the confirmation; otherwise, the
 * client has no good way of telling if the 'PUT' message actually got
 * to the DHT service!
 *
 * @param handle handle to DHT service
 * @param key the key to store under
 * @param desired_replication_level estimate of how many
 *                nearest peers this request should reach
 * @param options routing options for this message
 * @param type type of the value
 * @param size number of bytes in data; must be less than 64k
 * @param data the data to store
 * @param exp desired expiration time for the value
 * @param timeout how long to wait for transmission of this request
 * @param cont continuation to call when done (transmitting request to service)
 *        You must not call #GNUNET_DHT_disconnect in this continuation
 * @param cont_cls closure for @a cont
 */
struct GNUNET_DHT_PutHandle *
GNUNET_DHT_put (struct GNUNET_DHT_Handle *handle,
		const struct GNUNET_HashCode * key,
                uint32_t desired_replication_level,
                enum GNUNET_DHT_RouteOption options,
                enum GNUNET_BLOCK_Type type, size_t size,
		const void *data,
                struct GNUNET_TIME_Absolute exp,
                struct GNUNET_TIME_Relative timeout,
		GNUNET_DHT_PutContinuation cont,
                void *cont_cls)
{
  struct GNUNET_DHT_ClientPutMessage *put_msg;
  size_t msize;
  struct PendingMessage *pending;
  struct GNUNET_DHT_PutHandle *ph;


  msize = sizeof (struct GNUNET_DHT_ClientPutMessage) + size;
  if ((msize >= GNUNET_SERVER_MAX_MESSAGE_SIZE) ||
      (size >= GNUNET_SERVER_MAX_MESSAGE_SIZE))
  {
    GNUNET_break (0);
    return NULL;
  }
  ph = GNUNET_new (struct GNUNET_DHT_PutHandle);
  ph->dht_handle = handle;
  ph->timeout_task = GNUNET_SCHEDULER_add_delayed (timeout, &timeout_put_request, ph);
  ph->cont = cont;
  ph->cont_cls = cont_cls;
  ph->unique_id = ++handle->uid_gen;
  pending = GNUNET_malloc (sizeof (struct PendingMessage) + msize);
  ph->pending = pending;
  put_msg = (struct GNUNET_DHT_ClientPutMessage *) &pending[1];
  pending->msg = &put_msg->header;
  pending->handle = handle;
  pending->cont = &mark_put_message_gone;
  pending->cont_cls = ph;
  pending->free_on_send = GNUNET_YES;
  put_msg->header.size = htons (msize);
  put_msg->header.type = htons (GNUNET_MESSAGE_TYPE_DHT_CLIENT_PUT);
  put_msg->type = htonl (type);
  put_msg->options = htonl ((uint32_t) options);
  put_msg->desired_replication_level = htonl (desired_replication_level);
  put_msg->unique_id = ph->unique_id;
  put_msg->expiration = GNUNET_TIME_absolute_hton (exp);
  put_msg->key = *key;
  memcpy (&put_msg[1], data, size);
  GNUNET_CONTAINER_DLL_insert (handle->pending_head, handle->pending_tail,
                               pending);
  pending->in_pending_queue = GNUNET_YES;
  GNUNET_CONTAINER_DLL_insert_tail (handle->put_head,
				    handle->put_tail,
				    ph);
  process_pending_messages (handle);
  return ph;
}
예제 #24
0
파일: helper.c 프로젝트: GNUnet/gnunet
/**
 * Start the helper process.
 *
 * @param h handle to the helper process
 */
static void
start_helper (struct GNUNET_HELPER_Handle *h)
{
  h->helper_in = GNUNET_DISK_pipe (GNUNET_YES, GNUNET_YES, GNUNET_YES, GNUNET_NO);
  h->helper_out = GNUNET_DISK_pipe (GNUNET_YES, GNUNET_YES, GNUNET_NO, GNUNET_YES);
  if ( (h->helper_in == NULL) || (h->helper_out == NULL))
  {
    /* out of file descriptors? try again later... */
    stop_helper (h, GNUNET_NO);
    h->restart_task =
      GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS,
								  h->retry_back_off),
				    &restart_task, h);
    return;
  }
  GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
	      "Starting HELPER process `%s'\n",
	      h->binary_name);
  h->fh_from_helper =
      GNUNET_DISK_pipe_handle (h->helper_out, GNUNET_DISK_PIPE_END_READ);
  h->fh_to_helper =
      GNUNET_DISK_pipe_handle (h->helper_in, GNUNET_DISK_PIPE_END_WRITE);
  h->helper_proc =
    GNUNET_OS_start_process_vap (h->with_control_pipe, GNUNET_OS_INHERIT_STD_ERR,
				 h->helper_in, h->helper_out, NULL,
				 h->binary_name,
				 h->binary_argv);
  if (NULL == h->helper_proc)
  {
    /* failed to start process? try again later... */
    stop_helper (h, GNUNET_NO);
    h->restart_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_SECONDS,
										  h->retry_back_off),
						    &restart_task, h);
    return;
  }
  GNUNET_DISK_pipe_close_end (h->helper_out, GNUNET_DISK_PIPE_END_WRITE);
  GNUNET_DISK_pipe_close_end (h->helper_in, GNUNET_DISK_PIPE_END_READ);
  if (NULL != h->mst)
    h->read_task = GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL,
						   h->fh_from_helper,
						   &helper_read,
						   h);
}
예제 #25
0
/**
 * Call a method for each known matching host and change its trust
 * value.  The callback method will be invoked once for each matching
 * host and then finally once with a NULL pointer.  After that final
 * invocation, the iterator context must no longer be used.
 *
 * Instead of calling this function with 'peer == NULL' it is often
 * better to use 'GNUNET_PEERINFO_notify'.
 *
 * @param h handle to the peerinfo service
 * @param peer restrict iteration to this peer only (can be NULL)
 * @param timeout how long to wait until timing out
 * @param callback the method to call for each peer
 * @param callback_cls closure for callback
 * @return iterator context
 */
struct GNUNET_PEERINFO_IteratorContext *
GNUNET_PEERINFO_iterate (struct GNUNET_PEERINFO_Handle *h,
                         const struct GNUNET_PeerIdentity *peer,
                         struct GNUNET_TIME_Relative timeout,
                         GNUNET_PEERINFO_Processor callback, void *callback_cls)
{
  struct GNUNET_MessageHeader *lapm;
  struct ListPeerMessage *lpm;
  struct GNUNET_PEERINFO_IteratorContext *ic;
  struct GNUNET_PEERINFO_AddContext *ac;

  ic = GNUNET_malloc (sizeof (struct GNUNET_PEERINFO_IteratorContext));
  if (NULL == peer)
  {
    LOG (GNUNET_ERROR_TYPE_DEBUG,
         "Requesting list of peers from PEERINFO service\n");
    ac =
        GNUNET_malloc (sizeof (struct GNUNET_PEERINFO_AddContext) +
                       sizeof (struct GNUNET_MessageHeader));
    ac->size = sizeof (struct GNUNET_MessageHeader);
    lapm = (struct GNUNET_MessageHeader *) &ac[1];
    lapm->size = htons (sizeof (struct GNUNET_MessageHeader));
    lapm->type = htons (GNUNET_MESSAGE_TYPE_PEERINFO_GET_ALL);
  }
  else
  {
    LOG (GNUNET_ERROR_TYPE_DEBUG,
         "Requesting information on peer `%4s' from PEERINFO service\n",
         GNUNET_i2s (peer));
    ac =
        GNUNET_malloc (sizeof (struct GNUNET_PEERINFO_AddContext) +
                       sizeof (struct ListPeerMessage));
    ac->size = sizeof (struct ListPeerMessage);
    lpm = (struct ListPeerMessage *) &ac[1];
    lpm->header.size = htons (sizeof (struct ListPeerMessage));
    lpm->header.type = htons (GNUNET_MESSAGE_TYPE_PEERINFO_GET);
    memcpy (&lpm->peer, peer, sizeof (struct GNUNET_PeerIdentity));
    ic->have_peer = GNUNET_YES;
    ic->peer = *peer;
  }
  ic->h = h;
  ic->ac = ac;
  ic->callback = callback;
  ic->callback_cls = callback_cls;
  ic->timeout = GNUNET_TIME_relative_to_absolute (timeout);
  ic->timeout_task =
      GNUNET_SCHEDULER_add_delayed (timeout, &signal_timeout, ic);
  ac->cont = &iterator_start_receive;
  ac->cont_cls = ic;
  GNUNET_CONTAINER_DLL_insert_tail (h->ac_head, h->ac_tail, ac);
  GNUNET_CONTAINER_DLL_insert_tail (h->ic_head,
				    h->ic_tail,
				    ic);
  trigger_transmit (h);
  return ic;
}
static void
run_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
{
  char *fn;
  const struct GNUNET_DISK_FileHandle *stdout_read_handle;
  const struct GNUNET_DISK_FileHandle *wh;

  GNUNET_asprintf (&fn, "cat");

  hello_pipe_stdin = GNUNET_DISK_pipe (GNUNET_YES, GNUNET_YES, GNUNET_YES, GNUNET_NO);
  hello_pipe_stdout = GNUNET_DISK_pipe (GNUNET_YES, GNUNET_YES, GNUNET_NO, GNUNET_YES);

  if ((hello_pipe_stdout == NULL) || (hello_pipe_stdin == NULL))
  {
    GNUNET_break (0);
    ok = 1;
    GNUNET_free (fn);
    return;
  }

  proc =
      GNUNET_OS_start_process (GNUNET_NO, hello_pipe_stdin, hello_pipe_stdout, fn,
                               "test_gnunet_echo_hello", "-", NULL);
  GNUNET_free (fn);

  /* Close the write end of the read pipe */
  GNUNET_DISK_pipe_close_end (hello_pipe_stdout, GNUNET_DISK_PIPE_END_WRITE);
  /* Close the read end of the write pipe */
  GNUNET_DISK_pipe_close_end (hello_pipe_stdin, GNUNET_DISK_PIPE_END_READ);

  wh = GNUNET_DISK_pipe_handle (hello_pipe_stdin, GNUNET_DISK_PIPE_END_WRITE);

  /* Write the test_phrase to the cat process */
  if (GNUNET_DISK_file_write (wh, test_phrase, strlen (test_phrase) + 1) !=
      strlen (test_phrase) + 1)
  {
    GNUNET_break (0);
    ok = 1;
    return;
  }

  /* Close the write end to end the cycle! */
  GNUNET_DISK_pipe_close_end (hello_pipe_stdin, GNUNET_DISK_PIPE_END_WRITE);

  stdout_read_handle =
      GNUNET_DISK_pipe_handle (hello_pipe_stdout, GNUNET_DISK_PIPE_END_READ);

  die_task =
      GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_relative_multiply
                                    (GNUNET_TIME_UNIT_MINUTES, 1), &end_task,
                                    NULL);

  GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL,
                                  stdout_read_handle, &read_call,
                                  (void *) stdout_read_handle);
}
예제 #27
0
/**
 * Periodic task to refresh our announcement of the regex.
 *
 * @param cls the `struct ClientEntry *` of the client that triggered the
 *        announcement
 */
static void
reannounce (void *cls)
{
  struct ClientEntry *ce = cls;

  REGEX_INTERNAL_reannounce (ce->ah);
  ce->refresh_task = GNUNET_SCHEDULER_add_delayed (ce->frequency,
						   &reannounce,
						   ce);
}
static void
reconnect (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
{
  struct PeerContext *p = cls;

  reconnect_task = GNUNET_SCHEDULER_NO_TASK;
  GNUNET_TRANSPORT_try_connect (p1->th, &p2->id, NULL, NULL); /*FIXME TRY_CONNECT change */
  reconnect_task =
      GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS, &reconnect, p);
}
예제 #29
0
/**
 * Disconnect from service and then reconnect.
 *
 * @param h our handle
 */
static void
force_reconnect (struct GNUNET_NAMESTORE_Handle *h)
{
  h->reconnect = GNUNET_NO;
  GNUNET_CLIENT_disconnect (h->client);
  h->client = NULL;
  h->reconnect_task = GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS,
                                    &reconnect_task,
                                    h);
}
예제 #30
0
/**
 * Continuation called from expected-to-fail rename operation.
 *
 * @param cls NULL
 * @param emsg (should also be NULL)
 */
static void
fail_rename_cont (void *cls,
		  const char *emsg)
{
  GNUNET_assert (NULL != emsg);
  op = NULL;
  GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS,
                                &finally_delete,
                                NULL);
}