diff options
author | Matthias Wachs <wachs@net.in.tum.de> | 2012-10-26 12:22:21 +0000 |
---|---|---|
committer | Matthias Wachs <wachs@net.in.tum.de> | 2012-10-26 12:22:21 +0000 |
commit | 0c1b1c5380cfff0a8e0e3adae4df2ee048a5fe88 (patch) | |
tree | 99b00e4cfba9b6c497511c7a8000a79c42befcb2 /src/transport/plugin_transport_unix.c | |
parent | d8dc59b1cc0324392fd90f9e5d6f5adc876d4de9 (diff) | |
download | gnunet-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.c | 150 |
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 | */ |
491 | static ssize_t | 493 | static ssize_t |
492 | unix_real_send (void *cls, | 494 | unix_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 | ||
544 | resend: | ||
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 | ||
630 | struct gsi_ctx | 594 | struct gsi_ctx |
@@ -930,7 +894,7 @@ unix_plugin_select_read (struct Plugin * plugin) | |||
930 | static void | 894 | static void |
931 | unix_plugin_select_write (struct Plugin * plugin) | 895 | unix_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 | ||