From: Daniel Stenberg Date: Thu, 25 Mar 2004 13:37:18 +0000 (+0000) Subject: tcp-nodelay patch by Joe Halpin X-Git-Tag: upstream/7.37.1~13082 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=bb3d6e8552f428bd0c2624854403d36ab3cf163d;p=platform%2Fupstream%2Fcurl.git tcp-nodelay patch by Joe Halpin --- diff --git a/docs/curl.1 b/docs/curl.1 index 9ed4528..f37e03f 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 " 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 16bed31..eeb35d4 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 abe3844..766d4ef 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 04e3d23..2878344 100644 --- a/lib/connect.c +++ b/lib/connect.c @@ -31,6 +31,7 @@ #endif #ifdef HAVE_SYS_SOCKET_H #include +#include /* for TCP_NODELAY */ #endif #include #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 f7b7cc3..bebf51d 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 e9bea7e..fbb6c49 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 485901f..31a9e63 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 Write the headers to this file", " --egd-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);