I have been witnessing some very strange behavior of Winsock on
Windows Vista SP1, and would like to share my findings to see if
anyone could help me figure out the answer to what's wrong.
I've been running a simple program which tests the behavior of Winsock
when it comes to binding a UDP socket, binding a TCP socket and
binding and then connecting a TCP socket with a wildcard interface and
a specific interface.
On my Windows XP SP3, running as an administrator, I get the following
results:
----------------------------------------------------------------------------------------
Testing bind() UDP with 0.0.0.0:0...
+++ Success!!!
Testing bind() UDP with 0.0.0.0:1024...
+++ Success!!!
Testing bind() UDP with 0.0.0.0:32033...
+++ Success!!!
Testing bind() UDP with 0.0.0.0:55301...
+++ Success!!!
Testing bind() UDP with 192.168.2.110:0...
+++ Success!!!
Testing bind() UDP with 192.168.2.110:1024...
+++ Success!!!
Testing bind() UDP with 192.168.2.110:32033...
+++ Success!!!
Testing bind() UDP with 192.168.2.110:55301...
+++ Success!!!
Testing bind() TCP with 0.0.0.0:0...
+++ Success!!!
Testing bind() TCP with 0.0.0.0:1024...
+++ Success!!!
Testing bind() TCP with 0.0.0.0:32033...
+++ Success!!!
Testing bind() TCP with 0.0.0.0:55301...
+++ Success!!!
Testing bind() TCP with 192.168.2.110:0...
+++ Success!!!
Testing bind() TCP with 192.168.2.110:1024...
+++ Success!!!
Testing bind() TCP with 192.168.2.110:32033...
+++ Success!!!
Testing bind() TCP with 192.168.2.110:55301...
+++ Success!!!
Testing bind() AND connect() TCP with 0.0.0.0:0...
+++ Success!!!
Testing bind() AND connect() TCP with 0.0.0.0:1024...
+++ Success!!!
Testing bind() AND connect() TCP with 0.0.0.0:32033...
+++ Success!!!
Testing bind() AND connect() TCP with 0.0.0.0:55301...
+++ Success!!!
Testing bind() AND connect() TCP with 192.168.2.110:0...
+++ Success!!!
Testing bind() AND connect() TCP with 192.168.2.110:1024...
+++ Success!!!
Testing bind() AND connect() TCP with 192.168.2.110:32033...
+++ Success!!!
Testing bind() AND connect() TCP with 192.168.2.110:55301...
+++ Success!!!
Press any key to continue . . .
----------------------------------------------------------------------------------------
The same results appear in Windows Vista SP2, being run as an
Administrator and as a standard user. Windows firewall is disabled, or
an exception is added, in all cases.
Windows Vista SP1, with firewall disabled, eSET NOD32 antivirus
disabled and no other special software I can think of gives me this
result, however:
----------------------------------------------------------------------------------------
Testing bind() UDP with 0.0.0.0:0...
+++ Success!!!
Testing bind() UDP with 0.0.0.0:1024...
+++ Success!!!
Testing bind() UDP with 0.0.0.0:32033...
+++ Success!!!
Testing bind() UDP with 0.0.0.0:55301...
+++ Success!!!
Testing bind() UDP with 192.168.2.24:0...
+++ Success!!!
Testing bind() UDP with 192.168.2.24:1024...
+++ Success!!!
Testing bind() UDP with 192.168.2.24:32033...
+++ Success!!!
Testing bind() UDP with 192.168.2.24:55301...
+++ Success!!!
Testing bind() TCP with 0.0.0.0:0...
+++ Success!!!
Testing bind() TCP with 0.0.0.0:1024...
+++ Success!!!
Testing bind() TCP with 0.0.0.0:32033...
+++ Success!!!
Testing bind() TCP with 0.0.0.0:55301...
+++ Success!!!
Testing bind() TCP with 192.168.2.24:0...
+++ Success!!!
Testing bind() TCP with 192.168.2.24:1024...
+++ Success!!!
Testing bind() TCP with 192.168.2.24:32033...
+++ Success!!!
Testing bind() TCP with 192.168.2.24:55301...
+++ Success!!!
Testing bind() AND connect() TCP with 0.0.0.0:0...
+++ Success!!!
Testing bind() AND connect() TCP with 0.0.0.0:1024...
+++ Success!!!
Testing bind() AND connect() TCP with 0.0.0.0:32033...
+++ Success!!!
Testing bind() AND connect() TCP with 0.0.0.0:55301...
+++ Success!!!
Testing bind() AND connect() TCP with 192.168.2.24:0...
--- connect() failed: 10049 (The requested address is not valid in its
context.).
Testing bind() AND connect() TCP with 192.168.2.24:1024...
--- connect() failed: 10049 (The requested address is not valid in its
context.).
Testing bind() AND connect() TCP with 192.168.2.24:32033...
--- connect() failed: 10049 (The requested address is not valid in its
context.).
Testing bind() AND connect() TCP with 192.168.2.24:55301...
--- connect() failed: 10049 (The requested address is not valid in its
context.).
----------------------------------------------------------------------------------------
I can't seem to understand why this happens only on Windows Vista SP1,
with a specific *CORRECT* interface.
The program code is attached after this post.
Does anyone have any clue as to what is causing this?
Thanks,
Alon
----------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------
// WinsockTester.cpp : Defines the entry point for the console
application.
//
#include "stdafx.h"
#include <windows.h>
#define SO_EXCLUSIVEADDRUSE ((int)(~SO_REUSEADDR)) /* disallow local
address reuse */
#define SD_SEND 0
#define SD_RECV 1
#define SD_BOTH 2
void TryBindUDP(char* p_szIPAddress, unsigned short usPort)
{
printf("Testing bind() UDP with %s:%d...\n", p_szIPAddress,
usPort);
WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD( 2, 2 );
err = WSAStartup( wVersionRequested, &wsaData );
if ( err != 0 ) {
/* Tell the user that we could not find a usable */
/* WinSock DLL. */
return;
}
//-----------------------------------------------
// Create a socket
SOCKET SomeSocket =
socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (SomeSocket == INVALID_SOCKET) {
printf("--- socket call failed with error: %ld\n",
WSAGetLastError());
WSACleanup();
return;
}
//----------------------
// Reuse address
BOOL OptValTrue = TRUE;
BOOL OptValFalse = FALSE;
if (setsockopt(SomeSocket, SOL_SOCKET, SO_REUSEADDR, (char*)
&OptValTrue, sizeof(OptValTrue)) == SOCKET_ERROR ||
setsockopt(SomeSocket, SOL_SOCKET, SO_EXCLUSIVEADDRUSE,
(char*) &OptValFalse, sizeof(OptValFalse)) == SOCKET_ERROR)
{
int iLastError = WSAGetLastError();
char szMessageBuffer[512];
memset(szMessageBuffer, 0, sizeof(szMessageBuffer));
FormatMessageA(
FORMAT_MESSAGE_FROM_SYSTEM,
NULL,
iLastError,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default
language
szMessageBuffer,
sizeof(szMessageBuffer) - 1,
NULL
);
// Remove newlines
char* p_CurrentChar = szMessageBuffer;
while (p_CurrentChar != szMessageBuffer + sizeof
(szMessageBuffer) &&
*p_CurrentChar != NULL)
{
if (*p_CurrentChar == 10 ||
*p_CurrentChar == 13)
{
*p_CurrentChar = NULL;
}
p_CurrentChar++;
}
printf("--- setsockopt() failed: %d (%s).\n", iLastError,
szMessageBuffer);
closesocket(SomeSocket);
WSACleanup();
return;
}
//----------------------
// The sockaddr_in structure specifies the address family,
// IP address, and port for the socket that is being bound.
sockaddr_in service;
service.sin_family = AF_INET;
service.sin_addr.s_addr = inet_addr(p_szIPAddress);
service.sin_port = htons(usPort);
//----------------------
// Bind the socket.
if (bind( SomeSocket, (SOCKADDR*) &service, sizeof(service)) ==
SOCKET_ERROR)
{
int iLastError = WSAGetLastError();
char szMessageBuffer[512];
memset(szMessageBuffer, 0, sizeof(szMessageBuffer));
FormatMessageA(
FORMAT_MESSAGE_FROM_SYSTEM,
NULL,
iLastError,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default
language
szMessageBuffer,
sizeof(szMessageBuffer) - 1,
NULL
);
// Remove newlines
char* p_CurrentChar = szMessageBuffer;
while (p_CurrentChar != szMessageBuffer + sizeof
(szMessageBuffer) &&
*p_CurrentChar != NULL)
{
if (*p_CurrentChar == 10 ||
*p_CurrentChar == 13)
{
*p_CurrentChar = NULL;
}
p_CurrentChar++;
}
printf("--- bind() failed: %d (%s).\n", iLastError,
szMessageBuffer);
closesocket(SomeSocket);
WSACleanup();
return;
}
printf("+++ Success!!!\n");
//----------------------
// Cleanup
closesocket(SomeSocket);
WSACleanup( );
}
void TryBindTCP(char* p_szIPAddress, unsigned short usPort)
{
printf("Testing bind() TCP with %s:%d...\n", p_szIPAddress,
usPort);
WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD( 2, 2 );
err = WSAStartup( wVersionRequested, &wsaData );
if ( err != 0 ) {
/* Tell the user that we could not find a usable */
/* WinSock DLL. */
return;
}
//-----------------------------------------------
// Create a socket
SOCKET SomeSocket =
socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (SomeSocket == INVALID_SOCKET) {
printf("--- socket call failed with error: %ld\n",
WSAGetLastError());
WSACleanup();
return;
}
//----------------------
// Reuse address
BOOL OptValTrue = TRUE;
BOOL OptValFalse = FALSE;
// Force hard closing
LINGER sLinger;
sLinger.l_onoff = 1;
sLinger.l_linger = 0;
if (setsockopt(SomeSocket, SOL_SOCKET, SO_REUSEADDR, (char*)
&OptValTrue, sizeof(OptValTrue)) == SOCKET_ERROR ||
setsockopt(SomeSocket, SOL_SOCKET, SO_EXCLUSIVEADDRUSE,
(char*) &OptValFalse, sizeof(OptValFalse)) == SOCKET_ERROR ||
setsockopt(SomeSocket, SOL_SOCKET, SO_LINGER, (char*)
&sLinger, sizeof(sLinger)) == SOCKET_ERROR)
{
int iLastError = WSAGetLastError();
char szMessageBuffer[512];
memset(szMessageBuffer, 0, sizeof(szMessageBuffer));
FormatMessageA(
FORMAT_MESSAGE_FROM_SYSTEM,
NULL,
iLastError,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default
language
szMessageBuffer,
sizeof(szMessageBuffer) - 1,
NULL
);
// Remove newlines
char* p_CurrentChar = szMessageBuffer;
while (p_CurrentChar != szMessageBuffer + sizeof
(szMessageBuffer) &&
*p_CurrentChar != NULL)
{
if (*p_CurrentChar == 10 ||
*p_CurrentChar == 13)
{
*p_CurrentChar = NULL;
}
p_CurrentChar++;
}
printf("--- setsockopt() failed: %d (%s).\n", iLastError,
szMessageBuffer);
closesocket(SomeSocket);
WSACleanup();
return;
}
//----------------------
// The sockaddr_in structure specifies the address family,
// IP address, and port for the socket that is being bound.
sockaddr_in service;
service.sin_family = AF_INET;
service.sin_addr.s_addr = inet_addr(p_szIPAddress);
service.sin_port = htons(usPort);
//----------------------
// Bind the socket.
if (bind( SomeSocket, (SOCKADDR*) &service, sizeof(service)) ==
SOCKET_ERROR)
{
int iLastError = WSAGetLastError();
char szMessageBuffer[512];
memset(szMessageBuffer, 0, sizeof(szMessageBuffer));
FormatMessageA(
FORMAT_MESSAGE_FROM_SYSTEM,
NULL,
iLastError,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default
language
szMessageBuffer,
sizeof(szMessageBuffer) - 1,
NULL
);
// Remove newlines
char* p_CurrentChar = szMessageBuffer;
while (p_CurrentChar != szMessageBuffer + sizeof
(szMessageBuffer) &&
*p_CurrentChar != NULL)
{
if (*p_CurrentChar == 10 ||
*p_CurrentChar == 13)
{
*p_CurrentChar = NULL;
}
p_CurrentChar++;
}
printf("--- bind() failed: %d (%s).\n", iLastError,
szMessageBuffer);
closesocket(SomeSocket);
WSACleanup();
return;
}
printf("+++ Success!!!\n");
//----------------------
// Cleanup
closesocket(SomeSocket);
WSACleanup( );
}
void TryConnectTCP(char* p_szIPAddress, unsigned short usPort)
{
printf("Testing bind() AND connect() TCP with %s:%d...\n",
p_szIPAddress, usPort);
WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD( 2, 2 );
err = WSAStartup( wVersionRequested, &wsaData );
if ( err != 0 ) {
/* Tell the user that we could not find a usable */
/* WinSock DLL. */
return;
}
//-----------------------------------------------
// Create a socket
SOCKET SomeSocket =
socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (SomeSocket == INVALID_SOCKET)
{
printf("--- socket call failed with error: %ld\n",
WSAGetLastError());
WSACleanup();
return;
}
//----------------------
// Reuse address
BOOL OptValTrue = TRUE;
BOOL OptValFalse = FALSE;
// Force hard closing
LINGER sLinger;
sLinger.l_onoff = 1;
sLinger.l_linger = 0;
if (setsockopt(SomeSocket, SOL_SOCKET, SO_REUSEADDR, (char*)
&OptValTrue, sizeof(OptValTrue)) == SOCKET_ERROR ||
setsockopt(SomeSocket, SOL_SOCKET, SO_EXCLUSIVEADDRUSE,
(char*) &OptValFalse, sizeof(OptValFalse)) == SOCKET_ERROR ||
setsockopt(SomeSocket, SOL_SOCKET, SO_LINGER, (char*)
&sLinger, sizeof(sLinger)) == SOCKET_ERROR)
{
int iLastError = WSAGetLastError();
char szMessageBuffer[512];
memset(szMessageBuffer, 0, sizeof(szMessageBuffer));
FormatMessageA(
FORMAT_MESSAGE_FROM_SYSTEM,
NULL,
iLastError,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default
language
szMessageBuffer,
sizeof(szMessageBuffer) - 1,
NULL
);
// Remove newlines
char* p_CurrentChar = szMessageBuffer;
while (p_CurrentChar != szMessageBuffer + sizeof
(szMessageBuffer) &&
*p_CurrentChar != NULL)
{
if (*p_CurrentChar == 10 ||
*p_CurrentChar == 13)
{
*p_CurrentChar = NULL;
}
p_CurrentChar++;
}
printf("--- setsockopt() failed: %d (%s).\n", iLastError,
szMessageBuffer);
closesocket(SomeSocket);
WSACleanup();
return;
}
//----------------------
// The sockaddr_in structure specifies the address family,
// IP address, and port for the socket that is being bound.
sockaddr_in service;
service.sin_family = AF_INET;
service.sin_addr.s_addr = inet_addr(p_szIPAddress);
service.sin_port = htons(usPort);
//----------------------
// Bind the socket.
if (bind( SomeSocket, (SOCKADDR*) &service, sizeof(service)) ==
SOCKET_ERROR)
{
int iLastError = WSAGetLastError();
char szMessageBuffer[512];
memset(szMessageBuffer, 0, sizeof(szMessageBuffer));
FormatMessageA(
FORMAT_MESSAGE_FROM_SYSTEM,
NULL,
iLastError,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default
language
szMessageBuffer,
sizeof(szMessageBuffer) - 1,
NULL
);
// Remove newlines
char* p_CurrentChar = szMessageBuffer;
while (p_CurrentChar != szMessageBuffer + sizeof
(szMessageBuffer) &&
*p_CurrentChar != NULL)
{
if (*p_CurrentChar == 10 ||
*p_CurrentChar == 13)
{
*p_CurrentChar = NULL;
}
p_CurrentChar++;
}
printf("--- bind() failed: %d (%s).\n", iLastError,
szMessageBuffer);
closesocket(SomeSocket);
WSACleanup();
return;
}
//----------------------
// The sockaddr_in structure specifies the address family,
// IP address, and port for the socket that is being connected to.
sockaddr_in client_service;
client_service.sin_family = AF_INET;
client_service.sin_addr.s_addr = inet_addr("209.85.129.104");
client_service.sin_port = htons(80);
//----------------------
// Connect to server.
if ( connect( SomeSocket, (SOCKADDR*) &client_service, sizeof
(client_service) ) == SOCKET_ERROR)
{
int iLastError = WSAGetLastError();
char szMessageBuffer[512];
memset(szMessageBuffer, 0, sizeof(szMessageBuffer));
FormatMessageA(
FORMAT_MESSAGE_FROM_SYSTEM,
NULL,
iLastError,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default
language
szMessageBuffer,
sizeof(szMessageBuffer) - 1,
NULL
);
// Remove newlines
char* p_CurrentChar = szMessageBuffer;
while (p_CurrentChar != szMessageBuffer + sizeof
(szMessageBuffer) &&
*p_CurrentChar != NULL)
{
if (*p_CurrentChar == 10 ||
*p_CurrentChar == 13)
{
*p_CurrentChar = NULL;
}
p_CurrentChar++;
}
printf("--- connect() failed: %d (%s).\n", iLastError,
szMessageBuffer);
closesocket(SomeSocket);
WSACleanup();
return;
}
printf("+++ Success!!!\n");
//----------------------
// Cleanup
closesocket(SomeSocket);
WSACleanup( );
}
int main(int argc, char* argv[])
{
char* p_szIP = "192.168.2.23";
if (argc == 2)
{
p_szIP = argv[1];
}
TryBindUDP("0.0.0.0", 0);
TryBindUDP("0.0.0.0", 1024);
TryBindUDP("0.0.0.0", 32033);
TryBindUDP("0.0.0.0", 55301);
TryBindUDP(p_szIP, 0);
TryBindUDP(p_szIP, 1024);
TryBindUDP(p_szIP, 32033);
TryBindUDP(p_szIP, 55301);
TryBindTCP("0.0.0.0", 0);
TryBindTCP("0.0.0.0", 1024);
TryBindTCP("0.0.0.0", 32033);
TryBindTCP("0.0.0.0", 55301);
TryBindTCP(p_szIP, 0);
TryBindTCP(p_szIP, 1024);
TryBindTCP(p_szIP, 32033);
TryBindTCP(p_szIP, 55301);
TryConnectTCP("0.0.0.0", 0);
TryConnectTCP("0.0.0.0", 1024);
TryConnectTCP("0.0.0.0", 32033);
TryConnectTCP("0.0.0.0", 55301);
TryConnectTCP(p_szIP, 0);
TryConnectTCP(p_szIP, 1024);
TryConnectTCP(p_szIP, 32033);
TryConnectTCP(p_szIP, 55301);
}
----------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------
Your program appears malicious, making all these connections and no
doing anything with them. You are triggering Vista SP1's anti-malware
logic. This logic has been removed in SP2.
DS
Hi David,
Thanks for the reply.The test application that I included with this
post
might indeed be considered suspicious - but it is not the application
which I originally discovered that the issue affects. My real
application
simply attempts to open TCP connections to www.google.com,
www.microsoft.com and www.facebook.com (port 80) to try and detect
connectivity to the internet. The application works great everywhere,
except on Windows Vista SP1. Is the real application's behavior also
considered malware-ish?
I am considering moving to ICMP pings instead of TCP connections
to test connectivity, which might help us circumvent the problem.
However, I am afraid it will pop up later on with other socket based
activities we perform in the application. I would really appreciate
any relevant links that document the anti-malware logic in SP1 and
its removal in SP2 that you might have and can possibly share!
Thanks again,
Alon
Hi,
I've figured out the problem. It was the ESET NOD32 antivirus HTTP
filter module,
which apparently keeps on working even when the rest of the anti-virus
and web
protection modules are disabled.
For more details, look here:
http://aprogrammers.blogspot.com/2009/08/winsock-error-10049-with-no-apparent.html
Alon
> I've figured out the problem. It was the ESET NOD32 antivirus HTTP
> filter module,
> which apparently keeps on working even when the rest of the anti-virus
> and web
> protection modules are disabled.
>
> For more details, look here:http://aprogrammers.blogspot.com/2009/08/winsock-error-10049-with-no-...
Sounds like you correctly detected that the computer did not have
Internet access. If a program cannot make an HTTP connection, the
computer does not have Internet access. Your test defines Internet
access as "any program can make a connection to port 80 on well-known
servers".
The trick to correctly detecting if a computer has Internet access is
to first precisely defined what it means to "have Internet access" and
test for exactly that.
DS