CloseSocket is now implemented (needs some more tuning) (Rev 315)
authortzachid <tzachid@ad392aa1-c5ef-ae45-8dd8-e69d62a5ef86>
Mon, 21 Nov 2005 12:22:16 +0000 (12:22 +0000)
committertzachid <tzachid@ad392aa1-c5ef-ae45-8dd8-e69d62a5ef86>
Mon, 21 Nov 2005 12:22:16 +0000 (12:22 +0000)
git-svn-id: svn://openib.tc.cornell.edu/gen1/trunk@173 ad392aa1-c5ef-ae45-8dd8-e69d62a5ef86

19 files changed:
ulp/sdp/include/SdpShared.h
ulp/sdp/kernel/SdpArp.h
ulp/sdp/kernel/SdpBufferPool.cpp
ulp/sdp/kernel/SdpBufferPool.h
ulp/sdp/kernel/SdpConnectionList.cpp
ulp/sdp/kernel/SdpConnectionList.h
ulp/sdp/kernel/SdpDriver.cpp
ulp/sdp/kernel/SdpGenUtils.cpp
ulp/sdp/kernel/SdpGenUtils.h
ulp/sdp/kernel/SdpLock.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.cpp
ulp/sdp/kernel/SdpTrace.h
ulp/sdp/kernel/SdpUserFile.cpp
ulp/sdp/kernel/SdpUserFile.h
ulp/sdp/todo

index f647de4..6638927 100644 (file)
 \r
 // Define the IOCTL codes that will be used for sending the requests down\r
 \r
-#define IOCTL_WSP_SOCKET    CTL_CODE(FILE_DEVICE_UNKNOWN, 0x801, METHOD_BUFFERED ,FILE_ANY_ACCESS)\r
-#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
+#define IOCTL_WSP_SOCKET        CTL_CODE(FILE_DEVICE_UNKNOWN, 0x801, METHOD_BUFFERED ,FILE_ANY_ACCESS)\r
+#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
+#define IOCTL_WSP_CLOSE_SOCKET  CTL_CODE(FILE_DEVICE_UNKNOWN, 0x808, METHOD_BUFFERED ,FILE_ANY_ACCESS)\r
 \r
 \r
 // Data structures that are used for connect\r
@@ -96,5 +96,14 @@ struct WspAcceptOut {
     USHORT Port;    \r
 };\r
 \r
+struct WspSocketCloseIn {\r
+    VOID *pSocket;    \r
+};\r
+\r
+struct WspSocketCloseOut {\r
+    int Errno;\r
+};\r
+\r
+\r
 \r
 #endif //_SDP_SHARED_H\r
index f869d56..09b92a3 100644 (file)
@@ -46,6 +46,17 @@ public:
                       + 159;\r
             return STATUS_SUCCESS;\r
         }\r
+\r
+        if (DestIp == 11 * 256*256*256 + \r
+                      4 * 256*256 +\r
+                      8 * 256 +\r
+                      + 157) {\r
+            *SrcIp = 11 * 256*256*256 + \r
+                      4 * 256*256 +\r
+                      8 * 256 +\r
+                      + 154;\r
+            return STATUS_SUCCESS;\r
+        }\r
         \r
         ASSERT(FALSE);\r
         *SrcIp = 0;\r
@@ -92,6 +103,26 @@ public:
             *SrcCaGuid = CL_NTOH64(0x2c901093d8430);\r
             return STATUS_SUCCESS;\r
         }\r
+\r
+        if (SourceAddr == 11 * 256*256*256 + \r
+                      4 * 256*256 +\r
+                      8 * 256 +\r
+                      + 154) {\r
+\r
+            *SrcPortGuid = CL_NTOH64(0x2c9000100d151);//????? swlab63\r
+            *SrcCaGuid = CL_NTOH64(0x2c9000100d150);\r
+            return STATUS_SUCCESS;\r
+        }\r
+        \r
+        if (SourceAddr == 11 * 256*256*256 + \r
+                      4 * 256*256 +\r
+                      8 * 256 +\r
+                      + 157) {\r
+\r
+            *SrcPortGuid = CL_NTOH64(0x2c9000100d051);//????? swlab63\r
+            *SrcCaGuid = CL_NTOH64(0x2c9000100d050);\r
+            return STATUS_SUCCESS;\r
+        }\r
         \r
         ASSERT(FALSE);\r
         *SrcPortGuid = 0;\r
@@ -101,6 +132,7 @@ public:
     }\r
 \r
 \r
+    // Get the remote GID based on it's IP addresses\r
     NTSTATUS DestPortGidFromIP(\r
         IN  ULONG  DestAddr, \r
         OUT ib_net64_t *DestPortGuid)\r
@@ -132,6 +164,16 @@ public:
             \r
             return STATUS_SUCCESS;\r
         }\r
+\r
+        if (DestAddr == 11 * 256*256*256 + \r
+                      4 * 256*256 +\r
+                      8 * 256 +\r
+                      + 157) {\r
+            *DestPortGuid =   CL_NTOH64(0x2c9000100d051);//????? swlab57\r
+            \r
+            return STATUS_SUCCESS;\r
+        }\r
+        \r
         \r
         ASSERT(FALSE);\r
         *DestPortGuid = 0;\r
