diff options
author | Christian Grothoff <christian@grothoff.org> | 2011-06-16 08:09:46 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2011-06-16 08:09:46 +0000 |
commit | 29e0d43e92d47ec5e6b632184939518546b74520 (patch) | |
tree | 1fbc98c6237ebf3f06268b1a2690993b61a2280a | |
parent | 4d2c6c417cd295905ae5140e477c76da48b30fe4 (diff) | |
download | gnunet-29e0d43e92d47ec5e6b632184939518546b74520.tar.gz gnunet-29e0d43e92d47ec5e6b632184939518546b74520.zip |
do not crash if we run out of sockets
-rw-r--r-- | src/util/client.c | 75 | ||||
-rw-r--r-- | src/util/network.c | 1 |
2 files changed, 55 insertions, 21 deletions
diff --git a/src/util/client.c b/src/util/client.c index f9fc67c9d..9458cc94b 100644 --- a/src/util/client.c +++ b/src/util/client.c | |||
@@ -373,8 +373,6 @@ GNUNET_CLIENT_connect (const char *service_name, | |||
373 | 373 | ||
374 | sock = do_connect (service_name, | 374 | sock = do_connect (service_name, |
375 | cfg, 0); | 375 | cfg, 0); |
376 | if (sock == NULL) | ||
377 | return NULL; | ||
378 | ret = GNUNET_malloc (sizeof (struct GNUNET_CLIENT_Connection)); | 376 | ret = GNUNET_malloc (sizeof (struct GNUNET_CLIENT_Connection)); |
379 | ret->attempts = 1; | 377 | ret->attempts = 1; |
380 | ret->sock = sock; | 378 | ret->sock = sock; |
@@ -421,14 +419,16 @@ void | |||
421 | GNUNET_CLIENT_disconnect (struct GNUNET_CLIENT_Connection *sock, | 419 | GNUNET_CLIENT_disconnect (struct GNUNET_CLIENT_Connection *sock, |
422 | int finish_pending_write) | 420 | int finish_pending_write) |
423 | { | 421 | { |
424 | GNUNET_assert (sock->sock != NULL); | ||
425 | if (sock->in_receive == GNUNET_YES) | 422 | if (sock->in_receive == GNUNET_YES) |
426 | { | 423 | { |
427 | GNUNET_CONNECTION_receive_cancel (sock->sock); | 424 | GNUNET_CONNECTION_receive_cancel (sock->sock); |
428 | sock->in_receive = GNUNET_NO; | 425 | sock->in_receive = GNUNET_NO; |
429 | } | 426 | } |
430 | GNUNET_CONNECTION_destroy (sock->sock, finish_pending_write); | 427 | if (NULL != sock->sock) |
431 | sock->sock = NULL; | 428 | { |
429 | GNUNET_CONNECTION_destroy (sock->sock, finish_pending_write); | ||
430 | sock->sock = NULL; | ||
431 | } | ||
432 | if (sock->tag != NULL) | 432 | if (sock->tag != NULL) |
433 | { | 433 | { |
434 | GNUNET_free (sock->tag); | 434 | GNUNET_free (sock->tag); |
@@ -436,7 +436,10 @@ GNUNET_CLIENT_disconnect (struct GNUNET_CLIENT_Connection *sock, | |||
436 | } | 436 | } |
437 | sock->receiver_handler = NULL; | 437 | sock->receiver_handler = NULL; |
438 | if (sock->th != NULL) | 438 | if (sock->th != NULL) |
439 | GNUNET_CLIENT_notify_transmit_ready_cancel (sock->th); | 439 | { |
440 | GNUNET_CLIENT_notify_transmit_ready_cancel (sock->th); | ||
441 | sock->th = NULL; | ||
442 | } | ||
440 | if (sock->receive_task != GNUNET_SCHEDULER_NO_TASK) | 443 | if (sock->receive_task != GNUNET_SCHEDULER_NO_TASK) |
441 | { | 444 | { |
442 | GNUNET_SCHEDULER_cancel (sock->receive_task); | 445 | GNUNET_SCHEDULER_cancel (sock->receive_task); |
@@ -766,6 +769,7 @@ client_delayed_retry (void *cls, | |||
766 | const struct GNUNET_SCHEDULER_TaskContext *tc) | 769 | const struct GNUNET_SCHEDULER_TaskContext *tc) |
767 | { | 770 | { |
768 | struct GNUNET_CLIENT_TransmitHandle *th = cls; | 771 | struct GNUNET_CLIENT_TransmitHandle *th = cls; |
772 | struct GNUNET_TIME_Relative delay; | ||
769 | 773 | ||
770 | th->reconnect_task = GNUNET_SCHEDULER_NO_TASK; | 774 | th->reconnect_task = GNUNET_SCHEDULER_NO_TASK; |
771 | if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) | 775 | if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN)) |
@@ -779,6 +783,30 @@ client_delayed_retry (void *cls, | |||
779 | GNUNET_free (th); | 783 | GNUNET_free (th); |
780 | return; | 784 | return; |
781 | } | 785 | } |
786 | th->sock->sock = do_connect (th->sock->service_name, | ||
787 | th->sock->cfg, | ||
788 | th->sock->attempts++); | ||
789 | if (NULL == th->sock->sock) | ||
790 | { | ||
791 | /* could happen if we're out of sockets */ | ||
792 | delay = GNUNET_TIME_relative_min (GNUNET_TIME_absolute_get_remaining (th->timeout), | ||
793 | th->sock->back_off); | ||
794 | th->sock->back_off | ||
795 | = GNUNET_TIME_relative_min (GNUNET_TIME_relative_multiply (th->sock->back_off, 2), | ||
796 | GNUNET_TIME_UNIT_SECONDS); | ||
797 | #if DEBUG_CLIENT | ||
798 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | ||
799 | "Transmission failed %u times, trying again in %llums.\n", | ||
800 | MAX_ATTEMPTS - th->attempts_left, | ||
801 | (unsigned long long) delay.rel_value); | ||
802 | #endif | ||
803 | th->reconnect_task = GNUNET_SCHEDULER_add_delayed (delay, | ||
804 | &client_delayed_retry, | ||
805 | th); | ||
806 | return; | ||
807 | } | ||
808 | GNUNET_CONNECTION_ignore_shutdown (th->sock->sock, | ||
809 | th->sock->ignore_shutdown); | ||
782 | th->th = GNUNET_CONNECTION_notify_transmit_ready (th->sock->sock, | 810 | th->th = GNUNET_CONNECTION_notify_transmit_ready (th->sock->sock, |
783 | th->size, | 811 | th->size, |
784 | GNUNET_TIME_absolute_get_remaining | 812 | GNUNET_TIME_absolute_get_remaining |
@@ -837,15 +865,10 @@ client_notify (void *cls, size_t size, void *buf) | |||
837 | th->sock->service_name); | 865 | th->sock->service_name); |
838 | #endif | 866 | #endif |
839 | GNUNET_CONNECTION_destroy (th->sock->sock, GNUNET_NO); | 867 | GNUNET_CONNECTION_destroy (th->sock->sock, GNUNET_NO); |
840 | th->sock->sock = do_connect (th->sock->service_name, | 868 | th->sock->sock = NULL; |
841 | th->sock->cfg, | ||
842 | th->sock->attempts++); | ||
843 | GNUNET_assert (NULL != th->sock->sock); | ||
844 | GNUNET_CONNECTION_ignore_shutdown (th->sock->sock, | ||
845 | th->sock->ignore_shutdown); | ||
846 | delay = GNUNET_TIME_relative_min (delay, th->sock->back_off); | 869 | delay = GNUNET_TIME_relative_min (delay, th->sock->back_off); |
847 | th->sock->back_off | 870 | th->sock->back_off |
848 | = GNUNET_TIME_relative_min (GNUNET_TIME_relative_multiply (th->sock->back_off, 2), | 871 | = GNUNET_TIME_relative_min (GNUNET_TIME_relative_multiply (th->sock->back_off, 2), |
849 | GNUNET_TIME_UNIT_SECONDS); | 872 | GNUNET_TIME_UNIT_SECONDS); |
850 | #if DEBUG_CLIENT | 873 | #if DEBUG_CLIENT |
851 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 874 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
@@ -910,15 +933,25 @@ GNUNET_CLIENT_notify_transmit_ready (struct GNUNET_CLIENT_Connection *sock, | |||
910 | th->notify = notify; | 933 | th->notify = notify; |
911 | th->notify_cls = notify_cls; | 934 | th->notify_cls = notify_cls; |
912 | th->attempts_left = MAX_ATTEMPTS; | 935 | th->attempts_left = MAX_ATTEMPTS; |
913 | th->th = GNUNET_CONNECTION_notify_transmit_ready (sock->sock, | 936 | if (sock->sock == NULL) |
914 | size, | ||
915 | timeout, | ||
916 | &client_notify, th); | ||
917 | if (NULL == th->th) | ||
918 | { | 937 | { |
919 | GNUNET_break (0); | 938 | th->reconnect_task = GNUNET_SCHEDULER_add_delayed (sock->back_off, |
920 | GNUNET_free (th); | 939 | &client_delayed_retry, |
921 | return NULL; | 940 | th); |
941 | |||
942 | } | ||
943 | else | ||
944 | { | ||
945 | th->th = GNUNET_CONNECTION_notify_transmit_ready (sock->sock, | ||
946 | size, | ||
947 | timeout, | ||
948 | &client_notify, th); | ||
949 | if (NULL == th->th) | ||
950 | { | ||
951 | GNUNET_break (0); | ||
952 | GNUNET_free (th); | ||
953 | return NULL; | ||
954 | } | ||
922 | } | 955 | } |
923 | sock->th = th; | 956 | sock->th = th; |
924 | return th; | 957 | return th; |
diff --git a/src/util/network.c b/src/util/network.c index 49e50101b..0446d649c 100644 --- a/src/util/network.c +++ b/src/util/network.c | |||
@@ -652,6 +652,7 @@ struct GNUNET_NETWORK_Handle * | |||
652 | GNUNET_NETWORK_socket_create (int domain, int type, int protocol) | 652 | GNUNET_NETWORK_socket_create (int domain, int type, int protocol) |
653 | { | 653 | { |
654 | struct GNUNET_NETWORK_Handle *ret; | 654 | struct GNUNET_NETWORK_Handle *ret; |
655 | |||
655 | ret = GNUNET_malloc (sizeof (struct GNUNET_NETWORK_Handle)); | 656 | ret = GNUNET_malloc (sizeof (struct GNUNET_NETWORK_Handle)); |
656 | ret->af = domain; | 657 | ret->af = domain; |
657 | ret->fd = socket (domain, type, protocol); | 658 | ret->fd = socket (domain, type, protocol); |