curl-library
Re: TCP_NODELAY
Date: Wed, 24 Mar 2004 19:05:08 -0600
Daniel Stenberg wrote:
> On Sun, 21 Mar 2004, Joe Halpin wrote:
> I approve of the idea and the concept. I have only a few minor nits on the
> patch:
>
> 1. I'd rather see a new command line option than an environment variable for
> the command line tool (perhaps called --tcp-nodelay).
>
> 2. Instead of duplicating 5 lines of code, I'd prefer to have the actual code
> that do the setsockopt() call put into a separate function, and call
> that function from two places (the ipv4 code and the ipv6 code).
>
> 3. errno is not set on windows for network related stuff as one would think,
> use Curl_ourerrno() to get a portable errno. (used if the setsockopt() call
> returns failure)
>
> Should we include some further details on what TCP_NODELAY actually does in
> the curl_easy_setopt man page?
>
Sorry I haven't sent this before now, but I'm buried at work and my
alergies are kicking my butt :-(
Joe
Index: docs/curl.1
===================================================================
RCS file: /repository/curl/docs/curl.1,v
retrieving revision 1.118
diff -u -r1.118 curl.1
--- docs/curl.1 5 Mar 2004 07:55:02 -0000 1.118
+++ docs/curl.1 25 Mar 2004 01:00:25 -0000
@@ -707,6 +707,9 @@
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 curl_easy_setopt man page for
+details about this option.
.IP "-t/--telnet-option <OPT=val>"
Pass options to the telnet protocol. Supported options are:
Index: docs/libcurl/curl_easy_setopt.3
===================================================================
RCS file: /repository/curl/docs/libcurl/curl_easy_setopt.3,v
retrieving revision 1.82
diff -u -r1.82 curl_easy_setopt.3
--- docs/libcurl/curl_easy_setopt.3 12 Mar 2004 09:14:45 -0000 1.82
+++ docs/libcurl/curl_easy_setopt.3 25 Mar 2004 01:00:30 -0000
@@ -295,6 +295,22 @@
.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
Index: include/curl/curl.h
===================================================================
RCS file: /repository/curl/include/curl/curl.h,v
retrieving revision 1.243
diff -u -r1.243 curl.h
--- include/curl/curl.h 12 Mar 2004 08:55:50 -0000 1.243
+++ include/curl/curl.h 25 Mar 2004 01:00:31 -0000
@@ -786,6 +786,9 @@
/* 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;
Index: lib/connect.c
===================================================================
RCS file: /repository/curl/lib/connect.c,v
retrieving revision 1.82
diff -u -r1.82 connect.c
--- lib/connect.c 17 Mar 2004 12:46:45 -0000 1.82
+++ lib/connect.c 25 Mar 2004 01:00:32 -0000
@@ -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
@@ -504,6 +505,15 @@
}
+void Curl_setNoDelay(struct SessionHandle *data,int sockfd,const char *ip)
+{
+ socklen_t onoff = (socklen_t) data->tcp_nodelay;
+ infof(data,"Setting TCP_NODELAY for %s\n", ip);
+ if(setsockopt(sockfd,IPPROTO_TCP,TCP_NODELAY,&onoff,sizeof onoff) < 0)
+ infof(data, "Could not set TCP_NODELAY: %s\n", strerror(errno));
+}
+
+
/*
* TCP connect to the given host with timeout, proxy or remote doesn't matter.
* There might be more than one IP address to try out. Fill in the passed
@@ -581,6 +591,9 @@
sockfd = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
if (sockfd == CURL_SOCKET_BAD)
continue;
+
+ else if(1 == conn->tcp_nodelay)
+ Curl_setNoDelay(data,sockfd,"IPv6");
#else
/*
* Connecting with old style IPv4-only support
@@ -600,6 +613,9 @@
return CURLE_COULDNT_CONNECT; /* big time error */
}
+ else if(1 == conn->tcp_nodelay)
+ Curl_setNoDelay(data,sockfd,"IPv4");
+
/* nasty address work before connect can be made */
memset((char *) &serv_addr, '\0', sizeof(serv_addr));
memcpy((char *)&(serv_addr.sin_addr),
Index: lib/connect.h
===================================================================
RCS file: /repository/curl/lib/connect.h,v
retrieving revision 1.16
diff -u -r1.16 connect.h
--- lib/connect.h 9 Mar 2004 22:52:50 -0000 1.16
+++ lib/connect.h 25 Mar 2004 01:00:32 -0000
@@ -38,5 +38,7 @@
bool *connected /* truly connected? */
);
+void Curl_setNoDelay(struct SessionHandle *data,int sockfd,const char *ip);
+
int Curl_ourerrno(void);
#endif
Index: lib/url.c
===================================================================
RCS file: /repository/curl/lib/url.c,v
retrieving revision 1.350
diff -u -r1.350 url.c
--- lib/url.c 12 Mar 2004 08:55:51 -0000 1.350
+++ lib/url.c 25 Mar 2004 01:00:35 -0000
@@ -1303,6 +1303,14 @@
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 */
@@ -2059,6 +2067,10 @@
conn->bits.user_passwd = data->set.userpwd?1:0;
conn->bits.proxy_user_passwd = data->set.proxyuserpwd?1:0;
+ /* Pass the nagle flag from the SessionHandle struct to the connectdata
+ * struct so it will be available for Curl_connecthost(). */
+ conn->tcp_nodelay = (data->tcp_nodelay == 0) ? 0 : 1;
+
/* This initing continues below, see the comment "Continue connectdata
* initialization here" */
Index: lib/urldata.h
===================================================================
RCS file: /repository/curl/lib/urldata.h,v
retrieving revision 1.204
diff -u -r1.204 urldata.h
--- lib/urldata.h 12 Mar 2004 13:06:01 -0000 1.204
+++ lib/urldata.h 25 Mar 2004 01:00:36 -0000
@@ -576,6 +576,9 @@
/* data used for the asynch name resolve callback */
struct Curl_async async;
#endif
+
+ /* This tells Curl_connectHost whether or not to enable TCP_NODELAY */
+ int tcp_nodelay;
};
/* The end of connectdata. */
@@ -906,6 +909,9 @@
#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"
Index: src/main.c
===================================================================
RCS file: /repository/curl/src/main.c,v
retrieving revision 1.247
diff -u -r1.247 main.c
--- src/main.c 17 Mar 2004 12:46:48 -0000 1.247
+++ src/main.c 25 Mar 2004 01:00:40 -0000
@@ -294,6 +294,8 @@
" --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 (see the curl_easy_setopt"
+ " man page for details)",
#ifdef USE_ENVIRONMENT
" --environment Write result codes to environment variables (RISC OS)",
#endif
@@ -506,6 +508,8 @@
bool ftp_ssl;
char *socks5proxy;
+
+ bool tcp_nodelay;
};
/* global variable to hold info about libcurl */
@@ -1140,6 +1144,7 @@
{"$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 +1468,9 @@
case 'c': /* --socks specifies a socks5 proxy to use */
GetStr(&config->socks5proxy, nextarg);
break;
+ case 'd': /* --tcp-nodelay option */
+ config->tcp_nodelay = 1;
+ break;
}
break;
case '#': /* added 19990617 larsa */
@@ -3112,6 +3120,9 @@
}
#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);
Received on 2004-03-25