#define DEBUG_ATS GNUNET_NO
#define VERBOSE_GLPK GNUNET_NO
+#define ENABLE_C8 GNUNET_YES
+#define ENABLE_C9 GNUNET_YES
/**
* Translate glpk solver error codes to text
* @param retcode return code
/* c 10) obey network specific quotas
* (1)*b_1 + ... + (1)*b_m <= quota_n
*/
+
int cur_row = 0;
int c;
for (c = 0; c < GNUNET_ATS_NetworkTypeCount; c++)
mlp_lookup_ats (struct ATS_Address *addr, int ats_index)
{
struct GNUNET_ATS_Information * ats = addr->ats;
- int c;
+ int c = 0;
int found = GNUNET_NO;
for (c = 0; c < addr->ats_count; c++)
{
for (c = 0; c < GNUNET_ATS_NetworkTypeCount; c++)
{
mlp->r_quota[c] = glp_add_rows (mlp->prob, 1);
+ char * text;
+ GNUNET_asprintf(&text, "quota_ats_%i", mlp->quota_index[c]);
+ glp_set_row_name (mlp->prob, mlp->r_quota[c], text);
+ GNUNET_free (text);
/* Set bounds to 0 <= x <= quota_out */
- glp_set_row_bnds (mlp->prob, mlp->r_quota[c], GLP_DB, 0.0, mlp->quota_out[c]);
+ glp_set_row_bnds (mlp->prob, mlp->r_quota[c], GLP_UP, 0.0, mlp->quota_out[c]);
}
GNUNET_CONTAINER_multihashmap_iterate (addresses, create_constraint_it, mlp);
/* Set row bound == 0 */
glp_set_row_bnds (mlp->prob, mlp->r_c8, GLP_FX, 0.0, 0.0);
/* -u */
+
ia[mlp->ci] = mlp->r_c8;
ja[mlp->ci] = mlp->c_u;
ar[mlp->ci] = -1;
glp_set_row_bnds (mlp->prob, peer->r_c2, GLP_FX, 1.0, 1.0);
/* Adding rows for c 9) */
+#if ENABLE_C9
peer->r_c9 = glp_add_rows (mlp->prob, 1);
GNUNET_asprintf(&name, "c9_%s", GNUNET_i2s(&peer->id));
glp_set_row_name (mlp->prob, peer->r_c9, name);
ja[mlp->ci] = mlp->c_r;
ar[mlp->ci] = -1;
mlp->ci++;
+#endif
while (addr != NULL)
{
mlpi = (struct MLP_information *) addr->mlp_information;
/* coefficient for c 2) */
+
ia[mlp->ci] = peer->r_c2;
ja[mlp->ci] = mlpi->c_n;
ar[mlp->ci] = 1;
ar[mlp->ci] = peer->f;
mlp->ci++;
+#if ENABLE_C9
/* coefficient for c 9) */
ia[mlp->ci] = peer->r_c9;
ja[mlp->ci] = mlpi->c_b;
ar[mlp->ci] = 1;
mlp->ci++;
+#endif
addr = addr->next;
}
/* c 7) For all quality metrics */
+
for (c = 0; c < mlp->m_q; c++)
{
- struct ATS_Peer *p = mlp->peer_head;
- struct ATS_Address *addr = p->head;
+ struct ATS_Peer *tp;
+ struct ATS_Address *ta;
struct MLP_information * mlpi;
double value = 1.0;
- while (p != NULL)
- {
- /* Adding rows for c 7) */
- mlp->r_q[c] = glp_add_rows (mlp->prob, 1);
- GNUNET_asprintf(&name, "c7_q%i_atsi_%i", c, mlp->q[c]);
- glp_set_row_name (mlp->prob, mlp->r_q[c], name);
- GNUNET_free (name);
- /* Set row bound == 0 */
- glp_set_row_bnds (mlp->prob, mlp->r_q[c], GLP_LO, 0.0, 0.0);
-
- ia[mlp->ci] = mlp->r_q[c];
- ja[mlp->ci] = mlp->c_q[c];
- ar[mlp->ci] = -1;
- mlp->ci++;
+ /* Adding rows for c 7) */
+ mlp->r_q[c] = glp_add_rows (mlp->prob, 1);
+ GNUNET_asprintf(&name, "c7_q%i_%s", c, mlp_ats_to_string(mlp->q[c]));
+ glp_set_row_name (mlp->prob, mlp->r_q[c], name);
+ GNUNET_free (name);
+ /* Set row bound == 0 */
+ glp_set_row_bnds (mlp->prob, mlp->r_q[c], GLP_LO, 0.0, 0.0);
- while (addr != NULL)
- {
- mlpi = addr->mlp_information;
- /* lookup ATS information */
- int index = mlp_lookup_ats(addr, mlp->q[c]);
+ ia[mlp->ci] = mlp->r_q[c];
+ ja[mlp->ci] = mlp->c_q[c];
+ ar[mlp->ci] = -1;
+ mlp->ci++;
- if (index != GNUNET_SYSERR)
+ for (tp = mlp->peer_head; tp != NULL; tp = tp->next)
+ for (ta = tp->head; ta != NULL; ta = ta->next)
{
- value = (double) addr->ats[index].value;
-
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Quality %i with ATS property `%s' has index %i in addresses ats information has value %f\n", c, mlp_ats_to_string(mlp->q[c]), index, (double) addr->ats[index].value);
- }
- else
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Quality %i with ATS property `%s' not existing\n", c, mlp_ats_to_string(mlp->q[c]), index);
-
- mlpi = addr->mlp_information;
-
- mlpi->r_q[c] = mlp->r_q[c];
- mlpi->c_q[c] = mlpi->c_b;
- mlpi->q[c] = value;
+ mlpi = ta->mlp_information;
+ value = mlpi->q_averaged[c];
- ia[mlp->ci] = mlp->r_q[c];
- ja[mlp->ci] = mlpi->c_b;
- ar[mlp->ci] = p->f * value;
- mlp->ci++;
+ mlpi->r_q[c] = mlp->r_q[c];
- addr = addr->next;
- }
- p = p->next;
- }
+ ia[mlp->ci] = mlp->r_q[c];
+ ja[mlp->ci] = mlpi->c_b;
+ ar[mlp->ci] = tp->f * value;
+ mlp->ci++;
+ }
}
}
mlpi->c_b = col;
mlpi->c_n = col + 1;
+
GNUNET_asprintf (&name, "b_%s_%s", GNUNET_i2s (&address->peer), address->plugin);
glp_set_col_name (mlp->prob, mlpi->c_b , name);
GNUNET_free (name);
/* Column lower bound = 0.0 */
glp_set_col_bnds (mlp->prob, col, GLP_LO, 0.0, 0.0);
+#if ENABLE_C9
/* Relativity r column */
col = glp_add_cols (mlp->prob, 1);
mlp->c_r = col;
glp_set_obj_coef (mlp->prob, col, mlp->co_R);
/* Column lower bound = 0.0 */
glp_set_col_bnds (mlp->prob, col, GLP_LO, 0.0, 0.0);
+#endif
/* Quality metric columns */
col = glp_add_cols(mlp->prob, mlp->m_q);
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "\tAddress %s %f\n",
(n == 1.0) ? "[x]" : "[ ]", b);
}
-
}
if (mlp->mlp_task != GNUNET_SCHEDULER_NO_TASK)
unsigned int b_min;
unsigned int n_min;
struct GNUNET_TIME_Relative i_exec;
+ int c;
+ char * quota_out_str;
+ char * quota_in_str;
/* Init GLPK environment */
GNUNET_assert (glp_init_env() == 0);
mlp->prob = glp_create_prob();
GNUNET_assert (mlp->prob != NULL);
+ mlp->BIG_M = (double) BIG_M_VALUE;
+
/* Get diversity coefficient from configuration */
if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_size (cfg, "ats",
"COEFFICIENT_D",
else
U = 1.0;
- /* Init network quotas */
- int quotas[GNUNET_ATS_NetworkTypeCount] = GNUNET_ATS_NetworkType;
- int c;
-
- for (c = 0; c < GNUNET_ATS_NetworkTypeCount; c++)
- {
- mlp->quota_index[c] = quotas[c];
- static char * entry_in = NULL;
- static char * entry_out = NULL;
- unsigned long long quota_in = 0;
- unsigned long long quota_out = 0;
-
- switch (quotas[c]) {
- case GNUNET_ATS_NET_UNSPECIFIED:
- entry_out = "UNSPECIFIED_QUOTA_OUT";
- entry_in = "UNSPECIFIED_QUOTA_IN";
- break;
- case GNUNET_ATS_NET_LOOPBACK:
- entry_out = "LOOPBACK_QUOTA_OUT";
- entry_in = "LOOPBACK_QUOTA_IN";
- break;
- case GNUNET_ATS_NET_LAN:
- entry_out = "LAN_QUOTA_OUT";
- entry_in = "LAN_QUOTA_IN";
- break;
- case GNUNET_ATS_NET_WAN:
- entry_out = "WAN_QUOTA_OUT";
- entry_in = "WAN_QUOTA_IN";
- break;
- case GNUNET_ATS_NET_WLAN:
- entry_out = "WLAN_QUOTA_OUT";
- entry_in = "WLAN_QUOTA_IN";
- break;
- default:
- break;
- }
-
- if ((entry_in == NULL) || (entry_out == NULL))
- continue;
-
- if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_size (cfg, "ats", entry_out, "a_out))
- {
- quota_out = UINT32_MAX;
- }
- if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_size (cfg, "ats", entry_in, "a_in))
- {
- quota_in = UINT32_MAX;
- }
-
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Found `%s' quota %llu and `%s' quota %llu\n",
- entry_out, quota_out, entry_in, quota_in);
- mlp->quota_out[c] = quota_out;
- mlp->quota_in[c] = quota_in;
- }
-
/* Get quality metric coefficients from configuration */
int i_delay = -1;
int i_distance = -1;
else
n_min = 4;
+ /* Init network quotas */
+ int quotas[GNUNET_ATS_NetworkTypeCount] = GNUNET_ATS_NetworkType;
+ for (c = 0; c < GNUNET_ATS_NetworkTypeCount; c++)
+ {
+ mlp->quota_index[c] = quotas[c];
+ static char * entry_in = NULL;
+ static char * entry_out = NULL;
+ unsigned long long quota_in = 0;
+ unsigned long long quota_out = 0;
+
+ switch (quotas[c]) {
+ case GNUNET_ATS_NET_UNSPECIFIED:
+ entry_out = "UNSPECIFIED_QUOTA_OUT";
+ entry_in = "UNSPECIFIED_QUOTA_IN";
+ break;
+ case GNUNET_ATS_NET_LOOPBACK:
+ entry_out = "LOOPBACK_QUOTA_OUT";
+ entry_in = "LOOPBACK_QUOTA_IN";
+ break;
+ case GNUNET_ATS_NET_LAN:
+ entry_out = "LAN_QUOTA_OUT";
+ entry_in = "LAN_QUOTA_IN";
+ break;
+ case GNUNET_ATS_NET_WAN:
+ entry_out = "WAN_QUOTA_OUT";
+ entry_in = "WAN_QUOTA_IN";
+ break;
+ case GNUNET_ATS_NET_WLAN:
+ entry_out = "WLAN_QUOTA_OUT";
+ entry_in = "WLAN_QUOTA_IN";
+ break;
+ default:
+ break;
+ }
+
+ if ((entry_in == NULL) || (entry_out == NULL))
+ continue;
+
+ if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_string(cfg, "ats", entry_out, "a_out_str))
+ {
+ if (0 == strcmp(quota_out_str, BIG_M_STRING) ||
+ (GNUNET_SYSERR == GNUNET_STRINGS_fancy_size_to_bytes (quota_out_str, "a_out)))
+ quota_out = mlp->BIG_M;
+
+ GNUNET_free (quota_out_str);
+ quota_out_str = NULL;
+ }
+ else if (GNUNET_ATS_NET_UNSPECIFIED == quotas[c])
+ {
+ quota_out = 0;
+ }
+ else
+ {
+ quota_out = mlp->BIG_M;
+ }
+
+ if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_string(cfg, "ats", entry_in, "a_in_str))
+ {
+ if (0 == strcmp(quota_in_str, BIG_M_STRING) ||
+ (GNUNET_SYSERR == GNUNET_STRINGS_fancy_size_to_bytes (quota_in_str, "a_in)))
+ quota_in = mlp->BIG_M;
+
+ GNUNET_free (quota_in_str);
+ quota_in_str = NULL;
+ }
+ else if (GNUNET_ATS_NET_UNSPECIFIED == quotas[c])
+ {
+ quota_in = 0;
+ }
+ else
+ {
+ quota_in = mlp->BIG_M;
+ }
+
+ /* Check if defined quota could make problem unsolvable */
+ if (((n_min * b_min) > quota_out) && (GNUNET_ATS_NET_UNSPECIFIED != quotas[c]))
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Inconsistent quota configuration value `%s': " \
+ "outbound quota (%u Bps) too small for combination of minimum connections and minimum bandwidth per peer (%u * %u Bps = %u)\n", entry_out, quota_out, n_min, b_min, n_min * b_min);
+
+ GAS_mlp_done(mlp);
+ mlp = NULL;
+ return NULL;
+ }
+
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Found `%s' quota %llu and `%s' quota %llu\n",
+ entry_out, quota_out, entry_in, quota_in);
+ GNUNET_STATISTICS_update ((struct GNUNET_STATISTICS_Handle *) stats, entry_out, quota_out, GNUNET_NO);
+ GNUNET_STATISTICS_update ((struct GNUNET_STATISTICS_Handle *) stats, entry_in, quota_in, GNUNET_NO);
+ mlp->quota_out[c] = quota_out;
+ mlp->quota_in[c] = quota_in;
+ }
+
/* Get minimum number of connections from configuration */
if (GNUNET_OK == GNUNET_CONFIGURATION_get_value_time (cfg, "ats",
"ATS_EXEC_INTERVAL",
mlp->last_execution = GNUNET_TIME_absolute_get_forever();
-
- mlp->BIG_M = (double) UINT32_MAX;
mlp->co_D = D;
mlp->co_R = R;
mlp->co_U = U;
return mlp;
}
+static void
+update_quality (struct GAS_MLP_Handle *mlp, struct ATS_Address * address)
+{
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Updating quality metrics for peer `%s'\n",
+ GNUNET_i2s (&address->peer));
+
+ struct MLP_information *mlpi = address->mlp_information;
+ struct GNUNET_ATS_Information *ats = address->ats;
+ GNUNET_assert (mlpi != NULL);
+
+ int c;
+
+ for (c = 0; c < GNUNET_ATS_QualityPropertiesCount; c++)
+ {
+ int index = mlp_lookup_ats(address, mlp->q[c]);
+
+ if (index == GNUNET_SYSERR)
+ continue;
+
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Updating address for peer `%s' value `%s': %f\n",
+ GNUNET_i2s (&address->peer),
+ mlp_ats_to_string(mlp->q[c]),
+ (double) ats[index].value);
+
+ int i = mlpi->q_avg_i[c];
+ double * qp = mlpi->q[c];
+ qp[i] = (double) ats[index].value;
+
+ int t;
+ for (t = 0; t < MLP_AVERAGING_QUEUE_LENGTH; t++)
+ {
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Peer `%s': `%s' queue[%u]: %f\n",
+ GNUNET_i2s (&address->peer),
+ mlp_ats_to_string(mlp->q[c]),
+ t,
+ qp[t]);
+ }
+
+ if (mlpi->q_avg_i[c] + 1 < (MLP_AVERAGING_QUEUE_LENGTH))
+ mlpi->q_avg_i[c] ++;
+ else
+ mlpi->q_avg_i[c] = 0;
+
+
+ int c2;
+ int c3;
+ double avg = 0.0;
+ switch (mlp->q[c])
+ {
+ case GNUNET_ATS_QUALITY_NET_DELAY:
+ c3 = 0;
+ for (c2 = 0; c2 < MLP_AVERAGING_QUEUE_LENGTH; c2++)
+ {
+ if (mlpi->q[c][c2] != -1)
+ {
+ double * t2 = mlpi->q[c] ;
+ avg += t2[c2];
+ c3 ++;
+ }
+ }
+ if (c3 > 0)
+ /* avg = 1 / ((q[0] + ... + q[l]) /c3) => c3 / avg*/
+ mlpi->q_averaged[c] = (double) c3 / avg;
+ else
+ mlpi->q_averaged[c] = 0.0;
+
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Peer `%s': `%s' average sum: %f, average: %f, weight: %f\n",
+ GNUNET_i2s (&address->peer),
+ mlp_ats_to_string(mlp->q[c]),
+ avg,
+ avg / (double) c3,
+ mlpi->q_averaged[c]);
+
+ break;
+ case GNUNET_ATS_QUALITY_NET_DISTANCE:
+ c3 = 0;
+ for (c2 = 0; c2 < MLP_AVERAGING_QUEUE_LENGTH; c2++)
+ {
+ if (mlpi->q[c][c2] != -1)
+ {
+ double * t2 = mlpi->q[c] ;
+ avg += t2[c2];
+ c3 ++;
+ }
+ }
+ if (c3 > 0)
+ /* avg = 1 / ((q[0] + ... + q[l]) /c3) => c3 / avg*/
+ mlpi->q_averaged[c] = (double) c3 / avg;
+ else
+ mlpi->q_averaged[c] = 0.0;
+
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Peer `%s': `%s' average sum: %f, average: %f, weight: %f\n",
+ GNUNET_i2s (&address->peer),
+ mlp_ats_to_string(mlp->q[c]),
+ avg,
+ avg / (double) c3,
+ mlpi->q_averaged[c]);
+
+ break;
+ default:
+ break;
+ }
+
+ if ((mlpi->c_b != 0) && (mlpi->r_q[c] != 0))
+ {
+
+ /* Get current number of columns */
+ int found = GNUNET_NO;
+ int cols = glp_get_num_cols(mlp->prob);
+ int *ind = GNUNET_malloc (cols * sizeof (int) + 1);
+ double *val = GNUNET_malloc (cols * sizeof (double) + 1);
+
+ /* Get the matrix row of quality */
+ int length = glp_get_mat_row(mlp->prob, mlp->r_q[c], ind, val);
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "cols %i, length %i c_b %i\n", cols, length, mlpi->c_b);
+ int c4;
+ /* Get the index if matrix row of quality */
+ for (c4 = 1; c4 <= length; c4++ )
+ {
+ if (mlpi->c_b == ind[c4])
+ {
+ /* Update the value */
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Updating quality `%s' column `%s' row `%s' : %f -> %f\n",
+ mlp_ats_to_string(mlp->q[c]),
+ glp_get_col_name (mlp->prob, ind[c4]),
+ glp_get_row_name (mlp->prob, mlp->r_q[c]),
+ val[c4],
+ mlpi->q_averaged[c]);
+ val[c4] = mlpi->q_averaged[c];
+ found = GNUNET_YES;
+ break;
+ }
+ }
+
+ if (found == GNUNET_NO)
+ {
+
+ ind[length+1] = mlpi->c_b;
+ val[length+1] = mlpi->q_averaged[c];
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "%i ind[%i] val[%i]: %i %f\n", length+1, length+1, length+1, mlpi->c_b, mlpi->q_averaged[c]);
+ glp_set_mat_row (mlp->prob, mlpi->r_q[c], length+1, ind, val);
+ }
+ else
+ {
+ /* Get the index if matrix row of quality */
+ glp_set_mat_row (mlp->prob, mlpi->r_q[c], length, ind, val);
+ }
+
+ GNUNET_free (ind);
+ GNUNET_free (val);
+ }
+ }
+}
/**
* Updates a single address in the MLP problem
int c;
for (c = 0; c < GNUNET_ATS_QualityPropertiesCount; c++)
{
- mlpi->c_q[c] = 0;
+ int c2;
mlpi->r_q[c] = 0;
- mlpi->q[c] = 0.0;
+ for (c2 = 0; c2 < MLP_AVERAGING_QUEUE_LENGTH; c2++)
+ mlpi->q[c][c2] = -1.0; /* -1.0: invalid value */
+ mlpi->q_avg_i[c] = 0;
+ mlpi->q_averaged[c] = 0.0;
}
address->mlp_information = mlpi;
GNUNET_CONTAINER_DLL_insert (peer->head, peer->tail, address);
}
+
+ update_quality (mlp, address);
}
else
{
-
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Updating existing address to peer `%s'\n",
GNUNET_i2s (&address->peer));
- mlpi = address->mlp_information;
- int c;
- for (c = 0; c < GNUNET_ATS_QualityPropertiesCount; c++)
- {
- int index = mlp_lookup_ats(address, mlp->q[c]);
- if ((index != GNUNET_SYSERR) && (mlpi->c_q[c] != 0) && (mlpi->r_q[c] != 0))
- {
- if (mlpi->q[c] == (double) address->ats[index].value)
- break;
-
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Updating address for peer `%s' value `%s'from %f to %f\n",
- GNUNET_i2s (&address->peer),
- mlp_ats_to_string(mlp->q[c]),
- mlpi->q[c],
- (double) address->ats[index].value);
-
- switch (mlp->q[c])
- {
- case GNUNET_ATS_QUALITY_NET_DELAY:
- mlpi->q[c] = (double) address->ats[index].value;
- break;
- case GNUNET_ATS_QUALITY_NET_DISTANCE:
- mlpi->q[c] = (double) address->ats[index].value;
- break;
- default:
- break;
- }
-
- /* Get current number of columns */
- int cols = glp_get_num_cols(mlp->prob);
- int *ind = GNUNET_malloc (cols * sizeof (int));
- double *val = GNUNET_malloc (cols * sizeof (double));
-
- /* Get the matrix row of quality */
- cols = glp_get_mat_row(mlp->prob, mlp->r_q[c], ind, val);
-
- int c2;
- /* Get the index if matrix row of quality */
- for (c2 = 1; c2 <= cols; c2++ )
- {
-
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Existing element column %i : %f\n",
- ind[c2], val[c2]);
-
- if ((mlpi->c_b == ind[c2]) && (val[c2] != mlpi->q[c]))
- {
- /* Update the value */
- val[c2] = mlpi->q[c];
-
- GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "New element column %i : %f\n",
- ind[c2], val[c2]);
-
- }
- }
-
- /* Get the index if matrix row of quality */
- glp_set_mat_row (mlp->prob, mlpi->r_q[c], cols, ind, val);
-
- GNUNET_free (ind);
- GNUNET_free (val);
- }
- }
+ update_quality (mlp, address);
}
/* Recalculate */
if (new == GNUNET_YES)
{
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Recreating problem: new address\n");
+
mlp_delete_problem (mlp);
mlp_create_problem (mlp, addresses);
mlp->presolver_required = GNUNET_YES;
}
/* Update problem */
+ GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Recreating problem: new address\n");
+
mlp_delete_problem (mlp);
if ((GNUNET_CONTAINER_multihashmap_size (addresses) > 0) && (mlp->c_p > 0))
{
mlp_get_preferred_address_it (void *cls, const GNUNET_HashCode * key, void *value)
{
- struct ATS_Address **aa = (struct ATS_Address **)cls;
+ struct ATS_PreferedAddress *aa = (struct ATS_PreferedAddress *) cls;
struct ATS_Address *addr = value;
struct MLP_information *mlpi = addr->mlp_information;
+ if (mlpi == NULL)
+ return GNUNET_YES;
if (mlpi->n == GNUNET_YES)
{
- *aa = addr;
+ aa->address = addr;
+ if (mlpi->b > (double) UINT32_MAX)
+ aa->bandwidth_out = UINT32_MAX;
+ else
+ aa->bandwidth_out = (uint32_t) mlpi->b;
+ aa->bandwidth_in = 0;
return GNUNET_NO;
}
return GNUNET_YES;
* Get the preferred address for a specific peer
*
* @param mlp the MLP Handle
+ * @param addresses address hashmap
* @param peer the peer
* @return suggested address
*/
-struct ATS_Address *
+struct ATS_PreferedAddress *
GAS_mlp_get_preferred_address (struct GAS_MLP_Handle *mlp,
struct GNUNET_CONTAINER_MultiHashMap * addresses,
const struct GNUNET_PeerIdentity *peer)
{
- struct ATS_Address * aa = NULL;
+ struct ATS_PreferedAddress * aa = GNUNET_malloc (sizeof (struct ATS_PreferedAddress));
+ aa->address = NULL;
+ aa->bandwidth_in = 0;
+ aa->bandwidth_out = 0;
GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Getting preferred address for `%s'\n", GNUNET_i2s (peer));
- GNUNET_CONTAINER_multihashmap_get_multiple(addresses, &peer->hashPubKey, mlp_get_preferred_address_it, &aa);
+ GNUNET_CONTAINER_multihashmap_get_multiple (addresses, &peer->hashPubKey, mlp_get_preferred_address_it, aa);
return aa;
}