aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/curl.17
-rw-r--r--docs/libcurl/curl_easy_setopt.316
-rw-r--r--include/curl/curl.h3
-rw-r--r--lib/connect.c24
-rw-r--r--lib/url.c8
-rw-r--r--lib/urldata.h3
-rw-r--r--src/main.c10
7 files changed, 70 insertions, 1 deletions
diff --git a/docs/curl.1 b/docs/curl.1
index 9ed452883..f37e03f25 100644
--- a/docs/curl.1
+++ b/docs/curl.1
@@ -2,7 +2,7 @@
.\" nroff -man curl.1
.\" Written by Daniel Stenberg
.\"
-.TH curl 1 "5 Mar 2004" "Curl 7.11.1" "Curl Manual"
+.TH curl 1 "25 Mar 2004" "Curl 7.11.2" "Curl Manual"
.SH NAME
curl \- transfer a URL
.SH SYNOPSIS
@@ -707,6 +707,11 @@ is a plain '-', it is instead written to stdout. This option has no point when
you're using a shell with decent redirecting capabilities.
If this option is used several times, the last one will be used.
+.IP "--tcp-nodelay"
+Turn on the TCP_NODELAY option. See the \fIcurl_easy_setopt(3)\fP man page for
+details about this option. (Added in 7.11.2)
+
+If this option is used several times, each occurance toggles this on/off.
.IP "-t/--telnet-option <OPT=val>"
Pass options to the telnet protocol. Supported options are:
diff --git a/docs/libcurl/curl_easy_setopt.3 b/docs/libcurl/curl_easy_setopt.3
index 16bed31a9..eeb35d41e 100644
--- a/docs/libcurl/curl_easy_setopt.3
+++ b/docs/libcurl/curl_easy_setopt.3
@@ -295,6 +295,22 @@ cannot be guaranteed to actually get the given size. (Added in 7.10)
.IP CURLOPT_PORT
Pass a long specifying what remote port number to connect to, instead of the
one specified in the URL or the default port for the used protocol.
+.IP CURLOPT_TCP_NODELAY
+Pass a long specifying whether the TCP_NODELAY option should be set or
+cleared (1 = set, 0 = clear). The option is cleared by default. This
+will have no effect after the connection has been established.
+
+Setting this option will disable TCP's Nagle algorithm. The purpose of
+this algorithm is to try to minimize the number of small packets on
+the network (where "small packets" means TCP segments less than the
+Maximum Segment Size (MSS) for the network).
+
+Maximizing the amount of data sent per TCP segment is good because it
+amortizes the overhead of the send. However, in some cases (most
+notably telnet or rlogin) small segments may need to be sent
+without delay. This is less efficient than sending larger amounts of
+data at a time, and can contribute to congestion on the network if
+overdone.
.SH NAMES and PASSWORDS OPTIONS (Authentication)
.IP CURLOPT_NETRC
This parameter controls the preference of libcurl between using user names and
diff --git a/include/curl/curl.h b/include/curl/curl.h
index abe384445..766d4efc4 100644
--- a/include/curl/curl.h
+++ b/include/curl/curl.h
@@ -762,6 +762,9 @@ typedef enum {
/* The _LARGE version of the standard POSTFIELDSIZE option */
CINIT(POSTFIELDSIZE_LARGE, OFF_T, 120),
+ /* Enable/disable the TCP Nagle algorithm */
+ CINIT(TCP_NODELAY, LONG, 121),
+
CURLOPT_LASTENTRY /* the last unused */
} CURLoption;
diff --git a/lib/connect.c b/lib/connect.c
index 04e3d234b..28783445e 100644
--- a/lib/connect.c
+++ b/lib/connect.c
@@ -31,6 +31,7 @@
#endif
#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
+#include <netinet/tcp.h> /* for TCP_NODELAY */
#endif
#include <sys/ioctl.h>
#ifdef HAVE_UNISTD_H
@@ -476,6 +477,23 @@ CURLcode Curl_is_connected(struct connectdata *conn,
return CURLE_OK;
}
+static void Curl_setNoDelay(struct connectdata *conn,
+ curl_socket_t sockfd,
+ int ip)
+{
+#ifdef TCP_NODELAY
+ struct SessionHandle *data= conn->data;
+ socklen_t onoff = (socklen_t) data->tcp_nodelay;
+ infof(data,"Setting TCP_NODELAY for IPv%d\n", ip);
+ if(setsockopt(sockfd, IPPROTO_TCP, TCP_NODELAY, &onoff, sizeof(onoff)) < 0)
+ infof(data, "Could not set TCP_NODELAY: %s\n",
+ Curl_strerror(conn, Curl_ourerrno()));
+#else
+ (void)conn;
+ (void)sockfd;
+ (void)ip;
+#endif
+}
/*
* TCP connect to the given host with timeout, proxy or remote doesn't matter.
@@ -554,6 +572,9 @@ CURLcode Curl_connecthost(struct connectdata *conn, /* context */
sockfd = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
if (sockfd == CURL_SOCKET_BAD)
continue;
+
+ else if(data->tcp_nodelay)
+ Curl_setNoDelay(conn, sockfd, 6);
#else
/*
* Connecting with old style IPv4-only support
@@ -573,6 +594,9 @@ CURLcode Curl_connecthost(struct connectdata *conn, /* context */
return CURLE_COULDNT_CONNECT; /* big time error */
}
+ else if(data->tcp_nodelay)
+ Curl_setNoDelay(conn, sockfd, 4);
+
/* nasty address work before connect can be made */
memset((char *) &serv_addr, '\0', sizeof(serv_addr));
memcpy((char *)&(serv_addr.sin_addr),
diff --git a/lib/url.c b/lib/url.c
index f7b7cc378..bebf51df1 100644
--- a/lib/url.c
+++ b/lib/url.c
@@ -1303,6 +1303,14 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...)
data->set.max_filesize = va_arg(param, curl_off_t);
break;
+ case CURLOPT_TCP_NODELAY:
+ /*
+ * Enable or disable TCP_NODELAY, which will disable/enable the Nagle
+ * algorithm
+ */
+ data->tcp_nodelay = va_arg(param, long);
+ break;
+
default:
/* unknown tag and its companion, just ignore: */
return CURLE_FAILED_INIT; /* correct this */
diff --git a/lib/urldata.h b/lib/urldata.h
index e9bea7e44..fbb6c498f 100644
--- a/lib/urldata.h
+++ b/lib/urldata.h
@@ -908,6 +908,9 @@ struct SessionHandle {
#if defined(USE_SSLEAY) && defined(HAVE_OPENSSL_ENGINE_H)
ENGINE* engine;
#endif /* USE_SSLEAY */
+
+ /* This tells CreateConnection() whether to enable TCP_NODELAY or not */
+ int tcp_nodelay;
};
#define LIBCURL_NAME "libcurl"
diff --git a/src/main.c b/src/main.c
index 485901fcd..31a9e632a 100644
--- a/src/main.c
+++ b/src/main.c
@@ -294,6 +294,7 @@ static void help(void)
" --disable-epsv Prevent curl from using EPSV (F)",
" -D/--dump-header <file> Write the headers to this file",
" --egd-file <file> EGD socket path for random data (SSL)",
+ " --tcp-nodelay Set the TCP_NODELAY option",
#ifdef USE_ENVIRONMENT
" --environment Write result codes to environment variables (RISC OS)",
#endif
@@ -506,6 +507,8 @@ struct Configurable {
bool ftp_ssl;
char *socks5proxy;
+
+ bool tcp_nodelay;
};
/* global variable to hold info about libcurl */
@@ -1140,6 +1143,7 @@ static ParameterError getparameter(char *flag, /* f or -long-flag */
{"$a", "ftp-ssl", FALSE},
{"$b", "ftp-pasv", FALSE},
{"$c", "socks5", TRUE},
+ {"$d", "tcp-nodelay",FALSE},
{"0", "http1.0", FALSE},
{"1", "tlsv1", FALSE},
{"2", "sslv2", FALSE},
@@ -1463,6 +1467,9 @@ static ParameterError getparameter(char *flag, /* f or -long-flag */
case 'c': /* --socks specifies a socks5 proxy to use */
GetStr(&config->socks5proxy, nextarg);
break;
+ case 'd': /* --tcp-nodelay option */
+ config->tcp_nodelay ^= TRUE;
+ break;
}
break;
case '#': /* added 19990617 larsa */
@@ -3112,6 +3119,9 @@ operate(struct Configurable *config, int argc, char *argv[])
}
#endif
+ if(1 == config->tcp_nodelay)
+ curl_easy_setopt(curl, CURLOPT_TCP_NODELAY, 1);
+
curl_easy_setopt(curl, CURLOPT_SSLENGINE, config->engine);
curl_easy_setopt(curl, CURLOPT_SSLENGINE_DEFAULT, 1);