*/
#include "platform.h"
#include "gnunet_ats_service.h"
+#include "gnunet_ats_plugin.h"
#include "gnunet-service-ats.h"
#include "gnunet-service-ats_addresses.h"
#include "gnunet-service-ats_normalization.h"
#include "gnunet-service-ats_performance.h"
#include "gnunet-service-ats_scheduling.h"
#include "gnunet-service-ats_reservations.h"
+
+#if 0
#if HAVE_LIBGLPK
#include "gnunet-service-ats-solver_mlp.h"
#endif
#include "gnunet-service-ats-solver_proportional.h"
#include "gnunet-service-ats-solver_ril.h"
+#endif
/**
* NOTE: Do not change this documentation. This documentation is based on
struct GAS_Addresses_Suggestion_Requests *r_tail;
/* Solver functions */
+ struct GNUNET_ATS_PluginEnvironment env;
- /**
- * Initialize solver
- */
- GAS_solver_init s_init;
-
- /**
- * Add an address to the solver
- */
- GAS_solver_address_add s_add;
-
- GAS_solver_address_property_changed s_address_update_property;
-
- GAS_solver_address_session_changed s_address_update_session;
-
- GAS_solver_address_inuse_changed s_address_update_inuse;
-
- GAS_solver_address_network_changed s_address_update_network;
-
- /**
- * Get address from solver
- */
- GAS_solver_get_preferred_address s_get;
-
- /**
- * Get address from solver
- */
- GAS_solver_stop_get_preferred_address s_get_stop;
-
- /**
- * Delete address in solver
- */
- GAS_solver_address_delete s_del;
-
- /**
- * Change relative preference for quality in solver
- */
- GAS_solver_address_change_preference s_pref;
-
- /**
- * Give feedback about the current assignment
- */
- GAS_solver_address_feedback_preference s_feedback;
-
- /**
- * Start a bulk operation
- */
- GAS_solver_bulk_start s_bulk_start;
-
- /**
- * Bulk operation done
- */
- GAS_solver_bulk_stop s_bulk_stop;
-
- /**
- * Shutdown solver
- */
- GAS_solver_done s_done;
+ char *plugin;
};
/**
* @return #GNUNET_YES to continue, #GNUNET_NO if address is founce
*/
static int
-compare_address_it (void *cls,
- const struct GNUNET_PeerIdentity *key,
+compare_address_it (void *cls,
+ const struct GNUNET_PeerIdentity *key,
void *value)
{
struct CompareAddressContext *cac = cls;
cac.base_address = NULL;
cac.search = addr;
GNUNET_CONTAINER_multipeermap_get_multiple (handle->addresses,
- peer,
+ peer,
&compare_address_it, &cac);
if (cac.exact_address == NULL)
GNUNET_ATS_print_network_type (addr_net));
/* Tell solver about new address */
- handle->s_add (handle->solver, new_address, addr_net);
+ handle->env.sf.s_add (handle->solver, new_address, addr_net);
- handle->s_bulk_start (handle->solver);
+ handle->env.sf.s_bulk_start (handle->solver);
GAS_normalization_normalize_property (handle->addresses, new_address, atsi,
atsi_count);
- handle->s_bulk_stop (handle->solver);
+ handle->env.sf.s_bulk_stop (handle->solver);
/* Notify performance clients about new address */
GAS_performance_notify_all_clients (&new_address->peer, new_address->plugin,
GNUNET_i2s (peer), existing_address,
GNUNET_ATS_print_network_type (addr_net),
GNUNET_ATS_print_network_type (ntohl (atsi_delta[c1].value)));
- handle->s_address_update_network (handle->solver, existing_address,
+ handle->env.sf.s_address_update_network (handle->solver, existing_address,
ntohl (atsi_delta[c1].value),
get_performance_info (existing_address, GNUNET_ATS_NETWORK_TYPE));
addr_net = get_performance_info (existing_address,
}
}
/* Notify solver about update with atsi information and session */
- handle->s_bulk_start (handle->solver);
+ handle->env.sf.s_bulk_start (handle->solver);
GAS_normalization_normalize_property (handle->addresses, existing_address,
atsi, atsi_count);
- handle->s_bulk_stop (handle->solver);
+ handle->env.sf.s_bulk_stop (handle->solver);
}
GNUNET_free_non_null(atsi_delta);
previous_session = existing_address->session_id;
existing_address->session_id = session_id;
- handle->s_address_update_session (handle->solver, existing_address,
+ handle->env.sf.s_address_update_session (handle->solver, existing_address,
previous_session, session_id);
GNUNET_log(GNUNET_ERROR_TYPE_INFO,
/* Session changed */
prev_session = aa->session_id;
aa->session_id = session_id;
- handle->s_address_update_session (handle->solver, aa, prev_session,
+ handle->env.sf.s_address_update_session (handle->solver, aa, prev_session,
aa->session_id);
}
if (GNUNET_ATS_NETWORK_TYPE == ntohl (atsi_delta[c1].type))
{
/* Network type changed */
- handle->s_address_update_network (handle->solver, aa,
+ handle->env.sf.s_address_update_network (handle->solver, aa,
ntohl (atsi_delta[c1].value),
get_performance_info (aa, GNUNET_ATS_NETWORK_TYPE));
}
aa->addr_len, aa->session_id, aa->atsi, aa->atsi_count,
aa->assigned_bw_out, aa->assigned_bw_in);
- handle->s_bulk_start (handle->solver);
+ handle->env.sf.s_bulk_start (handle->solver);
GAS_normalization_normalize_property (handle->addresses, aa, atsi,
atsi_count);
- handle->s_bulk_stop (handle->solver);
+ handle->env.sf.s_bulk_stop (handle->solver);
}
GNUNET_free_non_null(atsi_delta);
}
GNUNET_YES == GNUNET_CONTAINER_multipeermap_remove (handle->addresses,
&aa->peer,
aa));
- handle->s_del (handle->solver, aa, GNUNET_NO);
+ handle->env.sf.s_del (handle->solver, aa, GNUNET_NO);
free_address (aa);
dc->result = GNUNET_NO;
return GNUNET_OK; /* Continue iteration */
/* Notify solver about deletion */
GNUNET_assert(
- GNUNET_YES == GNUNET_CONTAINER_multipeermap_remove (handle->addresses,
+ GNUNET_YES == GNUNET_CONTAINER_multipeermap_remove (handle->addresses,
&aa->peer, aa));
- handle->s_del (handle->solver, aa, GNUNET_NO);
+ handle->env.sf.s_del (handle->solver, aa, GNUNET_NO);
free_address (aa);
dc->result = GNUNET_NO;
return GNUNET_OK; /* Continue iteration */
"Deleting session for peer `%s': `%s' %u\n", GNUNET_i2s (&aa->peer),
aa->plugin, aa->session_id);
/* Notify solver to delete session */
- handle->s_del (handle->solver, aa, GNUNET_YES);
+ handle->env.sf.s_del (handle->solver, aa, GNUNET_YES);
aa->session_id = 0;
aa->active = GNUNET_NO;
return GNUNET_OK;
/* Tell solver about update */
ea->used = in_use;
- handle->s_address_update_inuse (handle->solver, ea, ea->used);
+ handle->env.sf.s_address_update_inuse (handle->solver, ea, ea->used);
return GNUNET_OK;
}
GNUNET_i2s (peer));
return;
}
- handle->s_get_stop (handle->solver, peer);
+ handle->env.sf.s_get_stop (handle->solver, peer);
GAS_addresses_handle_backoff_reset (handle, peer);
GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Removed request pending for peer `%s\n",
GNUNET_i2s (peer));
*/
/* Get prefered address from solver */
- aa = (struct ATS_Address *) handle->s_get (handle->solver, peer);
+ aa = (struct ATS_Address *) handle->env.sf.s_get (handle->solver, peer);
if (NULL == aa)
{
GNUNET_log(GNUNET_ERROR_TYPE_INFO, "Cannot suggest address for peer `%s'\n",
* @return #GNUNET_OK to continue
*/
static int
-reset_address_it (void *cls,
- const struct GNUNET_PeerIdentity *key,
+reset_address_it (void *cls,
+ const struct GNUNET_PeerIdentity *key,
void *value)
{
struct ATS_Address *aa = value;
GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
"Resetting interval for peer `%s' address %p from %llu to 0\n",
- GNUNET_i2s (&aa->peer),
- aa,
+ GNUNET_i2s (&aa->peer),
+ aa,
aa->block_interval);
aa->blocked_until = GNUNET_TIME_UNIT_ZERO_ABS;
aa->block_interval = GNUNET_TIME_UNIT_ZERO;
struct GAS_Addresses_Handle *handle = cls;
/* Tell solver about update */
- handle->s_pref (handle->solver, peer, kind, pref_rel);
+ handle->env.sf.s_pref (handle->solver, peer, kind, pref_rel);
}
/**
GNUNET_ATS_print_property_type (type), GNUNET_i2s (&address->peer),
prop_rel);
- ah->s_address_update_property (ah->solver, address, type, 0, prop_rel);
+ ah->env.sf.s_address_update_property (ah->solver, address, type, 0, prop_rel);
}
/**
return;
}
- handle->s_bulk_start (handle->solver);
+ handle->env.sf.s_bulk_start (handle->solver);
/* Tell normalization about change, normalization will call callback if preference changed */
GAS_normalization_normalize_preference (client, peer, kind, score_abs);
- handle->s_bulk_stop (handle->solver);
+ handle->env.sf.s_bulk_stop (handle->solver);
}
/**
return;
}
- handle->s_feedback (handle->solver, application, peer, scope, kind,
+ handle->env.sf.s_feedback (handle->solver, application, peer, scope, kind,
score_abs);
}
const struct GNUNET_STATISTICS_Handle *stats)
{
struct GAS_Addresses_Handle *ah;
- int quotas[GNUNET_ATS_NetworkTypeCount] = GNUNET_ATS_NetworkType;
unsigned long long quotas_in[GNUNET_ATS_NetworkTypeCount];
unsigned long long quotas_out[GNUNET_ATS_NetworkTypeCount];
- int quota_count;
char *mode_str;
+ char *plugin_short;
int c;
ah = GNUNET_malloc (sizeof (struct GAS_Addresses_Handle));
if (0 == strcmp (mode_str, "PROPORTIONAL"))
{
ah->ats_mode = MODE_PROPORTIONAL;
+ plugin_short = "proportional";
}
else if (0 == strcmp (mode_str, "MLP"))
{
ah->ats_mode = MODE_MLP;
+ plugin_short = "mlp";
#if !HAVE_LIBGLPK
GNUNET_log(GNUNET_ERROR_TYPE_ERROR,
"Assignment method `%s' configured, but GLPK is not available, please install \n",
mode_str);
ah->ats_mode = MODE_PROPORTIONAL;
+ plugin_short = "proportional";
#endif
}
else if (0 == strcmp (mode_str, "RIL"))
{
ah->ats_mode = MODE_RIL;
+ plugin_short = "ril";
}
else
{
"Invalid resource assignment method `%s' configured, using proportional approach\n",
mode_str);
ah->ats_mode = MODE_PROPORTIONAL;
+ plugin_short = "proportional";
}
GNUNET_free(mode_str);
}
- /* Start configured solution method */
- switch (ah->ats_mode)
+
+ load_quotas (cfg, quotas_in, quotas_out, GNUNET_ATS_NetworkTypeCount);
+ ah->env.bandwidth_changed_cb = &bandwidth_changed_cb;
+ ah->env.bw_changed_cb_cls = ah;
+ ah->env.get_preferences = &get_preferences_cb;
+ ah->env.get_preference_cls = ah;
+ ah->env.get_property = &get_property_cb;
+ ah->env.get_property_cls = ah;
+ ah->env.cfg = cfg;
+ ah->env.stats = stats;
+ ah->env.addresses = ah->addresses;
+
+ ah->env.network_count = GNUNET_ATS_NetworkTypeCount;
+ int networks[GNUNET_ATS_NetworkTypeCount] = GNUNET_ATS_NetworkType;
+ for (c = 0; c < GNUNET_ATS_NetworkTypeCount; c++)
{
- case MODE_MLP:
- /* Init the MLP solver with default values */
-#if HAVE_LIBGLPK
- ah->s_init = &GAS_mlp_init;
- ah->s_add = &GAS_mlp_address_add;
- ah->s_address_update_property = &GAS_mlp_address_property_changed;
- ah->s_address_update_session = &GAS_mlp_address_session_changed;
- ah->s_address_update_inuse = &GAS_mlp_address_inuse_changed;
- ah->s_address_update_network = &GAS_mlp_address_change_network;
- ah->s_get = &GAS_mlp_get_preferred_address;
- ah->s_get_stop = &GAS_mlp_stop_get_preferred_address;
- ah->s_pref = &GAS_mlp_address_change_preference;
- ah->s_feedback = &GAS_mlp_address_preference_feedback;
- ah->s_del = &GAS_mlp_address_delete;
- ah->s_bulk_start = &GAS_mlp_bulk_start;
- ah->s_bulk_stop = &GAS_mlp_bulk_stop;
- ah->s_done = &GAS_mlp_done;
-#else
- GNUNET_free(ah);
- return NULL ;
-#endif
- break;
- case MODE_PROPORTIONAL:
- /* Init the proportional solver with default values */
- ah->s_init = &GAS_proportional_init;
- ah->s_add = &GAS_proportional_address_add;
- ah->s_address_update_property = &GAS_proportional_address_property_changed;
- ah->s_address_update_session = &GAS_proportional_address_session_changed;
- ah->s_address_update_inuse = &GAS_proportional_address_inuse_changed;
- ah->s_address_update_network = &GAS_proportional_address_change_network;
- ah->s_get = &GAS_proportional_get_preferred_address;
- ah->s_get_stop = &GAS_proportional_stop_get_preferred_address;
- ah->s_pref = &GAS_proportional_address_change_preference;
- ah->s_feedback = &GAS_proportional_address_preference_feedback;
- ah->s_del = &GAS_proportional_address_delete;
- ah->s_bulk_start = &GAS_proportional_bulk_start;
- ah->s_bulk_stop = &GAS_proportional_bulk_stop;
- ah->s_done = &GAS_proportional_done;
- GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "ATS started in %s mode\n",
- "PROPORTIONAL");
- break;
- case MODE_RIL:
- /* Init the ril solver with default values */
- ah->s_init = &GAS_ril_init;
- ah->s_add = &GAS_ril_address_add;
- ah->s_address_update_property = &GAS_ril_address_property_changed;
- ah->s_address_update_session = &GAS_ril_address_session_changed;
- ah->s_address_update_inuse = &GAS_ril_address_inuse_changed;
- ah->s_address_update_network = &GAS_ril_address_change_network;
- ah->s_get = &GAS_ril_get_preferred_address;
- ah->s_get_stop = &GAS_ril_stop_get_preferred_address;
- ah->s_pref = &GAS_ril_address_change_preference;
- ah->s_feedback = &GAS_ril_address_preference_feedback;
- ah->s_del = &GAS_ril_address_delete;
- ah->s_bulk_start = &GAS_ril_bulk_start;
- ah->s_bulk_stop = &GAS_ril_bulk_stop;
- ah->s_done = &GAS_ril_done;
- GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "ATS started in %s mode\n", "RIL");
- break;
- default:
- return NULL ;
- break;
+ ah->env.networks[c] = networks[c];
+ ah->env.out_quota[c] = quotas_out[c];
+ ah->env.in_quota[c] = quotas_in[c];
}
- GNUNET_assert (NULL != ah->s_init);
- GNUNET_assert (NULL != ah->s_add);
- GNUNET_assert (NULL != ah->s_address_update_inuse);
- GNUNET_assert (NULL != ah->s_address_update_property);
- GNUNET_assert (NULL != ah->s_address_update_session);
- GNUNET_assert (NULL != ah->s_address_update_network);
- GNUNET_assert (NULL != ah->s_get);
- GNUNET_assert (NULL != ah->s_get_stop);
- GNUNET_assert (NULL != ah->s_pref);
- GNUNET_assert (NULL != ah->s_feedback);
- GNUNET_assert (NULL != ah->s_del);
- GNUNET_assert (NULL != ah->s_done);
- GNUNET_assert (NULL != ah->s_bulk_start);
- GNUNET_assert (NULL != ah->s_bulk_stop);
+ GNUNET_asprintf (&ah->plugin, "libgnunet_plugin_ats_%s", plugin_short);
+ GNUNET_log(GNUNET_ERROR_TYPE_INFO, _("Initializing solver `%s '`%s'\n"), plugin_short, ah->plugin);
+ if (NULL == (ah->solver = GNUNET_PLUGIN_load (ah->plugin, &ah->env)))
+ {
+ GNUNET_log(GNUNET_ERROR_TYPE_ERROR, _("Failed to initialize solver `%s'!\n"), ah->plugin);
+ return NULL;
+ }
+
+ GNUNET_assert (NULL != ah->env.sf.s_add);
+ GNUNET_assert (NULL != ah->env.sf.s_address_update_inuse);
+ GNUNET_assert (NULL != ah->env.sf.s_address_update_property);
+ GNUNET_assert (NULL != ah->env.sf.s_address_update_session);
+ GNUNET_assert (NULL != ah->env.sf.s_address_update_network);
+ GNUNET_assert (NULL != ah->env.sf.s_get);
+ GNUNET_assert (NULL != ah->env.sf.s_get_stop);
+ GNUNET_assert (NULL != ah->env.sf.s_pref);
+ GNUNET_assert (NULL != ah->env.sf.s_feedback);
+ GNUNET_assert (NULL != ah->env.sf.s_del);
+ GNUNET_assert (NULL != ah->env.sf.s_bulk_start);
+ GNUNET_assert (NULL != ah->env.sf.s_bulk_stop);
+
GAS_normalization_start (&normalized_preference_changed_cb, ah,
&normalized_property_changed_cb, ah);
- quota_count = load_quotas (cfg, quotas_in, quotas_out,
- GNUNET_ATS_NetworkTypeCount);
- ah->solver = ah->s_init (cfg, stats, ah->addresses, quotas, quotas_in,
- quotas_out, quota_count,
- &bandwidth_changed_cb, ah, &get_preferences_cb,
- NULL, &get_property_cb, NULL );
if (NULL == ah->solver)
{
GNUNET_log(GNUNET_ERROR_TYPE_ERROR, _("Failed to initialize solver!\n"));
* @return #GNUNET_OK (continue to iterate)
*/
static int
-destroy_all_address_it (void *cls,
+destroy_all_address_it (void *cls,
const struct GNUNET_PeerIdentity *key,
void *value)
{
struct ATS_Address *aa = value;
/* Remove */
- GNUNET_assert(GNUNET_YES ==
+ GNUNET_assert(GNUNET_YES ==
GNUNET_CONTAINER_multipeermap_remove (handle->addresses, key, value));
/* Notify */
- handle->s_del (handle->solver, aa, GNUNET_NO);
+ handle->env.sf.s_del (handle->solver, aa, GNUNET_NO);
/* Destroy */
free_address (aa);
return;
GNUNET_log(GNUNET_ERROR_TYPE_INFO, "Destroying all addresses\n");
- handle->s_bulk_start (handle->solver);
+ handle->env.sf.s_bulk_start (handle->solver);
if (handle->addresses != NULL )
GNUNET_CONTAINER_multipeermap_iterate (handle->addresses,
&destroy_all_address_it,
handle);
- handle->s_bulk_start (handle->solver);
+ handle->env.sf.s_bulk_start (handle->solver);
}
GNUNET_CONTAINER_DLL_remove(handle->r_head, handle->r_tail, cur);
GNUNET_free(cur);
}
- handle->s_done (handle->solver);
+
+ GNUNET_PLUGIN_unload (handle->plugin, handle->solver);
+ GNUNET_free (handle->plugin);
GNUNET_free(handle);
/* Stop configured solution method */
GAS_normalization_stop ();
* @return #GNUNET_OK to continue
*/
static int
-peer_it (void *cls,
+peer_it (void *cls,
const struct GNUNET_PeerIdentity *key,
void *value)
{
ip_ctx.it_cls = p_it_cls;
ip_ctx.peers_returned = GNUNET_CONTAINER_multipeermap_create (size,
GNUNET_NO);
- GNUNET_CONTAINER_multipeermap_iterate (handle->addresses,
+ GNUNET_CONTAINER_multipeermap_iterate (handle->addresses,
&peer_it,
&ip_ctx);
GNUNET_CONTAINER_multipeermap_destroy (ip_ctx.peers_returned);