Implementation of Listen Bind and accept. (Rev 273)
authortzachid <tzachid@ad392aa1-c5ef-ae45-8dd8-e69d62a5ef86>
Mon, 21 Nov 2005 12:19:58 +0000 (12:19 +0000)
committertzachid <tzachid@ad392aa1-c5ef-ae45-8dd8-e69d62a5ef86>
Mon, 21 Nov 2005 12:19:58 +0000 (12:19 +0000)
git-svn-id: svn://openib.tc.cornell.edu/gen1/trunk@171 ad392aa1-c5ef-ae45-8dd8-e69d62a5ef86

15 files changed:
ulp/sdp/include/SdpShared.h
ulp/sdp/kernel/Precompile.h
ulp/sdp/kernel/SOURCES
ulp/sdp/kernel/SdpArp.h
ulp/sdp/kernel/SdpConnectionList.cpp [new file with mode: 0644]
ulp/sdp/kernel/SdpConnectionList.h [new file with mode: 0644]
ulp/sdp/kernel/SdpDriver.cpp
ulp/sdp/kernel/SdpGenUtils.cpp
ulp/sdp/kernel/SdpGenUtils.h
ulp/sdp/kernel/SdpMsgs.h
ulp/sdp/kernel/SdpRecvPool.cpp
ulp/sdp/kernel/SdpRecvPool.h
ulp/sdp/kernel/SdpSocket.cpp
ulp/sdp/kernel/SdpSocket.h
ulp/sdp/kernel/SdpTrace.h

index 2c4a8d5..f647de4 100644 (file)
@@ -15,6 +15,9 @@
 #define IOCTL_WSP_CONNECT   CTL_CODE(FILE_DEVICE_UNKNOWN, 0x802, METHOD_BUFFERED ,FILE_ANY_ACCESS)\r
 #define IOCTL_WSP_SEND      CTL_CODE(FILE_DEVICE_UNKNOWN, 0x803, METHOD_BUFFERED ,FILE_ANY_ACCESS)\r
 #define IOCTL_WSP_RECV      CTL_CODE(FILE_DEVICE_UNKNOWN, 0x804, METHOD_BUFFERED ,FILE_ANY_ACCESS)\r
+#define IOCTL_WSP_BIND      CTL_CODE(FILE_DEVICE_UNKNOWN, 0x805, METHOD_BUFFERED ,FILE_ANY_ACCESS)\r
+#define IOCTL_WSP_LISTEN    CTL_CODE(FILE_DEVICE_UNKNOWN, 0x806, METHOD_BUFFERED ,FILE_ANY_ACCESS)\r
+#define IOCTL_WSP_ACCEPT    CTL_CODE(FILE_DEVICE_UNKNOWN, 0x807, METHOD_BUFFERED ,FILE_ANY_ACCESS)\r
 \r
 \r
 \r
@@ -63,5 +66,35 @@ struct WspRecvOut {
     ULONG dwFlags;    \r
 };\r
 \r
+struct WspBindIn {\r
+    VOID *pSocket;    \r
+    ULONG IP;\r
+    USHORT Port;\r
+};\r
+\r
+struct WspBindOut {\r
+    int Errno;\r
+};\r
+\r
+struct WspListenIn {\r
+    VOID *pSocket;    \r
+    int backlog;\r
+};\r
+\r
+struct WspListenOut {\r
+    int Errno;\r
+};\r
+\r
+struct WspAcceptIn {\r
+    VOID *pSocket;    \r
+};\r
+\r
+struct WspAcceptOut {\r
+    int Errno;\r
+    VOID *pAccaptedSocket;\r
+    ULONG IP;\r
+    USHORT Port;    \r
+};\r
+\r
 \r
 #endif //_SDP_SHARED_H\r
index 3f31442..ffcdb34 100644 (file)
@@ -25,6 +25,7 @@ class SdpArp;
 #include "SdpUserFile.h"\r
 #include "SdpBufferPool.h"\r
 #include "SdpRecvPool.h"\r
+#include "SdpConnectionList.h"\r
 #include "SdpSocket.h"\r
 #include "SdpArp.h"\r
 \r
index a675f0a..83f1c42 100644 (file)
@@ -9,6 +9,7 @@ SOURCES= SdpDriver.cpp          \
         SdpArp.cpp             \\r
         SdpBufferPool.cpp      \\r
         SdpRecvPool.cpp        \\r
+        SdpConnectionList.cpp  \\r
         SdpTrace.cpp\r
 \r
 INCLUDES=..\include;\\r
index 5ad6236..0ce5135 100644 (file)
@@ -28,11 +28,11 @@ public:
         if (DestIp == 11 * 256*256*256 + \r
                       4 * 256*256 +\r
                       8 * 256 +\r
-                      + 124) {\r
+                      + 170) {\r
             *SrcIp = 11 * 256*256*256 + \r
                       4 * 256*256 +\r
                       8 * 256 +\r
-                      + 120;\r
+                      + 159;\r
             return STATUS_SUCCESS;\r
         }\r
         ASSERT(FALSE);\r
@@ -54,7 +54,6 @@ public:
 \r
     }\r
 \r
