diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/connect.c | 19 | ||||
-rw-r--r-- | src/options.c | 14 | ||||
-rw-r--r-- | src/session.c | 1 |
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 |