diff options
author | Ross Lagerwall <rosslagerwall@gmail.com> | 2015-02-26 22:48:13 +0000 |
---|---|---|
committer | Ross Lagerwall <rosslagerwall@gmail.com> | 2015-04-09 22:10:45 +0100 |
commit | 4667adac97ff1617373c3d3d7f56ba9f94bda877 (patch) | |
tree | 967659255d7b63cbd4cf0c5571a0cdcfa93a51ed | |
parent | dccf4aeea3f94251062836f2c6f5f37219c64054 (diff) | |
download | gvfs-4667adac97ff1617373c3d3d7f56ba9f94bda877.tar.gz |
ftp: Use TCP_NODELAY
When ftp is layered on top of TLS, it does a write-write-read which
causes a large amount of latency due to the combination of Nagle's
algorithm and delayed ACKs. Use TCP_NODELAY to disable Nagle's algorithm
and prevent this.
The flag is used for both secure and normal connections. This should
not cause any issues.
https://bugzilla.gnome.org/show_bug.cgi?id=526582
-rw-r--r-- | daemon/gvfsftpconnection.c | 20 |
1 files changed, 20 insertions, 0 deletions
diff --git a/daemon/gvfsftpconnection.c b/daemon/gvfsftpconnection.c index 217d798d..2db6f51c 100644 --- a/daemon/gvfsftpconnection.c +++ b/daemon/gvfsftpconnection.c @@ -26,6 +26,7 @@ #include <string.h> #include <glib/gi18n.h> +#include <gio/gnetworking.h> #include "gvfsbackendftp.h" @@ -63,6 +64,21 @@ enable_keepalive (GSocketConnection *conn) g_socket_set_keepalive (g_socket_connection_get_socket (conn), TRUE); } +/* Set TCP_NODELAY on the connection to avoid a bad interaction between Nagle's + * algorithm and delayed acks when doing a write-write-read. */ +static void +enable_nodelay (GSocketConnection *conn) +{ + GError *error = NULL; + GSocket *socket = g_socket_connection_get_socket (conn); + + if (!g_socket_set_option (socket, IPPROTO_TCP, TCP_NODELAY, TRUE, &error)) + { + g_warning ("Could not set TCP_NODELAY: %s\n", error->message); + g_error_free (error); + } +} + static void create_input_stream (GVfsFtpConnection *conn) { @@ -100,6 +116,7 @@ g_vfs_ftp_connection_new (GSocketConnectable *addr, } conn->connection = G_SOCKET_CONNECTION (conn->commands); + enable_nodelay (conn->connection); enable_keepalive (conn->connection); create_input_stream (conn); /* The first thing that needs to happen is receiving the welcome message */ @@ -334,6 +351,8 @@ g_vfs_ftp_connection_open_data_connection (GVfsFtpConnection *conn, G_SOCKET_CONNECTABLE (addr), cancellable, error)); + if (conn->data) + enable_nodelay (G_SOCKET_CONNECTION (conn->data)); return conn->data != NULL; } @@ -474,6 +493,7 @@ g_vfs_ftp_connection_accept_data_connection (GVfsFtpConnection *conn, conn->data = G_IO_STREAM (g_socket_connection_factory_create_connection (accepted)); g_object_unref (accepted); + enable_nodelay (G_SOCKET_CONNECTION (conn->data)); return TRUE; } |