Home > Blockchain >  Get WSAEFAULT error when I use getsockname
Get WSAEFAULT error when I use getsockname

Time:07-29

When I run following code, I always get WSAEFAULT error. Not sure what am I doing wrong? Any help will be appreciated. Thank you.

uint8_t status = ICRON_OK;
struct sockaddr_in serverAddr, clientAddr;
int rc = 0;
int clen = sizeof(clientAddr);
int serverSocket;

if((serverSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == INVALID_SOCKET)
{
    printf("Socket Creation failure\n");
    exit(EXIT_FAILURE);
}

memset(&serverAddr, 0, sizeof(serverAddr));
serverAddr.sin_family = AF_INET;
serverAddr.sin_addr.s_addr = INADDR_ANY;
serverAddr.sin_port = htons(ICONTROLNET_EVENT_PORT);

if(bind(serverSocket, (struct sockaddr *)&serverAddr, sizeof(serverAddr)) == SOCKET_ERROR)
{
    printf("bind failure\n");
    WSACleanup();
    closesocket(serverSocket);
    exit(EXIT_FAILURE);
}

if (getsockname(serverSocket, (struct sockaddr *)&serverAddr, (int *)sizeof(serverAddr)) != 0)
{  
    printf("GETSOCKNAME ERROR = %d\n", WSAGetLastError());
    //Here always get WSAEFAULT
}

CodePudding user response:

According to the official Microsoft documentation for the function getsockname, when you get the error code WSAEFAULT, it means the following:

The name or the namelen parameter is not a valid part of the user address space, or the namelen parameter is too small.

This documentation later states the following about the namelen parameter, which is the third parameter of getsockname:

On call, the namelen parameter contains the size of the name buffer, in bytes. On return, the namelen parameter contains the actual size in bytes of the name parameter.

When the documentation uses the word "contains", it means that the pointer namelen should point to an int which specifies the size of the object pointed to by name (the second parameter).

You are passing the following expression as the third parameter:

(int *)sizeof(serverAddr)

This is wrong. It is correct to use the expression sizeof serverAddr or sizeof(serverAddr). However, instead of casting that value to a pointer and passing that pointer directly to the function getsockname, you should instead pass a pointer to an int which contains the value sizeof serverAddr.

Therefore, you should change the line

if (getsockname(serverSocket, (struct sockaddr *)&serverAddr, (int *)sizeof(serverAddr)) != 0)

to:

int serverAddrSize = sizeof serverAddr;
if (getsockname(serverSocket, (struct sockaddr *)&serverAddr, &serverAddrSize) != 0)
  • Related