diff options
-rw-r--r-- | src/arm/gnunet-service-arm.c | 4 | ||||
-rw-r--r-- | src/include/gnunet_connection_lib.h | 15 | ||||
-rw-r--r-- | src/include/gnunet_network_lib.h | 11 | ||||
-rw-r--r-- | src/include/gnunet_server_lib.h | 12 | ||||
-rw-r--r-- | src/util/connection.c | 17 | ||||
-rw-r--r-- | src/util/network.c | 24 | ||||
-rw-r--r-- | src/util/server.c | 15 |
7 files changed, 98 insertions, 0 deletions
diff --git a/src/arm/gnunet-service-arm.c b/src/arm/gnunet-service-arm.c index e357668d3f..c388d0c427 100644 --- a/src/arm/gnunet-service-arm.c +++ b/src/arm/gnunet-service-arm.c @@ -958,6 +958,10 @@ transmit_shutdown_ack (void *cls, size_t size, void *buf) GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Transmitting shutdown ACK.\n")); + /* Make the connection flushing for the purpose of ACK transmitting, + needed on W32 to ensure that the message is even received, harmless + on other platforms... */ + GNUNET_break (GNUNET_OK == GNUNET_SERVER_client_disable_corking (client)); 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 700fef3db8..3184e821b9 100644 --- a/src/include/gnunet_connection_lib.h +++ b/src/include/gnunet_connection_lib.h @@ -114,6 +114,21 @@ void GNUNET_CONNECTION_persist_(struct GNUNET_CONNECTION_Handle *sock); /** + * Disable the "CORK" feature for communication with the given socket, + * forcing the OS to immediately flush the buffer on transmission + * instead of potentially buffering multiple messages. Essentially + * reduces the OS send buffers to zero. + * 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 + * @return GNUNET_OK on success + */ +int +GNUNET_CONNECTION_disable_corking (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 34cb7bc323..1945d210f8 100644 --- a/src/include/gnunet_network_lib.h +++ b/src/include/gnunet_network_lib.h @@ -240,6 +240,17 @@ int GNUNET_NETWORK_socket_setsockopt (struct GNUNET_NETWORK_Handle *fd, int GNUNET_NETWORK_socket_shutdown (struct GNUNET_NETWORK_Handle *desc, int how); +/** + * Disable the "CORK" feature for communication with the given socket, + * forcing the OS to immediately flush the buffer on transmission + * instead of potentially buffering multiple messages. Essentially + * reduces the OS send buffers to zero. + * + * @param desc socket + * @return GNUNET_OK on success, GNUNET_SYSERR otherwise + */ +int GNUNET_NETWORK_socket_disable_corking (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 ca2041984d..2bb5304430 100644 --- a/src/include/gnunet_server_lib.h +++ b/src/include/gnunet_server_lib.h @@ -384,6 +384,18 @@ GNUNET_SERVER_ignore_shutdown (struct GNUNET_SERVER_Handle *h, /** + * Disable the "CORK" feature for communication with the given client, + * forcing the OS to immediately flush the buffer on transmission + * instead of potentially buffering multiple messages. + * + * @param client handle to the client + * @return GNUNET_OK on success + */ +int +GNUNET_SERVER_client_disable_corking (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 80f2cae7f8..ef38d99a9f 100644 --- a/src/util/connection.c +++ b/src/util/connection.c @@ -301,6 +301,23 @@ void GNUNET_CONNECTION_persist_(struct GNUNET_CONNECTION_Handle *sock) sock->persist = GNUNET_YES; } + +/** + * Disable the "CORK" feature for communication with the given socket, + * forcing the OS to immediately flush the buffer on transmission + * instead of potentially buffering multiple messages. Essentially + * reduces the OS send buffers to zero. + * 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 + * @return GNUNET_OK on success + */ +int GNUNET_CONNECTION_disable_corking (struct GNUNET_CONNECTION_Handle *sock) +{ + return GNUNET_NETWORK_socket_disable_corking (sock->sock); +} + /** * Create a socket handle by boxing an existing OS socket. The OS * socket should henceforth be no longer used directly. diff --git a/src/util/network.c b/src/util/network.c index 0446d649c7..b0669b5b1b 100644 --- a/src/util/network.c +++ b/src/util/network.c @@ -722,6 +722,30 @@ GNUNET_NETWORK_socket_shutdown (struct GNUNET_NETWORK_Handle *desc, int how) /** + * Disable the "CORK" feature for communication with the given socket, + * forcing the OS to immediately flush the buffer on transmission + * instead of potentially buffering multiple messages. Essentially + * reduces the OS send buffers to zero. + * + * @param desc socket + * @return GNUNET_OK on success, GNUNET_SYSERR otherwise + */ +int +GNUNET_NETWORK_socket_disable_corking (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 33a824e7c8..103ca24e7a 100644 --- a/src/util/server.c +++ b/src/util/server.c @@ -1170,6 +1170,21 @@ GNUNET_SERVER_client_disconnect (struct GNUNET_SERVER_Client *client) /** + * Disable the "CORK" feature for communication with the given client, + * forcing the OS to immediately flush the buffer on transmission + * instead of potentially buffering multiple messages. + * + * @param client handle to the client + * @return GNUNET_OK on success + */ +int +GNUNET_SERVER_client_disable_corking (struct GNUNET_SERVER_Client *client) +{ + return GNUNET_CONNECTION_disable_corking (client->connection); +} + + +/** * Notify us when the server has enough space to transmit * a message of the given size to the given client. * |