Home > front end >  Winsock connect fails with WSAEFAULT | Error on Windows 11 only
Winsock connect fails with WSAEFAULT | Error on Windows 11 only

Time:11-06

My code perfectly works on any Windows from XP to 10. Now I've tested my code for the first time in Win11, and the connect() function fails with error 10014 WSAEFAULT:

Bad address. The system detected an invalid pointer address in attempting to use a pointer argument of a call. This error occurs if an application passes an invalid pointer value, or if the length of the buffer is too small. For instance, if the length of an argument, which is a sockaddr structure, is smaller than the sizeof(sockaddr).

However as I checked with my debugger, the sockaddr_in structure seems to be passed correctly:

connect(hSocket, (sockaddr*)(&InSockAddr), sizeof(InSockAddr))

enter image description here

I am using Visual C 2015 compiler.

Here is a snipped of the relevant code:

#include <WinSock2.h>

class CConnection
{
   public:
    static bool         bWinsockInitialized;
    SOCKET              hSocket = INVALID_SOCKET;
    sockaddr_in         sockAddr;
         
    bool                Create();
    bool                InitializeWinsock();
    bool                Connect(sockaddr_in &InSockAddr);
};   

CConnection sckt_Main;
sockaddr_in g_sockAddr;


void main()
{
    if (!sckt_Main.Create())
    {
        // Error: Unable to create connection socket
        return;
    }

    g_sockAddr.sin_family = AF_INET;

    // Get IP address from string. 
    // If address is a DNS, HostInfo->h_addr will contain resolved IP address.
    // Save host information into HostInfo struct:
    hostent* HostInfo = gethostbyname("127.0.0.1");

    //Error checking:
    if (!HostInfo) {
        return;
    }

    assert((sizeof(g_sockAddr.sin_addr)) >= HostInfo->h_length);

    //Copy the resolved IP address into our sockAddr structure: 
    memcpy(&g_sockAddr.sin_addr, HostInfo->h_addr, HostInfo->h_length);

    //Saves connection port
    g_sockAddr.sin_port = htons(atoi("2405"));
    
    sckt_Main.Connect(g_sockAddr);
}


bool CConnection::Create()
{
    if (!InitializeWinsock()) {
        return false;
    }
        
    hSocket = socket(AF_UNSPEC, SOCK_STREAM, IPPROTO_TCP);
        
    if (this->hSocket == INVALID_SOCKET) 
        return false;
        
    return true;
}


bool CConnection::InitializeWinsock()
{
    WSADATA wsaData;
    if (!WSAStartup(MAKEWORD(2, 2), &wsaData)) {
       bWinsockInitialized = true;
    } 
    else bWinsockInitialized = false;
        
    return bWinsockInitialized;
}


bool CConnection::Connect(sockaddr_in &InSockAddr)
{

    // If no error occurs, connect returns zero. 
    // Otherwise, it returns SOCKET_ERROR, and a specific error code can be retrieved by calling WSAGetLastError.
    if (connect(hSocket, (sockaddr*)(&InSockAddr), sizeof(InSockAddr)) == 0)
    {
       // Connect SUCCESS
       return true;
    }
    else 
    {   
       // !!! connect error !!!
       int err = WSAGetLastError();
       return false;
    }
}

CodePudding user response:

As noted in the comments, your code is not IPv6 aware. Windows 11 ships with IPv6 enabled by default.

You should update your code to be IPv4 vs. IPv6 agnostic.

See Microsoft Docs.

Note Microsoft stop shipping checkv4.exe ages ago, but if I run it against your code I get:

sockaddr_in : use sockaddr_storage instead, or use sockaddr_in6 in addition for IPv6 support

AF_INET : use AF_INET6 in addition for IPv6 support

gethostbyname : use getaddrinfo instead

hostent : use addrinfo instead
  • Related