-\r
     NTSTATUS SourcePortGidFromIP(\r
         IN  ULONG  SourceAddr, \r
         OUT ib_net64_t *SrcPortGuid,\r
@@ -64,11 +63,11 @@ public:
         if (SourceAddr == 11 * 256*256*256 + \r
                       4 * 256*256 +\r
                       8 * 256 +\r
-                      + 120) {\r
+                      + 159) {\r
 //            *SrcPortGuid = CL_NTOH64(0x2c90200002001);//????? swlab120\r
 //            *SrcCaGuid = CL_NTOH64(0x2c90200002000);\r
 \r
-            *SrcPortGuid = CL_NTOH64(0x2c9010b7c4362);//????? swlab159\r
+            *SrcPortGuid = CL_NTOH64(0x2c9010b7c4361);//????? swlab159\r
             *SrcCaGuid = CL_NTOH64(0x2c9010b7c4360);\r
             return STATUS_SUCCESS;\r
         }\r
@@ -87,8 +86,11 @@ public:
         if (DestAddr == 11 * 256*256*256 + \r
                       4 * 256*256 +\r
                       8 * 256 +\r
-                      + 124) {\r
-            *DestPortGuid = CL_NTOH64(0x0000c900012a3a41);//????? swlab124\r
+                      + 170) {\r
+            //*DestPortGuid = CL_NTOH64(0x0000c900012a3a41);//????? swlab124\r
+            //*DestPortGuid = CL_NTOH64(0x0002c90200400301);//????? swlab170\r
+            *DestPortGuid =   CL_NTOH64(0x0002c902004002fe);//????? swlab170\r
+            \r
             return STATUS_SUCCESS;\r
         }\r
         ASSERT(FALSE);\r
diff --git a/ulp/sdp/kernel/SdpConnectionList.cpp b/ulp/sdp/kernel/SdpConnectionList.cpp
new file mode 100644 (file)
index 0000000..4888ccc
--- /dev/null
@@ -0,0 +1,136 @@
+/* Copyright mellanox */\r
+\r
+#include "Precompile.h"\r
+\r
+VOID \r
+ConnectionList::Init(SdpSocket *pSdpSocket) \r
+{\r
+    SDP_PRINT(SDP_TRACE, SDP_CONNECTION_LIST, ("this = 0x%p \n", this));\r
+    m_pSdpSocket = pSdpSocket;\r
+    m_ClientWaiting = false;\r
+    KeInitializeEvent(&m_WaitForConnection, NotificationEvent , FALSE );\r
+}\r
+\r
+VOID ConnectionList::Shutdown() \r
+{\r
+    //????????\r
+    //?????AssertLocked();\r
+    SDP_PRINT(SDP_TRACE, SDP_CONNECTION_LIST, ("this = 0x%p \n", this));\r
+    \r
+}\r
+\r
+bool \r
+ConnectionList::IsFull() \r
+{\r
+    SDP_PRINT(SDP_TRACE, SDP_CONNECTION_LIST, ("this = 0x%p \n", this));\r
+    AssertLocked();\r
+    int CurrentConnections = \r
+        m_ReplySentConnections.Size() + m_ReadyConnections.Size();\r
+    return CurrentConnections >= m_BackLog;\r
+}\r
+\r
+NTSTATUS \r
+ConnectionList::AddConnectionToReplySent(SdpSocket *pNewSocket) \r
+{   \r
+    SDP_PRINT(SDP_TRACE, SDP_CONNECTION_LIST, ("this = 0x%p \n", this));\r
+    AssertLocked();\r
+    m_ReplySentConnections.InsertTailList(&pNewSocket->m_ListeningSocketList);\r
+    pNewSocket->AddRef();\r
+    return 0;\r
+}\r
+\r
+// Go over the list of connections and verify that such a connection\r
+// exists\r
+NTSTATUS \r
+ConnectionList::VerifyConnictionInReplySent(SdpSocket *pNewSocket) \r
+{\r
+    SDP_PRINT(SDP_TRACE, SDP_CONNECTION_LIST, ("this = 0x%p \n", this));\r
+    AssertLocked();\r
+    SdpSocket *pSocket = NULL;\r
+#if DBG\r
+    LIST_ENTRY *item = m_ReplySentConnections.Head();\r
+    while (item->Flink != m_ReplySentConnections.Head()) {\r
+        pSocket = CONTAINING_RECORD(item, SdpSocket , m_ListeningSocketList);\r
+        if (pSocket == pNewSocket) {\r
+            // We have found what we were looking for\r
+            return STATUS_SUCCESS;\r
+        }\r
+    }\r
+    // Not found, return error\r
+    ASSERT(FALSE);\r
+    return STATUS_UNEXPECTED_IO_ERROR;\r
+#else\r
+    return STATUS_SUCCESS;\r
+    \r
+#endif // DBG\r
+\r
+}\r
+\r
+VOID \r
+ConnectionList::MoveConnectionFromReplyToReady(SdpSocket *pNewSocket) \r
+{\r
+    SDP_PRINT(SDP_TRACE, SDP_CONNECTION_LIST, ("this = 0x%p \n", this));\r
+    AssertLocked();\r
+    pNewSocket->AssertLocked();\r
+    // just take it out from one list and put it in the other\r
+    RemoveEntryList(&pNewSocket->m_ListeningSocketList);\r
+    m_ReadyConnections.InsertTailList(&pNewSocket->m_ListeningSocketList);\r
+}\r
+\r
+VOID \r
+ConnectionList::FreeWaitingIfCan() \r
+{\r
+    SDP_PRINT(SDP_TRACE, SDP_CONNECTION_LIST, ("this = 0x%p \n", this));\r
+    AssertLocked();\r
+    if (m_ClientWaiting) {\r
+        ASSERT(m_ReadyConnections.Size() > 0);\r
+        KeSetEvent( &m_WaitForConnection, IO_NO_INCREMENT, FALSE );\r
+        m_ClientWaiting = false;\r
+    }\r
+}\r
+\r
+NTSTATUS    \r
+ConnectionList::AcceptAReadyConnection(\r
+    SdpSocket **ppNewSocket,\r
+    KEVENT **ppEvent\r
+    )\r
+{\r
+    SDP_PRINT(SDP_TRACE, SDP_CONNECTION_LIST, ("this = 0x%p \n", this));\r
+\r
+    ASSERT(*ppEvent == NULL);\r
+    ASSERT(*ppNewSocket == NULL);\r
+    LIST_ENTRY *item = NULL;\r
+\r
+    if (m_ClientWaiting) {\r
+        ASSERT(m_ClientWaiting == false);\r
+        // This is very likely caused because of two threads that are calling\r
+        // accept (not supported currently)\r
+        //?????? print ?????\r
+        return STATUS_UNEXPECTED_IO_ERROR;\r
+    }\r
+    if (m_ReadyConnections.Size() > 0) {\r
+        // We have a connection to return\r
+        // TODO: This connection might be in a bad state. What should we do\r
+        item = m_ReadyConnections.RemoveHeadList();\r
+        *ppNewSocket = CONTAINING_RECORD(item, SdpSocket , m_ListeningSocketList);\r
+        // There is no change of the referance count, since we are taking \r
+        // the socket from the list, but we are also giving it to someone else\r
+        return STATUS_SUCCESS;        \r
+    }\r
+\r
+    // We don't have a ready socket to return, the caller will have\r
+    // to wait\r
+    KeClearEvent(&m_WaitForConnection);\r
+    m_ClientWaiting = true;\r
+    *ppEvent = &m_WaitForConnection;\r
+    return STATUS_SUCCESS;\r
+}\r
+\r
+\r
+VOID \r
+ConnectionList::AssertLocked() {\r
+#if DBG\r
+    m_pSdpSocket->AssertLocked();\r
+#endif\r
+}\r
+\r
diff --git a/ulp/sdp/kernel/SdpConnectionList.h b/ulp/sdp/kernel/SdpConnectionList.h
new file mode 100644 (file)
index 0000000..cb95896
--- /dev/null
@@ -0,0 +1,47 @@
+/* Copyright mellanox */\r
+\r
+#ifndef H_SDP_CONNECTION_LIST_H\r
+#define H_SDP_CONNECTION_LIST_H \r
+\r
+// All functions here (including shutdown, should be called with\r
+// the lock taken)\r
+\r
+class ConnectionList {\r
+\r
+public:\r
+    VOID        Init(SdpSocket *pSdpSocket);\r
+    VOID        Shutdown();\r
+\r
+    bool        IsFull();\r
+    VOID        SetBackLog(int BackLog) {\r
+        m_BackLog = BackLog;\r
+        };\r
+    NTSTATUS    AddConnectionToReplySent(SdpSocket *pNewSocket);\r
+\r
+    // Go over the list of connections and verify that such a connection\r
+    // exists\r
+    NTSTATUS    VerifyConnictionInReplySent(SdpSocket *pNewSocket);\r
+    \r
+    VOID        MoveConnectionFromReplyToReady(SdpSocket *pNewSocket);\r
+\r
+    VOID        FreeWaitingIfCan();\r
+\r
+    NTSTATUS    AcceptAReadyConnection(\r
+        SdpSocket **ppNewSocket,\r
+        KEVENT **ppEvent\r
+        );\r
+\r
+private:\r
+\r
+    VOID        AssertLocked();\r
+\r
+    SdpSocket   *m_pSdpSocket; // No refcount as we are part of this socket\r
+\r
+    int m_BackLog;\r
+    LinkedList  m_ReplySentConnections;\r
+    LinkedList  m_ReadyConnections;\r
+    KEVENT      m_WaitForConnection;\r
+    bool        m_ClientWaiting;\r
+\r
+};\r
+#endif //H_SDP_CONNECTION_LIST_H\r
index e262f0d..29a1271 100644 (file)
@@ -339,6 +339,7 @@ NTSTATUS SdpDriver::DispatchDeviceIoControl(
     NTSTATUS rc = STATUS_SUCCESS;\r
     SdpUserFile *pSdpUserFile = NULL;\r
     SdpSocket *pSdpSocket = NULL;\r
+    SdpSocket *pAcceptedSdpSocket = NULL;\r
     \r
     switch (IoControlCode) {\r
         case IOCTL_WSP_SOCKET :\r
@@ -446,6 +447,89 @@ NTSTATUS SdpDriver::DispatchDeviceIoControl(
         }\r
         break;\r
 \r
+        case IOCTL_WSP_BIND:\r
+        {\r
+            SDP_PRINT(SDP_DEBUG, SDP_DRIVER, ("IOCTL_WSP_BIND recieved\n" ));   \r
+            VERIFY_BUFFERS(InputBufferLength, OutputBufferLength, WspBindIn, WspBindOut);\r
+            OutputDataSize = sizeof (WspBindOut);\r
+\r
+            // get the socket based on the users pointer\r
+            WspBindIn wspBindIn = *(WspBindIn *) pInputBuffer;\r
+            WspBindOut *pWspBindOut = (WspBindOut *) pOutputBuffer;\r
+            pSdpUserFile = (SdpUserFile *)pIrpSp->FileObject->FsContext;\r
+            pSdpSocket = pSdpUserFile->SocketByPointer(wspBindIn.pSocket);\r
+            if (pSdpSocket == NULL) {\r
+               SDP_PRINT(SDP_DEBUG, SDP_DRIVER, ("IOCTL_WSP_BIND socket %x not found\n", wspBindIn.pSocket));   \r
+               // This is a well defined winsock error\r
+               pWspBindOut->Errno = WSAENOTSOCK;\r
+               goto Cleanup;\r
+            }\r
+            rc = pSdpSocket->WSPBind(&wspBindIn, pWspBindOut);\r
+            if (!NT_SUCCESS(rc)) {\r
+                SDP_PRINT(SDP_ERR, SDP_DRIVER, ("pSdpSocket->WSPBind failed rc = 0x%x\n", rc ));        \r
+                goto Cleanup;\r
+            }\r
+        }\r
+        break;\r
+\r
+        case IOCTL_WSP_LISTEN:\r
+        {\r
+            SDP_PRINT(SDP_DEBUG, SDP_DRIVER, ("IOCTL_WSP_LISTEN recieved\n" ));   \r
+            VERIFY_BUFFERS(InputBufferLength, OutputBufferLength, WspListenIn, WspListenOut);\r
+            OutputDataSize = sizeof (WspListenOut);\r
+\r
+            // get the socket based on the users pointer\r
+            WspListenIn wspListenIn = *(WspListenIn *) pInputBuffer;\r
+            WspListenOut *pWspListenOut = (WspListenOut *) pOutputBuffer;\r
+            pSdpUserFile = (SdpUserFile *)pIrpSp->FileObject->FsContext;\r
+            pSdpSocket = pSdpUserFile->SocketByPointer(wspListenIn.pSocket);\r
+            if (pSdpSocket == NULL) {\r
+               SDP_PRINT(SDP_DEBUG, SDP_DRIVER, ("IOCTL_WSP_LISTEN socket %x not found\n",wspListenIn.pSocket));   \r
+               // This is a well defined winsock error\r
+               pWspListenOut->Errno = WSAENOTSOCK;\r
+               goto Cleanup;\r
+            }\r
+            rc = pSdpSocket->WSPListen(&wspListenIn, pWspListenOut);\r
+            if (!NT_SUCCESS(rc)) {\r
+                SDP_PRINT(SDP_ERR, SDP_DRIVER, ("pSdpSocket->WSPRecv failed rc = 0x%x\n", rc ));        \r
+                goto Cleanup;\r
+            }\r
+        }\r
+        break;\r
+\r
+        case IOCTL_WSP_ACCEPT:\r
+        {\r
+            SDP_PRINT(SDP_DEBUG, SDP_DRIVER, ("IOCTL_WSP_ACCEPT recieved\n" ));   \r
+            VERIFY_BUFFERS(InputBufferLength, OutputBufferLength, WspAcceptIn, WspAcceptOut);\r
+            OutputDataSize = sizeof (WspAcceptOut);\r
+\r
+            // get the socket based on the users pointer\r
+            WspAcceptIn wspAcceptIn = *(WspAcceptIn *) pInputBuffer;\r
+            WspAcceptOut *pWspAcceptOut = (WspAcceptOut *) pOutputBuffer;\r
+            pSdpUserFile = (SdpUserFile *)pIrpSp->FileObject->FsContext;\r
+            pSdpSocket = pSdpUserFile->SocketByPointer(wspAcceptIn.pSocket);\r
+            if (pSdpSocket == NULL) {\r
+               SDP_PRINT(SDP_DEBUG, SDP_DRIVER, ("IOCTL_WSP_ACCEPT socket %x not found\n",wspAcceptIn.pSocket));   \r
+               // This is a well defined winsock error\r
+               pWspAcceptOut->Errno = WSAENOTSOCK;\r
+               goto Cleanup;\r
+            }\r
+            rc = pSdpSocket->WSPAccept(&wspAcceptIn, pWspAcceptOut);\r
+            if (!NT_SUCCESS(rc)) {\r
+                SDP_PRINT(SDP_ERR, SDP_DRIVER, ("pSdpSocket->WSPAccept failed rc = 0x%x\n", rc ));        \r
+                goto Cleanup;\r
+            }\r
+            if (pWspAcceptOut->pAccaptedSocket != NULL) {\r
+                pAcceptedSdpSocket = (SdpSocket *) pWspAcceptOut->pAccaptedSocket;\r
+                rc = pSdpUserFile->AddSocket(pAcceptedSdpSocket);\r
+                if (!NT_SUCCESS(rc)) {\r
+                    SDP_PRINT(SDP_ERR, SDP_DRIVER, ("pSdpUserFile->AddSocket failed rc = 0x%x\n", rc ));\r
+                    pAcceptedSdpSocket->Shutdown();\r
+                    goto Cleanup;\r
+                }            \r
+            }\r
+        }\r
+        break;\r
         \r
         \r
     default:\r
@@ -461,6 +545,10 @@ Cleanup:
     if (pSdpSocket) {\r
         pSdpSocket->Release();\r
     }\r
+    if (pAcceptedSdpSocket) {\r
+        pAcceptedSdpSocket->Release();\r
+    }\r
+    \r
     return rc;\r
 }\r
 \r
index 5f24697..cad9a83 100644 (file)
@@ -141,6 +141,34 @@ int abs(int i){
     return -i;\r
 }\r
 \r
+/* Convert an IBAL error to a Winsock error. */\r
+int IbalToWsaError(const       ib_api_status_t ib_status )\r
+{\r
+    switch( ib_status )\r
+    {\r
+    case IB_SUCCESS:\r
+        return 0;\r
+\r
+    case IB_INVALID_QP_HANDLE:\r
+        return WSAENOTCONN;\r
+\r
+    case IB_INVALID_PARAMETER:\r
+        return WSAEINVAL;\r
+\r
+    case IB_INSUFFICIENT_RESOURCES:\r
+        return WSAENOBUFS;\r
+\r
+    case IB_INVALID_WR_TYPE:\r
+        return WSAEINVAL;\r
+\r
+    case IB_INVALID_QP_STATE:\r
+        return WSAENOTCONN;\r
+\r
+    default:\r
+        return WSAEINVAL;\r
+    }\r
+}\r
+\r
 void* __cdecl operator new(size_t n ) throw() {\r
     return ExAllocatePoolWithTag(NonPagedPool , n, GLOBAL_ALLOCATION_TAG);\r
 }\r
index 497b805..98f2256 100644 (file)
@@ -72,9 +72,13 @@ VOID UpdateRc(NTSTATUS *rc, NTSTATUS rc1);
 \r
 int abs(int i);\r
 \r
+/* Convert an IBAL error to a Winsock error. */\r
+int IbalToWsaError(const       ib_api_status_t ib_status );\r
+\r
+#define INADDR_ANY              (ULONG)0x00000000\r
 \r
 // This error codes are taken from winsock2.h (the file can not)\r
-// be included from user mode\r
+// be included from kernel mode\r
 \r
 /*\r
  * All Windows Sockets error constants are biased by WSABASEERR from\r
index 1895d67..fcf1b83 100644 (file)
@@ -169,7 +169,7 @@ static inline void sdp_msg_swap_hh(struct msg_hdr_hh *header)
 /*\r
  * sdp_msg_swap_hah - SDP header endian byte swapping\r
  */\r
-static inline void sdp_msg_net_to_cpu_hah(struct msg_hdr_hah *header)\r
+static inline void sdp_msg_swap_hah(struct msg_hdr_hah *header)\r
 {\r
        header->l_rcv_size = CL_NTOH32(header->l_rcv_size);\r
 }\r
index 3928c99..bfa4d2f 100644 (file)
@@ -49,6 +49,10 @@ RecvPool::RecievedBuffer(BufferDescriptor *pBufferDescriptor, bool error)
         ,this, pBufferDescriptor, error ? "true" : "false"));\r
     AssertLocked();\r
     NTSTATUS rc = STATUS_SUCCESS;\r
