From 43e045fc3e8430b2d2f3a1fc1354f3ecd54b09ab Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Tue, 2 Apr 2013 11:22:41 +0200 Subject: [PATCH] SO_SNDBUF: don't set SNDBUF for win32 versions vista or later MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Microsoft knowledge-base article http://support.microsoft.com/kb/823764 describes how to use SNDBUF to overcome a performance shortcoming in winsock, but it doesn't apply to Windows Vista and later versions. If the described SNDBUF magic is applied when running on those more recent Windows versions, it seems to instead have the reversed effect in many cases and thus make libcurl perform less good on those systems. This fix thus adds a run-time version-check that does the SNDBUF magic conditionally depending if it is deemed necessary or not. Bug: http://curl.haxx.se/bug/view.cgi?id=1188 Reported by: Andrew Kurushin Tested by: Christian Hägele --- lib/connect.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/lib/connect.c b/lib/connect.c index b277d912e..e2350482c 100644 --- a/lib/connect.c +++ b/lib/connect.c @@ -852,13 +852,35 @@ static void nosigpipe(struct connectdata *conn, Work-around: Make the Socket Send Buffer Size Larger Than the Program Send Buffer Size + The problem described in this knowledge-base is applied only to pre-Vista + Windows. Following function trying to detect OS version and skips + SO_SNDBUF adjustment for Windows Vista and above. */ +#define DETECT_OS_NONE 0 +#define DETECT_OS_PREVISTA 1 +#define DETECT_OS_VISTA_OR_LATER 2 + void Curl_sndbufset(curl_socket_t sockfd) { int val = CURL_MAX_WRITE_SIZE + 32; int curval = 0; int curlen = sizeof(curval); + OSVERSIONINFO osver; + static int detectOsState = DETECT_OS_NONE; + + if(detectOsState == DETECT_OS_NONE) { + memset(&osver, 0, sizeof(osver)); + osver.dwOSVersionInfoSize = sizeof(osver); + detectOsState = DETECT_OS_PREVISTA; + if(GetVersionEx(&osver)) { + if(osver.dwMajorVersion >= 6) + detectOsState = DETECT_OS_VISTA_OR_LATER; + } + } + if(detectOsState == DETECT_OS_VISTA_OR_LATER) + return; + if(getsockopt(sockfd, SOL_SOCKET, SO_SNDBUF, (char *)&curval, &curlen) == 0) if(curval > val) return;