aboutsummaryrefslogtreecommitdiff
path: root/src/transport/plugin_transport_unix.c
diff options
context:
space:
mode:
authorMatthias Wachs <wachs@net.in.tum.de>2012-10-26 12:22:21 +0000
committerMatthias Wachs <wachs@net.in.tum.de>2012-10-26 12:22:21 +0000
commit0c1b1c5380cfff0a8e0e3adae4df2ee048a5fe88 (patch)
tree99b00e4cfba9b6c497511c7a8000a79c42befcb2 /src/transport/plugin_transport_unix.c
parentd8dc59b1cc0324392fd90f9e5d6f5adc876d4de9 (diff)
downloadgnunet-0c1b1c5380cfff0a8e0e3adae4df2ee048a5fe88.tar.gz
gnunet-0c1b1c5380cfff0a8e0e3adae4df2ee048a5fe88.zip
simplify retry mechanism
Diffstat (limited to 'src/transport/plugin_transport_unix.c')
-rw-r--r--src/transport/plugin_transport_unix.c150
1 files changed, 59 insertions, 91 deletions
diff --git a/src/transport/plugin_transport_unix.c b/src/transport/plugin_transport_unix.c
index 563df7cc7..fee1c58c0 100644
--- a/src/transport/plugin_transport_unix.c
+++ b/src/transport/plugin_transport_unix.c
@@ -43,6 +43,8 @@
43#include "transport.h" 43#include "transport.h"
44 44
45#define MAX_PROBES 20 45#define MAX_PROBES 20
46#define MAX_RETRIES 3
47#define RETRY 0
46 48
47#define LOG(kind,...) GNUNET_log_from (kind, "transport-unix",__VA_ARGS__) 49#define LOG(kind,...) GNUNET_log_from (kind, "transport-unix",__VA_ARGS__)
48 50
@@ -486,7 +488,7 @@ unix_transport_server_stop (void *cls)
486 * peer disconnected...) 488 * peer disconnected...)
487 * @param cont_cls closure for cont 489 * @param cont_cls closure for cont
488 * 490 *
489 * @return the number of bytes written, -1 on errors 491 * @return on success : the number of bytes written, 0 n retry, -1 on errors
490 */ 492 */
491static ssize_t 493static ssize_t
492unix_real_send (void *cls, 494unix_real_send (void *cls,
@@ -511,19 +513,13 @@ unix_real_send (void *cls,
511 513
512 if (send_handle == NULL) 514 if (send_handle == NULL)
513 { 515 {
514 /* We do not have a send handle */ 516 GNUNET_break (0); /* We do not have a send handle */
515 GNUNET_break (0); 517 return GNUNET_SYSERR;
516 if (cont != NULL)
517 cont (cont_cls, target, GNUNET_SYSERR, payload, 0);
518 return -1;
519 } 518 }
520 if ((addr == NULL) || (addrlen == 0)) 519 if ((addr == NULL) || (addrlen == 0))
521 { 520 {
522 /* Can never send if we don't have an address */ 521 GNUNET_break (0); /* Can never send if we don't have an address */
523 GNUNET_break (0); 522 return GNUNET_SYSERR;
524 if (cont != NULL)
525 cont (cont_cls, target, GNUNET_SYSERR, payload, 0);
526 return -1;
527 } 523 }
528 524
529 /* Prepare address */ 525 /* Prepare address */
@@ -545,86 +541,54 @@ unix_real_send (void *cls,
545 sb = (struct sockaddr *) &un; 541 sb = (struct sockaddr *) &un;
546 sbs = slen; 542 sbs = slen;
547 543
544resend:
548 /* Send the data */ 545 /* Send the data */
549 sent = 0; 546 sent = 0;
550 sent = GNUNET_NETWORK_socket_sendto (send_handle, msgbuf, msgbuf_size, sb, sbs); 547 sent = GNUNET_NETWORK_socket_sendto (send_handle, msgbuf, msgbuf_size, sb, sbs);
551 548
552 if ((GNUNET_SYSERR == sent) && ((errno == EAGAIN) || (errno == ENOBUFS))) 549 if (GNUNET_SYSERR == sent)
553 {
554 /* We have to retry later: retry */
555 return 0;
556 }
557
558 if ((GNUNET_SYSERR == sent) && (errno == EMSGSIZE))
559 { 550 {
560 socklen_t size = 0; 551 if ((errno == EAGAIN) || (errno == ENOBUFS))
561 socklen_t len = sizeof (size); 552 return RETRY; /* We have to retry later */
562 553 if (errno == EMSGSIZE)
563 GNUNET_NETWORK_socket_getsockopt ((struct GNUNET_NETWORK_Handle *)
564 send_handle, SOL_SOCKET, SO_SNDBUF, &size,
565 &len);
566
567 if (size < msgbuf_size)
568 { 554 {
569 LOG (GNUNET_ERROR_TYPE_DEBUG, 555 socklen_t size = 0;
570 "Trying to increase socket buffer size from %i to %i for message size %i\n", 556 socklen_t len = sizeof (size);
571 size, 557
572 ((msgbuf_size / 1000) + 2) * 1000, 558 GNUNET_NETWORK_socket_getsockopt ((struct GNUNET_NETWORK_Handle *)
573 msgbuf_size); 559 send_handle, SOL_SOCKET, SO_SNDBUF, &size,
574 size = ((msgbuf_size / 1000) + 2) * 1000; 560 &len);
575 if (GNUNET_NETWORK_socket_setsockopt 561 if (size < msgbuf_size)
576 ((struct GNUNET_NETWORK_Handle *) send_handle, SOL_SOCKET, SO_SNDBUF,
577 &size, sizeof (size)) == GNUNET_OK)
578 { 562 {
579 /* Increased buffer size, retry sending */ 563 LOG (GNUNET_ERROR_TYPE_DEBUG,
580 return 0; 564 "Trying to increase socket buffer size from %i to %i for message size %i\n",
565 size, ((msgbuf_size / 1000) + 2) * 1000, msgbuf_size);
566 size = ((msgbuf_size / 1000) + 2) * 1000;
567 if (GNUNET_OK == GNUNET_NETWORK_socket_setsockopt
568 ((struct GNUNET_NETWORK_Handle *) send_handle, SOL_SOCKET, SO_SNDBUF,
569 &size, sizeof (size)))
570 goto resend; /* Increased buffer size, retry sending */
571 else
572 {
573 /* Could not increase buffer size: error, no retry */
574 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "setsockopt");
575 return GNUNET_SYSERR;
576 }
581 } 577 }
582 else 578 else
583 { 579 {
584 /* Could not increase buffer size: error, no retry */ 580 /* Buffer is bigger than message: error, no retry
585 GNUNET_log_strerror (GNUNET_ERROR_TYPE_ERROR, "setsockopt"); 581 * This should never happen!*/
586 return -1; 582 GNUNET_break (0);
583 return GNUNET_SYSERR;
587 } 584 }
588 } 585 }
589 else
590 {
591 /* Buffer is bigger than message: error, no retry
592 * This should never happen!*/
593 GNUNET_break (0);
594 return -1;
595 }
596 } 586 }
597
598 LOG (GNUNET_ERROR_TYPE_DEBUG, 587 LOG (GNUNET_ERROR_TYPE_DEBUG,
599 "UNIX transmit %u-byte message to %s (%d: %s)\n", 588 "UNIX transmit %u-byte message to %s (%d: %s)\n",
600 (unsigned int) msgbuf_size, GNUNET_a2s (sb, sbs), (int) sent, 589 (unsigned int) msgbuf_size, GNUNET_a2s (sb, sbs), (int) sent,
601 (sent < 0) ? STRERROR (errno) : "ok"); 590 (sent < 0) ? STRERROR (errno) : "ok");
602 591 return sent;
603 /* Calling continuation */
604 if (cont != NULL)
605 {
606 if (sent == GNUNET_SYSERR)
607 cont (cont_cls, target, GNUNET_SYSERR, payload, 0);
608 else if (sent > 0)
609 cont (cont_cls, target, GNUNET_OK, payload, msgbuf_size);
610 else
611 GNUNET_break (0);
612 }
613
614 /* return number of bytes successfully sent */
615 if (sent > 0)
616 return sent;
617 if (sent == 0)
618 {
619 /* That should never happen */
620 GNUNET_break (0);
621 return -1;
622 }
623 /* failed and retry: return 0 */
624 if (GNUNET_SYSERR == sent)
625 return 0;
626 /* default */
627 return -1;
628} 592}
629 593
630struct gsi_ctx 594struct gsi_ctx
@@ -930,7 +894,7 @@ unix_plugin_select_read (struct Plugin * plugin)
930static void 894static void
931unix_plugin_select_write (struct Plugin * plugin) 895unix_plugin_select_write (struct Plugin * plugin)
932{ 896{
933 static int retry_counter; 897 static int retry_counter = 0;
934 int sent = 0; 898 int sent = 0;
935 struct UNIXMessageWrapper * msgw = plugin->msg_head; 899 struct UNIXMessageWrapper * msgw = plugin->msg_head;
936 900
@@ -946,26 +910,26 @@ unix_plugin_select_write (struct Plugin * plugin)
946 msgw->payload, 910 msgw->payload,
947 msgw->cont, msgw->cont_cls); 911 msgw->cont, msgw->cont_cls);
948 912
949 if (sent == 0) 913 if (0 == sent)
950 { 914 {
951 /* failed and retry */ 915 retry_counter ++;
952 retry_counter++; 916 if (retry_counter <= MAX_RETRIES)
953 GNUNET_STATISTICS_set (plugin->env->stats,"# UNIX retry attempt", 917 {
954 retry_counter, GNUNET_NO); 918 GNUNET_STATISTICS_update (plugin->env->stats,"# UNIX retry attempts",
955 return; 919 1, GNUNET_NO);
956 } 920 return; /* retry */
957 921 }
958 if (retry_counter > 0 ) 922 else
959 { 923 sent = GNUNET_SYSERR; /* abort */
960 /* no retry: reset counter */
961 retry_counter = 0;
962 GNUNET_STATISTICS_set (plugin->env->stats,"# UNIX retry attempt",
963 retry_counter, GNUNET_NO);
964 } 924 }
925 retry_counter = 0;
965 926
966 if (sent == -1) 927 if (GNUNET_SYSERR == sent)
967 { 928 {
968 /* failed and no retry */ 929 /* failed and no retry */
930 if (NULL != msgw->cont)
931 msgw->cont (msgw->cont_cls, &msgw->session->target, GNUNET_SYSERR, msgw->payload, 0);
932
969 GNUNET_CONTAINER_DLL_remove(plugin->msg_head, plugin->msg_tail, msgw); 933 GNUNET_CONTAINER_DLL_remove(plugin->msg_head, plugin->msg_tail, msgw);
970 934
971 GNUNET_assert (plugin->bytes_in_queue >= msgw->msgsize); 935 GNUNET_assert (plugin->bytes_in_queue >= msgw->msgsize);
@@ -981,9 +945,12 @@ unix_plugin_select_write (struct Plugin * plugin)
981 return; 945 return;
982 } 946 }
983 947
984 if (sent > 0) 948 else if (sent >= 0)
985 { 949 {
986 /* successfully sent bytes */ 950 /* successfully sent bytes */
951 if (NULL != msgw->cont)
952 msgw->cont (msgw->cont_cls, &msgw->session->target, GNUNET_OK, msgw->payload, msgw->msgsize);
953
987 GNUNET_CONTAINER_DLL_remove(plugin->msg_head, plugin->msg_tail, msgw); 954 GNUNET_CONTAINER_DLL_remove(plugin->msg_head, plugin->msg_tail, msgw);
988 955
989 GNUNET_assert (plugin->bytes_in_queue >= msgw->msgsize); 956 GNUNET_assert (plugin->bytes_in_queue >= msgw->msgsize);
@@ -999,6 +966,7 @@ unix_plugin_select_write (struct Plugin * plugin)
999 return; 966 return;
1000 } 967 }
1001 968
969
1002} 970}
1003 971
1004 972