+\r
+    m_CurrentlyPostedRecievedBuffers--;\r
+    ASSERT(m_CurrentlyPostedRecievedBuffers >= 0);\r
+\r
     if (error) {\r
         // Not much that we can do in this case (only return the packet)\r
         m_FreePackets.InsertTailList(&pBufferDescriptor->BuffersList);\r
@@ -75,22 +79,27 @@ RecvPool::RecievedBuffer(BufferDescriptor *pBufferDescriptor, bool error)
                     (int)pHeader->seq_ack);\r
     m_pSdpSocket->m_SendBufferPool.SetRemoteRecvBuf(rRecvBuf);\r
 \r
+    // ???? Handle state changes here ????\r
+    if (pHeader->mid != 0xFF) {\r
+        // This is a message without data, we currently ignore it\r
+        m_FreePackets.InsertTailList(&pBufferDescriptor->BuffersList);\r
+    } else {\r
 \r
-    if(pHeader->size > sizeof msg_hdr_bsdh) {\r
-        m_FullPackets.InsertTailList(&pBufferDescriptor->BuffersList);\r
-        ASSERT(m_FullPackets.Size() <= m_MaxBuffers);\r
+        if(pHeader->size > sizeof msg_hdr_bsdh) {\r
+            m_FullPackets.InsertTailList(&pBufferDescriptor->BuffersList);\r
+            ASSERT(m_FullPackets.Size() <= m_MaxBuffers);\r
 \r
-        // we need to notify the client that is waiting\r
-        if (m_ClientWaiting) {\r
-            KeSetEvent( &m_WaitingClients, IO_NO_INCREMENT, FALSE );\r
-            m_ClientWaiting = false;\r
+            // we need to notify the client that is waiting\r
+            if (m_ClientWaiting) {\r
+                KeSetEvent( &m_WaitingClients, IO_NO_INCREMENT, FALSE );\r
+                m_ClientWaiting = false;\r
+            }\r
+        } else {\r
+            // This is an empty buffer\r
+            ASSERT(pHeader->size == sizeof msg_hdr_bsdh);\r
+            m_FreePackets.InsertTailList(&pBufferDescriptor->BuffersList);        \r
         }\r
-    } else {\r
-        // This is an empty buffer\r
-        ASSERT(pHeader->size == sizeof msg_hdr_bsdh);\r
-        m_FreePackets.InsertTailList(&pBufferDescriptor->BuffersList);        \r
-    }\r
-    // ???? Handle state changes here ????\r
+    }    \r
 \r
     // Check if we have to send more credits to the remote side\r
     ASSERT(m_LocaleAdvertisedBuffers > 0);\r
@@ -112,10 +121,6 @@ RecvPool::RecievedBuffer(BufferDescriptor *pBufferDescriptor, bool error)
         SDP_PRINT(SDP_ERR, SDP_BUFFER_POOL, ("SendBuffersIfCan failed rc = 0x%x\n", rc ));\r
         goto Cleanup;\r
     }        \r
-\r
-    m_CurrentlyPostedRecievedBuffers--;\r
-    \r
-    ASSERT(m_CurrentlyPostedRecievedBuffers >= 0);\r
     // We might be able to post a new recieve buffer now\r
     ASSERT(m_CurrentlyPostedRecievedBuffers < m_MaxConcurrentRecieves);\r
     rc = ReceiveIfCan();\r
