diff options
author | Christian Grothoff <christian@grothoff.org> | 2014-01-30 19:22:23 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2014-01-30 19:22:23 +0000 |
commit | 6daf13eaa64b5b041edce219f30ab8dcfe38cdf5 (patch) | |
tree | c56e4517a0ee08cfb013e296b7d7cf33f2ab49d8 /src | |
parent | 6fd0a7efde08115b568b99b7755861a50f1b6c2e (diff) | |
download | gnunet-6daf13eaa64b5b041edce219f30ab8dcfe38cdf5.tar.gz gnunet-6daf13eaa64b5b041edce219f30ab8dcfe38cdf5.zip |
-towards fixing #3295 (core traffic prioritization)
Diffstat (limited to 'src')
-rw-r--r-- | src/core/core.h | 2 | ||||
-rw-r--r-- | src/core/core_api.c | 11 | ||||
-rw-r--r-- | src/core/gnunet-service-core_clients.c | 22 | ||||
-rw-r--r-- | src/core/gnunet-service-core_sessions.c | 149 | ||||
-rw-r--r-- | src/core/gnunet-service-core_sessions.h | 5 | ||||
-rw-r--r-- | src/fs/gnunet-service-fs_cp.c | 2 | ||||
-rw-r--r-- | src/include/gnunet_core_service.h | 19 |
7 files changed, 152 insertions, 58 deletions
diff --git a/src/core/core.h b/src/core/core.h index 17014d6ec..1c6e0bc72 100644 --- a/src/core/core.h +++ b/src/core/core.h | |||
@@ -286,7 +286,7 @@ struct SendMessage | |||
286 | /** | 286 | /** |
287 | * Always 0. | 287 | * Always 0. |
288 | */ | 288 | */ |
289 | uint64_t reserved GNUNET_PACKED; | 289 | uint32_t reserved GNUNET_PACKED; |
290 | 290 | ||
291 | }; | 291 | }; |
292 | 292 | ||
diff --git a/src/core/core_api.c b/src/core/core_api.c index 56bd29df3..7818a60a3 100644 --- a/src/core/core_api.c +++ b/src/core/core_api.c | |||
@@ -700,7 +700,8 @@ transmit_message (void *cls, size_t size, void *buf) | |||
700 | * @param ignore_currently_down transmit message even if not initialized? | 700 | * @param ignore_currently_down transmit message even if not initialized? |
701 | */ | 701 | */ |
702 | static void | 702 | static void |
703 | trigger_next_request (struct GNUNET_CORE_Handle *h, int ignore_currently_down) | 703 | trigger_next_request (struct GNUNET_CORE_Handle *h, |
704 | int ignore_currently_down) | ||
704 | { | 705 | { |
705 | uint16_t msize; | 706 | uint16_t msize; |
706 | 707 | ||
@@ -742,7 +743,8 @@ trigger_next_request (struct GNUNET_CORE_Handle *h, int ignore_currently_down) | |||
742 | * @param msg the message received from the core service | 743 | * @param msg the message received from the core service |
743 | */ | 744 | */ |
744 | static void | 745 | static void |
745 | main_notify_handler (void *cls, const struct GNUNET_MessageHeader *msg) | 746 | main_notify_handler (void *cls, |
747 | const struct GNUNET_MessageHeader *msg) | ||
746 | { | 748 | { |
747 | struct GNUNET_CORE_Handle *h = cls; | 749 | struct GNUNET_CORE_Handle *h = cls; |
748 | const struct InitReplyMessage *m; | 750 | const struct InitReplyMessage *m; |
@@ -1265,7 +1267,7 @@ run_request_next_transmission (void *cls, | |||
1265 | * @param handle connection to core service | 1267 | * @param handle connection to core service |
1266 | * @param cork is corking allowed for this transmission? | 1268 | * @param cork is corking allowed for this transmission? |
1267 | * @param priority how important is the message? | 1269 | * @param priority how important is the message? |
1268 | * @param maxdelay how long can the message wait? | 1270 | * @param maxdelay how long can the message wait? Only effective if @a cork is #GNUNET_YES |
1269 | * @param target who should receive the message, never NULL (can be this peer's identity for loopback) | 1271 | * @param target who should receive the message, never NULL (can be this peer's identity for loopback) |
1270 | * @param notify_size how many bytes of buffer space does @a notify want? | 1272 | * @param notify_size how many bytes of buffer space does @a notify want? |
1271 | * @param notify function to call when buffer space is available; | 1273 | * @param notify function to call when buffer space is available; |
@@ -1278,7 +1280,8 @@ run_request_next_transmission (void *cls, | |||
1278 | * if NULL is returned, @a notify will NOT be called. | 1280 | * if NULL is returned, @a notify will NOT be called. |
1279 | */ | 1281 | */ |
1280 | struct GNUNET_CORE_TransmitHandle * | 1282 | struct GNUNET_CORE_TransmitHandle * |
1281 | GNUNET_CORE_notify_transmit_ready (struct GNUNET_CORE_Handle *handle, int cork, | 1283 | GNUNET_CORE_notify_transmit_ready (struct GNUNET_CORE_Handle *handle, |
1284 | int cork, | ||
1282 | enum GNUNET_CORE_Priority priority, | 1285 | enum GNUNET_CORE_Priority priority, |
1283 | struct GNUNET_TIME_Relative maxdelay, | 1286 | struct GNUNET_TIME_Relative maxdelay, |
1284 | const struct GNUNET_PeerIdentity *target, | 1287 | const struct GNUNET_PeerIdentity *target, |
diff --git a/src/core/gnunet-service-core_clients.c b/src/core/gnunet-service-core_clients.c index f153ac397..fa87f82e6 100644 --- a/src/core/gnunet-service-core_clients.c +++ b/src/core/gnunet-service-core_clients.c | |||
@@ -419,6 +419,11 @@ struct TokenizerContext | |||
419 | struct GSC_ClientActiveRequest *car; | 419 | struct GSC_ClientActiveRequest *car; |
420 | 420 | ||
421 | /** | 421 | /** |
422 | * How important is this message. | ||
423 | */ | ||
424 | enum GNUNET_CORE_Priority priority; | ||
425 | |||
426 | /** | ||
422 | * Is corking allowed (set only once we have the real message). | 427 | * Is corking allowed (set only once we have the real message). |
423 | */ | 428 | */ |
424 | int cork; | 429 | int cork; |
@@ -454,7 +459,7 @@ handle_client_send (void *cls, struct GNUNET_SERVER_Client *client, | |||
454 | msize -= sizeof (struct SendMessage); | 459 | msize -= sizeof (struct SendMessage); |
455 | GNUNET_break (0 == ntohl (sm->reserved)); | 460 | GNUNET_break (0 == ntohl (sm->reserved)); |
456 | c = find_client (client); | 461 | c = find_client (client); |
457 | if (c == NULL) | 462 | if (NULL == c) |
458 | { | 463 | { |
459 | /* client did not send INIT first! */ | 464 | /* client did not send INIT first! */ |
460 | GNUNET_break (0); | 465 | GNUNET_break (0); |
@@ -482,10 +487,13 @@ handle_client_send (void *cls, struct GNUNET_SERVER_Client *client, | |||
482 | &sm->peer, | 487 | &sm->peer, |
483 | tc.car)); | 488 | tc.car)); |
484 | tc.cork = ntohl (sm->cork); | 489 | tc.cork = ntohl (sm->cork); |
490 | tc.priority = (enum GNUNET_CORE_Priority) ntohl (sm->priority); | ||
485 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 491 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
486 | "Client asked for transmission of %u bytes to `%s' %s\n", msize, | 492 | "Client asked for transmission of %u bytes to `%s' %s\n", |
493 | msize, | ||
487 | GNUNET_i2s (&sm->peer), tc.cork ? "now" : ""); | 494 | GNUNET_i2s (&sm->peer), tc.cork ? "now" : ""); |
488 | GNUNET_SERVER_mst_receive (client_mst, &tc, (const char *) &sm[1], msize, | 495 | GNUNET_SERVER_mst_receive (client_mst, &tc, |
496 | (const char *) &sm[1], msize, | ||
489 | GNUNET_YES, GNUNET_NO); | 497 | GNUNET_YES, GNUNET_NO); |
490 | if (0 != | 498 | if (0 != |
491 | memcmp (&tc.car->target, &GSC_my_identity, | 499 | memcmp (&tc.car->target, &GSC_my_identity, |
@@ -541,7 +549,8 @@ client_tokenizer_callback (void *cls, void *client, | |||
541 | else | 549 | else |
542 | { | 550 | { |
543 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 551 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
544 | "Delivering message of type %u to %s\n", ntohs (message->type), | 552 | "Delivering message of type %u to %s\n", |
553 | ntohs (message->type), | ||
545 | GNUNET_i2s (&car->target)); | 554 | GNUNET_i2s (&car->target)); |
546 | GSC_CLIENTS_deliver_message (&car->target, message, | 555 | GSC_CLIENTS_deliver_message (&car->target, message, |
547 | ntohs (message->size), | 556 | ntohs (message->size), |
@@ -549,7 +558,10 @@ client_tokenizer_callback (void *cls, void *client, | |||
549 | GSC_CLIENTS_deliver_message (&car->target, message, | 558 | GSC_CLIENTS_deliver_message (&car->target, message, |
550 | sizeof (struct GNUNET_MessageHeader), | 559 | sizeof (struct GNUNET_MessageHeader), |
551 | GNUNET_CORE_OPTION_SEND_HDR_OUTBOUND); | 560 | GNUNET_CORE_OPTION_SEND_HDR_OUTBOUND); |
552 | GSC_SESSIONS_transmit (car, message, tc->cork); | 561 | GSC_SESSIONS_transmit (car, |
562 | message, | ||
563 | tc->cork, | ||
564 | tc->priority); | ||
553 | } | 565 | } |
554 | return GNUNET_OK; | 566 | return GNUNET_OK; |
555 | } | 567 | } |
diff --git a/src/core/gnunet-service-core_sessions.c b/src/core/gnunet-service-core_sessions.c index eb42d6fbc..080bbf88b 100644 --- a/src/core/gnunet-service-core_sessions.c +++ b/src/core/gnunet-service-core_sessions.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | This file is part of GNUnet. | 2 | This file is part of GNUnet. |
3 | (C) 2009-2013 Christian Grothoff (and other contributing authors) | 3 | (C) 2009-2014 Christian Grothoff (and other contributing authors) |
4 | 4 | ||
5 | GNUnet is free software; you can redistribute it and/or modify | 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 | 6 | it under the terms of the GNU General Public License as published |
@@ -74,6 +74,11 @@ struct SessionMessageEntry | |||
74 | */ | 74 | */ |
75 | size_t size; | 75 | size_t size; |
76 | 76 | ||
77 | /** | ||
78 | * How important is this message. | ||
79 | */ | ||
80 | enum GNUNET_CORE_Priority priority; | ||
81 | |||
77 | }; | 82 | }; |
78 | 83 | ||
79 | 84 | ||
@@ -145,7 +150,7 @@ struct Session | |||
145 | 150 | ||
146 | 151 | ||
147 | /** | 152 | /** |
148 | * Map of peer identities to 'struct Session'. | 153 | * Map of peer identities to `struct Session`. |
149 | */ | 154 | */ |
150 | static struct GNUNET_CONTAINER_MultiPeerMap *sessions; | 155 | static struct GNUNET_CONTAINER_MultiPeerMap *sessions; |
151 | 156 | ||
@@ -180,7 +185,8 @@ GSC_SESSIONS_end (const struct GNUNET_PeerIdentity *pid) | |||
180 | session = find_session (pid); | 185 | session = find_session (pid); |
181 | if (NULL == session) | 186 | if (NULL == session) |
182 | return; | 187 | return; |
183 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Destroying session for peer `%4s'\n", | 188 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
189 | "Destroying session for peer `%4s'\n", | ||
184 | GNUNET_i2s (&session->peer)); | 190 | GNUNET_i2s (&session->peer)); |
185 | if (GNUNET_SCHEDULER_NO_TASK != session->cork_task) | 191 | if (GNUNET_SCHEDULER_NO_TASK != session->cork_task) |
186 | { | 192 | { |
@@ -218,11 +224,12 @@ GSC_SESSIONS_end (const struct GNUNET_PeerIdentity *pid) | |||
218 | * Transmit our current typemap message to the other peer. | 224 | * Transmit our current typemap message to the other peer. |
219 | * (Done periodically in case an update got lost). | 225 | * (Done periodically in case an update got lost). |
220 | * | 226 | * |
221 | * @param cls the 'struct Session*' | 227 | * @param cls the `struct Session *` |
222 | * @param tc unused | 228 | * @param tc unused |
223 | */ | 229 | */ |
224 | static void | 230 | static void |
225 | transmit_typemap_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | 231 | transmit_typemap_task (void *cls, |
232 | const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
226 | { | 233 | { |
227 | struct Session *session = cls; | 234 | struct Session *session = cls; |
228 | struct GNUNET_MessageHeader *hdr; | 235 | struct GNUNET_MessageHeader *hdr; |
@@ -263,7 +270,8 @@ GSC_SESSIONS_create (const struct GNUNET_PeerIdentity *peer, | |||
263 | { | 270 | { |
264 | struct Session *session; | 271 | struct Session *session; |
265 | 272 | ||
266 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Creating session for peer `%4s'\n", | 273 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
274 | "Creating session for peer `%4s'\n", | ||
267 | GNUNET_i2s (peer)); | 275 | GNUNET_i2s (peer)); |
268 | session = GNUNET_new (struct Session); | 276 | session = GNUNET_new (struct Session); |
269 | session->tmap = GSC_TYPEMAP_create (); | 277 | session->tmap = GSC_TYPEMAP_create (); |
@@ -286,13 +294,14 @@ GSC_SESSIONS_create (const struct GNUNET_PeerIdentity *peer, | |||
286 | /** | 294 | /** |
287 | * Notify the given client about the session (client is new). | 295 | * Notify the given client about the session (client is new). |
288 | * | 296 | * |
289 | * @param cls the 'struct GSC_Client' | 297 | * @param cls the `struct GSC_Client` |
290 | * @param key peer identity | 298 | * @param key peer identity |
291 | * @param value the 'struct Session' | 299 | * @param value the `struct Session` |
292 | * @return GNUNET_OK (continue to iterate) | 300 | * @return #GNUNET_OK (continue to iterate) |
293 | */ | 301 | */ |
294 | static int | 302 | static int |
295 | notify_client_about_session (void *cls, const struct GNUNET_PeerIdentity * key, | 303 | notify_client_about_session (void *cls, |
304 | const struct GNUNET_PeerIdentity *key, | ||
296 | void *value) | 305 | void *value) |
297 | { | 306 | { |
298 | struct GSC_Client *client = cls; | 307 | struct GSC_Client *client = cls; |
@@ -334,8 +343,8 @@ try_transmission (struct Session *session); | |||
334 | * | 343 | * |
335 | * @param car request to queue; this handle is then shared between | 344 | * @param car request to queue; this handle is then shared between |
336 | * the caller (CLIENTS subsystem) and SESSIONS and must not | 345 | * the caller (CLIENTS subsystem) and SESSIONS and must not |
337 | * be released by either until either 'GNUNET_SESSIONS_dequeue', | 346 | * be released by either until either #GSC_SESSIONS_dequeue(), |
338 | * 'GNUNET_SESSIONS_transmit' or 'GNUNET_CLIENTS_failed' | 347 | * #GSC_SESSIONS_transmit() or #GSC_CLIENTS_failed() |
339 | * have been invoked on it | 348 | * have been invoked on it |
340 | */ | 349 | */ |
341 | void | 350 | void |
@@ -344,7 +353,7 @@ GSC_SESSIONS_queue_request (struct GSC_ClientActiveRequest *car) | |||
344 | struct Session *session; | 353 | struct Session *session; |
345 | 354 | ||
346 | session = find_session (&car->target); | 355 | session = find_session (&car->target); |
347 | if (session == NULL) | 356 | if (NULL == session) |
348 | { | 357 | { |
349 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 358 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
350 | "Dropped client request for transmission (am disconnected)\n"); | 359 | "Dropped client request for transmission (am disconnected)\n"); |
@@ -423,27 +432,40 @@ discard_expired_requests (struct Session *session) | |||
423 | 432 | ||
424 | 433 | ||
425 | /** | 434 | /** |
426 | * Solicit messages for transmission. | 435 | * Solicit messages for transmission, starting with those of the highest |
436 | * priority. | ||
427 | * | 437 | * |
428 | * @param session session to solict messages for | 438 | * @param session session to solict messages for |
439 | * @param msize how many bytes do we have already | ||
429 | */ | 440 | */ |
430 | static void | 441 | static void |
431 | solicit_messages (struct Session *session) | 442 | solicit_messages (struct Session *session, |
443 | size_t msize) | ||
432 | { | 444 | { |
433 | struct GSC_ClientActiveRequest *car; | 445 | struct GSC_ClientActiveRequest *car; |
434 | struct GSC_ClientActiveRequest *nxt; | 446 | struct GSC_ClientActiveRequest *nxt; |
435 | size_t so_size; | 447 | size_t so_size; |
448 | enum GNUNET_CORE_Priority pmax; | ||
436 | 449 | ||
437 | discard_expired_requests (session); | 450 | discard_expired_requests (session); |
438 | so_size = 0; | 451 | so_size = msize; |
452 | pmax = GNUNET_CORE_PRIO_BACKGROUND; | ||
453 | for (car = session->active_client_request_head; NULL != car; car = car->next) | ||
454 | { | ||
455 | if (GNUNET_YES == car->was_solicited) | ||
456 | continue; | ||
457 | pmax = GNUNET_MAX (pmax, car->priority); | ||
458 | } | ||
439 | nxt = session->active_client_request_head; | 459 | nxt = session->active_client_request_head; |
440 | while (NULL != (car = nxt)) | 460 | while (NULL != (car = nxt)) |
441 | { | 461 | { |
442 | nxt = car->next; | 462 | nxt = car->next; |
463 | if (car->priority < pmax) | ||
464 | continue; | ||
443 | if (so_size + car->msize > GNUNET_CONSTANTS_MAX_ENCRYPTED_MESSAGE_SIZE) | 465 | if (so_size + car->msize > GNUNET_CONSTANTS_MAX_ENCRYPTED_MESSAGE_SIZE) |
444 | break; | 466 | break; |
445 | so_size += car->msize; | 467 | so_size += car->msize; |
446 | if (car->was_solicited == GNUNET_YES) | 468 | if (GNUNET_YES == car->was_solicited) |
447 | continue; | 469 | continue; |
448 | car->was_solicited = GNUNET_YES; | 470 | car->was_solicited = GNUNET_YES; |
449 | GSC_CLIENTS_solicit_request (car); | 471 | GSC_CLIENTS_solicit_request (car); |
@@ -455,11 +477,12 @@ solicit_messages (struct Session *session) | |||
455 | * Some messages were delayed (corked), but the timeout has now expired. | 477 | * Some messages were delayed (corked), but the timeout has now expired. |
456 | * Send them now. | 478 | * Send them now. |
457 | * | 479 | * |
458 | * @param cls 'struct Session' with the messages to transmit now | 480 | * @param cls `struct Session` with the messages to transmit now |
459 | * @param tc scheduler context (unused) | 481 | * @param tc scheduler context (unused) |
460 | */ | 482 | */ |
461 | static void | 483 | static void |
462 | pop_cork_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | 484 | pop_cork_task (void *cls, |
485 | const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
463 | { | 486 | { |
464 | struct Session *session = cls; | 487 | struct Session *session = cls; |
465 | 488 | ||
@@ -470,7 +493,8 @@ pop_cork_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
470 | 493 | ||
471 | /** | 494 | /** |
472 | * Try to perform a transmission on the given session. Will solicit | 495 | * Try to perform a transmission on the given session. Will solicit |
473 | * additional messages if the 'sme' queue is not full enough. | 496 | * additional messages if the 'sme' queue is not full enough or has |
497 | * only low-priority messages. | ||
474 | * | 498 | * |
475 | * @param session session to transmit messages from | 499 | * @param session session to transmit messages from |
476 | */ | 500 | */ |
@@ -481,33 +505,58 @@ try_transmission (struct Session *session) | |||
481 | size_t msize; | 505 | size_t msize; |
482 | struct GNUNET_TIME_Absolute now; | 506 | struct GNUNET_TIME_Absolute now; |
483 | struct GNUNET_TIME_Absolute min_deadline; | 507 | struct GNUNET_TIME_Absolute min_deadline; |
508 | enum GNUNET_CORE_Priority maxp; | ||
509 | enum GNUNET_CORE_Priority maxpc; | ||
510 | struct GSC_ClientActiveRequest *car; | ||
484 | 511 | ||
485 | if (GNUNET_YES != session->ready_to_transmit) | 512 | if (GNUNET_YES != session->ready_to_transmit) |
486 | return; | 513 | return; |
487 | msize = 0; | 514 | msize = 0; |
488 | min_deadline = GNUNET_TIME_UNIT_FOREVER_ABS; | 515 | min_deadline = GNUNET_TIME_UNIT_FOREVER_ABS; |
489 | /* check 'ready' messages */ | 516 | /* check 'ready' messages */ |
517 | maxp = GNUNET_CORE_PRIO_BACKGROUND; | ||
490 | pos = session->sme_head; | 518 | pos = session->sme_head; |
491 | while ((NULL != pos) && | 519 | while ((NULL != pos) && |
492 | (msize + pos->size <= GNUNET_CONSTANTS_MAX_ENCRYPTED_MESSAGE_SIZE)) | 520 | (msize + pos->size <= GNUNET_CONSTANTS_MAX_ENCRYPTED_MESSAGE_SIZE)) |
493 | { | 521 | { |
494 | GNUNET_assert (pos->size < GNUNET_CONSTANTS_MAX_ENCRYPTED_MESSAGE_SIZE); | 522 | GNUNET_assert (pos->size < GNUNET_CONSTANTS_MAX_ENCRYPTED_MESSAGE_SIZE); |
495 | msize += pos->size; | 523 | msize += pos->size; |
524 | maxp = GNUNET_MAX (maxp, pos->priority); | ||
496 | min_deadline = GNUNET_TIME_absolute_min (min_deadline, pos->deadline); | 525 | min_deadline = GNUNET_TIME_absolute_min (min_deadline, pos->deadline); |
497 | pos = pos->next; | 526 | pos = pos->next; |
498 | } | 527 | } |
528 | if (maxp < GNUNET_CORE_PRIO_CRITICAL_CONTROL) | ||
529 | { | ||
530 | maxpc = GNUNET_CORE_PRIO_BACKGROUND; | ||
531 | for (car = session->active_client_request_head; NULL != car; car = car->next) | ||
532 | { | ||
533 | if (GNUNET_YES == car->was_solicited) | ||
534 | continue; | ||
535 | maxpc = GNUNET_MAX (maxpc, car->priority); | ||
536 | } | ||
537 | if (maxpc > maxp) | ||
538 | { | ||
539 | /* we have messages waiting for solicitation that have a higher | ||
540 | priority than those that we already accepted; solicit the | ||
541 | high-priority messages first */ | ||
542 | solicit_messages (session, 0); | ||
543 | return; | ||
544 | } | ||
545 | } | ||
546 | |||
499 | now = GNUNET_TIME_absolute_get (); | 547 | now = GNUNET_TIME_absolute_get (); |
500 | if ((msize == 0) || | 548 | if ((0 == msize) || |
501 | ((msize < GNUNET_CONSTANTS_MAX_ENCRYPTED_MESSAGE_SIZE / 2) && | 549 | ((msize < GNUNET_CONSTANTS_MAX_ENCRYPTED_MESSAGE_SIZE / 2) && |
502 | (min_deadline.abs_value_us > now.abs_value_us))) | 550 | (min_deadline.abs_value_us > now.abs_value_us))) |
503 | { | 551 | { |
504 | /* not enough ready yet, try to solicit more */ | 552 | /* not enough ready yet, try to solicit more */ |
505 | solicit_messages (session); | 553 | solicit_messages (session, |
554 | msize); | ||
506 | if (msize > 0) | 555 | if (msize > 0) |
507 | { | 556 | { |
508 | /* if there is data to send, just not yet, make sure we do transmit | 557 | /* if there is data to send, just not yet, make sure we do transmit |
509 | * it once the deadline is reached */ | 558 | * it once the deadline is reached */ |
510 | if (session->cork_task != GNUNET_SCHEDULER_NO_TASK) | 559 | if (GNUNET_SCHEDULER_NO_TASK != session->cork_task) |
511 | GNUNET_SCHEDULER_cancel (session->cork_task); | 560 | GNUNET_SCHEDULER_cancel (session->cork_task); |
512 | session->cork_task = | 561 | session->cork_task = |
513 | GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_absolute_get_remaining | 562 | GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_absolute_get_remaining |
@@ -540,7 +589,8 @@ try_transmission (struct Session *session) | |||
540 | total_msgs = 1; | 589 | total_msgs = 1; |
541 | total_bytes = used; | 590 | total_bytes = used; |
542 | } | 591 | } |
543 | GNUNET_STATISTICS_set (GSC_stats, "# avg payload per encrypted message", | 592 | GNUNET_STATISTICS_set (GSC_stats, |
593 | "# avg payload per encrypted message", | ||
544 | total_bytes / total_msgs, GNUNET_NO); | 594 | total_bytes / total_msgs, GNUNET_NO); |
545 | /* now actually transmit... */ | 595 | /* now actually transmit... */ |
546 | session->ready_to_transmit = GNUNET_NO; | 596 | session->ready_to_transmit = GNUNET_NO; |
@@ -554,11 +604,13 @@ try_transmission (struct Session *session) | |||
554 | * | 604 | * |
555 | * @param cls the message | 605 | * @param cls the message |
556 | * @param key neighbour's identity | 606 | * @param key neighbour's identity |
557 | * @param value 'struct Neighbour' of the target | 607 | * @param value `struct Neighbour` of the target |
558 | * @return always GNUNET_OK | 608 | * @return always #GNUNET_OK |
559 | */ | 609 | */ |
560 | static int | 610 | static int |
561 | do_send_message (void *cls, const struct GNUNET_PeerIdentity * key, void *value) | 611 | do_send_message (void *cls, |
612 | const struct GNUNET_PeerIdentity *key, | ||
613 | void *value) | ||
562 | { | 614 | { |
563 | const struct GNUNET_MessageHeader *hdr = cls; | 615 | const struct GNUNET_MessageHeader *hdr = cls; |
564 | struct Session *session = value; | 616 | struct Session *session = value; |
@@ -569,7 +621,8 @@ do_send_message (void *cls, const struct GNUNET_PeerIdentity * key, void *value) | |||
569 | m = GNUNET_malloc (sizeof (struct SessionMessageEntry) + size); | 621 | m = GNUNET_malloc (sizeof (struct SessionMessageEntry) + size); |
570 | memcpy (&m[1], hdr, size); | 622 | memcpy (&m[1], hdr, size); |
571 | m->size = size; | 623 | m->size = size; |
572 | GNUNET_CONTAINER_DLL_insert (session->sme_head, session->sme_tail, m); | 624 | m->priority = GNUNET_CORE_PRIO_CRITICAL_CONTROL; |
625 | GNUNET_CONTAINER_DLL_insert_tail (session->sme_head, session->sme_tail, m); | ||
573 | try_transmission (session); | 626 | try_transmission (session); |
574 | return GNUNET_OK; | 627 | return GNUNET_OK; |
575 | } | 628 | } |
@@ -585,7 +638,8 @@ GSC_SESSIONS_broadcast (const struct GNUNET_MessageHeader *msg) | |||
585 | { | 638 | { |
586 | if (NULL == sessions) | 639 | if (NULL == sessions) |
587 | return; | 640 | return; |
588 | GNUNET_CONTAINER_multipeermap_iterate (sessions, &do_send_message, | 641 | GNUNET_CONTAINER_multipeermap_iterate (sessions, |
642 | &do_send_message, | ||
589 | (void *) msg); | 643 | (void *) msg); |
590 | } | 644 | } |
591 | 645 | ||
@@ -617,13 +671,17 @@ GSC_SESSIONS_solicit (const struct GNUNET_PeerIdentity *pid) | |||
617 | * this handle will now be 'owned' by the SESSIONS subsystem | 671 | * this handle will now be 'owned' by the SESSIONS subsystem |
618 | * @param msg message to transmit | 672 | * @param msg message to transmit |
619 | * @param cork is corking allowed? | 673 | * @param cork is corking allowed? |
674 | * @param priority how important is this message | ||
620 | */ | 675 | */ |
621 | void | 676 | void |
622 | GSC_SESSIONS_transmit (struct GSC_ClientActiveRequest *car, | 677 | GSC_SESSIONS_transmit (struct GSC_ClientActiveRequest *car, |
623 | const struct GNUNET_MessageHeader *msg, int cork) | 678 | const struct GNUNET_MessageHeader *msg, |
679 | int cork, | ||
680 | enum GNUNET_CORE_Priority priority) | ||
624 | { | 681 | { |
625 | struct Session *session; | 682 | struct Session *session; |
626 | struct SessionMessageEntry *sme; | 683 | struct SessionMessageEntry *sme; |
684 | struct SessionMessageEntry *pos; | ||
627 | size_t msize; | 685 | size_t msize; |
628 | 686 | ||
629 | session = find_session (&car->target); | 687 | session = find_session (&car->target); |
@@ -633,10 +691,23 @@ GSC_SESSIONS_transmit (struct GSC_ClientActiveRequest *car, | |||
633 | sme = GNUNET_malloc (sizeof (struct SessionMessageEntry) + msize); | 691 | sme = GNUNET_malloc (sizeof (struct SessionMessageEntry) + msize); |
634 | memcpy (&sme[1], msg, msize); | 692 | memcpy (&sme[1], msg, msize); |
635 | sme->size = msize; | 693 | sme->size = msize; |
694 | sme->priority = priority; | ||
636 | if (GNUNET_YES == cork) | 695 | if (GNUNET_YES == cork) |
637 | sme->deadline = | 696 | sme->deadline = |
638 | GNUNET_TIME_relative_to_absolute (GNUNET_CONSTANTS_MAX_CORK_DELAY); | 697 | GNUNET_TIME_relative_to_absolute (GNUNET_CONSTANTS_MAX_CORK_DELAY); |
639 | GNUNET_CONTAINER_DLL_insert_tail (session->sme_head, session->sme_tail, sme); | 698 | pos = session->sme_head; |
699 | while ( (NULL != pos) && | ||
700 | (pos->priority > sme->priority) ) | ||
701 | pos = pos->next; | ||
702 | if (NULL == pos) | ||
703 | GNUNET_CONTAINER_DLL_insert_tail (session->sme_head, | ||
704 | session->sme_tail, | ||
705 | sme); | ||
706 | else | ||
707 | GNUNET_CONTAINER_DLL_insert_after (session->sme_head, | ||
708 | session->sme_tail, | ||
709 | pos->prev, | ||
710 | sme); | ||
640 | try_transmission (session); | 711 | try_transmission (session); |
641 | } | 712 | } |
642 | 713 | ||
@@ -644,14 +715,16 @@ GSC_SESSIONS_transmit (struct GSC_ClientActiveRequest *car, | |||
644 | /** | 715 | /** |
645 | * Helper function for GSC_SESSIONS_handle_client_iterate_peers. | 716 | * Helper function for GSC_SESSIONS_handle_client_iterate_peers. |
646 | * | 717 | * |
647 | * @param cls the 'struct GNUNET_SERVER_TransmitContext' to queue replies | 718 | * @param cls the `struct GNUNET_SERVER_TransmitContext` to queue replies |
648 | * @param key identity of the connected peer | 719 | * @param key identity of the connected peer |
649 | * @param value the 'struct Neighbour' for the peer | 720 | * @param value the `struct Neighbour` for the peer |
650 | * @return GNUNET_OK (continue to iterate) | 721 | * @return GNUNET_OK (continue to iterate) |
651 | */ | 722 | */ |
652 | #include "core.h" | 723 | #include "core.h" |
653 | static int | 724 | static int |
654 | queue_connect_message (void *cls, const struct GNUNET_PeerIdentity * key, void *value) | 725 | queue_connect_message (void *cls, |
726 | const struct GNUNET_PeerIdentity *key, | ||
727 | void *value) | ||
655 | { | 728 | { |
656 | struct GNUNET_SERVER_TransmitContext *tc = cls; | 729 | struct GNUNET_SERVER_TransmitContext *tc = cls; |
657 | struct Session *session = value; | 730 | struct Session *session = value; |
@@ -768,11 +841,13 @@ GSC_SESSIONS_init () | |||
768 | * | 841 | * |
769 | * @param cls NULL | 842 | * @param cls NULL |
770 | * @param key identity of the connected peer | 843 | * @param key identity of the connected peer |
771 | * @param value the 'struct Session' for the peer | 844 | * @param value the `struct Session` for the peer |
772 | * @return GNUNET_OK (continue to iterate) | 845 | * @return #GNUNET_OK (continue to iterate) |
773 | */ | 846 | */ |
774 | static int | 847 | static int |
775 | free_session_helper (void *cls, const struct GNUNET_PeerIdentity * key, void *value) | 848 | free_session_helper (void *cls, |
849 | const struct GNUNET_PeerIdentity *key, | ||
850 | void *value) | ||
776 | { | 851 | { |
777 | struct Session *session = value; | 852 | struct Session *session = value; |
778 | 853 | ||
diff --git a/src/core/gnunet-service-core_sessions.h b/src/core/gnunet-service-core_sessions.h index d578e3d72..cc88548ec 100644 --- a/src/core/gnunet-service-core_sessions.h +++ b/src/core/gnunet-service-core_sessions.h | |||
@@ -92,10 +92,13 @@ GSC_SESSIONS_dequeue_request (struct GSC_ClientActiveRequest *car); | |||
92 | * ownership does not change (dequeue will be called soon). | 92 | * ownership does not change (dequeue will be called soon). |
93 | * @param msg message to transmit | 93 | * @param msg message to transmit |
94 | * @param cork is corking allowed? | 94 | * @param cork is corking allowed? |
95 | * @param priority how important is this message | ||
95 | */ | 96 | */ |
96 | void | 97 | void |
97 | GSC_SESSIONS_transmit (struct GSC_ClientActiveRequest *car, | 98 | GSC_SESSIONS_transmit (struct GSC_ClientActiveRequest *car, |
98 | const struct GNUNET_MessageHeader *msg, int cork); | 99 | const struct GNUNET_MessageHeader *msg, |
100 | int cork, | ||
101 | enum GNUNET_CORE_Priority priority); | ||
99 | 102 | ||
100 | 103 | ||
101 | /** | 104 | /** |
diff --git a/src/fs/gnunet-service-fs_cp.c b/src/fs/gnunet-service-fs_cp.c index 82b1f5867..087376218 100644 --- a/src/fs/gnunet-service-fs_cp.c +++ b/src/fs/gnunet-service-fs_cp.c | |||
@@ -268,7 +268,7 @@ struct GSF_ConnectedPeer | |||
268 | 268 | ||
269 | /** | 269 | /** |
270 | * Set to 1 if we're currently in the process of calling | 270 | * Set to 1 if we're currently in the process of calling |
271 | * #GNUNET_CORE_notify_transmit_ready() (so while cth is | 271 | * #GNUNET_CORE_notify_transmit_ready() (so while @e cth is |
272 | * NULL, we should not call notify_transmit_ready for this | 272 | * NULL, we should not call notify_transmit_ready for this |
273 | * handle right now). | 273 | * handle right now). |
274 | */ | 274 | */ |
diff --git a/src/include/gnunet_core_service.h b/src/include/gnunet_core_service.h index 6c68a6833..b0248323a 100644 --- a/src/include/gnunet_core_service.h +++ b/src/include/gnunet_core_service.h | |||
@@ -53,24 +53,25 @@ enum GNUNET_CORE_Priority | |||
53 | { | 53 | { |
54 | 54 | ||
55 | /** | 55 | /** |
56 | * Highest priority, control traffic (i.e. NSE, Core/Mesh KX). | 56 | * Lowest priority, i.e. background traffic (i.e. fs) |
57 | */ | 57 | */ |
58 | GNUNET_CORE_PRIO_CRITICAL_CONTROL = 0, | 58 | GNUNET_CORE_PRIO_BACKGROUND = 0, |
59 | 59 | ||
60 | /** | 60 | /** |
61 | * Urgent traffic (local peer, i.e. conversation). | 61 | * Normal traffic (i.e. mesh/dv relay, DHT) |
62 | */ | 62 | */ |
63 | GNUNET_CORE_PRIO_URGENT = 1, | 63 | GNUNET_CORE_PRIO_BEST_EFFORT = 1, |
64 | 64 | ||
65 | /** | 65 | /** |
66 | * Normal traffic (i.e. mesh/dv relay, DHT) | 66 | * Urgent traffic (local peer, i.e. conversation). |
67 | */ | 67 | */ |
68 | GNUNET_CORE_PRIO_BEST_EFFORT = 2, | 68 | GNUNET_CORE_PRIO_URGENT = 2, |
69 | 69 | ||
70 | /** | 70 | /** |
71 | * Background traffic (i.e. fs) | 71 | * Highest priority, control traffic (i.e. NSE, Core/Mesh KX). |
72 | */ | 72 | */ |
73 | GNUNET_CORE_PRIO_BACKGROUND = 3 | 73 | GNUNET_CORE_PRIO_CRITICAL_CONTROL = 3 |
74 | |||
74 | 75 | ||
75 | }; | 76 | }; |
76 | 77 | ||
@@ -250,7 +251,7 @@ struct GNUNET_CORE_TransmitHandle; | |||
250 | * @param handle connection to core service | 251 | * @param handle connection to core service |
251 | * @param cork is corking allowed for this transmission? | 252 | * @param cork is corking allowed for this transmission? |
252 | * @param priority how important is the message? | 253 | * @param priority how important is the message? |
253 | * @param maxdelay how long can the message wait? | 254 | * @param maxdelay how long can the message wait? Only effective if @a cork is #GNUNET_YES |
254 | * @param target who should receive the message, never NULL (can be this peer's identity for loopback) | 255 | * @param target who should receive the message, never NULL (can be this peer's identity for loopback) |
255 | * @param notify_size how many bytes of buffer space does notify want? | 256 | * @param notify_size how many bytes of buffer space does notify want? |
256 | * @param notify function to call when buffer space is available; | 257 | * @param notify function to call when buffer space is available; |