aboutsummaryrefslogtreecommitdiff
path: root/src/ats
diff options
context:
space:
mode:
authorMatthias Wachs <wachs@net.in.tum.de>2012-06-14 12:50:27 +0000
committerMatthias Wachs <wachs@net.in.tum.de>2012-06-14 12:50:27 +0000
commitc18fcd88d8897d0645900a1b6f527232d0153f88 (patch)
tree445441c0ac27a28e747757d7d347c8f44e1df72f /src/ats
parent21f92c1b07d8361c270fa08f9f41d78a3e8e18b3 (diff)
downloadgnunet-c18fcd88d8897d0645900a1b6f527232d0153f88.tar.gz
gnunet-c18fcd88d8897d0645900a1b6f527232d0153f88.zip
- adding GNUNET_ATS_address_add functionality .. no changes to scheduling API yet
Diffstat (limited to 'src/ats')
-rw-r--r--src/ats/Makefile.am8
-rw-r--r--src/ats/ats_api_scheduling.c115
-rw-r--r--src/ats/gnunet-service-ats.c2
-rw-r--r--src/ats/gnunet-service-ats_addresses.c71
-rw-r--r--src/ats/gnunet-service-ats_addresses.h6
-rw-r--r--src/ats/gnunet-service-ats_scheduling.c58
-rw-r--r--src/ats/gnunet-service-ats_scheduling.h12
-rw-r--r--src/ats/test_ats_api_scheduling_add_address.c226
8 files changed, 495 insertions, 3 deletions
diff --git a/src/ats/Makefile.am b/src/ats/Makefile.am
index bf0d1c2db..5b1c6b2e4 100644
--- a/src/ats/Makefile.am
+++ b/src/ats/Makefile.am
@@ -56,6 +56,7 @@ gnunet_service_ats_LDADD = \
56check_PROGRAMS = \ 56check_PROGRAMS = \
57 test_ats_api_scheduling \ 57 test_ats_api_scheduling \
58 test_ats_api_reset_backoff \ 58 test_ats_api_reset_backoff \
59 test_ats_api_scheduling_add_address \
59 $(GN_MLP_TEST) \ 60 $(GN_MLP_TEST) \
60 $(GN_MLP_TEST_AVG) \ 61 $(GN_MLP_TEST_AVG) \
61 $(GN_MLP_PERF) 62 $(GN_MLP_PERF)
@@ -104,6 +105,13 @@ test_ats_api_reset_backoff_LDADD = \
104 $(top_builddir)/src/util/libgnunetutil.la \ 105 $(top_builddir)/src/util/libgnunetutil.la \
105 $(top_builddir)/src/ats/libgnunetats.la 106 $(top_builddir)/src/ats/libgnunetats.la
106 107
108test_ats_api_scheduling_add_address_SOURCES = \
109 test_ats_api_scheduling_add_address.c
110test_ats_api_scheduling_add_address_LDADD = \
111 $(top_builddir)/src/util/libgnunetutil.la \
112 $(top_builddir)/src/ats/libgnunetats.la
113
114
107#test_ats_api_scheduling_get_type_SOURCES = \ 115#test_ats_api_scheduling_get_type_SOURCES = \
108# test_ats_api_scheduling_get_type.c 116# test_ats_api_scheduling_get_type.c
109#test_ats_api_scheduling_get_type_LDADD = \ 117#test_ats_api_scheduling_get_type_LDADD = \
diff --git a/src/ats/ats_api_scheduling.c b/src/ats/ats_api_scheduling.c
index 0e67a8628..cdf948291 100644
--- a/src/ats/ats_api_scheduling.c
+++ b/src/ats/ats_api_scheduling.c
@@ -1049,6 +1049,101 @@ GNUNET_ATS_suggest_address_cancel (struct GNUNET_ATS_SchedulingHandle *sh,
1049 1049
1050 1050
1051/** 1051/**
1052 * We have a new address ATS should know. Addresses have to be added with this
1053 * function before they can be: updated, set in use and destroyed
1054 *
1055 * @param sh handle
1056 * @param address the address
1057 * @param session session handle (if available)
1058 * @param ats performance data for the address
1059 * @param ats_count number of performance records in 'ats'
1060 * @return GNUNET_OK on success, GNUNET_SYSERR on error
1061 */
1062int
1063GNUNET_ATS_address_add (struct GNUNET_ATS_SchedulingHandle *sh,
1064 const struct GNUNET_HELLO_Address *address,
1065 struct Session *session,
1066 const struct GNUNET_ATS_Information *ats,
1067 uint32_t ats_count)
1068{
1069
1070 struct PendingMessage *p;
1071 struct AddressUpdateMessage *m;
1072 struct GNUNET_ATS_Information *am;
1073 char *pm;
1074 size_t namelen;
1075 size_t msize;
1076 uint32_t s = 0;
1077
1078 if (address == NULL)
1079 {
1080 GNUNET_break (0);
1081 return GNUNET_SYSERR;
1082 }
1083 if ((address == NULL) && (session == NULL))
1084 {
1085 GNUNET_break (0);
1086 return GNUNET_SYSERR;
1087 }
1088
1089 namelen =
1090 (address->transport_name ==
1091 NULL) ? 0 : strlen (address->transport_name) + 1;
1092 msize =
1093 sizeof (struct AddressUpdateMessage) + address->address_length +
1094 ats_count * sizeof (struct GNUNET_ATS_Information) + namelen;
1095 if ((msize >= GNUNET_SERVER_MAX_MESSAGE_SIZE) ||
1096 (address->address_length >= GNUNET_SERVER_MAX_MESSAGE_SIZE) ||
1097 (namelen >= GNUNET_SERVER_MAX_MESSAGE_SIZE) ||
1098 (ats_count >=
1099 GNUNET_SERVER_MAX_MESSAGE_SIZE / sizeof (struct GNUNET_ATS_Information)))
1100 {
1101 GNUNET_break (0);
1102 return GNUNET_SYSERR;
1103 }
1104
1105 p = GNUNET_malloc (sizeof (struct PendingMessage) + msize);
1106 p->size = msize;
1107 p->is_init = GNUNET_NO;
1108 m = (struct AddressUpdateMessage *) &p[1];
1109 m->header.type = htons (GNUNET_MESSAGE_TYPE_ATS_ADDRESS_ADD);
1110 m->header.size = htons (msize);
1111 m->ats_count = htonl (ats_count);
1112 m->peer = address->peer;
1113 m->address_length = htons (address->address_length);
1114 m->plugin_name_length = htons (namelen);
1115 if (NULL != session)
1116 {
1117 s = find_session_id (sh, session, &address->peer);
1118 if (NOT_FOUND != s)
1119 {
1120 /* Already existing */
1121 GNUNET_break (0);
1122 return GNUNET_SYSERR;
1123 }
1124 s = find_empty_session_slot (sh, session, &address->peer);
1125 GNUNET_break (NOT_FOUND != s);
1126 }
1127 m->session_id = htonl (s);
1128
1129 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1130 "Adding address for peer `%s', plugin `%s', session %p id %u\n",
1131 GNUNET_i2s (&address->peer),
1132 address->transport_name, session, s);
1133
1134 am = (struct GNUNET_ATS_Information *) &m[1];
1135 memcpy (am, ats, ats_count * sizeof (struct GNUNET_ATS_Information));
1136 pm = (char *) &am[ats_count];
1137 memcpy (pm, address->address, address->address_length);
1138 memcpy (&pm[address->address_length], address->transport_name, namelen);
1139 GNUNET_CONTAINER_DLL_insert_tail (sh->pending_head, sh->pending_tail, p);
1140 do_transmit (sh);
1141 return GNUNET_OK;
1142
1143}
1144
1145
1146/**
1052 * We have updated performance statistics for a given address. Note 1147 * We have updated performance statistics for a given address. Note
1053 * that this function can be called for addresses that are currently 1148 * that this function can be called for addresses that are currently
1054 * in use as well as addresses that are valid but not actively in use. 1149 * in use as well as addresses that are valid but not actively in use.
@@ -1127,6 +1222,11 @@ GNUNET_ATS_address_update (struct GNUNET_ATS_SchedulingHandle *sh,
1127 } 1222 }
1128 m->session_id = htonl (s); 1223 m->session_id = htonl (s);
1129 1224
1225 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1226 "Trying to update address for peer `%s', plugin `%s', session %p id %u\n",
1227 GNUNET_i2s (&address->peer),
1228 address->transport_name, session, s);
1229
1130 am = (struct GNUNET_ATS_Information *) &m[1]; 1230 am = (struct GNUNET_ATS_Information *) &m[1];
1131 memcpy (am, ats, ats_count * sizeof (struct GNUNET_ATS_Information)); 1231 memcpy (am, ats, ats_count * sizeof (struct GNUNET_ATS_Information));
1132 pm = (char *) &am[ats_count]; 1232 pm = (char *) &am[ats_count];
@@ -1172,6 +1272,12 @@ GNUNET_ATS_address_in_use (struct GNUNET_ATS_SchedulingHandle *sh,
1172 return; 1272 return;
1173 } 1273 }
1174 1274
1275 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
1276 "Trying to set address to %s for peer `%s', plugin `%s', session %p\n",
1277 GNUNET_i2s (&address->peer),
1278 (GNUNET_NO == in_use) ? "NO" : "YES",
1279 address->transport_name, session);
1280
1175 p = GNUNET_malloc (sizeof (struct PendingMessage) + msize); 1281 p = GNUNET_malloc (sizeof (struct PendingMessage) + msize);
1176 p->size = msize; 1282 p->size = msize;
1177 p->is_init = GNUNET_NO; 1283 p->is_init = GNUNET_NO;
@@ -1260,12 +1366,17 @@ GNUNET_ATS_address_destroyed (struct GNUNET_ATS_SchedulingHandle *sh,
1260 if ((NULL != session) && (NOT_FOUND == s)) 1366 if ((NULL != session) && (NOT_FOUND == s))
1261 { 1367 {
1262 /* trying to delete unknown address */ 1368 /* trying to delete unknown address */
1263 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, 1369 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1264 "Trying to delete unknown address for peer `%s', plugin `%s', session %p\n", 1370 "Trying to delete unknown address for peer `%s', plugin `%s', session %p\n",
1265 GNUNET_i2s (&address->peer), address->transport_name, session); 1371 GNUNET_i2s (&address->peer), address->transport_name, session);
1266 GNUNET_break (0);
1267 return; 1372 return;
1268 } 1373 }
1374 else
1375 {
1376 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
1377 "Deleting address for peer `%s', plugin `%s', session %p\n",
1378 GNUNET_i2s (&address->peer), address->transport_name, session);
1379 }
1269 1380
1270 m->session_id = htonl (s); 1381 m->session_id = htonl (s);
1271 pm = (char *) &m[1]; 1382 pm = (char *) &m[1];
diff --git a/src/ats/gnunet-service-ats.c b/src/ats/gnunet-service-ats.c
index aef72f171..8f2e45d5d 100644
--- a/src/ats/gnunet-service-ats.c
+++ b/src/ats/gnunet-service-ats.c
@@ -142,6 +142,8 @@ run (void *cls, struct GNUNET_SERVER_Handle *server,
142 {&GAS_handle_request_address_cancel, NULL, 142 {&GAS_handle_request_address_cancel, NULL,
143 GNUNET_MESSAGE_TYPE_ATS_REQUEST_ADDRESS_CANCEL, 143 GNUNET_MESSAGE_TYPE_ATS_REQUEST_ADDRESS_CANCEL,
144 sizeof (struct RequestAddressMessage)}, 144 sizeof (struct RequestAddressMessage)},
145 {&GAS_handle_address_add, NULL,
146 GNUNET_MESSAGE_TYPE_ATS_ADDRESS_ADD, 0},
145 {&GAS_handle_address_update, NULL, 147 {&GAS_handle_address_update, NULL,
146 GNUNET_MESSAGE_TYPE_ATS_ADDRESS_UPDATE, 0}, 148 GNUNET_MESSAGE_TYPE_ATS_ADDRESS_UPDATE, 0},
147 {&GAS_handle_address_in_use, NULL, 149 {&GAS_handle_address_in_use, NULL,
diff --git a/src/ats/gnunet-service-ats_addresses.c b/src/ats/gnunet-service-ats_addresses.c
index 97475ad19..854716dc7 100644
--- a/src/ats/gnunet-service-ats_addresses.c
+++ b/src/ats/gnunet-service-ats_addresses.c
@@ -330,6 +330,70 @@ find_exact_address (const struct GNUNET_PeerIdentity *peer,
330 330
331 331
332void 332void
333GAS_addresses_add (const struct GNUNET_PeerIdentity *peer,
334 const char *plugin_name, const void *plugin_addr,
335 size_t plugin_addr_len, uint32_t session_id,
336 const struct GNUNET_ATS_Information *atsi,
337 uint32_t atsi_count)
338{
339 struct ATS_Address *aa;
340 struct ATS_Address *old;
341
342 if (GNUNET_NO == running)
343 return;
344
345 GNUNET_assert (NULL != addresses);
346
347 aa = create_address (peer,
348 plugin_name,
349 plugin_addr, plugin_addr_len,
350 session_id);
351
352 aa->mlp_information = NULL;
353 aa->ats = GNUNET_malloc (atsi_count * sizeof (struct GNUNET_ATS_Information));
354 aa->ats_count = atsi_count;
355 memcpy (aa->ats, atsi, atsi_count * sizeof (struct GNUNET_ATS_Information));
356
357 /* Get existing address or address with session == 0 */
358 old = find_address (peer, aa);
359 if (old == NULL)
360 {
361 /* We have a new address */
362 GNUNET_assert (GNUNET_OK ==
363 GNUNET_CONTAINER_multihashmap_put (addresses,
364 &peer->hashPubKey, aa,
365 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE));
366 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Added new address for peer `%s' %p\n",
367 GNUNET_i2s (peer), aa);
368 return;
369 }
370
371 if (old->session_id == 0)
372 {
373 /* We have a base address with out an session, update this address */
374 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
375 "Updated existing address for peer `%s' %p with new session %u\n",
376 GNUNET_i2s (peer), old, session_id);
377 GNUNET_free_non_null (old->ats);
378 old->session_id = session_id;
379 old->ats = NULL;
380 old->ats_count = 0;
381 old->ats = aa->ats;
382 old->ats_count = aa->ats_count;
383 GNUNET_free (aa->plugin);
384 GNUNET_free (aa);
385 return;
386 }
387
388 /* This address and session is already existing */
389 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
390 "Added already existing address for peer `%s' `%s' %p with new session %u\n",
391 GNUNET_i2s (peer), plugin_name, session_id);
392 GNUNET_break (0);
393}
394
395
396void
333GAS_addresses_update (const struct GNUNET_PeerIdentity *peer, 397GAS_addresses_update (const struct GNUNET_PeerIdentity *peer,
334 const char *plugin_name, const void *plugin_addr, 398 const char *plugin_name, const void *plugin_addr,
335 size_t plugin_addr_len, uint32_t session_id, 399 size_t plugin_addr_len, uint32_t session_id,
@@ -368,7 +432,7 @@ GAS_addresses_update (const struct GNUNET_PeerIdentity *peer,
368 &peer->hashPubKey, aa, 432 &peer->hashPubKey, aa,
369 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE)); 433 GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE));
370#if DEBUG_ATS 434#if DEBUG_ATS
371 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Added new address for peer `%s' %X\n", 435 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Added new address for peer `%s' %p\n",
372 GNUNET_i2s (peer), aa); 436 GNUNET_i2s (peer), aa);
373#endif 437#endif
374 old = aa; 438 old = aa;
@@ -640,6 +704,11 @@ GAS_addresses_in_use (const struct GNUNET_PeerIdentity *peer,
640 704
641 if (NULL == old) 705 if (NULL == old)
642 { 706 {
707 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
708 "Unknown address `%s', %s %u %s \n",
709 GNUNET_i2s (peer),
710 plugin_name, session_id,
711 (GNUNET_NO == in_use) ? "NO" : "YES");
643 GNUNET_break (0); 712 GNUNET_break (0);
644 return GNUNET_SYSERR; 713 return GNUNET_SYSERR;
645 } 714 }
diff --git a/src/ats/gnunet-service-ats_addresses.h b/src/ats/gnunet-service-ats_addresses.h
index fe07563ac..866d25663 100644
--- a/src/ats/gnunet-service-ats_addresses.h
+++ b/src/ats/gnunet-service-ats_addresses.h
@@ -156,6 +156,12 @@ GAS_addresses_change_preference (const struct GNUNET_PeerIdentity *peer,
156 enum GNUNET_ATS_PreferenceKind kind, 156 enum GNUNET_ATS_PreferenceKind kind,
157 float score); 157 float score);
158 158
159void
160GAS_addresses_add (const struct GNUNET_PeerIdentity *peer,
161 const char *plugin_name, const void *plugin_addr,
162 size_t plugin_addr_len, uint32_t session_id,
163 const struct GNUNET_ATS_Information *atsi,
164 uint32_t atsi_count);
159 165
160/* FIXME: add performance request API */ 166/* FIXME: add performance request API */
161 167
diff --git a/src/ats/gnunet-service-ats_scheduling.c b/src/ats/gnunet-service-ats_scheduling.c
index 0b66ac566..a4c04275f 100644
--- a/src/ats/gnunet-service-ats_scheduling.c
+++ b/src/ats/gnunet-service-ats_scheduling.c
@@ -222,6 +222,64 @@ GAS_handle_reset_backoff (void *cls,
222 GNUNET_SERVER_receive_done (client, GNUNET_OK); 222 GNUNET_SERVER_receive_done (client, GNUNET_OK);
223} 223}
224 224
225/**
226 * Handle 'address add' messages from clients.
227 *
228 * @param cls unused, NULL
229 * @param client client that sent the request
230 * @param message the request message
231 */
232void
233GAS_handle_address_add (void *cls, struct GNUNET_SERVER_Client *client,
234 const struct GNUNET_MessageHeader *message)
235{
236 const struct AddressUpdateMessage *m;
237 const struct GNUNET_ATS_Information *atsi;
238 const char *address;
239 const char *plugin_name;
240 uint16_t address_length;
241 uint16_t plugin_name_length;
242 uint32_t ats_count;
243 uint16_t size;
244
245 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Received `%s' message\n",
246 "ADDRESS_ADD");
247 size = ntohs (message->size);
248 if (size < sizeof (struct AddressUpdateMessage))
249 {
250 GNUNET_break (0);
251 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
252 return;
253 }
254 m = (const struct AddressUpdateMessage *) message;
255 ats_count = ntohl (m->ats_count);
256 address_length = ntohs (m->address_length);
257 plugin_name_length = ntohs (m->plugin_name_length);
258 atsi = (const struct GNUNET_ATS_Information *) &m[1];
259 address = (const char *) &atsi[ats_count];
260 if (plugin_name_length != 0)
261 plugin_name = &address[address_length];
262 else
263 plugin_name = "";
264
265 if ((address_length + plugin_name_length +
266 ats_count * sizeof (struct GNUNET_ATS_Information) +
267 sizeof (struct AddressUpdateMessage) != ntohs (message->size)) ||
268 (ats_count >
269 GNUNET_SERVER_MAX_MESSAGE_SIZE / sizeof (struct GNUNET_ATS_Information)) ||
270 ((plugin_name_length > 0) && (plugin_name[plugin_name_length - 1] != '\0')))
271 {
272 GNUNET_break (0);
273 GNUNET_SERVER_receive_done (client, GNUNET_SYSERR);
274 return;
275 }
276 GNUNET_STATISTICS_update (GSA_stats, "# address updates received", 1,
277 GNUNET_NO);
278 GAS_addresses_add (&m->peer, plugin_name, address, address_length,
279 ntohl (m->session_id), atsi, ats_count);
280 GNUNET_SERVER_receive_done (client, GNUNET_OK);
281}
282
225 283
226/** 284/**
227 * Handle 'address update' messages from clients. 285 * Handle 'address update' messages from clients.
diff --git a/src/ats/gnunet-service-ats_scheduling.h b/src/ats/gnunet-service-ats_scheduling.h
index 08a7f1b33..48c301d19 100644
--- a/src/ats/gnunet-service-ats_scheduling.h
+++ b/src/ats/gnunet-service-ats_scheduling.h
@@ -115,6 +115,18 @@ GAS_handle_request_address_cancel (void *cls,
115 struct GNUNET_SERVER_Client *client, 115 struct GNUNET_SERVER_Client *client,
116 const struct GNUNET_MessageHeader *message); 116 const struct GNUNET_MessageHeader *message);
117 117
118
119/**
120 * Handle 'address add' messages from clients.
121 *
122 * @param cls unused, NULL
123 * @param client client that sent the request
124 * @param message the request message
125 */
126void
127GAS_handle_address_add (void *cls, struct GNUNET_SERVER_Client *client,
128 const struct GNUNET_MessageHeader *message);
129
118/** 130/**
119 * Handle 'address update' messages from clients. 131 * Handle 'address update' messages from clients.
120 * 132 *
diff --git a/src/ats/test_ats_api_scheduling_add_address.c b/src/ats/test_ats_api_scheduling_add_address.c
new file mode 100644
index 000000000..04ece4044
--- /dev/null
+++ b/src/ats/test_ats_api_scheduling_add_address.c
@@ -0,0 +1,226 @@
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.c
22 * @brief test automatic transport selection scheduling API
23 * @author Christian Grothoff
24 * @author Matthias Wachs
25 *
26 * TODO:
27 * - write test case
28 * - extend API to get performance data
29 * - implement simplistic strategy based on say 'lowest latency' or strict ordering
30 * - extend API to get peer preferences, implement proportional bandwidth assignment
31 * - re-implement API against a real ATS service (!)
32 */
33#include "platform.h"
34#include "gnunet_ats_service.h"
35#include "ats.h"
36
37#define TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 10)
38
39static GNUNET_SCHEDULER_TaskIdentifier die_task;
40
41static struct GNUNET_ATS_SchedulingHandle *ats;
42
43struct GNUNET_OS_Process *arm_proc;
44
45
46
47static int ret;
48
49struct Address
50{
51 char *plugin;
52 size_t plugin_len;
53
54 void *addr;
55 size_t addr_len;
56
57 struct GNUNET_ATS_Information *ats;
58 int ats_count;
59
60 void *session;
61};
62
63struct PeerContext
64{
65 struct GNUNET_PeerIdentity id;
66
67 struct Address *addr;
68};
69
70struct Address addr;
71struct PeerContext p;
72struct GNUNET_ATS_Information atsi;
73
74static void
75stop_arm ()
76{
77 if (0 != GNUNET_OS_process_kill (arm_proc, SIGTERM))
78 GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "kill");
79 GNUNET_OS_process_wait (arm_proc);
80 GNUNET_OS_process_destroy (arm_proc);
81 arm_proc = NULL;
82}
83
84
85static void
86end_badly (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
87{
88 die_task = GNUNET_SCHEDULER_NO_TASK;
89 if (ats != NULL)
90 GNUNET_ATS_scheduling_done (ats);
91
92 ret = GNUNET_SYSERR;
93
94 stop_arm ();
95}
96
97
98static void
99end ()
100{
101 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Shutting down\n");
102 if (die_task != GNUNET_SCHEDULER_NO_TASK)
103 {
104 GNUNET_SCHEDULER_cancel (die_task);
105 die_task = GNUNET_SCHEDULER_NO_TASK;
106 }
107
108 GNUNET_ATS_scheduling_done (ats);
109
110 ret = 0;
111
112 stop_arm ();
113}
114
115
116static void
117address_suggest_cb (void *cls, const struct GNUNET_HELLO_Address *address,
118 struct Session *session,
119 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_out,
120 struct GNUNET_BANDWIDTH_Value32NBO bandwidth_in,
121 const struct GNUNET_ATS_Information *ats,
122 uint32_t ats_count)
123{
124 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "ATS suggests address `%s'\n",
125 GNUNET_i2s (&address->peer));
126
127 GNUNET_assert (0 ==
128 memcmp (&address->peer, &p.id,
129 sizeof (struct GNUNET_PeerIdentity)));
130 GNUNET_assert (0 == strcmp (address->transport_name, addr.plugin));
131 GNUNET_assert (address->address_length == addr.addr_len);
132 GNUNET_assert (0 ==
133 memcmp (address->address, addr.plugin,
134 address->address_length));
135 GNUNET_assert (addr.session == session);
136
137 ret = 0;
138
139 GNUNET_SCHEDULER_add_now (&end, NULL);
140}
141
142void
143start_arm (const char *cfgname)
144{
145 arm_proc =
146 GNUNET_OS_start_process (GNUNET_YES, NULL, NULL, "gnunet-service-arm",
147 "gnunet-service-arm",
148 "-c", cfgname, NULL);
149}
150
151static void
152check (void *cls, char *const *args, const char *cfgfile,
153 const struct GNUNET_CONFIGURATION_Handle *cfg)
154{
155 struct GNUNET_HELLO_Address address0;
156
157 ret = GNUNET_SYSERR;
158
159 die_task = GNUNET_SCHEDULER_add_delayed (TIMEOUT, &end_badly, NULL);
160 start_arm (cfgfile);
161
162 ats = GNUNET_ATS_scheduling_init (cfg, &address_suggest_cb, NULL);
163
164 if (ats == NULL)
165 {
166 ret = GNUNET_SYSERR;
167 end ();
168 return;
169 }
170
171 /* set up peer */
172 GNUNET_CRYPTO_hash_create_random (GNUNET_CRYPTO_QUALITY_WEAK,
173 &p.id.hashPubKey);
174 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Created peer `%s'\n",
175 GNUNET_i2s (&p.id));
176
177 addr.plugin = "test";
178 addr.session = NULL;
179 addr.addr = GNUNET_strdup ("test");
180 addr.addr_len = 4;
181
182 /* Adding address without session */
183 address0.peer = p.id;
184 address0.transport_name = addr.plugin;
185 address0.address = addr.addr;
186 address0.address_length = addr.addr_len;
187 GNUNET_ATS_address_add (ats, &address0, addr.session, NULL, 0);
188
189 addr.session = &addr;
190 /* Update address with session */
191 GNUNET_ATS_address_add (ats, &address0, addr.session, NULL, 0);
192
193 /* Update address with session */
194 addr.session = &address0;
195 GNUNET_assert (GNUNET_OK == GNUNET_ATS_address_add (ats, &address0, addr.session, NULL, 0));
196 GNUNET_log_skip (2, GNUNET_NO);
197 GNUNET_assert (GNUNET_SYSERR == GNUNET_ATS_address_add (ats, &address0, addr.session, NULL, 0));
198
199 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Requesting peer `%s'\n",
200 GNUNET_i2s (&p.id));
201 GNUNET_ATS_suggest_address (ats, &p.id);
202}
203
204int
205main (int argc, char *argv[])
206{
207 static char *const argv2[] = { "test_ats_api_scheduling_add_address",
208 "-c",
209 "test_ats_api.conf",
210 "-L", "WARNING",
211 NULL
212 };
213
214 static struct GNUNET_GETOPT_CommandLineOption options[] = {
215 GNUNET_GETOPT_OPTION_END
216 };
217
218 GNUNET_PROGRAM_run ((sizeof (argv2) / sizeof (char *)) - 1, argv2,
219 "test_ats_api_scheduling_add_address", "nohelp", options, &check,
220 NULL);
221
222
223 return ret;
224}
225
226/* end of file test_ats_api_scheduling.c */