summaryrefslogtreecommitdiff
path: root/src/ats/ats_api_scheduling.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/ats/ats_api_scheduling.c')
-rw-r--r--src/ats/ats_api_scheduling.c613
1 files changed, 304 insertions, 309 deletions
diff --git a/src/ats/ats_api_scheduling.c b/src/ats/ats_api_scheduling.c
index 532426e91..f375be6a5 100644
--- a/src/ats/ats_api_scheduling.c
+++ b/src/ats/ats_api_scheduling.c
@@ -11,12 +11,12 @@
11 WITHOUT ANY WARRANTY; without even the implied warranty of 11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Affero General Public License for more details. 13 Affero General Public License for more details.
14 14
15 You should have received a copy of the GNU Affero General Public License 15 You should have received a copy of the GNU Affero General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>. 16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17 17
18 SPDX-License-Identifier: AGPL3.0-or-later 18 SPDX-License-Identifier: AGPL3.0-or-later
19*/ 19 */
20/** 20/**
21 * @file ats/ats_api_scheduling.c 21 * @file ats/ats_api_scheduling.c
22 * @brief automatic transport selection and outbound bandwidth determination 22 * @brief automatic transport selection and outbound bandwidth determination
@@ -38,9 +38,9 @@
38/** 38/**
39 * How frequently do we scan the interfaces for changes to the addresses? 39 * How frequently do we scan the interfaces for changes to the addresses?
40 */ 40 */
41#define INTERFACE_PROCESSING_INTERVAL GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_MINUTES, 2) 41#define INTERFACE_PROCESSING_INTERVAL GNUNET_TIME_relative_multiply(GNUNET_TIME_UNIT_MINUTES, 2)
42 42
43#define LOG(kind,...) GNUNET_log_from(kind, "ats-scheduling-api", __VA_ARGS__) 43#define LOG(kind, ...) GNUNET_log_from(kind, "ats-scheduling-api", __VA_ARGS__)
44 44
45/** 45/**
46 * Session ID we use if there is no session / slot. 46 * Session ID we use if there is no session / slot.
@@ -53,9 +53,7 @@
53 * doesn't matter if we have a session, any address that ATS is 53 * doesn't matter if we have a session, any address that ATS is
54 * allowed to suggest right now should be tracked. 54 * allowed to suggest right now should be tracked.
55 */ 55 */
56struct GNUNET_ATS_AddressRecord 56struct GNUNET_ATS_AddressRecord {
57{
58
59 /** 57 /**
60 * Scheduling handle this address record belongs to. 58 * Scheduling handle this address record belongs to.
61 */ 59 */
@@ -99,9 +97,7 @@ struct GNUNET_ATS_AddressRecord
99/** 97/**
100 * Handle to the ATS subsystem for bandwidth/transport scheduling information. 98 * Handle to the ATS subsystem for bandwidth/transport scheduling information.
101 */ 99 */
102struct GNUNET_ATS_SchedulingHandle 100struct GNUNET_ATS_SchedulingHandle {
103{
104
105 /** 101 /**
106 * Our configuration. 102 * Our configuration.
107 */ 103 */
@@ -144,7 +140,6 @@ struct GNUNET_ATS_SchedulingHandle
144 * Size of the @e session_array. 140 * Size of the @e session_array.
145 */ 141 */
146 unsigned int session_array_size; 142 unsigned int session_array_size;
147
148}; 143};
149 144
150 145
@@ -154,7 +149,7 @@ struct GNUNET_ATS_SchedulingHandle
154 * @param sh handle to use to re-connect. 149 * @param sh handle to use to re-connect.
155 */ 150 */
156static void 151static void
157reconnect (struct GNUNET_ATS_SchedulingHandle *sh); 152reconnect(struct GNUNET_ATS_SchedulingHandle *sh);
158 153
159 154
160/** 155/**
@@ -163,12 +158,12 @@ reconnect (struct GNUNET_ATS_SchedulingHandle *sh);
163 * @param cls handle to use to re-connect. 158 * @param cls handle to use to re-connect.
164 */ 159 */
165static void 160static void
166reconnect_task (void *cls) 161reconnect_task(void *cls)
167{ 162{
168 struct GNUNET_ATS_SchedulingHandle *sh = cls; 163 struct GNUNET_ATS_SchedulingHandle *sh = cls;
169 164
170 sh->task = NULL; 165 sh->task = NULL;
171 reconnect (sh); 166 reconnect(sh);
172} 167}
173 168
174 169
@@ -178,21 +173,21 @@ reconnect_task (void *cls)
178 * @param sh our handle 173 * @param sh our handle
179 */ 174 */
180static void 175static void
181force_reconnect (struct GNUNET_ATS_SchedulingHandle *sh) 176force_reconnect(struct GNUNET_ATS_SchedulingHandle *sh)
182{ 177{
183 if (NULL != sh->mq) 178 if (NULL != sh->mq)
184 { 179 {
185 GNUNET_MQ_destroy (sh->mq); 180 GNUNET_MQ_destroy(sh->mq);
186 sh->mq = NULL; 181 sh->mq = NULL;
187 } 182 }
188 sh->suggest_cb (sh->suggest_cb_cls, 183 sh->suggest_cb(sh->suggest_cb_cls,
189 NULL, NULL, NULL, 184 NULL, NULL, NULL,
190 GNUNET_BANDWIDTH_ZERO, 185 GNUNET_BANDWIDTH_ZERO,
191 GNUNET_BANDWIDTH_ZERO); 186 GNUNET_BANDWIDTH_ZERO);
192 sh->backoff = GNUNET_TIME_STD_BACKOFF (sh->backoff); 187 sh->backoff = GNUNET_TIME_STD_BACKOFF(sh->backoff);
193 sh->task = GNUNET_SCHEDULER_add_delayed (sh->backoff, 188 sh->task = GNUNET_SCHEDULER_add_delayed(sh->backoff,
194 &reconnect_task, 189 &reconnect_task,
195 sh); 190 sh);
196} 191}
197 192
198 193
@@ -205,37 +200,37 @@ force_reconnect (struct GNUNET_ATS_SchedulingHandle *sh)
205 * @return the session object (or NULL) 200 * @return the session object (or NULL)
206 */ 201 */
207static struct GNUNET_ATS_AddressRecord * 202static struct GNUNET_ATS_AddressRecord *
208find_session (struct GNUNET_ATS_SchedulingHandle *sh, 203find_session(struct GNUNET_ATS_SchedulingHandle *sh,
209 uint32_t session_id, 204 uint32_t session_id,
210 const struct GNUNET_PeerIdentity *peer) 205 const struct GNUNET_PeerIdentity *peer)
211{ 206{
212 struct GNUNET_ATS_AddressRecord *ar; 207 struct GNUNET_ATS_AddressRecord *ar;
213 208
214 if (session_id >= sh->session_array_size) 209 if (session_id >= sh->session_array_size)
215 { 210 {
216 GNUNET_break (0); 211 GNUNET_break(0);
217 return NULL; 212 return NULL;
218 } 213 }
219 if (0 == session_id) 214 if (0 == session_id)
220 return NULL; 215 return NULL;
221 ar = sh->session_array[session_id]; 216 ar = sh->session_array[session_id];
222 if (NULL == ar) 217 if (NULL == ar)
223 { 218 {
224 GNUNET_break (0); 219 GNUNET_break(0);
225 return NULL; 220 return NULL;
226 } 221 }
227 if (NULL == ar->address) 222 if (NULL == ar->address)
228 { 223 {
229 /* address was destroyed in the meantime, this can happen 224 /* address was destroyed in the meantime, this can happen
230 as we communicate asynchronously with the ATS service. */ 225 as we communicate asynchronously with the ATS service. */
231 return NULL; 226 return NULL;
232 } 227 }
233 if (0 != GNUNET_memcmp (peer, 228 if (0 != GNUNET_memcmp(peer,
234 &ar->address->peer)) 229 &ar->address->peer))
235 { 230 {
236 GNUNET_break (0); 231 GNUNET_break(0);
237 return NULL; 232 return NULL;
238 } 233 }
239 return ar; 234 return ar;
240} 235}
241 236
@@ -247,27 +242,27 @@ find_session (struct GNUNET_ATS_SchedulingHandle *sh,
247 * @return an unused slot, but never NOT_FOUND (0) 242 * @return an unused slot, but never NOT_FOUND (0)
248 */ 243 */
249static uint32_t 244static uint32_t
250find_empty_session_slot (struct GNUNET_ATS_SchedulingHandle *sh) 245find_empty_session_slot(struct GNUNET_ATS_SchedulingHandle *sh)
251{ 246{
252 static uint32_t off; 247 static uint32_t off;
253 uint32_t i; 248 uint32_t i;
254 249
255 GNUNET_assert (0 != sh->session_array_size); 250 GNUNET_assert(0 != sh->session_array_size);
256 i = 0; 251 i = 0;
257 while ( ( (NOT_FOUND == off) || 252 while (((NOT_FOUND == off) ||
258 (NULL != sh->session_array[off % sh->session_array_size]) ) && 253 (NULL != sh->session_array[off % sh->session_array_size])) &&
259 (i < sh->session_array_size) ) 254 (i < sh->session_array_size))
260 { 255 {
261 off++; 256 off++;
262 i++; 257 i++;
263 } 258 }
264 if ( (NOT_FOUND != off % sh->session_array_size) && 259 if ((NOT_FOUND != off % sh->session_array_size) &&
265 (NULL == sh->session_array[off % sh->session_array_size]) ) 260 (NULL == sh->session_array[off % sh->session_array_size]))
266 return off; 261 return off;
267 i = sh->session_array_size; 262 i = sh->session_array_size;
268 GNUNET_array_grow (sh->session_array, 263 GNUNET_array_grow(sh->session_array,
269 sh->session_array_size, 264 sh->session_array_size,
270 sh->session_array_size * 2); 265 sh->session_array_size * 2);
271 return i; 266 return i;
272} 267}
273 268
@@ -281,26 +276,26 @@ find_empty_session_slot (struct GNUNET_ATS_SchedulingHandle *sh)
281 * @return the session id or NOT_FOUND for error 276 * @return the session id or NOT_FOUND for error
282 */ 277 */
283static uint32_t 278static uint32_t
284find_session_id (struct GNUNET_ATS_SchedulingHandle *sh, 279find_session_id(struct GNUNET_ATS_SchedulingHandle *sh,
285 struct GNUNET_ATS_Session *session, 280 struct GNUNET_ATS_Session *session,
286 const struct GNUNET_HELLO_Address *address) 281 const struct GNUNET_HELLO_Address *address)
287{ 282{
288 uint32_t i; 283 uint32_t i;
289 284
290 if (NULL == address) 285 if (NULL == address)
291 { 286 {
292 GNUNET_break (0); 287 GNUNET_break(0);
293 return NOT_FOUND; 288 return NOT_FOUND;
294 } 289 }
295 for (i = 1; i < sh->session_array_size; i++) 290 for (i = 1; i < sh->session_array_size; i++)
296 if ( (NULL != sh->session_array[i]) && 291 if ((NULL != sh->session_array[i]) &&
297 (GNUNET_NO == sh->session_array[i]->in_destroy) && 292 (GNUNET_NO == sh->session_array[i]->in_destroy) &&
298 ( (session == sh->session_array[i]->session) || 293 ((session == sh->session_array[i]->session) ||
299 (NULL == sh->session_array[i]->session) ) && 294 (NULL == sh->session_array[i]->session)) &&
300 (0 == GNUNET_memcmp (&address->peer, 295 (0 == GNUNET_memcmp(&address->peer,
301 &sh->session_array[i]->address->peer)) && 296 &sh->session_array[i]->address->peer)) &&
302 (0 == GNUNET_HELLO_address_cmp (address, 297 (0 == GNUNET_HELLO_address_cmp(address,
303 sh->session_array[i]->address)) ) 298 sh->session_array[i]->address)))
304 return i; 299 return i;
305 return NOT_FOUND; 300 return NOT_FOUND;
306} 301}
@@ -314,29 +309,29 @@ find_session_id (struct GNUNET_ATS_SchedulingHandle *sh,
314 * @param session_id identifies session that is no longer valid 309 * @param session_id identifies session that is no longer valid
315 */ 310 */
316static void 311static void
317release_session (struct GNUNET_ATS_SchedulingHandle *sh, 312release_session(struct GNUNET_ATS_SchedulingHandle *sh,
318 uint32_t session_id) 313 uint32_t session_id)
319{ 314{
320 struct GNUNET_ATS_AddressRecord *ar; 315 struct GNUNET_ATS_AddressRecord *ar;
321 316
322 if (NOT_FOUND == session_id) 317 if (NOT_FOUND == session_id)
323 return; 318 return;
324 if (session_id >= sh->session_array_size) 319 if (session_id >= sh->session_array_size)
325 { 320 {
326 GNUNET_break (0); 321 GNUNET_break(0);
327 force_reconnect (sh); 322 force_reconnect(sh);
328 return; 323 return;
329 } 324 }
330 /* this slot should have been removed from remove_session before */ 325 /* this slot should have been removed from remove_session before */
331 ar = sh->session_array[session_id]; 326 ar = sh->session_array[session_id];
332 if (NULL != ar->session) 327 if (NULL != ar->session)
333 { 328 {
334 GNUNET_break (0); 329 GNUNET_break(0);
335 force_reconnect (sh); 330 force_reconnect(sh);
336 return; 331 return;
337 } 332 }
338 GNUNET_HELLO_address_free (ar->address); 333 GNUNET_HELLO_address_free(ar->address);
339 GNUNET_free (ar); 334 GNUNET_free(ar);
340 sh->session_array[session_id] = NULL; 335 sh->session_array[session_id] = NULL;
341} 336}
342 337
@@ -349,15 +344,15 @@ release_session (struct GNUNET_ATS_SchedulingHandle *sh,
349 * @param srm message received 344 * @param srm message received
350 */ 345 */
351static void 346static void
352handle_ats_session_release (void *cls, 347handle_ats_session_release(void *cls,
353 const struct GNUNET_ATS_SessionReleaseMessage *srm) 348 const struct GNUNET_ATS_SessionReleaseMessage *srm)
354{ 349{
355 struct GNUNET_ATS_SchedulingHandle *sh = cls; 350 struct GNUNET_ATS_SchedulingHandle *sh = cls;
356 351
357 /* Note: peer field in srm not necessary right now, 352 /* Note: peer field in srm not necessary right now,
358 but might be good to have in the future */ 353 but might be good to have in the future */
359 release_session (sh, 354 release_session(sh,
360 ntohl (srm->session_id)); 355 ntohl(srm->session_id));
361} 356}
362 357
363 358
@@ -369,71 +364,71 @@ handle_ats_session_release (void *cls,
369 * @param m message received 364 * @param m message received
370 */ 365 */
371static void 366static void
372handle_ats_address_suggestion (void *cls, 367handle_ats_address_suggestion(void *cls,
373 const struct AddressSuggestionMessage *m) 368 const struct AddressSuggestionMessage *m)
374{ 369{
375 struct GNUNET_ATS_SchedulingHandle *sh = cls; 370 struct GNUNET_ATS_SchedulingHandle *sh = cls;
376 struct GNUNET_ATS_AddressRecord *ar; 371 struct GNUNET_ATS_AddressRecord *ar;
377 uint32_t session_id; 372 uint32_t session_id;
378 373
379 session_id = ntohl (m->session_id); 374 session_id = ntohl(m->session_id);
380 if (0 == session_id) 375 if (0 == session_id)
381 { 376 {
382 GNUNET_break (0); 377 GNUNET_break(0);
383 force_reconnect (sh); 378 force_reconnect(sh);
384 return; 379 return;
385 } 380 }
386 ar = find_session (sh, 381 ar = find_session(sh,
387 session_id, 382 session_id,
388 &m->peer); 383 &m->peer);
389 if (NULL == ar) 384 if (NULL == ar)
390 { 385 {
391 GNUNET_break (0); 386 GNUNET_break(0);
392 force_reconnect (sh); 387 force_reconnect(sh);
393 return; 388 return;
394 } 389 }
395 if (NULL == sh->suggest_cb) 390 if (NULL == sh->suggest_cb)
396 return; 391 return;
397 if (GNUNET_YES == ar->in_destroy) 392 if (GNUNET_YES == ar->in_destroy)
398 {
399 /* ignore suggestion, as this address is dying, unless BW is 0,
400 in that case signal 'disconnect' via BW 0 */
401 if ( (0 == ntohl (m->bandwidth_out.value__)) &&
402 (0 == ntohl (m->bandwidth_in.value__)) )
403 { 393 {
404 LOG (GNUNET_ERROR_TYPE_DEBUG, 394 /* ignore suggestion, as this address is dying, unless BW is 0,
405 "ATS suggests disconnect from peer `%s' with BW %u/%u\n", 395 in that case signal 'disconnect' via BW 0 */
406 GNUNET_i2s (&ar->address->peer), 396 if ((0 == ntohl(m->bandwidth_out.value__)) &&
407 (unsigned int) ntohl (m->bandwidth_out.value__), 397 (0 == ntohl(m->bandwidth_in.value__)))
408 (unsigned int) ntohl (m->bandwidth_in.value__)); 398 {
409 sh->suggest_cb (sh->suggest_cb_cls, 399 LOG(GNUNET_ERROR_TYPE_DEBUG,
410 &m->peer, 400 "ATS suggests disconnect from peer `%s' with BW %u/%u\n",
411 NULL, 401 GNUNET_i2s(&ar->address->peer),
412 NULL, 402 (unsigned int)ntohl(m->bandwidth_out.value__),
413 m->bandwidth_out, 403 (unsigned int)ntohl(m->bandwidth_in.value__));
414 m->bandwidth_in); 404 sh->suggest_cb(sh->suggest_cb_cls,
405 &m->peer,
406 NULL,
407 NULL,
408 m->bandwidth_out,
409 m->bandwidth_in);
410 }
411 return;
412 }
413 if ((NULL == ar->session) &&
414 (GNUNET_HELLO_address_check_option(ar->address,
415 GNUNET_HELLO_ADDRESS_INFO_INBOUND)))
416 {
417 GNUNET_break(0);
418 return;
415 } 419 }
416 return;
417 }
418 if ( (NULL == ar->session) &&
419 (GNUNET_HELLO_address_check_option (ar->address,
420 GNUNET_HELLO_ADDRESS_INFO_INBOUND)) )
421 {
422 GNUNET_break (0);
423 return;
424 }
425 sh->backoff = GNUNET_TIME_UNIT_ZERO; 420 sh->backoff = GNUNET_TIME_UNIT_ZERO;
426 LOG (GNUNET_ERROR_TYPE_DEBUG, 421 LOG(GNUNET_ERROR_TYPE_DEBUG,
427 "ATS suggests address slot %u for peer `%s' using plugin %s\n", 422 "ATS suggests address slot %u for peer `%s' using plugin %s\n",
428 ar->slot, 423 ar->slot,
429 GNUNET_i2s (&ar->address->peer), 424 GNUNET_i2s(&ar->address->peer),
430 ar->address->transport_name); 425 ar->address->transport_name);
431 sh->suggest_cb (sh->suggest_cb_cls, 426 sh->suggest_cb(sh->suggest_cb_cls,
432 &m->peer, 427 &m->peer,
433 ar->address, 428 ar->address,
434 ar->session, 429 ar->session,
435 m->bandwidth_out, 430 m->bandwidth_out,
436 m->bandwidth_in); 431 m->bandwidth_in);
437} 432}
438 433
439 434
@@ -445,15 +440,15 @@ handle_ats_address_suggestion (void *cls,
445 * @param error details about the error 440 * @param error details about the error
446 */ 441 */
447static void 442static void
448error_handler (void *cls, 443error_handler(void *cls,
449 enum GNUNET_MQ_Error error) 444 enum GNUNET_MQ_Error error)
450{ 445{
451 struct GNUNET_ATS_SchedulingHandle *sh = cls; 446 struct GNUNET_ATS_SchedulingHandle *sh = cls;
452 447
453 LOG (GNUNET_ERROR_TYPE_DEBUG, 448 LOG(GNUNET_ERROR_TYPE_DEBUG,
454 "ATS connection died (code %d), reconnecting\n", 449 "ATS connection died (code %d), reconnecting\n",
455 (int) error); 450 (int)error);
456 force_reconnect (sh); 451 force_reconnect(sh);
457} 452}
458 453
459 454
@@ -465,8 +460,8 @@ error_handler (void *cls,
465 * @param ar the address to inform the ATS service about 460 * @param ar the address to inform the ATS service about
466 */ 461 */
467static void 462static void
468send_add_address_message (struct GNUNET_ATS_SchedulingHandle *sh, 463send_add_address_message(struct GNUNET_ATS_SchedulingHandle *sh,
469 const struct GNUNET_ATS_AddressRecord *ar) 464 const struct GNUNET_ATS_AddressRecord *ar)
470{ 465{
471 struct GNUNET_MQ_Envelope *ev; 466 struct GNUNET_MQ_Envelope *ev;
472 struct AddressAddMessage *m; 467 struct AddressAddMessage *m;
@@ -476,32 +471,32 @@ send_add_address_message (struct GNUNET_ATS_SchedulingHandle *sh,
476 471
477 if (NULL == sh->mq) 472 if (NULL == sh->mq)
478 return; /* disconnected, skip for now */ 473 return; /* disconnected, skip for now */
479 GNUNET_break (GNUNET_NT_UNSPECIFIED != ar->properties.scope); 474 GNUNET_break(GNUNET_NT_UNSPECIFIED != ar->properties.scope);
480 namelen = strlen (ar->address->transport_name) + 1; 475 namelen = strlen(ar->address->transport_name) + 1;
481 msize = ar->address->address_length + namelen; 476 msize = ar->address->address_length + namelen;
482 ev = GNUNET_MQ_msg_extra (m, msize, GNUNET_MESSAGE_TYPE_ATS_ADDRESS_ADD); 477 ev = GNUNET_MQ_msg_extra(m, msize, GNUNET_MESSAGE_TYPE_ATS_ADDRESS_ADD);
483 m->peer = ar->address->peer; 478 m->peer = ar->address->peer;
484 m->address_length = htons (ar->address->address_length); 479 m->address_length = htons(ar->address->address_length);
485 m->address_local_info = htonl ((uint32_t) ar->address->local_info); 480 m->address_local_info = htonl((uint32_t)ar->address->local_info);
486 m->plugin_name_length = htons (namelen); 481 m->plugin_name_length = htons(namelen);
487 m->session_id = htonl (ar->slot); 482 m->session_id = htonl(ar->slot);
488 m->properties = ar->properties; 483 m->properties = ar->properties;
489 484
490 LOG (GNUNET_ERROR_TYPE_DEBUG, 485 LOG(GNUNET_ERROR_TYPE_DEBUG,
491 "Adding address for peer `%s', plugin `%s', session %p slot %u\n", 486 "Adding address for peer `%s', plugin `%s', session %p slot %u\n",
492 GNUNET_i2s (&ar->address->peer), 487 GNUNET_i2s(&ar->address->peer),
493 ar->address->transport_name, 488 ar->address->transport_name,
494 ar->session, 489 ar->session,
495 ar->slot); 490 ar->slot);
496 pm = (char *) &m[1]; 491 pm = (char *)&m[1];
497 GNUNET_memcpy (pm, 492 GNUNET_memcpy(pm,
498 ar->address->address, 493 ar->address->address,
499 ar->address->address_length); 494 ar->address->address_length);
500 if (NULL != ar->address->transport_name) 495 if (NULL != ar->address->transport_name)
501 GNUNET_memcpy (&pm[ar->address->address_length], 496 GNUNET_memcpy(&pm[ar->address->address_length],
502 ar->address->transport_name, 497 ar->address->transport_name,
503 namelen); 498 namelen);
504 GNUNET_MQ_send (sh->mq, ev); 499 GNUNET_MQ_send(sh->mq, ev);
505} 500}
506 501
507 502
@@ -511,51 +506,51 @@ send_add_address_message (struct GNUNET_ATS_SchedulingHandle *sh,
511 * @param sh handle to use to re-connect. 506 * @param sh handle to use to re-connect.
512 */ 507 */
513static void 508static void
514reconnect (struct GNUNET_ATS_SchedulingHandle *sh) 509reconnect(struct GNUNET_ATS_SchedulingHandle *sh)
515{ 510{
516 struct GNUNET_MQ_MessageHandler handlers[] = { 511 struct GNUNET_MQ_MessageHandler handlers[] = {
517 GNUNET_MQ_hd_fixed_size (ats_session_release, 512 GNUNET_MQ_hd_fixed_size(ats_session_release,
518 GNUNET_MESSAGE_TYPE_ATS_SESSION_RELEASE, 513 GNUNET_MESSAGE_TYPE_ATS_SESSION_RELEASE,
519 struct GNUNET_ATS_SessionReleaseMessage, 514 struct GNUNET_ATS_SessionReleaseMessage,
520 sh), 515 sh),
521 GNUNET_MQ_hd_fixed_size (ats_address_suggestion, 516 GNUNET_MQ_hd_fixed_size(ats_address_suggestion,
522 GNUNET_MESSAGE_TYPE_ATS_ADDRESS_SUGGESTION, 517 GNUNET_MESSAGE_TYPE_ATS_ADDRESS_SUGGESTION,
523 struct AddressSuggestionMessage, 518 struct AddressSuggestionMessage,
524 sh), 519 sh),
525 GNUNET_MQ_handler_end () 520 GNUNET_MQ_handler_end()
526 }; 521 };
527 struct GNUNET_MQ_Envelope *ev; 522 struct GNUNET_MQ_Envelope *ev;
528 struct ClientStartMessage *init; 523 struct ClientStartMessage *init;
529 unsigned int i; 524 unsigned int i;
530 struct GNUNET_ATS_AddressRecord *ar; 525 struct GNUNET_ATS_AddressRecord *ar;
531 526
532 GNUNET_assert (NULL == sh->mq); 527 GNUNET_assert(NULL == sh->mq);
533 sh->mq = GNUNET_CLIENT_connect (sh->cfg, 528 sh->mq = GNUNET_CLIENT_connect(sh->cfg,
534 "ats", 529 "ats",
535 handlers, 530 handlers,
536 &error_handler, 531 &error_handler,
537 sh); 532 sh);
538 if (NULL == sh->mq) 533 if (NULL == sh->mq)
539 { 534 {
540 GNUNET_break (0); 535 GNUNET_break(0);
541 force_reconnect (sh); 536 force_reconnect(sh);
542 return; 537 return;
543 } 538 }
544 ev = GNUNET_MQ_msg (init, 539 ev = GNUNET_MQ_msg(init,
545 GNUNET_MESSAGE_TYPE_ATS_START); 540 GNUNET_MESSAGE_TYPE_ATS_START);
546 init->start_flag = htonl (START_FLAG_SCHEDULING); 541 init->start_flag = htonl(START_FLAG_SCHEDULING);
547 GNUNET_MQ_send (sh->mq, ev); 542 GNUNET_MQ_send(sh->mq, ev);
548 if (NULL == sh->mq) 543 if (NULL == sh->mq)
549 return; 544 return;
550 for (i=0;i<sh->session_array_size;i++) 545 for (i = 0; i < sh->session_array_size; i++)
551 { 546 {
552 ar = sh->session_array[i]; 547 ar = sh->session_array[i];
553 if (NULL == ar) 548 if (NULL == ar)
554 continue; 549 continue;
555 send_add_address_message (sh, ar); 550 send_add_address_message(sh, ar);
556 if (NULL == sh->mq) 551 if (NULL == sh->mq)
557 return; 552 return;
558 } 553 }
559} 554}
560 555
561 556
@@ -568,20 +563,20 @@ reconnect (struct GNUNET_ATS_SchedulingHandle *sh)
568 * @return ats context 563 * @return ats context
569 */ 564 */
570struct GNUNET_ATS_SchedulingHandle * 565struct GNUNET_ATS_SchedulingHandle *
571GNUNET_ATS_scheduling_init (const struct GNUNET_CONFIGURATION_Handle *cfg, 566GNUNET_ATS_scheduling_init(const struct GNUNET_CONFIGURATION_Handle *cfg,
572 GNUNET_ATS_AddressSuggestionCallback suggest_cb, 567 GNUNET_ATS_AddressSuggestionCallback suggest_cb,
573 void *suggest_cb_cls) 568 void *suggest_cb_cls)
574{ 569{
575 struct GNUNET_ATS_SchedulingHandle *sh; 570 struct GNUNET_ATS_SchedulingHandle *sh;
576 571
577 sh = GNUNET_new (struct GNUNET_ATS_SchedulingHandle); 572 sh = GNUNET_new(struct GNUNET_ATS_SchedulingHandle);
578 sh->cfg = cfg; 573 sh->cfg = cfg;
579 sh->suggest_cb = suggest_cb; 574 sh->suggest_cb = suggest_cb;
580 sh->suggest_cb_cls = suggest_cb_cls; 575 sh->suggest_cb_cls = suggest_cb_cls;
581 GNUNET_array_grow (sh->session_array, 576 GNUNET_array_grow(sh->session_array,
582 sh->session_array_size, 577 sh->session_array_size,
583 4); 578 4);
584 reconnect (sh); 579 reconnect(sh);
585 return sh; 580 return sh;
586} 581}
587 582
@@ -592,34 +587,34 @@ GNUNET_ATS_scheduling_init (const struct GNUNET_CONFIGURATION_Handle *cfg,
592 * @param sh handle to release 587 * @param sh handle to release
593 */ 588 */
594void 589void
595GNUNET_ATS_scheduling_done (struct GNUNET_ATS_SchedulingHandle *sh) 590GNUNET_ATS_scheduling_done(struct GNUNET_ATS_SchedulingHandle *sh)
596{ 591{
597 struct GNUNET_ATS_AddressRecord *ar; 592 struct GNUNET_ATS_AddressRecord *ar;
598 unsigned int i; 593 unsigned int i;
599 594
600 if (NULL != sh->mq) 595 if (NULL != sh->mq)
601 { 596 {
602 GNUNET_MQ_destroy (sh->mq); 597 GNUNET_MQ_destroy(sh->mq);
603 sh->mq = NULL; 598 sh->mq = NULL;
604 } 599 }
605 if (NULL != sh->task) 600 if (NULL != sh->task)
606 {
607 GNUNET_SCHEDULER_cancel (sh->task);
608 sh->task = NULL;
609 }
610 for (i=0;i<sh->session_array_size;i++)
611 {
612 if (NULL != (ar = sh->session_array[i]))
613 { 601 {
614 GNUNET_HELLO_address_free (ar->address); 602 GNUNET_SCHEDULER_cancel(sh->task);
615 GNUNET_free (ar); 603 sh->task = NULL;
616 sh->session_array[i] = NULL;
617 } 604 }
618 } 605 for (i = 0; i < sh->session_array_size; i++)
619 GNUNET_array_grow (sh->session_array, 606 {
620 sh->session_array_size, 607 if (NULL != (ar = sh->session_array[i]))
621 0); 608 {
622 GNUNET_free (sh); 609 GNUNET_HELLO_address_free(ar->address);
610 GNUNET_free(ar);
611 sh->session_array[i] = NULL;
612 }
613 }
614 GNUNET_array_grow(sh->session_array,
615 sh->session_array_size,
616 0);
617 GNUNET_free(sh);
623} 618}
624 619
625 620
@@ -636,10 +631,10 @@ GNUNET_ATS_scheduling_done (struct GNUNET_ATS_SchedulingHandle *sh)
636 * on error (i.e. ATS knows this exact address already) 631 * on error (i.e. ATS knows this exact address already)
637 */ 632 */
638struct GNUNET_ATS_AddressRecord * 633struct GNUNET_ATS_AddressRecord *
639GNUNET_ATS_address_add (struct GNUNET_ATS_SchedulingHandle *sh, 634GNUNET_ATS_address_add(struct GNUNET_ATS_SchedulingHandle *sh,
640 const struct GNUNET_HELLO_Address *address, 635 const struct GNUNET_HELLO_Address *address,
641 struct GNUNET_ATS_Session *session, 636 struct GNUNET_ATS_Session *session,
642 const struct GNUNET_ATS_Properties *prop) 637 const struct GNUNET_ATS_Properties *prop)
643{ 638{
644 struct GNUNET_ATS_AddressRecord *ar; 639 struct GNUNET_ATS_AddressRecord *ar;
645 size_t namelen; 640 size_t namelen;
@@ -647,42 +642,42 @@ GNUNET_ATS_address_add (struct GNUNET_ATS_SchedulingHandle *sh,
647 uint32_t s; 642 uint32_t s;
648 643
649 if (NULL == address) 644 if (NULL == address)
650 { 645 {
651 /* we need a valid address */ 646 /* we need a valid address */
652 GNUNET_break (0); 647 GNUNET_break(0);
653 return NULL; 648 return NULL;
654 } 649 }
655 GNUNET_break (GNUNET_NT_UNSPECIFIED != prop->scope); 650 GNUNET_break(GNUNET_NT_UNSPECIFIED != prop->scope);
656 namelen = strlen (address->transport_name) + 1; 651 namelen = strlen(address->transport_name) + 1;
657 msize = address->address_length + namelen; 652 msize = address->address_length + namelen;
658 if ((msize + sizeof (struct AddressUpdateMessage) >= GNUNET_MAX_MESSAGE_SIZE) || 653 if ((msize + sizeof(struct AddressUpdateMessage) >= GNUNET_MAX_MESSAGE_SIZE) ||
659 (address->address_length >= GNUNET_MAX_MESSAGE_SIZE) || 654 (address->address_length >= GNUNET_MAX_MESSAGE_SIZE) ||
660 (namelen >= GNUNET_MAX_MESSAGE_SIZE) ) 655 (namelen >= GNUNET_MAX_MESSAGE_SIZE))
661 { 656 {
662 /* address too large for us, this should not happen */ 657 /* address too large for us, this should not happen */
663 GNUNET_break (0); 658 GNUNET_break(0);
664 return NULL; 659 return NULL;
665 } 660 }
666 661
667 if (NOT_FOUND != 662 if (NOT_FOUND !=
668 find_session_id (sh, 663 find_session_id(sh,
669 session, 664 session,
670 address)) 665 address))
671 { 666 {
672 /* Already existing, nothing todo, but this should not happen */ 667 /* Already existing, nothing todo, but this should not happen */
673 GNUNET_break (0); 668 GNUNET_break(0);
674 return NULL; 669 return NULL;
675 } 670 }
676 s = find_empty_session_slot (sh); 671 s = find_empty_session_slot(sh);
677 ar = GNUNET_new (struct GNUNET_ATS_AddressRecord); 672 ar = GNUNET_new(struct GNUNET_ATS_AddressRecord);
678 ar->sh = sh; 673 ar->sh = sh;
679 ar->slot = s; 674 ar->slot = s;
680 ar->session = session; 675 ar->session = session;
681 ar->address = GNUNET_HELLO_address_copy (address); 676 ar->address = GNUNET_HELLO_address_copy(address);
682 GNUNET_ATS_properties_hton (&ar->properties, 677 GNUNET_ATS_properties_hton(&ar->properties,
683 prop); 678 prop);
684 sh->session_array[s] = ar; 679 sh->session_array[s] = ar;
685 send_add_address_message (sh, ar); 680 send_add_address_message(sh, ar);
686 return ar; 681 return ar;
687} 682}
688 683
@@ -694,10 +689,10 @@ GNUNET_ATS_address_add (struct GNUNET_ATS_SchedulingHandle *sh,
694 * @param session session handle 689 * @param session session handle
695 */ 690 */
696void 691void
697GNUNET_ATS_address_add_session (struct GNUNET_ATS_AddressRecord *ar, 692GNUNET_ATS_address_add_session(struct GNUNET_ATS_AddressRecord *ar,
698 struct GNUNET_ATS_Session *session) 693 struct GNUNET_ATS_Session *session)
699{ 694{
700 GNUNET_break (NULL == ar->session); 695 GNUNET_break(NULL == ar->session);
701 ar->session = session; 696 ar->session = session;
702} 697}
703 698
@@ -715,17 +710,17 @@ GNUNET_ATS_address_add_session (struct GNUNET_ATS_AddressRecord *ar,
715 * use it still to establish a new session 710 * use it still to establish a new session
716 */ 711 */
717int 712int
718GNUNET_ATS_address_del_session (struct GNUNET_ATS_AddressRecord *ar, 713GNUNET_ATS_address_del_session(struct GNUNET_ATS_AddressRecord *ar,
719 struct GNUNET_ATS_Session *session) 714 struct GNUNET_ATS_Session *session)
720{ 715{
721 GNUNET_assert (session == ar->session); 716 GNUNET_assert(session == ar->session);
722 ar->session = NULL; 717 ar->session = NULL;
723 if (GNUNET_HELLO_address_check_option (ar->address, 718 if (GNUNET_HELLO_address_check_option(ar->address,
724 GNUNET_HELLO_ADDRESS_INFO_INBOUND)) 719 GNUNET_HELLO_ADDRESS_INFO_INBOUND))
725 { 720 {
726 GNUNET_ATS_address_destroy (ar); 721 GNUNET_ATS_address_destroy(ar);
727 return GNUNET_YES; 722 return GNUNET_YES;
728 } 723 }
729 return GNUNET_NO; 724 return GNUNET_NO;
730} 725}
731 726
@@ -742,30 +737,30 @@ GNUNET_ATS_address_del_session (struct GNUNET_ATS_AddressRecord *ar,
742 * @param prop performance data for the address 737 * @param prop performance data for the address
743 */ 738 */
744void 739void
745GNUNET_ATS_address_update (struct GNUNET_ATS_AddressRecord *ar, 740GNUNET_ATS_address_update(struct GNUNET_ATS_AddressRecord *ar,
746 const struct GNUNET_ATS_Properties *prop) 741 const struct GNUNET_ATS_Properties *prop)
747{ 742{
748 struct GNUNET_ATS_SchedulingHandle *sh = ar->sh; 743 struct GNUNET_ATS_SchedulingHandle *sh = ar->sh;
749 struct GNUNET_MQ_Envelope *ev; 744 struct GNUNET_MQ_Envelope *ev;
750 struct AddressUpdateMessage *m; 745 struct AddressUpdateMessage *m;
751 746
752 LOG (GNUNET_ERROR_TYPE_DEBUG, 747 LOG(GNUNET_ERROR_TYPE_DEBUG,
753 "Updating address for peer `%s', plugin `%s', session %p slot %u\n", 748 "Updating address for peer `%s', plugin `%s', session %p slot %u\n",
754 GNUNET_i2s (&ar->address->peer), 749 GNUNET_i2s(&ar->address->peer),
755 ar->address->transport_name, 750 ar->address->transport_name,
756 ar->session, 751 ar->session,
757 ar->slot); 752 ar->slot);
758 GNUNET_break (GNUNET_NT_UNSPECIFIED != prop->scope); 753 GNUNET_break(GNUNET_NT_UNSPECIFIED != prop->scope);
759 GNUNET_ATS_properties_hton (&ar->properties, 754 GNUNET_ATS_properties_hton(&ar->properties,
760 prop); 755 prop);
761 if (NULL == sh->mq) 756 if (NULL == sh->mq)
762 return; /* disconnected, skip for now */ 757 return; /* disconnected, skip for now */
763 ev = GNUNET_MQ_msg (m, GNUNET_MESSAGE_TYPE_ATS_ADDRESS_UPDATE); 758 ev = GNUNET_MQ_msg(m, GNUNET_MESSAGE_TYPE_ATS_ADDRESS_UPDATE);
764 m->session_id = htonl (ar->slot); 759 m->session_id = htonl(ar->slot);
765 m->peer = ar->address->peer; 760 m->peer = ar->address->peer;
766 m->properties = ar->properties; 761 m->properties = ar->properties;
767 GNUNET_MQ_send (sh->mq, 762 GNUNET_MQ_send(sh->mq,
768 ev); 763 ev);
769} 764}
770 765
771 766
@@ -775,27 +770,27 @@ GNUNET_ATS_address_update (struct GNUNET_ATS_AddressRecord *ar,
775 * @param ar address to destroy 770 * @param ar address to destroy
776 */ 771 */
777void 772void
778GNUNET_ATS_address_destroy (struct GNUNET_ATS_AddressRecord *ar) 773GNUNET_ATS_address_destroy(struct GNUNET_ATS_AddressRecord *ar)
779{ 774{
780 struct GNUNET_ATS_SchedulingHandle *sh = ar->sh; 775 struct GNUNET_ATS_SchedulingHandle *sh = ar->sh;
781 struct GNUNET_MQ_Envelope *ev; 776 struct GNUNET_MQ_Envelope *ev;
782 struct AddressDestroyedMessage *m; 777 struct AddressDestroyedMessage *m;
783 778
784 LOG (GNUNET_ERROR_TYPE_DEBUG, 779 LOG(GNUNET_ERROR_TYPE_DEBUG,
785 "Deleting address for peer `%s', plugin `%s', slot %u session %p\n", 780 "Deleting address for peer `%s', plugin `%s', slot %u session %p\n",
786 GNUNET_i2s (&ar->address->peer), 781 GNUNET_i2s(&ar->address->peer),
787 ar->address->transport_name, 782 ar->address->transport_name,
788 ar->slot, 783 ar->slot,
789 ar->session); 784 ar->session);
790 GNUNET_break (NULL == ar->session); 785 GNUNET_break(NULL == ar->session);
791 ar->session = NULL; 786 ar->session = NULL;
792 ar->in_destroy = GNUNET_YES; 787 ar->in_destroy = GNUNET_YES;
793 if (NULL == sh->mq) 788 if (NULL == sh->mq)
794 return; 789 return;
795 ev = GNUNET_MQ_msg (m, GNUNET_MESSAGE_TYPE_ATS_ADDRESS_DESTROYED); 790 ev = GNUNET_MQ_msg(m, GNUNET_MESSAGE_TYPE_ATS_ADDRESS_DESTROYED);
796 m->session_id = htonl (ar->slot); 791 m->session_id = htonl(ar->slot);
797 m->peer = ar->address->peer; 792 m->peer = ar->address->peer;
798 GNUNET_MQ_send (sh->mq, ev); 793 GNUNET_MQ_send(sh->mq, ev);
799} 794}
800 795
801 796