From 55b8446528ad3915b3d28bdedd88c68f7334920f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=A0=D1=83=D1=81=D0=BB=D0=B0=D0=BD=20=D0=98=D0=B6=D0=B1=D1?= =?UTF-8?q?=83=D0=BB=D0=B0=D1=82=D0=BE=D0=B2?= Date: Sun, 19 Jun 2011 21:44:43 +0400 Subject: [PATCH] Reduce server-client socket buffer size to 0 to make sure that SHUTDOWN_ACK reaches the other end before the process terminates. --- src/arm/gnunet-service-arm.c | 7 +++++++ src/include/gnunet_connection_lib.h | 11 +++++++++++ src/include/gnunet_network_lib.h | 7 +++++++ src/include/gnunet_server_lib.h | 9 +++++++++ src/util/connection.c | 12 ++++++++++++ src/util/network.c | 20 ++++++++++++++++++++ src/util/server.c | 12 ++++++++++++ 7 files changed, 78 insertions(+), 0 deletions(-) diff --git a/src/arm/gnunet-service-arm.c b/src/arm/gnunet-service-arm.c index e357668..fa3caa3 100644 --- a/src/arm/gnunet-service-arm.c +++ b/src/arm/gnunet-service-arm.c @@ -958,6 +958,13 @@ transmit_shutdown_ack (void *cls, size_t size, void *buf) GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Transmitting shutdown ACK.\n")); +#if defined (WINDOWS) + /* Make the connection flushing for the purpose of ACK transmitting */ + if (GNUNET_OK != GNUNET_SERVER_client_set_flushing (client)) + GNUNET_log (GNUNET_ERROR_TYPE_WARNING, + _("Failed to make the client connection flushing.\n")); +#endif + msg = (struct GNUNET_MessageHeader *) buf; msg->type = htons (GNUNET_MESSAGE_TYPE_ARM_SHUTDOWN_ACK); msg->size = htons (sizeof (struct GNUNET_MessageHeader)); diff --git a/src/include/gnunet_connection_lib.h b/src/include/gnunet_connection_lib.h index 8d2dbb6..d080852 100644 --- a/src/include/gnunet_connection_lib.h +++ b/src/include/gnunet_connection_lib.h @@ -114,6 +114,17 @@ void GNUNET_CONNECTION_persist_(struct GNUNET_CONNECTION_Handle *sock); /** + * Make the connection flush itself and be blocking. + * Used to make sure that the last messages sent through the connection + * reach the other side before the process is terminated. + * + * @param sock the connection to make flushing and blocking + */ +int +GNUNET_CONNECTION_set_flushing (struct GNUNET_CONNECTION_Handle *sock); + + +/** * Create a socket handle by boxing an existing OS socket. The OS * socket should henceforth be no longer used directly. * GNUNET_socket_destroy will close it. diff --git a/src/include/gnunet_network_lib.h b/src/include/gnunet_network_lib.h index 34cb7bc..3afb403 100644 --- a/src/include/gnunet_network_lib.h +++ b/src/include/gnunet_network_lib.h @@ -240,6 +240,13 @@ int GNUNET_NETWORK_socket_setsockopt (struct GNUNET_NETWORK_Handle *fd, int GNUNET_NETWORK_socket_shutdown (struct GNUNET_NETWORK_Handle *desc, int how); +/** + * Reduce send and recv buffers to zero, flushing the socket. + * @param desc socket + * @return GNUNET_OK on success, GNUNET_SYSERR otherwise + */ +int GNUNET_NETWORK_socket_empty (struct GNUNET_NETWORK_Handle *desc); + /** * Create a new socket. Configure it for non-blocking IO and diff --git a/src/include/gnunet_server_lib.h b/src/include/gnunet_server_lib.h index ca20419..281a868 100644 --- a/src/include/gnunet_server_lib.h +++ b/src/include/gnunet_server_lib.h @@ -384,6 +384,15 @@ GNUNET_SERVER_ignore_shutdown (struct GNUNET_SERVER_Handle *h, /** + * FIXME + * + * @param sock handle to the service connection + */ +int +GNUNET_SERVER_client_set_flushing (struct GNUNET_SERVER_Client *client); + + +/** * The tansmit context is the key datastructure for a conveniance API * used for transmission of complex results to the client followed * ONLY by signaling receive_done with success or error diff --git a/src/util/connection.c b/src/util/connection.c index 6cb3495..c7bf325 100644 --- a/src/util/connection.c +++ b/src/util/connection.c @@ -302,6 +302,18 @@ void GNUNET_CONNECTION_persist_(struct GNUNET_CONNECTION_Handle *sock) } /** + * Make the connection flush itself and be blocking. + * Used to make sure that the last messages sent through the connection + * reach the other side before the process is terminated. + * + * @param sock the connection to make flushing and blocking + */ +int GNUNET_CONNECTION_set_flushing (struct GNUNET_CONNECTION_Handle *sock) +{ + return GNUNET_NETWORK_socket_empty (sock->sock); +} + +/** * Create a socket handle by boxing an existing OS socket. The OS * socket should henceforth be no longer used directly. * GNUNET_socket_destroy will close it. diff --git a/src/util/network.c b/src/util/network.c index 5ff49b1..c5cef24 100644 --- a/src/util/network.c +++ b/src/util/network.c @@ -721,6 +721,26 @@ GNUNET_NETWORK_socket_shutdown (struct GNUNET_NETWORK_Handle *desc, int how) /** + * Reduce send and recv buffers to zero, flushing the socket. + * @param desc socket + * @return GNUNET_OK on success, GNUNET_SYSERR otherwise + */ +int +GNUNET_NETWORK_socket_empty (struct GNUNET_NETWORK_Handle *desc) +{ + int value = 0; + int ret = 0; + + if (0 != (ret = setsockopt (desc->fd, SOL_SOCKET, SO_SNDBUF, &value, sizeof (value)))) + GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "setsockopt"); + if (0 != (ret = setsockopt (desc->fd, SOL_SOCKET, SO_RCVBUF, &value, sizeof (value)))) + GNUNET_log_strerror (GNUNET_ERROR_TYPE_WARNING, "setsockopt"); + + return ret == 0 ? GNUNET_OK : GNUNET_SYSERR; +} + + +/** * Reset FD set * @param fds fd set */ diff --git a/src/util/server.c b/src/util/server.c index 03cf48f..1282864 100644 --- a/src/util/server.c +++ b/src/util/server.c @@ -1154,6 +1154,18 @@ GNUNET_SERVER_client_disconnect (struct GNUNET_SERVER_Client *client) /** + * FIXME + * + * @param sock handle to the service connection + */ +int +GNUNET_SERVER_client_set_flushing (struct GNUNET_SERVER_Client *client) +{ + return GNUNET_CONNECTION_set_flushing (client->connection); +} + + +/** * Notify us when the server has enough space to transmit * a message of the given size to the given client. * -- 1.7.4