#pragma warning(disable: 4244 ) \r
\r
NTSTATUS sdp_cm_hello_ack_check(struct sdp_msg_hello_ack *hello_ack);\r
+NTSTATUS sdp_cm_hello_check(struct sdp_msg_hello *msg_hello);\r
static NTSTATUS __send_cb2(SdpSocket * pSdpSocket);\r
static NTSTATUS __recv_cb2(SdpSocket * pSdpSocket);\r
\r
cm_rep_callback(\r
IN ib_cm_rep_rec_t *p_cm_rep_rec )\r
{\r
- \r
-\r
- SDP_PRINT(SDP_TRACE, SDP_SOCKET, ("cm_rep_callback called\n"));\r
SdpSocket *pSocket = (SdpSocket *) p_cm_rep_rec->qp_context;\r
pSocket->CmRepCallback(p_cm_rep_rec);\r
}\r
SDP_PRINT(SDP_TRACE, SDP_SOCKET, ("dispatch level = %d\n", KeGetCurrentIrql()));\r
ASSERT(FALSE);\r
}\r
+\r
+static void AL_API\r
+cm_lap_callback(\r
+ IN ib_cm_lap_rec_t *p_cm_lap_rec )\r
+{\r
+ SDP_PRINT(SDP_TRACE, SDP_SOCKET, ("dispatch level = %d\n", KeGetCurrentIrql()));\r
+ ASSERT(FALSE);\r
+}\r
+\r
+void \r
+cm_rtu_callback(\r
+ IN ib_cm_rtu_rec_t *p_cm_rtu_rec )\r
+{\r
+ SDP_PRINT(SDP_TRACE, SDP_SOCKET, ("dispatch level = %d\n", KeGetCurrentIrql()));\r
+ // Note - Referance count is not increased here since this is a call\r
+ // back, and we are gurantied that shuting down ibal will only end\r
+ // after all callbacks are finished.\r
+ SdpSocket *pSocket = (SdpSocket *) p_cm_rtu_rec->qp_context;\r
+ SdpSocket *pListeningSocket = pSocket->m_pListeningSocket;\r
+ pListeningSocket->CmRtuCallback(p_cm_rtu_rec);\r
+ \r
+}\r
+/*\r
+ * A user-specified callback that is invoked after an error has occurred on\r
+ * a listen request.\r
+ */\r
+static void AL_API\r
+listen_err_callback(\r
+ IN ib_listen_err_rec_t *p_listen_err_rec )\r
+{\r
+ /* TODO ??????????????*/\r
+ UNUSED_PARAM( p_listen_err_rec );\r
+ ASSERT( 0 );\r
+}\r
+\r
+static void AL_API\r
+cm_req_callback(\r
+ IN ib_cm_req_rec_t *p_cm_req_rec )\r
+{\r
+ // Pass the request to the approperiate socket\r
+ SdpSocket *pSocket = (SdpSocket *) p_cm_req_rec->context;\r
+ pSocket->CmReqCallback(p_cm_req_rec);\r
+}\r
+\r
SdpSocket::SdpSocket()\r
{\r
m_CreationFlags = 0;\r
m_SrcPort = 0;\r
m_SrcIp = 0;\r
+ m_DstPort = 0;\r
+ m_DstIp = 0;\r
+ \r
+ m_SrcPortGuid = 0;\r
+ m_SrcCaGuid = 0;\r
+ m_ListenHandle = NULL;\r
\r
mh_Ca = NULL;\r
m_pd = NULL;\r
m_mr = NULL;\r
\r
m_state = SS_IDLE;\r
+ m_pListeningSocket = NULL;\r
}\r
\r
VOID SdpSocket::AssertLocked()\r
pSocketOutParam->pSocket = this; // give the user a handle to the socket\r
KeInitializeEvent(&m_ShutdownCompleteEvent, NotificationEvent , FALSE );\r
\r
+ m_ConnectionList.Init(this);\r
+\r
return rc;\r
}\r
\r
Locked = true;\r
ASSERT(pBuffersEvent == NULL);\r
\r
+ //??? Verify connected state (or whatever)?????????????\r
+\r
+\r
rc = m_SendBufferPool.GetBuffer(&pBufferDescriptor, &pBuffersEvent, First);\r
if (!NT_SUCCESS(rc)) {\r
SDP_PRINT(SDP_ERR, SDP_SOCKET, ("m_SendBufferPool.GetBuffer failed rc = 0x%x\n", rc ));\r
WspRecvOut *pWspRecvOut\r
)\r
{\r
- SDP_PRINT(SDP_TRACE, SDP_SOCKET, ("this = 0x%p \n",this));\r
+ SDP_PRINT(SDP_TRACE, SDP_SOCKET, ("this = 0x%p BufferSize = %d\n",this, pWspRecvIn->BufferSize));\r
\r
NTSTATUS rc = STATUS_SUCCESS;\r
bool First = true;\r
uint32_t Coppied = 0, ThisCopy = 0;\r
bool Locked = false;\r
PRKEVENT pBuffersEvent = NULL;\r
+ bool NoMoreData;\r
\r
if (pWspRecvIn->BufferSize == 0) {\r
SDP_PRINT(SDP_WARN, SDP_SOCKET, ("this = 0x%p - zero size recv \n",this));\r
Locked = true;\r
ASSERT(pBuffersEvent == NULL);\r
\r
+ //??? Verify connected state (or whatever)?????????????\r
+\r
rc = m_RecvBufferPool.GetData(\r
pWspRecvIn->pData + Coppied, \r
pWspRecvIn->BufferSize - Coppied, \r
&ThisCopy, \r
&pBuffersEvent, \r
- First\r
+ First,\r
+ &NoMoreData\r
);\r
if (!NT_SUCCESS(rc)) {\r
SDP_PRINT(SDP_ERR, SDP_SOCKET, ("m_RecvBufferPool.GetData failed rc = 0x%x\n", rc ));\r
Locked = false;\r
goto Cleanup;\r
}\r
- First = false;\r
Coppied += ThisCopy;\r
+\r
+ if (NoMoreData && (Coppied > 0)) {\r
+ // this means that there is nothing to copy, and we should return\r
+ ASSERT(pBuffersEvent == NULL);\r
+ break;\r
+ }\r
+ \r
+ First = false;\r
\r
if (pBuffersEvent != NULL) {\r
// We are told to wait on this event\r
Cleanup:\r
if (NT_SUCCESS(rc) ) {\r
pWspRecvOut->Errno = 0;\r
- ASSERT(pWspRecvIn->BufferSize == Coppied);\r
+ ASSERT(pWspRecvIn->BufferSize >= Coppied);\r
pWspRecvOut->NumberOfBytesRecieved = Coppied;\r
} else {\r
// Make sure that we have the error setted\r
ASSERT(pWspRecvOut->Errno != 0); // BUGBUG: Need to make sure that this\r
+ pWspRecvOut->NumberOfBytesRecieved = 0;\r
// is indeed the case.\r
}\r
// Currently in any case, the flags are not being used:\r
- pWspRecvOut->dwFlags = 0; \r
+ pWspRecvOut->dwFlags = 0;\r
+ SDP_PRINT(SDP_TRACE, SDP_SOCKET, ("this = 0x%p returning %d bytes \n",this, pWspRecvOut->NumberOfBytesRecieved));\r
return rc;\r
\r
}\r
{\r
NTSTATUS rc = STATUS_SUCCESS;\r
ib_api_status_t ib_status;\r
- ib_net64_t SrcPortGuid;\r
ib_net64_t DestPortGuid;\r
ib_path_rec_t path_rec;\r
\r
}\r
\r
// check socket state\r
- // BUGBUG: Do a better work here\r
+ // BUGBUG: Do a better work here (it might be localy bounded ?????)\r
m_Lock.Lock();//??? retval\r
if (m_state != SS_IDLE) {\r
// We can not connect in this state \r
if (m_SrcPort == 0) {\r
rc = g_pSdpDriver->m_pSdpArp->GetPort(m_SrcIp, &m_SrcPort);\r
if (!NT_SUCCESS(rc)) {\r
- SDP_PRINT(SDP_ERR, SDP_SOCKET, ("m_pSdpArp->SourcePortGidFromIP failed rc = 0x%x\n", rc ));\r
+ SDP_PRINT(SDP_ERR, SDP_SOCKET, ("m_pSdpArp->GetPort failed rc = 0x%x\n", rc ));\r
pWspConnectOut->Errno = WSAENETUNREACH; // BUGBUG: verify this error\r
m_Lock.Unlock(); // Error ignored as this is already an error pass\r
goto Cleanup;\r
} \r
+ } else {\r
+ // We need to connect to the global table of ports\r
+\r
}\r
- rc = g_pSdpDriver->m_pSdpArp->SourcePortGidFromIP(m_SrcIp, &SrcPortGuid, &m_CaGuid);\r
+\r
+ \r
+ rc = g_pSdpDriver->m_pSdpArp->SourcePortGidFromIP(m_SrcIp, &m_SrcPortGuid, &m_SrcCaGuid);\r
if (!NT_SUCCESS(rc)) {\r
SDP_PRINT(SDP_ERR, SDP_SOCKET, ("m_pSdpArp->SourcePortGidFromIP failed rc = 0x%x\n", rc ));\r
pWspConnectOut->Errno = WSAENETUNREACH; // BUGBUG: verify this error\r
m_state = SS_CONNECTING_QPR_SENT;\r
m_Lock.Unlock(); //?????\r
\r
- rc = g_pSdpDriver->m_pSdpArp->QueryPathRecord( SrcPortGuid, DestPortGuid, &path_rec );\r
+ rc = g_pSdpDriver->m_pSdpArp->QueryPathRecord( m_SrcPortGuid, DestPortGuid, &path_rec );\r
if (!NT_SUCCESS(rc)) {\r
SDP_PRINT(SDP_ERR, SDP_SOCKET, ("m_pSdpArp->QueryPathRecord failed rc = 0x%x\n", rc ));\r
pWspConnectOut->Errno = WSAENETUNREACH; // BUGBUG: verify this error\r
\r
}\r
\r
+NTSTATUS \r
+SdpSocket::WSPBind(\r
+ WspBindIn *pWspBindIn,\r
+ WspBindOut *pWspBindOut\r
+ )\r
+{\r
+ NTSTATUS rc = STATUS_SUCCESS;\r
+\r
+ SDP_PRINT(SDP_TRACE, SDP_SOCKET, ("this = 0x%p bind address ip=%d.%d.%d.%d:%d\n",\r
+ this,\r
+ (pWspBindIn->IP & 0XFF000000) >> 24,\r
+ (pWspBindIn->IP & 0XFF0000) >> 16,\r
+ (pWspBindIn->IP & 0XFF00) >> 8,\r
+ (pWspBindIn->IP & 0XFF),\r
+ pWspBindIn->Port\r
+ ));\r
+\r
+ if (!m_Lock.Lock()) {\r
+ SDP_PRINT(SDP_ERR, SDP_SOCKET, ("Failed to lock this = 0x%p \n",this));\r
+ rc = STATUS_SHUTDOWN_IN_PROGRESS;\r
+ goto Cleanup;\r
+ }\r
+\r
+ /* Verify the state of the socket */\r
+ if( m_state != SS_IDLE) {\r
+ SDP_PRINT(SDP_ERR, SDP_SOCKET, ("socket is in invalid state %s this = 0x%p \n",\r
+ this, \r
+ SS2String(m_state)));\r
+ m_Lock.Unlock(); // Error ignored as this is already an error pass\r
+ rc = STATUS_INVALID_DEVICE_STATE;\r
+ pWspBindOut->Errno = WSAEINVAL;\r
+ goto Cleanup;\r
+ }\r
+\r
+ \r
+ /* Check if the ip address is assigned to one of our IBoIB HCA. */\r
+ if( pWspBindIn->IP != INADDR_ANY )\r
+ {\r
+ ASSERT(m_SrcCaGuid == NULL);\r
+ rc = g_pSdpDriver->m_pSdpArp->SourcePortGidFromIP(pWspBindIn->IP, &m_SrcPortGuid, &m_SrcCaGuid);\r
+ if (!NT_SUCCESS(rc)) {\r
+ SDP_PRINT(SDP_ERR, SDP_SOCKET, ("m_pSdpArp->SourcePortGidFromIP failed rc = 0x%x\n", rc ));\r
+ pWspBindOut->Errno = WSAENETUNREACH; // BUGBUG: verify this error\r
+ m_Lock.Unlock(); // Error ignored as this is already an error pass\r
+ goto Cleanup;\r
+ } \r
+ }\r
+ else\r
+ {\r
+ m_SrcPortGuid = 0;\r
+ }\r
+\r
+ if( pWspBindIn->IP != INADDR_ANY ) {\r
+ /* Time to allocate our IB QP */\r
+ rc = CreateQp();\r
+ if (!NT_SUCCESS(rc)) {\r
+ SDP_PRINT(SDP_ERR, SDP_SOCKET, ("CreateQp failed rc = 0x%x\n", rc ));\r
+ pWspBindOut->Errno = WSAENOBUFS;\r
+ m_Lock.Unlock(); // Error ignored as this is already an error pass\r
+ goto Cleanup;\r
+ } \r
+ }\r
+\r
+ // If the src port is 0, we need to allocate a port for the caller.\r
+ if (pWspBindIn->Port == 0) {\r
+ m_SrcPort = 0;\r
+ rc = g_pSdpDriver->m_pSdpArp->GetPort(pWspBindIn->IP, &m_SrcPort);\r
+ if (!NT_SUCCESS(rc)) {\r
+ SDP_PRINT(SDP_ERR, SDP_SOCKET, ("m_pSdpArp->GetPort failed rc = 0x%x\n", rc ));\r
+ pWspBindOut->Errno = WSAENETUNREACH; // BUGBUG: verify this error\r
+ m_Lock.Unlock(); // Error ignored as this is already an error pass\r
+ goto Cleanup;\r
+ } \r
+ } else {\r
+ // We have to allocate the needed port in the table???????\r
+\r
+ }\r
+\r
+ // Everything went OK\r
+ m_SrcPort = pWspBindIn->Port;\r
+ m_SrcIp = pWspBindIn->IP;\r
+\r
+ m_state = SS_BOUND;\r
+ rc = m_Lock.Unlock();\r
+ if (!NT_SUCCESS(rc)) {\r
+ SDP_PRINT(SDP_ERR, SDP_SOCKET, ("m_Lock.Unlock() failed rc = 0x%x\n", rc ));\r
+ goto Cleanup;\r
+ }\r
+\r
+Cleanup: \r
+ if (NT_SUCCESS(rc) ) {\r
+ pWspBindOut->Errno = 0;\r
+ } else {\r
+ // Make sure that we have the error setted\r
+ ASSERT(pWspBindOut->Errno != 0); // BUGBUG: Need to make sure that this\r
+ // is indeed the case.\r
+ //??????????? Make sure that we clean this function on exit\r
+ }\r
+ return rc;\r
+\r
+}\r
+\r
+NTSTATUS SdpSocket::WSPListen(\r
+ WspListenIn *pWspListenIn,\r
+ WspListenOut *pWspListenOut\r
+ )\r
+{\r
+ NTSTATUS rc = STATUS_SUCCESS;\r
+ ib_cm_listen_t param;\r
+ ib_api_status_t ib_status;\r
+\r
+ SDP_PRINT(SDP_TRACE, SDP_SOCKET, ("this = 0x%p \n",this));\r
+ if (!m_Lock.Lock()) {\r
+ SDP_PRINT(SDP_ERR, SDP_SOCKET, ("Failed to lock this = 0x%p \n",this));\r
+ rc = STATUS_SHUTDOWN_IN_PROGRESS;\r
+ goto Cleanup;\r
+ }\r
+\r
+ /* Verify the state of the socket */\r
+ if( m_state != SS_BOUND) {\r
+ SDP_PRINT(SDP_ERR, SDP_SOCKET, ("socket is in invalid state %s this = 0x%p \n",\r
+ this, \r
+ SS2String(m_state)));\r
+ m_Lock.Unlock(); // Error ignored as this is already an error pass\r
+ rc = STATUS_INVALID_DEVICE_STATE;\r
+ pWspListenOut->Errno = WSAEINVAL;\r
+ goto Cleanup;\r
+ }\r
+\r
+ m_ConnectionList.SetBackLog(pWspListenIn->backlog);\r
+\r
+ // Create the CM request\r
+ memset( ¶m, 0, sizeof(param) );\r
+\r
+ ASSERT(m_SrcPort != 0);\r
+ param.svc_id = get_service_id_for_port( m_SrcPort);\r
+ if( m_SrcPortGuid )\r
+ {\r
+ /* The socket is bound to an IP address */\r
+ param.ca_guid = m_SrcCaGuid;\r
+ param.port_guid = m_SrcPortGuid;\r
+ }\r
+ else\r
+ {\r
+ /* The socket is bound to INADDR_ANY */\r
+ param.ca_guid = IB_ALL_CAS;\r
+ param.port_guid = IB_ALL_PORTS;\r
+ }\r
+\r
+ param.lid = IB_ALL_LIDS;\r
+\r
+ /* Currently no compare function ?????\r
+ param.p_compare_buffer = (uint8_t *) & socket_info->info.listen.listen_req_param;\r
+ param.compare_length = sizeof(struct listen_req_param);\r
+ param.compare_offset = offsetof(struct cm_req_params, listen_req_param);\r
+ */ \r
+\r
+ param.pfn_cm_req_cb = cm_req_callback;\r
+\r
+ param.qp_type = IB_QPT_RELIABLE_CONN;\r
+\r
+ ASSERT(m_ListenHandle == NULL);\r
+\r
+ ib_status = ib_cm_listen(\r
+ g_pSdpDriver->m_al_handle , \r
+ ¶m, \r
+ listen_err_callback, \r
+ this,\r
+ &m_ListenHandle \r
+ );\r
+\r
+ if( ib_status != IB_SUCCESS ) {\r
+ SDP_PRINT(SDP_ERR, SDP_SOCKET, ("ib_cm_listen failed ib_status = 0x%d\n", ib_status ));\r
+ rc = IB2Status(ib_status);\r
+ pWspListenOut->Errno = IbalToWsaError( ib_status );\r
+ goto Cleanup;\r
+ }\r
+ \r
+ // SUCCESS - change the state \r
+ m_state = SS_LISTENING;\r
+ rc = m_Lock.Unlock();\r
+ if (!NT_SUCCESS(rc)) {\r
+ SDP_PRINT(SDP_ERR, SDP_SOCKET, ("m_Lock.Unlock() failed rc = 0x%x\n", rc ));\r
+ goto Cleanup;\r
+ }\r
+\r
+Cleanup: \r
+ if (NT_SUCCESS(rc) ) {\r
+ pWspListenOut->Errno = 0;\r
+ } else {\r
+ // Make sure that we have the error setted\r
+ ASSERT(pWspListenOut->Errno != 0); // BUGBUG: Need to make sure that this\r
+ // is indeed the case.\r
+ }\r
+ return rc;\r
+}\r
+\r
+NTSTATUS \r
+SdpSocket::WSPAccept(\r
+ WspAcceptIn *pWspAcceptIn,\r
+ WspAcceptOut *pWspAcceptOut\r
+ )\r
+{\r
+ NTSTATUS rc = STATUS_SUCCESS;\r
+ bool Locked = false;\r
+ SdpSocket *pNewSocket = NULL;\r
+ PRKEVENT pAcceptEvent = NULL;\r
+\r
+ SDP_PRINT(SDP_TRACE, SDP_SOCKET, ("this = 0x%p \n",this));\r
+\r
+ while (true) {\r
+ if ((Locked == false) && !m_Lock.Lock()) {\r
+ SDP_PRINT(SDP_ERR, SDP_SOCKET, ("Failed to lock this = 0x%p \n",this));\r
+ rc = STATUS_SHUTDOWN_IN_PROGRESS;\r
+ goto Cleanup;\r
+ }\r
+ Locked = true;\r
+ ASSERT(pNewSocket == NULL);\r
+\r
+ /* Verify the state of the socket */\r
+ if( m_state != SS_LISTENING) {\r
+ SDP_PRINT(SDP_ERR, SDP_SOCKET, ("socket is in invalid state %s this = 0x%p \n",\r
+ this, \r
+ SS2String(m_state)));\r
+ m_Lock.Unlock(); // Error ignored as this is already an error pass\r
+ Locked = false;\r
+ rc = STATUS_INVALID_DEVICE_STATE;\r
+ pWspAcceptOut->Errno = WSAEINVAL;\r
+ goto Cleanup;\r
+ }\r
+\r
+ rc = m_ConnectionList.AcceptAReadyConnection(&pNewSocket, &pAcceptEvent);\r
+ if (!NT_SUCCESS(rc)) {\r
+ SDP_PRINT(SDP_ERR, SDP_SOCKET, ("m_ConnectionList.AcceptAReadyConnection failed rc = 0x%x\n", rc ));\r
+ m_Lock.Unlock(); // Error ignored as this is already an error pass\r
+ Locked = false;\r
+ goto Cleanup;\r
+ }\r
+\r
+ if (pNewSocket != NULL) {\r
+ ASSERT(pAcceptEvent == NULL);\r
+ break;\r
+ }\r
+\r
+ ASSERT(pAcceptEvent != NULL);\r
+ \r
+ // We are told to wait on this event\r
+ rc = m_Lock.Unlock();\r
+ Locked = false;\r
+ if (!NT_SUCCESS(rc)) {\r
+ SDP_PRINT(SDP_ERR, SDP_SOCKET, ("m_Lock.Unlock() failed rc = 0x%x\n", rc ));\r
+ goto Cleanup;\r
+ }\r
+\r
+ rc = MyKeWaitForSingleObject(\r
+ pAcceptEvent,\r
+ UserRequest,\r
+ UserMode,\r
+ FALSE,\r
+ NULL\r
+ ); \r
+ pAcceptEvent = NULL;\r
+ if (( rc == STATUS_ALERTED ) ||( rc == STATUS_USER_APC )) {\r
+ // BUGBUG: Think what to do here, we should be able to stop the\r
+ // connect, and quit (probably shutdown should be enough)\r
+ SDP_PRINT(SDP_WARN, SDP_SOCKET, ("MyKeWaitForSingleObject was alerted = 0x%x\n", rc ));\r
+ rc = STATUS_UNEXPECTED_IO_ERROR;\r
+ //pWspConnectOut->Errno = WSAENETUNREACH; // BUGBUG: verify this error\r
+ Shutdown();\r
+ goto Cleanup;\r
+ }\r
+ // try getting the socket again\r
+ } \r
+\r
+ // I want to copy this data before releasing the lock\r
+ ULONG IP = m_DstIp;\r
+ USHORT Port = m_DstPort; \r
+ \r
+ ASSERT(Locked == true);\r
+ rc = m_Lock.Unlock();\r
+ Locked = false;\r
+ if (!NT_SUCCESS(rc)) {\r
+ SDP_PRINT(SDP_ERR, SDP_SOCKET, ("m_Lock.Unlock() failed rc = 0x%x\n", rc ));\r
+ goto Cleanup;\r
+ }\r
+ \r
+Cleanup: \r
+ ASSERT(Locked == false);\r
+ if (NT_SUCCESS(rc) ) {\r
+ pWspAcceptOut->pAccaptedSocket = pNewSocket;\r
+ pWspAcceptOut->IP = IP;\r
+ pWspAcceptOut->Port = Port;\r
+ pWspAcceptOut->Errno = 0;\r
+ // We need to "register" this socket in the global list\r
+ \r
+ } else {\r
+ // Make sure that we have the error setted\r
+ ASSERT(pWspAcceptOut->Errno != 0); // BUGBUG: Need to make sure that this\r
+ ASSERT(pNewSocket == NULL);\r
+ pWspAcceptOut->pAccaptedSocket = NULL;\r
+ // is indeed the case.\r
+ }\r
+ // referance on pNewSocket is not currently released, since we are\r
+ // returning them to the next level\r
+ return rc;\r
+\r
+\r
+}\r
+\r
\r
NTSTATUS SdpSocket::CmSendRTU()\r
{\r
\r
rc = m_Lock.Lock();\r
if (!NT_SUCCESS(rc)) {\r
- SDP_PRINT(SDP_ERR, SDP_SOCKET, ("m_RecvBufferPool.Init failed rc = 0x%x\n", rc ));\r
+ SDP_PRINT(SDP_ERR, SDP_SOCKET, ("m_Lock.Lock failed rc = 0x%x\n", rc ));\r
goto Cleanup;\r
}\r
\r
rc = m_RecvBufferPool.ReceiveIfCan(); //??? error\r
m_Lock.Unlock(); // error ????\r
if (!NT_SUCCESS(rc)) {\r
- SDP_PRINT(SDP_ERR, SDP_SOCKET, ("m_RecvBufferPool.Init failed rc = 0x%x\n", rc ));\r
+ SDP_PRINT(SDP_ERR, SDP_SOCKET, ("m_RecvBufferPool.ReceiveIfCan failed rc = 0x%x\n", rc ));\r
goto Cleanup;\r
}\r
\r
\r
VOID SdpSocket::CmRepCallback(IN ib_cm_rep_rec_t *p_cm_rep_rec)\r
{\r
+ SDP_PRINT(SDP_TRACE, SDP_SOCKET, ("this = 0x%x\n", this));\r
+ ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL);\r
+\r
if (m_state != SS_CONNECTING_REQ_SENT) {\r
// This is not the state that we waited for, not much that we can\r
// do. (This might happen in shutdown)\r
- SDP_PRINT(SDP_ERR, SDP_SOCKET, ("SdpSocket::CmRepCallback Not the expacted state %s\n", SS2String(m_state)));\r
+ SDP_PRINT(SDP_ERR, SDP_SOCKET, ("Not the expacted state %s\n", SS2String(m_state)));\r
ASSERT(FALSE);\r
return;\r
}\r
KeSetEvent(&m_ConnectCmCompleteEvent, IO_NO_INCREMENT, FALSE);\r
}\r
\r
+VOID \r
+SdpSocket::CmReqCallback(IN ib_cm_req_rec_t *p_cm_req_rec)\r
+{\r
+ SDP_PRINT(SDP_TRACE, SDP_SOCKET, ("this = 0x%x\n", this));\r
+ NTSTATUS rc = STATUS_SUCCESS;\r
+ ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL);\r
+ net64_t SrcCaGuid;\r
+ ib_net64_t SrcPortGuid;\r
+ ib_api_status_t ib_status;\r
+ SdpSocket *pNewSocket = NULL;\r
+\r
+ sdp_msg_hello *msg_hello = (sdp_msg_hello *)p_cm_req_rec->p_req_pdata;\r
+\r
+ rc = sdp_cm_hello_check(msg_hello);\r
+ if (!NT_SUCCESS(rc)) {\r
+ SDP_PRINT(SDP_ERR, SDP_SOCKET, ("sdp_cm_hello_ack_check failed rc = 0x%x\n", rc ));\r
+ goto Cleanup;\r
+ }\r
+\r
+ // Take the lock and verify the state\r
+ rc = m_Lock.Lock();\r
+ if (!NT_SUCCESS(rc)) {\r
+ SDP_PRINT(SDP_ERR, SDP_SOCKET, ("m_Lock.Lock failed rc = 0x%x\n", rc ));\r
+ goto Cleanup;\r
+ }\r
+\r
+ if (m_state != SS_LISTENING) {\r
+ // This is not the state that we waited for, we drop the request\r
+ SDP_PRINT(SDP_ERR, SDP_SOCKET, ("Not the expacted state %s\n", SS2String(m_state)));\r
+ ASSERT(FALSE);\r
+ goto ErrorLocked;\r
+ }\r
+\r
+ // Check that we haven't passed the backlog for this connection\r
+ if (m_ConnectionList.IsFull()) {\r
+ SDP_PRINT(SDP_WARN, SDP_SOCKET, ("Dropping the connection, because of a backlog that is too small\n"));\r
+ goto ErrorLocked; \r
+ }\r
+\r
+ // Create a new socket for this request\r
+ pNewSocket = new SdpSocket;\r
+ if (pNewSocket == NULL) {\r
+ SDP_PRINT(SDP_ERR, SDP_SOCKET, ("pNewSocket failed\n")); \r
+ goto ErrorLocked;\r
+ }\r
+\r
+ // Code here is a little dirty to allow us to use the existing infrastructure\r
+ WspSocketIn SocketInParam;\r
+ WspSocketOut SocketOutParam;\r
+ SocketInParam.dwFlags = 0; \r
+ rc = pNewSocket->Init(&SocketInParam, &SocketOutParam);\r
+ if (!NT_SUCCESS(rc)) {\r
+ SDP_PRINT(SDP_ERR, SDP_SOCKET, ("pNewSocket.Init() failed rc = 0x%x\n", rc ));\r
+ goto ErrorLocked;\r
+ }\r
+ ASSERT(SocketOutParam.Errno == 0);\r
+ ASSERT(SocketOutParam.pSocket == pNewSocket);\r
+\r
+ // Connect the new socket to it's creator\r
+ ASSERT(pNewSocket->m_pListeningSocket == NULL);\r
+ pNewSocket->m_pListeningSocket = this;\r
+ pNewSocket->m_pListeningSocket->AddRef(); \r
+\r
+ /*\r
+ * save hello parameters.\r
+ */\r
+ pNewSocket->m_state = SS_REQ_RECV; //?????? do we really need this state?????\r
+\r
+ pNewSocket->m_SrcIp = msg_hello->hh.dst.ipv4.addr;\r
+ ASSERT(m_SrcPort != 0);\r
+ pNewSocket->m_SrcPort = m_SrcPort;\r
+ pNewSocket->m_DstIp = msg_hello->hh.src.ipv4.addr;\r
+ pNewSocket->m_DstPort = msg_hello->hh.port;\r
+\r
+ // Initiate parameters based on what we recieve from the remote side\r
+// pNewSocket->send_size = msg_hello->hh.l_rcv_size; ??? MAX_Message_size when calling init on the buffers ???\r
+//??? pNewSocket->r_max_adv = msg_hello->hh.max_adv; ???????????\r
+//???? pNewSocket->r_recv_bf = msg_hello->bsdh.recv_bufs; <= m_pSdpSocket->m_SendBufferPool.SetRemoteRecvBuf(rRecvBuf);\r
+//??? pNewSocket->recv_seq = msg_hello->bsdh.seq_num;\r
+//??? pNewSocket->advt_seq = msg_hello->bsdh.seq_num;\r
+\r
+ /*\r
+ * The maximum amount of data that can be sent to the remote\r
+ * peer is the smaller of the local and remote buffer sizes,\r
+ * minus the size of the message header.\r
+ */\r
+// conn->send_size = min((u16)sdp_buff_pool_buff_size(),\r
+// (u16)conn->send_size) - SDP_MSG_HDR_SIZE; ??????????\r
+\r
+ // We will now allocate our QP.\r
+\r
+ rc = g_pSdpDriver->m_pSdpArp->SourcePortGidFromIP(pNewSocket->m_SrcIp, &SrcPortGuid, &SrcCaGuid);\r
+ if (!NT_SUCCESS(rc)) {\r
+ SDP_PRINT(SDP_ERR, SDP_SOCKET, ("m_pSdpArp->SourcePortGidFromIP failed rc = 0x%x\n", rc ));\r
+ goto ErrorLocked;\r
+ } \r
+\r
+ if (pNewSocket->m_SrcCaGuid == 0) {\r
+ pNewSocket->m_SrcCaGuid = SrcCaGuid;\r
+ } else {\r
+ ASSERT(pNewSocket->m_SrcCaGuid == CL_NTOH64(p_cm_req_rec->primary_path.sgid.unicast.interface_id));\r
+ }\r
+ \r
+ // MAke sure that the port that was recieved muches the one that we\r
+ // get based on the source IP.\r
+ if (SrcPortGuid != p_cm_req_rec->primary_path.sgid.unicast.interface_id) {\r
+ SDP_PRINT(SDP_ERR, SDP_SOCKET, ("Recieved guid is not what we have expected\n" )); \r
+ ASSERT(0);\r
+ goto ErrorLocked;\r
+ }\r
+\r
+ rc = pNewSocket->CreateQp();\r
+ if (!NT_SUCCESS(rc)) {\r
+ SDP_PRINT(SDP_ERR, SDP_SOCKET, ("pNewSocket.CreateQp() failed rc = 0x%x\n", rc ));\r
+ goto ErrorLocked;\r
+ }\r
+\r
+ // We will now call init on the sender and the reciever\r
+ int MaxMessageSize = min(msg_hello->hh.l_rcv_size, MAX_SEND_BUFFER_SIZE);\r
+\r
+ rc = pNewSocket->m_SendBufferPool.Init(MAX_SEND_PACKETS, QP_ATTRIB_SQ_DEPTH, MaxMessageSize, pNewSocket->m_pd, pNewSocket->m_qp, pNewSocket->m_lkey, pNewSocket);\r
+ if (!NT_SUCCESS(rc)) {\r
+ SDP_PRINT(SDP_ERR, SDP_SOCKET, ("m_SendBufferPool.Init failed rc = 0x%x\n", rc ));\r
+ goto ErrorLocked;\r
+ }\r
+\r
+ rc = pNewSocket->m_RecvBufferPool.Init(MAX_RECV_PACKETS, QP_ATTRIB_RQ_DEPTH, MaxMessageSize, pNewSocket->m_pd, pNewSocket->m_qp, pNewSocket->m_lkey, pNewSocket);\r
+ if (!NT_SUCCESS(rc)) {\r
+ SDP_PRINT(SDP_ERR, SDP_SOCKET, ("m_RecvBufferPool.Init failed rc = 0x%x\n", rc ));\r
+ goto ErrorLocked;\r
+ }\r
+ pNewSocket->m_SendBufferPool.SetRemoteRecvBuf(msg_hello->bsdh.recv_bufs);\r
+\r
+ // It won't be used, but I want to make sure that there won't be\r
+ // problems later\r
+ pNewSocket->m_ConnectionList.Init(pNewSocket);\r
+\r
+#if 0 // ???????????????????????\r
+ /*\r
+ * Save connect request info for QP modify in cm_accept().\r
+ */\r
+ conn->d_lid = event->param.req_rcvd.primary_path->dlid;\r
+ conn->s_lid = event->param.req_rcvd.primary_path->slid;\r
+ conn->d_qpn = event->param.req_rcvd.remote_qpn;\r
+\r
+ conn->path_mtu = event->param.req_rcvd.primary_path->mtu;\r
+ /*\r
+ * inherit listener properties\r
+ */\r
+ sdp_cm_listen_inherit(listen_conn, conn);\r
+ /*\r
+ * initiate a CM response message.\r
+ */\r
+#endif \r
+\r
+ //\r
+ // Send the ib_cm_rep message to the remote side\r
+ //\r
+ ib_cm_rep_t cm_rep;\r
+\r
+ memset( &cm_rep, 0, sizeof(cm_rep) );\r
+\r
+ cm_rep.qp_type = IB_QPT_RELIABLE_CONN;\r
+ cm_rep.h_qp = pNewSocket->m_qp;\r
+// TODO: Add more cababilities once we start using RDMA\r
+// cm_rep.access_ctrl = IB_AC_RDMA_READ | IB_AC_RDMA_WRITE | IB_AC_LOCAL_WRITE;\r
+ cm_rep.access_ctrl = IB_AC_LOCAL_WRITE;\r
+#if 0\r
+ // Bug in TAVOR\r
+ cm_rep.sq_depth = QP_ATTRIB_SQ_DEPTH;\r
+ cm_rep.rq_depth = QP_ATTRIB_RQ_DEPTH;\r
+#endif\r
+ // We need to prepare the hello mesage for the CM\r
+ sdp_msg_hello_ack hello_ack_msg;\r
+ CreateHelloAckHeader(&hello_ack_msg);\r
+\r
+ cm_rep.p_rep_pdata = (uint8_t *) &hello_ack_msg;\r
+ cm_rep.rep_length = sizeof(hello_ack_msg);\r
+\r
+ cm_rep.init_depth = QP_ATTRIB_INITIATOR_DEPTH;\r
+ cm_rep.target_ack_delay = 10;\r
+ cm_rep.failover_accepted = IB_FAILOVER_ACCEPT_UNSUPPORTED;\r
+ cm_rep.flow_ctrl = p_cm_req_rec->flow_ctrl;\r
+ cm_rep.rnr_nak_timeout = QP_ATTRIB_RNR_NAK_TIMEOUT;\r
+ cm_rep.rnr_retry_cnt = p_cm_req_rec->rnr_retry_cnt;\r
+ cm_rep.pfn_cm_mra_cb = cm_mra_callback;\r
+ cm_rep.pfn_cm_rej_cb = cm_rej_callback;\r
+ cm_rep.pfn_cm_rtu_cb = cm_rtu_callback;\r
+ cm_rep.pfn_cm_lap_cb = cm_lap_callback;\r
+ cm_rep.pfn_cm_dreq_cb = cm_dreq_callback;\r
+\r
+ ib_status = ib_cm_rep( p_cm_req_rec->h_cm_req, &cm_rep );\r
+ if( ib_status != IB_SUCCESS ) {\r
+ SDP_PRINT(SDP_ERR, SDP_SOCKET, ("ib_cm_rep failed ib_status = 0x%d\n", ib_status ));\r
+ rc = IB2Status(ib_status);\r
+ goto Cleanup;\r
+ }\r
+\r
+ // Add this socket to the list of sockets ?????? should this also be done on errors ????\r
+ rc = m_ConnectionList.AddConnectionToReplySent(pNewSocket);\r
+ if (!NT_SUCCESS(rc)) {\r
+ SDP_PRINT(SDP_ERR, SDP_SOCKET, ("pNewSocket.Init() failed rc = 0x%x\n", rc ));\r
+ goto ErrorLocked;\r
+ }\r
+\r
+ rc = pNewSocket->m_Lock.Lock();\r
+ if (!NT_SUCCESS(rc)) {\r
+ SDP_PRINT(SDP_ERR, SDP_SOCKET, ("pNewSocket.Init() failed rc = 0x%x\n", rc ));\r
+ goto ErrorLocked;\r
+ } \r
+\r
+ rc = pNewSocket->m_RecvBufferPool.ReceiveIfCan();\r
+ if (!NT_SUCCESS(rc)) {\r
+ SDP_PRINT(SDP_ERR, SDP_SOCKET, ("pNewSocket.Init() failed rc = 0x%x\n", rc ));\r
+ pNewSocket->m_Lock.Unlock(); // Error is ignored, since this is already an error path\r
+ goto ErrorLocked;\r
+ }\r
+\r
+ // we now arm the CQs (after that a call back might happen)\r
+ ib_status = ib_rearm_cq(pNewSocket->m_rcq, FALSE);\r
+ if( ib_status != IB_SUCCESS ) {\r
+ SDP_PRINT(SDP_ERR, SDP_SOCKET, ("ib_rearm_cq failed ib_status = 0x%d\n", ib_status ));\r
+ rc = IB2Status(ib_status);\r
+ pNewSocket->m_Lock.Unlock(); // Error is ignored, since this is already an error path\r
+ goto ErrorLocked;\r
+ }\r
+\r
+ ib_status = ib_rearm_cq(pNewSocket->m_scq, FALSE);\r
+ if( ib_status != IB_SUCCESS ) {\r
+ SDP_PRINT(SDP_ERR, SDP_SOCKET, ("ib_rearm_cq failed ib_status = 0x%d\n", ib_status ));\r
+ rc = IB2Status(ib_status);\r
+ pNewSocket->m_Lock.Unlock(); // Error is ignored, since this is already an error path\r
+ goto ErrorLocked;\r
+ }\r
+ \r
+ // Sucess - we can now release the lock and update our state\r
+ pNewSocket->m_state = SS_REP_SENT;\r
+\r
+ rc = pNewSocket->m_Lock.Unlock(); // Error is ignored, since this is already an error path\r
+ if (!NT_SUCCESS(rc)) {\r
+ SDP_PRINT(SDP_ERR, SDP_SOCKET, ("pNewSocket->m_Lock.Unlock() failed rc = 0x%x\n", rc ));\r
+ // BUGBUG: who is responsibale for the cleanup ???????\r
+ goto ErrorLocked;\r
+ } \r
+ \r
+ rc = m_Lock.Unlock();\r
+ if (!NT_SUCCESS(rc)) {\r
+ SDP_PRINT(SDP_ERR, SDP_SOCKET, ("m_Lock.Unlock() failed rc = 0x%x\n", rc ));\r
+ // BUGBUG: who is responsibale for the cleanup ???????\r
+ } \r
+\r
+Cleanup:\r
+ if (pNewSocket != NULL) {\r
+ pNewSocket->Release();\r
+ }\r
+ return;\r
+\r
+ErrorLocked:\r
+ // Previous rc doesn't mater as this function is void\r
+ rc = m_Lock.Unlock();\r
+ if (!NT_SUCCESS(rc)) {\r
+ SDP_PRINT(SDP_ERR, SDP_SOCKET, ("m_Lock.Unlock() failed rc = 0x%x\n", rc ));\r
+ // BUGBUG: who is responsibale for the cleanup ???????\r
+ }\r
+ goto Cleanup; \r
+\r
+}\r
+\r
+VOID \r
+SdpSocket::CmRtuCallback(IN ib_cm_rtu_rec_t *p_cm_rtu_rec)\r
+{\r
+ SDP_PRINT(SDP_TRACE, SDP_SOCKET, ("this = 0x%x\n", this));\r
+ NTSTATUS rc = STATUS_SUCCESS;\r
+ ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL);\r
+\r
+ SdpSocket *pSocket = (SdpSocket *) p_cm_rtu_rec->qp_context;\r
+ // In order to make our model more consistent we increase the refcount here.\r
+ // (This is not a must since this is a callback and we are gurantied that the last\r
+ // callback won't happen untill we free IBAL)\r
+ pSocket->AddRef();\r
+\r
+\r
+ // Take the lock and verify the state\r
+ rc = m_Lock.Lock();\r
+ if (!NT_SUCCESS(rc)) {\r
+ SDP_PRINT(SDP_ERR, SDP_SOCKET, ("m_Lock.Lock failed rc = 0x%x\n", rc ));\r
+ goto Cleanup;\r
+ }\r
+\r
+ if (m_state != SS_LISTENING) {\r
+ // This is not the state that we waited for, we drop the request\r
+ SDP_PRINT(SDP_ERR, SDP_SOCKET, ("Not the expacted state %s\n", SS2String(m_state)));\r
+ ASSERT(FALSE); // Can this happen on shutdown ?\r
+ goto ErrorLocked;\r
+ }\r
+ \r
+ // First step is to verify that we have the new socket\r
+ rc = m_ConnectionList.VerifyConnictionInReplySent(pSocket);\r
+ if (!NT_SUCCESS(rc)) {\r
+ SDP_PRINT(SDP_ERR, SDP_SOCKET, ("m_ConnectionList.GetConnection failed (got a call back on a not existing connection) rc = 0x%x\n", rc ));\r
+ ASSERT(FALSE);\r
+ goto ErrorLocked;\r
+ }\r
+\r
+ // Next step is to move the new socket to the SS_CONNECTED state\r
+ rc = pSocket->m_Lock.Lock();\r
+ if (!NT_SUCCESS(rc)) {\r
+ SDP_PRINT(SDP_ERR, SDP_SOCKET, ("m_Lock.Lock failed rc = 0x%x\n", rc ));\r
+ goto ErrorLocked;\r
+ }\r
+ if (pSocket->m_state != SS_REP_SENT) {\r
+ ASSERT(pSocket->m_state == SS_REP_SENT);\r
+ // This is not the expected state (probably shutdown).\r
+ // we should signal an error also on the one that is waiting\r
+ pSocket->m_Lock.Unlock(); // Error is ignored since this is already\r
+ // an error path\r
+ pSocket->Shutdown(); \r
+ rc = STATUS_UNEXPECTED_IO_ERROR;\r
+ goto ErrorLocked;\r
+ }\r
+\r
+ pSocket->m_state = SS_CONNECTED;\r
+\r
+ m_ConnectionList.MoveConnectionFromReplyToReady(pSocket);\r
+ rc = pSocket->m_Lock.Unlock();\r
+ if (!NT_SUCCESS(rc)) {\r
+ SDP_PRINT(SDP_ERR, SDP_SOCKET, ("pSocket->m_Lock.Lock failed rc = 0x%x\n", rc ));\r
+ goto ErrorLocked;\r
+ }\r
+\r
+ // if needed we will free the one that is waiting\r
+ m_ConnectionList.FreeWaitingIfCan();\r
+ rc = m_Lock.Unlock();\r
+ if (!NT_SUCCESS(rc)) {\r
+ SDP_PRINT(SDP_ERR, SDP_SOCKET, ("m_Lock.Lock failed rc = 0x%x\n", rc ));\r
+ goto Cleanup;\r
+ }\r
+ \r
+Cleanup:\r
+\r
+ if (pSocket != NULL) {\r
+ pSocket->Release();\r
+ }\r
+ \r
+ // Who should take care of the errors that were found here (if found)????????\r
+ return;\r
+\r
+ErrorLocked:\r
+ // Previous rc doesn't mater as this function is void\r
+ rc = m_Lock.Unlock();\r
+ if (!NT_SUCCESS(rc)) {\r
+ SDP_PRINT(SDP_ERR, SDP_SOCKET, ("m_Lock.Unlock() failed rc = 0x%x\n", rc ));\r
+ // BUGBUG: who is responsibale for the cleanup ???????\r
+ }\r
+ goto Cleanup; \r
+\r
+}\r
+\r
\r
VOID\r
SdpSocket::__recv_cb1(\r
net32_t rkey;\r
\r
\r
- SDP_PRINT(SDP_TRACE, SDP_SOCKET, ("CreateQp called this = 0x%p\n", this));\r
+ SDP_PRINT(SDP_TRACE, SDP_SOCKET, ("this = 0x%p\n", this));\r
+ ASSERT(m_SrcCaGuid != 0);\r
/* Open the CA. */\r
ib_status = ib_open_ca(\r
g_pSdpDriver->m_al_handle, \r
- m_CaGuid,\r
+ m_SrcCaGuid,\r
NULL, \r
this, \r
&mh_Ca \r
\r
)\r
{\r
- SDP_PRINT(SDP_TRACE, SDP_SOCKET, ("SdpSocket::CreateHelloHeader called this = 0x%p\n", this));\r
+ SDP_PRINT(SDP_TRACE, SDP_SOCKET, ("this = 0x%p\n", this));\r
ASSERT(DestIp != 0);\r
ASSERT(m_SrcPort != 0);\r
ASSERT(m_SrcIp != 0);\r
sdp_msg_swap_bsdh(&hello_msg->bsdh);\r
sdp_msg_swap_hh(&hello_msg->hh);\r
\r
+}\r
+\r
+VOID SdpSocket::CreateHelloAckHeader(\r
+ sdp_msg_hello_ack* hello_ack_msg\r
+ )\r
+{\r
+ SDP_PRINT(SDP_TRACE, SDP_SOCKET, ("called this = 0x%p\n", this));\r
+\r
+ memset(hello_ack_msg, 0, sizeof(struct sdp_msg_hello_ack));\r
+ hello_ack_msg->bsdh.recv_bufs = QP_ATTRIB_RQ_DEPTH; //????conn->l_advt_bf;\r
+ hello_ack_msg->bsdh.flags = SDP_MSG_FLAG_NON_FLAG;\r
+ hello_ack_msg->bsdh.mid = SDP_MID_HELLO_ACK;\r
+ hello_ack_msg->bsdh.size = sizeof(struct sdp_msg_hello_ack);\r
+ hello_ack_msg->bsdh.seq_num = m_SendBufferPool.GetAndIncreaseSendSeq();//conn->send_seq; ???\r
+ hello_ack_msg->bsdh.seq_ack = m_RecvBufferPool.GetRecvSeq();//conn->advt_seq; ???\r
+\r
+ hello_ack_msg->hah.max_adv = QP_ATTRIB_RQ_DEPTH;// ??? conn->l_max_adv;\r
+ hello_ack_msg->hah.version = SDP_MSG_VERSION;\r
+ hello_ack_msg->hah.l_rcv_size = 4096;//???conn->recv_size;\r
+\r
+ /*\r
+ * endian swap\r
+ */\r
+ sdp_msg_swap_bsdh(&hello_ack_msg->bsdh);\r
+ sdp_msg_swap_hah(&hello_ack_msg->hah);\r
+\r
\r
}\r
\r
+\r
VOID SdpSocket::CreateCmRequest(\r
ib_cm_req_t *cm_req,\r
sdp_msg_hello *hello_msg,\r
\r
m_Lock.SignalShutdown();\r
\r
+ if (m_ListenHandle != NULL) {\r
+ ib_status = ib_cm_cancel( m_ListenHandle, ShutdownCB );\r
+ if( ib_status != IB_SUCCESS ) {\r
+ SDP_PRINT(SDP_ERR, SDP_SOCKET, ("ib_cm_cancel failed ib_status = 0x%d\n", ib_status ));\r
+ rc = IB2Status(ib_status);\r
+ } else {\r
+ WaitForShutdownEvent(&m_ShutdownCompleteEvent);\r
+ m_ListenHandle = NULL;\r
+ }\r
+ }\r
+\r
+ m_ConnectionList.Shutdown();\r
+ \r
+\r
if (m_qp != NULL) {\r
ib_status = ib_destroy_qp(m_qp, ShutdownCB);\r
ASSERT(ib_status == IB_SUCCESS);\r
mh_Ca = NULL;\r
WaitForShutdownEvent(&m_ShutdownCompleteEvent);\r
}\r
+\r
+ if (m_pListeningSocket != NULL) {\r
+ m_pListeningSocket->Release();\r
+ m_pListeningSocket = NULL;\r
+ }\r
\r
\r
// Now that all ibal operations have finished we can free the memory\r
* endian swap\r
*/\r
sdp_msg_swap_bsdh(&hello_ack->bsdh);\r
- sdp_msg_net_to_cpu_hah(&hello_ack->hah);\r
+ sdp_msg_swap_hah(&hello_ack->hah);\r
/*\r
* validation and consistency checks\r
*/\r
return STATUS_SUCCESS;\r
}\r
\r
+NTSTATUS sdp_cm_hello_check(struct sdp_msg_hello *msg_hello)\r
+{\r
+ /*\r
+ * endian swap\r
+ */\r
+ sdp_msg_swap_bsdh(&msg_hello->bsdh);\r
+ sdp_msg_swap_hh(&msg_hello->hh);\r
+ /*\r
+ * validation and consistency checks\r
+ */\r
+ \r
+ if (msg_hello->bsdh.size != sizeof(struct sdp_msg_hello)) {\r
+ SDP_PRINT(SDP_WARN, SDP_SOCKET,( "hello msg size mismatch. (2) <%d:%Zu>",\r
+ msg_hello->bsdh.size,\r
+ sizeof(struct sdp_msg_hello)));\r
+ return STATUS_UNEXPECTED_IO_ERROR;\r
+ }\r
+\r
+ if (SDP_MID_HELLO != msg_hello->bsdh.mid) {\r
+ SDP_PRINT(SDP_WARN, SDP_SOCKET,("hello msg unexpected ID. <%d>",\r
+ msg_hello->bsdh.mid));\r
+ return STATUS_UNEXPECTED_IO_ERROR;\r
+ }\r
\r
+ if (msg_hello->hh.max_adv <= 0) {\r
+ SDP_PRINT(SDP_WARN, SDP_SOCKET,("hello msg, bad zcopy count <%d>",\r
+ msg_hello->hh.max_adv));\r
+ return STATUS_UNEXPECTED_IO_ERROR;\r
+ }\r
+\r
+ if ((0xF0 & msg_hello->hh.version) != (0xF0 & SDP_MSG_VERSION)) {\r
+ SDP_PRINT(SDP_WARN, SDP_SOCKET,("hello msg, version mismatch. <%d:%d>",\r
+ ((0xF0 & msg_hello->hh.version) >> 4),\r
+ ((0xF0 & SDP_MSG_VERSION) >> 4)));\r
+ return STATUS_UNEXPECTED_IO_ERROR;\r
+ }\r
+#ifdef _SDP_MS_APRIL_ERROR_COMPAT\r
+ if ((SDP_MSG_IPVER & 0x0F) != (msg_hello->hh.ip_ver & 0x0F)) \r
+#else\r
+ if ((SDP_MSG_IPVER & 0xF0) != (msg_hello->hh.ip_ver & 0xF0)) {\r
+#endif\r
+ SDP_PRINT(SDP_WARN, SDP_SOCKET,( "hello msg, ip version mismatch. <%d:%d>",\r
+ msg_hello->hh.ip_ver, SDP_MSG_IPVER));\r
+ return STATUS_UNEXPECTED_IO_ERROR;\r
+ }\r
+\r
+ SDP_PRINT(SDP_TRACE, SDP_SOCKET,("Hello BSDH <%04x:%02x:%02x:%08x:%08x:%08x>",\r
+ msg_hello->bsdh.recv_bufs,\r
+ msg_hello->bsdh.flags,\r
+ msg_hello->bsdh.mid,\r
+ msg_hello->bsdh.size,\r
+ msg_hello->bsdh.seq_num,\r
+ msg_hello->bsdh.seq_ack));\r
+ SDP_PRINT(SDP_TRACE, SDP_SOCKET,(\r
+ "Hello HH <%02x:%02x:%02x:%08x:%08x:%04x:%08x:%08x>",\r
+ msg_hello->hh.max_adv,\r
+ msg_hello->hh.ip_ver,\r
+ msg_hello->hh.version,\r
+ msg_hello->hh.r_rcv_size,\r
+ msg_hello->hh.l_rcv_size,\r
+ msg_hello->hh.port,\r
+ msg_hello->hh.src.ipv4.addr,\r
+ msg_hello->hh.dst.ipv4.addr));\r
+\r
+ return STATUS_SUCCESS;\r
+}\r
\r