From: tzachid Date: Mon, 21 Nov 2005 12:31:12 +0000 (+0000) Subject: merge from branch (rev-652) X-Git-Url: https://openfabrics.org/gitweb/?a=commitdiff_plain;h=c2de50c2bbe07c66b6ee9148afcf9e94318b3c3f;p=~shefty%2Frdma-win.git merge from branch (rev-652) Added GetSockName and GetPeerName. Usermode API's are printed in DEBUG. Fix a BUG in multiple connect. Fix a leak of buffers. (Rev 700) git-svn-id: svn://openib.tc.cornell.edu/gen1@182 ad392aa1-c5ef-ae45-8dd8-e69d62a5ef86 --- diff --git a/trunk/ulp/sdp/include/SdpShared.h b/trunk/ulp/sdp/include/SdpShared.h index 36215b55..85c04479 100644 --- a/trunk/ulp/sdp/include/SdpShared.h +++ b/trunk/ulp/sdp/include/SdpShared.h @@ -18,7 +18,8 @@ #define IOCTL_WSP_BIND CTL_CODE(FILE_DEVICE_UNKNOWN, 0x805, METHOD_BUFFERED ,FILE_ANY_ACCESS) #define IOCTL_WSP_LISTEN CTL_CODE(FILE_DEVICE_UNKNOWN, 0x806, METHOD_BUFFERED ,FILE_ANY_ACCESS) #define IOCTL_WSP_ACCEPT CTL_CODE(FILE_DEVICE_UNKNOWN, 0x807, METHOD_BUFFERED ,FILE_ANY_ACCESS) -#define IOCTL_WSP_CLOSE_SOCKET CTL_CODE(FILE_DEVICE_UNKNOWN, 0x808, METHOD_BUFFERED ,FILE_ANY_ACCESS) +#define IOCTL_WSP_GET_XXX_NAME CTL_CODE(FILE_DEVICE_UNKNOWN, 0x808, METHOD_BUFFERED ,FILE_ANY_ACCESS) +#define IOCTL_WSP_CLOSE_SOCKET CTL_CODE(FILE_DEVICE_UNKNOWN, 0x809, METHOD_BUFFERED ,FILE_ANY_ACCESS) // Data structures that are used for connect @@ -101,6 +102,17 @@ struct WspAcceptOut { USHORT Port; }; +struct WspGetSockXXIn { + VOID *pSocket; + bool LocaleAddress; // Tells if this is used as GetSockName or GetPeerName +}; + +struct WspGetSockXXOut { + int Errno; + ULONG IP; + USHORT Port; +}; + struct WspSocketCloseIn { VOID *pSocket; }; diff --git a/trunk/ulp/sdp/kernel/SdpArp.h b/trunk/ulp/sdp/kernel/SdpArp.h index 6737b867..4b59ca8b 100644 --- a/trunk/ulp/sdp/kernel/SdpArp.h +++ b/trunk/ulp/sdp/kernel/SdpArp.h @@ -33,10 +33,9 @@ public: OUT USHORT *SrcPort ) { - ASSERT(SourceAddr != 0); // If the port is 0, choose your own free port. // If the port is not 0 check if this port is already in use - *SrcPort = 5050; + *SrcPort = 5050; // BUGBUG: Complete this mechanism return STATUS_SUCCESS; } diff --git a/trunk/ulp/sdp/kernel/SdpConnectionList.cpp b/trunk/ulp/sdp/kernel/SdpConnectionList.cpp index a56c714a..e6284bc4 100644 --- a/trunk/ulp/sdp/kernel/SdpConnectionList.cpp +++ b/trunk/ulp/sdp/kernel/SdpConnectionList.cpp @@ -90,12 +90,13 @@ ConnectionList::VerifyConnictionInReplySent(SdpSocket *pNewSocket) SdpSocket *pSocket = NULL; #if DBG LIST_ENTRY *item = m_ReplySentConnections.Head(); - while (item->Flink != m_ReplySentConnections.Head()) { + for (int i = 0 ; i < m_ReplySentConnections.Size(); i++) { pSocket = CONTAINING_RECORD(item, SdpSocket , m_ListeningSocketList); if (pSocket == pNewSocket) { // We have found what we were looking for return STATUS_SUCCESS; } + item = item->Flink; } // Not found, return error ASSERT(FALSE); diff --git a/trunk/ulp/sdp/kernel/SdpDriver.cpp b/trunk/ulp/sdp/kernel/SdpDriver.cpp index 207c760f..25b179ea 100644 --- a/trunk/ulp/sdp/kernel/SdpDriver.cpp +++ b/trunk/ulp/sdp/kernel/SdpDriver.cpp @@ -525,7 +525,7 @@ SdpDriver::DispatchDeviceIoControl( } rc = pSdpSocket->WSPListen(&wspListenIn, pWspListenOut); if (!NT_SUCCESS(rc)) { - SDP_PRINT(SDP_ERR, SDP_DRIVER, ("pSdpSocket->WSPRecv failed rc = 0x%x\n", rc )); + SDP_PRINT(SDP_ERR, SDP_DRIVER, ("pSdpSocket->WSPListen failed rc = 0x%x\n", rc )); goto Cleanup; } } @@ -566,6 +566,32 @@ SdpDriver::DispatchDeviceIoControl( } break; + case IOCTL_WSP_GET_XXX_NAME: + { + SDP_PRINT(SDP_TRACE, SDP_DRIVER, ("IOCTL_WSP_GET_XXX_NAME recieved\n" )); + VERIFY_BUFFERS(InputBufferLength, OutputBufferLength, WspGetSockXXIn, WspGetSockXXOut); + OutputDataSize = sizeof (WspGetSockXXOut); + + // get the socket based on the users pointer + WspGetSockXXIn wspGetSockXXin = *(WspGetSockXXIn *) pInputBuffer; + WspGetSockXXOut *pWspGetSockXXOut = (WspGetSockXXOut *) pOutputBuffer; + pSdpUserFile = (SdpUserFile *)pIrpSp->FileObject->FsContext; + pSdpSocket = pSdpUserFile->SocketByPointer(wspGetSockXXin.pSocket); + if (pSdpSocket == NULL) { + SDP_PRINT(SDP_DEBUG, SDP_DRIVER, ("IOCTL_WSP_GET_XXX_NAME socket %x not found\n", wspGetSockXXin.pSocket)); + // This is a well defined winsock error + pWspGetSockXXOut->Errno = WSAENOTSOCK; + goto Cleanup; + } + rc = pSdpSocket->WSPGetXXXName(&wspGetSockXXin, pWspGetSockXXOut); + if (!NT_SUCCESS(rc)) { + SDP_PRINT(SDP_ERR, SDP_DRIVER, ("pSdpSocket->WSPGetXXXName failed rc = 0x%x\n", rc )); + goto Cleanup; + } + } + break; + + case IOCTL_WSP_CLOSE_SOCKET : { SDP_PRINT(SDP_TRACE, SDP_DRIVER, ("IOCTL_WSP_CLOSE_SOCKET recieved\n" )); diff --git a/trunk/ulp/sdp/kernel/SdpGenUtils.h b/trunk/ulp/sdp/kernel/SdpGenUtils.h index 53356d1f..8f55e1ec 100644 --- a/trunk/ulp/sdp/kernel/SdpGenUtils.h +++ b/trunk/ulp/sdp/kernel/SdpGenUtils.h @@ -6,6 +6,7 @@ #define GLOBAL_ALLOCATION_TAG ' pdS' #define SEND_BUFFERS_ALLOCATION_TAG 'SpdS' +#define RECV_BUFFERS_ALLOCATION_TAG 'RpdS' class CSpinLockWrapper { diff --git a/trunk/ulp/sdp/kernel/SdpLock.h b/trunk/ulp/sdp/kernel/SdpLock.h index af447de8..82d27b51 100644 --- a/trunk/ulp/sdp/kernel/SdpLock.h +++ b/trunk/ulp/sdp/kernel/SdpLock.h @@ -152,6 +152,12 @@ Cleanup: return Locked; } + // This is the first stage in moving the lock to return rc (and later void) + NTSTATUS LockRc() { + if (Lock()) return STATUS_SUCCESS; + return STATUS_SHUTDOWN_IN_PROGRESS; + } + /* Frees the lock and handle any events that might happen there. Please note that the lock is freed no metter what the error code is. @@ -169,6 +175,7 @@ Cleanup: ASSERT(m_InUse); ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL); KeAcquireSpinLock(&m_SpinLock, &OldIrql); + ASSERT(m_InUse); // Also with the lock taken OldFlags = m_flags; ResetFlags(m_flags); if (!SomethingToHandle(OldFlags)) { diff --git a/trunk/ulp/sdp/kernel/SdpRecvPool.cpp b/trunk/ulp/sdp/kernel/SdpRecvPool.cpp index eafa0a3d..a51eb955 100644 --- a/trunk/ulp/sdp/kernel/SdpRecvPool.cpp +++ b/trunk/ulp/sdp/kernel/SdpRecvPool.cpp @@ -44,15 +44,29 @@ RecvPool::Init( NTSTATUS rc = STATUS_SUCCESS; for (int i=0;i < MAX_RECV_PACKETS; i++) { - rc = BufferDescriptor::AllocateBuffer(&pBufferDescriptor, m_MaxMessageSize, SEND_BUFFERS_ALLOCATION_TAG); - ASSERT(NT_SUCCESS(rc)); + rc = BufferDescriptor::AllocateBuffer(&pBufferDescriptor, m_MaxMessageSize, RECV_BUFFERS_ALLOCATION_TAG); + if (!NT_SUCCESS(rc)) { + SDP_PRINT(SDP_ERR, SDP_BUFFER_POOL, ("BufferDescriptor::AllocateBuffer failed rc=0x%x \n", rc)); + goto Cleanup; + } + m_CurrentlyAllocated++; pBufferDescriptor->Reset(); m_FreePackets.InsertTailList(&pBufferDescriptor->BuffersList); } - - return STATUS_SUCCESS; +Cleanup: + if (!NT_SUCCESS(rc)) { + LIST_ENTRY *item = NULL; + while (m_FreePackets.Size() > 0 ) { + item = m_FreePackets.RemoveHeadList(); + pBufferDescriptor = CONTAINING_RECORD(item, BufferDescriptor , BuffersList); + BufferDescriptor::DeAllocateBuffer(pBufferDescriptor, RECV_BUFFERS_ALLOCATION_TAG); + } + + } + + return rc; } /* @@ -301,7 +315,7 @@ RecvPool::ReceiveIfCan() pBufferDescriptor = CONTAINING_RECORD(item, BufferDescriptor , BuffersList); } else if (m_CurrentlyAllocated < m_MaxBuffers) { // We can allocate more buffers - rc = BufferDescriptor::AllocateBuffer(&pBufferDescriptor, m_MaxMessageSize, SEND_BUFFERS_ALLOCATION_TAG); + rc = BufferDescriptor::AllocateBuffer(&pBufferDescriptor, m_MaxMessageSize, RECV_BUFFERS_ALLOCATION_TAG); if (!NT_SUCCESS(rc)) { SDP_PRINT(SDP_ERR, SDP_BUFFER_POOL, ("AllocateBuffer failed rc = 0x%x\n", rc )); goto Cleanup; @@ -352,13 +366,13 @@ RecvPool::ShutDown() while (m_FreePackets.Size() > 0 ) { item = m_FreePackets.RemoveHeadList(); pBufferDescriptor = CONTAINING_RECORD(item, BufferDescriptor , BuffersList); - BufferDescriptor::DeAllocateBuffer(pBufferDescriptor, SEND_BUFFERS_ALLOCATION_TAG); + BufferDescriptor::DeAllocateBuffer(pBufferDescriptor, RECV_BUFFERS_ALLOCATION_TAG); } while (m_FullPackets.Size() > 0 ) { item = m_FullPackets.RemoveHeadList(); pBufferDescriptor = CONTAINING_RECORD(item, BufferDescriptor , BuffersList); - BufferDescriptor::DeAllocateBuffer(pBufferDescriptor, SEND_BUFFERS_ALLOCATION_TAG); + BufferDescriptor::DeAllocateBuffer(pBufferDescriptor, RECV_BUFFERS_ALLOCATION_TAG); } } diff --git a/trunk/ulp/sdp/kernel/SdpSocket.cpp b/trunk/ulp/sdp/kernel/SdpSocket.cpp index 0c373d0f..54a7d742 100644 --- a/trunk/ulp/sdp/kernel/SdpSocket.cpp +++ b/trunk/ulp/sdp/kernel/SdpSocket.cpp @@ -303,6 +303,7 @@ Cleanup: } else { // Make sure that we have the error setted ASSERT(pWspSendOut->Errno != 0); // BUGBUG: Need to make sure that this + SDP_PRINT(SDP_WARN, SDP_SOCKET, ("this = 0x%p rc = 0x%x\n",this, rc)); // is indeed the case. } return rc; @@ -941,6 +942,54 @@ Cleanup: return rc; } +NTSTATUS +SdpSocket::WSPGetXXXName( + WspGetSockXXIn *pWspGetSockXXIn, + WspGetSockXXOut *pWspGetSockXXOut + ) +{ + NTSTATUS rc = STATUS_SUCCESS; + ib_api_status_t ib_status; + + SDP_PRINT(SDP_TRACE, SDP_SOCKET, ("this = 0x%p \n",this)); + rc = m_Lock.LockRc(); + if (!NT_SUCCESS(rc)) { + SDP_PRINT(SDP_ERR, SDP_SOCKET, ("Failed to lock this = 0x%p \n",this)); + pWspGetSockXXOut->Errno = WSAENETDOWN; + goto Cleanup; + } + pWspGetSockXXOut->Errno = 0; + if(pWspGetSockXXIn->LocaleAddress) { + // This is the WSPGetSockName + pWspGetSockXXOut->IP = m_SrcIp; + pWspGetSockXXOut->Port = m_SrcPort; + } else { + // This is the WSPGetPeerName + pWspGetSockXXOut->IP = m_DstIp; + pWspGetSockXXOut->Port = m_DstPort; + } + rc = m_Lock.Unlock(); + if (!NT_SUCCESS(rc)) { + SDP_PRINT(SDP_ERR, SDP_SOCKET, ("m_Lock.Unlock() failed rc = 0x%x\n", rc )); + pWspGetSockXXOut->Errno = WSAENETDOWN; + goto Cleanup; + } + +Cleanup: + if (NT_SUCCESS(rc) ) { + pWspGetSockXXOut->Errno = 0; + } else { + // Make sure that we have the error setted + ASSERT(pWspGetSockXXOut->Errno != 0); + // is indeed the case. + } + return rc; + + +} + + + /* CloseSocket is probably one of the most complicated winsock APIs. Our current implmentation will be the default implmentation always. @@ -1260,7 +1309,7 @@ NTSTATUS SdpSocket::CmSendRTU() // We now start the recieve processing - rc = m_Lock.Lock(); //?????????? + rc = m_Lock.LockRc(); if (!NT_SUCCESS(rc)) { SDP_PRINT(SDP_ERR, SDP_SOCKET, ("m_Lock.Lock failed rc = 0x%x\n", rc )); goto Cleanup; @@ -1303,6 +1352,7 @@ VOID SdpSocket::CmReqCallback(IN ib_cm_req_rec_t *p_cm_req_rec) { SDP_PRINT(SDP_TRACE, SDP_SOCKET, ("this = 0x%p\n", this)); + NTSTATUS rc = STATUS_SUCCESS; ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL); net64_t SrcCaGuid; @@ -1319,7 +1369,7 @@ SdpSocket::CmReqCallback(IN ib_cm_req_rec_t *p_cm_req_rec) } // Take the lock and verify the state - rc = m_Lock.Lock(); //??????? + rc = m_Lock.LockRc(); if (!NT_SUCCESS(rc)) { SDP_PRINT(SDP_ERR, SDP_SOCKET, ("m_Lock.Lock failed rc = 0x%x\n", rc )); goto Cleanup; @@ -1341,7 +1391,7 @@ SdpSocket::CmReqCallback(IN ib_cm_req_rec_t *p_cm_req_rec) // Create a new socket for this request pNewSocket = new SdpSocket; if (pNewSocket == NULL) { - SDP_PRINT(SDP_ERR, SDP_SOCKET, ("pNewSocket failed\n")); + SDP_PRINT(SDP_ERR, SDP_SOCKET, ("new pNewSocket failed\n")); goto ErrorLocked; } @@ -1506,7 +1556,7 @@ SdpSocket::CmReqCallback(IN ib_cm_req_rec_t *p_cm_req_rec) goto ErrorLocked; } - rc = pNewSocket->m_Lock.Lock(); //???????? + rc = pNewSocket->m_Lock.LockRc(); if (!NT_SUCCESS(rc)) { SDP_PRINT(SDP_ERR, SDP_SOCKET, ("pNewSocket.Init() failed rc = 0x%x\n", rc )); goto ErrorLocked; @@ -1552,9 +1602,12 @@ SdpSocket::CmReqCallback(IN ib_cm_req_rec_t *p_cm_req_rec) } Cleanup: + if (!NT_SUCCESS(rc)) { + // BUGBUG: We need to send a rej here + } if (pNewSocket != NULL) { pNewSocket->Release(); - } + } return; ErrorLocked: @@ -1584,7 +1637,7 @@ SdpSocket::CmRtuCallback(IN ib_cm_rtu_rec_t *p_cm_rtu_rec) // Take the lock and verify the state - rc = m_Lock.Lock(); //????? + rc = m_Lock.LockRc(); if (!NT_SUCCESS(rc)) { SDP_PRINT(SDP_ERR, SDP_SOCKET, ("m_Lock.Lock failed rc = 0x%x\n", rc )); goto Cleanup; @@ -1606,7 +1659,7 @@ SdpSocket::CmRtuCallback(IN ib_cm_rtu_rec_t *p_cm_rtu_rec) } // Next step is to move the new socket to the SS_CONNECTED state - rc = pSocket->m_Lock.Lock(); //??????? + rc = pSocket->m_Lock.LockRc(); if (!NT_SUCCESS(rc)) { SDP_PRINT(SDP_ERR, SDP_SOCKET, ("m_Lock.Lock failed rc = 0x%x\n", rc )); goto ErrorLocked; @@ -1731,6 +1784,8 @@ SdpSocket::__recv_cb1( IN const ib_cq_handle_t h_cq, IN void *cq_context ) { + SDP_PRINT(SDP_ALL, SDP_SOCKET, ("__recv_cb1\n")); + SdpSocket *pSocket = (SdpSocket *) cq_context; pSocket->m_Lock.SignalCB(RECV_CB_CALLED); } @@ -1770,11 +1825,11 @@ SdpSocket::recv_cb() ASSERT (ib_status == IB_SUCCESS); ib_wc_t *p_wc; for( p_wc = p_wc1; p_wc; p_wc = p_wc->p_next ) { - ASSERT( p_wc->status == IB_WCS_SUCCESS || p_wc->status == IB_WCS_WR_FLUSHED_ERR); + ASSERT( p_wc->status == IB_WCS_SUCCESS || p_wc->status == IB_WCS_WR_FLUSHED_ERR); // BUGBUG: Can there be other errors here ??? if (p_wc->status == IB_WCS_WR_FLUSHED_ERR) { // We have an error, but we still need to return the packet to the caller pBufferDescriptor = (BufferDescriptor *)p_wc->wr_id; - SDP_PRINT(SDP_ERR, SDP_SOCKET, ("p_wc->status == IB_WCS_WR_FLUSHED_ERR \n" )); + SDP_PRINT(SDP_DEBUG, SDP_SOCKET, ("p_wc->status == IB_WCS_WR_FLUSHED_ERR \n" )); // we can not handle it, but we can and should return it to the pool of recieved buffers rc1 = m_RecvBufferPool.RecievedBuffer(pBufferDescriptor, true); ASSERT(rc1 == STATUS_SUCCESS); // return with error can not fail @@ -2280,6 +2335,7 @@ VOID SdpSocket::Shutdown() SDP_PRINT(SDP_TRACE, SDP_SOCKET, ("called this = 0x%p\n", this)); NTSTATUS rc = STATUS_SUCCESS; ib_api_status_t ib_status; + ib_qp_mod_t qp_mod; if (m_ShutdownCalled) { @@ -2317,10 +2373,23 @@ VOID SdpSocket::Shutdown() } m_ConnectionList.Shutdown(); + - SDP_PRINT(SDP_TRACE, SDP_SOCKET, ("111111\n", this)); + SDP_PRINT(SDP_TRACE, SDP_SOCKET, ("111111\n", this)); if (m_qp != NULL) { + + SDP_PRINT(SDP_TRACE, SDP_SOCKET, ("222222\n", this)); + + cl_memclr( &qp_mod, sizeof(ib_qp_mod_t) ); + qp_mod.req_state = IB_QPS_ERROR; + ib_status = ib_modify_qp( m_qp, &qp_mod ); + if( ib_status != IB_SUCCESS ) { + SDP_PRINT(SDP_ERR, SDP_SOCKET, ("ib_modify_qp failed ib_status = 0x%d\n", ib_status )); + ASSERT(FALSE); + // We are probably going to leak, but we have to continue + } + ib_status = ib_destroy_qp(m_qp, ShutdownCB); //m_qp = NULL; if(ib_status == IB_SUCCESS) { @@ -2333,8 +2402,8 @@ VOID SdpSocket::Shutdown() } } - SDP_PRINT(SDP_TRACE, SDP_SOCKET, ("22222\n", this)); - + SDP_PRINT(SDP_TRACE, SDP_SOCKET, ("333333\n", this)); + if (m_scq != NULL) { ib_status = ib_destroy_cq(m_scq, ShutdownCB); //???ASSERT(ib_status == IB_SUCCESS); @@ -2343,7 +2412,7 @@ VOID SdpSocket::Shutdown() } //?????m_scq = NULL; } - SDP_PRINT(SDP_TRACE, SDP_SOCKET, ("33333\n", this)); + SDP_PRINT(SDP_TRACE, SDP_SOCKET, ("444444\n", this)); if (m_rcq != NULL) { ib_status = ib_destroy_cq(m_rcq, ShutdownCB); @@ -2354,7 +2423,7 @@ VOID SdpSocket::Shutdown() //??????m_rcq = NULL; } - SDP_PRINT(SDP_TRACE, SDP_SOCKET, ("44444\n", this)); + SDP_PRINT(SDP_TRACE, SDP_SOCKET, ("555555\n", this)); if (m_pd != NULL) { ib_status = ib_dealloc_pd(m_pd, ShutdownCB); //???ASSERT(ib_status == IB_SUCCESS); @@ -2364,7 +2433,7 @@ VOID SdpSocket::Shutdown() //?????m_pd = NULL; } - SDP_PRINT(SDP_TRACE, SDP_SOCKET, ("55555\n", this)); + SDP_PRINT(SDP_TRACE, SDP_SOCKET, ("666666\n", this)); if (mh_Ca != NULL) { ib_status = ib_close_ca(mh_Ca, ShutdownCB); diff --git a/trunk/ulp/sdp/kernel/SdpSocket.h b/trunk/ulp/sdp/kernel/SdpSocket.h index 15c5c9ce..e424f67d 100644 --- a/trunk/ulp/sdp/kernel/SdpSocket.h +++ b/trunk/ulp/sdp/kernel/SdpSocket.h @@ -139,6 +139,10 @@ public: SdpSocket(); + ~SdpSocket() { + SDP_PRINT(SDP_TRACE, SDP_SOCKET, ("this = 0x%p\n", this)); + } + NTSTATUS Init( WspSocketIn *pSocketInParam, WspSocketOut *pSocketOutParam @@ -172,7 +176,12 @@ public: NTSTATUS WSPAccept( WspAcceptIn *pWspAcceptIn, WspAcceptOut *pWspAcceptOut - ); + ); + + NTSTATUS WSPGetXXXName( + WspGetSockXXIn *pWspGetSockXXIn, + WspGetSockXXOut *pWspGetSockXXOut + ); NTSTATUS WSPCloseSocket( WspSocketCloseIn *pWspSocketCloseIn, diff --git a/trunk/ulp/sdp/kernel/SdpTrace.cpp b/trunk/ulp/sdp/kernel/SdpTrace.cpp index bd7da2ab..d2a19556 100644 --- a/trunk/ulp/sdp/kernel/SdpTrace.cpp +++ b/trunk/ulp/sdp/kernel/SdpTrace.cpp @@ -4,8 +4,8 @@ #include "Precompile.h" //int g_SdpDbgLevel = SDP_WARN; -//int g_SdpDbgLevel = SDP_TRACE; -int g_SdpDbgLevel = SDP_DEBUG; +int g_SdpDbgLevel = SDP_TRACE; +//int g_SdpDbgLevel = SDP_DEBUG; BOOLEAN CheckCondition(int sev, int top, char *file, int line, char * func) { diff --git a/trunk/ulp/sdp/todo b/trunk/ulp/sdp/todo index 2d455f72..d44cafce 100644 --- a/trunk/ulp/sdp/todo +++ b/trunk/ulp/sdp/todo @@ -29,7 +29,9 @@ general: Find a better solution for threading and remove the current solution. Fix the race of sdp user file - Fix the lock implmentation to have also a void implmentation as well as an RC implmentation + Fix the lock implmentation to have also a void implmentation as well as an RC implmentation. + + Check the ArpCache problems (on a native windows machine) and decide what to do. USER MODE: