/**
 * Recalculate preference for a specific ATS property
 *
 * @param c the preference client
 * @param kind the preference kind
 * @return the result
 */
static void
recalculate_relative_preferences (struct PreferenceClient *c,
                                  enum GNUNET_ATS_PreferenceKind kind)
{
  struct UpdateContext uc;

  /* For this client: sum of absolute preference values for this preference */
  uc.kind = kind;
  uc.pc = c;
  c->f_abs_sum[kind] = 0.0;

  /* For all peers: calculate sum of absolute preferences */
  GNUNET_CONTAINER_multipeermap_iterate (c->peer2pref,
                                         &update_abs_sum,
                                         &uc);
  LOG (GNUNET_ERROR_TYPE_DEBUG,
       "Client has sum of total preferences for %s of %.3f\n",
       GNUNET_ATS_print_preference_type (kind),
       c->f_abs_sum[kind]);

  /* For all peers: calculate relative preference */
  GNUNET_CONTAINER_multipeermap_iterate (c->peer2pref,
                                         &update_rel_sum,
                                         &uc);
}
Beispiel #2
0
/**
 * Task run to terminate the testcase.
 *
 * @param cls NULL
 * @param tc unused
 */
static void
end (void *cls,
     const struct GNUNET_SCHEDULER_TaskContext *tc)
{
  if (0 != ret)
    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                "Test failed at stage %u %s\n",
                off,
                (NULL != test_commands[off].label)
                ? test_commands[off].label
                : "");
  if (NULL != interpreter_task)
  {
    GNUNET_SCHEDULER_cancel (interpreter_task);
    interpreter_task = NULL;
  }
  if (NULL != sched_ats)
  {
    GNUNET_ATS_scheduling_done (sched_ats);
    sched_ats = NULL;
  }
  if (NULL != con_ats)
  {
    GNUNET_ATS_connectivity_done (con_ats);
    con_ats = NULL;
  }
  if (NULL != perf_ats)
  {
    GNUNET_ATS_performance_done (perf_ats);
    perf_ats = NULL;
  }
  if (NULL != p2asd)
  {
    GNUNET_CONTAINER_multipeermap_iterate (p2asd,
                                           &free_asd,
                                           NULL);
    GNUNET_CONTAINER_multipeermap_destroy (p2asd);
    p2asd = NULL;
  }
  if (NULL != p2aid)
  {
    GNUNET_CONTAINER_multipeermap_iterate (p2aid,
                                           &free_aid,
                                           NULL);
    GNUNET_CONTAINER_multipeermap_destroy (p2aid);
    p2aid = NULL;
  }
}
/**
 * Update and normalize atsi performance information
 *
 * @param address the address to update
 */
void
GAS_normalization_update_property (struct ATS_Address *address)
{
  const struct GNUNET_ATS_Properties *prop = &address->properties;
  struct PropertyRange range;

  LOG (GNUNET_ERROR_TYPE_DEBUG,
       "Updating properties for peer `%s'\n",
       GNUNET_i2s (&address->peer));
  GAS_plugin_solver_lock ();
  update_avg (prop->delay.rel_value_us,
              &address->norm_delay);
  update_avg (prop->distance,
              &address->norm_distance);
  update_avg (prop->utilization_in,
              &address->norm_utilization_in);
  update_avg (prop->utilization_in,
              &address->norm_utilization_out);

  init_range (&range);
  GNUNET_CONTAINER_multipeermap_iterate (GSA_addresses,
                                         &find_min_max_it,
                                         &range);
  if (0 != memcmp (&range,
                   &property_range,
                   sizeof (struct PropertyRange)))
  {
    /* limits changed, (re)normalize all addresses */
    property_range = range;
    GNUNET_CONTAINER_multipeermap_iterate (GSA_addresses,
                                           &normalize_address,
                                           NULL);
    GNUNET_CONTAINER_multipeermap_iterate (GSA_addresses,
                                           &notify_change,
                                           NULL);
  }
  else
  {
    /* renormalize just this one address */
    normalize_address (NULL,
                       &address->peer,
                       address);
    notify_change (NULL,
                   &address->peer,
                   address);
  }
  GAS_plugin_solver_unlock ();
}
/**
 * Unregister a client (which may have been a connectivity client,
 * but this is not assured).
 *
 * @param client handle of the (now dead) client
 */
