aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/ats/ats_api_scheduling.c136
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 */
360static uint32_t 361static uint32_t
361get_session_id (struct GNUNET_ATS_SchedulingHandle *sh, struct Session *session, 362find_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 */
410static uint32_t
411find_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 */