aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMatthias Wachs <wachs@net.in.tum.de>2014-05-08 13:41:54 +0000
committerMatthias Wachs <wachs@net.in.tum.de>2014-05-08 13:41:54 +0000
commitfe75dda0d3bec4282dda91cd722f365d07cddd47 (patch)
treeb06cf14e30118fcad0b8f13378be276b7a35931c /src
parent94d362e7c457e7f98d543474b86f1ceb2d19f695 (diff)
downloadgnunet-fe75dda0d3bec4282dda91cd722f365d07cddd47.tar.gz
gnunet-fe75dda0d3bec4282dda91cd722f365d07cddd47.zip
clarification for proportional solver
Diffstat (limited to 'src')
-rw-r--r--src/ats/plugin_ats_proportional.c230
1 files changed, 175 insertions, 55 deletions
diff --git a/src/ats/plugin_ats_proportional.c b/src/ats/plugin_ats_proportional.c
index 01993f471..413b61fc6 100644
--- a/src/ats/plugin_ats_proportional.c
+++ b/src/ats/plugin_ats_proportional.c
@@ -220,7 +220,7 @@ struct GAS_PROPORTIONAL_Handle
220 /** 220 /**
221 * Hashmap containing all valid addresses 221 * Hashmap containing all valid addresses
222 */ 222 */
223 const struct GNUNET_CONTAINER_MultiPeerMap *addresses; 223 struct GNUNET_CONTAINER_MultiPeerMap *addresses;
224 224
225 /** 225 /**
226 * Pending address requests 226 * Pending address requests
@@ -834,6 +834,21 @@ end:
834 return GNUNET_OK; 834 return GNUNET_OK;
835} 835}
836 836
837struct ATS_Address *
838get_best_address (struct GAS_PROPORTIONAL_Handle *s,
839 struct GNUNET_CONTAINER_MultiPeerMap *addresses,
840 const struct GNUNET_PeerIdentity *id)
841{
842 struct FindBestAddressCtx fba_ctx;
843 fba_ctx.best = NULL;
844 fba_ctx.s = s;
845
846 GNUNET_CONTAINER_multipeermap_get_multiple (addresses, id,
847 &find_best_address_it, &fba_ctx);
848
849 return fba_ctx.best;
850}
851
837/** 852/**
838 * Helper functions 853 * Helper functions
839 * --------------------------- 854 * ---------------------------
@@ -899,14 +914,20 @@ distribute_bandwidth_in_network (struct GAS_PROPORTIONAL_Handle *s,
899 if (NULL != s->env->info_cb) 914 if (NULL != s->env->info_cb)
900 s->env->info_cb(s->env->info_cb_cls, GAS_OP_SOLVE_START, 915 s->env->info_cb(s->env->info_cb_cls, GAS_OP_SOLVE_START,
901 GAS_STAT_SUCCESS, GAS_INFO_PROP_SINGLE); 916 GAS_STAT_SUCCESS, GAS_INFO_PROP_SINGLE);
917
918 /* Distribute */
902 distribute_bandwidth(s, n, address_except); 919 distribute_bandwidth(s, n, address_except);
920
903 if (NULL != s->env->info_cb) 921 if (NULL != s->env->info_cb)
904 s->env->info_cb(s->env->info_cb_cls, GAS_OP_SOLVE_STOP, 922 s->env->info_cb(s->env->info_cb_cls, GAS_OP_SOLVE_STOP,
905 GAS_STAT_SUCCESS, GAS_INFO_PROP_SINGLE); 923 GAS_STAT_SUCCESS, GAS_INFO_PROP_SINGLE);
906 if (NULL != s->env->info_cb) 924 if (NULL != s->env->info_cb)
907 s->env->info_cb(s->env->info_cb_cls, GAS_OP_SOLVE_UPDATE_NOTIFICATION_START, 925 s->env->info_cb(s->env->info_cb_cls, GAS_OP_SOLVE_UPDATE_NOTIFICATION_START,
908 GAS_STAT_SUCCESS, GAS_INFO_PROP_SINGLE); 926 GAS_STAT_SUCCESS, GAS_INFO_PROP_SINGLE);
909 propagate_bandwidth(s, n, address_except); 927
928 /* Do propagation */
929 propagate_bandwidth (s, n, address_except);
930
910 if (NULL != s->env->info_cb) 931 if (NULL != s->env->info_cb)
911 s->env->info_cb(s->env->info_cb_cls, GAS_OP_SOLVE_UPDATE_NOTIFICATION_STOP, 932 s->env->info_cb(s->env->info_cb_cls, GAS_OP_SOLVE_UPDATE_NOTIFICATION_STOP,
912 GAS_STAT_SUCCESS, GAS_INFO_PROP_SINGLE); 933 GAS_STAT_SUCCESS, GAS_INFO_PROP_SINGLE);
@@ -918,7 +939,11 @@ distribute_bandwidth_in_network (struct GAS_PROPORTIONAL_Handle *s,
918 s->env->info_cb(s->env->info_cb_cls, GAS_OP_SOLVE_START, 939 s->env->info_cb(s->env->info_cb_cls, GAS_OP_SOLVE_START,
919 GAS_STAT_SUCCESS, GAS_INFO_PROP_ALL); 940 GAS_STAT_SUCCESS, GAS_INFO_PROP_ALL);
920 for (i = 0; i < s->network_count; i++) 941 for (i = 0; i < s->network_count; i++)
942 {
943 /* Distribute */
921 distribute_bandwidth(s, &s->network_entries[i], NULL); 944 distribute_bandwidth(s, &s->network_entries[i], NULL);
945 }
946
922 if (NULL != s->env->info_cb) 947 if (NULL != s->env->info_cb)
923 s->env->info_cb(s->env->info_cb_cls, GAS_OP_SOLVE_STOP, 948 s->env->info_cb(s->env->info_cb_cls, GAS_OP_SOLVE_STOP,
924 GAS_STAT_SUCCESS, GAS_INFO_PROP_ALL); 949 GAS_STAT_SUCCESS, GAS_INFO_PROP_ALL);
@@ -927,6 +952,7 @@ distribute_bandwidth_in_network (struct GAS_PROPORTIONAL_Handle *s,
927 GAS_STAT_SUCCESS, GAS_INFO_PROP_ALL); 952 GAS_STAT_SUCCESS, GAS_INFO_PROP_ALL);
928 for (i = 0; i < s->network_count; i++) 953 for (i = 0; i < s->network_count; i++)
929 { 954 {
955 /* Do propagation */
930 propagate_bandwidth(s, &s->network_entries[i], address_except); 956 propagate_bandwidth(s, &s->network_entries[i], address_except);
931 } 957 }
932 if (NULL != s->env->info_cb) 958 if (NULL != s->env->info_cb)
@@ -1087,6 +1113,22 @@ addresse_decrement (struct GAS_PROPORTIONAL_Handle *s, struct Network *net,
1087 return res; 1113 return res;
1088} 1114}
1089 1115
1116static int
1117address_eq (struct ATS_Address *a, struct ATS_Address *b)
1118{
1119 GNUNET_assert (NULL != a);
1120 GNUNET_assert (NULL != b);
1121 if (0 != strcmp(a->plugin, b->plugin))
1122 return GNUNET_NO;
1123 if (a->addr_len != b->addr_len)
1124 return GNUNET_NO;
1125 if (0 != memcmp (a->addr, b->addr, b->addr_len))
1126 return GNUNET_NO;
1127 if (a->session_id != b->session_id)
1128 return GNUNET_NO;
1129 return GNUNET_YES;
1130}
1131
1090/** 1132/**
1091 * Solver API functions 1133 * Solver API functions
1092 * --------------------------- 1134 * ---------------------------
@@ -1107,9 +1149,31 @@ GAS_proportional_address_change_preference (void *solver,
1107 double pref_rel) 1149 double pref_rel)
1108{ 1150{
1109 struct GAS_PROPORTIONAL_Handle *s = solver; 1151 struct GAS_PROPORTIONAL_Handle *s = solver;
1152 struct ATS_Address *best_address;
1153 struct ATS_Address *active_address;
1154
1110 GNUNET_assert(NULL != solver); 1155 GNUNET_assert(NULL != solver);
1111 GNUNET_assert(NULL != peer); 1156 GNUNET_assert(NULL != peer);
1112 1157
1158 if (GNUNET_NO == GNUNET_CONTAINER_multipeermap_contains (s->requests, peer))
1159 return; /* Peer is not requested */
1160
1161 /* This peer is requested, find best address */
1162 active_address = get_active_address(s, s->addresses, peer);
1163 best_address = (struct ATS_Address *) GAS_proportional_get_preferred_address (s, peer);
1164
1165 if (NULL == best_address)
1166 return; /* No address to suggest */
1167
1168 if ((NULL == active_address) || ((NULL != active_address) &&
1169 (GNUNET_NO == address_eq (active_address, best_address))))
1170 {
1171 /* We now have an active address */
1172 s->bw_changed (s->bw_changed_cls, best_address);
1173 return;
1174 }
1175
1176 /* Preferences changed, we have to recalculate bandwidth distribution */
1113 distribute_bandwidth_in_network (s, NULL, NULL); 1177 distribute_bandwidth_in_network (s, NULL, NULL);
1114} 1178}
1115 1179
@@ -1141,6 +1205,8 @@ GAS_proportional_address_preference_feedback (void *solver, void *application,
1141/** 1205/**
1142 * Get the preferred address for a specific peer 1206 * Get the preferred address for a specific peer
1143 * 1207 *
1208 *
1209 *
1144 * @param solver the solver handle 1210 * @param solver the solver handle
1145 * @param peer the identity of the peer 1211 * @param peer the identity of the peer
1146 */ 1212 */
@@ -1152,7 +1218,7 @@ GAS_proportional_get_preferred_address (void *solver,
1152 struct Network *net_prev; 1218 struct Network *net_prev;
1153 struct Network *net_cur; 1219 struct Network *net_cur;
1154 struct ATS_Address *prev; 1220 struct ATS_Address *prev;
1155 struct FindBestAddressCtx fba_ctx; 1221 struct ATS_Address *best_address;
1156 struct AddressSolverInformation *asi; 1222 struct AddressSolverInformation *asi;
1157 struct AddressSolverInformation *asi_prev; 1223 struct AddressSolverInformation *asi_prev;
1158 1224
@@ -1167,35 +1233,25 @@ GAS_proportional_get_preferred_address (void *solver,
1167 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY)); 1233 GNUNET_CONTAINER_MULTIHASHMAPOPTION_UNIQUE_ONLY));
1168 } 1234 }
1169 1235
1170 /* Get address with: stick to current address, lower distance, lower latency */ 1236 /* Find best address */
1171 fba_ctx.s = s; 1237 best_address = get_best_address (s,s->addresses, peer);
1172 fba_ctx.best = NULL; 1238 if (NULL == best_address)
1173
1174 GNUNET_CONTAINER_multipeermap_get_multiple (s->addresses, peer,
1175 &find_best_address_it, &fba_ctx);
1176 if (NULL == fba_ctx.best)
1177 { 1239 {
1178 LOG(GNUNET_ERROR_TYPE_INFO, "Cannot suggest address for peer `%s'\n", 1240 LOG (GNUNET_ERROR_TYPE_INFO, "Cannot suggest address for peer `%s'\n",
1179 GNUNET_i2s (peer)); 1241 GNUNET_i2s (peer));
1180 return NULL ; 1242 return NULL ;
1181 } 1243 }
1182 1244
1183 LOG(GNUNET_ERROR_TYPE_INFO, "Suggesting %s address %p for peer `%s'\n", 1245 LOG (GNUNET_ERROR_TYPE_INFO, "Suggesting %s address %p for peer `%s'\n",
1184 (GNUNET_NO == fba_ctx.best->active) ? "inactive" : "active", fba_ctx.best, 1246 (GNUNET_NO == best_address->active) ? "inactive" : "active", best_address,
1185 GNUNET_i2s (peer)); 1247 GNUNET_i2s (peer));
1186 asi = fba_ctx.best->solver_information; 1248
1249 asi = best_address->solver_information;
1187 net_cur = asi->network ; 1250 net_cur = asi->network ;
1188 if (NULL == fba_ctx.best) 1251 if (GNUNET_YES == best_address->active)
1189 {
1190 LOG(GNUNET_ERROR_TYPE_ERROR,
1191 "Trying to suggesting unknown address peer `%s'\n", GNUNET_i2s (peer));
1192 GNUNET_break(0);
1193 return NULL ;
1194 }
1195 if (GNUNET_YES == fba_ctx.best->active)
1196 { 1252 {
1197 /* This address was selected previously, so no need to update quotas */ 1253 /* This address was selected previously, so no need to update quotas */
1198 return fba_ctx.best; 1254 return best_address;
1199 } 1255 }
1200 1256
1201 /* This address was not active, so we have to: 1257 /* This address was not active, so we have to:
@@ -1208,26 +1264,32 @@ GAS_proportional_get_preferred_address (void *solver,
1208 if (NULL != prev) 1264 if (NULL != prev)
1209 { 1265 {
1210 asi_prev = prev->solver_information; 1266 asi_prev = prev->solver_information;
1211 net_prev = (struct Network *) asi_prev->network; 1267 net_prev = asi_prev->network;
1212 prev->active = GNUNET_NO; /* No active any longer */ 1268 prev->active = GNUNET_NO; /* No active any longer */
1213 prev->assigned_bw_in = BANDWIDTH_ZERO; /* no bandwidth assigned */ 1269 prev->assigned_bw_in = BANDWIDTH_ZERO; /* no bandwidth assigned */
1214 prev->assigned_bw_out = BANDWIDTH_ZERO; /* no bandwidth assigned */ 1270 prev->assigned_bw_out = BANDWIDTH_ZERO; /* no bandwidth assigned */
1215 1271
1216 if (GNUNET_SYSERR == addresse_decrement (s, net_prev, GNUNET_NO, GNUNET_YES)) 1272 if (GNUNET_SYSERR == addresse_decrement (s, net_prev, GNUNET_NO, GNUNET_YES))
1217 GNUNET_break(0); 1273 GNUNET_break(0);
1274
1275 /* Update network of previous address */
1218 distribute_bandwidth_in_network (s, net_prev, NULL); 1276 distribute_bandwidth_in_network (s, net_prev, NULL);
1219 } 1277 }
1220 1278
1221 if (GNUNET_NO == (is_bandwidth_available_in_network (net_cur))) 1279 if (GNUNET_NO == (is_bandwidth_available_in_network (net_cur)))
1222 { 1280 {
1223 GNUNET_break(0); /* This should never happen*/ 1281 /* This should never happen, because we checked when finding best address */
1282 GNUNET_break(0);
1224 return NULL ; 1283 return NULL ;
1225 } 1284 }
1226 1285
1227 fba_ctx.best->active = GNUNET_YES; 1286 /* Mark address as active */
1287 best_address->active = GNUNET_YES;
1228 addresse_increment (s, net_cur, GNUNET_NO, GNUNET_YES); 1288 addresse_increment (s, net_cur, GNUNET_NO, GNUNET_YES);
1229 distribute_bandwidth_in_network (s, net_cur, fba_ctx.best); 1289
1230 return fba_ctx.best; 1290 /* Distribute bandwidth */
1291 distribute_bandwidth_in_network (s, net_cur, best_address);
1292 return best_address;
1231} 1293}
1232 1294
1233/** 1295/**
@@ -1245,11 +1307,9 @@ GAS_proportional_stop_get_preferred_address (void *solver,
1245 struct AddressSolverInformation *asi; 1307 struct AddressSolverInformation *asi;
1246 struct Network *cur_net; 1308 struct Network *cur_net;
1247 1309
1248 if (GNUNET_YES 1310 if (GNUNET_YES == GNUNET_CONTAINER_multipeermap_contains (s->requests, peer))
1249 == GNUNET_CONTAINER_multipeermap_contains (s->requests, 1311 GNUNET_assert (GNUNET_OK == GNUNET_CONTAINER_multipeermap_remove (s->requests,
1250 peer)) 1312 peer, NULL));
1251 GNUNET_assert (GNUNET_OK == GNUNET_CONTAINER_multipeermap_remove (s->requests, peer,
1252 NULL));
1253 1313
1254 cur = get_active_address (s, s->addresses, peer); 1314 cur = get_active_address (s, s->addresses, peer);
1255 if (NULL != cur) 1315 if (NULL != cur)
@@ -1441,6 +1501,8 @@ GAS_proportional_address_property_changed (void *solver,
1441 struct GAS_PROPORTIONAL_Handle *s; 1501 struct GAS_PROPORTIONAL_Handle *s;
1442 struct Network *n; 1502 struct Network *n;
1443 struct AddressSolverInformation *asi; 1503 struct AddressSolverInformation *asi;
1504 struct ATS_Address *best_address;
1505 struct ATS_Address *active_address;
1444 1506
1445 GNUNET_assert(NULL != solver); 1507 GNUNET_assert(NULL != solver);
1446 GNUNET_assert(NULL != address); 1508 GNUNET_assert(NULL != address);
@@ -1454,7 +1516,6 @@ GAS_proportional_address_property_changed (void *solver,
1454 } 1516 }
1455 1517
1456 n = asi->network; 1518 n = asi->network;
1457
1458 if (NULL == n) 1519 if (NULL == n)
1459 { 1520 {
1460 GNUNET_break(0); 1521 GNUNET_break(0);
@@ -1465,19 +1526,29 @@ GAS_proportional_address_property_changed (void *solver,
1465 "Property `%s' for peer `%s' address %p changed to %.2f \n", 1526 "Property `%s' for peer `%s' address %p changed to %.2f \n",
1466 GNUNET_ATS_print_property_type (type), GNUNET_i2s (&address->peer), 1527 GNUNET_ATS_print_property_type (type), GNUNET_i2s (&address->peer),
1467 address, rel_value); 1528 address, rel_value);
1468 switch (type) 1529
1530 if (GNUNET_NO == GNUNET_CONTAINER_multipeermap_contains (s->requests, &address->peer))
1531 return; /* Peer is not requested */
1532
1533 /* This peer is requested, find active and best address */
1534 active_address = get_active_address(s, s->addresses, &address->peer);
1535 best_address = (struct ATS_Address *) GAS_proportional_get_preferred_address (s, &address->peer);
1536
1537 if (NULL == best_address)
1538 return; /* No address to suggest */
1539
1540 if ((NULL != active_address) && GNUNET_YES == address_eq (active_address, best_address))
1469 { 1541 {
1470 case GNUNET_ATS_UTILIZATION_OUT: 1542 /* We kept the active address, just redistribute */
1471 case GNUNET_ATS_UTILIZATION_IN:
1472 case GNUNET_ATS_UTILIZATION_PAYLOAD_IN:
1473 case GNUNET_ATS_UTILIZATION_PAYLOAD_OUT:
1474 case GNUNET_ATS_QUALITY_NET_DELAY:
1475 case GNUNET_ATS_QUALITY_NET_DISTANCE:
1476 case GNUNET_ATS_COST_WAN:
1477 case GNUNET_ATS_COST_LAN:
1478 case GNUNET_ATS_COST_WLAN:
1479 distribute_bandwidth_in_network (s, n, NULL); 1543 distribute_bandwidth_in_network (s, n, NULL);
1480 break; 1544 return;
1545 }
1546
1547 if ((NULL == active_address) || ((NULL != active_address) &&
1548 (GNUNET_NO == address_eq (active_address, best_address))))
1549 {
1550 /* We switched active addresses */
1551 s->bw_changed (s->bw_changed_cls, (struct ATS_Address *) best_address);
1481 } 1552 }
1482} 1553}
1483 1554
@@ -1495,11 +1566,50 @@ void
1495GAS_proportional_address_session_changed (void *solver, 1566GAS_proportional_address_session_changed (void *solver,
1496 struct ATS_Address *address, uint32_t cur_session, uint32_t new_session) 1567 struct ATS_Address *address, uint32_t cur_session, uint32_t new_session)
1497{ 1568{
1569 struct GAS_PROPORTIONAL_Handle *s = solver;
1570 struct ATS_Address *best_address;
1571 struct ATS_Address *active_address;
1572 struct AddressSolverInformation *asi;
1573 struct Network *net_cur;
1574
1575 s = (struct GAS_PROPORTIONAL_Handle *) solver;
1498 if (cur_session != new_session) 1576 if (cur_session != new_session)
1499 { 1577 {
1500 LOG(GNUNET_ERROR_TYPE_DEBUG, "Session changed from %u to %u\n", cur_session, 1578 LOG(GNUNET_ERROR_TYPE_DEBUG, "Session changed from %u to %u\n", cur_session,
1501 new_session); 1579 new_session);
1502 } 1580 }
1581
1582 if (NULL == address->solver_information)
1583 {
1584 GNUNET_break (0);
1585 return;
1586 }
1587
1588 if (GNUNET_NO == GNUNET_CONTAINER_multipeermap_contains (s->requests, &address->peer))
1589 return; /* Peer is not requested */
1590
1591 /* This peer is requested, find active and best address */
1592 active_address = get_active_address(s, s->addresses, &address->peer);
1593 best_address = (struct ATS_Address *) GAS_proportional_get_preferred_address (s, &address->peer);
1594 asi = best_address->solver_information;
1595 net_cur = asi->network ;
1596
1597 if (NULL == best_address)
1598 return; /* No address to suggest */
1599
1600 if ((NULL != active_address) && GNUNET_YES == address_eq (active_address, best_address))
1601 {
1602 /* We kept the active address, just redistribute */
1603 distribute_bandwidth_in_network (s, net_cur, NULL);
1604 return;
1605 }
1606
1607 if ((NULL == active_address) || ((NULL != active_address) &&
1608 (GNUNET_NO == address_eq (active_address, best_address))))
1609 {
1610 /* We switched active addresses */
1611 s->bw_changed (s->bw_changed_cls, (struct ATS_Address *) best_address);
1612 }
1503} 1613}
1504 1614
1505/** 1615/**
@@ -1552,7 +1662,6 @@ GAS_proportional_address_change_network (void *solver,
1552 return; 1662 return;
1553 } 1663 }
1554 1664
1555
1556 /* Network changed */ 1665 /* Network changed */
1557 LOG(GNUNET_ERROR_TYPE_DEBUG, 1666 LOG(GNUNET_ERROR_TYPE_DEBUG,
1558 "Network type changed, moving %s address from `%s' to `%s'\n", 1667 "Network type changed, moving %s address from `%s' to `%s'\n",
@@ -1629,6 +1738,8 @@ GAS_proportional_address_add (void *solver, struct ATS_Address *address,
1629 struct Network *net = NULL; 1738 struct Network *net = NULL;
1630 struct AddressWrapper *aw = NULL; 1739 struct AddressWrapper *aw = NULL;
1631 struct AddressSolverInformation *asi; 1740 struct AddressSolverInformation *asi;
1741 struct ATS_Address *best_address;
1742 struct ATS_Address *active_address;
1632 1743
1633 GNUNET_assert(NULL != s); 1744 GNUNET_assert(NULL != s);
1634 net = get_network (s, network); 1745 net = get_network (s, network);
@@ -1655,18 +1766,27 @@ GAS_proportional_address_add (void *solver, struct ATS_Address *address,
1655 asi->calculated_quota_out_NBO = htonl (0); 1766 asi->calculated_quota_out_NBO = htonl (0);
1656 aw->addr->solver_information = asi; 1767 aw->addr->solver_information = asi;
1657 1768
1658 if (GNUNET_YES == GNUNET_CONTAINER_multipeermap_contains (s->requests, &address->peer))
1659 {
1660 if (NULL == get_active_address (s, s->addresses, &address->peer))
1661 {
1662 if (NULL != GAS_proportional_get_preferred_address (s, &address->peer))
1663 s->bw_changed (s->bw_changed_cls, (struct ATS_Address *) address);
1664 }
1665 }
1666
1667 LOG(GNUNET_ERROR_TYPE_INFO, 1769 LOG(GNUNET_ERROR_TYPE_INFO,
1668 "Adding new address %p for peer `%s', now total %u and active %u addresses in network `%s'\n", 1770 "Adding new address %p for peer `%s', now total %u and active %u addresses in network `%s'\n",
1669 address, GNUNET_i2s(&address->peer), net->total_addresses, net->active_addresses, net->desc); 1771 address, GNUNET_i2s(&address->peer), net->total_addresses, net->active_addresses, net->desc);
1772
1773 if (GNUNET_NO == GNUNET_CONTAINER_multipeermap_contains (s->requests, &address->peer))
1774 return; /* Peer is not requested */
1775
1776 /* This peer is requested, find best address */
1777 active_address = get_active_address(s, s->addresses, &address->peer);
1778 best_address = (struct ATS_Address *) GAS_proportional_get_preferred_address (s, &address->peer);
1779
1780 if (NULL == best_address)
1781 return; /* No address to suggest */
1782
1783 if ((NULL == active_address)
1784 || ((NULL != active_address)
1785 && (GNUNET_NO == address_eq (active_address, best_address))))
1786 {
1787 /* We now have an active address or the active address changed */
1788 s->bw_changed (s->bw_changed_cls, (struct ATS_Address *) best_address);
1789 }
1670} 1790}
1671 1791
1672 1792