@@ -149,7 +154,8 @@ RecvPool::GetData(
     uint32_t  CopySize,\r
     uint32_t *Copied,\r
     KEVENT **ppEvent,\r
-    bool FirstBuffer\r
+    bool FirstBuffer,\r
+    bool *pNoMoreData\r
     )\r
 {\r
     SDP_PRINT(SDP_TRACE, SDP_BUFFER_POOL, ("this = 0x%p FirstBuffer = %s\n",this,\r
@@ -157,6 +163,7 @@ RecvPool::GetData(
     AssertLocked();\r
     bool BufferFreed = false;\r
     *Copied = 0;\r
+    *pNoMoreData = false;\r
     BufferDescriptor *pBufferDescriptor = NULL;\r
     uint32_t  OldDataSize = 0;\r
 \r
@@ -207,6 +214,11 @@ RecvPool::GetData(
             }\r
 \r
         } else {\r
+            *pNoMoreData = true;\r
+            // If data was already supplied, then we shouldn't wait any more\r
+            if ((*Copied > 0) || (FirstBuffer == false)) {\r
+                break;\r
+            }\r
             // No buffers available, we have to wait\r
             ASSERT(m_ClientWaiting == false);\r
             KeClearEvent(&m_WaitingClients);\r
index b25a833..715b03a 100644 (file)
@@ -24,7 +24,8 @@ public:
         uint32_t  CopySize,\r
         uint32_t *Copied,\r
         KEVENT **ppEvent,\r
-        bool FirstBuffer\r
+        bool FirstBuffer,\r
+        bool *pNoMoreData\r
         );\r
 \r
     VOID AllowOthersToGet();    \r
index c35c720..d6d7e9e 100644 (file)
@@ -5,6 +5,7 @@
 #pragma warning(disable: 4244 ) \r
 \r
 NTSTATUS sdp_cm_hello_ack_check(struct sdp_msg_hello_ack *hello_ack);\r
+NTSTATUS sdp_cm_hello_check(struct sdp_msg_hello *msg_hello);\r
 static NTSTATUS __send_cb2(SdpSocket * pSdpSocket);\r
 static NTSTATUS __recv_cb2(SdpSocket * pSdpSocket);\r
 \r
@@ -19,9 +20,6 @@ static void AL_API
 cm_rep_callback(\r
     IN          ib_cm_rep_rec_t         *p_cm_rep_rec )\r
 {\r
-    \r
-\r
-    SDP_PRINT(SDP_TRACE, SDP_SOCKET, ("cm_rep_callback called\n"));\r
     SdpSocket *pSocket = (SdpSocket *) p_cm_rep_rec->qp_context;\r
     pSocket->CmRepCallback(p_cm_rep_rec);\r
 }\r
@@ -52,11 +50,61 @@ cm_dreq_callback(IN ib_cm_dreq_rec_t    *p_cm_dreq_rec )
     SDP_PRINT(SDP_TRACE, SDP_SOCKET, ("dispatch level = %d\n", KeGetCurrentIrql()));\r
     ASSERT(FALSE);\r
 }\r
+\r
+static void AL_API\r
+cm_lap_callback(\r
+    IN          ib_cm_lap_rec_t *p_cm_lap_rec )\r
+{\r
+    SDP_PRINT(SDP_TRACE, SDP_SOCKET, ("dispatch level = %d\n", KeGetCurrentIrql()));\r
+    ASSERT(FALSE);\r
+}\r
+\r
+void \r
+cm_rtu_callback(\r
+    IN          ib_cm_rtu_rec_t *p_cm_rtu_rec )\r
+{\r
+    SDP_PRINT(SDP_TRACE, SDP_SOCKET, ("dispatch level = %d\n", KeGetCurrentIrql()));\r
+    // Note - Referance count is not increased here since this is a call\r
+    // back, and we are gurantied that shuting down ibal will only end\r
+    // after all callbacks are finished.\r
+    SdpSocket *pSocket = (SdpSocket *) p_cm_rtu_rec->qp_context;\r
+    SdpSocket *pListeningSocket = pSocket->m_pListeningSocket;\r
+    pListeningSocket->CmRtuCallback(p_cm_rtu_rec);\r
+    \r
+}\r
+/*\r
+ * A user-specified callback that is invoked after an error has occurred on\r
+ * a listen request.\r
+ */\r
+static void AL_API\r
+listen_err_callback(\r
+    IN              ib_listen_err_rec_t         *p_listen_err_rec )\r
+{\r
+    /* TODO ??????????????*/\r
+    UNUSED_PARAM( p_listen_err_rec );\r
+    ASSERT( 0 );\r
+}\r
+\r
+static void AL_API\r
+cm_req_callback(\r
+    IN              ib_cm_req_rec_t         *p_cm_req_rec )\r
+{\r
+    // Pass the request to the approperiate socket\r
+    SdpSocket *pSocket = (SdpSocket *) p_cm_req_rec->context;\r
+    pSocket->CmReqCallback(p_cm_req_rec);\r
+}\r
+\r
 SdpSocket::SdpSocket()\r
 {\r
     m_CreationFlags = 0;\r
     m_SrcPort = 0;\r
     m_SrcIp = 0;\r
+    m_DstPort = 0;\r
+    m_DstIp = 0;\r
+    \r
+    m_SrcPortGuid = 0;\r
+    m_SrcCaGuid = 0;\r
+    m_ListenHandle = NULL;\r
 \r
     mh_Ca = NULL;\r
     m_pd = NULL;\r
@@ -66,6 +114,7 @@ SdpSocket::SdpSocket()
     m_mr = NULL;\r
 \r
     m_state = SS_IDLE;\r
+    m_pListeningSocket = NULL;\r
 }\r
 \r
 VOID SdpSocket::AssertLocked()\r
@@ -89,6 +138,8 @@ NTSTATUS SdpSocket::Init(
     pSocketOutParam->pSocket = this; // give the user a handle to the socket\r
     KeInitializeEvent(&m_ShutdownCompleteEvent, NotificationEvent , FALSE );\r
 \r
+    m_ConnectionList.Init(this);\r
+\r
     return rc;\r
 }\r
 \r
@@ -124,6 +175,9 @@ NTSTATUS SdpSocket::WSPSend(
         Locked = true;\r
         ASSERT(pBuffersEvent == NULL);\r
 \r
+        //??? Verify connected state (or whatever)?????????????\r
+\r
+\r
         rc = m_SendBufferPool.GetBuffer(&pBufferDescriptor, &pBuffersEvent, First);\r
         if (!NT_SUCCESS(rc)) {\r
             SDP_PRINT(SDP_ERR, SDP_SOCKET, ("m_SendBufferPool.GetBuffer failed rc = 0x%x\n", rc ));\r
@@ -217,13 +271,14 @@ SdpSocket::WSPRecv(
         WspRecvOut   *pWspRecvOut\r
         )\r
 {\r
-    SDP_PRINT(SDP_TRACE, SDP_SOCKET, ("this = 0x%p \n",this));\r
+    SDP_PRINT(SDP_TRACE, SDP_SOCKET, ("this = 0x%p BufferSize = %d\n",this, pWspRecvIn->BufferSize));\r
 \r
     NTSTATUS rc = STATUS_SUCCESS;\r
     bool First = true;\r
     uint32_t Coppied = 0, ThisCopy = 0;\r
     bool Locked = false;\r
     PRKEVENT  pBuffersEvent = NULL;\r
+    bool NoMoreData;\r
 \r
     if (pWspRecvIn->BufferSize == 0) {\r
         SDP_PRINT(SDP_WARN, SDP_SOCKET, ("this = 0x%p - zero size recv \n",this));\r
@@ -239,12 +294,15 @@ SdpSocket::WSPRecv(
         Locked = true;\r
         ASSERT(pBuffersEvent == NULL);\r
 \r
+        //??? Verify connected state (or whatever)?????????????\r
+\r
         rc = m_RecvBufferPool.GetData(\r
             pWspRecvIn->pData + Coppied, \r
             pWspRecvIn->BufferSize - Coppied, \r
             &ThisCopy, \r
             &pBuffersEvent, \r
-            First\r
+            First,\r
+            &NoMoreData\r
             );\r
         if (!NT_SUCCESS(rc)) {\r
             SDP_PRINT(SDP_ERR, SDP_SOCKET, ("m_RecvBufferPool.GetData failed rc = 0x%x\n", rc ));\r
@@ -252,8 +310,15 @@ SdpSocket::WSPRecv(
             Locked = false;\r
             goto Cleanup;\r
         }\r
-        First = false;\r
         Coppied += ThisCopy;\r
+\r
+        if (NoMoreData && (Coppied > 0)) {\r
+            // this means that there is nothing to copy, and we should return\r
+            ASSERT(pBuffersEvent == NULL);\r
+            break;\r
+        }\r
+        \r
+        First = false;\r
         \r
         if (pBuffersEvent != NULL) {\r
             // We are told to wait on this event\r
@@ -298,15 +363,17 @@ SdpSocket::WSPRecv(
 Cleanup:\r
     if (NT_SUCCESS(rc) ) {\r
         pWspRecvOut->Errno = 0;\r
-        ASSERT(pWspRecvIn->BufferSize == Coppied);\r
+        ASSERT(pWspRecvIn->BufferSize >= Coppied);\r
         pWspRecvOut->NumberOfBytesRecieved = Coppied;\r
     } else {\r
         // Make sure that we have the error setted\r
         ASSERT(pWspRecvOut->Errno != 0); // BUGBUG: Need to make sure that this\r
+        pWspRecvOut->NumberOfBytesRecieved = 0;\r
         // is indeed the case.\r
     }\r
     // Currently in any case, the flags are not being used:\r
-    pWspRecvOut->dwFlags = 0;    \r
+    pWspRecvOut->dwFlags = 0;\r
+    SDP_PRINT(SDP_TRACE, SDP_SOCKET, ("this = 0x%p returning %d bytes \n",this, pWspRecvOut->NumberOfBytesRecieved));\r
     return rc;\r
 \r
 }\r
@@ -318,7 +385,6 @@ NTSTATUS SdpSocket::WSPConnect(
 {\r
     NTSTATUS rc = STATUS_SUCCESS;\r
     ib_api_status_t ib_status;\r
-    ib_net64_t SrcPortGuid;\r
     ib_net64_t DestPortGuid;\r
     ib_path_rec_t path_rec;\r
         \r
@@ -338,7 +404,7 @@ NTSTATUS SdpSocket::WSPConnect(
     }\r
 \r
     // check socket state\r
-    // BUGBUG: Do a better work here\r
+    // BUGBUG: Do a better work here (it might be localy bounded ?????)\r
     m_Lock.Lock();//??? retval\r
     if (m_state != SS_IDLE) {\r
         // We can not connect in this state \r
@@ -369,13 +435,18 @@ NTSTATUS SdpSocket::WSPConnect(
     if (m_SrcPort == 0) {\r
        rc = g_pSdpDriver->m_pSdpArp->GetPort(m_SrcIp, &m_SrcPort);\r
        if (!NT_SUCCESS(rc)) {\r
-            SDP_PRINT(SDP_ERR, SDP_SOCKET, ("m_pSdpArp->SourcePortGidFromIP failed rc = 0x%x\n", rc ));\r
+            SDP_PRINT(SDP_ERR, SDP_SOCKET, ("m_pSdpArp->GetPort failed rc = 0x%x\n", rc ));\r
             pWspConnectOut->Errno = WSAENETUNREACH; // BUGBUG: verify this error\r
             m_Lock.Unlock(); // Error ignored as this is already an error pass\r
             goto Cleanup;\r
         }    \r
+    } else {\r
+        // We need to connect to the global table of ports\r
+\r
     }\r
-    rc = g_pSdpDriver->m_pSdpArp->SourcePortGidFromIP(m_SrcIp, &SrcPortGuid, &m_CaGuid);\r
+\r
+    \r
+    rc = g_pSdpDriver->m_pSdpArp->SourcePortGidFromIP(m_SrcIp, &m_SrcPortGuid, &m_SrcCaGuid);\r
     if (!NT_SUCCESS(rc)) {\r
         SDP_PRINT(SDP_ERR, SDP_SOCKET, ("m_pSdpArp->SourcePortGidFromIP failed rc = 0x%x\n", rc ));\r
         pWspConnectOut->Errno = WSAENETUNREACH; // BUGBUG: verify this error\r
@@ -399,7 +470,7 @@ NTSTATUS SdpSocket::WSPConnect(
     m_state = SS_CONNECTING_QPR_SENT;\r
     m_Lock.Unlock(); //?????\r
 \r
-    rc = g_pSdpDriver->m_pSdpArp->QueryPathRecord( SrcPortGuid, DestPortGuid, &path_rec );\r
+    rc = g_pSdpDriver->m_pSdpArp->QueryPathRecord( m_SrcPortGuid, DestPortGuid, &path_rec );\r
     if (!NT_SUCCESS(rc)) {\r
         SDP_PRINT(SDP_ERR, SDP_SOCKET, ("m_pSdpArp->QueryPathRecord failed rc = 0x%x\n", rc ));\r
         pWspConnectOut->Errno = WSAENETUNREACH; // BUGBUG: verify this error\r
@@ -501,6 +572,315 @@ Cleanup:
 \r
 }\r
 \r
+NTSTATUS \r
+SdpSocket::WSPBind(\r
+    WspBindIn    *pWspBindIn,\r
+    WspBindOut   *pWspBindOut\r
+    )\r
+{\r
+    NTSTATUS rc = STATUS_SUCCESS;\r
+\r
+    SDP_PRINT(SDP_TRACE, SDP_SOCKET, ("this = 0x%p bind address ip=%d.%d.%d.%d:%d\n",\r
+        this,\r
+        (pWspBindIn->IP & 0XFF000000) >> 24,\r
+        (pWspBindIn->IP & 0XFF0000) >> 16,\r
+        (pWspBindIn->IP & 0XFF00) >> 8,\r
+        (pWspBindIn->IP & 0XFF),\r
+        pWspBindIn->Port\r
+        ));\r
+\r
+    if (!m_Lock.Lock()) {\r
+        SDP_PRINT(SDP_ERR, SDP_SOCKET, ("Failed to lock this = 0x%p \n",this));\r
+        rc = STATUS_SHUTDOWN_IN_PROGRESS;\r
+        goto Cleanup;\r
+    }\r
+\r
+    /* Verify the state of the socket */\r
+    if( m_state != SS_IDLE) {\r
+        SDP_PRINT(SDP_ERR, SDP_SOCKET, ("socket is in invalid state %s this = 0x%p \n",\r
+            this, \r
+            SS2String(m_state)));\r
+        m_Lock.Unlock(); // Error ignored as this is already an error pass\r
+        rc = STATUS_INVALID_DEVICE_STATE;\r
+        pWspBindOut->Errno = WSAEINVAL;\r
+        goto Cleanup;\r
+    }\r
+\r
+    \r
+    /* Check if the ip address is assigned to one of our IBoIB HCA. */\r
+    if( pWspBindIn->IP != INADDR_ANY )\r
+    {\r
+        ASSERT(m_SrcCaGuid == NULL);\r
+        rc = g_pSdpDriver->m_pSdpArp->SourcePortGidFromIP(pWspBindIn->IP, &m_SrcPortGuid, &m_SrcCaGuid);\r
+        if (!NT_SUCCESS(rc)) {\r
+            SDP_PRINT(SDP_ERR, SDP_SOCKET, ("m_pSdpArp->SourcePortGidFromIP failed rc = 0x%x\n", rc ));\r
+            pWspBindOut->Errno = WSAENETUNREACH; // BUGBUG: verify this error\r
+            m_Lock.Unlock(); // Error ignored as this is already an error pass\r
+            goto Cleanup;\r
+        }        \r
+    }\r
+    else\r
+    {\r
+        m_SrcPortGuid = 0;\r
+    }\r
+\r
+    if( pWspBindIn->IP != INADDR_ANY ) {\r
+        /* Time to allocate our IB QP */\r
+        rc = CreateQp();\r
+        if (!NT_SUCCESS(rc)) {\r
+            SDP_PRINT(SDP_ERR, SDP_SOCKET, ("CreateQp failed rc = 0x%x\n", rc ));\r
+            pWspBindOut->Errno = WSAENOBUFS;\r
+            m_Lock.Unlock(); // Error ignored as this is already an error pass\r
+            goto Cleanup;\r
+        }    \r
+    }\r
+\r
+    // If the src port is 0, we need to allocate a port for the caller.\r
+    if (pWspBindIn->Port == 0) {\r
+        m_SrcPort = 0;\r
+        rc = g_pSdpDriver->m_pSdpArp->GetPort(pWspBindIn->IP, &m_SrcPort);\r
+        if (!NT_SUCCESS(rc)) {\r
+            SDP_PRINT(SDP_ERR, SDP_SOCKET, ("m_pSdpArp->GetPort failed rc = 0x%x\n", rc ));\r
+            pWspBindOut->Errno = WSAENETUNREACH; // BUGBUG: verify this error\r
+            m_Lock.Unlock(); // Error ignored as this is already an error pass\r
+            goto Cleanup;\r
+        }    \r
+    } else {\r
+        // We have to allocate the needed port in the table???????\r
+\r
+    }\r
+\r
+    // Everything went OK\r
+    m_SrcPort = pWspBindIn->Port;\r
+    m_SrcIp = pWspBindIn->IP;\r
+\r
+    m_state = SS_BOUND;\r
+    rc = m_Lock.Unlock();\r
+    if (!NT_SUCCESS(rc)) {\r
+        SDP_PRINT(SDP_ERR, SDP_SOCKET, ("m_Lock.Unlock() failed rc = 0x%x\n", rc ));\r
+        goto Cleanup;\r
+    }\r
+\r
+Cleanup:    \r
+    if (NT_SUCCESS(rc) ) {\r
+        pWspBindOut->Errno = 0;\r
+    } else {\r
+        // Make sure that we have the error setted\r
+        ASSERT(pWspBindOut->Errno != 0); // BUGBUG: Need to make sure that this\r
+        // is indeed the case.\r
+        //??????????? Make sure that we clean this function on exit\r
+    }\r
+    return rc;\r
+\r
+}\r
+\r
+NTSTATUS SdpSocket::WSPListen(\r
+    WspListenIn    *pWspListenIn,\r
+    WspListenOut   *pWspListenOut\r
+    )\r
+{\r
+    NTSTATUS rc = STATUS_SUCCESS;\r
+    ib_cm_listen_t param;\r
+    ib_api_status_t ib_status;\r
+\r
+    SDP_PRINT(SDP_TRACE, SDP_SOCKET, ("this = 0x%p \n",this));\r
+    if (!m_Lock.Lock()) {\r
+        SDP_PRINT(SDP_ERR, SDP_SOCKET, ("Failed to lock this = 0x%p \n",this));\r
+        rc = STATUS_SHUTDOWN_IN_PROGRESS;\r
+        goto Cleanup;\r
+    }\r
+\r
+    /* Verify the state of the socket */\r
+    if( m_state != SS_BOUND) {\r
+        SDP_PRINT(SDP_ERR, SDP_SOCKET, ("socket is in invalid state %s this = 0x%p \n",\r
+            this, \r
+            SS2String(m_state)));\r
+        m_Lock.Unlock(); // Error ignored as this is already an error pass\r
+        rc = STATUS_INVALID_DEVICE_STATE;\r
+        pWspListenOut->Errno = WSAEINVAL;\r
+        goto Cleanup;\r
+    }\r
+\r
+    m_ConnectionList.SetBackLog(pWspListenIn->backlog);\r
+\r
+    // Create the CM request\r
+    memset( &param, 0, sizeof(param) );\r
+\r
+    ASSERT(m_SrcPort != 0);\r
+    param.svc_id = get_service_id_for_port( m_SrcPort);\r
+    if( m_SrcPortGuid )\r
+    {\r
+        /* The socket is bound to an IP address */\r
+        param.ca_guid = m_SrcCaGuid;\r
+        param.port_guid = m_SrcPortGuid;\r
+    }\r
+    else\r
+    {\r
+        /* The socket is bound to INADDR_ANY */\r
+        param.ca_guid = IB_ALL_CAS;\r
+        param.port_guid = IB_ALL_PORTS;\r
+    }\r
+\r
+    param.lid = IB_ALL_LIDS;\r
+\r
+    /* Currently no compare function ?????\r
+    param.p_compare_buffer = (uint8_t *) & socket_info->info.listen.listen_req_param;\r
+    param.compare_length = sizeof(struct listen_req_param);\r
+    param.compare_offset = offsetof(struct cm_req_params, listen_req_param);\r
+    */ \r
+\r
+    param.pfn_cm_req_cb = cm_req_callback;\r
+\r
+    param.qp_type = IB_QPT_RELIABLE_CONN;\r
+\r
+    ASSERT(m_ListenHandle == NULL);\r
+\r
+    ib_status = ib_cm_listen(\r
+        g_pSdpDriver->m_al_handle , \r
+        &param, \r
+        listen_err_callback, \r
+        this,\r
+        &m_ListenHandle \r
+        );\r
+\r
+    if( ib_status != IB_SUCCESS ) {\r
+        SDP_PRINT(SDP_ERR, SDP_SOCKET, ("ib_cm_listen failed ib_status = 0x%d\n", ib_status ));\r
+        rc = IB2Status(ib_status);\r
+        pWspListenOut->Errno = IbalToWsaError( ib_status );\r
+        goto Cleanup;\r
+    }\r
+        \r
+    // SUCCESS - change the state     \r
+    m_state = SS_LISTENING;\r
+    rc = m_Lock.Unlock();\r
+    if (!NT_SUCCESS(rc)) {\r
+        SDP_PRINT(SDP_ERR, SDP_SOCKET, ("m_Lock.Unlock() failed rc = 0x%x\n", rc ));\r
+        goto Cleanup;\r
+    }\r
+\r
+Cleanup:    \r
+    if (NT_SUCCESS(rc) ) {\r
+        pWspListenOut->Errno = 0;\r
+    } else {\r
+        // Make sure that we have the error setted\r
+        ASSERT(pWspListenOut->Errno != 0); // BUGBUG: Need to make sure that this\r
+        // is indeed the case.\r
+    }\r
+    return rc;\r
+}\r
+\r
+NTSTATUS \r
+SdpSocket::WSPAccept(\r
+    WspAcceptIn    *pWspAcceptIn,\r
+    WspAcceptOut   *pWspAcceptOut\r
+    )\r
+{\r
+    NTSTATUS rc = STATUS_SUCCESS;\r
+    bool Locked = false;\r
+    SdpSocket *pNewSocket = NULL;\r
+    PRKEVENT  pAcceptEvent = NULL;\r
+\r
+    SDP_PRINT(SDP_TRACE, SDP_SOCKET, ("this = 0x%p \n",this));\r
+\r
+    while (true) {\r
+        if ((Locked == false) && !m_Lock.Lock()) {\r
+            SDP_PRINT(SDP_ERR, SDP_SOCKET, ("Failed to lock this = 0x%p \n",this));\r
+            rc = STATUS_SHUTDOWN_IN_PROGRESS;\r
+            goto Cleanup;\r
+        }\r
+        Locked = true;\r
+        ASSERT(pNewSocket == NULL);\r
+\r
+        /* Verify the state of the socket */\r
+        if( m_state != SS_LISTENING) {\r
+            SDP_PRINT(SDP_ERR, SDP_SOCKET, ("socket is in invalid state %s this = 0x%p \n",\r
+                this, \r
+                SS2String(m_state)));\r
+            m_Lock.Unlock(); // Error ignored as this is already an error pass\r
+            Locked = false;\r
+            rc = STATUS_INVALID_DEVICE_STATE;\r
+            pWspAcceptOut->Errno = WSAEINVAL;\r
+            goto Cleanup;\r
+        }\r
+\r
+        rc = m_ConnectionList.AcceptAReadyConnection(&pNewSocket, &pAcceptEvent);\r
+        if (!NT_SUCCESS(rc)) {\r
+            SDP_PRINT(SDP_ERR, SDP_SOCKET, ("m_ConnectionList.AcceptAReadyConnection failed rc = 0x%x\n", rc ));\r
+            m_Lock.Unlock(); // Error ignored as this is already an error pass\r
+            Locked = false;\r
+            goto Cleanup;\r
+        }\r
+\r
+        if (pNewSocket != NULL) {\r
+            ASSERT(pAcceptEvent == NULL);\r
+            break;\r
+        }\r
+\r
+        ASSERT(pAcceptEvent != NULL);\r
+        \r
+        // We are told to wait on this event\r
+        rc = m_Lock.Unlock();\r
+        Locked = false;\r
+        if (!NT_SUCCESS(rc)) {\r
+            SDP_PRINT(SDP_ERR, SDP_SOCKET, ("m_Lock.Unlock() failed rc = 0x%x\n", rc ));\r
+            goto Cleanup;\r
+        }\r
+\r
+        rc = MyKeWaitForSingleObject(\r
+            pAcceptEvent,\r
+            UserRequest,\r
+            UserMode,\r
+            FALSE,\r
+            NULL\r
+            );    \r
+        pAcceptEvent = NULL;\r
+        if (( rc == STATUS_ALERTED ) ||( rc == STATUS_USER_APC )) {\r
+            // BUGBUG: Think what to do here, we should be able to stop the\r
+            // connect, and quit (probably shutdown should be enough)\r
+            SDP_PRINT(SDP_WARN, SDP_SOCKET, ("MyKeWaitForSingleObject was alerted = 0x%x\n", rc ));\r
+            rc = STATUS_UNEXPECTED_IO_ERROR;\r
+            //pWspConnectOut->Errno = WSAENETUNREACH; // BUGBUG: verify this error\r
+            Shutdown();\r
+            goto Cleanup;\r
+        }\r
+        // try getting the socket again\r
+    }    \r
+\r
+    // I want to copy this data before releasing the lock\r
+    ULONG IP = m_DstIp;\r
+    USHORT Port = m_DstPort;    \r
+    \r
+    ASSERT(Locked == true);\r
+    rc = m_Lock.Unlock();\r
+    Locked = false;\r
+    if (!NT_SUCCESS(rc)) {\r
+        SDP_PRINT(SDP_ERR, SDP_SOCKET, ("m_Lock.Unlock() failed rc = 0x%x\n", rc ));\r
+        goto Cleanup;\r
+    }\r
+   \r
+Cleanup:    \r
+    ASSERT(Locked == false);\r
+    if (NT_SUCCESS(rc) ) {\r
+        pWspAcceptOut->pAccaptedSocket = pNewSocket;\r
+        pWspAcceptOut->IP = IP;\r
+        pWspAcceptOut->Port = Port;\r
+        pWspAcceptOut->Errno = 0;\r
+        // We need to "register" this socket in the global list\r
+        \r
+    } else {\r
+        // Make sure that we have the error setted\r
+        ASSERT(pWspAcceptOut->Errno != 0); // BUGBUG: Need to make sure that this\r
+        ASSERT(pNewSocket == NULL);\r
+        pWspAcceptOut->pAccaptedSocket = NULL;\r
+        // is indeed the case.\r
+    }\r
+    // referance on pNewSocket is not currently released, since we are\r
+    // returning them to the next level\r
+    return rc;\r
+\r
+\r
+}\r
+\r
 \r
 NTSTATUS SdpSocket::CmSendRTU()\r
 {\r
@@ -614,14 +994,14 @@ NTSTATUS SdpSocket::CmSendRTU()
 \r
     rc = m_Lock.Lock();\r
     if (!NT_SUCCESS(rc)) {\r
-        SDP_PRINT(SDP_ERR, SDP_SOCKET, ("m_RecvBufferPool.Init failed rc = 0x%x\n", rc ));\r
+        SDP_PRINT(SDP_ERR, SDP_SOCKET, ("m_Lock.Lock failed rc = 0x%x\n", rc ));\r
         goto Cleanup;\r
     }\r
     \r
     rc = m_RecvBufferPool.ReceiveIfCan(); //??? error\r
     m_Lock.Unlock(); // error ????\r
     if (!NT_SUCCESS(rc)) {\r
-        SDP_PRINT(SDP_ERR, SDP_SOCKET, ("m_RecvBufferPool.Init failed rc = 0x%x\n", rc ));\r
+        SDP_PRINT(SDP_ERR, SDP_SOCKET, ("m_RecvBufferPool.ReceiveIfCan failed rc = 0x%x\n", rc ));\r
         goto Cleanup;\r
     }\r
 \r
@@ -632,10 +1012,13 @@ Cleanup:
 \r
 VOID SdpSocket::CmRepCallback(IN   ib_cm_rep_rec_t *p_cm_rep_rec)\r
 {\r
+    SDP_PRINT(SDP_TRACE, SDP_SOCKET, ("this = 0x%x\n", this));\r
+    ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL);\r
+\r
     if (m_state != SS_CONNECTING_REQ_SENT) {\r
         // This is not the state that we waited for, not much that we can\r
         // do. (This might happen in shutdown)\r
-        SDP_PRINT(SDP_ERR, SDP_SOCKET, ("SdpSocket::CmRepCallback Not the expacted state %s\n", SS2String(m_state)));\r
+        SDP_PRINT(SDP_ERR, SDP_SOCKET, ("Not the expacted state %s\n", SS2String(m_state)));\r
         ASSERT(FALSE);\r
         return;\r
     }\r
@@ -648,6 +1031,364 @@ VOID SdpSocket::CmRepCallback(IN   ib_cm_rep_rec_t *p_cm_rep_rec)
     KeSetEvent(&m_ConnectCmCompleteEvent, IO_NO_INCREMENT, FALSE);\r
 }\r
 \r
+VOID \r
+SdpSocket::CmReqCallback(IN   ib_cm_req_rec_t *p_cm_req_rec)\r
+{\r
+    SDP_PRINT(SDP_TRACE, SDP_SOCKET, ("this = 0x%x\n", this));\r
+    NTSTATUS rc = STATUS_SUCCESS;\r
+    ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL);\r
+    net64_t SrcCaGuid;\r
+    ib_net64_t SrcPortGuid;\r
+    ib_api_status_t ib_status;\r
+    SdpSocket *pNewSocket = NULL;\r
+\r
+    sdp_msg_hello *msg_hello = (sdp_msg_hello *)p_cm_req_rec->p_req_pdata;\r
+\r
+    rc = sdp_cm_hello_check(msg_hello);\r
+    if (!NT_SUCCESS(rc)) {\r
+        SDP_PRINT(SDP_ERR, SDP_SOCKET, ("sdp_cm_hello_ack_check failed rc = 0x%x\n", rc ));\r
+        goto Cleanup;\r
+    }\r
+\r
+    // Take the lock and verify the state\r
+    rc = m_Lock.Lock();\r
+    if (!NT_SUCCESS(rc)) {\r
+        SDP_PRINT(SDP_ERR, SDP_SOCKET, ("m_Lock.Lock failed rc = 0x%x\n", rc ));\r
+        goto Cleanup;\r
+    }\r
+\r
+    if (m_state != SS_LISTENING) {\r
+        // This is not the state that we waited for, we drop the request\r
+        SDP_PRINT(SDP_ERR, SDP_SOCKET, ("Not the expacted state %s\n", SS2String(m_state)));\r
+        ASSERT(FALSE);\r
+        goto ErrorLocked;\r
+    }\r
+\r
+    // Check that we haven't passed the backlog for this connection\r
+    if (m_ConnectionList.IsFull()) {\r
+        SDP_PRINT(SDP_WARN, SDP_SOCKET, ("Dropping the connection, because of a backlog that is too small\n"));\r
+        goto ErrorLocked;        \r
+    }\r
+\r
+    // Create a new socket for this request\r
+    pNewSocket = new SdpSocket;\r
+    if (pNewSocket == NULL) {\r
+        SDP_PRINT(SDP_ERR, SDP_SOCKET, ("pNewSocket failed\n"));        \r
+        goto ErrorLocked;\r
+    }\r
+\r
+    // Code here is a little dirty to allow us to use the existing infrastructure\r
+    WspSocketIn SocketInParam;\r
+    WspSocketOut SocketOutParam;\r
+    SocketInParam.dwFlags = 0;        \r
+    rc = pNewSocket->Init(&SocketInParam, &SocketOutParam);\r
+    if (!NT_SUCCESS(rc)) {\r
+        SDP_PRINT(SDP_ERR, SDP_SOCKET, ("pNewSocket.Init() failed rc = 0x%x\n", rc ));\r
+        goto ErrorLocked;\r
+    }\r
+    ASSERT(SocketOutParam.Errno == 0);\r
+    ASSERT(SocketOutParam.pSocket == pNewSocket);\r
+\r
+    // Connect the new socket to it's creator\r
+    ASSERT(pNewSocket->m_pListeningSocket == NULL);\r
+    pNewSocket->m_pListeningSocket = this;\r
+    pNewSocket->m_pListeningSocket->AddRef();    \r
+\r
+    /*\r
+     * save hello parameters.\r
+     */\r
+    pNewSocket->m_state = SS_REQ_RECV; //?????? do we really need this state?????\r
+\r
+    pNewSocket->m_SrcIp = msg_hello->hh.dst.ipv4.addr;\r
+    ASSERT(m_SrcPort != 0);\r
+    pNewSocket->m_SrcPort  = m_SrcPort;\r
+    pNewSocket->m_DstIp = msg_hello->hh.src.ipv4.addr;\r
+    pNewSocket->m_DstPort  = msg_hello->hh.port;\r
+\r
+    // Initiate parameters based on what we recieve from the remote side\r
+//    pNewSocket->send_size = msg_hello->hh.l_rcv_size; ??? MAX_Message_size when calling init on the buffers ???\r
+//???    pNewSocket->r_max_adv = msg_hello->hh.max_adv; ???????????\r
+//????    pNewSocket->r_recv_bf = msg_hello->bsdh.recv_bufs; <= m_pSdpSocket->m_SendBufferPool.SetRemoteRecvBuf(rRecvBuf);\r
+//???    pNewSocket->recv_seq  = msg_hello->bsdh.seq_num;\r
+//???    pNewSocket->advt_seq  = msg_hello->bsdh.seq_num;\r
+\r
+    /*\r
+     * The maximum amount of data that can be sent to the remote\r
+     * peer is the smaller of the local and remote buffer sizes,\r
+     * minus the size of the message header.\r
+     */\r
+//    conn->send_size = min((u16)sdp_buff_pool_buff_size(),\r
+//            (u16)conn->send_size) - SDP_MSG_HDR_SIZE; ??????????\r
+\r
+    // We will now allocate our QP.\r
+\r
+    rc = g_pSdpDriver->m_pSdpArp->SourcePortGidFromIP(pNewSocket->m_SrcIp, &SrcPortGuid, &SrcCaGuid);\r
+    if (!NT_SUCCESS(rc)) {\r
+        SDP_PRINT(SDP_ERR, SDP_SOCKET, ("m_pSdpArp->SourcePortGidFromIP failed rc = 0x%x\n", rc ));\r
+        goto ErrorLocked;\r
+    }        \r
+\r
+    if (pNewSocket->m_SrcCaGuid == 0) {\r
+        pNewSocket->m_SrcCaGuid = SrcCaGuid;\r
+    } else {\r
+        ASSERT(pNewSocket->m_SrcCaGuid == CL_NTOH64(p_cm_req_rec->primary_path.sgid.unicast.interface_id));\r
+    }\r
+    \r
+    // MAke sure that the port that was recieved muches the one that we\r
+    // get based on the source IP.\r
+    if (SrcPortGuid != p_cm_req_rec->primary_path.sgid.unicast.interface_id) {\r
+        SDP_PRINT(SDP_ERR, SDP_SOCKET, ("Recieved guid is not what we have expected\n" ));        \r
+        ASSERT(0);\r
+        goto ErrorLocked;\r
+    }\r
+\r
+    rc = pNewSocket->CreateQp();\r
+    if (!NT_SUCCESS(rc)) {\r
+        SDP_PRINT(SDP_ERR, SDP_SOCKET, ("pNewSocket.CreateQp() failed rc = 0x%x\n", rc ));\r
+        goto ErrorLocked;\r
+    }\r
+\r
+    // We will now call init on the sender and the reciever\r
+    int MaxMessageSize = min(msg_hello->hh.l_rcv_size, MAX_SEND_BUFFER_SIZE);\r
+\r
+    rc = pNewSocket->m_SendBufferPool.Init(MAX_SEND_PACKETS, QP_ATTRIB_SQ_DEPTH, MaxMessageSize, pNewSocket->m_pd, pNewSocket->m_qp, pNewSocket->m_lkey, pNewSocket);\r
+    if (!NT_SUCCESS(rc)) {\r
+        SDP_PRINT(SDP_ERR, SDP_SOCKET, ("m_SendBufferPool.Init failed rc = 0x%x\n", rc ));\r
+        goto ErrorLocked;\r
+    }\r
+\r
+    rc = pNewSocket->m_RecvBufferPool.Init(MAX_RECV_PACKETS, QP_ATTRIB_RQ_DEPTH, MaxMessageSize, pNewSocket->m_pd, pNewSocket->m_qp, pNewSocket->m_lkey, pNewSocket);\r
+    if (!NT_SUCCESS(rc)) {\r
+        SDP_PRINT(SDP_ERR, SDP_SOCKET, ("m_RecvBufferPool.Init failed rc = 0x%x\n", rc ));\r
+        goto ErrorLocked;\r
+    }\r
+    pNewSocket->m_SendBufferPool.SetRemoteRecvBuf(msg_hello->bsdh.recv_bufs);\r
+\r
+    // It won't be used, but I want to make sure that there won't be\r
+    // problems later\r
+    pNewSocket->m_ConnectionList.Init(pNewSocket);\r
+\r
+#if 0 // ???????????????????????\r
+       /*\r
+        * Save connect request info for QP modify in cm_accept().\r
+        */\r
+       conn->d_lid = event->param.req_rcvd.primary_path->dlid;\r
+       conn->s_lid = event->param.req_rcvd.primary_path->slid;\r
+       conn->d_qpn = event->param.req_rcvd.remote_qpn;\r
+\r
+        conn->path_mtu = event->param.req_rcvd.primary_path->mtu;\r
+       /*\r
+        * inherit listener properties\r
+        */\r
+       sdp_cm_listen_inherit(listen_conn, conn);\r
+       /*\r
+        * initiate a CM response message.\r
+        */\r
+#endif \r
+\r
+    //\r
+    // Send the ib_cm_rep message to the remote side\r
+    //\r
+    ib_cm_rep_t cm_rep;\r
+\r
+    memset( &cm_rep, 0, sizeof(cm_rep) );\r
+\r
+    cm_rep.qp_type = IB_QPT_RELIABLE_CONN;\r
+    cm_rep.h_qp = pNewSocket->m_qp;\r
+// TODO: Add more cababilities once we start using RDMA\r
+// cm_rep.access_ctrl = IB_AC_RDMA_READ | IB_AC_RDMA_WRITE | IB_AC_LOCAL_WRITE;\r
+    cm_rep.access_ctrl = IB_AC_LOCAL_WRITE;\r
+#if 0\r
+       // Bug in TAVOR\r
+       cm_rep.sq_depth = QP_ATTRIB_SQ_DEPTH;\r
+       cm_rep.rq_depth = QP_ATTRIB_RQ_DEPTH;\r
+#endif\r
+    // We need to prepare the hello mesage for the CM\r
+    sdp_msg_hello_ack hello_ack_msg;\r
+    CreateHelloAckHeader(&hello_ack_msg);\r
+\r
+    cm_rep.p_rep_pdata = (uint8_t *) &hello_ack_msg;\r
+    cm_rep.rep_length = sizeof(hello_ack_msg);\r
+\r
+    cm_rep.init_depth = QP_ATTRIB_INITIATOR_DEPTH;\r
+    cm_rep.target_ack_delay = 10;\r
+    cm_rep.failover_accepted = IB_FAILOVER_ACCEPT_UNSUPPORTED;\r
+    cm_rep.flow_ctrl = p_cm_req_rec->flow_ctrl;\r
+    cm_rep.rnr_nak_timeout = QP_ATTRIB_RNR_NAK_TIMEOUT;\r
+    cm_rep.rnr_retry_cnt = p_cm_req_rec->rnr_retry_cnt;\r
+    cm_rep.pfn_cm_mra_cb = cm_mra_callback;\r
+    cm_rep.pfn_cm_rej_cb = cm_rej_callback;\r
+    cm_rep.pfn_cm_rtu_cb = cm_rtu_callback;\r
+    cm_rep.pfn_cm_lap_cb = cm_lap_callback;\r
+    cm_rep.pfn_cm_dreq_cb = cm_dreq_callback;\r
+\r
+    ib_status = ib_cm_rep( p_cm_req_rec->h_cm_req, &cm_rep );\r
+    if( ib_status != IB_SUCCESS ) {\r
+        SDP_PRINT(SDP_ERR, SDP_SOCKET, ("ib_cm_rep failed ib_status = 0x%d\n", ib_status ));\r
+        rc = IB2Status(ib_status);\r
+        goto Cleanup;\r
+    }\r
+\r
+    // Add this socket to the list of sockets ?????? should this also be done on errors ????\r
+    rc = m_ConnectionList.AddConnectionToReplySent(pNewSocket);\r
+    if (!NT_SUCCESS(rc)) {\r
+        SDP_PRINT(SDP_ERR, SDP_SOCKET, ("pNewSocket.Init() failed rc = 0x%x\n", rc ));\r
+        goto ErrorLocked;\r
+    }\r
+\r
+    rc = pNewSocket->m_Lock.Lock();\r
+    if (!NT_SUCCESS(rc)) {\r
+        SDP_PRINT(SDP_ERR, SDP_SOCKET, ("pNewSocket.Init() failed rc = 0x%x\n", rc ));\r
+        goto ErrorLocked;\r
+    }    \r
+\r
+    rc = pNewSocket->m_RecvBufferPool.ReceiveIfCan();\r
+    if (!NT_SUCCESS(rc)) {\r
+        SDP_PRINT(SDP_ERR, SDP_SOCKET, ("pNewSocket.Init() failed rc = 0x%x\n", rc ));\r
+        pNewSocket->m_Lock.Unlock(); // Error is ignored, since this is already an error path\r
+        goto ErrorLocked;\r
+    }\r
+\r
+    // we now arm the CQs (after that a call back might happen)\r
+    ib_status = ib_rearm_cq(pNewSocket->m_rcq, FALSE);\r
+     if( ib_status != IB_SUCCESS ) {\r
+        SDP_PRINT(SDP_ERR, SDP_SOCKET, ("ib_rearm_cq failed ib_status = 0x%d\n", ib_status ));\r
+        rc = IB2Status(ib_status);\r
+        pNewSocket->m_Lock.Unlock(); // Error is ignored, since this is already an error path\r
+        goto ErrorLocked;\r
+    }\r
+\r
+    ib_status = ib_rearm_cq(pNewSocket->m_scq, FALSE);\r
+    if( ib_status != IB_SUCCESS ) {\r
+        SDP_PRINT(SDP_ERR, SDP_SOCKET, ("ib_rearm_cq failed ib_status = 0x%d\n", ib_status ));\r
+        rc = IB2Status(ib_status);\r
+        pNewSocket->m_Lock.Unlock(); // Error is ignored, since this is already an error path\r
+        goto ErrorLocked;\r
+    }\r
+    \r
+    // Sucess - we can now release the lock and update our state\r
+    pNewSocket->m_state = SS_REP_SENT;\r
+\r
+    rc = pNewSocket->m_Lock.Unlock(); // Error is ignored, since this is already an error path\r
+    if (!NT_SUCCESS(rc)) {\r
+        SDP_PRINT(SDP_ERR, SDP_SOCKET, ("pNewSocket->m_Lock.Unlock() failed rc = 0x%x\n", rc ));\r
+        // BUGBUG: who is responsibale for the cleanup ???????\r
+        goto ErrorLocked;\r
+    }    \r
+    \r
+    rc = m_Lock.Unlock();\r
+    if (!NT_SUCCESS(rc)) {\r
+        SDP_PRINT(SDP_ERR, SDP_SOCKET, ("m_Lock.Unlock() failed rc = 0x%x\n", rc ));\r
+        // BUGBUG: who is responsibale for the cleanup ???????\r
+    }    \r
+\r
+Cleanup:\r
+    if (pNewSocket != NULL) {\r
+        pNewSocket->Release();\r
+    }\r
+    return;\r
+\r
+ErrorLocked:\r
+    // Previous rc doesn't mater as this function is void\r
+    rc = m_Lock.Unlock();\r
+    if (!NT_SUCCESS(rc)) {\r
+        SDP_PRINT(SDP_ERR, SDP_SOCKET, ("m_Lock.Unlock() failed rc = 0x%x\n", rc ));\r
+        // BUGBUG: who is responsibale for the cleanup ???????\r
+    }\r
+    goto Cleanup;       \r
+\r
+}\r
+\r
+VOID \r
+SdpSocket::CmRtuCallback(IN   ib_cm_rtu_rec_t *p_cm_rtu_rec)\r
+{\r
+    SDP_PRINT(SDP_TRACE, SDP_SOCKET, ("this = 0x%x\n", this));\r
+    NTSTATUS rc = STATUS_SUCCESS;\r
+    ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL);\r
+\r
+    SdpSocket *pSocket = (SdpSocket *) p_cm_rtu_rec->qp_context;\r
+    // In order to make our model more consistent we increase the refcount here.\r
+    // (This is not a must since this is a callback and we are gurantied that the last\r
+    // callback won't happen untill we free IBAL)\r
+    pSocket->AddRef();\r
+\r
+\r
+    // Take the lock and verify the state\r
+    rc = m_Lock.Lock();\r
+    if (!NT_SUCCESS(rc)) {\r
+        SDP_PRINT(SDP_ERR, SDP_SOCKET, ("m_Lock.Lock failed rc = 0x%x\n", rc ));\r
+        goto Cleanup;\r
+    }\r
+\r
+    if (m_state != SS_LISTENING) {\r
+        // This is not the state that we waited for, we drop the request\r
+        SDP_PRINT(SDP_ERR, SDP_SOCKET, ("Not the expacted state %s\n", SS2String(m_state)));\r
+        ASSERT(FALSE); // Can this happen on shutdown ?\r
+        goto ErrorLocked;\r
+    }\r
+    \r
+    // First step is to verify that we have the new socket\r
+    rc = m_ConnectionList.VerifyConnictionInReplySent(pSocket);\r
+    if (!NT_SUCCESS(rc)) {\r
+        SDP_PRINT(SDP_ERR, SDP_SOCKET, ("m_ConnectionList.GetConnection failed (got a call back on a not existing connection) rc = 0x%x\n", rc ));\r
+        ASSERT(FALSE);\r
+        goto ErrorLocked;\r
+    }\r
+\r
+    // Next step is to move the new socket to the SS_CONNECTED state\r
+    rc = pSocket->m_Lock.Lock();\r
+    if (!NT_SUCCESS(rc)) {\r
+        SDP_PRINT(SDP_ERR, SDP_SOCKET, ("m_Lock.Lock failed rc = 0x%x\n", rc ));\r
+        goto ErrorLocked;\r
+    }\r
+    if (pSocket->m_state != SS_REP_SENT) {\r
+        ASSERT(pSocket->m_state == SS_REP_SENT);\r
+        // This is not the expected state (probably shutdown).\r
+        // we should signal an error also on the one that is waiting\r
+        pSocket->m_Lock.Unlock(); // Error is ignored since this is already\r
+                                  // an error path\r
+        pSocket->Shutdown();                                  \r
+        rc = STATUS_UNEXPECTED_IO_ERROR;\r
+        goto ErrorLocked;\r
+    }\r
+\r
+    pSocket->m_state = SS_CONNECTED;\r
+\r
+    m_ConnectionList.MoveConnectionFromReplyToReady(pSocket);\r
+    rc = pSocket->m_Lock.Unlock();\r
+    if (!NT_SUCCESS(rc)) {\r
+        SDP_PRINT(SDP_ERR, SDP_SOCKET, ("pSocket->m_Lock.Lock failed rc = 0x%x\n", rc ));\r
+        goto ErrorLocked;\r
+    }\r
+\r
+    // if needed we will free the one that is waiting\r
+    m_ConnectionList.FreeWaitingIfCan();\r
+    rc = m_Lock.Unlock();\r
+    if (!NT_SUCCESS(rc)) {\r
+        SDP_PRINT(SDP_ERR, SDP_SOCKET, ("m_Lock.Lock failed rc = 0x%x\n", rc ));\r
+        goto Cleanup;\r
+    }\r
+    \r
+Cleanup:\r
+\r
+    if (pSocket != NULL) {\r
+        pSocket->Release();\r
+    }\r
+  \r
+    // Who should take care of the errors that were found here (if found)????????\r
+    return;\r
+\r
+ErrorLocked:\r
+    // Previous rc doesn't mater as this function is void\r
+    rc = m_Lock.Unlock();\r
+    if (!NT_SUCCESS(rc)) {\r
+        SDP_PRINT(SDP_ERR, SDP_SOCKET, ("m_Lock.Unlock() failed rc = 0x%x\n", rc ));\r
+        // BUGBUG: who is responsibale for the cleanup ???????\r
+    }\r
+    goto Cleanup;       \r
+\r
+}\r
+\r
 \r
 VOID\r
 SdpSocket::__recv_cb1(\r
@@ -924,11 +1665,12 @@ NTSTATUS SdpSocket::CreateQp()
     net32_t             rkey;\r
 \r
 \r
-    SDP_PRINT(SDP_TRACE, SDP_SOCKET, ("CreateQp called this = 0x%p\n", this));\r
+    SDP_PRINT(SDP_TRACE, SDP_SOCKET, ("this = 0x%p\n", this));\r
+    ASSERT(m_SrcCaGuid != 0);\r
     /* Open the CA. */\r
     ib_status = ib_open_ca(\r
         g_pSdpDriver->m_al_handle, \r
-        m_CaGuid,\r
+        m_SrcCaGuid,\r
         NULL, \r
         this, \r
         &mh_Ca \r
@@ -1059,7 +1801,7 @@ VOID SdpSocket::CreateHelloHeader(
                          \r
                         )\r
 {\r
-    SDP_PRINT(SDP_TRACE, SDP_SOCKET, ("SdpSocket::CreateHelloHeader called this = 0x%p\n", this));\r
+    SDP_PRINT(SDP_TRACE, SDP_SOCKET, ("this = 0x%p\n", this));\r
     ASSERT(DestIp != 0);\r
     ASSERT(m_SrcPort != 0);\r
     ASSERT(m_SrcIp != 0);\r
@@ -1087,9 +1829,36 @@ VOID SdpSocket::CreateHelloHeader(
     sdp_msg_swap_bsdh(&hello_msg->bsdh);\r
     sdp_msg_swap_hh(&hello_msg->hh);\r
 \r
+}\r
+\r
+VOID SdpSocket::CreateHelloAckHeader(\r
+    sdp_msg_hello_ack* hello_ack_msg\r
+    )\r
+{\r
+    SDP_PRINT(SDP_TRACE, SDP_SOCKET, ("called this = 0x%p\n", this));\r
+\r
+    memset(hello_ack_msg, 0, sizeof(struct sdp_msg_hello_ack));\r
+    hello_ack_msg->bsdh.recv_bufs = QP_ATTRIB_RQ_DEPTH; //????conn->l_advt_bf;\r
+    hello_ack_msg->bsdh.flags     = SDP_MSG_FLAG_NON_FLAG;\r
+    hello_ack_msg->bsdh.mid       = SDP_MID_HELLO_ACK;\r
+    hello_ack_msg->bsdh.size      = sizeof(struct sdp_msg_hello_ack);\r
+    hello_ack_msg->bsdh.seq_num   = m_SendBufferPool.GetAndIncreaseSendSeq();//conn->send_seq; ???\r
+    hello_ack_msg->bsdh.seq_ack   = m_RecvBufferPool.GetRecvSeq();//conn->advt_seq; ???\r
+\r
+    hello_ack_msg->hah.max_adv       = QP_ATTRIB_RQ_DEPTH;// ??? conn->l_max_adv;\r
+    hello_ack_msg->hah.version       = SDP_MSG_VERSION;\r
+    hello_ack_msg->hah.l_rcv_size    = 4096;//???conn->recv_size;\r
+\r
+    /*\r
+     * endian swap\r
+     */\r
+    sdp_msg_swap_bsdh(&hello_ack_msg->bsdh);\r
+    sdp_msg_swap_hah(&hello_ack_msg->hah);\r
+\r
 \r
 }\r
 \r
+\r
 VOID SdpSocket::CreateCmRequest(\r
         ib_cm_req_t *cm_req,\r
         sdp_msg_hello *hello_msg,\r
@@ -1176,6 +1945,20 @@ VOID SdpSocket::Shutdown()
     \r
     m_Lock.SignalShutdown();\r
 \r
+    if (m_ListenHandle != NULL) {\r
+        ib_status = ib_cm_cancel( m_ListenHandle, ShutdownCB );\r
+        if( ib_status != IB_SUCCESS ) {\r
+            SDP_PRINT(SDP_ERR, SDP_SOCKET, ("ib_cm_cancel failed ib_status = 0x%d\n", ib_status ));\r
+            rc = IB2Status(ib_status);\r
+        } else {\r
+            WaitForShutdownEvent(&m_ShutdownCompleteEvent);\r
+            m_ListenHandle = NULL;\r
+        }\r
+    }\r
+\r
+    m_ConnectionList.Shutdown();\r
+    \r
+\r
     if (m_qp != NULL) {\r
         ib_status = ib_destroy_qp(m_qp, ShutdownCB);\r
         ASSERT(ib_status == IB_SUCCESS);\r
@@ -1206,6 +1989,11 @@ VOID SdpSocket::Shutdown()
         mh_Ca = NULL;\r
         WaitForShutdownEvent(&m_ShutdownCompleteEvent);\r
     }\r
+\r
+    if (m_pListeningSocket != NULL) {\r
+        m_pListeningSocket->Release();\r
+        m_pListeningSocket = NULL;\r
+    }\r
     \r
 \r
     // Now that all ibal operations have finished we can free the memory\r
@@ -1236,7 +2024,7 @@ NTSTATUS sdp_cm_hello_ack_check(struct sdp_msg_hello_ack *hello_ack)
      * endian swap\r
      */\r
     sdp_msg_swap_bsdh(&hello_ack->bsdh);\r
-    sdp_msg_net_to_cpu_hah(&hello_ack->hah);\r
+    sdp_msg_swap_hah(&hello_ack->hah);\r
     /*\r
      * validation and consistency checks\r
      */\r
@@ -1283,5 +2071,70 @@ NTSTATUS sdp_cm_hello_ack_check(struct sdp_msg_hello_ack *hello_ack)
     return STATUS_SUCCESS;\r
 }\r
 \r
+NTSTATUS sdp_cm_hello_check(struct sdp_msg_hello *msg_hello)\r
+{\r
+    /*\r
+     * endian swap\r
+     */\r
+    sdp_msg_swap_bsdh(&msg_hello->bsdh);\r
+    sdp_msg_swap_hh(&msg_hello->hh);\r
+    /*\r
+     * validation and consistency checks\r
+     */\r
+     \r
+    if (msg_hello->bsdh.size != sizeof(struct sdp_msg_hello)) {\r
+        SDP_PRINT(SDP_WARN, SDP_SOCKET,( "hello msg size mismatch. (2) <%d:%Zu>",\r
+             msg_hello->bsdh.size,\r
+             sizeof(struct sdp_msg_hello)));\r
+        return STATUS_UNEXPECTED_IO_ERROR;\r
+    }\r
+\r
+    if (SDP_MID_HELLO != msg_hello->bsdh.mid) {\r
+        SDP_PRINT(SDP_WARN, SDP_SOCKET,("hello msg unexpected ID. <%d>",\r
+            msg_hello->bsdh.mid));\r
+        return STATUS_UNEXPECTED_IO_ERROR;\r
+    }\r
 \r
+    if (msg_hello->hh.max_adv <= 0) {\r
+        SDP_PRINT(SDP_WARN, SDP_SOCKET,("hello msg, bad zcopy count <%d>",\r
+                msg_hello->hh.max_adv));\r
+        return STATUS_UNEXPECTED_IO_ERROR;\r
+    }\r
+\r
+    if ((0xF0 & msg_hello->hh.version) != (0xF0 & SDP_MSG_VERSION)) {\r
+        SDP_PRINT(SDP_WARN, SDP_SOCKET,("hello msg, version mismatch. <%d:%d>",\r
+            ((0xF0 & msg_hello->hh.version) >> 4),\r
+            ((0xF0 & SDP_MSG_VERSION) >> 4)));\r
+        return STATUS_UNEXPECTED_IO_ERROR;\r
+    }\r
+#ifdef _SDP_MS_APRIL_ERROR_COMPAT\r
+    if ((SDP_MSG_IPVER & 0x0F) != (msg_hello->hh.ip_ver & 0x0F)) \r
+#else\r
+    if ((SDP_MSG_IPVER & 0xF0) != (msg_hello->hh.ip_ver & 0xF0)) {\r
+#endif\r
+        SDP_PRINT(SDP_WARN, SDP_SOCKET,( "hello msg, ip version mismatch. <%d:%d>",\r
+                msg_hello->hh.ip_ver, SDP_MSG_IPVER));\r
+        return STATUS_UNEXPECTED_IO_ERROR;\r
+    }\r
+\r
+    SDP_PRINT(SDP_TRACE, SDP_SOCKET,("Hello BSDH <%04x:%02x:%02x:%08x:%08x:%08x>",\r
+                msg_hello->bsdh.recv_bufs,\r
+                msg_hello->bsdh.flags,\r
+                msg_hello->bsdh.mid,\r
+                msg_hello->bsdh.size,\r
+                msg_hello->bsdh.seq_num,\r
+                msg_hello->bsdh.seq_ack));\r
+    SDP_PRINT(SDP_TRACE, SDP_SOCKET,(\r
+            "Hello HH <%02x:%02x:%02x:%08x:%08x:%04x:%08x:%08x>",\r
+            msg_hello->hh.max_adv,\r
+            msg_hello->hh.ip_ver,\r
+            msg_hello->hh.version,\r
+            msg_hello->hh.r_rcv_size,\r
+            msg_hello->hh.l_rcv_size,\r
+            msg_hello->hh.port,\r
+            msg_hello->hh.src.ipv4.addr,\r
+            msg_hello->hh.dst.ipv4.addr));\r
+\r
+    return STATUS_SUCCESS;\r
+}\r
 \r
index 61c7c24..3e03021 100644 (file)
@@ -18,6 +18,11 @@ const int MAX_RECV_PACKETS              = 200;    // This is the maximum number
 \r
 #define QP_ATTRIB_SQ_DEPTH                             64\r
 #define QP_ATTRIB_SQ_SGE                               1       /* Set based on inline data requirements */\r
+//#define QP_ATTRIB_RESPONDER_RESOURCES        4\r
+#define QP_ATTRIB_INITIATOR_DEPTH              4\r
+//#define QP_ATTRIB_RETRY_COUNT                        6\r
+//#define QP_ATTRIB_RNR_RETRY                          6\r
+#define QP_ATTRIB_RNR_NAK_TIMEOUT              6\r
 \r
 /* \r
  * TODO: During testing, the switch has been observed to post\r
@@ -37,12 +42,20 @@ enum SocketStates {
     SS_CONNECTING_REQ_SENT,\r
     SS_CONNECTING_RTU_SENT,\r
     SS_CONNECTED,\r
+    SS_BOUND,\r
+    SS_LISTENING,\r
+    SS_REQ_RECV,\r
+    SS_REP_SENT,\r
     SS_INSHUTDOWN\r
 };\r
 \r
+void cm_rtu_callback(IN ib_cm_rtu_rec_t *p_cm_rtu_rec );\r
 \r
 \r
 class SdpSocket : public RefCountImpl {\r
+\r
+    friend void cm_rtu_callback(IN ib_cm_rtu_rec_t *p_cm_rtu_rec );\r
+    friend class ConnectionList;\r
 private: \r
    \r
     SocketStates m_state;\r
@@ -54,13 +67,17 @@ private:
     USHORT m_SrcPort;\r
     ULONG  m_SrcIp;\r
 \r
+    USHORT m_DstPort;\r
+    ULONG  m_DstIp;\r
+\r
     bool                    m_shutdown; // Make sure this is synced w\r
     SdpLock                 m_Lock;\r
 \r
 \r
     // A handle to the ca that is being used (in connect) and its guid\r
     ib_ca_handle_t          mh_Ca;\r
-    net64_t                 m_CaGuid;\r
+    net64_t                 m_SrcCaGuid;   // The guid of the CA that is used\r
+    ib_net64_t              m_SrcPortGuid; // The guid of the port that is used\r
     ib_pd_handle_t          m_pd;\r
     ib_cq_handle_t          m_rcq;\r
 \r
@@ -72,6 +89,17 @@ private:
 \r
     net32_t                            m_lkey;\r
 \r
+    // This handle is used if this is a socket that is listening for new connections\r
+    ib_listen_handle_t      m_ListenHandle;\r
+\r
+    // If this socket was created fron a listening socket, this is a\r
+    // pointer to the "mother socket"\r
+    SdpSocket*              m_pListeningSocket;\r
+\r
+    // If this socket is in a listners list of socket, this is the place that is\r
+    // used for puting it in the list\r
+    LIST_ENTRY              m_ListeningSocketList;\r
+\r
 \r
     KEVENT                  m_ConnectCmCompleteEvent;\r
     KEVENT                  m_ShutdownCompleteEvent;\r
@@ -95,6 +123,7 @@ public:
 \r
     BufferPool              m_SendBufferPool;\r
     RecvPool                m_RecvBufferPool;\r
+    ConnectionList          m_ConnectionList;\r
 \r
     \r
     SdpSocket();\r
@@ -119,6 +148,22 @@ public:
         WspRecvOut   *pWspRecvOut\r
         );    \r
 \r
+    NTSTATUS WSPBind(\r
+        WspBindIn    *pWspBindIn,\r
+        WspBindOut   *pWspBindOut\r
+        );    \r
+\r
+    NTSTATUS WSPListen(\r
+        WspListenIn    *pWspListenIn,\r
+        WspListenOut   *pWspListenOut\r
+        );\r
+\r
+    NTSTATUS WSPAccept(\r
+        WspAcceptIn    *pWspAcceptIn,\r
+        WspAcceptOut   *pWspAcceptOut\r
+        );    \r
+    \r
+\r
     VOID Shutdown();\r
 \r
     static VOID ShutdownCB(VOID* pContext);\r
@@ -133,6 +178,10 @@ public:
         ULONG DestIp\r
         );\r
 \r
+    VOID CreateHelloAckHeader(\r
+        sdp_msg_hello_ack* hello_ack_msg\r
+        );\r
+\r
     VOID CreateCmRequest(\r
         ib_cm_req_t *cm_req,\r
         sdp_msg_hello *hello_msg,\r
@@ -141,6 +190,9 @@ public:
     );\r
 \r
     VOID CmRepCallback(IN   ib_cm_rep_rec_t *p_cm_rep_rec);\r
+    VOID CmReqCallback(IN   ib_cm_req_rec_t *p_cm_req_rec);\r
+    VOID CmRtuCallback(IN   ib_cm_rtu_rec_t *p_cm_rtu_rec);\r
+\r
     // Two varibales that are needed for passing REP data\r
     struct sdp_msg_hello_ack m_hello_ack;\r
     ib_cm_handle_t m_cm_handle_t; // BUGBUG: Check how this is used / locked\r
index 45403e0..247b340 100644 (file)
@@ -18,6 +18,7 @@
 #define SDP_BUFFER_POOL     0x000020\r
 #define SDP_LOCK            0x000040\r
 #define SDP_PERFORMANCE     0x000080\r
+#define SDP_CONNECTION_LIST 0x000100\r
 \r
 \r
 // BUGBUG: CONVERT TO A FUNCTION\r