aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAlberto Aguirre <albaguirre@gmail.com>2018-03-20 11:42:45 -0500
committerAndreas Schneider <asn@cryptomilk.org>2018-03-21 20:44:04 +0100
commitbe22c0d442a1c5c016e2ebb99075b61614b5b447 (patch)
tree7f4f93a8d38b02a1dc86183a2b08e27e9fffe9a0 /src
parent467d78a442a0b3cea20f7fefadf9fa4b5119b1fe (diff)
downloadlibssh-be22c0d442a1c5c016e2ebb99075b61614b5b447.tar.gz
libssh-be22c0d442a1c5c016e2ebb99075b61614b5b447.tar.xz
libssh-be22c0d442a1c5c016e2ebb99075b61614b5b447.zip
Add a NODELAY option
Add a new option SSH_OPTIONS_NODELAY to enable or disable the Nagle Algorithm (TCP_NODELAY) on the session socket. Improved performance can be achieved for some applications like sftp servers by enabling SSH_OPTIONS_NODELAY as typically, the next request won't arrive until the server replies, which are typically small writes. Signed-off-by: Alberto Aguirre <albaguirre@gmail.com> Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
Diffstat (limited to 'src')
-rw-r--r--src/connect.c19
-rw-r--r--src/options.c14
-rw-r--r--src/session.c1
3 files changed, 33 insertions, 1 deletions
diff --git a/src/connect.c b/src/connect.c
index 50c9e997..d7c2a32c 100644
--- a/src/connect.c
+++ b/src/connect.c
@@ -74,6 +74,7 @@
#include <sys/socket.h>
#include <sys/select.h>
#include <netinet/in.h>
+#include <netinet/tcp.h>
#endif /* _WIN32 */
@@ -216,6 +217,12 @@ static int ssh_connect_ai_timeout(ssh_session session, const char *host,
return s;
}
+static int set_tcp_nodelay(socket_t socket)
+{
+ int opt = 1;
+ return setsockopt(socket, IPPROTO_TCP, TCP_NODELAY, &opt, sizeof(opt));
+}
+
/**
* @internal
*
@@ -387,6 +394,18 @@ socket_t ssh_connect_host_nonblocking(ssh_session session, const char *host,
continue;
}
+ if (session->opts.nodelay) {
+ /* For winsock, socket options are only effective before connect */
+ rc = set_tcp_nodelay(s);
+ if (rc < 0) {
+ ssh_set_error(session, SSH_FATAL,
+ "Failed to set TCP_NODELAY on socket: %s", strerror(errno));
+ ssh_connect_socket_close(s);
+ s = -1;
+ continue;
+ }
+ }
+
errno = 0;
rc = connect(s, itr->ai_addr, itr->ai_addrlen);
if (rc == -1 && (errno != 0) && (errno != EINPROGRESS)) {
diff --git a/src/options.c b/src/options.c
index 14b9e01e..adfecdc7 100644
--- a/src/options.c
+++ b/src/options.c
@@ -408,6 +408,10 @@ int ssh_options_set_algo(ssh_session session,
* Currently without effect (ssh_userauth_auto_pubkey doesn't use
* gssapi authentication).
*
+ * - SSH_OPTIONS_NODELAY
+ * Set it to disable Nagle's Algorithm (TCP_NODELAY) on the
+ * session socket. (int, 0=false)
+ *
* @param value The value to set. This is a generic pointer and the
* datatype which is used should be set according to the
* type set.
@@ -938,7 +942,15 @@ int ssh_options_set(ssh_session session, enum ssh_options_e type,
}
}
break;
-
+ case SSH_OPTIONS_NODELAY:
+ if (value == NULL) {
+ ssh_set_error_invalid(session);
+ return -1;
+ } else {
+ int *x = (int *) value;
+ session->opts.nodelay = (*x & 0xff) > 0 ? 1 : 0;
+ }
+ break;
default:
ssh_set_error(session, SSH_REQUEST_DENIED, "Unknown ssh option %d", type);
return -1;
diff --git a/src/session.c b/src/session.c
index 1c03b62b..deaa1ae1 100644
--- a/src/session.c
+++ b/src/session.c
@@ -107,6 +107,7 @@ ssh_session ssh_new(void) {
session->opts.fd = -1;
session->opts.ssh2 = 1;
session->opts.compressionlevel=7;
+ session->opts.nodelay = 0;
#ifdef WITH_SSH1
session->opts.ssh1 = 1;
#else