aboutsummaryrefslogtreecommitdiff
path: root/src/transport
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2011-10-25 14:48:34 +0000
committerChristian Grothoff <christian@grothoff.org>2011-10-25 14:48:34 +0000
commit0307ab82093f876665e4ac77fffa0a52e0d6d89c (patch)
tree789ab6827194f957ad5004aac8832e5deda6c559 /src/transport
parentc8a0ccb72aa1527e8610063700d2ae5718253897 (diff)
downloadgnunet-0307ab82093f876665e4ac77fffa0a52e0d6d89c.tar.gz
gnunet-0307ab82093f876665e4ac77fffa0a52e0d6d89c.zip
trying to fix #1813 by actually respecting delay values, also some minor code cleanup
Diffstat (limited to 'src/transport')
-rw-r--r--src/transport/plugin_transport_udp.c92
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 */
355struct Session * 357static struct Session *
356find_session (struct Plugin *plugin, const struct GNUNET_PeerIdentity *peer) 358find_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
362int inbound_session_iterator (void *cls, 364
363 const GNUNET_HashCode * key, 365static int
364 void *value) 366inbound_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 */
386struct Session * 390static struct Session *
387find_inbound_session (struct Plugin *plugin, 391find_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
400int inbound_session_by_addr_iterator (void *cls, 404
401 const GNUNET_HashCode * key, 405static int
402 void *value) 406inbound_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 */
425struct Session * 431static struct Session *
426find_inbound_session_by_addr (struct Plugin *plugin, const void * addr, size_t addrlen) 432find_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
581static struct Session * 594static struct Session *
582create_session (struct Plugin *plugin, const struct GNUNET_PeerIdentity *target, 595create_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,
649static const char * 662static const char *
650udp_address_to_string (void *cls, const void *addr, size_t addrlen); 663udp_address_to_string (void *cls, const void *addr, size_t addrlen);
651 664
665
666static void
667udp_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))