diff options
author | Matthias Wachs <wachs@net.in.tum.de> | 2012-06-14 12:50:27 +0000 |
---|---|---|
committer | Matthias Wachs <wachs@net.in.tum.de> | 2012-06-14 12:50:27 +0000 |
commit | c18fcd88d8897d0645900a1b6f527232d0153f88 (patch) | |
tree | 445441c0ac27a28e747757d7d347c8f44e1df72f /src/ats | |
parent | 21f92c1b07d8361c270fa08f9f41d78a3e8e18b3 (diff) | |
download | gnunet-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.am | 8 | ||||
-rw-r--r-- | src/ats/ats_api_scheduling.c | 115 | ||||
-rw-r--r-- | src/ats/gnunet-service-ats.c | 2 | ||||
-rw-r--r-- | src/ats/gnunet-service-ats_addresses.c | 71 | ||||
-rw-r--r-- | src/ats/gnunet-service-ats_addresses.h | 6 | ||||
-rw-r--r-- | src/ats/gnunet-service-ats_scheduling.c | 58 | ||||
-rw-r--r-- | src/ats/gnunet-service-ats_scheduling.h | 12 | ||||
-rw-r--r-- | src/ats/test_ats_api_scheduling_add_address.c | 226 |
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 = \ | |||
56 | check_PROGRAMS = \ | 56 | check_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 | ||
108 | test_ats_api_scheduling_add_address_SOURCES = \ | ||
109 | test_ats_api_scheduling_add_address.c | ||
110 | test_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 | */ | ||
1062 | int | ||
1063 | GNUNET_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 | ||
332 | void | 332 | void |
333 | GAS_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 | |||
396 | void | ||
333 | GAS_addresses_update (const struct GNUNET_PeerIdentity *peer, | 397 | GAS_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 | ||
159 | void | ||
160 | GAS_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 | */ | ||
232 | void | ||
233 | GAS_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 | */ | ||
126 | void | ||
127 | GAS_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 | |||
39 | static GNUNET_SCHEDULER_TaskIdentifier die_task; | ||
40 | |||
41 | static struct GNUNET_ATS_SchedulingHandle *ats; | ||
42 | |||
43 | struct GNUNET_OS_Process *arm_proc; | ||
44 | |||
45 | |||
46 | |||
47 | static int ret; | ||
48 | |||
49 | struct 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 | |||
63 | struct PeerContext | ||
64 | { | ||
65 | struct GNUNET_PeerIdentity id; | ||
66 | |||
67 | struct Address *addr; | ||
68 | }; | ||
69 | |||
70 | struct Address addr; | ||
71 | struct PeerContext p; | ||
72 | struct GNUNET_ATS_Information atsi; | ||
73 | |||
74 | static void | ||
75 | stop_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 | |||
85 | static void | ||
86 | end_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 | |||
98 | static void | ||
99 | end () | ||
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 | |||
116 | static void | ||
117 | address_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 | |||
142 | void | ||
143 | start_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 | |||
151 | static void | ||
152 | check (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 | |||
204 | int | ||
205 | main (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 */ | ||