-2

I'm making a socket program in C++ using winsock2 and I'm trying to use WSAAccept to conditionally accept connections. I copied the example ConditionalFunction from MSDN for the lpfnCondition argument in WSAAccept as seen below.

SOCKET WSAAccept(
  _In_    SOCKET          s,
  _Out_   struct sockaddr *addr,
  _Inout_ LPINT           addrlen,
  _In_    LPCONDITIONPROC lpfnCondition, //<---------
  _In_    DWORD_PTR       dwCallbackData
);

However when trying to access the contents of lpCallerId in the ConditionalFunction like so WSABUF buffer = *lpCallerData my program crashes. I know this is the source of the problem because when I comment that line out my program doesn't crash. I don't think all of my code would be necessary. Any help would be lovely.

EDIT:

CALLBACK ConditionalAccept(LPWSABUF lpCallerId,LPWSABUF lpCallerData,LPQOS lpSQOS,
                           LPQOS lpGQOS,LPWSABUF lpCalleeId,LPWSABUF lpCalleeData,
                           GROUP *g,DWORD_PTR dwCallbackData)
{
    WSABUF buffer = *lpCallerData;

    if (lpSQOS != NULL) {
        RtlZeroMemory(lpSQOS, sizeof(QOS));
        return CF_ACCEPT;
    } else
        return CF_REJECT;
}

...

WSAAccept(slisten, (SOCKADDR*)&acceptSock, &Size, &ConditionalAccept, NULL);
John Doe
  • 120
  • 8
  • 3
    Please try to create a [Minimal, Complete, and Verifiable Example](http://stackoverflow.com/help/mcve) that you can show us. – Some programmer dude Jun 13 '16 at 22:19
  • What is `lpCallerData`? – user253751 Jun 13 '16 at 22:21
  • 2
    If you can read the MSDN document regarding this parameter: The information in these parameters is sent along with the connection request. *If no caller identification or caller data is available, the corresponding parameters will be NULL*. – xiaofeng.li Jun 13 '16 at 22:24
  • @LukeLee I don't understand why trying to retrieve the contents of a `NULL` variable would make my program crash. – John Doe Jun 13 '16 at 22:26
  • @immibis `lpCallerData` is, as stated on [MSDN](https://msdn.microsoft.com/en-us/library/windows/desktop/ms741513(v=vs.85).aspx#code-snippet-2) "The lpCallerData is a value parameter that contains any user data." – John Doe Jun 13 '16 at 22:29
  • Related: [how to use WSAConnect and WSAAccept for sending receving init Data before accept a request](http://stackoverflow.com/questions/16247621/). `lpCallerData` is **always** NULL in TCP/IP. – Remy Lebeau Jun 13 '16 at 23:05

1 Answers1

3

As Luke stated, you are not checking lpCallerData for NULL before dereferencing it. That is why your code is crashing.

int CALLBACK ConditionalAccept(LPWSABUF lpCallerId,LPWSABUF lpCallerData,LPQOS lpSQOS,
                           LPQOS lpGQOS,LPWSABUF lpCalleeId,LPWSABUF lpCalleeData,
                           GROUP *g,DWORD_PTR dwCallbackData)
{
    WSABUF buffer = {0};

    if (lpCallerData != NULL) { // <-- add this check!
        buffer = *lpCallerData;
    }

    if (lpSQOS != NULL) {
        RtlZeroMemory(lpSQOS, sizeof(QOS));
        return CF_ACCEPT;
    } else
        return CF_REJECT;
}

However, lpCallerData is meaningless in TCP/IP and will always be NULL. TCP/IP does not support exchanging caller/callee data during connection establishment. This is clearly stated in the WSAConnect() documentation:

The lpCallerData parameter contains a pointer to any user data that is to be sent along with the connection request (called connect data). This is additional data, not in the normal network data stream, that is sent with network requests to establish a connection. This option is used by legacy protocols such as DECNet, OSI TP4, and others.

Note Connect data is not supported by the TCP/IP protocol in Windows. Connect data is supported only on ATM (RAWWAN) over a raw socket.

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770