aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/ats/Makefile.am10
-rw-r--r--src/ats/ats_api_scheduling.c158
-rw-r--r--src/ats/test_ats_api_scheduling_destroy_address.c20
-rw-r--r--src/ats/test_ats_api_scheduling_destroy_address_twice.c244
-rw-r--r--src/ats/test_ats_solver_alternative_after_delete_address.c22
-rw-r--r--src/ats/test_ats_solver_request_and_delete_address.c13
-rw-r--r--src/include/gnunet_ats_service.h61
-rw-r--r--src/transport/gnunet-service-transport_ats.c45
-rw-r--r--src/transport/gnunet-service-transport_ats.h13
-rw-r--r--src/transport/gnunet-service-transport_neighbours.c22
10 files changed, 215 insertions, 393 deletions
diff --git a/src/ats/Makefile.am b/src/ats/Makefile.am
index ea631709c..abe61d37e 100644
--- a/src/ats/Makefile.am
+++ b/src/ats/Makefile.am
@@ -116,7 +116,6 @@ TESTING_TESTS = \
116 test_ats_api_scheduling_add_address_duplicate \ 116 test_ats_api_scheduling_add_address_duplicate \
117 test_ats_api_scheduling_add_address_inbound \ 117 test_ats_api_scheduling_add_address_inbound \
118 test_ats_api_scheduling_destroy_address \ 118 test_ats_api_scheduling_destroy_address \
119 test_ats_api_scheduling_destroy_address_twice \
120 test_ats_api_scheduling_add_session \ 119 test_ats_api_scheduling_add_session \
121 test_ats_api_scheduling_destroy_session \ 120 test_ats_api_scheduling_destroy_session \
122 test_ats_api_delayed_service_scheduling_add_address \ 121 test_ats_api_delayed_service_scheduling_add_address \
@@ -217,15 +216,6 @@ test_ats_api_scheduling_destroy_address_LDADD = \
217 libgnunetats.la \ 216 libgnunetats.la \
218 $(top_builddir)/src/statistics/libgnunetstatistics.la 217 $(top_builddir)/src/statistics/libgnunetstatistics.la
219 218
220test_ats_api_scheduling_destroy_address_twice_SOURCES = \
221 test_ats_api_scheduling_destroy_address_twice.c \
222 test_ats_api_common.c test_ats_api_common.h
223test_ats_api_scheduling_destroy_address_twice_LDADD = \
224 $(top_builddir)/src/util/libgnunetutil.la \
225 $(top_builddir)/src/testing/libgnunettesting.la \
226 libgnunetats.la \
227 $(top_builddir)/src/statistics/libgnunetstatistics.la
228
229test_ats_api_scheduling_add_session_SOURCES = \ 219test_ats_api_scheduling_add_session_SOURCES = \
230 test_ats_api_scheduling_add_session.c test_ats_api_common.c 220 test_ats_api_scheduling_add_session.c test_ats_api_common.c
231test_ats_api_scheduling_add_session_LDADD = \ 221test_ats_api_scheduling_add_session_LDADD = \
diff --git a/src/ats/ats_api_scheduling.c b/src/ats/ats_api_scheduling.c
index 1c30f2e66..52dcb49ba 100644
--- a/src/ats/ats_api_scheduling.c
+++ b/src/ats/ats_api_scheduling.c
@@ -1257,6 +1257,49 @@ GNUNET_ATS_address_add (struct GNUNET_ATS_SchedulingHandle *sh,
1257 1257
1258 1258
1259/** 1259/**
1260 * An address was used to initiate a session.
1261 *
1262 * @param ar address record to update information for
1263 * @param session session handle
1264 */
1265void
1266GNUNET_ATS_address_add_session (struct GNUNET_ATS_AddressRecord *ar,
1267 struct Session *session)
1268{
1269 GNUNET_break (NULL == ar->session);
1270 ar->session = session;
1271}
1272
1273
1274/**
1275 * A session was destroyed, disassociate it from the
1276 * given address record. If this was an incoming
1277 * addess, destroy the address as well.
1278 *
1279 * @param ar address record to update information for
1280 * @param session session handle
1281 * @return #GNUNET_YES if the @a ar was destroyed because
1282 * it was an incoming address,
1283 * #GNUNET_NO if the @ar was kept because we can
1284 * use it still to establish a new session
1285 */
1286int
1287GNUNET_ATS_address_del_session (struct GNUNET_ATS_AddressRecord *ar,
1288 struct Session *session)
1289{
1290 GNUNET_break (session == ar->session);
1291 ar->session = NULL;
1292 if (GNUNET_HELLO_address_check_option (ar->address,
1293 GNUNET_HELLO_ADDRESS_INFO_INBOUND))
1294 {
1295 GNUNET_ATS_address_destroy (ar);
1296 return GNUNET_YES;
1297 }
1298 return GNUNET_NO;
1299}
1300
1301
1302/**
1260 * We have updated performance statistics for a given address. Note 1303 * We have updated performance statistics for a given address. Note
1261 * that this function can be called for addresses that are currently 1304 * that this function can be called for addresses that are currently
1262 * in use as well as addresses that are valid but not actively in use. 1305 * in use as well as addresses that are valid but not actively in use.
@@ -1265,13 +1308,11 @@ GNUNET_ATS_address_add (struct GNUNET_ATS_SchedulingHandle *sh,
1265 * for later use). Update bandwidth assignments. 1308 * for later use). Update bandwidth assignments.
1266 * 1309 *
1267 * @param ar address record to update information for 1310 * @param ar address record to update information for
1268 * @param session session handle, can be NULL
1269 * @param ats performance data for the address 1311 * @param ats performance data for the address
1270 * @param ats_count number of performance records in @a ats 1312 * @param ats_count number of performance records in @a ats
1271 */ 1313 */
1272void 1314void
1273GNUNET_ATS_address_update (struct GNUNET_ATS_AddressRecord *ar, 1315GNUNET_ATS_address_update (struct GNUNET_ATS_AddressRecord *ar,
1274 struct Session *session,
1275 const struct GNUNET_ATS_Information *ats, 1316 const struct GNUNET_ATS_Information *ats,
1276 uint32_t ats_count) 1317 uint32_t ats_count)
1277{ 1318{
@@ -1281,7 +1322,6 @@ GNUNET_ATS_address_update (struct GNUNET_ATS_AddressRecord *ar,
1281 memcpy (ar->ats, 1322 memcpy (ar->ats,
1282 ats, 1323 ats,
1283 ats_count * sizeof (struct GNUNET_ATS_Information)); 1324 ats_count * sizeof (struct GNUNET_ATS_Information));
1284 ar->session = session;
1285 send_add_address_message (ar->sh, 1325 send_add_address_message (ar->sh,
1286 ar, 1326 ar,
1287 GNUNET_MESSAGE_TYPE_ATS_ADDRESS_UPDATE); 1327 GNUNET_MESSAGE_TYPE_ATS_ADDRESS_UPDATE);
@@ -1291,111 +1331,73 @@ GNUNET_ATS_address_update (struct GNUNET_ATS_AddressRecord *ar,
1291/** 1331/**
1292 * An address is now in use or not used any more. 1332 * An address is now in use or not used any more.
1293 * 1333 *
1294 * @param sh handle 1334 * @param ar the address
1295 * @param address the address
1296 * @param session session handle, can be NULL
1297 * @param in_use #GNUNET_YES if this address is now used, #GNUNET_NO 1335 * @param in_use #GNUNET_YES if this address is now used, #GNUNET_NO
1298 * if address is not used any more 1336 * if address is not used any more
1299 */ 1337 */
1300void 1338void
1301GNUNET_ATS_address_in_use (struct GNUNET_ATS_SchedulingHandle *sh, 1339GNUNET_ATS_address_set_in_use (struct GNUNET_ATS_AddressRecord *ar,
1302 const struct GNUNET_HELLO_Address *address, 1340 int in_use)
1303 struct Session *session,
1304 int in_use)
1305{ 1341{
1342 struct GNUNET_ATS_SchedulingHandle *sh = ar->sh;
1306 struct GNUNET_MQ_Envelope *ev; 1343 struct GNUNET_MQ_Envelope *ev;
1307 struct AddressUseMessage *m; 1344 struct AddressUseMessage *m;
1308 struct GNUNET_ATS_AddressRecord *ar;
1309 char *pm; 1345 char *pm;
1310 size_t namelen; 1346 size_t namelen;
1311 size_t msize; 1347 size_t msize;
1312 uint32_t s = 0;
1313 1348
1314 s = find_session_id (sh, session, address);
1315 if (s == NOT_FOUND)
1316 {
1317 /* trying to set unknown address to NO */
1318 GNUNET_break (0);
1319 return;
1320 }
1321 ar = sh->session_array[s];
1322 ar->in_use = in_use; 1349 ar->in_use = in_use;
1323 namelen = (NULL == address->transport_name) 1350 namelen = (NULL == ar->address->transport_name)
1324 ? 0 1351 ? 0
1325 : strlen (address->transport_name) + 1; 1352 : strlen (ar->address->transport_name) + 1;
1326 msize = address->address_length + namelen; 1353 msize = ar->address->address_length + namelen;
1327 1354
1328 ev = GNUNET_MQ_msg_extra (m, msize, GNUNET_MESSAGE_TYPE_ATS_ADDRESS_IN_USE); 1355 ev = GNUNET_MQ_msg_extra (m, msize, GNUNET_MESSAGE_TYPE_ATS_ADDRESS_IN_USE);
1329 m->peer = address->peer; 1356 m->peer = ar->address->peer;
1330 m->in_use = htons (in_use); 1357 m->in_use = htons (in_use);
1331 m->address_length = htons (address->address_length); 1358 m->address_length = htons (ar->address->address_length);
1332 m->address_local_info = htonl ((uint32_t) address->local_info); 1359 m->address_local_info = htonl ((uint32_t) ar->address->local_info);
1333 m->plugin_name_length = htons (namelen); 1360 m->plugin_name_length = htons (namelen);
1334 1361
1335 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1362 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1336 "Setting address used to %s for peer `%s', plugin `%s', session %p\n", 1363 "Setting address used to %s for peer `%s', plugin `%s', session %p\n",
1337 (GNUNET_YES == in_use) ? "YES" : "NO", 1364 (GNUNET_YES == in_use) ? "YES" : "NO",
1338 GNUNET_i2s (&address->peer), 1365 GNUNET_i2s (&ar->address->peer),
1339 address->transport_name, 1366 ar->address->transport_name,
1340 session); 1367 ar->session);
1341 1368
1342 m->session_id = htonl (s); 1369 m->session_id = htonl (ar->slot);
1343 pm = (char *) &m[1]; 1370 pm = (char *) &m[1];
1344 /* FIXME: no need to send the address data */ 1371 /* FIXME: no need to send the address data */
1345 memcpy (pm, address->address, address->address_length); 1372 memcpy (pm, ar->address->address, ar->address->address_length);
1346 memcpy (&pm[address->address_length], address->transport_name, namelen); 1373 memcpy (&pm[ar->address->address_length],
1374 ar->address->transport_name, namelen);
1347 GNUNET_MQ_send (sh->mq, ev); 1375 GNUNET_MQ_send (sh->mq, ev);
1348} 1376}
1349 1377
1350 1378
1351/** 1379/**
1352 * An address got destroyed, stop including it as a valid address. 1380 * An address got destroyed, stop using it as a valid address.
1353 *
1354 * If a session is given, only the session will be removed, if no session is
1355 * given the full address will be deleted.
1356 * 1381 *
1357 * FIXME: the above sentence already indicates that this API is a 1382 * @param ar address to destroy
1358 * mess and troublesome. FIX IT!
1359 *
1360 * @param sh handle
1361 * @param address the address
1362 * @param session session handle that is no longer valid, can be NULL
1363 */ 1383 */
1364void 1384void
1365GNUNET_ATS_address_destroyed (struct GNUNET_ATS_SchedulingHandle *sh, 1385GNUNET_ATS_address_destroy (struct GNUNET_ATS_AddressRecord *ar)
1366 const struct GNUNET_HELLO_Address *address,
1367 struct Session *session)
1368{ 1386{
1369 uint32_t s; 1387 struct GNUNET_ATS_SchedulingHandle *sh = ar->sh;
1370 struct GNUNET_MQ_Envelope *ev; 1388 struct GNUNET_MQ_Envelope *ev;
1371 struct AddressDestroyedMessage *m; 1389 struct AddressDestroyedMessage *m;
1372 struct GNUNET_ATS_AddressRecord *ar;
1373 char *pm; 1390 char *pm;
1374 size_t namelen; 1391 size_t namelen;
1375 size_t msize; 1392 size_t msize;
1376 1393
1377 s = find_session_id (sh, session, address); 1394 GNUNET_break (NULL == ar->session);
1378 if (NOT_FOUND == s) 1395 GNUNET_assert (NULL != ar->address->transport_name);
1379 { 1396 namelen = strlen (ar->address->transport_name) + 1;
1380 GNUNET_assert (0);
1381 return;
1382 }
1383 ar = sh->session_array[s];
1384 if (NULL != session)
1385 {
1386 /* FIXME: this is yucky, fix API! */
1387 GNUNET_break (ar->session == session);
1388 ar->session = NULL;
1389 return;
1390 }
1391
1392
1393 GNUNET_assert (NULL != address->transport_name);
1394 namelen = strlen (address->transport_name) + 1;
1395 GNUNET_assert (namelen > 1); 1397 GNUNET_assert (namelen > 1);
1396 msize = address->address_length + namelen; 1398 msize = ar->address->address_length + namelen;
1397 if ((msize + sizeof (struct AddressDestroyedMessage) >= GNUNET_SERVER_MAX_MESSAGE_SIZE) || 1399 if ((msize + sizeof (struct AddressDestroyedMessage) >= GNUNET_SERVER_MAX_MESSAGE_SIZE) ||
1398 (address->address_length >= GNUNET_SERVER_MAX_MESSAGE_SIZE) || 1400 (ar->address->address_length >= GNUNET_SERVER_MAX_MESSAGE_SIZE) ||
1399 (namelen >= GNUNET_SERVER_MAX_MESSAGE_SIZE)) 1401 (namelen >= GNUNET_SERVER_MAX_MESSAGE_SIZE))
1400 { 1402 {
1401 GNUNET_break (0); 1403 GNUNET_break (0);
@@ -1403,24 +1405,24 @@ GNUNET_ATS_address_destroyed (struct GNUNET_ATS_SchedulingHandle *sh,
1403 } 1405 }
1404 1406
1405 ev = GNUNET_MQ_msg_extra (m, msize, GNUNET_MESSAGE_TYPE_ATS_ADDRESS_DESTROYED); 1407 ev = GNUNET_MQ_msg_extra (m, msize, GNUNET_MESSAGE_TYPE_ATS_ADDRESS_DESTROYED);
1406 m->peer = address->peer; 1408 m->peer = ar->address->peer;
1407 m->address_length = htons (address->address_length); 1409 m->address_length = htons (ar->address->address_length);
1408 m->address_local_info = htonl ((uint32_t) address->local_info); 1410 m->address_local_info = htonl ((uint32_t) ar->address->local_info);
1409 m->plugin_name_length = htons (namelen); 1411 m->plugin_name_length = htons (namelen);
1410 1412
1411 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, 1413 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1412 "Deleting address for peer `%s', plugin `%s', session %p\n", 1414 "Deleting address for peer `%s', plugin `%s', session %p\n",
1413 GNUNET_i2s (&address->peer), 1415 GNUNET_i2s (&ar->address->peer),
1414 address->transport_name, 1416 ar->address->transport_name,
1415 session); 1417 ar->session);
1416 1418
1417 m->session_id = htonl (s); 1419 m->session_id = htonl (ar->slot);
1418 pm = (char *) &m[1]; 1420 pm = (char *) &m[1];
1419 memcpy (pm, 1421 memcpy (pm,
1420 address->address, 1422 ar->address->address,
1421 address->address_length); 1423 ar->address->address_length);
1422 memcpy (&pm[address->address_length], 1424 memcpy (&pm[ar->address->address_length],
1423 address->transport_name, 1425 ar->address->transport_name,
1424 namelen); 1426 namelen);
1425 GNUNET_MQ_send (sh->mq, ev); 1427 GNUNET_MQ_send (sh->mq, ev);
1426 ar->session = NULL; 1428 ar->session = NULL;
diff --git a/src/ats/test_ats_api_scheduling_destroy_address.c b/src/ats/test_ats_api_scheduling_destroy_address.c
index 323128ac2..5807ac456 100644
--- a/src/ats/test_ats_api_scheduling_destroy_address.c
+++ b/src/ats/test_ats_api_scheduling_destroy_address.c
@@ -46,6 +46,11 @@ static struct GNUNET_STATISTICS_Handle *stats;
46static struct GNUNET_ATS_SchedulingHandle *sched_ats; 46static struct GNUNET_ATS_SchedulingHandle *sched_ats;
47 47
48/** 48/**
49 * Our address record.
50 */
51static struct GNUNET_ATS_AddressRecord *ar;
52
53/**
49 * Return value 54 * Return value
50 */ 55 */
51static int ret; 56static int ret;
@@ -139,9 +144,8 @@ stat_cb (void *cls, const char *subsystem,
139 { 144 {
140 GNUNET_log (GNUNET_ERROR_TYPE_INFO, 145 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
141 "Statistics observed address added, now destroying address\n"); 146 "Statistics observed address added, now destroying address\n");
142 GNUNET_ATS_address_destroyed (sched_ats, 147 GNUNET_ATS_address_destroy (ar);
143 &test_hello_address, 148 ar = NULL;
144 test_session);
145 } 149 }
146 return GNUNET_OK; 150 return GNUNET_OK;
147} 151}
@@ -211,11 +215,11 @@ got_initial_value (void *cls,
211 test_hello_address.address_length = test_addr.addr_len; 215 test_hello_address.address_length = test_addr.addr_len;
212 216
213 /* Adding address */ 217 /* Adding address */
214 GNUNET_ATS_address_add (sched_ats, 218 ar = GNUNET_ATS_address_add (sched_ats,
215 &test_hello_address, 219 &test_hello_address,
216 test_session, 220 test_session,
217 test_ats_info, 221 test_ats_info,
218 test_ats_count); 222 test_ats_count);
219} 223}
220 224
221 225
diff --git a/src/ats/test_ats_api_scheduling_destroy_address_twice.c b/src/ats/test_ats_api_scheduling_destroy_address_twice.c
deleted file mode 100644
index 995538e7e..000000000
--- a/src/ats/test_ats_api_scheduling_destroy_address_twice.c
+++ /dev/null
@@ -1,244 +0,0 @@
1/*
2 This file is part of GNUnet.
3 (C) 2010,2011 Christian Grothoff (and other contributing authors)
4
5 GNUnet is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 3, or (at your
8 option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with GNUnet; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
19*/
20/**
21 * @file ats/test_ats_api_scheduling_destroy_address.c
22 * @brief test destroying addresses in automatic transport selection scheduling API
23 * @author Christian Grothoff
24 * @author Matthias Wachs
25 *
26 */
27#include "platform.h"
28#include "gnunet_ats_service.h"
29#include "gnunet_testing_lib.h"
30#include "ats.h"
31#include "test_ats_api_common.h"
32
33/**
34 * Timeout task
35 */
36static struct GNUNET_SCHEDULER_Task * die_task;
37
38/**
39 * Statistics handle
40 */
41static struct GNUNET_STATISTICS_Handle *stats;
42
43/**
44 * Scheduling handle
45 */
46static struct GNUNET_ATS_SchedulingHandle *sched_ats;
47
48/**
49 * Return value
50 */
51static int ret;
52
53/**
54 * Test address
55 */
56static struct Test_Address test_addr;
57
58/**
59 * Test peer
60 */
61static struct PeerContext p;
62
63/**
64 * HELLO address
65 */
66struct GNUNET_HELLO_Address test_hello_address;
67
68/**
69 * Session
70 */
71static void *test_session;
72
73/**
74 * Test ats info
75 */
76struct GNUNET_ATS_Information test_ats_info[2];
77
78/**
79 * Test ats count
80 */
81static uint32_t test_ats_count;
82
83
84static void end (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc);
85
86
87static int
88stat_cb(void *cls, const char *subsystem,
89 const char *name, uint64_t value,
90 int is_persistent)
91{
92 static int initial_ats_stat_cb = GNUNET_YES;
93 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "ATS statistics: `%s' `%s' %llu\n",
94 subsystem,name, value);
95
96 if ((0 == value) && (initial_ats_stat_cb == GNUNET_NO))
97 {
98 fprintf (stderr, "We now expect a warning about destroying an unknown address...\n");
99 GNUNET_ATS_address_destroyed (sched_ats, &test_hello_address, test_session);
100 GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_SECONDS, &end, NULL);
101 }
102 if ((0 == value) && (initial_ats_stat_cb == GNUNET_YES))
103 {
104 initial_ats_stat_cb = GNUNET_NO;
105 }
106 if (1 == value)
107 {
108 GNUNET_ATS_address_destroyed (sched_ats, &test_hello_address, test_session);
109 }
110
111 return GNUNET_OK;
112}
113
114
115static void
116end (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
117{
118 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Shutting down\n");
119
120 if (die_task != NULL)
121 {
122 GNUNET_SCHEDULER_cancel (die_task);
123 die_task = NULL;
124 }
125
126 if (NULL != sched_ats)
127 {
128 GNUNET_ATS_scheduling_done (sched_ats);
129 sched_ats = NULL;
130 }
131
132 GNUNET_STATISTICS_watch_cancel (stats, "ats", "# addresses", &stat_cb, NULL);
133 if (NULL != stats)
134 {
135 GNUNET_STATISTICS_destroy (stats, GNUNET_NO);
136 stats = NULL;
137 }
138
139 free_test_address (&test_addr);
140
141 ret = 0;
142}
143
144
145static void
146end_badly (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
147{
148 die_task = NULL;
149 end ( NULL, NULL);
150 ret = GNUNET_SYSERR;
151}
152
153
154static void
155address_suggest_cb (void *cls,
156 const struct GNUNET_PeerIdentity *peer,
157 const struct GNUNET_HELLO_Address *address,
158 struct Session *session,
159 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out,
160 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in)
161{
162 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Did not expect suggestion callback!\n");
163 GNUNET_SCHEDULER_add_now (&end_badly, NULL);
164}
165
166
167static int
168dummy_stat (void *cls,
169 const char *subsystem,
170 const char *name,
171 uint64_t value,
172 int is_persistent)
173{
174 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
175 "Got dummy stat %s%s:%s = %llu\n",
176 is_persistent ? "!" : " ", subsystem, name, value);
177 return GNUNET_OK;
178}
179
180
181static void
182got_initial_value (void *cls, int success)
183{
184 struct GNUNET_CONFIGURATION_Handle *cfg = cls;
185
186 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Got initial value\n");
187
188 /* Connect to ATS scheduling */
189 sched_ats = GNUNET_ATS_scheduling_init (cfg, &address_suggest_cb, NULL);
190 if (sched_ats == NULL)
191 {
192 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Could not connect to ATS scheduling!\n");
193 GNUNET_SCHEDULER_add_now (&end_badly, NULL);
194 return;
195 }
196
197 /* Set up peer */
198 memset (&p.id, '1', sizeof (p.id));
199 /* Prepare ATS Information */
200 test_ats_info[0].type = htonl (GNUNET_ATS_NETWORK_TYPE);
201 test_ats_info[0].value = htonl(GNUNET_ATS_NET_WAN);
202 test_ats_info[1].type = htonl (GNUNET_ATS_QUALITY_NET_DISTANCE);
203 test_ats_info[1].value = htonl(1);
204 test_ats_count = 2;
205
206 /* Adding address without session */
207 test_session = NULL;
208 create_test_address (&test_addr, "test", test_session, "test", strlen ("test") + 1);
209 test_hello_address.peer = p.id;
210 test_hello_address.transport_name = test_addr.plugin;
211 test_hello_address.address = test_addr.addr;
212 test_hello_address.address_length = test_addr.addr_len;
213
214 /* Adding address */
215 GNUNET_ATS_address_add (sched_ats, &test_hello_address, test_session, test_ats_info, test_ats_count);
216}
217
218static void
219run (void *cls,
220 const struct GNUNET_CONFIGURATION_Handle *cfg,
221 struct GNUNET_TESTING_Peer *peer)
222{
223 die_task = GNUNET_SCHEDULER_add_delayed (TIMEOUT, &end_badly, NULL);
224 stats = GNUNET_STATISTICS_create ("ats", cfg);
225 GNUNET_STATISTICS_watch (stats, "ats", "# addresses", &stat_cb, NULL);
226
227 GNUNET_STATISTICS_get (stats, "ats", "# addresses", TIMEOUT,
228 &got_initial_value, &dummy_stat,
229 GNUNET_CONFIGURATION_dup (cfg));
230}
231
232
233int
234main (int argc, char *argv[])
235{
236 ret = 0;
237 if (0 != GNUNET_TESTING_peer_run ("test-ats-api",
238 "test_ats_api.conf",
239 &run, NULL))
240 return 1;
241 return ret;
242}
243
244/* end of file test_ats_api_scheduling_destroy_address.c */
diff --git a/src/ats/test_ats_solver_alternative_after_delete_address.c b/src/ats/test_ats_solver_alternative_after_delete_address.c
index 85216419a..aa04e82d5 100644
--- a/src/ats/test_ats_solver_alternative_after_delete_address.c
+++ b/src/ats/test_ats_solver_alternative_after_delete_address.c
@@ -106,6 +106,16 @@ static struct GNUNET_HELLO_Address *first_suggestion = NULL;
106 106
107static struct GNUNET_HELLO_Address *second_suggestion = NULL; 107static struct GNUNET_HELLO_Address *second_suggestion = NULL;
108 108
109/**
110 * 1st Address we will destroy.
111 */
112static struct GNUNET_ATS_AddressRecord *ar;
113
114/**
115 * 2nd Address we will destroy.
116 */
117static struct GNUNET_ATS_AddressRecord *ar2;
118
109 119
110static int 120static int
111stat_cb(void *cls, const char *subsystem, const char *name, uint64_t value, 121stat_cb(void *cls, const char *subsystem, const char *name, uint64_t value,
@@ -198,7 +208,8 @@ address_suggest_cb (void *cls,
198 208
199 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Deleting 1st address for peer `%s' : `%s'\n", 209 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Deleting 1st address for peer `%s' : `%s'\n",
200 GNUNET_i2s (&address->peer), (char *) address->address); 210 GNUNET_i2s (&address->peer), (char *) address->address);
201 GNUNET_ATS_address_destroyed (sched_ats, address, session); 211 GNUNET_ATS_address_destroy (ar);
212 ar = NULL;
202 first_address_deleted = GNUNET_YES; 213 first_address_deleted = GNUNET_YES;
203 214
204 return; 215 return;
@@ -225,7 +236,8 @@ address_suggest_cb (void *cls,
225 236
226 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Deleting 2nd address for peer `%s' : `%s'\n", 237 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Deleting 2nd address for peer `%s' : `%s'\n",
227 GNUNET_i2s (&address->peer), (char *) address->address); 238 GNUNET_i2s (&address->peer), (char *) address->address);
228 GNUNET_ATS_address_destroyed (sched_ats, address, session); 239 GNUNET_ATS_address_destroy (ar2);
240 ar2 = NULL;
229 second_address_deleted = GNUNET_YES; 241 second_address_deleted = GNUNET_YES;
230 return; 242 return;
231 } 243 }
@@ -318,9 +330,11 @@ run (void *cls, const struct GNUNET_CONFIGURATION_Handle *mycfg,
318 330
319 331
320 /* Adding address */ 332 /* Adding address */
321 GNUNET_ATS_address_add (sched_ats, &test_hello_address, NULL, test_ats_info, test_ats_count); 333 ar = GNUNET_ATS_address_add (sched_ats, &test_hello_address, NULL,
334 test_ats_info, test_ats_count);
322 /* Adding alternative address */ 335 /* Adding alternative address */
323 GNUNET_ATS_address_add (sched_ats, &alt_test_hello_address, NULL, test_ats_info, test_ats_count); 336 ar2 = GNUNET_ATS_address_add (sched_ats, &alt_test_hello_address, NULL,
337 test_ats_info, test_ats_count);
324} 338}
325 339
326 340
diff --git a/src/ats/test_ats_solver_request_and_delete_address.c b/src/ats/test_ats_solver_request_and_delete_address.c
index e1dad6dcf..bca340ac1 100644
--- a/src/ats/test_ats_solver_request_and_delete_address.c
+++ b/src/ats/test_ats_solver_request_and_delete_address.c
@@ -85,6 +85,10 @@ struct GNUNET_ATS_Information test_ats_info[2];
85 */ 85 */
86static uint32_t test_ats_count; 86static uint32_t test_ats_count;
87 87
88/**
89 * The address we will delete.
90 */
91static struct GNUNET_ATS_AddressRecord *ar;
88 92
89static int address_deleted = GNUNET_NO; 93static int address_deleted = GNUNET_NO;
90 94
@@ -152,7 +156,8 @@ address_suggest_cb (void *cls,
152 "Received sugggestion for peer `%s', deleting address\n", 156 "Received sugggestion for peer `%s', deleting address\n",
153 GNUNET_i2s (&address->peer)); 157 GNUNET_i2s (&address->peer));
154 address_deleted = GNUNET_YES; 158 address_deleted = GNUNET_YES;
155 GNUNET_ATS_address_destroyed (sched_ats, &test_hello_address, NULL); 159 GNUNET_ATS_address_destroy (ar);
160 ar = NULL;
156 } 161 }
157 else 162 else
158 { 163 {
@@ -231,9 +236,9 @@ run (void *cls,
231 test_hello_address.address_length = test_addr.addr_len; 236 test_hello_address.address_length = test_addr.addr_len;
232 237
233 /* Adding address */ 238 /* Adding address */
234 GNUNET_ATS_address_add (sched_ats, &test_hello_address, 239 ar = GNUNET_ATS_address_add (sched_ats, &test_hello_address,
235 NULL, 240 NULL,
236 test_ats_info, test_ats_count); 241 test_ats_info, test_ats_count);
237} 242}
238 243
239 244
diff --git a/src/include/gnunet_ats_service.h b/src/include/gnunet_ats_service.h
index 271d6009e..74e7c7c80 100644
--- a/src/include/gnunet_ats_service.h
+++ b/src/include/gnunet_ats_service.h
@@ -460,7 +460,7 @@ struct GNUNET_ATS_AddressRecord;
460 * 460 *
461 * @param sh handle 461 * @param sh handle
462 * @param address the address 462 * @param address the address
463 * @param session session handle (if available) 463 * @param session session handle (if available, i.e. for incoming connections)
464 * @param ats performance data for the address 464 * @param ats performance data for the address
465 * @param ats_count number of performance records in @a ats 465 * @param ats_count number of performance records in @a ats
466 * @return handle to the address representation inside ATS, NULL 466 * @return handle to the address representation inside ATS, NULL
@@ -476,6 +476,34 @@ GNUNET_ATS_address_add (struct GNUNET_ATS_SchedulingHandle *sh,
476 476
477 477
478/** 478/**
479 * An address was used to initiate a session.
480 *
481 * @param ar address record to update information for
482 * @param session session handle
483 */
484void
485GNUNET_ATS_address_add_session (struct GNUNET_ATS_AddressRecord *ar,
486 struct Session *session);
487
488
489/**
490 * A session was destroyed, disassociate it from the
491 * given address record. If this was an incoming
492 * addess, destroy the address as well.
493 *
494 * @param ar address record to update information for
495 * @param session session handle
496 * @return #GNUNET_YES if the @a ar was destroyed because
497 * it was an incoming address,
498 * #GNUNET_NO if the @ar was kept because we can
499 * use it still to establish a new session
500 */
501int
502GNUNET_ATS_address_del_session (struct GNUNET_ATS_AddressRecord *ar,
503 struct Session *session);
504
505
506/**
479 * We have updated performance statistics for a given address. Note 507 * We have updated performance statistics for a given address. Note
480 * that this function can be called for addresses that are currently 508 * that this function can be called for addresses that are currently
481 * in use as well as addresses that are valid but not actively in use. 509 * in use as well as addresses that are valid but not actively in use.
@@ -486,47 +514,36 @@ GNUNET_ATS_address_add (struct GNUNET_ATS_SchedulingHandle *sh,
486 * suggest to switch addresses. 514 * suggest to switch addresses.
487 * 515 *
488 * @param ar address record to update information for 516 * @param ar address record to update information for
489 * @param session session handle (if available)
490 * @param ats performance data for the address 517 * @param ats performance data for the address
491 * @param ats_count number of performance records in @a ats 518 * @param ats_count number of performance records in @a ats
492 */ 519 */
493void 520void
494GNUNET_ATS_address_update (struct GNUNET_ATS_AddressRecord *ar, 521GNUNET_ATS_address_update (struct GNUNET_ATS_AddressRecord *ar,
495 struct Session *session,
496 const struct GNUNET_ATS_Information *ats, 522 const struct GNUNET_ATS_Information *ats,
497 uint32_t ats_count); 523 uint32_t ats_count);
498 524
499 525
500/** 526/**
501 * An address is now in use or not used any more. 527 * An address is now in use, or not used any more.
502 * 528 *
503 * @param sh handle 529 * @param ar address record for which to toggle the flag
504 * @param address the address
505 * @param session session handle
506 * @param in_use #GNUNET_YES if this address is now used, #GNUNET_NO 530 * @param in_use #GNUNET_YES if this address is now used, #GNUNET_NO
507 * if address is not used any more 531 * if address is not used any more
508 */ 532 */
509void 533void
510GNUNET_ATS_address_in_use (struct GNUNET_ATS_SchedulingHandle *sh, 534GNUNET_ATS_address_set_in_use (struct GNUNET_ATS_AddressRecord *ar,
511 const struct GNUNET_HELLO_Address *address, 535 int in_use);
512 struct Session *session,
513 int in_use);
514 536
515 537
516/** 538/**
517 * An address got destroyed, stop including it as a valid address. 539 * An address got destroyed, stop using it as a valid address.
518 *
519 * If a session is given, only the session will be removed, if no session is
520 * given the full address will be deleted.
521 * 540 *
522 * @param sh handle 541 * @param ar address record to destroy, it's validation has
523 * @param address the address 542 * expired and ATS may no longer use it
524 * @param session session handle that is no longer valid (if available)
525 */ 543 */
526void 544void
527GNUNET_ATS_address_destroyed (struct GNUNET_ATS_SchedulingHandle *sh, 545GNUNET_ATS_address_destroy (struct GNUNET_ATS_AddressRecord *ar);
528 const struct GNUNET_HELLO_Address *address, 546
529 struct Session *session);
530 547
531 548
532/* ******************************** Performance API ***************************** */ 549/* ******************************** Performance API ***************************** */
diff --git a/src/transport/gnunet-service-transport_ats.c b/src/transport/gnunet-service-transport_ats.c
index c6975e526..4fcf7c9dc 100644
--- a/src/transport/gnunet-service-transport_ats.c
+++ b/src/transport/gnunet-service-transport_ats.c
@@ -254,11 +254,8 @@ GST_ats_new_session (const struct GNUNET_HELLO_Address *address,
254 "Telling ATS about new session %p for peer %s\n", 254 "Telling ATS about new session %p for peer %s\n",
255 session, 255 session,
256 GNUNET_i2s (&address->peer)); 256 GNUNET_i2s (&address->peer));
257 // FIXME: tell ATS API, but not using this call: 257 GNUNET_ATS_address_add_session (ai->ar,
258 GNUNET_ATS_address_update (ai->ar, 258 session);
259 session,
260 NULL, 0);
261
262} 259}
263 260
264 261
@@ -300,14 +297,12 @@ GST_ats_del_session (const struct GNUNET_HELLO_Address *address,
300 "Telling ATS to destroy session %p from peer %s\n", 297 "Telling ATS to destroy session %p from peer %s\n",
301 session, 298 session,
302 GNUNET_i2s (&address->peer)); 299 GNUNET_i2s (&address->peer));
303 /* FIXME: if this was an *inbound* address, destroy it
304 FULLY here well; but use different API, as looking up
305 inbound address without session is not great... */
306 GNUNET_ATS_address_destroyed (GST_ats, address, session);
307 if (GNUNET_YES == 300 if (GNUNET_YES ==
308 GNUNET_HELLO_address_check_option (address, 301 GNUNET_ATS_address_del_session (ai->ar, session))
309 GNUNET_HELLO_ADDRESS_INFO_INBOUND)) 302 {
303 ai->ar = NULL;
310 GST_ats_expire_address (address); 304 GST_ats_expire_address (address);
305 }
311} 306}
312 307
313 308
@@ -355,13 +350,36 @@ GST_ats_update_metrics (const struct GNUNET_HELLO_Address *address,
355 ats, 350 ats,
356 ats_count); 351 ats_count);
357 GNUNET_ATS_address_update (ai->ar, 352 GNUNET_ATS_address_update (ai->ar,
358 session,
359 ats_new, ats_count); 353 ats_new, ats_count);
360 GNUNET_free_non_null (ats_new); 354 GNUNET_free_non_null (ats_new);
361} 355}
362 356
363 357
364/** 358/**
359 * Notify ATS about a new session now being in use (or not).
360 *
361 * @param address the address
362 * @param session the session
363 * @param in_use #GNUNET_YES or #GNUNET_NO
364 */
365void
366GST_ats_set_in_use (const struct GNUNET_HELLO_Address *address,
367 struct Session *session,
368 int in_use)
369{
370 struct AddressInfo *ai;
371
372 ai = find_ai (address, session);
373 if (NULL == ai)
374 {
375 GNUNET_break (0);
376 return;
377 }
378 GNUNET_ATS_address_set_in_use (ai->ar, in_use);
379}
380
381
382/**
365 * Notify ATS that the address has expired and thus cannot 383 * Notify ATS that the address has expired and thus cannot
366 * be used any longer. This function must only be called 384 * be used any longer. This function must only be called
367 * if the corresponding session is already gone. 385 * if the corresponding session is already gone.
@@ -388,7 +406,8 @@ GST_ats_expire_address (const struct GNUNET_HELLO_Address *address)
388 "transport-ats", 406 "transport-ats",
389 "Telling ATS to destroy address from peer %s\n", 407 "Telling ATS to destroy address from peer %s\n",
390 GNUNET_i2s (&address->peer)); 408 GNUNET_i2s (&address->peer));
391 GNUNET_ATS_address_destroyed (GST_ats, address, NULL); 409 if (NULL != ai->ar)
410 GNUNET_ATS_address_destroy (ai->ar);
392 GNUNET_HELLO_address_free (ai->address); 411 GNUNET_HELLO_address_free (ai->address);
393 GNUNET_free (ai); 412 GNUNET_free (ai);
394} 413}
diff --git a/src/transport/gnunet-service-transport_ats.h b/src/transport/gnunet-service-transport_ats.h
index c7b826484..b066ad74f 100644
--- a/src/transport/gnunet-service-transport_ats.h
+++ b/src/transport/gnunet-service-transport_ats.h
@@ -79,6 +79,19 @@ GST_ats_new_session (const struct GNUNET_HELLO_Address *address,
79 79
80 80
81/** 81/**
82 * Notify ATS about a new session now being in use (or not).
83 *
84 * @param address the address
85 * @param session the session
86 * @param in_use #GNUNET_YES or #GNUNET_NO
87 */
88void
89GST_ats_set_in_use (const struct GNUNET_HELLO_Address *address,
90 struct Session *session,
91 int in_use);
92
93
94/**
82 * Notify ATS about property changes to an address 95 * Notify ATS about property changes to an address
83 * 96 *
84 * @param address the address 97 * @param address the address
diff --git a/src/transport/gnunet-service-transport_neighbours.c b/src/transport/gnunet-service-transport_neighbours.c
index 40bad6d75..aca86535f 100644
--- a/src/transport/gnunet-service-transport_neighbours.c
+++ b/src/transport/gnunet-service-transport_neighbours.c
@@ -631,8 +631,12 @@ free_address (struct NeighbourAddress *na)
631{ 631{
632 if (GNUNET_YES == na->ats_active) 632 if (GNUNET_YES == na->ats_active)
633 { 633 {
634 GST_validation_set_address_use (na->address, na->session, GNUNET_NO); 634 GST_validation_set_address_use (na->address,
635 GNUNET_ATS_address_in_use (GST_ats, na->address, na->session, GNUNET_NO); 635 na->session,
636 GNUNET_NO);
637 GST_ats_set_in_use (na->address,
638 na->session,
639 GNUNET_NO);
636 } 640 }
637 641
638 na->bandwidth_in = GNUNET_BANDWIDTH_value_init (0); 642 na->bandwidth_in = GNUNET_BANDWIDTH_value_init (0);
@@ -816,10 +820,9 @@ set_primary_address (struct NeighbourMapEntry *n,
816 if (is_active != n->primary_address.ats_active) 820 if (is_active != n->primary_address.ats_active)
817 { 821 {
818 n->primary_address.ats_active = is_active; 822 n->primary_address.ats_active = is_active;
819 GNUNET_ATS_address_in_use (GST_ats, 823 GST_ats_set_in_use (n->primary_address.address,
820 n->primary_address.address, 824 n->primary_address.session,
821 n->primary_address.session, 825 is_active);
822 is_active);
823 GST_validation_set_address_use (n->primary_address.address, 826 GST_validation_set_address_use (n->primary_address.address,
824 n->primary_address.session, 827 n->primary_address.session,
825 is_active); 828 is_active);
@@ -855,10 +858,9 @@ set_primary_address (struct NeighbourMapEntry *n,
855 if (GNUNET_YES == is_active) 858 if (GNUNET_YES == is_active)
856 { 859 {
857 /* Telling ATS about new session */ 860 /* Telling ATS about new session */
858 GNUNET_ATS_address_in_use (GST_ats, 861 GST_ats_set_in_use (n->primary_address.address,
859 n->primary_address.address, 862 n->primary_address.session,
860 n->primary_address.session, 863 GNUNET_YES);
861 GNUNET_YES);
862 GST_validation_set_address_use (n->primary_address.address, 864 GST_validation_set_address_use (n->primary_address.address,
863 n->primary_address.session, 865 n->primary_address.session,
864 GNUNET_YES); 866 GNUNET_YES);