diff options
-rw-r--r-- | src/ats/ats_api_scheduling.c | 136 |
1 files changed, 115 insertions, 21 deletions
diff --git a/src/ats/ats_api_scheduling.c b/src/ats/ats_api_scheduling.c index 5a4e8831f..0e67a8628 100644 --- a/src/ats/ats_api_scheduling.c +++ b/src/ats/ats_api_scheduling.c | |||
@@ -30,6 +30,8 @@ | |||
30 | 30 | ||
31 | #define INTERFACE_PROCESSING_INTERVALL GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 1) | 31 | #define INTERFACE_PROCESSING_INTERVALL GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_SECONDS, 1) |
32 | 32 | ||
33 | #define NOT_FOUND 0 | ||
34 | |||
33 | /** | 35 | /** |
34 | * Message in linked list we should send to the ATS service. The | 36 | * Message in linked list we should send to the ATS service. The |
35 | * actual binary message follows this struct. | 37 | * actual binary message follows this struct. |
@@ -349,8 +351,7 @@ find_session (struct GNUNET_ATS_SchedulingHandle *sh, uint32_t session_id, | |||
349 | 351 | ||
350 | 352 | ||
351 | /** | 353 | /** |
352 | * Get the ID for the given session object. If we do not have an ID for | 354 | * Get an available session ID for the given session object. |
353 | * the given session object, allocate one. | ||
354 | * | 355 | * |
355 | * @param sh our handle | 356 | * @param sh our handle |
356 | * @param session session object | 357 | * @param session session object |
@@ -358,29 +359,21 @@ find_session (struct GNUNET_ATS_SchedulingHandle *sh, uint32_t session_id, | |||
358 | * @return the session id | 359 | * @return the session id |
359 | */ | 360 | */ |
360 | static uint32_t | 361 | static uint32_t |
361 | get_session_id (struct GNUNET_ATS_SchedulingHandle *sh, struct Session *session, | 362 | find_empty_session_slot (struct GNUNET_ATS_SchedulingHandle *sh, struct Session *session, |
362 | const struct GNUNET_PeerIdentity *peer) | 363 | const struct GNUNET_PeerIdentity *peer) |
363 | { | 364 | { |
364 | unsigned int i; | 365 | unsigned int i; |
365 | unsigned int f; | 366 | unsigned int f; |
366 | 367 | ||
367 | |||
368 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "ats-scheduling-api", | 368 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "ats-scheduling-api", |
369 | "Get session ID for session %p from peer %s in %p\n", session, | 369 | "Get session ID for session %p from peer %s in %p\n", session, |
370 | GNUNET_i2s (peer), sh); | 370 | GNUNET_i2s (peer), sh); |
371 | 371 | ||
372 | if (NULL == session) | 372 | if (NULL == session) |
373 | return 0; | 373 | return NOT_FOUND; |
374 | f = 0; | 374 | f = 0; |
375 | for (i = 1; i < sh->session_array_size; i++) | 375 | for (i = 1; i < sh->session_array_size; i++) |
376 | { | 376 | { |
377 | if (session == sh->session_array[i].session) | ||
378 | { | ||
379 | GNUNET_assert (0 == | ||
380 | memcmp (peer, &sh->session_array[i].peer, | ||
381 | sizeof (struct GNUNET_PeerIdentity))); | ||
382 | return i; | ||
383 | } | ||
384 | if ((f == 0) && (sh->session_array[i].slot_used == GNUNET_NO)) | 377 | if ((f == 0) && (sh->session_array[i].slot_used == GNUNET_NO)) |
385 | f = i; | 378 | f = i; |
386 | } | 379 | } |
@@ -391,6 +384,9 @@ get_session_id (struct GNUNET_ATS_SchedulingHandle *sh, struct Session *session, | |||
391 | sh->session_array_size * 2); | 384 | sh->session_array_size * 2); |
392 | } | 385 | } |
393 | GNUNET_assert (f > 0); | 386 | GNUNET_assert (f > 0); |
387 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "ats-scheduling-api", | ||
388 | "Session %p for peer `%s' stored in slot %u \n", | ||
389 | session, GNUNET_i2s (peer), f); | ||
394 | sh->session_array[f].session = session; | 390 | sh->session_array[f].session = session; |
395 | sh->session_array[f].peer = *peer; | 391 | sh->session_array[f].peer = *peer; |
396 | sh->session_array[f].slot_used = GNUNET_YES; | 392 | sh->session_array[f].slot_used = GNUNET_YES; |
@@ -404,6 +400,50 @@ get_session_id (struct GNUNET_ATS_SchedulingHandle *sh, struct Session *session, | |||
404 | 400 | ||
405 | 401 | ||
406 | /** | 402 | /** |
403 | * Get the ID for the given session object. | ||
404 | * | ||
405 | * @param sh our handle | ||
406 | * @param session session object | ||
407 | * @param peer peer the session belongs to | ||
408 | * @return the session id or NOT_FOUND for error | ||
409 | */ | ||
410 | static uint32_t | ||
411 | find_session_id (struct GNUNET_ATS_SchedulingHandle *sh, struct Session *session, | ||
412 | const struct GNUNET_PeerIdentity *peer) | ||
413 | { | ||
414 | unsigned int i; | ||
415 | unsigned int f; | ||
416 | char * p2; | ||
417 | |||
418 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "ats-scheduling-api", | ||
419 | "Get session ID for session %p from peer %s in %p\n", session, | ||
420 | GNUNET_i2s (peer), sh); | ||
421 | |||
422 | if (NULL == session) | ||
423 | return NOT_FOUND; | ||
424 | f = 0; | ||
425 | for (i = 1; i < sh->session_array_size; i++) | ||
426 | { | ||
427 | if (session == sh->session_array[i].session) | ||
428 | { | ||
429 | if (0 != memcmp (peer, &sh->session_array[i].peer, | ||
430 | sizeof (struct GNUNET_PeerIdentity))) | ||
431 | { | ||
432 | p2 = strdup (GNUNET_i2s (&sh->session_array[i].peer)); | ||
433 | GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, "ats-scheduling-api", | ||
434 | "Session %p did not match: old session was for peer `%s' new session is for `%s'\n", | ||
435 | session, GNUNET_i2s (peer), p2); | ||
436 | GNUNET_free (p2); | ||
437 | return NOT_FOUND; | ||
438 | } | ||
439 | return i; | ||
440 | } | ||
441 | } | ||
442 | return NOT_FOUND; | ||
443 | } | ||
444 | |||
445 | |||
446 | /** | ||
407 | * Remove the session of the given session ID from the session | 447 | * Remove the session of the given session ID from the session |
408 | * table (it is no longer valid). | 448 | * table (it is no longer valid). |
409 | * | 449 | * |
@@ -424,12 +464,19 @@ remove_session (struct GNUNET_ATS_SchedulingHandle *sh, uint32_t session_id, | |||
424 | 464 | ||
425 | if (0 == session_id) | 465 | if (0 == session_id) |
426 | return; | 466 | return; |
467 | |||
427 | GNUNET_assert (session_id < sh->session_array_size); | 468 | GNUNET_assert (session_id < sh->session_array_size); |
428 | GNUNET_assert (GNUNET_YES == sh->session_array[session_id].slot_used); | 469 | GNUNET_assert (GNUNET_YES == sh->session_array[session_id].slot_used); |
429 | GNUNET_assert (0 == | 470 | GNUNET_assert (0 == memcmp (peer, |
430 | memcmp (peer, &sh->session_array[session_id].peer, | 471 | &sh->session_array[session_id].peer, |
431 | sizeof (struct GNUNET_PeerIdentity))); | 472 | sizeof (struct GNUNET_PeerIdentity))); |
473 | GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, "ats-scheduling-api", | ||
474 | "Session %p for peer `%s' removed from slot %u \n", | ||
475 | sh->session_array[session_id].session, | ||
476 | GNUNET_i2s (peer), | ||
477 | session_id); | ||
432 | sh->session_array[session_id].session = NULL; | 478 | sh->session_array[session_id].session = NULL; |
479 | |||
433 | } | 480 | } |
434 | 481 | ||
435 | 482 | ||
@@ -1028,6 +1075,7 @@ GNUNET_ATS_address_update (struct GNUNET_ATS_SchedulingHandle *sh, | |||
1028 | char *pm; | 1075 | char *pm; |
1029 | size_t namelen; | 1076 | size_t namelen; |
1030 | size_t msize; | 1077 | size_t msize; |
1078 | uint32_t s = 0; | ||
1031 | 1079 | ||
1032 | if (address == NULL) | 1080 | if (address == NULL) |
1033 | { | 1081 | { |
@@ -1066,7 +1114,19 @@ GNUNET_ATS_address_update (struct GNUNET_ATS_SchedulingHandle *sh, | |||
1066 | m->peer = address->peer; | 1114 | m->peer = address->peer; |
1067 | m->address_length = htons (address->address_length); | 1115 | m->address_length = htons (address->address_length); |
1068 | m->plugin_name_length = htons (namelen); | 1116 | m->plugin_name_length = htons (namelen); |
1069 | m->session_id = htonl (get_session_id (sh, session, &address->peer)); | 1117 | if (NULL != session) |
1118 | { | ||
1119 | s = find_session_id (sh, session, &address->peer); | ||
1120 | if (NOT_FOUND == s) | ||
1121 | { | ||
1122 | /* new session without slot, find one */ | ||
1123 | s = find_empty_session_slot (sh, session, &address->peer); | ||
1124 | GNUNET_break (NOT_FOUND != s); | ||
1125 | return; | ||
1126 | } | ||
1127 | } | ||
1128 | m->session_id = htonl (s); | ||
1129 | |||
1070 | am = (struct GNUNET_ATS_Information *) &m[1]; | 1130 | am = (struct GNUNET_ATS_Information *) &m[1]; |
1071 | memcpy (am, ats, ats_count * sizeof (struct GNUNET_ATS_Information)); | 1131 | memcpy (am, ats, ats_count * sizeof (struct GNUNET_ATS_Information)); |
1072 | pm = (char *) &am[ats_count]; | 1132 | pm = (char *) &am[ats_count]; |
@@ -1074,6 +1134,7 @@ GNUNET_ATS_address_update (struct GNUNET_ATS_SchedulingHandle *sh, | |||
1074 | memcpy (&pm[address->address_length], address->transport_name, namelen); | 1134 | memcpy (&pm[address->address_length], address->transport_name, namelen); |
1075 | GNUNET_CONTAINER_DLL_insert_tail (sh->pending_head, sh->pending_tail, p); | 1135 | GNUNET_CONTAINER_DLL_insert_tail (sh->pending_head, sh->pending_tail, p); |
1076 | do_transmit (sh); | 1136 | do_transmit (sh); |
1137 | return; | ||
1077 | } | 1138 | } |
1078 | 1139 | ||
1079 | 1140 | ||
@@ -1096,6 +1157,7 @@ GNUNET_ATS_address_in_use (struct GNUNET_ATS_SchedulingHandle *sh, | |||
1096 | char *pm; | 1157 | char *pm; |
1097 | size_t namelen; | 1158 | size_t namelen; |
1098 | size_t msize; | 1159 | size_t msize; |
1160 | uint32_t s = 0; | ||
1099 | 1161 | ||
1100 | GNUNET_assert (NULL != address); | 1162 | GNUNET_assert (NULL != address); |
1101 | namelen = | 1163 | namelen = |
@@ -1120,12 +1182,33 @@ GNUNET_ATS_address_in_use (struct GNUNET_ATS_SchedulingHandle *sh, | |||
1120 | m->in_use = htons (in_use); | 1182 | m->in_use = htons (in_use); |
1121 | m->address_length = htons (address->address_length); | 1183 | m->address_length = htons (address->address_length); |
1122 | m->plugin_name_length = htons (namelen); | 1184 | m->plugin_name_length = htons (namelen); |
1123 | m->session_id = htonl (get_session_id (sh, session, &address->peer)); | 1185 | if (session != NULL) |
1186 | { | ||
1187 | s = find_session_id (sh, session, &address->peer); | ||
1188 | if ((s == NOT_FOUND) && (GNUNET_NO == in_use)) | ||
1189 | { | ||
1190 | /* trying to set unknown address to NO */ | ||
1191 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
1192 | "Trying to set unknown address to unused for peer `%s', plugin `%s', session %p\n", | ||
1193 | GNUNET_i2s (&address->peer), address->transport_name, session); | ||
1194 | GNUNET_break (0); | ||
1195 | return; | ||
1196 | } | ||
1197 | if ((s == NOT_FOUND) && (GNUNET_YES == in_use)) | ||
1198 | { | ||
1199 | /* trying to set new address to YES */ | ||
1200 | s = find_empty_session_slot (sh, session, &address->peer); | ||
1201 | GNUNET_assert (NOT_FOUND != s); | ||
1202 | } | ||
1203 | } | ||
1204 | |||
1205 | m->session_id = htonl (s); | ||
1124 | pm = (char *) &m[1]; | 1206 | pm = (char *) &m[1]; |
1125 | memcpy (pm, address->address, address->address_length); | 1207 | memcpy (pm, address->address, address->address_length); |
1126 | memcpy (&pm[address->address_length], address->transport_name, namelen); | 1208 | memcpy (&pm[address->address_length], address->transport_name, namelen); |
1127 | GNUNET_CONTAINER_DLL_insert_tail (sh->pending_head, sh->pending_tail, p); | 1209 | GNUNET_CONTAINER_DLL_insert_tail (sh->pending_head, sh->pending_tail, p); |
1128 | do_transmit (sh); | 1210 | do_transmit (sh); |
1211 | return; | ||
1129 | } | 1212 | } |
1130 | 1213 | ||
1131 | 1214 | ||
@@ -1146,7 +1229,7 @@ GNUNET_ATS_address_destroyed (struct GNUNET_ATS_SchedulingHandle *sh, | |||
1146 | char *pm; | 1229 | char *pm; |
1147 | size_t namelen; | 1230 | size_t namelen; |
1148 | size_t msize; | 1231 | size_t msize; |
1149 | uint32_t session_id; | 1232 | uint32_t s = 0; |
1150 | 1233 | ||
1151 | GNUNET_assert (address->transport_name != NULL); | 1234 | GNUNET_assert (address->transport_name != NULL); |
1152 | namelen = strlen (address->transport_name) + 1; | 1235 | namelen = strlen (address->transport_name) + 1; |
@@ -1172,14 +1255,25 @@ GNUNET_ATS_address_destroyed (struct GNUNET_ATS_SchedulingHandle *sh, | |||
1172 | m->peer = address->peer; | 1255 | m->peer = address->peer; |
1173 | m->address_length = htons (address->address_length); | 1256 | m->address_length = htons (address->address_length); |
1174 | m->plugin_name_length = htons (namelen); | 1257 | m->plugin_name_length = htons (namelen); |
1175 | session_id = get_session_id (sh, session, &address->peer); | 1258 | |
1176 | m->session_id = htonl (session_id); | 1259 | s = find_session_id (sh, session, &address->peer); |
1260 | if ((NULL != session) && (NOT_FOUND == s)) | ||
1261 | { | ||
1262 | /* trying to delete unknown address */ | ||
1263 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
1264 | "Trying to delete unknown address for peer `%s', plugin `%s', session %p\n", | ||
1265 | GNUNET_i2s (&address->peer), address->transport_name, session); | ||
1266 | GNUNET_break (0); | ||
1267 | return; | ||
1268 | } | ||
1269 | |||
1270 | m->session_id = htonl (s); | ||
1177 | pm = (char *) &m[1]; | 1271 | pm = (char *) &m[1]; |
1178 | memcpy (pm, address->address, address->address_length); | 1272 | memcpy (pm, address->address, address->address_length); |
1179 | memcpy (&pm[address->address_length], address->transport_name, namelen); | 1273 | memcpy (&pm[address->address_length], address->transport_name, namelen); |
1180 | GNUNET_CONTAINER_DLL_insert_tail (sh->pending_head, sh->pending_tail, p); | 1274 | GNUNET_CONTAINER_DLL_insert_tail (sh->pending_head, sh->pending_tail, p); |
1181 | do_transmit (sh); | 1275 | do_transmit (sh); |
1182 | remove_session (sh, session_id, &address->peer); | 1276 | remove_session (sh, s, &address->peer); |
1183 | } | 1277 | } |
1184 | 1278 | ||
1185 | /* end of ats_api_scheduling.c */ | 1279 | /* end of ats_api_scheduling.c */ |