summaryrefslogtreecommitdiff
path: root/daemon/gvfsftpconnection.c
diff options
context:
space:
mode:
authorRoss Lagerwall <rosslagerwall@gmail.com>2015-02-26 22:48:13 +0000
committerRoss Lagerwall <rosslagerwall@gmail.com>2015-04-09 22:10:45 +0100
commit4667adac97ff1617373c3d3d7f56ba9f94bda877 (patch)
tree967659255d7b63cbd4cf0c5571a0cdcfa93a51ed /daemon/gvfsftpconnection.c
parentdccf4aeea3f94251062836f2c6f5f37219c64054 (diff)
downloadgvfs-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
Diffstat (limited to 'daemon/gvfsftpconnection.c')
-rw-r--r--daemon/gvfsftpconnection.c20
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;
}