diff options
-rw-r--r-- | src/transport/plugin_transport_udp.c | 92 |
1 files changed, 60 insertions, 32 deletions
diff --git a/src/transport/plugin_transport_udp.c b/src/transport/plugin_transport_udp.c index fa632f28a..ad5b165b1 100644 --- a/src/transport/plugin_transport_udp.c +++ b/src/transport/plugin_transport_udp.c | |||
@@ -197,12 +197,14 @@ struct Session | |||
197 | 197 | ||
198 | GNUNET_SCHEDULER_TaskIdentifier invalidation_task; | 198 | GNUNET_SCHEDULER_TaskIdentifier invalidation_task; |
199 | 199 | ||
200 | /* | 200 | GNUNET_SCHEDULER_TaskIdentifier delayed_cont_task; |
201 | |||
202 | /** | ||
201 | * Desired delay for next sending we send to other peer | 203 | * Desired delay for next sending we send to other peer |
202 | */ | 204 | */ |
203 | struct GNUNET_TIME_Relative flow_delay_for_other_peer; | 205 | struct GNUNET_TIME_Relative flow_delay_for_other_peer; |
204 | 206 | ||
205 | /* | 207 | /** |
206 | * Desired delay for next sending we received from other peer | 208 | * Desired delay for next sending we received from other peer |
207 | */ | 209 | */ |
208 | struct GNUNET_TIME_Absolute flow_delay_from_other_peer; | 210 | struct GNUNET_TIME_Absolute flow_delay_from_other_peer; |
@@ -352,16 +354,18 @@ struct PeerSessionIteratorContext | |||
352 | * @param peer peer's identity | 354 | * @param peer peer's identity |
353 | * @return NULL if we have no session | 355 | * @return NULL if we have no session |
354 | */ | 356 | */ |
355 | struct Session * | 357 | static struct Session * |
356 | find_session (struct Plugin *plugin, const struct GNUNET_PeerIdentity *peer) | 358 | find_session (struct Plugin *plugin, const struct GNUNET_PeerIdentity *peer) |
357 | { | 359 | { |
358 | return GNUNET_CONTAINER_multihashmap_get (plugin->sessions, | 360 | return GNUNET_CONTAINER_multihashmap_get (plugin->sessions, |
359 | &peer->hashPubKey); | 361 | &peer->hashPubKey); |
360 | } | 362 | } |
361 | 363 | ||
362 | int inbound_session_iterator (void *cls, | 364 | |
363 | const GNUNET_HashCode * key, | 365 | static int |
364 | void *value) | 366 | inbound_session_iterator (void *cls, |
367 | const GNUNET_HashCode * key, | ||
368 | void *value) | ||
365 | { | 369 | { |
366 | struct PeerSessionIteratorContext *psc = cls; | 370 | struct PeerSessionIteratorContext *psc = cls; |
367 | struct Session *s = value; | 371 | struct Session *s = value; |
@@ -372,9 +376,9 @@ int inbound_session_iterator (void *cls, | |||
372 | } | 376 | } |
373 | if (psc->result != NULL) | 377 | if (psc->result != NULL) |
374 | return GNUNET_NO; | 378 | return GNUNET_NO; |
375 | else | 379 | return GNUNET_YES; |
376 | return GNUNET_YES; | 380 | } |
377 | }; | 381 | |
378 | 382 | ||
379 | /** | 383 | /** |
380 | * Lookup the session for the given peer. | 384 | * Lookup the session for the given peer. |
@@ -383,7 +387,7 @@ int inbound_session_iterator (void *cls, | |||
383 | * @param peer peer's identity | 387 | * @param peer peer's identity |
384 | * @return NULL if we have no session | 388 | * @return NULL if we have no session |
385 | */ | 389 | */ |
386 | struct Session * | 390 | static struct Session * |
387 | find_inbound_session (struct Plugin *plugin, | 391 | find_inbound_session (struct Plugin *plugin, |
388 | const struct GNUNET_PeerIdentity *peer, | 392 | const struct GNUNET_PeerIdentity *peer, |
389 | const void * addr, size_t addrlen) | 393 | const void * addr, size_t addrlen) |
@@ -397,9 +401,11 @@ find_inbound_session (struct Plugin *plugin, | |||
397 | return psc.result; | 401 | return psc.result; |
398 | } | 402 | } |
399 | 403 | ||
400 | int inbound_session_by_addr_iterator (void *cls, | 404 | |
401 | const GNUNET_HashCode * key, | 405 | static int |
402 | void *value) | 406 | inbound_session_by_addr_iterator (void *cls, |
407 | const GNUNET_HashCode * key, | ||
408 | void *value) | ||
403 | { | 409 | { |
404 | struct PeerSessionIteratorContext *psc = cls; | 410 | struct PeerSessionIteratorContext *psc = cls; |
405 | struct Session *s = value; | 411 | struct Session *s = value; |
@@ -422,7 +428,7 @@ int inbound_session_by_addr_iterator (void *cls, | |||
422 | * @param addrlen address length | 428 | * @param addrlen address length |
423 | * @return NULL if we have no session | 429 | * @return NULL if we have no session |
424 | */ | 430 | */ |
425 | struct Session * | 431 | static struct Session * |
426 | find_inbound_session_by_addr (struct Plugin *plugin, const void * addr, size_t addrlen) | 432 | find_inbound_session_by_addr (struct Plugin *plugin, const void * addr, size_t addrlen) |
427 | { | 433 | { |
428 | struct PeerSessionIteratorContext psc; | 434 | struct PeerSessionIteratorContext psc; |
@@ -450,6 +456,8 @@ destroy_session (void *cls, const GNUNET_HashCode * key, void *value) | |||
450 | 456 | ||
451 | if (peer_session->frag != NULL) | 457 | if (peer_session->frag != NULL) |
452 | GNUNET_FRAGMENT_context_destroy (peer_session->frag); | 458 | GNUNET_FRAGMENT_context_destroy (peer_session->frag); |
459 | if (GNUNET_SCHEDULER_NO_TASK != peer_session->delayed_cont_task) | ||
460 | GNUNET_SCHEDULER_cancel (peer_session->delayed_cont_task); | ||
453 | GNUNET_free (peer_session); | 461 | GNUNET_free (peer_session); |
454 | return GNUNET_OK; | 462 | return GNUNET_OK; |
455 | } | 463 | } |
@@ -469,6 +477,8 @@ destroy_inbound_session (void *cls, const GNUNET_HashCode * key, void *value) | |||
469 | 477 | ||
470 | if (s->invalidation_task != GNUNET_SCHEDULER_NO_TASK) | 478 | if (s->invalidation_task != GNUNET_SCHEDULER_NO_TASK) |
471 | GNUNET_SCHEDULER_cancel(s->invalidation_task); | 479 | GNUNET_SCHEDULER_cancel(s->invalidation_task); |
480 | if (GNUNET_SCHEDULER_NO_TASK != s->delayed_cont_task) | ||
481 | GNUNET_SCHEDULER_cancel (s->delayed_cont_task); | ||
472 | GNUNET_free (s); | 482 | GNUNET_free (s); |
473 | return GNUNET_OK; | 483 | return GNUNET_OK; |
474 | } | 484 | } |
@@ -502,6 +512,8 @@ udp_disconnect (void *cls, const struct GNUNET_PeerIdentity *target) | |||
502 | "UDP DISCONNECT\n"); | 512 | "UDP DISCONNECT\n"); |
503 | 513 | ||
504 | plugin->last_expected_delay = GNUNET_FRAGMENT_context_destroy (session->frag); | 514 | plugin->last_expected_delay = GNUNET_FRAGMENT_context_destroy (session->frag); |
515 | if (GNUNET_SCHEDULER_NO_TASK != session->delayed_cont_task) | ||
516 | GNUNET_SCHEDULER_cancel (session->delayed_cont_task); | ||
505 | if (session->cont != NULL) | 517 | if (session->cont != NULL) |
506 | session->cont (session->cont_cls, target, GNUNET_SYSERR); | 518 | session->cont (session->cont_cls, target, GNUNET_SYSERR); |
507 | GNUNET_free (session); | 519 | GNUNET_free (session); |
@@ -578,6 +590,7 @@ send_fragment (void *cls, const struct GNUNET_MessageHeader *msg) | |||
578 | GNUNET_FRAGMENT_context_transmission_done (session->frag); | 590 | GNUNET_FRAGMENT_context_transmission_done (session->frag); |
579 | } | 591 | } |
580 | 592 | ||
593 | |||
581 | static struct Session * | 594 | static struct Session * |
582 | create_session (struct Plugin *plugin, const struct GNUNET_PeerIdentity *target, | 595 | create_session (struct Plugin *plugin, const struct GNUNET_PeerIdentity *target, |
583 | const void *addr, size_t addrlen, | 596 | const void *addr, size_t addrlen, |
@@ -649,6 +662,20 @@ create_session (struct Plugin *plugin, const struct GNUNET_PeerIdentity *target, | |||
649 | static const char * | 662 | static const char * |
650 | udp_address_to_string (void *cls, const void *addr, size_t addrlen); | 663 | udp_address_to_string (void *cls, const void *addr, size_t addrlen); |
651 | 664 | ||
665 | |||
666 | static void | ||
667 | udp_call_continuation (void *cls, | ||
668 | const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
669 | { | ||
670 | struct Session *s = cls; | ||
671 | GNUNET_TRANSPORT_TransmitContinuation cont = s->cont; | ||
672 | |||
673 | s->delayed_cont_task = GNUNET_SCHEDULER_NO_TASK; | ||
674 | s->cont = NULL; | ||
675 | cont (s->cont_cls, &s->target, GNUNET_OK); | ||
676 | } | ||
677 | |||
678 | |||
652 | /** | 679 | /** |
653 | * Function that can be used by the transport service to transmit | 680 | * Function that can be used by the transport service to transmit |
654 | * a message using the plugin. | 681 | * a message using the plugin. |
@@ -688,6 +715,7 @@ udp_plugin_send (void *cls, const struct GNUNET_PeerIdentity *target, | |||
688 | size_t mlen = msgbuf_size + sizeof (struct UDPMessage); | 715 | size_t mlen = msgbuf_size + sizeof (struct UDPMessage); |
689 | char mbuf[mlen]; | 716 | char mbuf[mlen]; |
690 | struct UDPMessage *udp; | 717 | struct UDPMessage *udp; |
718 | struct GNUNET_TIME_Relative delta; | ||
691 | 719 | ||
692 | if (mlen >= GNUNET_SERVER_MAX_MESSAGE_SIZE) | 720 | if (mlen >= GNUNET_SERVER_MAX_MESSAGE_SIZE) |
693 | { | 721 | { |
@@ -771,27 +799,27 @@ udp_plugin_send (void *cls, const struct GNUNET_PeerIdentity *target, | |||
771 | udp->sender = *plugin->env->my_identity; | 799 | udp->sender = *plugin->env->my_identity; |
772 | memcpy (&udp[1], msgbuf, msgbuf_size); | 800 | memcpy (&udp[1], msgbuf, msgbuf_size); |
773 | 801 | ||
774 | if (s != NULL) | 802 | if (s != NULL) |
775 | { | 803 | delta = GNUNET_TIME_absolute_get_remaining (s->flow_delay_from_other_peer); |
776 | struct GNUNET_TIME_Absolute now = GNUNET_TIME_absolute_get(); | ||
777 | if (s->flow_delay_from_other_peer.abs_value > now.abs_value) | ||
778 | { | ||
779 | struct GNUNET_TIME_Relative delta = GNUNET_TIME_absolute_get_difference(now, s->flow_delay_from_other_peer); | ||
780 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
781 | "We try to send to early! Should in %llu!\n", delta.rel_value); | ||
782 | } | ||
783 | else | ||
784 | LOG (GNUNET_ERROR_TYPE_DEBUG, | ||
785 | "We can send!\n"); | ||
786 | } | ||
787 | else | 804 | else |
788 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 805 | delta = GNUNET_TIME_UNIT_ZERO; |
789 | "SENDING without session!\n"); | ||
790 | if (mlen <= UDP_MTU) | 806 | if (mlen <= UDP_MTU) |
791 | { | 807 | { |
792 | mlen = udp_send (plugin, peer_session->sock_addr, &udp->header); | 808 | mlen = udp_send (plugin, peer_session->sock_addr, &udp->header); |
793 | if (cont != NULL) | 809 | if (cont != NULL) |
794 | cont (cont_cls, target, (mlen > 0) ? GNUNET_OK : GNUNET_SYSERR); | 810 | { |
811 | if ( (delta.rel_value > 0) && | ||
812 | (mlen > 0) ) | ||
813 | { | ||
814 | s->cont = cont; | ||
815 | s->cont_cls = cont_cls; | ||
816 | s->delayed_cont_task = GNUNET_SCHEDULER_add_delayed (delta, | ||
817 | &udp_call_continuation, | ||
818 | s); | ||
819 | } | ||
820 | else | ||
821 | cont (cont_cls, target, (mlen > 0) ? GNUNET_OK : GNUNET_SYSERR); | ||
822 | } | ||
795 | GNUNET_free_non_null (peer_session); | 823 | GNUNET_free_non_null (peer_session); |
796 | } | 824 | } |
797 | else | 825 | else |
@@ -970,7 +998,7 @@ process_udp_message (struct Plugin *plugin, const struct UDPMessage *msg, | |||
970 | s, | 998 | s, |
971 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE)); | 999 | GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE)); |
972 | } | 1000 | } |
973 | s->valid_until = GNUNET_TIME_absolute_add(GNUNET_TIME_absolute_get(), GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT); | 1001 | s->valid_until = GNUNET_TIME_relative_to_absolute (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT); |
974 | if (s->invalidation_task != GNUNET_SCHEDULER_NO_TASK) | 1002 | if (s->invalidation_task != GNUNET_SCHEDULER_NO_TASK) |
975 | { | 1003 | { |
976 | GNUNET_SCHEDULER_cancel(s->invalidation_task); | 1004 | GNUNET_SCHEDULER_cancel(s->invalidation_task); |
@@ -1186,7 +1214,7 @@ udp_read (struct Plugin *plugin, struct GNUNET_NETWORK_Handle *rsock) | |||
1186 | LOG (GNUNET_ERROR_TYPE_DEBUG, | 1214 | LOG (GNUNET_ERROR_TYPE_DEBUG, |
1187 | "We received a sending delay of %llu\n", flow_delay.rel_value); | 1215 | "We received a sending delay of %llu\n", flow_delay.rel_value); |
1188 | 1216 | ||
1189 | s->flow_delay_from_other_peer = GNUNET_TIME_absolute_add(GNUNET_TIME_absolute_get(), flow_delay); | 1217 | s->flow_delay_from_other_peer = GNUNET_TIME_relative_to_absolute (flow_delay); |
1190 | } | 1218 | } |
1191 | ack = (const struct GNUNET_MessageHeader *) &udp_ack[1]; | 1219 | ack = (const struct GNUNET_MessageHeader *) &udp_ack[1]; |
1192 | if (ntohs (ack->size) != ntohs (msg->size) - sizeof (struct UDP_ACK_Message)) | 1220 | if (ntohs (ack->size) != ntohs (msg->size) - sizeof (struct UDP_ACK_Message)) |