void
GAS_connectivity_remove_client (struct GNUNET_SERVER_Client *client)
{
  GNUNET_CONTAINER_multipeermap_iterate (connection_requests,
                                         &free_matching_requests,
                                         client);
}
/**
 * Reduce absolute preferences since they got old.
 *
 * @param cls unused
 */
static void
preference_aging (void *cls)
{
  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");
  }
}
Beispiel #6
0
/**
 * Disconnect from DV service.
 *
 * @param sh service handle
 */
void
GNUNET_DV_service_disconnect (struct GNUNET_DV_ServiceHandle *sh)
{
  struct GNUNET_DV_TransmitHandle *pos;

  if (NULL == sh)
    return;
  if (NULL != sh->th)
  {
    GNUNET_CLIENT_notify_transmit_ready_cancel (sh->th);
    sh->th = NULL;
  }
  while (NULL != (pos = sh->th_head))
  {
    GNUNET_CONTAINER_DLL_remove (sh->th_head,
				 sh->th_tail,
				 pos);
    GNUNET_free (pos);
  }
  if (NULL != sh->client)
  {
    GNUNET_CLIENT_disconnect (sh->client);
    sh->client = NULL;
  }
  GNUNET_CONTAINER_multipeermap_iterate (sh->peers,
					 &cleanup_send_cb,
					 sh);
  GNUNET_CONTAINER_multipeermap_destroy (sh->peers);
  GNUNET_free (sh);
}
Beispiel #7
0
/**
 * Disconnect and then reconnect to the DV service.
 *
 * @param sh service handle
 */
static void
reconnect (struct GNUNET_DV_ServiceHandle *sh)
{
  if (NULL != sh->th)
  {
    GNUNET_CLIENT_notify_transmit_ready_cancel (sh->th);
    sh->th = NULL;
  }
  LOG (GNUNET_ERROR_TYPE_DEBUG,
       "Disconnecting from DV service at %p\n",
       sh->client);
  if (NULL != sh->client)
  {
    GNUNET_CLIENT_disconnect (sh->client);
    sh->client = NULL;
  }
  GNUNET_CONTAINER_multipeermap_iterate (sh->peers,
					 &cleanup_send_cb,
					 sh);
  LOG (GNUNET_ERROR_TYPE_DEBUG,
       "Connecting to DV service\n");
  sh->client = GNUNET_CLIENT_connect ("dv", sh->cfg);
  if (NULL == sh->client)
  {
    GNUNET_break (0);
    return;
  }
  sh->th = GNUNET_CLIENT_notify_transmit_ready (sh->client,
						sizeof (struct GNUNET_MessageHeader),
						GNUNET_TIME_UNIT_FOREVER_REL,
						GNUNET_YES,
						&transmit_start,
						sh);
}
/**
 * Task run in monitor mode when the user presses CTRL-C to abort.
 * Stops monitoring activity.
 *
 * @param cls the 'struct GNUNET_TRANSPORT_PeerIterateContext *'
 * @param tc scheduler context
 */
static void
shutdown_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
{
  struct GNUNET_TIME_Relative duration;
  end = GNUNET_SCHEDULER_NO_TASK;
  if (GNUNET_SCHEDULER_NO_TASK != op_timeout)
  {
    GNUNET_SCHEDULER_cancel (op_timeout);
    op_timeout = GNUNET_SCHEDULER_NO_TASK;
  }
  if (NULL != tc_handle)
  {
    GNUNET_TRANSPORT_try_connect_cancel (tc_handle);
    tc_handle = NULL;
  }
  if (NULL != pic)
  {
    GNUNET_TRANSPORT_monitor_peers_cancel (pic);
    pic = NULL;
  }
  if (NULL != vic)
  {
    GNUNET_TRANSPORT_monitor_validation_entries_cancel (vic);
    vic = NULL;
  }
  if (NULL != th)
  {
    GNUNET_TRANSPORT_notify_transmit_ready_cancel (th);
    th = NULL;
  }
  if (NULL != handle)
  {
    GNUNET_TRANSPORT_disconnect (handle);
    handle = NULL;
  }
  if (benchmark_send)
  {
    duration = GNUNET_TIME_absolute_get_duration (start_time);
    FPRINTF (stdout, _("Transmitted %llu bytes/s (%llu bytes in %s)\n"),
        1000LL * 1000LL * traffic_sent / (1 + duration.rel_value_us),
        traffic_sent,
        GNUNET_STRINGS_relative_time_to_string (duration, GNUNET_YES));
  }
  if (benchmark_receive)
  {
    duration = GNUNET_TIME_absolute_get_duration (start_time);
    FPRINTF (stdout, _("Received %llu bytes/s (%llu bytes in %s)\n"),
        1000LL * 1000LL * traffic_received / (1 + duration.rel_value_us),
        traffic_received,
        GNUNET_STRINGS_relative_time_to_string (duration, GNUNET_YES));
  }

  if (NULL != monitored_peers)
  {
    GNUNET_CONTAINER_multipeermap_iterate (monitored_peers, &destroy_it, NULL);
    GNUNET_CONTAINER_multipeermap_destroy (monitored_peers);
    monitored_peers = NULL;
  }
}
/**
 * We have a new client, notify it about all current sessions.
 *
 * @param client the new client
 */
void
GSC_SESSIONS_notify_client_about_sessions (struct GSC_Client *client)
{
  /* notify new client about existing sessions */
  GNUNET_CONTAINER_multipeermap_iterate (sessions,
                                         &notify_client_about_session,
                                         client);
}
Beispiel #10
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);
}
Beispiel #11
0
/**
 * Add peers and schedule connection attempt
 *
 * @param cls unused, NULL
 */
static void
add_peer_task (void *cls)
{
  add_task = NULL;

  GNUNET_CONTAINER_multipeermap_iterate (peers,
                                         &try_add_peers,
                                         NULL);
}
/**
 * Shutdown connectivity subsystem.
 */
void
GAS_connectivity_done ()
{
  GNUNET_CONTAINER_multipeermap_iterate (connection_requests,
                                         &free_request,
                                         NULL);
  GNUNET_CONTAINER_multipeermap_destroy (connection_requests);
  connection_requests = NULL;
}
/**
 * Broadcast an updated typemap message to all neighbours.
 * Restarts the retransmissions until the typemaps are confirmed.
 *
 * @param msg message to transmit
 */
void
GSC_SESSIONS_broadcast_typemap (const struct GNUNET_MessageHeader *msg)
{
  if (NULL == sessions)
    return;
  GNUNET_CONTAINER_multipeermap_iterate (sessions,
                                         &do_restart_typemap_message,
                                         (void *) msg);
}
/**
 * Shutdown ATS subsystem.
 */
void
GST_ats_done ()
{
  GNUNET_CONTAINER_multipeermap_iterate (p2a,
                                         &destroy_ai_cb,
                                         NULL);
  publish_p2a_stat_update ();
  GNUNET_CONTAINER_multipeermap_destroy (p2a);
  p2a = NULL;
}
/**
 * Shutdown sessions subsystem.
 */
void
GSC_SESSIONS_done ()
{
  if (NULL != sessions)
  {
    GNUNET_CONTAINER_multipeermap_iterate (sessions,
                                           &free_session_helper, NULL);
    GNUNET_CONTAINER_multipeermap_destroy (sessions);
    sessions = NULL;
  }
}
/**
 * Cleaup and destroy the map
 */
static void
cleanup_map ()
{
    if (NULL != map)
    {
        GNUNET_assert (GNUNET_SYSERR != GNUNET_CONTAINER_multipeermap_iterate (map,
                       &iterator,
                       NULL));
        GNUNET_CONTAINER_multipeermap_destroy (map);
        map = NULL;
    }
}
Beispiel #17
0
/**
 * Signature of a function called by ATS with the current bandwidth
 * and address preferences as determined by ATS.
 *
 * @param cls closure, should point to "asc-closure"
 * @param peer for which we suggest an address, NULL if ATS connection died
 * @param address suggested address (including peer identity of the peer),
 *             may be NULL to signal disconnect from peer
 * @param session session to use, NULL to establish a new outgoing session
 * @param bandwidth_out assigned outbound bandwidth for the connection,
 *        0 to signal disconnect
 * @param bandwidth_in assigned inbound bandwidth for the connection,
 *        0 to signal disconnect
 */
static void
address_suggest_cb (void *cls,
                    const struct GNUNET_PeerIdentity *peer,
                    const struct GNUNET_HELLO_Address *address,
                    struct GNUNET_ATS_Session *session,
                    struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out,
                    struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in)
{
  const char *asc_cls = cls;
  struct AddressSuggestData *asd;

  GNUNET_break (0 == strcmp (asc_cls, "asc-closure"));
  if (NULL == peer)
  {
    GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
                "Connection to ATS died, likely a crash!\n");
    GNUNET_SCHEDULER_shutdown ();
#if 0
    /* This is what we should do if we wanted to continue past
       the ATS crash. */
    GNUNET_CONTAINER_multipeermap_iterate (p2asd,
                                           &free_asd,
                                           NULL);
    GNUNET_CONTAINER_multipeermap_iterate (p2aid,
                                           &free_aid,
                                           NULL);
#endif
    return;
  }

  asd = find_address_suggestion (peer);
  if (NULL == asd)
  {
    asd = GNUNET_new (struct AddressSuggestData);
    GNUNET_assert (GNUNET_YES ==
                   GNUNET_CONTAINER_multipeermap_put (p2asd,
                                                      peer,
                                                      asd,
                                                      GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
  }
/**
 * Stop the nodes management
 */
void
GED_nodes_stop ()
{
  if (NULL != ch)
  {
  		GNUNET_CORE_disconnect (ch);
  		ch = NULL;
  }

  if (NULL != nodes_requested)
  {
  		GNUNET_CONTAINER_multipeermap_iterate (nodes_requested,
  																					 &cleanup_node,
  																					 nodes_requested);
  		update_stats (nodes_requested);
  		GNUNET_CONTAINER_multipeermap_destroy (nodes_requested);
  		nodes_requested = NULL;
  }

  if (NULL != nodes_active)
  {
  		GNUNET_CONTAINER_multipeermap_iterate (nodes_active,
  																					 &cleanup_node,
  																					 nodes_active);
  		update_stats (nodes_active);
  		GNUNET_CONTAINER_multipeermap_destroy (nodes_active);
  		nodes_active = NULL;
  }

  if (NULL != nodes_inactive)
  {
  		GNUNET_CONTAINER_multipeermap_iterate (nodes_inactive,
  																					 &cleanup_node,
  																					 nodes_inactive);
  		update_stats (nodes_inactive);
  		GNUNET_CONTAINER_multipeermap_destroy (nodes_inactive);
  		nodes_inactive = NULL;
  }
}
/**
 * @brief Store the peers currently in #valid_peers to disk.
 */
static void
store_valid_peers ()
{
  struct GNUNET_DISK_FileHandle *fh;
  uint32_t number_written_peers;
  int ret;

  if (0 == strncmp ("DISABLE", filename_valid_peers, 7))
  {
    return;
  }

  ret = GNUNET_DISK_directory_create_for_file (filename_valid_peers);
  if (GNUNET_SYSERR == ret)
  {
    LOG (GNUNET_ERROR_TYPE_WARNING,
        "Not able to create directory for file `%s'\n",
        filename_valid_peers);
    GNUNET_break (0);
  }
  else if (GNUNET_NO == ret)
  {
    LOG (GNUNET_ERROR_TYPE_WARNING,
        "Directory for file `%s' exists but is not writable for us\n",
        filename_valid_peers);
    GNUNET_break (0);
  }
  fh = GNUNET_DISK_file_open (filename_valid_peers,
                              GNUNET_DISK_OPEN_WRITE |
                                  GNUNET_DISK_OPEN_CREATE,
                              GNUNET_DISK_PERM_USER_READ |
                                  GNUNET_DISK_PERM_USER_WRITE);
  if (NULL == fh)
  {
    LOG (GNUNET_ERROR_TYPE_WARNING,
        "Not able to write valid peers to file `%s'\n",
        filename_valid_peers);
    return;
  }
  LOG (GNUNET_ERROR_TYPE_DEBUG,
      "Writing %u valid peers to disk\n",
      GNUNET_CONTAINER_multipeermap_size (valid_peers));
  number_written_peers =
    GNUNET_CONTAINER_multipeermap_iterate (valid_peers,
                                           store_peer_presistently_iterator,
                                           fh);
  GNUNET_assert (GNUNET_OK == GNUNET_DISK_file_close (fh));
  GNUNET_assert (number_written_peers ==
      GNUNET_CONTAINER_multipeermap_size (valid_peers));
}
Beispiel #20
0
/**
 * Update our flood message to be sent (and our timestamps).
 *
 * @param cls unused
 */
static void
update_flood_message (void *cls)
{
  struct GNUNET_TIME_Relative offset;
  unsigned int i;

  flood_task = NULL;
  offset = GNUNET_TIME_absolute_get_remaining (next_timestamp);
  if (0 != offset.rel_value_us)
  {
    /* somehow run early, delay more */
    flood_task =
        GNUNET_SCHEDULER_add_delayed (offset,
				      &update_flood_message,
				      NULL);
    return;
  }
  estimate_index = (estimate_index + 1) % HISTORY_SIZE;
  if (estimate_count < HISTORY_SIZE)
    estimate_count++;
  current_timestamp = next_timestamp;
  next_timestamp =
      GNUNET_TIME_absolute_add (current_timestamp, gnunet_nse_interval);
  if ( (current_timestamp.abs_value_us ==
	GNUNET_TIME_absolute_ntoh (next_message.timestamp).abs_value_us) &&
       (get_matching_bits (current_timestamp, &my_identity) <
	ntohl(next_message.matching_bits)) )
  {
    /* we received a message for this round way early, use it! */
    size_estimate_messages[estimate_index] = next_message;
    size_estimate_messages[estimate_index].hop_count =
        htonl (1 + ntohl (next_message.hop_count));
  }
  else
    setup_flood_message (estimate_index,
			 current_timestamp);
  next_message.matching_bits = htonl (0);       /* reset for 'next' round */
  hop_count_max = 0;
  for (i = 0; i < HISTORY_SIZE; i++)
    hop_count_max = GNUNET_MAX (ntohl (size_estimate_messages[i].hop_count),
				hop_count_max);
  GNUNET_CONTAINER_multipeermap_iterate (peers,
                                         &schedule_current_round,
                                         NULL);
  flood_task
    = GNUNET_SCHEDULER_add_at (next_timestamp,
                               &update_flood_message,
                               NULL);
}
/**
 * @brief Delete storage of peers that was created with #Peers_initialise ()
 */
void
Peers_terminate ()
{
  if (GNUNET_SYSERR ==
      GNUNET_CONTAINER_multipeermap_iterate (peer_map,
                                             peermap_clear_iterator,
                                             NULL))
  {
    LOG (GNUNET_ERROR_TYPE_WARNING,
        "Iteration destroying peers was aborted.\n");
  }
  GNUNET_CONTAINER_multipeermap_destroy (peer_map);
  store_valid_peers ();
  GNUNET_free (filename_valid_peers);
  GNUNET_CONTAINER_multipeermap_destroy (valid_peers);
}
/**
 * @brief Get all currently known, valid peer ids.
 *
 * @param it function to call on each peer id
 * @param it_cls extra argument to @a it
 * @return the number of key value pairs processed,
 *         #GNUNET_SYSERR if it aborted iteration
 */
int
Peers_get_valid_peers (PeersIterator iterator,
                       void *it_cls)
{
  struct PeersIteratorCls *cls;
  int ret;

  cls = GNUNET_new (struct PeersIteratorCls);
  cls->iterator = iterator;
  cls->cls = it_cls;
  ret = GNUNET_CONTAINER_multipeermap_iterate (valid_peers,
                                               valid_peer_iterator,
                                               cls);
  GNUNET_free (cls);
  return ret;
}
/**
 * Shutdown neighbours subsystem.
 */
void
GSC_NEIGHBOURS_done ()
{
  if (NULL != transport)
  {
    GNUNET_TRANSPORT_disconnect (transport);
    transport = NULL;
  }
  if (NULL != neighbours)
  {
    GNUNET_CONTAINER_multipeermap_iterate (neighbours,
                                           &free_neighbour_helper,
					   NULL);
    GNUNET_CONTAINER_multipeermap_destroy (neighbours);
    neighbours = NULL;
  }
}
/**
 * @brief Get a random peer from @a peer_map
 *
 * @param peer_map the peer_map to get the peer from
 *
 * @return a random peer
 */
static const struct GNUNET_PeerIdentity *
get_random_peer_from_peermap (const struct
                              GNUNET_CONTAINER_MultiPeerMap *peer_map)
{
  struct GetRandPeerIteratorCls *iterator_cls;
  const struct GNUNET_PeerIdentity *ret;

  iterator_cls = GNUNET_new (struct GetRandPeerIteratorCls);
  iterator_cls->index = GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_WEAK,
      GNUNET_CONTAINER_multipeermap_size (peer_map));
  (void) GNUNET_CONTAINER_multipeermap_iterate (valid_peers,
                                                get_rand_peer_iterator,
                                                iterator_cls);
  ret = iterator_cls->peer;
  GNUNET_free (iterator_cls);
  return ret;
}
/**
 * Begin monitoring sessions of a plugin.  There can only
 * be one active monitor per plugin (i.e. if there are
 * multiple monitors, the transport service needs to
 * multiplex the generated events over all of them).
 *
 * @param cls closure of the plugin
 * @param sic callback to invoke, NULL to disable monitor;
 *            plugin will being by iterating over all active
 *            sessions immediately and then enter monitor mode
 * @param sic_cls closure for @a sic
 */
static void
template_plugin_setup_monitor (void *cls,
                               GNUNET_TRANSPORT_SessionInfoCallback sic,
                               void *sic_cls)
{
  struct Plugin *plugin = cls;

  plugin->sic = sic;
  plugin->sic_cls = sic_cls;
  if (NULL != sic)
  {
#if 0
    GNUNET_CONTAINER_multipeermap_iterate (NULL /* FIXME */,
                                           &send_session_info_iter,
                                           plugin);
#endif
    /* signal end of first iteration */
    sic (sic_cls, NULL, NULL);
  }
}
Beispiel #26
0
/**
 * Disconnect from the core service.  This function can only
 * be called *after* all pending #GNUNET_CORE_notify_transmit_ready()
 * requests have been explicitly canceled.
 *
 * @param handle connection to core to disconnect
 */
void
GNUNET_CORE_disconnect (struct GNUNET_CORE_Handle *handle)
{
  struct ControlMessage *cm;

  GNUNET_assert (NULL != handle);

  LOG (GNUNET_ERROR_TYPE_DEBUG, "Disconnecting from CORE service\n");
  if (NULL != handle->cth)
  {
    GNUNET_CLIENT_notify_transmit_ready_cancel (handle->cth);
    handle->cth = NULL;
  }
  while (NULL != (cm = handle->control_pending_head))
  {
    GNUNET_CONTAINER_DLL_remove (handle->control_pending_head,
                                 handle->control_pending_tail, cm);
    if (NULL != cm->th)
      cm->th->cm = NULL;
    if (NULL != cm->cont)
      cm->cont (cm->cont_cls, GNUNET_SYSERR);
    GNUNET_free (cm);
  }
  if (NULL != handle->client)
  {
    GNUNET_CLIENT_disconnect (handle->client);
    handle->client = NULL;
  }
  GNUNET_CONTAINER_multipeermap_iterate (handle->peers,
                                         &disconnect_and_free_peer_entry,
                                         handle);
  if (handle->reconnect_task != GNUNET_SCHEDULER_NO_TASK)
  {
    GNUNET_SCHEDULER_cancel (handle->reconnect_task);
    handle->reconnect_task = GNUNET_SCHEDULER_NO_TASK;
  }
  GNUNET_CONTAINER_multipeermap_destroy (handle->peers);
  handle->peers = NULL;
  GNUNET_break (handle->ready_peer_head == NULL);
  GNUNET_free (handle);
}
/**
 * Shutdown
 *
 * @param cls NULL
 * @param tc task context from scheduler
 * @return 
 */
static void
do_shutdown (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
{
  shutdown_task = GNUNET_SCHEDULER_NO_TASK;
  GNUNET_ATS_performance_done (ats);
  ats = NULL;
  if (NULL != stmt_insert)
  {
    sqlite3_finalize (stmt_insert);
    stmt_insert = NULL;
  }
  GNUNET_break (SQLITE_OK == sqlite3_close (db));
  db = NULL;
  if (NULL != map)
  {
    GNUNET_assert (GNUNET_SYSERR != 
                   GNUNET_CONTAINER_multipeermap_iterate (map, free_iterator, NULL));
    GNUNET_CONTAINER_multipeermap_destroy (map);
    map = NULL;
  }
}
Beispiel #28
0
/**
 * Last task run during shutdown.  Disconnects us from
 * the transport and core.
 *
 * @param cls unused, NULL
 */
static void
cleaning_task (void *cls)
{
  if (NULL != peerinfo_notify)
  {
    GNUNET_PEERINFO_notify_cancel (peerinfo_notify);
    peerinfo_notify = NULL;
  }
  if (NULL != handle)
  {
    GNUNET_CORE_disconnect (handle);
    handle = NULL;
  }
  whitelist_peers ();
  if (NULL != add_task)
  {
    GNUNET_SCHEDULER_cancel (add_task);
    add_task = NULL;
  }
  if (NULL != oh)
  {
    GNUNET_TRANSPORT_offer_hello_cancel (oh);
    oh = NULL;
  }
  GNUNET_CONTAINER_multipeermap_iterate (peers,
                                         &free_peer,
                                         NULL);
  GNUNET_CONTAINER_multipeermap_destroy (peers);
  peers = NULL;
  if (NULL != ats)
  {
    GNUNET_ATS_connectivity_done (ats);
    ats = NULL;
  }
  if (NULL != stats)
  {
    GNUNET_STATISTICS_destroy (stats, GNUNET_NO);
    stats = NULL;
  }
}
Beispiel #29
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);
}
static int
testMap (int i)
{
  struct GNUNET_CONTAINER_MultiPeerMap *m;
  struct GNUNET_PeerIdentity k1;
  struct GNUNET_PeerIdentity k2;
  struct GNUNET_CONTAINER_MultiPeerMapIterator *iter;
  struct GNUNET_PeerIdentity key_ret;
  const char *ret;
  int j;

  CHECK (NULL != (m = GNUNET_CONTAINER_multipeermap_create (i, GNUNET_NO)));
  memset (&k1, 0, sizeof (k1));
  memset (&k2, 1, sizeof (k2));
  CHECK (GNUNET_NO == GNUNET_CONTAINER_multipeermap_contains (m, &k1));
  CHECK (GNUNET_NO == GNUNET_CONTAINER_multipeermap_contains (m, &k2));
  CHECK (GNUNET_NO == GNUNET_CONTAINER_multipeermap_remove (m, &k1, NULL));
  CHECK (GNUNET_NO == GNUNET_CONTAINER_multipeermap_remove (m, &k2, NULL));
  CHECK (NULL == GNUNET_CONTAINER_multipeermap_get (m, &k1));
  CHECK (NULL == GNUNET_CONTAINER_multipeermap_get (m, &k2));
  CHECK (0 == GNUNET_CONTAINER_multipeermap_remove_all (m, &k1));
  CHECK (0 == GNUNET_CONTAINER_multipeermap_size (m));
  CHECK (0 == GNUNET_CONTAINER_multipeermap_iterate (m, NULL, NULL));
  CHECK (0 == GNUNET_CONTAINER_multipeermap_get_multiple (m, &k1, NULL, NULL));

  CHECK (GNUNET_OK ==
         GNUNET_CONTAINER_multipeermap_put (m, &k1, "v1",
                                            GNUNET_CONTAINER_MULTIHASHMAPOPTION_REPLACE));
  CHECK (1 == GNUNET_CONTAINER_multipeermap_size (m));
  ret = GNUNET_CONTAINER_multipeermap_get (m, &k1);
  GNUNET_assert (ret != NULL);
  CHECK (0 == strcmp ("v1", ret));
  CHECK (GNUNET_NO ==
         GNUNET_CONTAINER_multipeermap_put (m, &k1, "v1",
                                            GNUNET_CONTAINER_MULTIHASHMAPOPTION_REPLACE));
  CHECK (1 == GNUNET_CONTAINER_multipeermap_size (m));
  CHECK (GNUNET_OK ==
         GNUNET_CONTAINER_multipeermap_put (m, &k1, "v2",
                                            GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE));
  CHECK (GNUNET_OK ==
         GNUNET_CONTAINER_multipeermap_put (m, &k1, "v3",
                                            GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE));
  CHECK (3 == GNUNET_CONTAINER_multipeermap_size (m));
  CHECK (GNUNET_OK == GNUNET_CONTAINER_multipeermap_remove (m, &k1, "v3"));
  CHECK (2 == GNUNET_CONTAINER_multipeermap_size (m));
  CHECK (GNUNET_YES == GNUNET_CONTAINER_multipeermap_contains (m, &k1));
  CHECK (GNUNET_NO == GNUNET_CONTAINER_multipeermap_contains (m, &k2));
  CHECK (2 == GNUNET_CONTAINER_multipeermap_get_multiple (m, &k1, NULL, NULL));
  CHECK (0 == GNUNET_CONTAINER_multipeermap_get_multiple (m, &k2, NULL, NULL));
  CHECK (2 == GNUNET_CONTAINER_multipeermap_iterate (m, NULL, NULL));
  iter = GNUNET_CONTAINER_multipeermap_iterator_create (m);
  CHECK (GNUNET_YES == GNUNET_CONTAINER_multipeermap_iterator_next (iter, &key_ret, (const void **)&ret));
  CHECK (0 == memcmp (&key_ret, &k1, sizeof (key_ret)));
  CHECK (GNUNET_YES == GNUNET_CONTAINER_multipeermap_iterator_next (iter, &key_ret, (const void **)&ret));
  CHECK (0 == memcmp (&key_ret, &k1, sizeof (key_ret)));
  CHECK (GNUNET_NO == GNUNET_CONTAINER_multipeermap_iterator_next (iter, NULL, NULL));
  GNUNET_free (iter);

  CHECK (2 == GNUNET_CONTAINER_multipeermap_remove_all (m, &k1));
  for (j = 0; j < 1024; j++)
    CHECK (GNUNET_OK ==
           GNUNET_CONTAINER_multipeermap_put (m, &k1, "v2",
                                              GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE));
  iter = GNUNET_CONTAINER_multipeermap_iterator_create (m);
  for (j = 0; j < GNUNET_CONTAINER_multipeermap_size (m); j++)
    CHECK (GNUNET_YES == GNUNET_CONTAINER_multipeermap_iterator_next (iter, NULL, NULL));
  CHECK (GNUNET_NO == GNUNET_CONTAINER_multipeermap_iterator_next (iter, NULL, NULL));
  GNUNET_free (iter);

  GNUNET_CONTAINER_multipeermap_destroy (m);
  return 0;
}