mirror of
https://git.libssh.org/projects/libssh.git
synced 2025-11-29 01:03:57 +03:00
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>
This commit is contained in:
committed by
Andreas Schneider
parent
467d78a442
commit
be22c0d442
@@ -355,7 +355,8 @@ enum ssh_options_e {
|
|||||||
SSH_OPTIONS_PUBKEY_AUTH,
|
SSH_OPTIONS_PUBKEY_AUTH,
|
||||||
SSH_OPTIONS_KBDINT_AUTH,
|
SSH_OPTIONS_KBDINT_AUTH,
|
||||||
SSH_OPTIONS_GSSAPI_AUTH,
|
SSH_OPTIONS_GSSAPI_AUTH,
|
||||||
SSH_OPTIONS_GLOBAL_KNOWNHOSTS
|
SSH_OPTIONS_GLOBAL_KNOWNHOSTS,
|
||||||
|
SSH_OPTIONS_NODELAY,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
|
|||||||
@@ -205,6 +205,7 @@ struct ssh_session_struct {
|
|||||||
char *gss_client_identity;
|
char *gss_client_identity;
|
||||||
int gss_delegate_creds;
|
int gss_delegate_creds;
|
||||||
int flags;
|
int flags;
|
||||||
|
int nodelay;
|
||||||
} opts;
|
} opts;
|
||||||
/* counters */
|
/* counters */
|
||||||
ssh_counter socket_counter;
|
ssh_counter socket_counter;
|
||||||
|
|||||||
@@ -74,6 +74,7 @@
|
|||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <sys/select.h>
|
#include <sys/select.h>
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
|
#include <netinet/tcp.h>
|
||||||
|
|
||||||
#endif /* _WIN32 */
|
#endif /* _WIN32 */
|
||||||
|
|
||||||
@@ -216,6 +217,12 @@ static int ssh_connect_ai_timeout(ssh_session session, const char *host,
|
|||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int set_tcp_nodelay(socket_t socket)
|
||||||
|
{
|
||||||
|
int opt = 1;
|
||||||
|
return setsockopt(socket, IPPROTO_TCP, TCP_NODELAY, &opt, sizeof(opt));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @internal
|
* @internal
|
||||||
*
|
*
|
||||||
@@ -387,6 +394,18 @@ socket_t ssh_connect_host_nonblocking(ssh_session session, const char *host,
|
|||||||
continue;
|
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;
|
errno = 0;
|
||||||
rc = connect(s, itr->ai_addr, itr->ai_addrlen);
|
rc = connect(s, itr->ai_addr, itr->ai_addrlen);
|
||||||
if (rc == -1 && (errno != 0) && (errno != EINPROGRESS)) {
|
if (rc == -1 && (errno != 0) && (errno != EINPROGRESS)) {
|
||||||
|
|||||||
@@ -408,6 +408,10 @@ int ssh_options_set_algo(ssh_session session,
|
|||||||
* Currently without effect (ssh_userauth_auto_pubkey doesn't use
|
* Currently without effect (ssh_userauth_auto_pubkey doesn't use
|
||||||
* gssapi authentication).
|
* 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
|
* @param value The value to set. This is a generic pointer and the
|
||||||
* datatype which is used should be set according to the
|
* datatype which is used should be set according to the
|
||||||
* type set.
|
* type set.
|
||||||
@@ -938,7 +942,15 @@ int ssh_options_set(ssh_session session, enum ssh_options_e type,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
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:
|
default:
|
||||||
ssh_set_error(session, SSH_REQUEST_DENIED, "Unknown ssh option %d", type);
|
ssh_set_error(session, SSH_REQUEST_DENIED, "Unknown ssh option %d", type);
|
||||||
return -1;
|
return -1;
|
||||||
|
|||||||
@@ -107,6 +107,7 @@ ssh_session ssh_new(void) {
|
|||||||
session->opts.fd = -1;
|
session->opts.fd = -1;
|
||||||
session->opts.ssh2 = 1;
|
session->opts.ssh2 = 1;
|
||||||
session->opts.compressionlevel=7;
|
session->opts.compressionlevel=7;
|
||||||
|
session->opts.nodelay = 0;
|
||||||
#ifdef WITH_SSH1
|
#ifdef WITH_SSH1
|
||||||
session->opts.ssh1 = 1;
|
session->opts.ssh1 = 1;
|
||||||
#else
|
#else
|
||||||
|
|||||||
Reference in New Issue
Block a user