\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
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
+ 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
*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
}\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
\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
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
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
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
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
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
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
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
}\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
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
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
\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
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
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
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
\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
\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
\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
\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
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
\r
NTSTATUS SendBuffersIfCan();\r
\r
+ VOID CloseSocket();\r
+\r
VOID ShutDown();\r
\r
uint32_t GetSendSeq() {return m_SendSeq;}\r
}\r
\r
NTSTATUS PostCredits();\r
+\r
+ NTSTATUS PostDisConn();\r
\r
private:\r
\r
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
\r
public:\r
VOID Init(SdpSocket *pSdpSocket);\r
+\r
+ VOID CloseSocket();\r
+\r
VOID Shutdown();\r
\r
bool IsFull();\r
int Method;\r
SdpUserFile *pSdpUserFile = NULL;\r
\r
-\r
-\r
pIrpSp = IoGetCurrentIrpStackLocation(pIrp);\r
\r
switch (pIrpSp->MajorFunction) {\r
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
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
\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
\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
\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
\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
}\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
}\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
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
\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
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
m_CurrentlyPostedRecievedBuffers = 0;\r
m_CurrentlyAllocated = 0;\r
m_ClientWaiting = false;\r
+ m_DisConnRecieved = false;\r
m_LocaleAdvertisedBuffers = 0;\r
}\r
\r
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
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
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
(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
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
} 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
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
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
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
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
}\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
\r
uint32_t GetRecvSeq() { return m_RecvSeq;}\r
\r
+ VOID CloseSocket();\r
+\r
VOID ShutDown();\r
\r
uint16_t GetCurrentlyPostedRecievedBuffers() {\r
\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
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
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
\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
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
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
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
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
}\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
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
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
}\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
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
}\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
}\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
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
// 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
(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
\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
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
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
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
\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
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
\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
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
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
rc = rc1;\r
goto Cleanup;\r
}\r
- \r
\r
/* Rearm the CQ. */\r
ib_status = ib_rearm_cq(m_scq, FALSE );\r
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
\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
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
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
\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
#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
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
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
\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
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
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
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
\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
\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
\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
\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
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
\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
* 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