struct AddressWrapper *tail;
};
+/**
+ * Address information stored in the solver
+ */
+struct AddressSolverInformation
+{
+ struct Network *network;
+
+ /**
+ * Inbound quota
+ *
+ */
+ unsigned long long calculated_quota_in_NBO;
+
+ /**
+ * Outbound quota
+ *
+ */
+ unsigned long long calculated_quota_out_NBO;
+
+
+};
+
/**
* Wrapper for addresses to store them in network's linked list
*/
next = cur->next;
GNUNET_CONTAINER_DLL_remove(s->network_entries[c].head,
s->network_entries[c].tail, cur);
+ GNUNET_free_non_null (cur->addr->solver_information);
GNUNET_free(cur);
}
GNUNET_free(s->network_entries[c].stat_total);
* this address
*/
static void
-distribute_bandwidth_in_network (struct GAS_PROPORTIONAL_Handle *s,
+distribute_bandwidth (struct GAS_PROPORTIONAL_Handle *s,
struct Network *net, struct ATS_Address *address_except)
{
+ struct AddressSolverInformation *asi;
+ struct AddressWrapper *cur;
+
unsigned long long remaining_quota_in = 0;
unsigned long long quota_out_used = 0;
-
unsigned long long remaining_quota_out = 0;
unsigned long long quota_in_used = 0;
uint32_t min_bw = ntohl (GNUNET_CONSTANTS_DEFAULT_BW_IN_OUT.value__);
double cur_pref; /* Important: has to be double not float due to precision */
const double *t = NULL; /* Important: has to be double not float due to precision */
int c;
-
unsigned long long assigned_quota_in = 0;
unsigned long long assigned_quota_out = 0;
- struct AddressWrapper *cur;
- if (GNUNET_YES == s->bulk_lock)
- {
- s->bulk_requests++;
- return;
- }
LOG(GNUNET_ERROR_TYPE_DEBUG,
"Recalculate quota for network type `%s' for %u addresses (in/out): %llu/%llu \n",
assigned_quota_out = UINT32_MAX;
/* Compare to current bandwidth assigned */
- if ((assigned_quota_in != ntohl (cur->addr->assigned_bw_in.value__))
- || (assigned_quota_out != ntohl (cur->addr->assigned_bw_out.value__)))
- {
- cur->addr->assigned_bw_in.value__ = htonl (assigned_quota_in);
- cur->addr->assigned_bw_out.value__ = htonl (assigned_quota_out);
- /* Notify on change */
- if ((GNUNET_YES == cur->addr->active) && (cur->addr != address_except))
- s->bw_changed (s->bw_changed_cls, cur->addr);
- }
-
+ asi = cur->addr->solver_information;
+ asi->calculated_quota_in_NBO = htonl (assigned_quota_in);
+ asi->calculated_quota_out_NBO = htonl (assigned_quota_out);
}
LOG(GNUNET_ERROR_TYPE_DEBUG,
"Total bandwidth assigned is (in/out): %llu /%llu\n", quota_in_used,
struct FindBestAddressCtx *fba_ctx = (struct FindBestAddressCtx *) cls;
struct ATS_Address *current = (struct ATS_Address *) value;
struct GNUNET_TIME_Absolute now;
- struct Network *net = (struct Network *) current->solver_information;
+ struct AddressSolverInformation *asi;
const double *norm_prop_cur;
const double *norm_prop_prev;
int index;
+ asi = current->solver_information;
now = GNUNET_TIME_absolute_get ();
if (current->blocked_until.abs_value_us
GNUNET_STRINGS_relative_time_to_string (GNUNET_TIME_absolute_get_difference (now, current->blocked_until), GNUNET_YES));
return GNUNET_OK;
}
- if (GNUNET_NO == is_bandwidth_available_in_network (net))
+ if (GNUNET_NO == is_bandwidth_available_in_network (asi->network))
return GNUNET_OK; /* There's no bandwidth available in this network */
if (NULL != fba_ctx->best)
{
* Helper functions
* ---------------------------
*/
+static void
+propagate_bandwidth (struct GAS_PROPORTIONAL_Handle *s,
+ struct Network *net, struct ATS_Address *address_except)
+{
+ struct AddressWrapper *cur;
+ struct AddressSolverInformation *asi;
+ for (cur = net->head; NULL != cur; cur = cur->next)
+ {
+ asi = cur->addr->solver_information;
+ if ( (cur->addr->assigned_bw_in.value__ != asi->calculated_quota_in_NBO) ||
+ (cur->addr->assigned_bw_out.value__ != asi->calculated_quota_out_NBO) )
+ {
+ cur->addr->assigned_bw_in.value__ = asi->calculated_quota_in_NBO;
+ cur->addr->assigned_bw_out.value__ = asi->calculated_quota_in_NBO;
+ /* Notify on change */
+ if ((GNUNET_YES == cur->addr->active) && (cur->addr != address_except))
+ s->bw_changed (s->bw_changed_cls, cur->addr);
+ }
+ }
+}
/**
- * Update bandwidth assignment for all networks
+ * Distribibute bandwidth
*
* @param s the solver handle
+ * @param n the network, can be NULL for all network
+ * @param address_except do not notify for this address
*/
static void
-distribute_bandwidth_in_all_networks (struct GAS_PROPORTIONAL_Handle *s)
+distribute_bandwidth_in_network (struct GAS_PROPORTIONAL_Handle *s,
+ struct Network *n, struct ATS_Address *address_except)
{
- int i;
- for (i = 0; i < s->network_count; i++)
- distribute_bandwidth_in_network (s, &s->network_entries[i], NULL );
+ if (GNUNET_YES == s->bulk_lock)
+ {
+ s->bulk_requests++;
+ return;
+ }
+
+ if (NULL != n)
+ {
+ if (NULL != s->env->info_cb)
+ s->env->info_cb(s->env->info_cb_cls, GAS_OP_SOLVE_START,
+ GAS_STAT_SUCCESS, GAS_INFO_PROP_SINGLE);
+ distribute_bandwidth(s, n, address_except);
+ if (NULL != s->env->info_cb)
+ s->env->info_cb(s->env->info_cb_cls, GAS_OP_SOLVE_STOP,
+ GAS_STAT_SUCCESS, GAS_INFO_PROP_SINGLE);
+ if (NULL != s->env->info_cb)
+ s->env->info_cb(s->env->info_cb_cls, GAS_OP_SOLVE_UPDATE_NOTIFICATION_START,
+ GAS_STAT_SUCCESS, GAS_INFO_PROP_SINGLE);
+ propagate_bandwidth(s, n, address_except);
+ if (NULL != s->env->info_cb)
+ s->env->info_cb(s->env->info_cb_cls, GAS_OP_SOLVE_UPDATE_NOTIFICATION_STOP,
+ GAS_STAT_SUCCESS, GAS_INFO_PROP_SINGLE);
+ }
+ else
+ {
+ int i;
+ if (NULL != s->env->info_cb)
+ s->env->info_cb(s->env->info_cb_cls, GAS_OP_SOLVE_START,
+ GAS_STAT_SUCCESS, GAS_INFO_PROP_ALL);
+ for (i = 0; i < s->network_count; i++)
+ distribute_bandwidth(s, &s->network_entries[i], NULL);
+ if (NULL != s->env->info_cb)
+ s->env->info_cb(s->env->info_cb_cls, GAS_OP_SOLVE_STOP,
+ GAS_STAT_SUCCESS, GAS_INFO_PROP_ALL);
+ for (i = 0; i < s->network_count; i++)
+ {
+ if (NULL != s->env->info_cb)
+ s->env->info_cb(s->env->info_cb_cls, GAS_OP_SOLVE_UPDATE_NOTIFICATION_START,
+ GAS_STAT_SUCCESS, GAS_INFO_PROP_ALL);
+ propagate_bandwidth(s, &s->network_entries[i], address_except);
+ if (NULL != s->env->info_cb)
+ s->env->info_cb(s->env->info_cb_cls, GAS_OP_SOLVE_UPDATE_NOTIFICATION_STOP,
+ GAS_STAT_SUCCESS, GAS_INFO_PROP_ALL);
+ }
+ }
}
/**
GNUNET_assert(NULL != solver);
GNUNET_assert(NULL != peer);
- distribute_bandwidth_in_all_networks (s);
+ distribute_bandwidth_in_network (s, NULL, NULL);
}
struct Network *net_cur;
struct ATS_Address *prev;
struct FindBestAddressCtx fba_ctx;
+ struct AddressSolverInformation *asi;
+ struct AddressSolverInformation *asi_prev;
GNUNET_assert(s != NULL);
GNUNET_assert(peer != NULL);
LOG(GNUNET_ERROR_TYPE_INFO, "Suggesting %s address %p for peer `%s'\n",
(GNUNET_NO == fba_ctx.best->active) ? "inactive" : "active", fba_ctx.best,
GNUNET_i2s (peer));
- net_cur = (struct Network *) fba_ctx.best->solver_information;
+ asi = fba_ctx.best->solver_information;
+ net_cur = asi->network ;
if (NULL == fba_ctx.best)
{
LOG(GNUNET_ERROR_TYPE_ERROR,
* - update quota for previous address network
* - update quota for this address network
*/
- prev = get_active_address (s,
- s->addresses, peer);
+ prev = get_active_address (s, s->addresses, peer);
if (NULL != prev)
{
- net_prev = (struct Network *) prev->solver_information;
+ asi_prev = prev->solver_information;
+ net_prev = (struct Network *) asi_prev->network;
prev->active = GNUNET_NO; /* No active any longer */
prev->assigned_bw_in = BANDWIDTH_ZERO; /* no bandwidth assigned */
prev->assigned_bw_out = BANDWIDTH_ZERO; /* no bandwidth assigned */
if (GNUNET_SYSERR == addresse_decrement (s, net_prev, GNUNET_NO, GNUNET_YES))
GNUNET_break(0);
- distribute_bandwidth_in_network (s, net_prev, NULL );
+ distribute_bandwidth_in_network (s, net_prev, NULL);
}
- if (GNUNET_NO == (is_bandwidth_available_in_network (fba_ctx.best->solver_information)))
+ if (GNUNET_NO == (is_bandwidth_available_in_network (net_cur)))
{
GNUNET_break(0); /* This should never happen*/
return NULL ;
fba_ctx.best->active = GNUNET_YES;
addresse_increment (s, net_cur, GNUNET_NO, GNUNET_YES);
- distribute_bandwidth_in_network (s, net_cur, fba_ctx.best );
+ distribute_bandwidth_in_network (s, net_cur, fba_ctx.best);
return fba_ctx.best;
}
{
struct GAS_PROPORTIONAL_Handle *s = solver;
struct ATS_Address *cur;
+ struct AddressSolverInformation *asi;
struct Network *cur_net;
if (GNUNET_YES
if (NULL != cur)
{
/* Disabling current address */
- cur_net = (struct Network *) cur->solver_information;
+ asi = cur->solver_information;
+ cur_net = asi->network ;
cur->active = GNUNET_NO; /* No active any longer */
cur->assigned_bw_in = BANDWIDTH_ZERO; /* no bandwidth assigned */
cur->assigned_bw_out = BANDWIDTH_ZERO; /* no bandwidth assigned */
struct GAS_PROPORTIONAL_Handle *s = solver;
struct Network *net;
struct AddressWrapper *aw;
+ struct AddressSolverInformation *asi;
const struct ATS_Address *new_address;
* - decrease number of active addreses
* - update quotas
*/
-
- net = (struct Network *) address->solver_information;
+ asi = address->solver_information;
+ net = asi->network;
if (GNUNET_NO == session_only)
{
return;
}
GNUNET_CONTAINER_DLL_remove(net->head, net->tail, aw);
+ GNUNET_free_non_null (aw->addr->solver_information);
GNUNET_free(aw);
}
else
if (GNUNET_SYSERR == addresse_decrement (s, net, GNUNET_NO, GNUNET_YES))
GNUNET_break(0);
- distribute_bandwidth_in_network (s, net, NULL );
+ distribute_bandwidth_in_network (s, net, NULL);
if (NULL == (new_address = GAS_proportional_get_preferred_address (s, &address->peer)))
{
/* No alternative address found, disconnect peer */
s->bw_changed (s->bw_changed_cls, (struct ATS_Address *) new_address);
}
}
- LOG(GNUNET_ERROR_TYPE_DEBUG,
+ LOG(GNUNET_ERROR_TYPE_INFO,
"After deleting address now total %u and active %u addresses in network `%s'\n",
net->total_addresses, net->active_addresses, net->desc);
if ((0 == s->bulk_lock) && (0 < s->bulk_requests))
{
LOG(GNUNET_ERROR_TYPE_DEBUG, "No lock pending, recalculating\n");
- distribute_bandwidth_in_all_networks (s);
+ distribute_bandwidth_in_network (s, NULL, NULL);
s->bulk_requests = 0;
}
}
{
struct GAS_PROPORTIONAL_Handle *s;
struct Network *n;
+ struct AddressSolverInformation *asi;
GNUNET_assert(NULL != solver);
GNUNET_assert(NULL != address);
s = (struct GAS_PROPORTIONAL_Handle *) solver;
- n = (struct Network *) address->solver_information;
+ asi = address->solver_information;
+ n = asi->network;
if (NULL == n)
{
case GNUNET_ATS_COST_WAN:
case GNUNET_ATS_COST_LAN:
case GNUNET_ATS_COST_WLAN:
- distribute_bandwidth_in_network (s, n, GNUNET_NO);
+ distribute_bandwidth_in_network (s, n, NULL);
break;
}
}
struct ATS_Address *address, uint32_t current_network, uint32_t new_network)
{
struct GAS_PROPORTIONAL_Handle *s = (struct GAS_PROPORTIONAL_Handle *) solver;
+ struct AddressSolverInformation *asi;
int save_active = GNUNET_NO;
+
struct Network *new_net = NULL;
if (current_network == new_network)
}
/* Add to new network and update*/
- address->solver_information = new_net;
+ asi = address->solver_information;
+ asi->network = new_net;
GAS_proportional_address_add (solver, address, new_network);
if (GNUNET_YES == save_active)
{
/* Assign bandwidth to updated address */
address->active = GNUNET_YES;
addresse_increment (s, new_net, GNUNET_NO, GNUNET_YES);
- distribute_bandwidth_in_network (solver, new_net, NULL );
+ distribute_bandwidth_in_network (solver, new_net, NULL);
}
else
{
struct GAS_PROPORTIONAL_Handle *s = solver;
struct Network *net = NULL;
struct AddressWrapper *aw = NULL;
+ struct AddressSolverInformation *asi;
GNUNET_assert(NULL != s);
-
net = get_network (s, network);
if (NULL == net)
{
aw->addr = address;
GNUNET_CONTAINER_DLL_insert(net->head, net->tail, aw);
addresse_increment (s, net, GNUNET_YES, GNUNET_NO);
- aw->addr->solver_information = net;
+
+ asi = GNUNET_malloc (sizeof (struct AddressSolverInformation));
+ asi->network = net;
+ asi->calculated_quota_in_NBO = 0;
+ asi->calculated_quota_out_NBO = 0;
+ aw->addr->solver_information = asi;
if (GNUNET_YES == GNUNET_CONTAINER_multipeermap_contains (s->requests, &address->peer))
{
s->bw_changed (s->bw_changed_cls, (struct ATS_Address *) address);
}
}
- LOG(GNUNET_ERROR_TYPE_DEBUG,
- "After adding address now total %u and active %u addresses in network `%s'\n",
- net->total_addresses, net->active_addresses, net->desc);
+
+ LOG(GNUNET_ERROR_TYPE_INFO,
+ "Adding new address %p for peer `%s', now total %u and active %u addresses in network `%s'\n",
+ address, GNUNET_i2s(&address->peer), net->total_addresses, net->active_addresses, net->desc);
}