]> git.openfabrics.org - ~shefty/rdma-win.git/commitdiff
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@173 ad392aa1-c5ef-ae45-8dd8-e69d62a5ef86

19 files changed:
trunk/ulp/sdp/include/SdpShared.h
trunk/ulp/sdp/kernel/SdpArp.h
trunk/ulp/sdp/kernel/SdpBufferPool.cpp
trunk/ulp/sdp/kernel/SdpBufferPool.h
trunk/ulp/sdp/kernel/SdpConnectionList.cpp
trunk/ulp/sdp/kernel/SdpConnectionList.h
trunk/ulp/sdp/kernel/SdpDriver.cpp
trunk/ulp/sdp/kernel/SdpGenUtils.cpp
trunk/ulp/sdp/kernel/SdpGenUtils.h
trunk/ulp/sdp/kernel/SdpLock.h
trunk/ulp/sdp/kernel/SdpRecvPool.cpp
trunk/ulp/sdp/kernel/SdpRecvPool.h
trunk/ulp/sdp/kernel/SdpSocket.cpp
trunk/ulp/sdp/kernel/SdpSocket.h
trunk/ulp/sdp/kernel/SdpTrace.cpp
trunk/ulp/sdp/kernel/SdpTrace.h
trunk/ulp/sdp/kernel/SdpUserFile.cpp
trunk/ulp/sdp/kernel/SdpUserFile.h
trunk/ulp/sdp/todo

index f647de4ec44b267c39025be66a65050630a1bcbf..6638927daf7a46f26d9ed8772ac61d33f3a3ccca 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 f869d56757bd1518b498e2e0bcca1366d18db4a3..09b92a33760f1fdd2e271add5fa530a3184abec2 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 b2e2ecb3fa5345ddaacbb61654f1c8a21fe8cb66..dbf8f3b5b4772dabdad1512747ed2f70d983a64e 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 05940a0dea0f3a7d564f7aaeb55b186892fe413e..deccc6a5079022e7292bbc0d50f6632f03f07653 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 7920fefcd3641d6a46c76529d8ed5affd9cac045..a56c714a00b5a87703ce314982100691a4518859 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 cb95896fa59c2205215252c347c71443c64c2399..d6b8759257ef044e55bdcf7ee4f942a10710f52f 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 29a12710a245ac52759e5ac0e96b2f8d8a7ccbc4..40e87840ba64c81f8d7ba693ef3d100dfae20dfc 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 cad9a834ba8e9d55711f5869062cb0d57069aa42..34ccce21503bcef43307e675285ba1fd2256f6dd 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 98f2256d5eee6c99bf8e47fc3b2357664fbb88d9..ebd95ff8b9baaaf994029eecbb93317b3b227c96 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 b833d4db147ab3a784446e5743dc05fa6d6f3745..1eeb024ec8e564edec6c69acec1c550279cf6602 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 d25f15e7a01ffa6c2650c8d47d2da4665ebe6a0c..bd3372cd65780c8a32058b3406448b9c986064bf 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 715b03ae2171058d21e8d45a4e1abde5d8cb2b16..625b94c64933f5ffc0317adfe6d865257b4de94d 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 d6d7e9ecd4bb8071858918dcd3c81600bb7234d4..6bdccb31e2bc985d6eb35966fc677754eee4ba9e 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 3e03021c495a6305021f36d74dac53a668abbe42..653c9153d176afad346c25c7dcf871c39eb7ecb7 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 cba394c2f2210b157d0f29f13b2dedeeba009260..6a7724d406bb223aab70f4126bd1e3d67104cbc3 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 5254c231950e7cd550b01a62275214e78e05cc1a..8b64b4559d2bea1ad0977356faaf918740ae015e 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 3442dd4c4ac131c3e9d3765edab20d48d6c6efdb..d675f374a965540a46e8d0557f1300802a93f4c1 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 67ab18bfb7b98df2ec86845696467027a5418da8..1e782d3c18b57e69a76e63a47e926781c23c066e 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 25b433c1ee2fc4b194b048b5b8427c6c57d2ab08..07c1f1b6a06074cd4e702e0a504ea7b0afc70b61 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