index b2e2ecb..dbf8f3b 100644 (file)
@@ -8,7 +8,7 @@
 NTSTATUS \r
 BufferDescriptor::AllocateBuffer(BufferDescriptor ** ppBufferDescriptor, int BufferSize, int Tag)\r
 {\r
-    SDP_PRINT(SDP_TRACE, SDP_BUFFER_POOL, ("\n"));\r
+    SDP_PRINT(SDP_DEBUG, SDP_BUFFER_POOL, ("\n"));\r
     NTSTATUS rc = STATUS_SUCCESS;\r
     BufferDescriptor *pBufferDescriptor = NULL;\r
 \r
@@ -20,22 +20,21 @@ BufferDescriptor::AllocateBuffer(BufferDescriptor ** ppBufferDescriptor, int Buf
                             sizeof BufferDescriptor, \r
                             Tag\r
                             );\r
+        \r
     if (pBufferDescriptor == NULL) {\r
         SDP_PRINT(SDP_ERR, SDP_BUFFER_POOL, ("ExAllocatePoolWithTag failed \n"));\r
         rc = STATUS_NO_MEMORY;\r
         goto Cleanup;\r
     }\r
 \r
-    // Allocate the buffer itself\r
-    pBufferDescriptor->pBuffer = \r
-        ExAllocatePoolWithTag(\r
-                        NonPagedPool ,\r
-                        BufferSize, \r
-                        Tag\r
-                        );\r
-\r
+    // Allocate the buffer itself (from continious memory)\r
+    PHYSICAL_ADDRESS mem;\r
+    mem.HighPart = 0xffffffff;\r
+    mem.LowPart = 0xffffffff;    \r
+    pBufferDescriptor->pBuffer = MmAllocateContiguousMemory(BufferSize, mem);\r
+        \r
     if (pBufferDescriptor->pBuffer == NULL) {\r
-        SDP_PRINT(SDP_ERR, SDP_BUFFER_POOL, ("ExAllocatePoolWithTag failed \n"));\r
+        SDP_PRINT(SDP_ERR, SDP_BUFFER_POOL, ("ExAllocatePoolWithTag failed BufferSize = %d irql=%d\n",BufferSize, KeGetCurrentIrql()));\r
         rc = STATUS_NO_MEMORY;\r
         goto Cleanup;\r
     }\r
@@ -47,7 +46,7 @@ Cleanup:
     if (!NT_SUCCESS(rc)) {\r
         if (pBufferDescriptor != NULL) {\r
             if (pBufferDescriptor->pBuffer != NULL) {\r
-                ExFreePoolWithTag(pBufferDescriptor->pBuffer, SEND_BUFFERS_ALLOCATION_TAG);\r
+                MmFreeContiguousMemory(pBufferDescriptor->pBuffer);\r
             }\r
             ExFreePoolWithTag(pBufferDescriptor, SEND_BUFFERS_ALLOCATION_TAG);\r
             pBufferDescriptor = NULL;\r
@@ -62,7 +61,7 @@ Cleanup:
 VOID \r
 BufferDescriptor::DeAllocateBuffer(BufferDescriptor *pBufferDescriptor, int Tag)\r
 {\r
-    ExFreePoolWithTag(pBufferDescriptor->pBuffer, Tag);\r
+    MmFreeContiguousMemory(pBufferDescriptor->pBuffer);\r
     ExFreePoolWithTag(pBufferDescriptor, Tag);\r
 \r
 }\r
@@ -130,7 +129,7 @@ BufferPool::GetBuffer(
     bool FirstBuffer\r
     )\r
 {\r
-    SDP_PRINT(SDP_TRACE, SDP_BUFFER_POOL, ("this = 0x%p FirstBuffer = %s\n",this,\r
+    SDP_PRINT(SDP_DEBUG, SDP_BUFFER_POOL, ("this = 0x%p FirstBuffer = %s\n",this,\r
         FirstBuffer ? "TRUE" : "FALSE"));\r
     AssertLocked();\r
 \r
@@ -187,12 +186,13 @@ queue
 NTSTATUS \r
 BufferPool::AddBufferToQueuedList(BufferDescriptor *pBufferDescriptor)\r
 {\r
-    SDP_PRINT(SDP_TRACE, SDP_BUFFER_POOL, ("this = 0x%p pBufferDescriptor = 0x%x\n",this,\r
+    SDP_PRINT(SDP_DEBUG, SDP_BUFFER_POOL, ("this = 0x%p pBufferDescriptor = 0x%x\n",this,\r
         pBufferDescriptor));\r
     AssertLocked();\r
 \r
     NTSTATUS rc = STATUS_SUCCESS;\r
-    ASSERT(pBufferDescriptor->GetFlags() == 0);\r
+    ASSERT(pBufferDescriptor->GetFlags() == 0 || \r
+           pBufferDescriptor->GetFlags() == DISCONNECT_MESSAGE);\r
 \r
     m_QueuedPackets.InsertTailList(&pBufferDescriptor->BuffersList);\r
     rc = SendBuffersIfCan();\r
@@ -227,9 +227,10 @@ BufferPool::AllowOthersToGet()
 NTSTATUS \r
 BufferPool::ReturnBuffer(BufferDescriptor *pBufferDescriptor)\r
 {\r
-    SDP_PRINT(SDP_TRACE, SDP_BUFFER_POOL, ("this = 0x%p buffer=0x%p\n",this, pBufferDescriptor));\r
+    SDP_PRINT(SDP_DEBUG, SDP_BUFFER_POOL, ("this = 0x%p buffer=0x%p\n",this, pBufferDescriptor));\r
     AssertLocked();\r
     bool CreditUpdate = false;\r
+    bool DissconnectMessage = false;\r
     NTSTATUS rc = STATUS_SUCCESS;\r
 \r
 #if DBG    \r
@@ -239,9 +240,11 @@ BufferPool::ReturnBuffer(BufferDescriptor *pBufferDescriptor)
     }\r
 #endif\r
     ASSERT( pBufferDescriptor->GetFlags() == CREDIT_UPDATE ||\r
+            pBufferDescriptor->GetFlags() == DISCONNECT_MESSAGE ||\r
             pBufferDescriptor->GetFlags() == 0);\r
 \r
     CreditUpdate = (pBufferDescriptor->GetFlags() == CREDIT_UPDATE);\r
+    DissconnectMessage = (pBufferDescriptor->GetFlags() == DISCONNECT_MESSAGE);\r
     if (CreditUpdate) {\r
         // This is a credit update packet, need to act accordingly\r
         ASSERT(m_CreditdBufferDescriptor == NULL);\r
@@ -264,6 +267,10 @@ BufferPool::ReturnBuffer(BufferDescriptor *pBufferDescriptor)
             KeSetEvent( &m_WaitingClients, IO_NO_INCREMENT, FALSE );\r
             m_ClientWaiting = false;        \r
         }\r
+        if (DissconnectMessage) {\r
+            SDP_PRINT(SDP_TRACE, SDP_BUFFER_POOL, ("We have recieved a DissconnectMessage complition\n" ));\r
+            m_pSdpSocket->DisconectSentEvent();\r
+        }\r
     }\r
 Cleanup:    \r
     m_CurrentlySentBuffers--;\r
@@ -281,7 +288,7 @@ Cleanup:
 NTSTATUS\r
 BufferPool::SendBuffersIfCan()\r
 {\r
-    SDP_PRINT(SDP_TRACE, SDP_BUFFER_POOL, ("this = 0x%p \n",this));\r
+    SDP_PRINT(SDP_DEBUG, SDP_BUFFER_POOL, ("this = 0x%p \n",this));\r
     AssertLocked();\r
     NTSTATUS rc = STATUS_SUCCESS;\r
 \r
@@ -304,6 +311,30 @@ Cleanup:
 \r
 }\r
 \r
+\r
+/* This function is called when the user mode has called close socket\r
+   If a client is waiting on recieve we free him, he should get an\r
+   error on his callback. *** The caller probably has a bug - as one\r
+   can't race a closesocket ***\r
+*/   \r
+\r
+VOID \r
+BufferPool::CloseSocket()\r
+{\r
+    SDP_PRINT(SDP_TRACE, SDP_BUFFER_POOL, ("this = 0x%p m_WaitingClients = %s\n",\r
+    m_ClientWaiting ? "true" : "false"));\r
+    AssertLocked();\r
+\r
+    if (m_ClientWaiting) {\r
+        KeSetEvent( &m_WaitingClients, IO_NO_INCREMENT, FALSE );\r
+        m_ClientWaiting = false;\r
+    }\r
+    // The next time our client will try to get data, he will get \r
+    // the error \r
+}\r
+\r
+\r
+\r
 /*\r
     This function is being called from under the lock and is the last one to be called.\r
     It frees all resources\r
@@ -339,7 +370,7 @@ BufferPool::ShutDown()
 NTSTATUS\r
 BufferPool::SendBuffer(BufferDescriptor *pBufferDescriptor)\r
 {\r
-    SDP_PRINT(SDP_TRACE, SDP_BUFFER_POOL, ("this = 0x%p \n",this));\r
+    SDP_PRINT(SDP_DEBUG, SDP_BUFFER_POOL, ("this = 0x%p \n",this));\r
     AssertLocked();\r
     NTSTATUS rc = STATUS_SUCCESS;\r
 \r
@@ -350,7 +381,6 @@ BufferPool::SendBuffer(BufferDescriptor *pBufferDescriptor)
     pHeader->seq_num = GetAndIncreaseSendSeq();\r
     pHeader->seq_ack = m_pSdpSocket->m_RecvBufferPool.GetRecvSeq();\r
     m_AdvtSeq = pHeader->seq_ack;// Currently only for debug\r
-    pHeader->mid = SDP_MID_DATA;\r
     pHeader->flags = SDP_MSG_FLAG_NON_FLAG;\r
     /*\r
      * endian swap\r
@@ -392,11 +422,10 @@ Cleanup:
     return rc;\r
 }\r
 \r
-\r
 NTSTATUS \r
 BufferPool::PostCredits()\r
 {\r
-    SDP_PRINT(SDP_TRACE, SDP_BUFFER_POOL, ("this = 0x%p \n",this));\r
+    SDP_PRINT(SDP_DEBUG, SDP_BUFFER_POOL, ("this = 0x%p \n",this));\r
     AssertLocked();    \r
     NTSTATUS rc = STATUS_SUCCESS;\r
 \r
@@ -415,7 +444,7 @@ BufferPool::PostCredits()
 \r
         rc = BufferDescriptor::AllocateBuffer(\r
                             &m_CreditdBufferDescriptor, \r
-                            sizeof msg_hdr_bsdh, \r
+                            sizeof msg_hdr_bsdh,\r
                             SEND_BUFFERS_ALLOCATION_TAG\r
                             );\r
         if (!NT_SUCCESS(rc)) {\r
@@ -429,6 +458,7 @@ BufferPool::PostCredits()
 \r
     ASSERT(m_CreditdBufferDescriptor->DataSize == 0);\r
 \r
+    m_CreditdBufferDescriptor->SetMid(SDP_MID_DATA);\r
     rc = SendBuffer(m_CreditdBufferDescriptor);\r
     if (!NT_SUCCESS(rc)) {\r
         SDP_PRINT(SDP_ERR, SDP_BUFFER_POOL, ("SendBuffer failed rc = 0x%x\n", rc ));\r
@@ -443,6 +473,41 @@ Cleanup:
 \r
 }\r
 \r
+NTSTATUS BufferPool::PostDisConn()\r
+{\r
+    SDP_PRINT(SDP_TRACE, SDP_BUFFER_POOL, ("this = 0x%p \n",this));\r
+    AssertLocked();    \r
+    NTSTATUS rc = STATUS_SUCCESS;\r
+    BufferDescriptor *pBufferDescriptor = NULL;\r
+\r
+    rc = BufferDescriptor::AllocateBuffer(\r
+                        &pBufferDescriptor, \r
+                        sizeof msg_hdr_bsdh,\r
+                        SEND_BUFFERS_ALLOCATION_TAG\r
+                        );\r
+    if (!NT_SUCCESS(rc)) {\r
+        SDP_PRINT(SDP_ERR, SDP_BUFFER_POOL, ("AllocateBuffer failed rc = 0x%x\n", rc ));\r
+        ASSERT(m_CreditdBufferDescriptor == NULL);\r
+        goto Cleanup;\r
+    }\r
+\r
+    pBufferDescriptor->SetFlags(DISCONNECT_MESSAGE);\r
+\r
+    ASSERT(pBufferDescriptor->DataSize == 0);\r
+\r
+    pBufferDescriptor->SetMid(SDP_MID_DISCONNECT);\r
+    rc = AddBufferToQueuedList(pBufferDescriptor);\r
+    if (!NT_SUCCESS(rc)) {\r
+        SDP_PRINT(SDP_ERR, SDP_BUFFER_POOL, ("SendBuffer failed rc = 0x%x\n", rc ));\r
+        goto Cleanup;\r
+    }\r
+       \r
+Cleanup:\r
+    return rc;\r
+\r
+}\r
+\r
+\r
 VOID \r
 BufferPool::AssertLocked() {\r
 #if DBG\r
index 05940a0..deccc6a 100644 (file)
@@ -69,6 +69,7 @@ typedef void (* SendErrorCB )(NTSTATUS Error, VOID *Context);
 \r
 // The flags that are being used to give more information about the BufferDescriptors\r
 const uint8_t CREDIT_UPDATE = 1;\r
+const uint8_t DISCONNECT_MESSAGE = 2;\r
 \r
 \r
 // Each buffer starts with msg_hdr_bsdh and is followed by the actual data\r
@@ -114,6 +115,11 @@ public:
     VOID SetFlags(uint8_t flags) { Flags = flags; }\r
     uint8_t GetFlags() { return Flags; }\r
 \r
+    VOID SetMid(uint8_t Mid) {\r
+        msg_hdr_bsdh *pHeader = (msg_hdr_bsdh *) pBuffer;\r
+        pHeader->mid = Mid;\r
+    }\r
+\r
     // Each buffer starts with bsdh_hdr structure\r
     VOID    *pBuffer;           // A pointer to the actual place that we put the data\r
     uint32_t BufferSize;        // The total size of the buffer (size that we have allocated)\r
@@ -161,6 +167,8 @@ public:
 \r
     NTSTATUS SendBuffersIfCan();\r
 \r
+    VOID CloseSocket();\r
+\r
     VOID ShutDown();\r
 \r
     uint32_t GetSendSeq() {return m_SendSeq;}\r
@@ -176,6 +184,8 @@ public:
     }\r
 \r
     NTSTATUS PostCredits();\r
+\r
+    NTSTATUS PostDisConn();\r
     \r
 private:\r
 \r
index 7920fef..a56c714 100644 (file)
@@ -11,6 +11,29 @@ ConnectionList::Init(SdpSocket *pSdpSocket)
     KeInitializeEvent(&m_WaitForConnection, NotificationEvent , FALSE );\r
 }\r
 \r
+\r
+/* This function is called when the user mode has called close socket\r
+   If a client is waiting on recieve we free him, he should get an\r
+   error on his callback. *** The caller probably has a bug - as one\r
+   can't race a closesocket ***\r
+*/   \r
+\r
+VOID \r
+ConnectionList::CloseSocket()\r
+{\r
+    SDP_PRINT(SDP_TRACE, SDP_BUFFER_POOL, ("this = 0x%p m_WaitingClients = %s\n",\r
+    m_ClientWaiting ? "true" : "false"));\r
+    AssertLocked();\r
+\r
+    if (m_ClientWaiting) {\r
+        KeSetEvent( &m_WaitForConnection, IO_NO_INCREMENT, FALSE );\r
+        m_ClientWaiting = false;\r
+    }\r
+    // The next time our client will try to get data, he will get \r
+    // the error \r
+}\r
+\r
+\r
 VOID ConnectionList::Shutdown() \r
 {\r
     //?????AssertLocked();\r
index cb95896..d6b8759 100644 (file)
@@ -10,6 +10,9 @@ class ConnectionList {
 \r
 public:\r
     VOID        Init(SdpSocket *pSdpSocket);\r
+\r
+    VOID        CloseSocket();\r
+\r
     VOID        Shutdown();\r
 \r
     bool        IsFull();\r
index 29a1271..40e8784 100644 (file)
@@ -135,8 +135,6 @@ NTSTATUS SdpDriver::Dispatch(
     int Method;\r
     SdpUserFile *pSdpUserFile = NULL;\r
 \r
-\r
-\r
     pIrpSp = IoGetCurrentIrpStackLocation(pIrp);\r
 \r
     switch (pIrpSp->MajorFunction) {\r
@@ -192,7 +190,7 @@ NTSTATUS SdpDriver::Dispatch(
             break;\r
         }\r
         case IRP_MJ_DEVICE_CONTROL: {\r
-                SDP_PRINT(SDP_TRACE, SDP_DRIVER, ("IRP_MJ_DEVICE_CONTROL pIrpSp->FileObject = 0x%x\n", \r
+                SDP_PRINT(SDP_DEBUG, SDP_DRIVER, ("IRP_MJ_DEVICE_CONTROL pIrpSp->FileObject = 0x%x\n", \r
                     pIrpSp->FileObject ));\r
 \r
             // IOCTLs are allowed only for user mode processes\r
@@ -344,7 +342,7 @@ NTSTATUS SdpDriver::DispatchDeviceIoControl(
     switch (IoControlCode) {\r
         case IOCTL_WSP_SOCKET :\r
         {\r
-            SDP_PRINT(SDP_DEBUG, SDP_DRIVER, ("IOCTL_WSP_SOCKET recieved\n" ));   \r
+            SDP_PRINT(SDP_TRACE, SDP_DRIVER, ("IOCTL_WSP_SOCKET recieved\n" ));   \r
             VERIFY_BUFFERS(InputBufferLength, OutputBufferLength, WspSocketIn, WspSocketOut);\r
             OutputDataSize = sizeof (WspSocketOut);\r
 \r
@@ -374,7 +372,7 @@ NTSTATUS SdpDriver::DispatchDeviceIoControl(
 \r
         case IOCTL_WSP_CONNECT :\r
         {\r
-            SDP_PRINT(SDP_DEBUG, SDP_DRIVER, ("IOCTL_WSP_CONNECT recieved\n" ));   \r
+            SDP_PRINT(SDP_TRACE, SDP_DRIVER, ("IOCTL_WSP_CONNECT recieved\n" ));   \r
             VERIFY_BUFFERS(InputBufferLength, OutputBufferLength, WspConnectIn, WspConnectOut);\r
             OutputDataSize = sizeof (WspConnectOut);\r
 \r
@@ -449,7 +447,7 @@ NTSTATUS SdpDriver::DispatchDeviceIoControl(
 \r
         case IOCTL_WSP_BIND:\r
         {\r
-            SDP_PRINT(SDP_DEBUG, SDP_DRIVER, ("IOCTL_WSP_BIND recieved\n" ));   \r
+            SDP_PRINT(SDP_TRACE, SDP_DRIVER, ("IOCTL_WSP_BIND recieved\n" ));   \r
             VERIFY_BUFFERS(InputBufferLength, OutputBufferLength, WspBindIn, WspBindOut);\r
             OutputDataSize = sizeof (WspBindOut);\r
 \r
@@ -474,7 +472,7 @@ NTSTATUS SdpDriver::DispatchDeviceIoControl(
 \r
         case IOCTL_WSP_LISTEN:\r
         {\r
-            SDP_PRINT(SDP_DEBUG, SDP_DRIVER, ("IOCTL_WSP_LISTEN recieved\n" ));   \r
+            SDP_PRINT(SDP_TRACE, SDP_DRIVER, ("IOCTL_WSP_LISTEN recieved\n" ));   \r
             VERIFY_BUFFERS(InputBufferLength, OutputBufferLength, WspListenIn, WspListenOut);\r
             OutputDataSize = sizeof (WspListenOut);\r
 \r
@@ -499,7 +497,7 @@ NTSTATUS SdpDriver::DispatchDeviceIoControl(
 \r
         case IOCTL_WSP_ACCEPT:\r
         {\r
-            SDP_PRINT(SDP_DEBUG, SDP_DRIVER, ("IOCTL_WSP_ACCEPT recieved\n" ));   \r
+            SDP_PRINT(SDP_TRACE, SDP_DRIVER, ("IOCTL_WSP_ACCEPT recieved\n" ));   \r
             VERIFY_BUFFERS(InputBufferLength, OutputBufferLength, WspAcceptIn, WspAcceptOut);\r
             OutputDataSize = sizeof (WspAcceptOut);\r
 \r
@@ -530,7 +528,35 @@ NTSTATUS SdpDriver::DispatchDeviceIoControl(
             }\r
         }\r
         break;\r
-        \r
+\r
+        case IOCTL_WSP_CLOSE_SOCKET :\r
+        {\r
+            SDP_PRINT(SDP_TRACE, SDP_DRIVER, ("IOCTL_WSP_CLOSE_SOCKET recieved\n" ));   \r
+            VERIFY_BUFFERS(InputBufferLength, OutputBufferLength, WspSocketCloseIn, WspSocketCloseOut);\r
+            OutputDataSize = sizeof (WspSocketCloseOut);\r
+\r
+            // get the socket based on the users pointer\r
+            WspSocketCloseIn wspSocketCloseIn = *(WspSocketCloseIn *) pInputBuffer;\r
+            WspSocketCloseOut *pWspSocketCloseOut = (WspSocketCloseOut *) pOutputBuffer;\r
+            pSdpUserFile = (SdpUserFile *)pIrpSp->FileObject->FsContext;\r
+            pSdpSocket = pSdpUserFile->SocketByPointer(wspSocketCloseIn.pSocket);\r
+            if (pSdpSocket == NULL) {\r
+               SDP_PRINT(SDP_DEBUG, SDP_DRIVER, ("IOCTL_WSP_CLOSE_SOCKET socket %x not found\n",wspSocketCloseIn.pSocket));   \r
+               // This is a well defined winsock error\r
+               pWspSocketCloseOut->Errno = WSAENOTSOCK;\r
+               goto Cleanup;\r
+            }\r
+            rc = pSdpSocket->WSPCloseSocket(&wspSocketCloseIn, pWspSocketCloseOut);\r
+            // After closing a socket we "unlink" the kernel object, and it won't\r
+            // be accessable for the user. (currently succesfull or not)\r
+            // BUGBUG: Change this behavior while the linger don't linger staff is fixed\r
+            pSdpUserFile->RemoveSocket(pSdpSocket); // Must succed\r
+            if (!NT_SUCCESS(rc)) {\r
+                SDP_PRINT(SDP_ERR, SDP_DRIVER, ("pSdpSocket->WSPCloseSocket failed rc = 0x%x\n", rc ));        \r
+                goto Cleanup; \r
+            }\r
+        }\r
+        break;\r
         \r
     default:\r
         // This is an unrecgnized IOCTL\r
index cad9a83..34ccce2 100644 (file)
@@ -73,8 +73,9 @@ NTSTATUS
         }\r
     }\r
     if (i == 20) {\r
-            SDP_PRINT(SDP_ERR, SDP_SOCKET, ("!!!! KeWaitForSingleObject was Exhausted STATUS_USER_APC\n" ));\r
-\r
+        SDP_PRINT(SDP_ERR, SDP_SOCKET, ("!!!! KeWaitForSingleObject was Exhausted STATUS_USER_APC\n" ));\r
+        // This is probably fine if we are runnign for a user thread\r
+        ASSERT((WaitReason == UserRequest) && (WaitMode == UserMode));\r
     }\r
     return rc;\r
 }\r
@@ -141,6 +142,35 @@ int abs(int i){
     return -i;\r
 }\r
 \r
+LARGE_INTEGER  TimeFromLong(ULONG HandredNanos)\r
+{\r
+    LARGE_INTEGER  Timeout;\r
+    Timeout.HighPart = 0xffffffff;\r
+    Timeout.LowPart =  0xffffffff ^ HandredNanos;\r
+    return Timeout;\r
+}\r
+\r
+NTSTATUS Sleep(ULONG HandredNanos)\r
+{\r
+    KEVENT Event;\r
+    NTSTATUS rc = STATUS_SUCCESS;\r
+\r
+    KeInitializeEvent(&Event, NotificationEvent , FALSE );\r
+\r
+    LARGE_INTEGER  Timeout = TimeFromLong(HandredNanos);\r
+\r
+    SDP_PRINT(SDP_TRACE, SDP_BUFFER_POOL, ("Before Sleep\n"));                        \r
+    rc = MyKeWaitForSingleObject(\r
+            &Event,\r
+            UserRequest,\r
+            UserMode,\r
+            FALSE,\r
+            &Timeout);                        \r
+    SDP_PRINT(SDP_TRACE, SDP_BUFFER_POOL, ("After Sleep rc = 0x%x\n", rc));\r
+    return rc;\r
+\r
+}\r
+\r
 /* Convert an IBAL error to a Winsock error. */\r
 int IbalToWsaError(const       ib_api_status_t ib_status )\r
 {\r
index 98f2256..ebd95ff 100644 (file)
@@ -72,6 +72,11 @@ VOID UpdateRc(NTSTATUS *rc, NTSTATUS rc1);
 \r
 int abs(int i);\r
 \r
+LARGE_INTEGER  TimeFromLong(ULONG HandredNanos);\r
+\r
+NTSTATUS Sleep(ULONG HandredNanos);\r
+\r
+\r
 /* Convert an IBAL error to a Winsock error. */\r
 int IbalToWsaError(const       ib_api_status_t ib_status );\r
 \r
index b833d4d..1eeb024 100644 (file)
@@ -221,10 +221,8 @@ Cleanup:
                 ASSERT(m_flags & ERROR_SIGNALLED);\r
             }\r
             KeAcquireSpinLock(&m_SpinLock, &OldIrql);\r
-            int xxx = m_flags;\r
             if ((m_flags & DPC_FLAGS) == 0) {\r
                 // No flags to handle from the DPC layer\r
-                ASSERT(m_flags == 0);\r
                 break;\r
             }\r
         }\r
index d25f15e..bd3372c 100644 (file)
@@ -9,6 +9,7 @@ RecvPool::RecvPool()
     m_CurrentlyPostedRecievedBuffers = 0;\r
     m_CurrentlyAllocated = 0;\r
     m_ClientWaiting = false;\r
+    m_DisConnRecieved = false;\r
     m_LocaleAdvertisedBuffers = 0;\r
 }\r
 \r
@@ -23,7 +24,7 @@ RecvPool::Init(
     SdpSocket *pSdpSocket\r
     )\r
 {\r
-    SDP_PRINT(SDP_TRACE, SDP_BUFFER_POOL, ("this = 0x%p \n",this));\r
+    SDP_PRINT(SDP_TRACE, SDP_BUFFER_POOL, ("this = 0x%p \n", m_pSdpSocket));\r
     m_MaxBuffers = MaxBuffers;\r
     m_MaxConcurrentRecieves = MaxConcurrentRecieves;\r
     m_MaxMessageSize = MaxMessageSize;        \r
@@ -35,6 +36,23 @@ RecvPool::Init(
     ASSERT(lkey != NULL);\r
     m_lkey = lkey;\r
     m_pSdpSocket = pSdpSocket;\r
+\r
+    // Allocate all the buffers as continues memory (better be done\r
+    // at passive level)\r
+    BufferDescriptor *pBufferDescriptor = NULL;\r
+    NTSTATUS rc = STATUS_SUCCESS;\r
+    \r
+    for (int i=0;i < MAX_RECV_PACKETS; i++) {\r
+        rc = BufferDescriptor::AllocateBuffer(&pBufferDescriptor, m_MaxMessageSize, SEND_BUFFERS_ALLOCATION_TAG);\r
+        ASSERT(NT_SUCCESS(rc));\r
+        m_CurrentlyAllocated++;\r
+    \r
+        pBufferDescriptor->Reset();\r
+        m_FreePackets.InsertTailList(&pBufferDescriptor->BuffersList);\r
+    }\r
+    m_FirstPostingOfBuffers = 0;\r
+\r
+        \r
     return STATUS_SUCCESS;\r
 }\r
 \r
@@ -45,8 +63,8 @@ RecvPool::Init(
 NTSTATUS\r
 RecvPool::RecievedBuffer(BufferDescriptor *pBufferDescriptor, bool error)\r
 {\r
-    SDP_PRINT(SDP_TRACE, SDP_BUFFER_POOL, ("this = 0x%p pBufferDescriptor = 0x%x error = %s\n"\r
-        ,this, pBufferDescriptor, error ? "true" : "false"));\r
+    SDP_PRINT(SDP_DEBUG, SDP_BUFFER_POOL, ("this = 0x%p pBufferDescriptor = 0x%p error = %s\n"\r
+        ,m_pSdpSocket, pBufferDescriptor, error ? "true" : "false"));\r
     AssertLocked();\r
     NTSTATUS rc = STATUS_SUCCESS;\r
 \r
@@ -84,8 +102,18 @@ 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
+    // m_DisConnRecieved is the last message that should be recieved\r
+    ASSERT(m_DisConnRecieved == false); // BUGBUG: do a real check here\r
+\r
+    // ???? Handle more state changes here ????\r
+    if (pHeader->mid != SDP_MID_DATA) {\r
+        if (pHeader->mid == SDP_MID_DISCONNECT) {\r
+            m_DisConnRecieved = true;\r
+            if (m_ClientWaiting) {\r
+                KeSetEvent( &m_WaitingClients, IO_NO_INCREMENT, FALSE );\r
+                m_ClientWaiting = false;\r
+            }            \r
+        }\r
         // This is a message without data, we currently ignore it\r
         m_FreePackets.InsertTailList(&pBufferDescriptor->BuffersList);\r
     } else {\r
@@ -163,7 +191,7 @@ RecvPool::GetData(
     bool *pNoMoreData\r
     )\r
 {\r
-    SDP_PRINT(SDP_TRACE, SDP_BUFFER_POOL, ("this = 0x%p FirstBuffer = %s\n",this,\r
+    SDP_PRINT(SDP_DEBUG, SDP_BUFFER_POOL, ("this = 0x%p FirstBuffer = %s\n", m_pSdpSocket,\r
         FirstBuffer ? "TRUE" : "FALSE"));\r
     AssertLocked();\r
     bool BufferFreed = false;\r
@@ -221,7 +249,10 @@ RecvPool::GetData(
         } else {\r
             *pNoMoreData = true;\r
             // If data was already supplied, then we shouldn't wait any more\r
-            if ((*Copied > 0) || (FirstBuffer == false)) {\r
+            if ((*Copied > 0) || \r
+                (FirstBuffer == false) ||\r
+                m_DisConnRecieved) {\r
+                ASSERT(*ppEvent == NULL);\r
                 break;\r
             }\r
             // No buffers available, we have to wait\r
@@ -245,7 +276,7 @@ Cleanup:
 VOID \r
 RecvPool::AllowOthersToGet()\r
 {\r
-    SDP_PRINT(SDP_TRACE, SDP_BUFFER_POOL, ("this = 0x%p \n",this));\r
+    SDP_PRINT(SDP_DEBUG, SDP_BUFFER_POOL, ("this = 0x%p \n", m_pSdpSocket));\r
     ASSERT(m_ClientBeingServed == true);\r
     m_ClientBeingServed = false;\r
 \r
@@ -256,8 +287,8 @@ RecvPool::AllowOthersToGet()
 NTSTATUS \r
 RecvPool::ReceiveIfCan()\r
 {\r
-    SDP_PRINT(SDP_TRACE, SDP_BUFFER_POOL, ("this = 0x%p m_CurrentlyPostedRecievedBuffers = %d m_LocaleAdvertisedBuffers = %d\n",\r
-        this, m_CurrentlyPostedRecievedBuffers, m_LocaleAdvertisedBuffers));\r
+    SDP_PRINT(SDP_DEBUG, SDP_BUFFER_POOL, ("this = 0x%p m_CurrentlyPostedRecievedBuffers = %d m_LocaleAdvertisedBuffers = %d\n",\r
+        m_pSdpSocket, m_CurrentlyPostedRecievedBuffers, m_LocaleAdvertisedBuffers));\r
     AssertLocked();\r
     BufferDescriptor *pBufferDescriptor = NULL;\r
     NTSTATUS rc = STATUS_SUCCESS;\r
@@ -266,6 +297,13 @@ RecvPool::ReceiveIfCan()
     while (m_CurrentlyPostedRecievedBuffers < m_MaxConcurrentRecieves) {\r
         // do we have a free packet ?\r
         if (m_FreePackets.Size() > 0) {\r
+            //??????????? lET'S Sleep here for some time (FIND THE RACE) ??????????\r
+            {\r
+                if (m_FirstPostingOfBuffers ==0 ) {\r
+                    m_FirstPostingOfBuffers++;\r
+                    Sleep(0xfffff);\r
+                }\r
+            }\r
             // we can take a packet from the list\r
             LIST_ENTRY *item = m_FreePackets.RemoveHeadList();\r
             pBufferDescriptor = CONTAINING_RECORD(item, BufferDescriptor , BuffersList);            \r
@@ -313,8 +351,9 @@ Cleanup:
 VOID \r
 RecvPool::ShutDown()\r
 {\r
-    SDP_PRINT(SDP_TRACE, SDP_BUFFER_POOL, ("this = 0x%p \n",this));\r
-    //???? AssertLocked();\r
+    // Lock is not taken here, but we should be gurantied that no\r
+    // one can be racing us in here\r
+    SDP_PRINT(SDP_TRACE, SDP_BUFFER_POOL, ("this = 0x%p \n", m_pSdpSocket));\r
     BufferDescriptor *pBufferDescriptor = NULL;\r
     LIST_ENTRY *item = NULL;\r
 \r
@@ -331,10 +370,34 @@ RecvPool::ShutDown()
     }\r
 }\r
 \r
+/* This function is called when the user mode has called close socket\r
+   If a client is waiting on recieve we free him, he should get an\r
+   error on his callback. *** The caller probably has a bug - as one\r
+   can't race a closesocket ***\r
+*/   \r
+\r
+VOID \r
+RecvPool::CloseSocket()\r
+{\r
+    SDP_PRINT(SDP_TRACE, SDP_BUFFER_POOL, ("this = 0x%p m_WaitingClients = %s waiting buffer = %d\n",\r
+        this,\r
+        m_ClientWaiting ? "true" : "false",\r
+        m_FullPackets.Size())\r
+        );\r
+    AssertLocked();\r
+\r
+    if (m_ClientWaiting) {\r
+        KeSetEvent( &m_WaitingClients, IO_NO_INCREMENT, FALSE );\r
+        m_ClientWaiting = false;\r
+    }\r
+    // The next time our client will try to get data, he will get \r
+    // the error \r
+}\r
+\r
 NTSTATUS \r
 RecvPool::PostReceiveBuffer(BufferDescriptor *pBufferDescriptor)\r
 {\r
-    SDP_PRINT(SDP_TRACE, SDP_BUFFER_POOL, ("this = 0x%p \n",this));\r
+    SDP_PRINT(SDP_DEBUG, SDP_BUFFER_POOL, ("this = 0x%p \n", m_pSdpSocket));\r
     AssertLocked();\r
     NTSTATUS rc = STATUS_SUCCESS;\r
 \r
index 715b03a..625b94c 100644 (file)
@@ -36,6 +36,8 @@ public:
 \r
     uint32_t GetRecvSeq() { return m_RecvSeq;}\r
 \r
+    VOID CloseSocket();\r
+\r
     VOID ShutDown();\r
 \r
     uint16_t GetCurrentlyPostedRecievedBuffers() {\r
@@ -85,6 +87,11 @@ private:
 \r
     SdpSocket *m_pSdpSocket;\r
 \r
+    // This signals that the remote side will not be sending any data any more\r
+    bool       m_DisConnRecieved; \r
+\r
+    int m_FirstPostingOfBuffers;//????????????????? USED TO HANDLE SOME RACE\r
+\r
 VOID AssertLocked();\r
 \r
 };\r
index d6d7e9e..6bdccb3 100644 (file)
@@ -48,7 +48,9 @@ static void AL_API
 cm_dreq_callback(IN ib_cm_dreq_rec_t    *p_cm_dreq_rec )\r
 {\r
     SDP_PRINT(SDP_TRACE, SDP_SOCKET, ("dispatch level = %d\n", KeGetCurrentIrql()));\r
-    ASSERT(FALSE);\r
+    SdpSocket *pSocket = (SdpSocket *) p_cm_dreq_rec->qp_context;\r
+    pSocket->CmDreqCallback(p_cm_dreq_rec);\r
+\r
 }\r
 \r
 static void AL_API\r
@@ -85,6 +87,12 @@ listen_err_callback(
     ASSERT( 0 );\r
 }\r
 \r
+void CloseSocketThread(void *pContext)\r
+{\r
+    SdpSocket *pSocket = (SdpSocket *) pContext;\r
+    pSocket->CloseSocketThread();\r
+    \r
+}\r
 static void AL_API\r
 cm_req_callback(\r
     IN              ib_cm_req_rec_t         *p_cm_req_rec )\r
@@ -115,6 +123,11 @@ SdpSocket::SdpSocket()
 \r
     m_state = SS_IDLE;\r
     m_pListeningSocket = NULL;\r
+\r
+    m_CloseSocketCalled = false;\r
+    m_ShutdownCalled = false;\r
+    m_DisconnectConnectionRecieved = false;\r
+    \r
 }\r
 \r
 VOID SdpSocket::AssertLocked()\r
@@ -137,6 +150,7 @@ NTSTATUS SdpSocket::Init(
     pSocketOutParam->Errno = 0;// No error\r
     pSocketOutParam->pSocket = this; // give the user a handle to the socket\r
     KeInitializeEvent(&m_ShutdownCompleteEvent, NotificationEvent , FALSE );\r
+    KeInitializeEvent(&m_DisconectSentEvent, NotificationEvent , FALSE );\r
 \r
     m_ConnectionList.Init(this);\r
 \r
@@ -148,7 +162,7 @@ NTSTATUS SdpSocket::WSPSend(
         WspSendOut   *pWspSendOut\r
         )\r
 {    \r
-    SDP_PRINT(SDP_TRACE, SDP_SOCKET, ("this = 0x%p \n",this));\r
+    SDP_PRINT(SDP_DEBUG, SDP_SOCKET, ("this = 0x%p \n",this));\r
 \r
     NTSTATUS rc = STATUS_SUCCESS;    \r
     NTSTATUS rc1; // used only to check that there are no more errors on the \r
@@ -175,8 +189,18 @@ NTSTATUS SdpSocket::WSPSend(
         Locked = true;\r
         ASSERT(pBuffersEvent == NULL);\r
 \r
-        //??? Verify connected state (or whatever)?????????????\r
-\r
+        if ((m_state != SS_CONNECTED)) {\r
+            // We can not send now.\r
+            SDP_PRINT(SDP_WARN, SDP_SOCKET, ("Can't send now, m_state = %s\n",\r
+                SS2String(m_state)\r
+            ));\r
+            rc = STATUS_SHUTDOWN_IN_PROGRESS;\r
+            pWspSendOut->Errno = WSAENOTCONN;\r
+                \r
+            m_Lock.Unlock(); // Error ignored as this is already an error pass\r
+            Locked = false;\r
+            goto Cleanup;\r
+        }\r
 \r
         rc = m_SendBufferPool.GetBuffer(&pBufferDescriptor, &pBuffersEvent, First);\r
         if (!NT_SUCCESS(rc)) {\r
@@ -207,7 +231,7 @@ NTSTATUS SdpSocket::WSPSend(
             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
+                SDP_PRINT(SDP_WARN, SDP_SOCKET, ("MyKeWaitForSingleObject was alerted rc = 0x%x\n", rc ));\r
                 rc = STATUS_UNEXPECTED_IO_ERROR;\r
                 //pWspConnectOut->Errno = WSAENETUNREACH; // BUGBUG: verify this error\r
                 Shutdown();\r
@@ -232,7 +256,8 @@ NTSTATUS SdpSocket::WSPSend(
         }\r
         Coppied += CopySize;\r
         \r
-        // return the data to the buffer\r
+        // send the data to the buffer\r
+        pBufferDescriptor->SetMid(SDP_MID_DATA);\r
         rc = m_SendBufferPool.AddBufferToQueuedList(pBufferDescriptor);\r
         if (!NT_SUCCESS(rc)) {\r
             SDP_PRINT(SDP_ERR, SDP_SOCKET, ("m_SendBufferPool.AddBufferToQueuedList failed rc = 0x%x\n", rc ));\r
@@ -271,7 +296,7 @@ SdpSocket::WSPRecv(
         WspRecvOut   *pWspRecvOut\r
         )\r
 {\r
-    SDP_PRINT(SDP_TRACE, SDP_SOCKET, ("this = 0x%p BufferSize = %d\n",this, pWspRecvIn->BufferSize));\r
+    SDP_PRINT(SDP_DEBUG, SDP_SOCKET, ("this = 0x%p BufferSize = %d\n",this, pWspRecvIn->BufferSize));\r
 \r
     NTSTATUS rc = STATUS_SUCCESS;\r
     bool First = true;\r
@@ -294,7 +319,18 @@ SdpSocket::WSPRecv(
         Locked = true;\r
         ASSERT(pBuffersEvent == NULL);\r
 \r
-        //??? Verify connected state (or whatever)?????????????\r
+        if ((m_state != SS_CONNECTED && m_state!= SS_CONNECTED_DREP_SENT ) ) {\r
+            // We can not recv now.\r
+            SDP_PRINT(SDP_WARN, SDP_SOCKET, ("Can't recv now, m_state = %s\n",\r
+                SS2String(m_state)\r
+            ));\r
+            rc = STATUS_SHUTDOWN_IN_PROGRESS;\r
+            pWspRecvOut->Errno = WSAENOTCONN;\r
+                \r
+            m_Lock.Unlock(); // Error ignored as this is already an error pass\r
+            Locked = false;\r
+            goto Cleanup;\r
+        }\r
 \r
         rc = m_RecvBufferPool.GetData(\r
             pWspRecvIn->pData + Coppied, \r
@@ -312,7 +348,7 @@ SdpSocket::WSPRecv(
         }\r
         Coppied += ThisCopy;\r
 \r
-        if (NoMoreData && (Coppied > 0)) {\r
+        if (NoMoreData && pBuffersEvent == NULL) {\r
             // this means that there is nothing to copy, and we should return\r
             ASSERT(pBuffersEvent == NULL);\r
             break;\r
@@ -341,7 +377,7 @@ SdpSocket::WSPRecv(
             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
+                SDP_PRINT(SDP_WARN, SDP_SOCKET, ("MyKeWaitForSingleObject was alerted rc = 0x%x\n", rc ));\r
                 rc = STATUS_UNEXPECTED_IO_ERROR;\r
                 //pWspConnectOut->Errno = WSAENETUNREACH; // BUGBUG: verify this error\r
                 Shutdown();\r
@@ -373,7 +409,7 @@ Cleanup:
     }\r
     // Currently in any case, the flags are not being used:\r
     pWspRecvOut->dwFlags = 0;\r
-    SDP_PRINT(SDP_TRACE, SDP_SOCKET, ("this = 0x%p returning %d bytes \n",this, pWspRecvOut->NumberOfBytesRecieved));\r
+    SDP_PRINT(SDP_DEBUG, SDP_SOCKET, ("this = 0x%p returning %d bytes \n",this, pWspRecvOut->NumberOfBytesRecieved));\r
     return rc;\r
 \r
 }\r
@@ -404,12 +440,15 @@ NTSTATUS SdpSocket::WSPConnect(
     }\r
 \r
     // check socket state\r
-    // BUGBUG: Do a better work here (it might be localy bounded ?????)\r
     m_Lock.Lock();//??? retval\r
-    if (m_state != SS_IDLE) {\r
+    if ((m_state != SS_IDLE)) {\r
         // We can not connect in this state \r
-        SDP_PRINT(SDP_ERR, SDP_SOCKET, ("Invalid Socket state %s\n", SS2String(m_state)));\r
-        pWspConnectOut->Errno = WSAEINVAL;\r
+        SDP_PRINT(SDP_WARN, SDP_SOCKET, ("Can't send now, m_state = %s\n",\r
+            SS2String(m_state)\r
+        ));\r
+        rc = STATUS_SHUTDOWN_IN_PROGRESS;\r
+        pWspConnectOut->Errno = WSAENOTCONN;\r
+\r
         m_Lock.Unlock(); //?????retval\r
         goto Cleanup;\r
         \r
@@ -525,7 +564,7 @@ NTSTATUS SdpSocket::WSPConnect(
     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
+        SDP_PRINT(SDP_WARN, SDP_SOCKET, ("MyKeWaitForSingleObject was alerted rc = 0x%x\n", rc ));\r
         rc = STATUS_UNEXPECTED_IO_ERROR;\r
         pWspConnectOut->Errno = WSAENETUNREACH; // BUGBUG: verify this error\r
         Shutdown();\r
@@ -877,10 +916,198 @@ Cleanup:
     // referance on pNewSocket is not currently released, since we are\r
     // returning them to the next level\r
     return rc;\r
+}\r
+\r
+/*\r
+    CloseSocket is probably one of the most complicated winsock APIs.\r
+    Our current implmentation will be the default implmentation always. \r
+    This means that the call is always non-blocking, and it is always gracefully.\r
+    As a result, the remote side should return 0 on it's last read, and we should\r
+    send a DisConn mesage.\r
+\r
+    Well, gracefull or not, the other side is not gourantied to call recieve and \r
+    we can't wait for ever. As a result a timer will be created and after 40 \r
+    seconds, we close abortively.\r
+\r
+    If a different thread is waiting on some event (read, send or accept), we will\r
+    stop the blocking operation, and complete that wait with error.\r
+\r
+    A special case to handle, is a socket that was created and after a while \r
+    closed. In this case, there is nothing really to do, and we will use the \r
+    same thread to close the socket.\r
+\r
+    In the case of an error, an abortive close will be done (using the CM).\r
+\r
+    There will be the following flag, telling the state of the socket.\r
+\r
+    1) CloseSocket called.\r
+\r
+    So basicly, on close, we will do the following:\r
+    1) Stop all blocking operations (send, recieve, accept). (ofcourse, new ones\r
+       are not allowed anymore)\r
+    2) Create the DisConn packet and send it. (if needed)\r
+    3) Start the timer, and wait for all the sends to end.\r
+    4) When ever a send is complited, we will check if this a shutdown in progress\r
+       and we can close the socket.\r
+\r
+    The "real" work of closing the socket will be done by the Shutdown function,\r
+    that will be called either by the CloseSocket when the logic is finished.\r
+\r
+*/\r
+\r
+NTSTATUS \r
+SdpSocket::WSPCloseSocket(\r
+    WspSocketCloseIn    *pWspSocketCloseIn,\r
+    WspSocketCloseOut   *pWspSocketCloseOut\r
+    )\r
+{\r
+    NTSTATUS rc = STATUS_SUCCESS;\r
+    SDP_PRINT(SDP_TRACE, SDP_SOCKET, ("this = 0x%p\n",this));\r
+    OBJECT_ATTRIBUTES   attr;\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_TRACE, SDP_SOCKET, ("socket is in idle state this = 0x%p \n",\r
+            this));\r
+        m_Lock.Unlock(); // Error ignored as this is already a Shutdown pass\r
+        Shutdown();\r
+        pWspSocketCloseOut->Errno = 0;\r
+        goto Cleanup;\r
+    }\r
+\r
+    // This will force that no more calls will be allowed\r
+    ASSERT(m_CloseSocketCalled == FALSE); // If this is not the case \r
+    // We shouldn't be able to take the lock\r
+    m_CloseSocketCalled = true;\r
+\r
+    // notify to all "subclients" to free all waiting clients\r
+    m_RecvBufferPool.CloseSocket();\r
+    m_SendBufferPool.CloseSocket();\r
+    m_ConnectionList.CloseSocket();\r
+\r
+    if (m_state == SS_CONNECTED) {\r
+        // Need to send the DisConn message to the remote side and wait\r
+        rc = m_SendBufferPool.PostDisConn();\r
+        if (!NT_SUCCESS(rc)) {\r
+            SDP_PRINT(SDP_ERR, SDP_SOCKET, ("m_SendBufferPool.PostDisConn failed rc = 0x%x\n", rc ));\r
+            m_Lock.Unlock(); // Error ignored as this is already an error pass\r
+            goto Cleanup;\r
+        }\r
+    }\r
+\r
+    // We will now create a thread that will be resposible for the\r
+    // destruction of this socket\r
+    AddRef();\r
+\r
+\r
+    /* Create a new thread, storing both the handle and thread id. */\r
+    InitializeObjectAttributes( &attr, NULL, OBJ_KERNEL_HANDLE, NULL, NULL );\r
+    \r
+    HANDLE  ThreadHandle;\r
+    rc = PsCreateSystemThread(\r
+        &ThreadHandle, \r
+        THREAD_ALL_ACCESS,\r
+        &attr,\r
+        NULL,\r
+        NULL,\r
+        ::CloseSocketThread,\r
+        this\r
+        );\r
+\r
+    if (!NT_SUCCESS(rc)) {\r
+        SDP_PRINT(SDP_ERR, SDP_SOCKET, ("PsCreateSystemThread failed rc = 0x%x\n", rc ));\r
+        m_Lock.Unlock(); // Error ignored as this is already an error pass\r
+        // The thread wasn't created so we should remove the refferance\r
+        Release();  \r
+        goto Cleanup;\r
+    }\r
+\r
+    // BUGBUG: Replace this with a mechanism that will allow\r
+    // to close the thered when the driver goes down\r
+    rc = ZwClose(ThreadHandle);\r
+    ASSERT(NT_SUCCESS(rc)); // Should succeed\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
+        goto Cleanup;\r
+    }\r
+    \r
+Cleanup:    \r
+    if (NT_SUCCESS(rc) ) {\r
+        pWspSocketCloseOut->Errno = 0;\r
+    } else {\r
+        // Make sure that we have the error setted\r
+        ASSERT(pWspSocketCloseOut->Errno != 0); // BUGBUG: Need to make sure that this\r
+        // is indeed the case. (also check if error was already signaled)\r
+        // In the current model, we call shutdown in any case (to kill the socket)\r
+        Shutdown();        \r
+    }\r
+    SDP_PRINT(SDP_TRACE, SDP_SOCKET, ("this = 0x%p returning Errno = %d\n", \r
+        this , pWspSocketCloseOut->Errno));\r
+\r
+\r
+    return rc;\r
+}\r
+\r
+/*\r
+    This function is supposed to wait for the send to compleate\r
+    and then to kill the socket.\r
+\r
+*/ \r
 \r
 \r
+VOID SdpSocket::DisconectSentEvent()\r
+{\r
+    KeSetEvent( &m_DisconectSentEvent, IO_NO_INCREMENT, FALSE );\r
 }\r
 \r
+/*\r
+    This is the "CloseSocket" thread call back.\r
+    This thread waits WAIT_TO_SOCKET_SHUTDOWN seconds for tht send to complete \r
+    and then it kills the socket abortively.\r
+*/ \r
+VOID SdpSocket::CloseSocketThread()\r
+{\r
+    NTSTATUS rc = STATUS_SUCCESS;\r
+    SDP_PRINT(SDP_TRACE, SDP_SOCKET, ("this = 0x%p\n",this));\r
+\r
+    // wait for the last thread to end.\r
+    LARGE_INTEGER  WaitTime;\r
+    \r
+    WaitTime = TimeFromLong(WAIT_TO_SOCKET_SHUTDOWN * 10 * 1000000);\r
+    rc = MyKeWaitForSingleObject(\r
+        &m_DisconectSentEvent,\r
+        Executive,\r
+        KernelMode,\r
+        FALSE,\r
+        &WaitTime\r
+        );\r
+\r
+    if (rc == STATUS_TIMEOUT) {\r
+        SDP_PRINT(SDP_ERR, SDP_SOCKET, ("Wait failed with time out\n"));\r
+    }\r
+\r
+    ASSERT(NT_SUCCESS(rc));\r
+    ASSERT(rc == STATUS_SUCCESS || rc == STATUS_TIMEOUT);// || rc == STATUS_USER_APC); //???????? what to do \r
+    \r
+    Shutdown();\r
+\r
+    // Everything done - the threads releases the last referance\r
+    // and kills itself\r
+    Release();\r
+    PsTerminateSystemThread(STATUS_SUCCESS);\r
+\r
+    // Do I get here ?\r
+    ASSERT(FALSE);\r
+    \r
+}\r
 \r
 NTSTATUS SdpSocket::CmSendRTU()\r
 {\r
@@ -946,9 +1173,6 @@ NTSTATUS SdpSocket::CmSendRTU()
             (u16)conn->send_size) - SDP_MSG_HDR_SIZE;\r
 \r
 #endif\r
-    /*\r
-     * Pop the hello message that was sent ????? I don't think that we need this\r
-     */\r
 \r
     ib_cm_rtu_t cm_rtu;\r
 \r
@@ -1012,7 +1236,7 @@ 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
+    SDP_PRINT(SDP_TRACE, SDP_SOCKET, ("this = 0x%p\n", this));\r
     ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL);\r
 \r
     if (m_state != SS_CONNECTING_REQ_SENT) {\r
@@ -1034,7 +1258,7 @@ VOID SdpSocket::CmRepCallback(IN   ib_cm_rep_rec_t *p_cm_rep_rec)
 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
+    SDP_PRINT(SDP_TRACE, SDP_SOCKET, ("this = 0x%p\n", this));\r
     NTSTATUS rc = STATUS_SUCCESS;\r
     ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL);\r
     net64_t SrcCaGuid;\r
@@ -1262,7 +1486,6 @@ SdpSocket::CmReqCallback(IN   ib_cm_req_rec_t *p_cm_req_rec)
     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
@@ -1302,7 +1525,7 @@ ErrorLocked:
 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
+    SDP_PRINT(SDP_TRACE, SDP_SOCKET, ("this = 0x%p\n", this));\r
     NTSTATUS rc = STATUS_SUCCESS;\r
     ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL);\r
 \r
@@ -1389,6 +1612,74 @@ ErrorLocked:
 \r
 }\r
 \r
+VOID \r
+SdpSocket::CmDreqCallback(IN   ib_cm_dreq_rec_t *p_cm_dreq_rec)\r
+{\r
+    SDP_PRINT(SDP_TRACE, SDP_SOCKET, ("this = 0x%p\n", this));\r
+    ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL);\r
+    NTSTATUS rc = STATUS_SUCCESS;\r
+    ib_cm_drep_t cm_drep;\r
+    ib_api_status_t ib_status;\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_CONNECTED) {\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
+    // We should send a DREP now\r
+    memset( &cm_drep, 0, sizeof(cm_drep) );\r
+\r
+    ib_status = ib_cm_drep( p_cm_dreq_rec->h_cm_dreq, &cm_drep );\r
+    if( ib_status != IB_SUCCESS ) {\r
+        SDP_PRINT(SDP_ERR, SDP_SOCKET, ("ib_cm_drep failed ib_status = 0x%d\n", ib_status ));\r
+        rc = IB2Status(ib_status);\r
+        goto ErrorLocked;\r
+    }\r
+\r
+    // last step is to change our state\r
+    m_state = SS_CONNECTED_DREP_SENT;\r
+\r
+    // We should close the connection know ??????????/\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
+    //??????? abortive close the connection \r
+\r
+Cleanup:\r
+\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
@@ -1402,12 +1693,8 @@ SdpSocket::__recv_cb1(
 NTSTATUS\r
 SdpSocket::recv_cb()\r
 {\r
-    SDP_PRINT(SDP_TRACE, SDP_SOCKET, ("this = 0x%p \n", this));\r
+    SDP_PRINT(SDP_DEBUG, SDP_SOCKET, ("this = 0x%p \n", this));\r
     NTSTATUS rc = STATUS_SUCCESS, rc1 = STATUS_SUCCESS;    \r
-    if (m_Lock.IsShutdownSignaled()) {\r
-        return 0; //?????????????????? this will cause a leak ??????\r
-    }\r
-\r
     ib_api_status_t     ib_status;\r
     ib_wc_t             *p_free, *p_wc1;\r
     uint32_t            pkt_cnt, recv_cnt = 0;\r
@@ -1534,7 +1821,7 @@ static NTSTATUS __recv_cb2(SdpSocket * pSdpSocket)
 \r
 NTSTATUS SdpSocket::send_cb()\r
 {\r
-    SDP_PRINT(SDP_TRACE, SDP_SOCKET, ("called this =0x%x\n", this));\r
+    SDP_PRINT(SDP_DEBUG, SDP_SOCKET, ("called this =0x%p\n", this));\r
     NTSTATUS rc = STATUS_SUCCESS, rc1 = STATUS_SUCCESS, rc2 = STATUS_SUCCESS;\r
     ib_api_status_t     ib_status;\r
     ib_wc_t  *p_wc, *p_free;\r
@@ -1552,11 +1839,11 @@ NTSTATUS SdpSocket::send_cb()
         ib_status = ib_poll_cq( m_scq, &p_free, &p_wc );\r
         ASSERT( ib_status == IB_SUCCESS || ib_status == IB_NOT_FOUND);\r
         if (ib_status == IB_NOT_FOUND) {\r
-            SDP_PRINT(SDP_WARN, SDP_SOCKET, ("ib_poll_cq returned IB_NOT_FOUND, this =0x%x\n", this));\r
+            SDP_PRINT(SDP_WARN, SDP_SOCKET, ("ib_poll_cq returned IB_NOT_FOUND, this =0x%p\n", this));\r
             break;\r
         }\r
         if (ib_status != IB_SUCCESS) {            \r
-            SDP_PRINT(SDP_ERR, SDP_SOCKET, ("ib_poll_cq failed ib_status=%d, this =0x%x\n", ib_status,this));\r
+            SDP_PRINT(SDP_ERR, SDP_SOCKET, ("ib_poll_cq failed ib_status=%d, this =0x%p\n", ib_status,this));\r
             ASSERT(ib_status == IB_INVALID_CQ_HANDLE || ib_status == IB_NOT_FOUND);\r
             rc = IB2Status(ib_status);\r
             goto Cleanup;\r
@@ -1575,23 +1862,13 @@ NTSTATUS SdpSocket::send_cb()
                 break;\r
 \r
             case IB_WCS_WR_FLUSHED_ERR:\r
-                SDP_PRINT(SDP_ERR, SDP_SOCKET, ("Flushed send completion. this =0x%x\n", this));\r
+                SDP_PRINT(SDP_ERR, SDP_SOCKET, ("Flushed send completion. this =0x%p\n", this));\r
                 // Intentainly fall down\r
             default:\r
                 SDP_PRINT( SDP_ERR, SDP_SOCKET, ("Send failed with %s\n",\r
                 ib_get_wc_status_str( p_wc->status )) );\r
                 m_Lock.SignalError(IB2Status(ib_status));\r
             }\r
-/* Do we need this ????\r
-        free the memory that was used for the send\r
-               if( p_send_buf )\r
-               {\r
-                       cl_perf_start( FreeSendBuf );\r
-                       ExFreeToNPagedLookasideList( &p_port->buf_mgr.send_buf_list,\r
-                               p_send_buf );\r
-                       cl_perf_stop( &p_port->p_adapter->perf, FreeSendBuf );\r
-               }\r
-*/\r
 \r
             p_wc = p_wc->p_next;\r
         }\r
@@ -1603,7 +1880,6 @@ NTSTATUS SdpSocket::send_cb()
         rc = rc1;\r
         goto Cleanup;\r
     }\r
-    \r
 \r
     /* Rearm the CQ. */\r
     ib_status = ib_rearm_cq(m_scq, FALSE );\r
@@ -1817,8 +2093,8 @@ VOID SdpSocket::CreateHelloHeader(
     hello_msg->hh.max_adv       = QP_ATTRIB_RQ_DEPTH;// ??? conn->l_max_adv;\r
     hello_msg->hh.ip_ver        = SDP_MSG_IPVER;\r
     hello_msg->hh.version       = SDP_MSG_VERSION;\r
-    hello_msg->hh.r_rcv_size    = 4096;//???conn->recv_size;\r
-    hello_msg->hh.l_rcv_size    = 4096;//???conn->recv_size;\r
+    hello_msg->hh.r_rcv_size    = MAX_RECV_BUFFER_SIZE;//???conn->recv_size;\r
+    hello_msg->hh.l_rcv_size    = MAX_RECV_BUFFER_SIZE;//???conn->recv_size;\r
     hello_msg->hh.port          = m_SrcPort;\r
     hello_msg->hh.src.ipv4.addr = m_SrcIp;\r
     hello_msg->hh.dst.ipv4.addr = DestIp;\r
@@ -1847,7 +2123,7 @@ VOID SdpSocket::CreateHelloAckHeader(
 \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
+    hello_ack_msg->hah.l_rcv_size    = MAX_RECV_BUFFER_SIZE;//???conn->recv_size;\r
 \r
     /*\r
      * endian swap\r
@@ -1897,7 +2173,7 @@ VOID SdpSocket::CreateCmRequest(
         else if( cm_req->local_resp_timeout < CM_MIN_LOCAL_TIMEOUT )\r
         cm_req->local_resp_timeout = CM_MIN_LOCAL_TIMEOUT;\r
 \r
-    cm_req->rnr_nak_timeout = 6;//6;//???QP_ATTRIB_RNR_NAK_TIMEOUT;\r
+    cm_req->rnr_nak_timeout = 6;//???QP_ATTRIB_RNR_NAK_TIMEOUT;\r
     cm_req->rnr_retry_cnt = 6;//????QP_ATTRIB_RNR_RETRY;\r
     cm_req->retry_cnt = 6;//????QP_ATTRIB_RETRY_COUNT;\r
 \r
@@ -1920,31 +2196,64 @@ VOID SdpSocket::ShutdownCB(VOID* pContext)
 VOID WaitForShutdownEvent(KEVENT *ShutdownCompleteEvent)\r
 {\r
     NTSTATUS rc = STATUS_SUCCESS;\r
+\r
+    LARGE_INTEGER  WaitTime;\r
+    // Why are we waiting with timeout? obviously we should wait forever\r
+    // and if this is the case, there is a bug *SOMEWHERE ELSE*\r
+    // Still I wait WAIT_TO_SOCKET_SHUTDOWN seconds and believe that the user \r
+    // will like me more If I do quit and let the application close\r
+    \r
+    WaitTime = TimeFromLong(WAIT_TO_SOCKET_SHUTDOWN * 10 * 1000000);\r
+\r
     rc = MyKeWaitForSingleObject(\r
         ShutdownCompleteEvent,\r
-        UserRequest,\r
-        UserMode,\r
+        Executive,\r
+        KernelMode,\r
         FALSE,\r
-        NULL\r
+        &WaitTime\r
         );\r
 \r
+    if (rc == STATUS_TIMEOUT) {\r
+        SDP_PRINT(SDP_ERR, SDP_SOCKET, ("Wait failed with time out\n"));\r
+        ASSERT(FALSE);\r
+    }\r
+\r
     ASSERT(NT_SUCCESS(rc));\r
-    ASSERT(rc == STATUS_SUCCESS || rc == STATUS_USER_APC); //???????? what to do \r
+    ASSERT(rc == STATUS_SUCCESS || rc == STATUS_TIMEOUT);// || rc == STATUS_USER_APC); //???????? what to do \r
     //???????? the wait fails\r
     KeClearEvent(ShutdownCompleteEvent);\r
 }\r
 \r
 VOID SdpSocket::Shutdown()\r
 {\r
-    SDP_PRINT(SDP_TRACE, SDP_SOCKET, ("SdpSocket::Shutdown called this = 0x%p\n", this));   \r
+    SDP_PRINT(SDP_TRACE, SDP_SOCKET, ("called this = 0x%p\n", this));   \r
     NTSTATUS rc = STATUS_SUCCESS;\r
-    \r
-    // locking ?????\r
-    // if(m_shutdown - on the lock) ???\r
     ib_api_status_t     ib_status;\r
-    \r
-    m_Lock.SignalShutdown();\r
 \r
+\r
+    if (m_ShutdownCalled) {\r
+        // Since this variable is always changing from false to true\r
+        // we can check it without the lock\r
+        return;\r
+    }\r
+    // now take the lock and test again\r
+\r
+    m_Lock.Lock();  //????????????????????force this locking ????\r
+    if (m_ShutdownCalled) {\r
+        // Already handled\r
+        m_Lock.Unlock(); // Error is ignored since this is already\r
+                         // shutdown call\r
+        return;\r
+    }\r
+    m_ShutdownCalled = true;\r
+    m_Lock.Unlock(); \r
+\r
+    //\r
+    // Here we start a list of operations that once comlpeated,\r
+    // should force that no complition exists anymore\r
+    // Although we are not holding the lock, they will not be able to\r
+    // lock it. This means that they will try to take it and fail\r
+       \r
     if (m_ListenHandle != NULL) {\r
         ib_status = ib_cm_cancel( m_ListenHandle, ShutdownCB );\r
         if( ib_status != IB_SUCCESS ) {\r
@@ -1958,38 +2267,66 @@ VOID SdpSocket::Shutdown()
 \r
     m_ConnectionList.Shutdown();\r
     \r
+    SDP_PRINT(SDP_TRACE, SDP_SOCKET, ("111111\n", this));   \r
 \r
     if (m_qp != NULL) {\r
         ib_status = ib_destroy_qp(m_qp, ShutdownCB);\r
-        ASSERT(ib_status == IB_SUCCESS);\r
-        m_qp = NULL;\r
-        WaitForShutdownEvent(&m_ShutdownCompleteEvent);        \r
+        //m_qp = NULL;\r
+        if(ib_status == IB_SUCCESS) {\r
+            WaitForShutdownEvent(&m_ShutdownCompleteEvent);\r
+        } else {\r
+            ASSERT(ib_status == IB_SUCCESS);\r
+            // If this is not the case, then we could have probably being\r
+            // closing a different socket, which is very bad.\r
+            // To give things a chance to work without shutdown, I'll continue\r
+        }\r
     }\r
 \r
+    SDP_PRINT(SDP_TRACE, SDP_SOCKET, ("22222\n", this));   \r
+\r
     if (m_scq != NULL) {\r
-        ib_destroy_cq(m_scq, ShutdownCB); \r
-        m_scq = NULL;\r
-        WaitForShutdownEvent(&m_ShutdownCompleteEvent);\r
+        ib_status = ib_destroy_cq(m_scq, ShutdownCB);\r
+        //???ASSERT(ib_status == IB_SUCCESS);\r
+        if(ib_status == IB_SUCCESS) {\r
+            WaitForShutdownEvent(&m_ShutdownCompleteEvent);\r
+        }\r
+        //?????m_scq = NULL;\r
     }\r
+    SDP_PRINT(SDP_TRACE, SDP_SOCKET, ("33333\n", this));   \r
 \r
     if (m_rcq != NULL) {\r
-        ib_destroy_cq(m_rcq, ShutdownCB); \r
-        m_rcq = NULL;\r
-        WaitForShutdownEvent(&m_ShutdownCompleteEvent);\r
+        ib_status = ib_destroy_cq(m_rcq, ShutdownCB); \r
+        //???ASSERT(ib_status == IB_SUCCESS);\r
+        if(ib_status == IB_SUCCESS) {\r
+            WaitForShutdownEvent(&m_ShutdownCompleteEvent);\r
+        }\r
+        //??????m_rcq = NULL;\r
+\r
     }\r
-    \r
+    SDP_PRINT(SDP_TRACE, SDP_SOCKET, ("44444\n", this));   \r
     if (m_pd != NULL) {\r
-        ib_dealloc_pd(m_pd, ShutdownCB); \r
-        m_pd = NULL;\r
-        WaitForShutdownEvent(&m_ShutdownCompleteEvent);\r
+        ib_status = ib_dealloc_pd(m_pd, ShutdownCB); \r
+        //???ASSERT(ib_status == IB_SUCCESS);\r
+        if(ib_status == IB_SUCCESS) {        \r
+            WaitForShutdownEvent(&m_ShutdownCompleteEvent);\r
+        }\r
+        //?????m_pd = NULL;\r
+        \r
     }\r
+    SDP_PRINT(SDP_TRACE, SDP_SOCKET, ("55555\n", this));   \r
 \r
     if (mh_Ca != NULL) {\r
-        ib_close_ca(mh_Ca, ShutdownCB); \r
-        mh_Ca = NULL;\r
-        WaitForShutdownEvent(&m_ShutdownCompleteEvent);\r
+        ib_status = ib_close_ca(mh_Ca, ShutdownCB); \r
+        //ASSERT(ib_status == IB_SUCCESS);\r
+        if(ib_status == IB_SUCCESS) {\r
+            WaitForShutdownEvent(&m_ShutdownCompleteEvent);\r
+        }\r
+        //?????mh_Ca = NULL;\r
+\r
     }\r
 \r
+    // No compleations should exist any more\r
+\r
     if (m_pListeningSocket != NULL) {\r
         m_pListeningSocket->Release();\r
         m_pListeningSocket = NULL;\r
index 3e03021..653c915 100644 (file)
@@ -11,24 +11,29 @@ It keeps a list of all the objects so we know when to remove them.
 #ifndef _SDP_SOCKET_H\r
 #define _SDP_SOCKET_H\r
 \r
-const int MAX_SEND_BUFFER_SIZE          = 32768; // This is the maximum send packet size\r
+const int MAX_SEND_BUFFER_SIZE          = 1*4096; // This is the maximum send packet size\r
+\r
+// BUGBUG: Check why changing this param crushes the system\r
+const int MAX_RECV_BUFFER_SIZE          = 1*4096; // This is the maximum send packet size\r
 const int MAX_SEND_PACKETS              = 200;    // This is the maximum number of packets allocated per send\r
 const int MAX_RECV_PACKETS              = 200;    // This is the maximum number of packets allocated per send\r
                                   \r
 \r
-#define QP_ATTRIB_SQ_DEPTH                             64\r
-#define QP_ATTRIB_SQ_SGE                               1       /* Set based on inline data requirements */\r
+const short QP_ATTRIB_SQ_DEPTH =               64;\r
+const short 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
+const short 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
+const short QP_ATTRIB_RNR_NAK_TIMEOUT = 6;\r
 \r
+const short WAIT_TO_SOCKET_SHUTDOWN   = 40; // The time to wait for a socket to complete\r
+                                            // it's shutdown before we become brutal\r
 /* \r
  * TODO: During testing, the switch has been observed to post\r
  * 12 receive buffers.  It would be nice to know what the max is.\r
  */\r
-#define QP_ATTRIB_RQ_DEPTH                             64\r
+const short QP_ATTRIB_RQ_DEPTH =                       64;//64\r
 #define QP_ATTRIB_RQ_SGE                               1\r
 const int SDP_RECV_CREDIT_UPDATE      = 20; // send credit update to the remote \r
                                             // side.\r
@@ -44,10 +49,12 @@ enum SocketStates {
     SS_CONNECTED,\r
     SS_BOUND,\r
     SS_LISTENING,\r
-    SS_REQ_RECV,\r
+    SS_REQ_RECV, //???? not really used ????\r
     SS_REP_SENT,\r
-    SS_INSHUTDOWN\r
+    SS_CONNECTED_DREP_SENT  //??? not really used \r
 };\r
+    // Plesae note that shutdwon and close socket is being done \r
+    // through flags\r
 \r
 void cm_rtu_callback(IN ib_cm_rtu_rec_t *p_cm_rtu_rec );\r
 \r
@@ -70,7 +77,6 @@ private:
     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
@@ -103,10 +109,16 @@ private:
 \r
     KEVENT                  m_ConnectCmCompleteEvent;\r
     KEVENT                  m_ShutdownCompleteEvent;\r
+    KEVENT                  m_DisconectSentEvent;\r
 \r
     ib_wc_t                 m_SendComplitionWC[QP_ATTRIB_SQ_DEPTH];\r
     ib_wc_t                 m_RecvComplitionWC[QP_ATTRIB_RQ_DEPTH];\r
 \r
+    // The following three falgs are used to shutdown a socket\r
+    bool                    m_CloseSocketCalled;\r
+    bool                    m_ShutdownCalled;\r
+    bool                    m_DisconnectConnectionRecieved;\r
+\r
     \r
 \r
     VOID SignalShutdown();\r
@@ -163,11 +175,23 @@ public:
         WspAcceptOut   *pWspAcceptOut\r
         );    \r
     \r
+    NTSTATUS WSPCloseSocket(\r
+        WspSocketCloseIn    *pWspSocketCloseIn,\r
+        WspSocketCloseOut   *pWspSocketCloseOut\r
+        );    \r
 \r
     VOID Shutdown();\r
 \r
     static VOID ShutdownCB(VOID* pContext);\r
 \r
+    // Make sure that lock does check this ??????????????????\r
+    bool AcceptRequests() {\r
+        // Check if our state allows us to handle send/recv/accept ...\r
+        if (m_ShutdownCalled) return false;\r
+        if (m_CloseSocketCalled) return false;\r
+        return true;\r
+    }\r
+\r
 \r
     NTSTATUS CreateQp();\r
 \r
@@ -192,6 +216,12 @@ public:
     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
+    VOID CmDreqCallback(IN   ib_cm_dreq_rec_t *p_cm_dreq_rec);\r
+\r
+    VOID CloseSocketThread();\r
+\r
+    VOID DisconectSentEvent();\r
+    \r
 \r
     // Two varibales that are needed for passing REP data\r
     struct sdp_msg_hello_ack m_hello_ack;\r
@@ -207,10 +237,15 @@ public:
     char * SS2String(SocketStates state) {\r
         switch (state) {\r
             case SS_IDLE                    : return "SS_IDLE";\r
+            case SS_CONNECTING_QPR_SENT     : return "SS_CONNECTING_QPR_SENT";            \r
             case SS_CONNECTING_REQ_SENT     : return "SS_CONNECTING_REQ_SENT";\r
             case SS_CONNECTING_RTU_SENT     : return "SS_CONNECTING_RTU_SENT";\r
             case SS_CONNECTED               : return "SS_CONNECTED";\r
-            case SS_INSHUTDOWN              : return "SS_INSHUTDOWN";\r
+            case SS_BOUND               : return "SS_BOUND";\r
+            case SS_LISTENING               : return "SS_LISTENING";\r
+            case SS_REQ_RECV               : return "SS_REQ_RECV";\r
+            case SS_REP_SENT               : return "SS_REP_SENT";\r
+            case SS_CONNECTED_DREP_SENT               : return "SS_CONNECTED_DREP_SENT";\r
             default : \r
                 ASSERT(FALSE);\r
 \r
index cba394c..6a7724d 100644 (file)
@@ -5,7 +5,8 @@
 \r
 BOOLEAN CheckCondition(int sev, int top, char *file, int line, char * func)\r
 {\r
-    if (sev < SDP_WARN) return FALSE;\r
+    if (sev < SDP_TRACE) return FALSE;\r
+//  if (sev < SDP_WARN) return FALSE;\r
     if (top == SDP_PERFORMANCE) return FALSE;\r
     \r
     DbgPrint ("%s: ", func);\r
index 5254c23..8b64b45 100644 (file)
@@ -4,7 +4,7 @@
 \r
 // Debug level masks\r
 #define SDP_ALL     0x00000001\r
-#define SDP_DEBUG   0x00000002   // No - per packet, but very noisy (i.e. credits) \r
+#define SDP_DEBUG   0x00000002   // also per packet, (would probably change)\r
 #define SDP_TRACE   0x00000004   // No - per packet (data) print \r
 #define SDP_WARN    0x00000008\r
 #define SDP_ERR     0x00000010\r
index 3442dd4..d675f37 100644 (file)
@@ -53,6 +53,26 @@ NTSTATUS SdpUserFile::AddSocket(SdpSocket *pSdpSocket)
 \r
 }\r
 \r
+VOID SdpUserFile::RemoveSocket(SdpSocket *pSdpSocket)\r
+{\r
+    CSpinLockWrapper Lock(m_Lock);\r
+    Lock.Lock();\r
+\r
+    // If shutodown is running, we don't do anything, weather this\r
+    // socket is out of the list already, or that it will soon be \r
+    // out\r
+    if (m_shutdown) {\r
+        Lock.Unlock();\r
+        return ;\r
+    }\r
+\r
+    RemoveEntryList(&pSdpSocket->m_UserFileList);\r
+    pSdpSocket->Release();\r
+    \r
+    Lock.Unlock();\r
+}\r
+\r
+\r
 SdpSocket *SdpUserFile::SocketByPointer(VOID *Socket)\r
 {\r
     SdpSocket *pSdpSocket = NULL;\r
index 67ab18b..1e782d3 100644 (file)
@@ -28,9 +28,10 @@ public:
 \r
     SdpSocket *SocketByPointer(VOID *Socket);\r
     \r
-    \r
     NTSTATUS AddSocket(SdpSocket *pSdpSocket);\r
 \r
+    VOID RemoveSocket(SdpSocket *pSdpSocket);\r
+\r
 };\r
 \r
 #endif //_SDP_USER_FILE_H\r
index 25b433c..07c1f1b 100644 (file)
@@ -17,7 +17,7 @@ KERNEL MODE:
            for the copy\r
 \r
      recv:\r
-       1) What to do when I don\92t have all the buffer to return?\r
+       1) Find and fix the race when the socket is being initialized\r
        2) When posting the credits, consider not sending the credits if there are packets pending and \r
            and we have credits.\r
 \r
@@ -26,8 +26,6 @@ general:
 \r
 USER MODE:\r
 \r
-* check why DHCP doesn't work when the provider is installed.\r
-\r
 * Check the lifetime of the SdpSocket (when is it deleted and so)??\r
 \r
 * check with intel that we can remove their lisence from the files.\r
@@ -35,4 +33,6 @@ USER MODE:
 * check the way that errors are reported to the user mode. It seems that returning an error\r
 in rc means that the output buffer won't pass out.\r
 \r
+* make sure that the "terminator thread" is being killed before we exit.\r
 \r
+* Check why sometimes the QP and so are not valid when you come to kill them\r