diff --git a/reactos/drivers/network/tcpip/datalink/lan.c b/reactos/drivers/network/tcpip/datalink/lan.c index fd0b818ac1b..fef1690dfa2 100644 --- a/reactos/drivers/network/tcpip/datalink/lan.c +++ b/reactos/drivers/network/tcpip/datalink/lan.c @@ -108,7 +108,7 @@ VOID FreeAdapter( * Adapter = Pointer to LAN_ADAPTER structure to free */ { - ExFreePoolWithTag(Adapter, LAN_ADAPTER_TAG); + exFreePool(Adapter); } @@ -249,7 +249,7 @@ VOID LanReceiveWorker( PVOID Context ) { Adapter = WorkItem->Adapter; BytesTransferred = WorkItem->BytesTransferred; - ExFreePoolWithTag(WorkItem, WQ_CONTEXT_TAG); + exFreePool(WorkItem); IPInitializePacket(&IPPacket, 0); @@ -300,8 +300,7 @@ VOID LanSubmitReceiveWork( PNDIS_PACKET Packet, NDIS_STATUS Status, UINT BytesTransferred) { - PLAN_WQ_ITEM WQItem = ExAllocatePoolWithTag(NonPagedPool, sizeof(LAN_WQ_ITEM), - WQ_CONTEXT_TAG); + PLAN_WQ_ITEM WQItem = exAllocatePool(NonPagedPool, sizeof(LAN_WQ_ITEM)); PLAN_ADAPTER Adapter = (PLAN_ADAPTER)BindingContext; TI_DbgPrint(DEBUG_DATALINK,("called\n")); @@ -313,7 +312,7 @@ VOID LanSubmitReceiveWork( WQItem->BytesTransferred = BytesTransferred; if (!ChewCreate( LanReceiveWorker, WQItem )) - ExFreePoolWithTag(WQItem, WQ_CONTEXT_TAG); + exFreePool(WQItem); } VOID NTAPI ProtocolTransferDataComplete( @@ -769,9 +768,9 @@ NTSTATUS NTAPI AppendUnicodeString(PUNICODE_STRING ResultFirst, BOOLEAN Deallocate) { NTSTATUS Status; UNICODE_STRING Ustr = *ResultFirst; - PWSTR new_string = ExAllocatePool + PWSTR new_string = ExAllocatePoolWithTag (PagedPool, - (ResultFirst->Length + Second->Length + sizeof(WCHAR))); + (ResultFirst->Length + Second->Length + sizeof(WCHAR)), TAG_STRING); if( !new_string ) { return STATUS_NO_MEMORY; } @@ -992,11 +991,6 @@ BOOLEAN BindAdapter( GetName( RegistryPath, &IF->Name ); Status = FindDeviceDescForAdapter( &IF->Name, &IF->Description ); - if (!NT_SUCCESS(Status)) { - TI_DbgPrint(MIN_TRACE, ("Failed to get device description.\n")); - IPDestroyInterface(IF); - return FALSE; - } TI_DbgPrint(DEBUG_DATALINK,("Adapter Description: %wZ\n", &IF->Description)); @@ -1088,7 +1082,7 @@ NDIS_STATUS LANRegisterAdapter( TI_DbgPrint(DEBUG_DATALINK, ("Called.\n")); - IF = ExAllocatePoolWithTag(NonPagedPool, sizeof(LAN_ADAPTER), LAN_ADAPTER_TAG); + IF = exAllocatePool(NonPagedPool, sizeof(LAN_ADAPTER)); if (!IF) { TI_DbgPrint(MIN_TRACE, ("Insufficient resources.\n")); return NDIS_STATUS_RESOURCES; @@ -1126,7 +1120,7 @@ NDIS_STATUS LANRegisterAdapter( KeWaitForSingleObject(&IF->Event, UserRequest, KernelMode, FALSE, NULL); else if (NdisStatus != NDIS_STATUS_SUCCESS) { TI_DbgPrint(DEBUG_DATALINK,("denying adapter %wZ\n", AdapterName)); - ExFreePoolWithTag(IF, LAN_ADAPTER_TAG); + exFreePool(IF); return NdisStatus; } @@ -1151,7 +1145,7 @@ NDIS_STATUS LANRegisterAdapter( default: /* Unsupported media */ TI_DbgPrint(MIN_TRACE, ("Unsupported media.\n")); - ExFreePoolWithTag(IF, LAN_ADAPTER_TAG); + exFreePool(IF); return NDIS_STATUS_NOT_SUPPORTED; } @@ -1163,7 +1157,7 @@ NDIS_STATUS LANRegisterAdapter( sizeof(UINT)); if (NdisStatus != NDIS_STATUS_SUCCESS) { TI_DbgPrint(DEBUG_DATALINK,("denying adapter %wZ (NDISCall)\n", AdapterName)); - ExFreePoolWithTag(IF, LAN_ADAPTER_TAG); + exFreePool(IF); return NdisStatus; } @@ -1175,7 +1169,7 @@ NDIS_STATUS LANRegisterAdapter( sizeof(UINT)); if (NdisStatus != NDIS_STATUS_SUCCESS) { TI_DbgPrint(MIN_TRACE, ("Query for maximum packet size failed.\n")); - ExFreePoolWithTag(IF, LAN_ADAPTER_TAG); + exFreePool(IF); return NdisStatus; } @@ -1198,7 +1192,7 @@ NDIS_STATUS LANRegisterAdapter( IF->HWAddressLength); if (NdisStatus != NDIS_STATUS_SUCCESS) { TI_DbgPrint(MIN_TRACE, ("Query for current hardware address failed.\n")); - ExFreePoolWithTag(IF, LAN_ADAPTER_TAG); + exFreePool(IF); return NdisStatus; } @@ -1210,7 +1204,7 @@ NDIS_STATUS LANRegisterAdapter( sizeof(UINT)); if (NdisStatus != NDIS_STATUS_SUCCESS) { TI_DbgPrint(MIN_TRACE, ("Query for maximum link speed failed.\n")); - ExFreePoolWithTag(IF, LAN_ADAPTER_TAG); + exFreePool(IF); return NdisStatus; } @@ -1220,7 +1214,7 @@ NDIS_STATUS LANRegisterAdapter( /* Bind adapter to IP layer */ if( !BindAdapter(IF, RegistryPath) ) { TI_DbgPrint(DEBUG_DATALINK,("denying adapter %wZ (BindAdapter)\n", AdapterName)); - ExFreePoolWithTag(IF, LAN_ADAPTER_TAG); + exFreePool(IF); return NDIS_STATUS_NOT_ACCEPTED; } diff --git a/reactos/drivers/network/tcpip/include/address.h b/reactos/drivers/network/tcpip/include/address.h index 1bd1dbd5c15..71a0f876499 100644 --- a/reactos/drivers/network/tcpip/include/address.h +++ b/reactos/drivers/network/tcpip/include/address.h @@ -15,6 +15,7 @@ */ #define AddrInitIPv4(IPAddress, RawAddress) \ { \ + INIT_TAG((IPAddress), '4VPI'); \ (IPAddress)->Type = IP_ADDRESS_V4; \ (IPAddress)->Address.IPv4Address = (RawAddress); \ } diff --git a/reactos/drivers/network/tcpip/include/datagram.h b/reactos/drivers/network/tcpip/include/datagram.h index f05107a7de1..760ba3a85be 100644 --- a/reactos/drivers/network/tcpip/include/datagram.h +++ b/reactos/drivers/network/tcpip/include/datagram.h @@ -21,7 +21,7 @@ NTSTATUS DGReceiveDatagram( PVOID Context, PIRP Irp); -BOOLEAN DGRemoveIRP( +VOID DGRemoveIRP( PADDRESS_FILE AddrFile, PIRP Irp); diff --git a/reactos/drivers/network/tcpip/include/debug.h b/reactos/drivers/network/tcpip/include/debug.h index 7f6d86b8e27..3bf4fb303c2 100644 --- a/reactos/drivers/network/tcpip/include/debug.h +++ b/reactos/drivers/network/tcpip/include/debug.h @@ -71,6 +71,8 @@ #define CP CHECKPOINT +#include + #define ASSERT_KM_POINTER(_x) \ ASSERT(((PVOID)_x) != (PVOID)0xcccccccc); \ ASSERT(((PVOID)_x) >= (PVOID)0x80000000); diff --git a/reactos/drivers/network/tcpip/include/dispatch.h b/reactos/drivers/network/tcpip/include/dispatch.h index 6be0f269aed..f9344252a8a 100644 --- a/reactos/drivers/network/tcpip/include/dispatch.h +++ b/reactos/drivers/network/tcpip/include/dispatch.h @@ -72,8 +72,6 @@ NTSTATUS DispTdiDeleteIPAddress( VOID DispDoDisconnect( PVOID Data); -NTSTATUS IRPFinish( PIRP Irp, NTSTATUS Status ); - #endif /* __DISPATCH_H */ /* EOF */ diff --git a/reactos/drivers/network/tcpip/include/fileobjs.h b/reactos/drivers/network/tcpip/include/fileobjs.h index 12327701db8..bff07a64b40 100644 --- a/reactos/drivers/network/tcpip/include/fileobjs.h +++ b/reactos/drivers/network/tcpip/include/fileobjs.h @@ -13,6 +13,7 @@ extern KSPIN_LOCK AddressFileListLock; extern LIST_ENTRY ConnectionEndpointListHead; extern KSPIN_LOCK ConnectionEndpointListLock; + NTSTATUS FileOpenAddress( PTDI_REQUEST Request, PTA_IP_ADDRESS AddrList, @@ -26,6 +27,8 @@ NTSTATUS FileOpenConnection( PTDI_REQUEST Request, PVOID ClientContext); +PCONNECTION_ENDPOINT FileFindConnectionByContext( PVOID Context ); + NTSTATUS FileCloseConnection( PTDI_REQUEST Request); diff --git a/reactos/drivers/network/tcpip/include/ip.h b/reactos/drivers/network/tcpip/include/ip.h index 068992f4839..61f8e7a2414 100644 --- a/reactos/drivers/network/tcpip/include/ip.h +++ b/reactos/drivers/network/tcpip/include/ip.h @@ -21,6 +21,7 @@ typedef IPv6_RAW_ADDRESS *PIPv6_RAW_ADDRESS; /* IP style address */ typedef struct IP_ADDRESS { + DEFINE_TAG UCHAR Type; /* Type of IP address */ union { IPv4_RAW_ADDRESS IPv4Address;/* IPv4 address (in network byte order) */ @@ -75,6 +76,7 @@ typedef VOID (*PACKET_COMPLETION_ROUTINE)( /* Structure for an IP packet */ typedef struct _IP_PACKET { + DEFINE_TAG OBJECT_FREE_ROUTINE Free; /* Routine used to free resources for the object */ UCHAR Type; /* Type of IP packet (see IP_ADDRESS_xx above) */ UCHAR Flags; /* Flags for packet (see IP_PACKET_FLAG_xx below)*/ @@ -148,6 +150,7 @@ typedef struct _SEND_RECV_STATS { /* Information about an IP interface */ typedef struct _IP_INTERFACE { + DEFINE_TAG LIST_ENTRY ListEntry; /* Entry on list */ OBJECT_FREE_ROUTINE Free; /* Routine used to free resources used by the object */ KSPIN_LOCK Lock; /* Spin lock for this object */ diff --git a/reactos/drivers/network/tcpip/include/irp.h b/reactos/drivers/network/tcpip/include/irp.h new file mode 100644 index 00000000000..532200980ab --- /dev/null +++ b/reactos/drivers/network/tcpip/include/irp.h @@ -0,0 +1,13 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS TCP/IP protocol driver + * FILE: include/irp.h + * PURPOSE: IRP routines + */ +#ifndef __IRP_H +#define __IRP_H + +VOID IRPRemember( PIRP Irp, PCHAR File, UINT Line ); +NTSTATUS IRPFinish( PIRP Irp, NTSTATUS Status ); + +#endif/*__IRP_H*/ diff --git a/reactos/drivers/network/tcpip/include/lock.h b/reactos/drivers/network/tcpip/include/lock.h index 31ed91a8495..f5c15f5aefa 100644 --- a/reactos/drivers/network/tcpip/include/lock.h +++ b/reactos/drivers/network/tcpip/include/lock.h @@ -12,5 +12,9 @@ extern VOID TcpipInterlockedInsertTailList( PLIST_ENTRY ListHead, PKSPIN_LOCK Lock ); extern VOID TcpipAcquireFastMutex( PFAST_MUTEX Mutex ); extern VOID TcpipReleaseFastMutex( PFAST_MUTEX Mutex ); +extern VOID TcpipRecursiveMutexInit( PRECURSIVE_MUTEX RecMutex ); +extern VOID TcpipRecursiveMutexEnter( PRECURSIVE_MUTEX RecMutex, + BOOLEAN ToWrite ); +extern VOID TcpipRecursiveMutexLeave( PRECURSIVE_MUTEX RecMutex ); #endif/*_LOCK_H*/ diff --git a/reactos/drivers/network/tcpip/include/memtrack.h b/reactos/drivers/network/tcpip/include/memtrack.h new file mode 100644 index 00000000000..778d7b75cc4 --- /dev/null +++ b/reactos/drivers/network/tcpip/include/memtrack.h @@ -0,0 +1,79 @@ +#ifndef MEMTRACK_H +#define MEMTRACK_H + +#include + +#ifndef FOURCC +#define FOURCC(a,b,c,d) (((a)<<24)|((b)<<16)|((c)<<8)|(d)) +#endif + +#define FBSD_MALLOC FOURCC('d','s','b','f') +#define EXALLOC_TAG FOURCC('E','x','A','l') +#define IRP_TAG FOURCC('P','I','R','P') +#define NPLOOK_TAG FOURCC('N','P','L','A') + +#define AllocatePacketWithBuffer(x,y,z) AllocatePacketWithBufferX(x,y,z,__FILE__,__LINE__) +#define FreeNdisPacket(x) FreeNdisPacketX(x,__FILE__,__LINE__) + +#if DBG +#define MTMARK() TrackDumpFL(__FILE__, __LINE__) +#define exAllocatePool(x,y) ExAllocatePoolX(x,y,__FILE__,__LINE__) +#define exAllocatePoolWithTag(x,y,z) ExAllocatePoolX(x,y,__FILE__,__LINE__) +#define exFreePool(x) ExFreePoolX(x,__FILE__,__LINE__) +#define exAllocateFromNPagedLookasideList(x) ExAllocateFromNPagedLookasideListX(x,__FILE__,__LINE__) +#define exFreeToNPagedLookasideList(x,y) ExFreeToNPagedLookasideListX(x,y,__FILE__,__LINE__) + +typedef struct _ALLOCATION_TRACKER { + LIST_ENTRY Entry; + ULONG Tag; + PVOID Thing; + PCHAR FileName; + ULONG LineNo; +} ALLOCATION_TRACKER, *PALLOCATION_TRACKER; + +VOID TrackingInit(); +VOID TrackWithTag( ULONG Tag, PVOID Thing, PCHAR File, ULONG Line ); +#define Track(Tag,Thing) TrackWithTag(Tag,Thing,__FILE__,__LINE__) +VOID UntrackFL( PCHAR File, ULONG Line, PVOID Thing, ULONG Tag ); +#define Untrack(Thing) UntrackFL(__FILE__,__LINE__,Thing) +VOID TrackDumpFL( PCHAR File, ULONG Line ); +#define TrackDump() TrackDumpFL(__FILE__,__LINE__) + +static __inline PVOID ExAllocateFromNPagedLookasideListX( PNPAGED_LOOKASIDE_LIST List, PCHAR File, ULONG Line ) { + PVOID Out = ExAllocateFromNPagedLookasideList( List ); + if( Out ) TrackWithTag( NPLOOK_TAG, Out, File, Line ); + return Out; +} + +static __inline VOID ExFreeToNPagedLookasideListX( PNPAGED_LOOKASIDE_LIST List, PVOID Thing, PCHAR File, ULONG Line ) { + UntrackFL(File, Line, Thing, NPLOOK_TAG); + ExFreeToNPagedLookasideList( List, Thing ); +} + +static __inline PVOID ExAllocatePoolX( POOL_TYPE type, SIZE_T size, PCHAR File, ULONG Line ) { + PVOID Out = ExAllocatePool( type, size ); + if( Out ) TrackWithTag( EXALLOC_TAG, Out, File, Line ); + return Out; +} + +static __inline VOID ExFreePoolX( PVOID Data, PCHAR File, ULONG Line ) { + UntrackFL(File, Line, Data, EXALLOC_TAG); + ExFreePool( Data ); +} + +#else +#define MTMARK() +#define Track(x,y) +#define TrackingInit() +#define TrackDump() +#define Untrack(x) +#define exAllocatePoolWithTag(x,y,z) ExAllocatePoolWithTag(x,y,z) +#define exAllocatePool(x,y) ExAllocatePool(x,y) +#define exFreePool(x) ExFreePool(x) +#define exAllocateFromNPagedLookasideList(x) ExAllocateFromNPagedLookasideList(x) +#define exFreeToNPagedLookasideList(x,y) ExFreeToNPagedLookasideList(x,y) +#define TrackWithTag(w,x,y,z) +#define UntrackFL(w,x,y,z) +#endif + +#endif/*MEMMTRAC_H*/ diff --git a/reactos/drivers/network/tcpip/include/neighbor.h b/reactos/drivers/network/tcpip/include/neighbor.h index 6f125f06c51..95ea1f92769 100644 --- a/reactos/drivers/network/tcpip/include/neighbor.h +++ b/reactos/drivers/network/tcpip/include/neighbor.h @@ -27,6 +27,7 @@ typedef struct NEIGHBOR_CACHE_TABLE { /* Information about a neighbor */ typedef struct NEIGHBOR_CACHE_ENTRY { + DEFINE_TAG struct NEIGHBOR_CACHE_ENTRY *Next; /* Pointer to next entry */ UCHAR State; /* State of NCE */ UINT EventTimer; /* Ticks since last event */ diff --git a/reactos/drivers/network/tcpip/include/precomp.h b/reactos/drivers/network/tcpip/include/precomp.h index f37046d128e..ec563ac4b68 100644 --- a/reactos/drivers/network/tcpip/include/precomp.h +++ b/reactos/drivers/network/tcpip/include/precomp.h @@ -1,9 +1,9 @@ #include #include #include -#include #include #include +#include <../recmutex/recmutex.h> #include #include #include @@ -24,11 +24,13 @@ #include #include #include +#include #include #include #include #include #include +#include #include #include #include diff --git a/reactos/drivers/network/tcpip/include/routines.h b/reactos/drivers/network/tcpip/include/routines.h index 1fda0e5aee8..31d7075abca 100644 --- a/reactos/drivers/network/tcpip/include/routines.h +++ b/reactos/drivers/network/tcpip/include/routines.h @@ -49,10 +49,9 @@ UINT ResizePacket( PNDIS_PACKET Packet, UINT Size); -NDIS_STATUS AllocatePacketWithBuffer( PNDIS_PACKET *NdisPacket, - PCHAR Data, UINT Len ); - -VOID FreeNdisPacket( PNDIS_PACKET Packet ); +NDIS_STATUS AllocatePacketWithBufferX( PNDIS_PACKET *NdisPacket, + PCHAR Data, UINT Len, + PCHAR File, UINT Line ); void GetDataPtr( PNDIS_PACKET Packet, UINT Offset, diff --git a/reactos/drivers/network/tcpip/include/tags.h b/reactos/drivers/network/tcpip/include/tags.h deleted file mode 100644 index 52c16a45cc9..00000000000 --- a/reactos/drivers/network/tcpip/include/tags.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - * COPYRIGHT: See COPYING in the top level directory - * PROJECT: ReactOS TCP/IP protocol driver - * FILE: include/tags.h - * PURPOSE: Memory tags - */ -#ifndef __TAGS_H -#define __TAGS_H - -#define CONN_ENDPT_TAG 'pEnC' -#define ADDR_FILE_TAG 'FrdA' -#define CONTROL_CHANNEL_TAG 'CnoC' -#define TRANS_CONTEXT_TAG 'noCT' -#define TDI_ENTITY_TAG 'EidT' -#define DATAGRAM_SEND_TAG 'StaD' -#define DATAGRAM_RECV_TAG 'RtaD' -#define QUERY_CONTEXT_TAG 'noCQ' -#define IP_ADDRESS_TAG 'dAPI' -#define IP_INTERFACE_TAG 'FIPI' -#define DATAGRAM_REASSEMBLY_TAG 'RDPI' -#define DATAGRAM_FRAGMENT_TAG 'GFPI' -#define DATAGRAM_HOLE_TAG 'LHPI' -#define OSKITTCP_CONTEXT_TAG 'TKSO' -#define NEIGHBOR_PACKET_TAG 'kPbN' -#define NCE_TAG ' ECN' -#define PORT_SET_TAG 'teSP' -#define PACKET_BUFFER_TAG 'fuBP' -#define FRAGMENT_DATA_TAG 'taDF' -#define FIB_TAG ' BIF' -#define IFC_TAG ' CFI' -#define TDI_BUCKET_TAG 'BidT' -#define FBSD_TAG 'DSBF' -#define OSK_OTHER_TAG 'OKSO' -#define OSK_LARGE_TAG 'LKSO' -#define OSK_SMALL_TAG 'SKSO' -#define LAN_ADAPTER_TAG ' NAL' -#define WQ_CONTEXT_TAG 'noCW' - -#endif diff --git a/reactos/drivers/network/tcpip/include/tcp.h b/reactos/drivers/network/tcpip/include/tcp.h index a02c03b796e..5caa86e7637 100644 --- a/reactos/drivers/network/tcpip/include/tcp.h +++ b/reactos/drivers/network/tcpip/include/tcp.h @@ -59,11 +59,6 @@ typedef struct _SLEEPING_THREAD { KEVENT Event; } SLEEPING_THREAD, *PSLEEPING_THREAD; -typedef struct _CLIENT_DATA { - BOOLEAN Unlocked; - KSPIN_LOCK Lock; -} CLIENT_DATA, *PCLIENT_DATA; - /* Retransmission timeout constants */ /* Lower bound for retransmission timeout in TCP timer ticks */ @@ -89,15 +84,19 @@ typedef struct _CLIENT_DATA { #define SRF_FIN TCP_FIN extern LONG TCP_IPIdentification; -extern CLIENT_DATA ClientInfo; +extern LIST_ENTRY SignalledConnectionsList; +extern KSPIN_LOCK SignalledConnectionsLock; +extern LIST_ENTRY SleepingThreadsList; +extern FAST_MUTEX SleepingThreadsLock; +extern RECURSIVE_MUTEX TCPLock; /* accept.c */ NTSTATUS TCPServiceListeningSocket( PCONNECTION_ENDPOINT Listener, PCONNECTION_ENDPOINT Connection, PTDI_REQUEST_KERNEL Request ); NTSTATUS TCPListen( PCONNECTION_ENDPOINT Connection, UINT Backlog ); -BOOLEAN TCPAbortListenForSocket( PCONNECTION_ENDPOINT Listener, - PCONNECTION_ENDPOINT Connection ); +VOID TCPAbortListenForSocket( PCONNECTION_ENDPOINT Listener, + PCONNECTION_ENDPOINT Connection ); NTSTATUS TCPAccept ( PTDI_REQUEST Request, PCONNECTION_ENDPOINT Listener, @@ -112,8 +111,6 @@ VOID TCPFreeConnectionEndpoint( PCONNECTION_ENDPOINT Connection ); NTSTATUS TCPSocket( PCONNECTION_ENDPOINT Connection, UINT Family, UINT Type, UINT Proto ); -VOID HandleSignalledConnection(PCONNECTION_ENDPOINT Connection); - PTCP_SEGMENT TCPCreateSegment( PIP_PACKET IPPacket, PTCPv4_HEADER TCPHeader, @@ -164,6 +161,8 @@ NTSTATUS TCPClose( PCONNECTION_ENDPOINT Connection ); NTSTATUS TCPTranslateError( int OskitError ); +VOID TCPTimeout(); + UINT TCPAllocatePort( UINT HintPort ); VOID TCPFreePort( UINT Port ); @@ -179,6 +178,6 @@ NTSTATUS TCPStartup( NTSTATUS TCPShutdown( VOID); -BOOLEAN TCPRemoveIRP( PCONNECTION_ENDPOINT Connection, PIRP Irp ); +VOID TCPRemoveIRP( PCONNECTION_ENDPOINT Connection, PIRP Irp ); #endif /* __TCP_H */ diff --git a/reactos/drivers/network/tcpip/include/titypes.h b/reactos/drivers/network/tcpip/include/titypes.h index 78584fb1391..ef985775088 100644 --- a/reactos/drivers/network/tcpip/include/titypes.h +++ b/reactos/drivers/network/tcpip/include/titypes.h @@ -10,6 +10,10 @@ #if DBG +#define DEFINE_TAG ULONG Tag; +#define INIT_TAG(_Object, _Tag) \ + ((_Object)->Tag = (_Tag)) + #define DEBUG_REFCHECK(Object) { \ if ((Object)->RefCount <= 0) { \ TI_DbgPrint(MIN_TRACE, ("Object at (0x%X) has invalid reference count (%d).\n", \ @@ -60,6 +64,9 @@ #else /* DBG */ +#define DEFINE_TAG +#define INIT_TAG(Object, Tag) + /* * VOID ReferenceObject( * PVOID Object) @@ -142,9 +149,11 @@ typedef struct _DATAGRAM_SEND_REQUEST { /* Transport address file context structure. The FileObject->FsContext2 field holds a pointer to this structure */ typedef struct _ADDRESS_FILE { + DEFINE_TAG LIST_ENTRY ListEntry; /* Entry on list */ KSPIN_LOCK Lock; /* Spin lock to manipulate this structure */ OBJECT_FREE_ROUTINE Free; /* Routine to use to free resources for the object */ + USHORT Flags; /* Flags for address file (see below) */ IP_ADDRESS Address; /* Address of this address file */ USHORT Family; /* Address family */ USHORT Protocol; /* Protocol number */ @@ -204,6 +213,29 @@ typedef struct _ADDRESS_FILE { BOOLEAN RegisteredChainedReceiveExpeditedHandler; } ADDRESS_FILE, *PADDRESS_FILE; +/* Address File Flag constants */ +#define AFF_VALID 0x0001 /* Address file object is valid for use */ +#define AFF_BUSY 0x0002 /* Address file object is exclusive to someone */ +#define AFF_DELETE 0x0004 /* Address file object is sheduled to be deleted */ +#define AFF_SEND 0x0008 /* A send request is pending */ +#define AFF_RECEIVE 0x0010 /* A receive request is pending */ +#define AFF_PENDING 0x001C /* A request is pending */ + +/* Macros for manipulating address file object flags */ + +#define AF_IS_VALID(ADF) ((ADF)->Flags & AFF_VALID) +#define AF_SET_VALID(ADF) ((ADF)->Flags |= AFF_VALID) +#define AF_CLR_VALID(ADF) ((ADF)->Flags &= ~AFF_VALID) + +#define AF_IS_BUSY(ADF) ((ADF)->Flags & AFF_BUSY) +#define AF_SET_BUSY(ADF) ((ADF)->Flags |= AFF_BUSY) +#define AF_CLR_BUSY(ADF) ((ADF)->Flags &= ~AFF_BUSY) + +#define AF_IS_PENDING(ADF, X) (ADF->Flags & X) +#define AF_SET_PENDING(ADF, X) (ADF->Flags |= X) +#define AF_CLR_PENDING(ADF, X) (ADF->Flags &= ~X) + + /* Structure used to search through Address Files */ typedef struct _AF_SEARCH { PLIST_ENTRY Next; /* Next address file to check */ @@ -255,8 +287,6 @@ typedef struct _TDI_BUCKET { LIST_ENTRY Entry; struct _CONNECTION_ENDPOINT *AssociatedEndpoint; TDI_REQUEST Request; - NTSTATUS Status; - ULONG Information; } TDI_BUCKET, *PTDI_BUCKET; /* Transport connection context structure A.K.A. Transmission Control Block @@ -269,15 +299,19 @@ typedef struct _CONNECTION_ENDPOINT { PADDRESS_FILE AddressFile; /* Associated address file object (NULL if none) */ PVOID SocketContext; /* Context for lower layer */ + UINT State; /* Socket state W.R.T. oskit */ + /* Requests */ LIST_ENTRY ConnectRequest; /* Queued connect rqueusts */ LIST_ENTRY ListenRequest; /* Queued listen requests */ LIST_ENTRY ReceiveRequest; /* Queued receive requests */ LIST_ENTRY SendRequest; /* Queued send requests */ - LIST_ENTRY CompletionQueue;/* Completed requests to finish */ /* Signals */ + LIST_ENTRY SignalList; /* Entry in the list of sockets waiting for + * notification service to the client */ UINT SignalState; /* Active signals from oskit */ + BOOLEAN Signalled; /* Are we a member of the signal list */ } CONNECTION_ENDPOINT, *PCONNECTION_ENDPOINT; diff --git a/reactos/drivers/network/tcpip/recmutex/recmutex.c b/reactos/drivers/network/tcpip/recmutex/recmutex.c new file mode 100644 index 00000000000..3450ab8567f --- /dev/null +++ b/reactos/drivers/network/tcpip/recmutex/recmutex.c @@ -0,0 +1,61 @@ +#include +#include "recmutex.h" + +VOID RecursiveMutexInit( PRECURSIVE_MUTEX RecMutex ) { + RtlZeroMemory( RecMutex, sizeof(*RecMutex) ); + ExInitializeFastMutex( &RecMutex->Mutex ); + KeInitializeEvent( &RecMutex->StateLockedEvent, + NotificationEvent, FALSE ); +} + +/* NOTE: When we leave, the FAST_MUTEX must have been released. The result +* is that we always exit in the same irql as entering */ +VOID RecursiveMutexEnter( PRECURSIVE_MUTEX RecMutex ) { + NTSTATUS Status = STATUS_SUCCESS; + PVOID CurrentThread = KeGetCurrentThread(); + + ASSERT(RecMutex); + ASSERT(KeGetCurrentIrql() <= APC_LEVEL); + + /* Wait for the previous user to unlock the RecMutex state. There might be + * multiple waiters waiting to change the state. We need to check each + * time we get the event whether somebody still has the state locked */ + + ExAcquireFastMutex( &RecMutex->Mutex ); + + if( CurrentThread == RecMutex->CurrentThread ) { + RecMutex->LockCount++; + ExReleaseFastMutex( &RecMutex->Mutex ); + return; + } + + while( RecMutex->LockCount != 0 ) { + ExReleaseFastMutex( &RecMutex->Mutex ); + Status = KeWaitForSingleObject( &RecMutex->StateLockedEvent, + UserRequest, + KernelMode, + FALSE, + NULL ); + ExAcquireFastMutex( &RecMutex->Mutex ); + } + RecMutex->CurrentThread = CurrentThread; + RecMutex->LockCount++; + ExReleaseFastMutex( &RecMutex->Mutex ); +} + +VOID RecursiveMutexLeave( PRECURSIVE_MUTEX RecMutex ) { + ASSERT(RecMutex); + + ExAcquireFastMutex( &RecMutex->Mutex ); + + ASSERT(RecMutex->LockCount > 0); + RecMutex->LockCount--; + + if( !RecMutex->LockCount ) { + KePulseEvent( &RecMutex->StateLockedEvent, IO_NETWORK_INCREMENT, + FALSE ); + } + + ExReleaseFastMutex( &RecMutex->Mutex ); +} + diff --git a/reactos/drivers/network/tcpip/recmutex/recmutex.h b/reactos/drivers/network/tcpip/recmutex/recmutex.h new file mode 100644 index 00000000000..3479268e3bd --- /dev/null +++ b/reactos/drivers/network/tcpip/recmutex/recmutex.h @@ -0,0 +1,21 @@ +#ifndef _ROSRTL_RECMUTEX_H +#define _ROSRTL_RECMUTEX_H + +typedef struct _RECURSIVE_MUTEX { + /* Lock. */ + FAST_MUTEX Mutex; + /* Number of times this object was locked */ + SIZE_T LockCount; + /* CurrentThread */ + PVOID CurrentThread; + /* Notification event which signals that another thread can take over */ + KEVENT StateLockedEvent; +} RECURSIVE_MUTEX, *PRECURSIVE_MUTEX; + +extern VOID RecursiveMutexInit( PRECURSIVE_MUTEX RecMutex ); +extern VOID RecursiveMutexEnter( PRECURSIVE_MUTEX RecMutex ); +extern VOID RecursiveMutexLeave( PRECURSIVE_MUTEX RecMutex ); + +#define ASSERT_LOCKED(x) + +#endif/*_ROSRTL_RECMUTEX_H*/ diff --git a/reactos/drivers/network/tcpip/tcpip.rbuild b/reactos/drivers/network/tcpip/tcpip.rbuild index ea9d3a6d5e1..2a9f91cc52e 100644 --- a/reactos/drivers/network/tcpip/tcpip.rbuild +++ b/reactos/drivers/network/tcpip/tcpip.rbuild @@ -21,6 +21,9 @@ lan.c + + recmutex.c + ainfo.c buffer.c @@ -28,6 +31,7 @@ fileobjs.c iinfo.c info.c + irp.c lock.c main.c ninfo.c diff --git a/reactos/drivers/network/tcpip/tcpip/ainfo.c b/reactos/drivers/network/tcpip/tcpip/ainfo.c index 0c1b11e717f..a3ea2e8889c 100644 --- a/reactos/drivers/network/tcpip/tcpip/ainfo.c +++ b/reactos/drivers/network/tcpip/tcpip/ainfo.c @@ -13,8 +13,6 @@ TDI_STATUS SetAddressFileInfo(TDIObjectID *ID, PVOID Buffer, UINT BufferSize) { - //KIRQL OldIrql; - switch (ID->toi_id) { #if 0 @@ -22,10 +20,7 @@ TDI_STATUS SetAddressFileInfo(TDIObjectID *ID, if (BufferSize < sizeof(UCHAR)) return TDI_INVALID_PARAMETER; - KeAcquireSpinLock(&AddrFile->Lock, &OldIrql); AddrFile->TTL = *((PUCHAR)Buffer); - KeReleaseSpinLock(&AddrFile->Lock, OldIrql); - return TDI_SUCCESS; #endif default: diff --git a/reactos/drivers/network/tcpip/tcpip/buffer.c b/reactos/drivers/network/tcpip/tcpip/buffer.c index 6858ddea984..e604c7bcacc 100644 --- a/reactos/drivers/network/tcpip/tcpip/buffer.c +++ b/reactos/drivers/network/tcpip/tcpip/buffer.c @@ -318,16 +318,13 @@ NDIS_STATUS PrependPacket( PNDIS_PACKET Packet, PCHAR Data, UINT Length, PCHAR NewBuf; if( Copy ) { - NewBuf = ExAllocatePoolWithTag( NonPagedPool, Length, PACKET_BUFFER_TAG ); + NewBuf = exAllocatePool( NonPagedPool, Length ); if( !NewBuf ) return NDIS_STATUS_RESOURCES; RtlCopyMemory( NewBuf, Data, Length ); } else NewBuf = Data; NdisAllocateBuffer( &Status, &Buffer, GlobalBufferPool, NewBuf, Length ); - if( Status != NDIS_STATUS_SUCCESS ) { - if (Copy) ExFreePoolWithTag(NewBuf, PACKET_BUFFER_TAG); - return Status; - } + if( Status != NDIS_STATUS_SUCCESS ) return Status; NdisChainBufferAtFront( Packet, Buffer ); @@ -345,30 +342,33 @@ void GetDataPtr( PNDIS_PACKET Packet, SkipToOffset( Buffer, Offset, DataOut, Size ); } -NDIS_STATUS AllocatePacketWithBuffer( PNDIS_PACKET *NdisPacket, - PCHAR Data, UINT Len ) { +NDIS_STATUS AllocatePacketWithBufferX( PNDIS_PACKET *NdisPacket, + PCHAR Data, UINT Len, + PCHAR File, UINT Line ) { PNDIS_PACKET Packet; PNDIS_BUFFER Buffer; NDIS_STATUS Status; PCHAR NewData; - NewData = ExAllocatePoolWithTag( NonPagedPool, Len, PACKET_BUFFER_TAG ); + NewData = exAllocatePool( NonPagedPool, Len ); if( !NewData ) return NDIS_STATUS_RESOURCES; if( Data ) RtlCopyMemory(NewData, Data, Len); NdisAllocatePacket( &Status, &Packet, GlobalPacketPool ); if( Status != NDIS_STATUS_SUCCESS ) { - ExFreePoolWithTag( NewData, PACKET_BUFFER_TAG ); + exFreePool( NewData ); return Status; } + TrackWithTag(NDIS_PACKET_TAG, Packet, File, Line); NdisAllocateBuffer( &Status, &Buffer, GlobalBufferPool, NewData, Len ); if( Status != NDIS_STATUS_SUCCESS ) { - ExFreePoolWithTag( NewData, PACKET_BUFFER_TAG ); + exFreePool( NewData ); FreeNdisPacket( Packet ); return Status; } + TrackWithTag(NDIS_BUFFER_TAG, Buffer, File, Line); NdisChainBufferAtFront( Packet, Buffer ); *NdisPacket = Packet; @@ -377,8 +377,10 @@ NDIS_STATUS AllocatePacketWithBuffer( PNDIS_PACKET *NdisPacket, } -VOID FreeNdisPacket -( PNDIS_PACKET Packet ) +VOID FreeNdisPacketX +( PNDIS_PACKET Packet, + PCHAR File, + UINT Line ) /* * FUNCTION: Frees an NDIS packet * ARGUMENTS: @@ -398,11 +400,13 @@ VOID FreeNdisPacket NdisGetNextBuffer(Buffer, &NextBuffer); NdisQueryBuffer(Buffer, &Data, &Length); TI_DbgPrint(DEBUG_PBUFFER, ("Freeing ndis buffer (0x%X)\n", Buffer)); + UntrackFL(File,Line,Buffer,NDIS_BUFFER_TAG); NdisFreeBuffer(Buffer); TI_DbgPrint(DEBUG_PBUFFER, ("Freeing exal buffer (0x%X)\n", Data)); - ExFreePoolWithTag(Data, PACKET_BUFFER_TAG); + exFreePool(Data); } /* Finally free the NDIS packet discriptor */ + UntrackFL(File,Line,Packet,NDIS_PACKET_TAG); NdisFreePacket(Packet); } diff --git a/reactos/drivers/network/tcpip/tcpip/dispatch.c b/reactos/drivers/network/tcpip/tcpip/dispatch.c index c6f2d2a55e9..237149520b3 100644 --- a/reactos/drivers/network/tcpip/tcpip/dispatch.c +++ b/reactos/drivers/network/tcpip/tcpip/dispatch.c @@ -12,25 +12,6 @@ #include "precomp.h" #include - -NTSTATUS IRPFinish( PIRP Irp, NTSTATUS Status ) { - KIRQL OldIrql; - - Irp->IoStatus.Status = Status; - - if( Status == STATUS_PENDING ) - IoMarkIrpPending( Irp ); - else { - IoAcquireCancelSpinLock(&OldIrql); - (void)IoSetCancelRoutine( Irp, NULL ); - IoReleaseCancelSpinLock(OldIrql); - - IoCompleteRequest( Irp, IO_NETWORK_INCREMENT ); - } - - return Status; -} - NTSTATUS DispPrepareIrpForCancel( PTRANSPORT_CONTEXT Context, PIRP Irp, @@ -91,6 +72,7 @@ VOID DispDataRequestComplete( { PIRP Irp; PIO_STACK_LOCATION IrpSp; + PTRANSPORT_CONTEXT TranContext; KIRQL OldIrql; TI_DbgPrint(DEBUG_IRP, ("Called for irp %x (%x, %d).\n", @@ -98,6 +80,7 @@ VOID DispDataRequestComplete( Irp = Context; IrpSp = IoGetCurrentIrpStackLocation(Irp); + TranContext = (PTRANSPORT_CONTEXT)IrpSp->FileObject->FsContext; IoAcquireCancelSpinLock(&OldIrql); @@ -119,6 +102,26 @@ VOID DispDataRequestComplete( TI_DbgPrint(DEBUG_IRP, ("Done Completing IRP\n")); } +VOID DispDoDisconnect( PVOID Data ) { + PDISCONNECT_TYPE DisType = (PDISCONNECT_TYPE)Data; + + TI_DbgPrint(DEBUG_IRP, ("PostCancel: DoDisconnect\n")); + TcpipRecursiveMutexEnter(&TCPLock, TRUE); + TCPDisconnect + ( DisType->Context, + DisType->Type, + NULL, + NULL, + DispDataRequestComplete, + DisType->Irp ); + TcpipRecursiveMutexLeave(&TCPLock); + TI_DbgPrint(DEBUG_IRP, ("PostCancel: DoDisconnect done\n")); + + DispDataRequestComplete(DisType->Irp, STATUS_CANCELLED, 0); + + exFreePool(DisType); +} + VOID NTAPI DispCancelRequest( PDEVICE_OBJECT Device, PIRP Irp) @@ -133,9 +136,7 @@ VOID NTAPI DispCancelRequest( PTRANSPORT_CONTEXT TranContext; PFILE_OBJECT FileObject; UCHAR MinorFunction; - BOOLEAN DequeuedIrp = TRUE; - - IoReleaseCancelSpinLock(Irp->CancelIrql); + PDISCONNECT_TYPE DisType; TI_DbgPrint(DEBUG_IRP, ("Called.\n")); @@ -158,8 +159,22 @@ VOID NTAPI DispCancelRequest( switch(MinorFunction) { case TDI_SEND: case TDI_RECEIVE: - DequeuedIrp = TCPRemoveIRP( TranContext->Handle.ConnectionContext, Irp ); - break; + DisType = exAllocatePool(NonPagedPool, sizeof(DISCONNECT_TYPE)); + if (DisType) + { + DisType->Type = TDI_DISCONNECT_RELEASE | + ((MinorFunction == TDI_RECEIVE) ? TDI_DISCONNECT_ABORT : 0); + DisType->Context = TranContext->Handle.ConnectionContext; + DisType->Irp = Irp; + + TCPRemoveIRP( TranContext->Handle.ConnectionContext, Irp ); + + if (!ChewCreate(DispDoDisconnect, DisType)) + exFreePool(DisType); + } + + IoReleaseCancelSpinLock(Irp->CancelIrql); + return; case TDI_SEND_DATAGRAM: if (FileObject->FsContext2 != (PVOID)TDI_TRANSPORT_ADDRESS_FILE) { @@ -167,7 +182,7 @@ VOID NTAPI DispCancelRequest( break; } - DequeuedIrp = DGRemoveIRP(TranContext->Handle.AddressHandle, Irp); + DGRemoveIRP(TranContext->Handle.AddressHandle, Irp); break; case TDI_RECEIVE_DATAGRAM: @@ -176,21 +191,20 @@ VOID NTAPI DispCancelRequest( break; } - DequeuedIrp = DGRemoveIRP(TranContext->Handle.AddressHandle, Irp); + DGRemoveIRP(TranContext->Handle.AddressHandle, Irp); break; case TDI_CONNECT: - DequeuedIrp = TCPRemoveIRP(TranContext->Handle.ConnectionContext, Irp); + TCPRemoveIRP(TranContext->Handle.ConnectionContext, Irp); break; default: TI_DbgPrint(MIN_TRACE, ("Unknown IRP. MinorFunction (0x%X).\n", MinorFunction)); - ASSERT(FALSE); break; } - if (DequeuedIrp) - IRPFinish(Irp, STATUS_CANCELLED); + IoReleaseCancelSpinLock(Irp->CancelIrql); + IRPFinish(Irp, STATUS_CANCELLED); TI_DbgPrint(MAX_TRACE, ("Leaving.\n")); } @@ -210,8 +224,7 @@ VOID NTAPI DispCancelListenRequest( PTRANSPORT_CONTEXT TranContext; PFILE_OBJECT FileObject; PCONNECTION_ENDPOINT Connection; - - IoReleaseCancelSpinLock(Irp->CancelIrql); + /*NTSTATUS Status = STATUS_SUCCESS;*/ TI_DbgPrint(DEBUG_IRP, ("Called.\n")); @@ -230,12 +243,16 @@ VOID NTAPI DispCancelListenRequest( /* Try canceling the request */ Connection = (PCONNECTION_ENDPOINT)TranContext->Handle.ConnectionContext; - if (TCPAbortListenForSocket(Connection->AddressFile->Listener, - Connection)) - { - Irp->IoStatus.Information = 0; - IRPFinish(Irp, STATUS_CANCELLED); - } + TCPRemoveIRP(Connection, Irp); + + TCPAbortListenForSocket( + Connection->AddressFile->Listener, + Connection ); + + IoReleaseCancelSpinLock(Irp->CancelIrql); + + Irp->IoStatus.Information = 0; + IRPFinish(Irp, STATUS_CANCELLED); TI_DbgPrint(MAX_TRACE, ("Leaving.\n")); } @@ -274,7 +291,6 @@ NTSTATUS DispTdiAssociateAddress( PFILE_OBJECT FileObject; PADDRESS_FILE AddrFile = NULL; NTSTATUS Status; - KIRQL OldIrql; TI_DbgPrint(DEBUG_IRP, ("Called.\n")); @@ -294,6 +310,11 @@ NTSTATUS DispTdiAssociateAddress( return STATUS_INVALID_PARAMETER; } + if (Connection->AddressFile) { + TI_DbgPrint(MID_TRACE, ("An address file is already asscociated.\n")); + return STATUS_INVALID_PARAMETER; + } + Parameters = (PTDI_REQUEST_KERNEL_ASSOCIATE)&IrpSp->Parameters; Status = ObReferenceObjectByHandle( @@ -309,18 +330,8 @@ NTSTATUS DispTdiAssociateAddress( return STATUS_INVALID_PARAMETER; } - KeAcquireSpinLock(&Connection->Lock, &OldIrql); - - if (Connection->AddressFile) { - ObDereferenceObject(FileObject); - KeReleaseSpinLock(&Connection->Lock, OldIrql); - TI_DbgPrint(MID_TRACE, ("An address file is already asscociated.\n")); - return STATUS_INVALID_PARAMETER; - } - if (FileObject->FsContext2 != (PVOID)TDI_TRANSPORT_ADDRESS_FILE) { ObDereferenceObject(FileObject); - KeReleaseSpinLock(&Connection->Lock, OldIrql); TI_DbgPrint(MID_TRACE, ("Bad address file object. Magic (0x%X).\n", FileObject->FsContext2)); return STATUS_INVALID_PARAMETER; @@ -331,21 +342,17 @@ NTSTATUS DispTdiAssociateAddress( TranContext = FileObject->FsContext; if (!TranContext) { ObDereferenceObject(FileObject); - KeReleaseSpinLock(&Connection->Lock, OldIrql); TI_DbgPrint(MID_TRACE, ("Bad transport context.\n")); return STATUS_INVALID_PARAMETER; } AddrFile = (PADDRESS_FILE)TranContext->Handle.AddressHandle; if (!AddrFile) { - KeReleaseSpinLock(&Connection->Lock, OldIrql); ObDereferenceObject(FileObject); TI_DbgPrint(MID_TRACE, ("No address file object.\n")); return STATUS_INVALID_PARAMETER; } - KeAcquireSpinLockAtDpcLevel(&AddrFile->Lock); - Connection->AddressFile = AddrFile; /* Add connection endpoint to the address file */ @@ -354,9 +361,6 @@ NTSTATUS DispTdiAssociateAddress( /* FIXME: Maybe do this in DispTdiDisassociateAddress() instead? */ ObDereferenceObject(FileObject); - KeReleaseSpinLockFromDpcLevel(&AddrFile->Lock); - KeReleaseSpinLock(&Connection->Lock, OldIrql); - return Status; } @@ -383,6 +387,8 @@ NTSTATUS DispTdiConnect( /* Get associated connection endpoint file object. Quit if none exists */ + TcpipRecursiveMutexEnter( &TCPLock, TRUE ); + TranContext = IrpSp->FileObject->FsContext; if (!TranContext) { TI_DbgPrint(MID_TRACE, ("Bad transport context.\n")); @@ -413,6 +419,8 @@ NTSTATUS DispTdiConnect( } done: + TcpipRecursiveMutexLeave( &TCPLock ); + if (Status != STATUS_PENDING) { DispDataRequestComplete(Irp, Status, 0); } else @@ -437,7 +445,6 @@ NTSTATUS DispTdiDisassociateAddress( PCONNECTION_ENDPOINT Connection; PTRANSPORT_CONTEXT TranContext; PIO_STACK_LOCATION IrpSp; - KIRQL OldIrql; TI_DbgPrint(DEBUG_IRP, ("Called.\n")); @@ -457,26 +464,17 @@ NTSTATUS DispTdiDisassociateAddress( return STATUS_INVALID_PARAMETER; } - KeAcquireSpinLock(&Connection->Lock, &OldIrql); - if (!Connection->AddressFile) { - KeReleaseSpinLock(&Connection->Lock, OldIrql); TI_DbgPrint(MID_TRACE, ("No address file is asscociated.\n")); return STATUS_INVALID_PARAMETER; } - KeAcquireSpinLockAtDpcLevel(&Connection->AddressFile->Lock); - /* Remove this connection from the address file */ Connection->AddressFile->Connection = NULL; - KeReleaseSpinLockFromDpcLevel(&Connection->AddressFile->Lock); - /* Remove the address file from this connection */ Connection->AddressFile = NULL; - KeReleaseSpinLock(&Connection->Lock, OldIrql); - return STATUS_SUCCESS; } @@ -502,6 +500,8 @@ NTSTATUS DispTdiDisconnect( IrpSp = IoGetCurrentIrpStackLocation(Irp); DisReq = (PTDI_REQUEST_KERNEL_DISCONNECT)&IrpSp->Parameters; + TcpipRecursiveMutexEnter( &TCPLock, TRUE ); + /* Get associated connection endpoint file object. Quit if none exists */ TranContext = IrpSp->FileObject->FsContext; @@ -527,6 +527,8 @@ NTSTATUS DispTdiDisconnect( Irp ); done: + TcpipRecursiveMutexLeave( &TCPLock ); + if (Status != STATUS_PENDING) { DispDataRequestComplete(Irp, Status, 0); } else @@ -553,7 +555,6 @@ NTSTATUS DispTdiListen( PTRANSPORT_CONTEXT TranContext; PIO_STACK_LOCATION IrpSp; NTSTATUS Status = STATUS_SUCCESS; - KIRQL OldIrql; TI_DbgPrint(DEBUG_IRP, ("Called.\n")); @@ -561,6 +562,8 @@ NTSTATUS DispTdiListen( /* Get associated connection endpoint file object. Quit if none exists */ + TcpipRecursiveMutexEnter( &TCPLock, TRUE ); + TranContext = IrpSp->FileObject->FsContext; if (TranContext == NULL) { @@ -579,23 +582,15 @@ NTSTATUS DispTdiListen( Parameters = (PTDI_REQUEST_KERNEL)&IrpSp->Parameters; + TI_DbgPrint(MIN_TRACE, ("Connection->AddressFile: %x\n", + Connection->AddressFile )); + ASSERT(Connection->AddressFile); + Status = DispPrepareIrpForCancel (TranContext->Handle.ConnectionContext, Irp, (PDRIVER_CANCEL)DispCancelListenRequest); - KeAcquireSpinLock(&Connection->Lock, &OldIrql); - - if (Connection->AddressFile == NULL) - { - TI_DbgPrint(MID_TRACE, ("No associated address file\n")); - KeReleaseSpinLock(&Connection->Lock, OldIrql); - Status = STATUS_INVALID_PARAMETER; - goto done; - } - - KeAcquireSpinLockAtDpcLevel(&Connection->AddressFile->Lock); - /* Listening will require us to create a listening socket and store it in * the address file. It will be signalled, and attempt to complete an irp * when a new connection arrives. */ @@ -632,10 +627,9 @@ NTSTATUS DispTdiListen( Irp ); } - KeReleaseSpinLockFromDpcLevel(&Connection->AddressFile->Lock); - KeReleaseSpinLock(&Connection->Lock, OldIrql); - done: + TcpipRecursiveMutexLeave( &TCPLock ); + if (Status != STATUS_PENDING) { DispDataRequestComplete(Irp, Status, 0); } else @@ -662,15 +656,19 @@ NTSTATUS DispTdiQueryInformation( PTDI_REQUEST_KERNEL_QUERY_INFORMATION Parameters; PTRANSPORT_CONTEXT TranContext; PIO_STACK_LOCATION IrpSp; + NTSTATUS Status; TI_DbgPrint(DEBUG_IRP, ("Called.\n")); IrpSp = IoGetCurrentIrpStackLocation(Irp); Parameters = (PTDI_REQUEST_KERNEL_QUERY_INFORMATION)&IrpSp->Parameters; + TcpipRecursiveMutexEnter( &TCPLock, TRUE ); + TranContext = IrpSp->FileObject->FsContext; if (!TranContext) { TI_DbgPrint(MID_TRACE, ("Bad transport context.\n")); + TcpipRecursiveMutexLeave(&TCPLock); return STATUS_INVALID_PARAMETER; } @@ -688,6 +686,7 @@ NTSTATUS DispTdiQueryInformation( (FIELD_OFFSET(TDI_ADDRESS_INFO, Address.Address[0].Address) + sizeof(TDI_ADDRESS_IP))) { TI_DbgPrint(MID_TRACE, ("MDL buffer too small.\n")); + TcpipRecursiveMutexLeave(&TCPLock); return STATUS_BUFFER_TOO_SMALL; } @@ -706,18 +705,23 @@ NTSTATUS DispTdiQueryInformation( RtlZeroMemory( &Address->Address[0].Address[0].sin_zero, sizeof(Address->Address[0].Address[0].sin_zero)); + TcpipRecursiveMutexLeave(&TCPLock); return STATUS_SUCCESS; case TDI_CONNECTION_FILE: Endpoint = (PCONNECTION_ENDPOINT)TranContext->Handle.ConnectionContext; + TCPGetSockAddress( Endpoint, (PTRANSPORT_ADDRESS)Address, FALSE ); + DbgPrint("Returning socket address %x\n", Address->Address[0].Address[0].in_addr); RtlZeroMemory( &Address->Address[0].Address[0].sin_zero, sizeof(Address->Address[0].Address[0].sin_zero)); - return TCPGetSockAddress( Endpoint, (PTRANSPORT_ADDRESS)Address, FALSE ); + TcpipRecursiveMutexLeave(&TCPLock); + return STATUS_SUCCESS; default: TI_DbgPrint(MIN_TRACE, ("Invalid transport context\n")); + TcpipRecursiveMutexLeave(&TCPLock); return STATUS_INVALID_PARAMETER; } } @@ -732,6 +736,7 @@ NTSTATUS DispTdiQueryInformation( (FIELD_OFFSET(TDI_CONNECTION_INFORMATION, RemoteAddress) + sizeof(PVOID))) { TI_DbgPrint(MID_TRACE, ("MDL buffer too small (ptr).\n")); + TcpipRecursiveMutexLeave(&TCPLock); return STATUS_BUFFER_TOO_SMALL; } @@ -751,18 +756,24 @@ NTSTATUS DispTdiQueryInformation( default: TI_DbgPrint(MIN_TRACE, ("Invalid transport context\n")); + TcpipRecursiveMutexLeave(&TCPLock); return STATUS_INVALID_PARAMETER; } if (!Endpoint) { TI_DbgPrint(MID_TRACE, ("No connection object.\n")); + TcpipRecursiveMutexLeave(&TCPLock); return STATUS_INVALID_PARAMETER; } - return TCPGetSockAddress( Endpoint, AddressInfo->RemoteAddress, TRUE ); + Status = TCPGetSockAddress( Endpoint, AddressInfo->RemoteAddress, TRUE ); + + TcpipRecursiveMutexLeave(&TCPLock); + return Status; } } + TcpipRecursiveMutexLeave(&TCPLock); return STATUS_NOT_IMPLEMENTED; } @@ -788,6 +799,8 @@ NTSTATUS DispTdiReceive( IrpSp = IoGetCurrentIrpStackLocation(Irp); ReceiveInfo = (PTDI_REQUEST_KERNEL_RECEIVE)&(IrpSp->Parameters); + TcpipRecursiveMutexEnter( &TCPLock, TRUE ); + TranContext = IrpSp->FileObject->FsContext; if (TranContext == NULL) { @@ -823,6 +836,8 @@ NTSTATUS DispTdiReceive( } done: + TcpipRecursiveMutexLeave( &TCPLock ); + if (Status != STATUS_PENDING) { DispDataRequestComplete(Irp, Status, BytesReceived); } else @@ -856,6 +871,8 @@ NTSTATUS DispTdiReceiveDatagram( IrpSp = IoGetCurrentIrpStackLocation(Irp); DgramInfo = (PTDI_REQUEST_KERNEL_RECEIVEDG)&(IrpSp->Parameters); + TcpipRecursiveMutexEnter( &TCPLock, TRUE ); + TranContext = IrpSp->FileObject->FsContext; if (TranContext == NULL) { @@ -897,6 +914,8 @@ NTSTATUS DispTdiReceiveDatagram( } done: + TcpipRecursiveMutexLeave( &TCPLock ); + if (Status != STATUS_PENDING) { DispDataRequestComplete(Irp, Status, BytesReceived); } else @@ -929,6 +948,8 @@ NTSTATUS DispTdiSend( IrpSp = IoGetCurrentIrpStackLocation(Irp); SendInfo = (PTDI_REQUEST_KERNEL_SEND)&(IrpSp->Parameters); + TcpipRecursiveMutexEnter( &TCPLock, TRUE ); + TranContext = IrpSp->FileObject->FsContext; if (TranContext == NULL) { @@ -969,6 +990,8 @@ NTSTATUS DispTdiSend( } done: + TcpipRecursiveMutexLeave( &TCPLock ); + if (Status != STATUS_PENDING) { DispDataRequestComplete(Irp, Status, BytesSent); } else @@ -1001,6 +1024,8 @@ NTSTATUS DispTdiSendDatagram( IrpSp = IoGetCurrentIrpStackLocation(Irp); DgramInfo = (PTDI_REQUEST_KERNEL_SENDDG)&(IrpSp->Parameters); + TcpipRecursiveMutexEnter( &TCPLock, TRUE ); + TranContext = IrpSp->FileObject->FsContext; if (TranContext == NULL) { @@ -1042,13 +1067,13 @@ NTSTATUS DispTdiSendDatagram( DataBuffer, BufferSize, &Irp->IoStatus.Information); - else { + else Status = STATUS_UNSUCCESSFUL; - ASSERT(FALSE); - } } done: + TcpipRecursiveMutexLeave( &TCPLock ); + if (Status != STATUS_PENDING) { DispDataRequestComplete(Irp, Status, Irp->IoStatus.Information); } else @@ -1097,7 +1122,7 @@ NTSTATUS DispTdiSetEventHandler(PIRP Irp) Parameters = (PTDI_REQUEST_KERNEL_SET_EVENT)&IrpSp->Parameters; Status = STATUS_SUCCESS; - KeAcquireSpinLock(&AddrFile->Lock, &OldIrql); + TcpipAcquireSpinLock(&AddrFile->Lock, &OldIrql); /* Set the event handler. if an event handler is associated with a specific event, it's flag (RegisteredXxxHandler) is TRUE. @@ -1218,7 +1243,7 @@ NTSTATUS DispTdiSetEventHandler(PIRP Irp) Status = STATUS_INVALID_PARAMETER; } - KeReleaseSpinLock(&AddrFile->Lock, OldIrql); + TcpipReleaseSpinLock(&AddrFile->Lock, OldIrql); return Status; } @@ -1253,10 +1278,11 @@ VOID DispTdiQueryInformationExComplete( */ { PTI_QUERY_CONTEXT QueryContext; + UINT Count = 0; QueryContext = (PTI_QUERY_CONTEXT)Context; if (NT_SUCCESS(Status)) { - CopyBufferToBufferChain( + Count = CopyBufferToBufferChain( QueryContext->InputMdl, FIELD_OFFSET(TCP_REQUEST_QUERY_INFORMATION_EX, Context), (PCHAR)&QueryContext->QueryInfo.Context, @@ -1273,7 +1299,7 @@ VOID DispTdiQueryInformationExComplete( QueryContext->Irp->IoStatus.Information = ByteCount; QueryContext->Irp->IoStatus.Status = Status; - ExFreePoolWithTag(QueryContext, QUERY_CONTEXT_TAG); + exFreePool(QueryContext); } @@ -1336,7 +1362,7 @@ NTSTATUS DispTdiQueryInformationEx( IrpSp->Parameters.DeviceIoControl.Type3InputBuffer; OutputBuffer = Irp->UserBuffer; - QueryContext = ExAllocatePoolWithTag(NonPagedPool, sizeof(TI_QUERY_CONTEXT), QUERY_CONTEXT_TAG); + QueryContext = exAllocatePool(NonPagedPool, sizeof(TI_QUERY_CONTEXT)); if (QueryContext) { _SEH2_TRY { InputMdl = IoAllocateMdl(InputBuffer, @@ -1399,7 +1425,7 @@ NTSTATUS DispTdiQueryInformationEx( IoFreeMdl(OutputMdl); } - ExFreePoolWithTag(QueryContext, QUERY_CONTEXT_TAG); + exFreePool(QueryContext); } else Status = STATUS_INSUFFICIENT_RESOURCES; } else if( InputBufferLength == @@ -1412,7 +1438,7 @@ NTSTATUS DispTdiQueryInformationEx( Size = 0; - QueryContext = ExAllocatePoolWithTag(NonPagedPool, sizeof(TI_QUERY_CONTEXT), QUERY_CONTEXT_TAG); + QueryContext = exAllocatePool(NonPagedPool, sizeof(TI_QUERY_CONTEXT)); if (!QueryContext) return STATUS_INSUFFICIENT_RESOURCES; _SEH2_TRY { @@ -1432,7 +1458,7 @@ NTSTATUS DispTdiQueryInformationEx( if( !NT_SUCCESS(Status) || !InputMdl ) { if( InputMdl ) IoFreeMdl( InputMdl ); - ExFreePoolWithTag(QueryContext, QUERY_CONTEXT_TAG); + exFreePool(QueryContext); return Status; } diff --git a/reactos/drivers/network/tcpip/tcpip/fileobjs.c b/reactos/drivers/network/tcpip/tcpip/fileobjs.c index 88ac1858b1e..866e9ff0694 100644 --- a/reactos/drivers/network/tcpip/tcpip/fileobjs.c +++ b/reactos/drivers/network/tcpip/tcpip/fileobjs.c @@ -153,7 +153,7 @@ VOID AddrFileFree( * Object = Pointer to address file object to free */ { - ExFreePoolWithTag(Object, ADDR_FILE_TAG); + exFreePool(Object); } @@ -165,7 +165,7 @@ VOID ControlChannelFree( * Object = Pointer to address file object to free */ { - ExFreePoolWithTag(Object, CONTROL_CHANNEL_TAG); + exFreePool(Object); } @@ -189,8 +189,7 @@ NTSTATUS FileOpenAddress( TI_DbgPrint(MID_TRACE, ("Called (Proto %d).\n", Protocol)); - AddrFile = ExAllocatePoolWithTag(NonPagedPool, sizeof(ADDRESS_FILE), - ADDR_FILE_TAG); + AddrFile = exAllocatePool(NonPagedPool, sizeof(ADDRESS_FILE)); if (!AddrFile) { TI_DbgPrint(MIN_TRACE, ("Insufficient resources.\n")); return STATUS_INSUFFICIENT_RESOURCES; @@ -213,7 +212,7 @@ NTSTATUS FileOpenAddress( if (!AddrIsUnspecified(&AddrFile->Address) && !AddrLocateInterface(&AddrFile->Address)) { - ExFreePoolWithTag(AddrFile, ADDR_FILE_TAG); + exFreePool(AddrFile); TI_DbgPrint(MIN_TRACE, ("Non-local address given (0x%X).\n", A2S(&AddrFile->Address))); return STATUS_INVALID_PARAMETER; } @@ -231,7 +230,7 @@ NTSTATUS FileOpenAddress( AddrFile->Port != Address->Address[0].Address[0].sin_port) || AddrFile->Port == 0xffff) { - ExFreePoolWithTag(AddrFile, ADDR_FILE_TAG); + exFreePool(AddrFile); return STATUS_INVALID_PARAMETER; } @@ -249,7 +248,7 @@ NTSTATUS FileOpenAddress( AddrFile->Port != Address->Address[0].Address[0].sin_port) || AddrFile->Port == 0xffff) { - ExFreePoolWithTag(AddrFile, ADDR_FILE_TAG); + exFreePool(AddrFile); return STATUS_INVALID_PARAMETER; } @@ -296,6 +295,9 @@ NTSTATUS FileOpenAddress( /* Initialize spin lock that protects the address file object */ KeInitializeSpinLock(&AddrFile->Lock); + /* Set valid flag so the address can be used */ + AF_SET_VALID(AddrFile); + /* Return address file object */ Request->Handle.AddressHandle = AddrFile; @@ -326,7 +328,7 @@ NTSTATUS FileCloseAddress( KIRQL OldIrql; PDATAGRAM_RECEIVE_REQUEST ReceiveRequest; PDATAGRAM_SEND_REQUEST SendRequest; - PLIST_ENTRY CurrentEntry; + PLIST_ENTRY CurrentEntry, NextEntry; AddrFile = Request->Handle.AddressHandle; @@ -337,6 +339,8 @@ NTSTATUS FileCloseAddress( RemoveEntryList(&AddrFile->ListEntry); TcpipReleaseSpinLock(&AddressFileListLock, OldIrql); + TcpipAcquireSpinLock(&AddrFile->Lock, &OldIrql); + /* FIXME: Kill TCP connections on this address file object */ /* Return pending requests with error */ @@ -344,27 +348,45 @@ NTSTATUS FileCloseAddress( TI_DbgPrint(DEBUG_ADDRFILE, ("Aborting receive requests on AddrFile at (0x%X).\n", AddrFile)); /* Go through pending receive request list and cancel them all */ - while ((CurrentEntry = ExInterlockedRemoveHeadList(&AddrFile->ReceiveQueue, &AddrFile->Lock))) { + CurrentEntry = AddrFile->ReceiveQueue.Flink; + while (CurrentEntry != &AddrFile->ReceiveQueue) { + NextEntry = CurrentEntry->Flink; ReceiveRequest = CONTAINING_RECORD(CurrentEntry, DATAGRAM_RECEIVE_REQUEST, ListEntry); + /* Abort the request and free its resources */ + TcpipReleaseSpinLock(&AddrFile->Lock, OldIrql); (*ReceiveRequest->Complete)(ReceiveRequest->Context, STATUS_CANCELLED, 0); - /* ExFreePoolWithTag(ReceiveRequest, DATAGRAM_RECV_TAG); FIXME: WTF? */ + TcpipAcquireSpinLock(&AddrFile->Lock, &OldIrql); + CurrentEntry = NextEntry; } TI_DbgPrint(DEBUG_ADDRFILE, ("Aborting send requests on address file at (0x%X).\n", AddrFile)); /* Go through pending send request list and cancel them all */ - while ((CurrentEntry = ExInterlockedRemoveHeadList(&AddrFile->ReceiveQueue, &AddrFile->Lock))) { - SendRequest = CONTAINING_RECORD(CurrentEntry, DATAGRAM_SEND_REQUEST, ListEntry); + CurrentEntry = AddrFile->TransmitQueue.Flink; + while (CurrentEntry != &AddrFile->TransmitQueue) { + NextEntry = CurrentEntry->Flink; + SendRequest = CONTAINING_RECORD(CurrentEntry, + DATAGRAM_SEND_REQUEST, ListEntry); + /* Abort the request and free its resources */ + TcpipReleaseSpinLock(&AddrFile->Lock, OldIrql); (*SendRequest->Complete)(SendRequest->Context, STATUS_CANCELLED, 0); - ExFreePoolWithTag(SendRequest, DATAGRAM_SEND_TAG); + exFreePool(SendRequest); + TcpipAcquireSpinLock(&AddrFile->Lock, &OldIrql); + CurrentEntry = NextEntry; } + TcpipReleaseSpinLock(&AddrFile->Lock, OldIrql); + /* Protocol specific handling */ switch (AddrFile->Protocol) { case IPPROTO_TCP: TCPFreePort( AddrFile->Port ); - if( AddrFile->Listener ) - TCPClose( AddrFile->Listener ); + if( AddrFile->Listener ) { + TcpipRecursiveMutexEnter(&TCPLock, TRUE); + TCPClose( AddrFile->Listener ); + TcpipRecursiveMutexLeave(&TCPLock); + exFreePool( AddrFile->Listener ); + } break; case IPPROTO_UDP: @@ -403,7 +425,9 @@ NTSTATUS FileOpenConnection( if( !Connection ) return STATUS_NO_MEMORY; + TcpipRecursiveMutexEnter(&TCPLock, TRUE); Status = TCPSocket( Connection, AF_INET, SOCK_STREAM, IPPROTO_TCP ); + TcpipRecursiveMutexLeave(&TCPLock); if( !NT_SUCCESS(Status) ) { TCPFreeConnectionEndpoint( Connection ); @@ -413,11 +437,48 @@ NTSTATUS FileOpenConnection( /* Return connection endpoint file object */ Request->Handle.ConnectionContext = Connection; + /* Add connection endpoint to global list */ + ExInterlockedInsertTailList( + &ConnectionEndpointListHead, + &Connection->ListEntry, + &ConnectionEndpointListLock); + TI_DbgPrint(MAX_TRACE, ("Leaving.\n")); return STATUS_SUCCESS; } + +/* + * FUNCTION: Find a connection by examining the context field. This + * is needed in some situations where a FIN reply is needed after a + * socket is formally broken. + * ARGUMENTS: + * Request = Pointer to TDI request structure for this request + * RETURNS: + * Status of operation + */ +PCONNECTION_ENDPOINT FileFindConnectionByContext( PVOID Context ) { + PLIST_ENTRY Entry; + KIRQL OldIrql; + PCONNECTION_ENDPOINT Connection = NULL; + + TcpipAcquireSpinLock( &ConnectionEndpointListLock, &OldIrql ); + + for( Entry = ConnectionEndpointListHead.Flink; + Entry != &ConnectionEndpointListHead; + Entry = Entry->Flink ) { + Connection = + CONTAINING_RECORD( Entry, CONNECTION_ENDPOINT, ListEntry ); + if( Connection->SocketContext == Context ) break; + else Connection = NULL; + } + + TcpipReleaseSpinLock( &ConnectionEndpointListLock, OldIrql ); + + return Connection; +} + /* * FUNCTION: Closes an connection file object * ARGUMENTS: @@ -429,12 +490,21 @@ NTSTATUS FileCloseConnection( PTDI_REQUEST Request) { PCONNECTION_ENDPOINT Connection; + KIRQL OldIrql; TI_DbgPrint(MID_TRACE, ("Called.\n")); Connection = Request->Handle.ConnectionContext; + TcpipAcquireSpinLock(&ConnectionEndpointListLock, &OldIrql); + RemoveEntryList(&Connection->ListEntry); + TcpipReleaseSpinLock(&ConnectionEndpointListLock, OldIrql); + + TcpipRecursiveMutexEnter( &TCPLock, TRUE ); TCPClose( Connection ); + TcpipRecursiveMutexLeave( &TCPLock ); + + TCPFreeConnectionEndpoint(Connection); TI_DbgPrint(MAX_TRACE, ("Leaving.\n")); @@ -455,8 +525,7 @@ NTSTATUS FileOpenControlChannel( PCONTROL_CHANNEL ControlChannel; TI_DbgPrint(MID_TRACE, ("Called.\n")); - ControlChannel = ExAllocatePoolWithTag(NonPagedPool, sizeof(*ControlChannel), - CONTROL_CHANNEL_TAG); + ControlChannel = exAllocatePool(NonPagedPool, sizeof(*ControlChannel)); if (!ControlChannel) { TI_DbgPrint(MIN_TRACE, ("Insufficient resources.\n")); @@ -496,7 +565,7 @@ NTSTATUS FileCloseControlChannel( PCONTROL_CHANNEL ControlChannel = Request->Handle.ControlChannel; NTSTATUS Status = STATUS_SUCCESS; - ExFreePoolWithTag(ControlChannel, CONTROL_CHANNEL_TAG); + exFreePool(ControlChannel); Request->Handle.ControlChannel = NULL; return Status; diff --git a/reactos/drivers/network/tcpip/tcpip/iinfo.c b/reactos/drivers/network/tcpip/tcpip/iinfo.c index 7a9f35c794f..7494d0a8113 100644 --- a/reactos/drivers/network/tcpip/tcpip/iinfo.c +++ b/reactos/drivers/network/tcpip/tcpip/iinfo.c @@ -32,7 +32,7 @@ TDI_STATUS InfoTdiQueryGetInterfaceMIB(TDIEntityID ID, Interface, IF, ID.tei_entity, ID.tei_instance)); OutData = - (PIFENTRY)ExAllocatePool( NonPagedPool, + (PIFENTRY)exAllocatePool( NonPagedPool, sizeof(IFENTRY) + MAX_IFDESCR_LEN ); if( !OutData ) return TDI_NO_RESOURCES; /* Out of memory */ @@ -99,7 +99,7 @@ TDI_STATUS InfoTdiQueryGetInterfaceMIB(TDIEntityID ID, ID.tei_entity, ID.tei_instance, Size)); Status = InfoCopyOut( (PCHAR)OutData, Size, Buffer, BufferSize ); - ExFreePool( OutData ); + exFreePool( OutData ); TI_DbgPrint(DEBUG_INFO,("Returning %x\n", Status)); @@ -117,14 +117,14 @@ TDI_STATUS InfoTdiQueryGetArptableMIB(TDIEntityID ID, if (MemSize != 0) { - ArpEntries = ExAllocatePool( NonPagedPool, MemSize ); + ArpEntries = exAllocatePoolWithTag( NonPagedPool, MemSize, FOURCC('A','R','P','t') ); if( !ArpEntries ) return STATUS_NO_MEMORY; NBCopyNeighbors( Interface, ArpEntries ); Status = InfoCopyOut( (PVOID)ArpEntries, MemSize, Buffer, BufferSize ); - ExFreePool( ArpEntries ); + exFreePool( ArpEntries ); } else { diff --git a/reactos/drivers/network/tcpip/tcpip/irp.c b/reactos/drivers/network/tcpip/tcpip/irp.c new file mode 100644 index 00000000000..f2fc589d19b --- /dev/null +++ b/reactos/drivers/network/tcpip/tcpip/irp.c @@ -0,0 +1,37 @@ +/* + * COPYRIGHT: See COPYING in the top level directory + * PROJECT: ReactOS TCP/IP protocol driver + * FILE: tcpip/dispatch.h + * PURPOSE: TDI dispatch routines + * PROGRAMMERS: arty + * REVISIONS: + * CSH 01/08-2000 Created + * TODO: Validate device object in all dispatch routines + */ + +#include "precomp.h" + +VOID IRPRemember( PIRP Irp, PCHAR File, UINT Line ) { + TrackWithTag( IRP_TAG, Irp, File, Line ); +} + +NTSTATUS IRPFinish( PIRP Irp, NTSTATUS Status ) { + KIRQL OldIrql; + + UntrackFL( __FILE__, __LINE__, Irp, IRP_TAG ); + + Irp->IoStatus.Status = Status; + + if( Status == STATUS_PENDING ) + IoMarkIrpPending( Irp ); + else { + IoAcquireCancelSpinLock(&OldIrql); + (void)IoSetCancelRoutine( Irp, NULL ); + IoReleaseCancelSpinLock(OldIrql); + + IoCompleteRequest( Irp, IO_NETWORK_INCREMENT ); + } + + return Status; +} + diff --git a/reactos/drivers/network/tcpip/tcpip/lock.c b/reactos/drivers/network/tcpip/tcpip/lock.c index 9a6cdc95fa3..db8ef244f33 100644 --- a/reactos/drivers/network/tcpip/tcpip/lock.c +++ b/reactos/drivers/network/tcpip/tcpip/lock.c @@ -44,3 +44,16 @@ VOID TcpipReleaseFastMutex( PFAST_MUTEX Mutex ) { ExReleaseFastMutex( Mutex ); } +VOID TcpipRecursiveMutexInit( PRECURSIVE_MUTEX RecMutex ) { + RecursiveMutexInit( RecMutex ); +} + +VOID TcpipRecursiveMutexEnter( PRECURSIVE_MUTEX RecMutex, BOOLEAN ToWrite ) { + //TI_DbgPrint(DEBUG_LOCK,("Locking\n")); + RecursiveMutexEnter( RecMutex ); +} + +VOID TcpipRecursiveMutexLeave( PRECURSIVE_MUTEX RecMutex ) { + //TI_DbgPrint(DEBUG_LOCK,("Unlocking\n")); + RecursiveMutexLeave( RecMutex ); +} diff --git a/reactos/drivers/network/tcpip/tcpip/main.c b/reactos/drivers/network/tcpip/tcpip/main.c index d1ce6c73c1d..f8aa2225bde 100644 --- a/reactos/drivers/network/tcpip/tcpip/main.c +++ b/reactos/drivers/network/tcpip/tcpip/main.c @@ -119,25 +119,30 @@ NTSTATUS TiCreateFileObject( TI_DbgPrint(DEBUG_IRP, ("Called. DeviceObject is at (0x%X), IRP is at (0x%X).\n", DeviceObject, Irp)); EaInfo = Irp->AssociatedIrp.SystemBuffer; - +CP /* Parameter check */ /* No EA information means that we're opening for SET/QUERY_INFORMATION * style calls. */ - +#if 0 + if (!EaInfo) { + TI_DbgPrint(MIN_TRACE, ("No EA information in IRP.\n")); + return STATUS_INVALID_PARAMETER; + } +#endif +CP /* Allocate resources here. We release them again if something failed */ - Context = ExAllocatePoolWithTag(NonPagedPool, sizeof(TRANSPORT_CONTEXT), - TRANS_CONTEXT_TAG); + Context = exAllocatePool(NonPagedPool, sizeof(TRANSPORT_CONTEXT)); if (!Context) { TI_DbgPrint(MIN_TRACE, ("Insufficient resources.\n")); return STATUS_INSUFFICIENT_RESOURCES; } - +CP Context->CancelIrps = FALSE; - +CP IrpSp = IoGetCurrentIrpStackLocation(Irp); IrpSp->FileObject->FsContext = Context; Request.RequestContext = Irp; - +CP /* Branch to the right handler */ if (EaInfo && (EaInfo->EaNameLength == TDI_TRANSPORT_ADDRESS_LENGTH) && @@ -145,7 +150,7 @@ NTSTATUS TiCreateFileObject( (&EaInfo->EaName, TdiTransportAddress, TDI_TRANSPORT_ADDRESS_LENGTH) == TDI_TRANSPORT_ADDRESS_LENGTH)) { /* This is a request to open an address */ - +CP /* XXX This should probably be done in IoCreateFile() */ /* Parameter checks */ @@ -164,10 +169,10 @@ NTSTATUS TiCreateFileObject( TI_DbgPrint(MIN_TRACE, ("AddressType: %\n", Address->Address[0].AddressType)); } - ExFreePoolWithTag(Context, TRANS_CONTEXT_TAG); + exFreePool(Context); return STATUS_INVALID_PARAMETER; } - +CP /* Open address file object */ /* Protocol depends on device object so find the protocol */ @@ -181,21 +186,21 @@ NTSTATUS TiCreateFileObject( Status = TiGetProtocolNumber(&IrpSp->FileObject->FileName, &Protocol); if (!NT_SUCCESS(Status)) { TI_DbgPrint(MIN_TRACE, ("Raw IP protocol number is invalid.\n")); - ExFreePoolWithTag(Context, TRANS_CONTEXT_TAG); + exFreePool(Context); return STATUS_INVALID_PARAMETER; } } else { TI_DbgPrint(MIN_TRACE, ("Invalid device object at (0x%X).\n", DeviceObject)); - ExFreePoolWithTag(Context, TRANS_CONTEXT_TAG); + exFreePool(Context); return STATUS_INVALID_PARAMETER; } - +CP Status = FileOpenAddress(&Request, Address, Protocol, NULL); if (NT_SUCCESS(Status)) { IrpSp->FileObject->FsContext2 = (PVOID)TDI_TRANSPORT_ADDRESS_FILE; Context->Handle.AddressHandle = Request.Handle.AddressHandle; } - +CP } else if (EaInfo && (EaInfo->EaNameLength == TDI_CONNECTION_CONTEXT_LENGTH) && (RtlCompareMemory @@ -203,12 +208,12 @@ NTSTATUS TiCreateFileObject( TDI_CONNECTION_CONTEXT_LENGTH) == TDI_CONNECTION_CONTEXT_LENGTH)) { /* This is a request to open a connection endpoint */ - +CP /* Parameter checks */ if (EaInfo->EaValueLength < sizeof(PVOID)) { TI_DbgPrint(MIN_TRACE, ("Parameters are invalid.\n")); - ExFreePoolWithTag(Context, TRANS_CONTEXT_TAG); + exFreePool(Context); return STATUS_INVALID_PARAMETER; } @@ -216,7 +221,7 @@ NTSTATUS TiCreateFileObject( if (DeviceObject != TCPDeviceObject) { TI_DbgPrint(MIN_TRACE, ("Bad device object.\n")); - ExFreePoolWithTag(Context, TRANS_CONTEXT_TAG); + exFreePool(Context); return STATUS_INVALID_PARAMETER; } @@ -239,7 +244,7 @@ NTSTATUS TiCreateFileObject( } if (!NT_SUCCESS(Status)) - ExFreePoolWithTag(Context, TRANS_CONTEXT_TAG); + exFreePool(Context); TI_DbgPrint(DEBUG_IRP, ("Leaving. Status = (0x%X).\n", Status)); @@ -317,6 +322,9 @@ TiDispatchOpenClose( { PIO_STACK_LOCATION IrpSp; NTSTATUS Status; + PTRANSPORT_CONTEXT Context; + + IRPRemember(Irp, __FILE__, __LINE__); // DbgPrint("Called. DeviceObject is at (0x%X), IRP is at (0x%X).\n", DeviceObject, Irp); @@ -330,7 +338,8 @@ TiDispatchOpenClose( /* Close an address file, connection endpoint, or control connection */ case IRP_MJ_CLOSE: - Status = TiCloseFileObject(DeviceObject, Irp); + Context = (PTRANSPORT_CONTEXT)IrpSp->FileObject->FsContext; + Status = TiCloseFileObject(DeviceObject, Irp); break; default: @@ -360,6 +369,8 @@ TiDispatchInternal( BOOLEAN Complete = TRUE; PIO_STACK_LOCATION IrpSp; + IRPRemember(Irp, __FILE__, __LINE__); + IrpSp = IoGetCurrentIrpStackLocation(Irp); TI_DbgPrint(DEBUG_IRP, ("Called. DeviceObject is at (0x%X), IRP is at (0x%X) MN (%d).\n", @@ -462,6 +473,8 @@ TiDispatch( NTSTATUS Status; PIO_STACK_LOCATION IrpSp; + IRPRemember(Irp, __FILE__, __LINE__); + IrpSp = IoGetCurrentIrpStackLocation(Irp); TI_DbgPrint(DEBUG_IRP, ("Called. IRP is at (0x%X).\n", Irp)); @@ -530,6 +543,8 @@ VOID NTAPI TiUnload( } TcpipReleaseSpinLock(&AddressFileListLock, OldIrql); #endif + ChewShutdown(); + /* Cancel timer */ KeCancelTimer(&IPTimer); @@ -567,13 +582,11 @@ VOID NTAPI TiUnload( if (RawIPDeviceObject) IoDeleteDevice(RawIPDeviceObject); - if (IPDeviceObject) { - ChewShutdown(); - IoDeleteDevice(IPDeviceObject); - } + if (IPDeviceObject) + IoDeleteDevice(IPDeviceObject); if (EntityList) - ExFreePoolWithTag(EntityList, TDI_ENTITY_TAG); + exFreePool(EntityList); TI_DbgPrint(MAX_TRACE, ("Leaving.\n")); } @@ -624,22 +637,17 @@ DriverEntry( TI_DbgPrint(MAX_TRACE, ("Called.\n")); + TrackingInit(); + /* TdiInitialize() ? */ /* FIXME: Create symbolic links in Win32 namespace */ - /* Initialize our periodic timer and its associated DPC object. When the - timer expires, the IPTimeout deferred procedure call (DPC) is queued */ - ExInitializeWorkItem( &IpWorkItem, IPTimeout, NULL ); - KeInitializeDpc(&IPTimeoutDpc, IPTimeoutDpcFn, NULL); - KeInitializeTimer(&IPTimer); - /* Create IP device object */ Status = IoCreateDevice(DriverObject, 0, &strIpDeviceName, FILE_DEVICE_NETWORK, 0, FALSE, &IPDeviceObject); if (!NT_SUCCESS(Status)) { TI_DbgPrint(MIN_TRACE, ("Failed to create IP device object. Status (0x%X).\n", Status)); - TiUnload(DriverObject); return Status; } @@ -650,7 +658,8 @@ DriverEntry( FILE_DEVICE_NETWORK, 0, FALSE, &RawIPDeviceObject); if (!NT_SUCCESS(Status)) { TI_DbgPrint(MIN_TRACE, ("Failed to create RawIP device object. Status (0x%X).\n", Status)); - TiUnload(DriverObject); + ChewShutdown(); + IoDeleteDevice(IPDeviceObject); return Status; } @@ -659,7 +668,9 @@ DriverEntry( FILE_DEVICE_NETWORK, 0, FALSE, &UDPDeviceObject); if (!NT_SUCCESS(Status)) { TI_DbgPrint(MIN_TRACE, ("Failed to create UDP device object. Status (0x%X).\n", Status)); - TiUnload(DriverObject); + ChewShutdown(); + IoDeleteDevice(IPDeviceObject); + IoDeleteDevice(RawIPDeviceObject); return Status; } @@ -668,18 +679,23 @@ DriverEntry( FILE_DEVICE_NETWORK, 0, FALSE, &TCPDeviceObject); if (!NT_SUCCESS(Status)) { TI_DbgPrint(MIN_TRACE, ("Failed to create TCP device object. Status (0x%X).\n", Status)); - TiUnload(DriverObject); + ChewShutdown(); + IoDeleteDevice(IPDeviceObject); + IoDeleteDevice(RawIPDeviceObject); + IoDeleteDevice(UDPDeviceObject); return Status; } /* Setup network layer and transport layer entities */ KeInitializeSpinLock(&EntityListLock); - EntityList = ExAllocatePoolWithTag(NonPagedPool, - sizeof(TDIEntityID) * MAX_TDI_ENTITIES, - TDI_ENTITY_TAG ); + EntityList = exAllocatePool(NonPagedPool, sizeof(TDIEntityID) * MAX_TDI_ENTITIES ); if (!EntityList) { TI_DbgPrint(MIN_TRACE, ("Insufficient resources.\n")); - TiUnload(DriverObject); + ChewShutdown(); + IoDeleteDevice(IPDeviceObject); + IoDeleteDevice(RawIPDeviceObject); + IoDeleteDevice(UDPDeviceObject); + IoDeleteDevice(TCPDeviceObject); return STATUS_INSUFFICIENT_RESOURCES; } @@ -689,14 +705,25 @@ DriverEntry( /* Allocate NDIS packet descriptors */ NdisAllocatePacketPool(&NdisStatus, &GlobalPacketPool, 100, sizeof(PACKET_CONTEXT)); if (NdisStatus != NDIS_STATUS_SUCCESS) { - TiUnload(DriverObject); + ChewShutdown(); + IoDeleteDevice(IPDeviceObject); + IoDeleteDevice(RawIPDeviceObject); + IoDeleteDevice(UDPDeviceObject); + IoDeleteDevice(TCPDeviceObject); + exFreePool(EntityList); return STATUS_INSUFFICIENT_RESOURCES; } /* Allocate NDIS buffer descriptors */ NdisAllocateBufferPool(&NdisStatus, &GlobalBufferPool, 100); if (NdisStatus != NDIS_STATUS_SUCCESS) { - TiUnload(DriverObject); + ChewShutdown(); + IoDeleteDevice(IPDeviceObject); + IoDeleteDevice(RawIPDeviceObject); + IoDeleteDevice(UDPDeviceObject); + IoDeleteDevice(TCPDeviceObject); + exFreePool(EntityList); + NdisFreePacketPool(GlobalPacketPool); return STATUS_INSUFFICIENT_RESOURCES; } @@ -718,26 +745,64 @@ DriverEntry( /* Initialize transport level protocol subsystems */ Status = RawIPStartup(); if( !NT_SUCCESS(Status) ) { - TiUnload(DriverObject); - return Status; + IPShutdown(); + ChewShutdown(); + IoDeleteDevice(IPDeviceObject); + IoDeleteDevice(RawIPDeviceObject); + IoDeleteDevice(UDPDeviceObject); + IoDeleteDevice(TCPDeviceObject); + exFreePool(EntityList); + NdisFreePacketPool(GlobalPacketPool); + NdisFreeBufferPool(GlobalBufferPool); + return Status; } Status = UDPStartup(); if( !NT_SUCCESS(Status) ) { - TiUnload(DriverObject); - return Status; + RawIPShutdown(); + IPShutdown(); + ChewShutdown(); + IoDeleteDevice(IPDeviceObject); + IoDeleteDevice(RawIPDeviceObject); + IoDeleteDevice(UDPDeviceObject); + IoDeleteDevice(TCPDeviceObject); + exFreePool(EntityList); + NdisFreePacketPool(GlobalPacketPool); + NdisFreeBufferPool(GlobalBufferPool); + return Status; } Status = TCPStartup(); if( !NT_SUCCESS(Status) ) { - TiUnload(DriverObject); - return Status; + UDPShutdown(); + RawIPShutdown(); + IPShutdown(); + ChewShutdown(); + IoDeleteDevice(IPDeviceObject); + IoDeleteDevice(RawIPDeviceObject); + IoDeleteDevice(UDPDeviceObject); + IoDeleteDevice(TCPDeviceObject); + exFreePool(EntityList); + NdisFreePacketPool(GlobalPacketPool); + NdisFreeBufferPool(GlobalBufferPool); + return Status; } Status = ICMPStartup(); if( !NT_SUCCESS(Status) ) { - TiUnload(DriverObject); - return Status; + TCPShutdown(); + UDPShutdown(); + RawIPShutdown(); + IPShutdown(); + ChewShutdown(); + IoDeleteDevice(IPDeviceObject); + IoDeleteDevice(RawIPDeviceObject); + IoDeleteDevice(UDPDeviceObject); + IoDeleteDevice(TCPDeviceObject); + exFreePool(EntityList); + NdisFreePacketPool(GlobalPacketPool); + NdisFreeBufferPool(GlobalBufferPool); + return Status; } /* Use direct I/O */ @@ -754,11 +819,33 @@ DriverEntry( DriverObject->DriverUnload = TiUnload; + /* Initialize our periodic timer and its associated DPC object. When the + timer expires, the IPTimeout deferred procedure call (DPC) is queued */ + ExInitializeWorkItem( &IpWorkItem, IPTimeout, NULL ); + KeInitializeDpc(&IPTimeoutDpc, IPTimeoutDpcFn, NULL); + KeInitializeTimer(&IPTimer); + + /* Start the periodic timer with an initial and periodic + relative expiration time of IP_TIMEOUT milliseconds */ + DueTime.QuadPart = -(LONGLONG)IP_TIMEOUT * 10000; + KeSetTimerEx(&IPTimer, DueTime, IP_TIMEOUT, &IPTimeoutDpc); + /* Open loopback adapter */ Status = LoopRegisterAdapter(NULL, NULL); if (!NT_SUCCESS(Status)) { TI_DbgPrint(MIN_TRACE, ("Failed to create loopback adapter. Status (0x%X).\n", Status)); - TiUnload(DriverObject); + TCPShutdown(); + UDPShutdown(); + RawIPShutdown(); + IPShutdown(); + ChewShutdown(); + IoDeleteDevice(IPDeviceObject); + IoDeleteDevice(RawIPDeviceObject); + IoDeleteDevice(UDPDeviceObject); + IoDeleteDevice(TCPDeviceObject); + exFreePool(EntityList); + NdisFreePacketPool(GlobalPacketPool); + NdisFreeBufferPool(GlobalBufferPool); return Status; } @@ -775,18 +862,25 @@ DriverEntry( NULL, 0, NULL); - TiUnload(DriverObject); - return Status; + TCPShutdown(); + UDPShutdown(); + RawIPShutdown(); + IPShutdown(); + ChewShutdown(); + IoDeleteDevice(IPDeviceObject); + IoDeleteDevice(RawIPDeviceObject); + IoDeleteDevice(UDPDeviceObject); + IoDeleteDevice(TCPDeviceObject); + exFreePool(EntityList); + NdisFreePacketPool(GlobalPacketPool); + NdisFreeBufferPool(GlobalBufferPool); + return Status; } - /* Start the periodic timer with an initial and periodic - relative expiration time of IP_TIMEOUT milliseconds */ - DueTime.QuadPart = -(LONGLONG)IP_TIMEOUT * 10000; - KeSetTimerEx(&IPTimer, DueTime, IP_TIMEOUT, &IPTimeoutDpc); - return STATUS_SUCCESS; } + VOID NTAPI IPAddInterface( ULONG Unknown0, diff --git a/reactos/drivers/network/tcpip/tcpip/mocklock.c b/reactos/drivers/network/tcpip/tcpip/mocklock.c index 0aa957c4035..d2ef46b3a56 100644 --- a/reactos/drivers/network/tcpip/tcpip/mocklock.c +++ b/reactos/drivers/network/tcpip/tcpip/mocklock.c @@ -45,3 +45,12 @@ VOID TcpipAcquireFastMutex( PFAST_MUTEX Mutex ) { VOID TcpipReleaseFastMutex( PFAST_MUTEX Mutex ) { } +VOID TcpipRecursiveMutexInit( PRECURSIVE_MUTEX RecMutex ) { +} + +UINT TcpipRecursiveMutexEnter( PRECURSIVE_MUTEX RecMutex, BOOL ToWrite ) { + return 0; +} + +VOID TcpipRecursiveMutexLeave( PRECURSIVE_MUTEX RecMutex ) { +} diff --git a/reactos/drivers/network/tcpip/tcpip/ninfo.c b/reactos/drivers/network/tcpip/tcpip/ninfo.c index 293eb19a027..af4fb99723e 100644 --- a/reactos/drivers/network/tcpip/tcpip/ninfo.c +++ b/reactos/drivers/network/tcpip/tcpip/ninfo.c @@ -22,9 +22,9 @@ TDI_STATUS InfoTdiQueryGetRouteTable( PIP_INTERFACE IF, PNDIS_BUFFER Buffer, PUI UINT RtCount = CountFIBs(IF); UINT Size = sizeof( IPROUTE_ENTRY ) * RtCount; PFIB_ENTRY RCache = - ExAllocatePool( NonPagedPool, sizeof( FIB_ENTRY ) * RtCount ), + exAllocatePool( NonPagedPool, sizeof( FIB_ENTRY ) * RtCount ), RCacheCur = RCache; - PIPROUTE_ENTRY RouteEntries = ExAllocatePool( NonPagedPool, Size ), + PIPROUTE_ENTRY RouteEntries = exAllocatePool( NonPagedPool, Size ), RtCurrent = RouteEntries; UINT i; @@ -32,8 +32,8 @@ TDI_STATUS InfoTdiQueryGetRouteTable( PIP_INTERFACE IF, PNDIS_BUFFER Buffer, PUI RtCount, RCache)); if( !RCache || !RouteEntries ) { - if( RCache ) ExFreePool( RCache ); - if( RouteEntries ) ExFreePool( RouteEntries ); + if( RCache ) exFreePool( RCache ); + if( RouteEntries ) exFreePool( RouteEntries ); return TDI_NO_RESOURCES; } @@ -83,8 +83,8 @@ TDI_STATUS InfoTdiQueryGetRouteTable( PIP_INTERFACE IF, PNDIS_BUFFER Buffer, PUI Status = InfoCopyOut( (PCHAR)RouteEntries, Size, Buffer, BufferSize ); - ExFreePool( RouteEntries ); - ExFreePool( RCache ); + exFreePool( RouteEntries ); + exFreePool( RCache ); TI_DbgPrint(DEBUG_INFO, ("Returning %08x\n", Status)); @@ -118,7 +118,7 @@ TDI_STATUS InfoTdiQueryGetAddrTable(TDIEntityID ID, return TDI_INVALID_PARAMETER; } - IPEntry = ExAllocatePool(NonPagedPool, sizeof(IPADDR_ENTRY)); + IPEntry = exAllocatePool(NonPagedPool, sizeof(IPADDR_ENTRY)); if (!IPEntry) { TcpipReleaseSpinLock(&EntityListLock, OldIrql); @@ -143,7 +143,7 @@ TDI_STATUS InfoTdiQueryGetAddrTable(TDIEntityID ID, InfoCopyOut((PCHAR)IPEntry, sizeof(IPADDR_ENTRY), Buffer, BufferSize); - ExFreePool(IPEntry); + exFreePool(IPEntry); return TDI_SUCCESS; } diff --git a/reactos/lib/drivers/ip/ip.rbuild b/reactos/lib/drivers/ip/ip.rbuild index 6a3e5500c30..d6ee690692a 100644 --- a/reactos/lib/drivers/ip/ip.rbuild +++ b/reactos/lib/drivers/ip/ip.rbuild @@ -17,6 +17,7 @@ interface.c ip.c loopback.c + memtrack.c neighbor.c ports.c receive.c diff --git a/reactos/lib/drivers/ip/network/address.c b/reactos/lib/drivers/ip/network/address.c index 6ddbfd97e6d..974dc7103a8 100644 --- a/reactos/lib/drivers/ip/network/address.c +++ b/reactos/lib/drivers/ip/network/address.c @@ -106,7 +106,7 @@ VOID IPAddressFree( * Nothing */ { - ExFreePoolWithTag(Object, IP_ADDRESS_TAG); + exFreePool(Object); } diff --git a/reactos/lib/drivers/ip/network/ip.c b/reactos/lib/drivers/ip/network/ip.c index 2d3621ba60f..f13dd614e8c 100644 --- a/reactos/lib/drivers/ip/network/ip.c +++ b/reactos/lib/drivers/ip/network/ip.c @@ -39,7 +39,7 @@ VOID FreeIF( * Object = Pointer to an interface structure */ { - ExFreePoolWithTag(Object, IP_INTERFACE_TAG); + exFreePool(Object); } PIP_PACKET IPInitializePacket( @@ -56,6 +56,8 @@ PIP_PACKET IPInitializePacket( /* FIXME: Is this needed? */ RtlZeroMemory(IPPacket, sizeof(IP_PACKET)); + INIT_TAG(IPPacket, 'TKPI'); + IPPacket->Free = DontFreePacket; IPPacket->Type = Type; @@ -71,6 +73,9 @@ void NTAPI IPTimeout( PVOID Context ) { /* Clean possible outdated cached neighbor addresses */ NBTimeout(); + + /* Call upper layer timeout routines */ + TCPTimeout(); } @@ -137,13 +142,14 @@ PIP_INTERFACE IPCreateInterface( } #endif - IF = ExAllocatePoolWithTag(NonPagedPool, sizeof(IP_INTERFACE), - IP_INTERFACE_TAG); + IF = exAllocatePool(NonPagedPool, sizeof(IP_INTERFACE)); if (!IF) { TI_DbgPrint(MIN_TRACE, ("Insufficient resources.\n")); return NULL; } + INIT_TAG(IF, 'ECAF'); + RtlZeroMemory(IF, sizeof(IP_INTERFACE)); IF->Free = FreeIF; @@ -162,11 +168,10 @@ PIP_INTERFACE IPCreateInterface( TcpipInitializeSpinLock(&IF->Lock); - IF->TCPContext = ExAllocatePoolWithTag - ( NonPagedPool, sizeof(OSK_IFADDR) + 2 * sizeof( struct sockaddr_in ), - OSKITTCP_CONTEXT_TAG ); + IF->TCPContext = exAllocatePool + ( NonPagedPool, sizeof(OSK_IFADDR) + 2 * sizeof( struct sockaddr_in ) ); if (!IF->TCPContext) { - ExFreePoolWithTag(IF, IP_INTERFACE_TAG); + exFreePool(IF); return NULL; } @@ -192,8 +197,8 @@ VOID IPDestroyInterface( RemoveTDIInterfaceEntity( IF ); #endif - ExFreePoolWithTag(IF->TCPContext, OSKITTCP_CONTEXT_TAG); - ExFreePoolWithTag(IF, IP_INTERFACE_TAG); + exFreePool(IF->TCPContext); + exFreePool(IF); } VOID IPAddInterfaceRoute( PIP_INTERFACE IF ) { @@ -359,7 +364,7 @@ NTSTATUS IPStartup(PUNICODE_STRING RegistryPath) NULL, /* Free routine */ 0, /* Flags */ sizeof(IPDATAGRAM_REASSEMBLY), /* Size of each entry */ - DATAGRAM_REASSEMBLY_TAG, /* Tag */ + 'RDPI', /* Tag */ 0); /* Depth */ ExInitializeNPagedLookasideList( @@ -368,7 +373,7 @@ NTSTATUS IPStartup(PUNICODE_STRING RegistryPath) NULL, /* Free routine */ 0, /* Flags */ sizeof(IP_FRAGMENT), /* Size of each entry */ - DATAGRAM_FRAGMENT_TAG, /* Tag */ + 'GFPI', /* Tag */ 0); /* Depth */ ExInitializeNPagedLookasideList( @@ -377,7 +382,7 @@ NTSTATUS IPStartup(PUNICODE_STRING RegistryPath) NULL, /* Free routine */ 0, /* Flags */ sizeof(IPDATAGRAM_HOLE), /* Size of each entry */ - DATAGRAM_HOLE_TAG, /* Tag */ + 'LHPI', /* Tag */ 0); /* Depth */ /* Start routing subsystem */ diff --git a/reactos/lib/drivers/ip/network/memtrack.c b/reactos/lib/drivers/ip/network/memtrack.c new file mode 100644 index 00000000000..5e8304f913b --- /dev/null +++ b/reactos/lib/drivers/ip/network/memtrack.c @@ -0,0 +1,153 @@ +#define MEMTRACK_NO_POOL +#include "precomp.h" + + +#if DBG +#define TRACK_TAG 'KCrT' + +static LIST_ENTRY AllocatedObjectsList; +static KSPIN_LOCK AllocatedObjectsLock; +static NPAGED_LOOKASIDE_LIST AllocatedObjectsLookasideList; + +VOID TrackingInit() { + TcpipInitializeSpinLock( &AllocatedObjectsLock ); + InitializeListHead( &AllocatedObjectsList ); + ExInitializeNPagedLookasideList(&AllocatedObjectsLookasideList, + NULL, + NULL, + 0, + sizeof(ALLOCATION_TRACKER), + TRACK_TAG, + 0 ); +} + +VOID ShowTrackedThing( PCHAR What, PALLOCATION_TRACKER Thing, BOOLEAN ForceShow ) { + + if (ForceShow) + { + DbgPrint("[%s] Thing %08x %c%c%c%c (%s:%d)\n", + What, + Thing->Thing, + ((PCHAR)&Thing->Tag)[3], + ((PCHAR)&Thing->Tag)[2], + ((PCHAR)&Thing->Tag)[1], + ((PCHAR)&Thing->Tag)[0], + Thing->FileName, + Thing->LineNo); + } + else + { + TI_DbgPrint(MAX_TRACE, + ("[%s] Thing %08x %c%c%c%c (%s:%d)\n", + What, + Thing->Thing, + ((PCHAR)&Thing->Tag)[3], + ((PCHAR)&Thing->Tag)[2], + ((PCHAR)&Thing->Tag)[1], + ((PCHAR)&Thing->Tag)[0], + Thing->FileName, + Thing->LineNo)); + } +} + +VOID TrackWithTag( ULONG Tag, PVOID Thing, PCHAR FileName, ULONG LineNo ) { + PALLOCATION_TRACKER TrackedThing = + ExAllocateFromNPagedLookasideList( &AllocatedObjectsLookasideList ); + + KIRQL OldIrql; + PLIST_ENTRY Entry; + PALLOCATION_TRACKER ThingInList; + + if (!TrackedThing) return; + + TrackedThing->Tag = Tag; + TrackedThing->Thing = Thing; + TrackedThing->FileName = FileName; + TrackedThing->LineNo = LineNo; + + ShowTrackedThing( "Alloc", TrackedThing, FALSE ); + + TcpipAcquireSpinLock( &AllocatedObjectsLock, &OldIrql ); + Entry = AllocatedObjectsList.Flink; + while( Entry != &AllocatedObjectsList ) { + ThingInList = CONTAINING_RECORD(Entry, ALLOCATION_TRACKER, Entry); + if( ThingInList->Thing == Thing ) { + RemoveEntryList(Entry); + + ShowTrackedThing( "Double Alloc (Item in list)", ThingInList, TRUE ); + ShowTrackedThing( "Double Alloc (Item not in list)", TrackedThing, TRUE ); + + ExFreeToNPagedLookasideList( &AllocatedObjectsLookasideList, + ThingInList ); + + break; + } + Entry = Entry->Flink; + } + + InsertHeadList( &AllocatedObjectsList, &TrackedThing->Entry ); + + TcpipReleaseSpinLock( &AllocatedObjectsLock, OldIrql ); +} + +VOID UntrackFL( PCHAR File, ULONG Line, PVOID Thing, ULONG Tag ) { + KIRQL OldIrql; + PLIST_ENTRY Entry; + PALLOCATION_TRACKER ThingInList; + + TcpipAcquireSpinLock( &AllocatedObjectsLock, &OldIrql ); + Entry = AllocatedObjectsList.Flink; + while( Entry != &AllocatedObjectsList ) { + ThingInList = CONTAINING_RECORD(Entry, ALLOCATION_TRACKER, Entry); + if( ThingInList->Thing == Thing ) { + RemoveEntryList(Entry); + + ShowTrackedThing( "Free ", ThingInList, FALSE ); + + if ( ThingInList->Tag != Tag ) { + DbgPrint("UNTRACK: TAG DOES NOT MATCH (%x)\n", Thing); + ShowTrackedThing("Tag Mismatch (Item in list)", ThingInList, TRUE); + ASSERT( FALSE ); + } + + ExFreeToNPagedLookasideList( &AllocatedObjectsLookasideList, + ThingInList ); + + TcpipReleaseSpinLock( &AllocatedObjectsLock, OldIrql ); + + return; + } + Entry = Entry->Flink; + } + TcpipReleaseSpinLock( &AllocatedObjectsLock, OldIrql ); + + DbgPrint("[Double Free] Thing %08x %c%c%c%c (%s:%d)\n", + Thing, + ((PCHAR)&Tag)[3], + ((PCHAR)&Tag)[2], + ((PCHAR)&Tag)[1], + ((PCHAR)&Tag)[0], + File, + Line); + + ASSERT( FALSE ); +} + +VOID TrackDumpFL( PCHAR File, ULONG Line ) { + KIRQL OldIrql; + PLIST_ENTRY Entry; + PALLOCATION_TRACKER Thing; + + TI_DbgPrint(MAX_TRACE,("Dump: %s:%d\n", File, Line)); + + TcpipAcquireSpinLock( &AllocatedObjectsLock, &OldIrql ); + Entry = AllocatedObjectsList.Flink; + while( Entry != &AllocatedObjectsList ) { + Thing = CONTAINING_RECORD(Entry, ALLOCATION_TRACKER, Entry); + ShowTrackedThing( "Dump ", Thing, FALSE ); + Entry = Entry->Flink; + } + TcpipReleaseSpinLock( &AllocatedObjectsLock, OldIrql ); +} + +#endif /* DBG */ diff --git a/reactos/lib/drivers/ip/network/neighbor.c b/reactos/lib/drivers/ip/network/neighbor.c index ae5e3a5bb19..375aac19457 100644 --- a/reactos/lib/drivers/ip/network/neighbor.c +++ b/reactos/lib/drivers/ip/network/neighbor.c @@ -21,7 +21,7 @@ VOID NBCompleteSend( PVOID Context, ASSERT_KM_POINTER(Packet->Complete); Packet->Complete( Packet->Context, Packet->Packet, Status ); TI_DbgPrint(MID_TRACE, ("Completed\n")); - ExFreePoolWithTag( Packet, NEIGHBOR_PACKET_TAG ); + exFreePool( Packet ); TI_DbgPrint(MID_TRACE, ("Freed\n")); } @@ -84,7 +84,7 @@ VOID NBFlushPacketQueue( PNEIGHBOR_CACHE_ENTRY NCE, Packet->Packet, ErrorCode ); - ExFreePoolWithTag( Packet, NEIGHBOR_PACKET_TAG ); + exFreePool( Packet ); } } @@ -128,7 +128,7 @@ VOID NBTimeout(VOID) *PrevNCE = NCE->Next; NBFlushPacketQueue(NCE, NDIS_STATUS_REQUEST_ABORTED); - ExFreePoolWithTag(NCE, NCE_TAG); + exFreePool(NCE); continue; } @@ -179,7 +179,7 @@ VOID NBShutdown(VOID) /* Flush wait queue */ NBFlushPacketQueue( CurNCE, NDIS_STATUS_NOT_ACCEPTED ); - ExFreePoolWithTag(CurNCE, NCE_TAG); + exFreePool(CurNCE); CurNCE = NextNCE; } @@ -241,15 +241,16 @@ PNEIGHBOR_CACHE_ENTRY NBAddNeighbor( "LinkAddress (0x%X) LinkAddressLength (%d) State (0x%X)\n", Interface, Address, LinkAddress, LinkAddressLength, State)); - NCE = ExAllocatePoolWithTag - (NonPagedPool, sizeof(NEIGHBOR_CACHE_ENTRY) + LinkAddressLength, - NCE_TAG); + NCE = exAllocatePool + (NonPagedPool, sizeof(NEIGHBOR_CACHE_ENTRY) + LinkAddressLength); if (NCE == NULL) { TI_DbgPrint(MIN_TRACE, ("Insufficient resources.\n")); return NULL; } + INIT_TAG(NCE, ' ECN'); + NCE->Interface = Interface; NCE->Address = *Address; NCE->LinkAddressLength = LinkAddressLength; @@ -451,8 +452,7 @@ BOOLEAN NBQueuePacket( (DEBUG_NCACHE, ("Called. NCE (0x%X) NdisPacket (0x%X).\n", NCE, NdisPacket)); - Packet = ExAllocatePoolWithTag( NonPagedPool, sizeof(NEIGHBOR_PACKET), - NEIGHBOR_PACKET_TAG ); + Packet = exAllocatePool( NonPagedPool, sizeof(NEIGHBOR_PACKET) ); if( !Packet ) return FALSE; /* FIXME: Should we limit the number of queued packets? */ @@ -514,7 +514,7 @@ VOID NBRemoveNeighbor( *PrevNCE = CurNCE->Next; NBFlushPacketQueue( CurNCE, NDIS_STATUS_REQUEST_ABORTED ); - ExFreePoolWithTag(CurNCE, NCE_TAG); + exFreePool(CurNCE); break; } diff --git a/reactos/lib/drivers/ip/network/ports.c b/reactos/lib/drivers/ip/network/ports.c index cd9dbd2f05f..c8b0835c0f1 100644 --- a/reactos/lib/drivers/ip/network/ports.c +++ b/reactos/lib/drivers/ip/network/ports.c @@ -17,8 +17,7 @@ NTSTATUS PortsStartup( PPORT_SET PortSet, PortSet->PortsToOversee = PortsToManage; PortSet->ProtoBitBuffer = - ExAllocatePoolWithTag( NonPagedPool, (PortSet->PortsToOversee + 7) / 8, - PORT_SET_TAG ); + exAllocatePool( NonPagedPool, (PortSet->PortsToOversee + 7) / 8 ); if(!PortSet->ProtoBitBuffer) return STATUS_INSUFFICIENT_RESOURCES; RtlInitializeBitMap( &PortSet->ProtoBitmap, PortSet->ProtoBitBuffer, @@ -29,7 +28,7 @@ NTSTATUS PortsStartup( PPORT_SET PortSet, } VOID PortsShutdown( PPORT_SET PortSet ) { - ExFreePoolWithTag( PortSet->ProtoBitBuffer, PORT_SET_TAG ); + exFreePool( PortSet->ProtoBitBuffer ); } VOID DeallocatePort( PPORT_SET PortSet, ULONG Port ) { diff --git a/reactos/lib/drivers/ip/network/receive.c b/reactos/lib/drivers/ip/network/receive.c index afdca21600f..174b647abfd 100644 --- a/reactos/lib/drivers/ip/network/receive.c +++ b/reactos/lib/drivers/ip/network/receive.c @@ -35,7 +35,7 @@ PIPDATAGRAM_HOLE CreateHoleDescriptor( TI_DbgPrint(DEBUG_IP, ("Called. First (%d) Last (%d).\n", First, Last)); - Hole = ExAllocateFromNPagedLookasideList(&IPHoleList); + Hole = exAllocateFromNPagedLookasideList(&IPHoleList); if (!Hole) { TI_DbgPrint(MIN_TRACE, ("Insufficient resources.\n")); return NULL; @@ -76,7 +76,7 @@ VOID FreeIPDR( TI_DbgPrint(DEBUG_IP, ("Freeing hole descriptor at (0x%X).\n", CurrentH)); /* And free the hole descriptor */ - ExFreeToNPagedLookasideList(&IPHoleList, CurrentH); + exFreeToNPagedLookasideList(&IPHoleList, CurrentH); CurrentEntry = NextEntry; } @@ -92,18 +92,18 @@ VOID FreeIPDR( TI_DbgPrint(DEBUG_IP, ("Freeing fragment data at (0x%X).\n", CurrentF->Data)); /* Free the fragment data buffer */ - ExFreePoolWithTag(CurrentF->Data, FRAGMENT_DATA_TAG); + exFreePool(CurrentF->Data); TI_DbgPrint(DEBUG_IP, ("Freeing fragment at (0x%X).\n", CurrentF)); /* And free the fragment descriptor */ - ExFreeToNPagedLookasideList(&IPFragmentList, CurrentF); + exFreeToNPagedLookasideList(&IPFragmentList, CurrentF); CurrentEntry = NextEntry; } TI_DbgPrint(DEBUG_IP, ("Freeing IPDR data at (0x%X).\n", IPDR)); - ExFreeToNPagedLookasideList(&IPDRList, IPDR); + exFreeToNPagedLookasideList(&IPDRList, IPDR); } @@ -205,7 +205,7 @@ ReassembleDatagram( RtlCopyMemory(&IPPacket->DstAddr, &IPDR->DstAddr, sizeof(IP_ADDRESS)); /* Allocate space for full IP datagram */ - IPPacket->Header = ExAllocatePoolWithTag(NonPagedPool, IPPacket->TotalSize, PACKET_BUFFER_TAG); + IPPacket->Header = exAllocatePool(NonPagedPool, IPPacket->TotalSize); if (!IPPacket->Header) { TI_DbgPrint(MIN_TRACE, ("Insufficient resources.\n")); (*IPPacket->Free)(IPPacket); @@ -297,7 +297,7 @@ VOID ProcessFragment( TI_DbgPrint(DEBUG_IP, ("Starting new assembly.\n")); /* We don't have a reassembly structure, create one */ - IPDR = ExAllocateFromNPagedLookasideList(&IPDRList); + IPDR = exAllocateFromNPagedLookasideList(&IPDRList); if (!IPDR) /* We don't have the resources to process this packet, discard it */ return; @@ -308,7 +308,7 @@ VOID ProcessFragment( Hole = CreateHoleDescriptor(0, 65536); if (!Hole) { /* We don't have the resources to process this packet, discard it */ - ExFreeToNPagedLookasideList(&IPDRList, IPDR); + exFreeToNPagedLookasideList(&IPDRList, IPDR); return; } AddrInitIPv4(&IPDR->SrcAddr, IPv4Header->SrcAddr); @@ -361,7 +361,7 @@ VOID ProcessFragment( NewHole = CreateHoleDescriptor(Hole->First, FragFirst - 1); if (!NewHole) { /* We don't have the resources to process this packet, discard it */ - ExFreeToNPagedLookasideList(&IPHoleList, Hole); + exFreeToNPagedLookasideList(&IPHoleList, Hole); Cleanup(&IPDR->Lock, OldIrql, IPDR); return; } @@ -374,7 +374,7 @@ VOID ProcessFragment( NewHole = CreateHoleDescriptor(FragLast + 1, Hole->Last); if (!NewHole) { /* We don't have the resources to process this packet, discard it */ - ExFreeToNPagedLookasideList(&IPHoleList, Hole); + exFreeToNPagedLookasideList(&IPHoleList, Hole); Cleanup(&IPDR->Lock, OldIrql, IPDR); return; } @@ -383,7 +383,7 @@ VOID ProcessFragment( InsertTailList(&IPDR->HoleListHead, &NewHole->ListEntry); } - ExFreeToNPagedLookasideList(&IPHoleList, Hole); + exFreeToNPagedLookasideList(&IPHoleList, Hole); /* If this is the first fragment, save the IP header */ if (FragFirst == 0) { @@ -397,7 +397,7 @@ VOID ProcessFragment( /* Create a buffer, copy the data into it and put it in the fragment list */ - Fragment = ExAllocateFromNPagedLookasideList(&IPFragmentList); + Fragment = exAllocateFromNPagedLookasideList(&IPFragmentList); if (!Fragment) { /* We don't have the resources to process this packet, discard it */ Cleanup(&IPDR->Lock, OldIrql, IPDR); @@ -407,10 +407,10 @@ VOID ProcessFragment( TI_DbgPrint(DEBUG_IP, ("Fragment descriptor allocated at (0x%X).\n", Fragment)); Fragment->Size = IPPacket->TotalSize - IPPacket->HeaderSize; - Fragment->Data = ExAllocatePoolWithTag(NonPagedPool, Fragment->Size, FRAGMENT_DATA_TAG); + Fragment->Data = exAllocatePool(NonPagedPool, Fragment->Size); if (!Fragment->Data) { /* We don't have the resources to process this packet, discard it */ - ExFreeToNPagedLookasideList(&IPFragmentList, Fragment); + exFreeToNPagedLookasideList(&IPFragmentList, Fragment); Cleanup(&IPDR->Lock, OldIrql, IPDR); return; } @@ -465,7 +465,7 @@ VOID ProcessFragment( IF->Stats.InBytes += Datagram.TotalSize; /* We're done with this datagram */ - ExFreePoolWithTag(Datagram.Header, PACKET_BUFFER_TAG); + exFreePool(Datagram.Header); TI_DbgPrint(MAX_TRACE, ("Freeing datagram at (0x%X).\n", Datagram)); (*Datagram.Free)(&Datagram); } else diff --git a/reactos/lib/drivers/ip/network/router.c b/reactos/lib/drivers/ip/network/router.c index d5411240549..c2b79a2f968 100644 --- a/reactos/lib/drivers/ip/network/router.c +++ b/reactos/lib/drivers/ip/network/router.c @@ -51,7 +51,7 @@ VOID FreeFIB( * Object = Pointer to an forward information base structure */ { - ExFreePoolWithTag(Object, FIB_TAG); + exFreePool(Object); } @@ -217,12 +217,14 @@ PFIB_ENTRY RouterAddRoute( A2S(Netmask), A2S(&Router->Address))); - FIBE = ExAllocatePoolWithTag(NonPagedPool, sizeof(FIB_ENTRY), FIB_TAG); + FIBE = exAllocatePool(NonPagedPool, sizeof(FIB_ENTRY)); if (!FIBE) { TI_DbgPrint(MIN_TRACE, ("Insufficient resources.\n")); return NULL; } + INIT_TAG(Router, 'TUOR'); + RtlCopyMemory( &FIBE->NetworkAddress, NetworkAddress, sizeof(FIBE->NetworkAddress) ); RtlCopyMemory( &FIBE->Netmask, Netmask, diff --git a/reactos/lib/drivers/ip/network/routines.c b/reactos/lib/drivers/ip/network/routines.c index 44aa2761076..6407ecb25c7 100644 --- a/reactos/lib/drivers/ip/network/routines.c +++ b/reactos/lib/drivers/ip/network/routines.c @@ -115,11 +115,11 @@ VOID DisplayTCPPacket( if (IPPacket->NdisPacket) { NdisQueryPacket(IPPacket->NdisPacket, NULL, NULL, NULL, &Length); - Buffer = ExAllocatePool(NonPagedPool, Length); + Buffer = exAllocatePool(NonPagedPool, Length); if (Buffer) { Length = CopyPacketToBuffer(Buffer, IPPacket->NdisPacket, 0, Length); DisplayTCPHeader(Buffer, Length); - ExFreePool(Buffer); + exFreePool(Buffer); } } else { Buffer = IPPacket->Header; diff --git a/reactos/lib/drivers/ip/network/transmit.c b/reactos/lib/drivers/ip/network/transmit.c index b97318223f2..554f5778cbf 100644 --- a/reactos/lib/drivers/ip/network/transmit.c +++ b/reactos/lib/drivers/ip/network/transmit.c @@ -42,7 +42,7 @@ VOID IPSendComplete { FreeNdisPacket(IFC->NdisPacket); IFC->Complete(IFC->Context, IFC->Datagram, Status); - ExFreePoolWithTag(IFC, IFC_TAG); + exFreePool(IFC); } } else { TI_DbgPrint(MAX_TRACE, ("Calling completion handler.\n")); @@ -50,7 +50,7 @@ VOID IPSendComplete /* There are no more fragments to transmit, so call completion handler */ FreeNdisPacket(IFC->NdisPacket); IFC->Complete(IFC->Context, IFC->Datagram, NdisStatus); - ExFreePoolWithTag(IFC, IFC_TAG); + exFreePool(IFC); } } @@ -178,7 +178,7 @@ NTSTATUS SendFragments( TI_DbgPrint(MAX_TRACE, ("Fragment buffer is %d bytes\n", BufferSize)); - IFC = ExAllocatePoolWithTag(NonPagedPool, sizeof(IPFRAGMENT_CONTEXT), IFC_TAG); + IFC = exAllocatePool(NonPagedPool, sizeof(IPFRAGMENT_CONTEXT)); if (IFC == NULL) return STATUS_INSUFFICIENT_RESOURCES; @@ -187,7 +187,7 @@ NTSTATUS SendFragments( ( &IFC->NdisPacket, NULL, BufferSize ); if( !NT_SUCCESS(NdisStatus) ) { - ExFreePoolWithTag( IFC, IFC_TAG ); + exFreePool( IFC ); return NdisStatus; } @@ -215,14 +215,14 @@ NTSTATUS SendFragments( if (!PrepareNextFragment(IFC)) { FreeNdisPacket(IFC->NdisPacket); - ExFreePoolWithTag(IFC, IFC_TAG); + exFreePool(IFC); return NDIS_STATUS_FAILURE; } if (!NT_SUCCESS((NdisStatus = IPSendFragment(IFC->NdisPacket, NCE, IFC)))) { FreeNdisPacket(IFC->NdisPacket); - ExFreePoolWithTag(IFC, IFC_TAG); + exFreePool(IFC); } return NdisStatus; diff --git a/reactos/lib/drivers/ip/transport/datagram/datagram.c b/reactos/lib/drivers/ip/transport/datagram/datagram.c index 3c92aa26002..70660605950 100644 --- a/reactos/lib/drivers/ip/transport/datagram/datagram.c +++ b/reactos/lib/drivers/ip/transport/datagram/datagram.c @@ -10,14 +10,13 @@ #include "precomp.h" -BOOLEAN DGRemoveIRP( +VOID DGRemoveIRP( PADDRESS_FILE AddrFile, PIRP Irp) { PLIST_ENTRY ListEntry; PDATAGRAM_RECEIVE_REQUEST ReceiveRequest; KIRQL OldIrql; - BOOLEAN Found = FALSE; TI_DbgPrint(MAX_TRACE, ("Called (Cancel IRP %08x for file %08x).\n", Irp, AddrFile)); @@ -36,8 +35,7 @@ BOOLEAN DGRemoveIRP( if (ReceiveRequest->Irp == Irp) { RemoveEntryList(&ReceiveRequest->ListEntry); - ExFreePoolWithTag(ReceiveRequest, DATAGRAM_RECV_TAG); - Found = TRUE; + exFreePool(ReceiveRequest); break; } } @@ -45,8 +43,6 @@ BOOLEAN DGRemoveIRP( KeReleaseSpinLock(&AddrFile->Lock, OldIrql); TI_DbgPrint(MAX_TRACE, ("Done.\n")); - - return Found; } VOID DGDeliverData( @@ -83,7 +79,7 @@ VOID DGDeliverData( TI_DbgPrint(MAX_TRACE, ("Called.\n")); - KeAcquireSpinLock(&AddrFile->Lock, &OldIrql); + TcpipAcquireSpinLock(&AddrFile->Lock, &OldIrql); if (AddrFile->Protocol == IPPROTO_UDP) { @@ -140,7 +136,7 @@ VOID DGDeliverData( &SrcAddress->Address.IPv4Address, sizeof(SrcAddress->Address.IPv4Address) ); - KeReleaseSpinLock(&AddrFile->Lock, OldIrql); + TcpipReleaseSpinLock(&AddrFile->Lock, OldIrql); /* Complete the receive request */ if (Current->BufferSize < DataSize) @@ -148,11 +144,11 @@ VOID DGDeliverData( else Current->Complete(Current->Context, STATUS_SUCCESS, DataSize); - KeAcquireSpinLock(&AddrFile->Lock, &OldIrql); + TcpipAcquireSpinLock(&AddrFile->Lock, &OldIrql); } } - KeReleaseSpinLock(&AddrFile->Lock, OldIrql); + TcpipReleaseSpinLock(&AddrFile->Lock, OldIrql); } else if (AddrFile->RegisteredReceiveDatagramHandler) { @@ -161,6 +157,8 @@ VOID DGDeliverData( ReceiveHandler = AddrFile->ReceiveDatagramHandler; HandlerContext = AddrFile->ReceiveDatagramHandlerContext; + TcpipReleaseSpinLock(&AddrFile->Lock, OldIrql); + if (SrcAddress->Type == IP_ADDRESS_V4) { AddressLength = sizeof(IPv4_RAW_ADDRESS); @@ -172,8 +170,6 @@ VOID DGDeliverData( SourceAddress = SrcAddress->Address.IPv6Address; } - KeReleaseSpinLock(&AddrFile->Lock, OldIrql); - Status = (*ReceiveHandler)(HandlerContext, AddressLength, SourceAddress, @@ -188,7 +184,7 @@ VOID DGDeliverData( } else { - KeReleaseSpinLock(&AddrFile->Lock, OldIrql); + TcpipReleaseSpinLock(&AddrFile->Lock, OldIrql); TI_DbgPrint(MAX_TRACE, ("Discarding datagram.\n")); } @@ -201,7 +197,7 @@ VOID DGReceiveComplete(PVOID Context, NTSTATUS Status, ULONG Count) { (PDATAGRAM_RECEIVE_REQUEST)Context; TI_DbgPrint(MAX_TRACE,("Called (%08x:%08x)\n", Status, Count)); ReceiveRequest->UserComplete( ReceiveRequest->UserContext, Status, Count ); - ExFreePoolWithTag( ReceiveRequest, DATAGRAM_RECV_TAG ); + exFreePool( ReceiveRequest ); TI_DbgPrint(MAX_TRACE,("Done\n")); } @@ -232,68 +228,76 @@ NTSTATUS DGReceiveDatagram( * This is the high level interface for receiving DG datagrams */ { + KIRQL OldIrql; NTSTATUS Status; PDATAGRAM_RECEIVE_REQUEST ReceiveRequest; - KIRQL OldIrql; TI_DbgPrint(MAX_TRACE, ("Called.\n")); - KeAcquireSpinLock(&AddrFile->Lock, &OldIrql); + TcpipAcquireSpinLock(&AddrFile->Lock, &OldIrql); - ReceiveRequest = ExAllocatePoolWithTag(NonPagedPool, sizeof(DATAGRAM_RECEIVE_REQUEST), - DATAGRAM_RECV_TAG); - if (ReceiveRequest) + if (AF_IS_VALID(AddrFile)) { - /* Initialize a receive request */ - - /* Extract the remote address filter from the request (if any) */ - if ((ConnInfo->RemoteAddressLength != 0) && - (ConnInfo->RemoteAddress)) + ReceiveRequest = exAllocatePool(NonPagedPool, sizeof(DATAGRAM_RECEIVE_REQUEST)); + if (ReceiveRequest) { - Status = AddrGetAddress(ConnInfo->RemoteAddress, - &ReceiveRequest->RemoteAddress, - &ReceiveRequest->RemotePort); - if (!NT_SUCCESS(Status)) + /* Initialize a receive request */ + + /* Extract the remote address filter from the request (if any) */ + if ((ConnInfo->RemoteAddressLength != 0) && + (ConnInfo->RemoteAddress)) { - ExFreePoolWithTag(ReceiveRequest, DATAGRAM_RECV_TAG); - KeReleaseSpinLock(&AddrFile->Lock, OldIrql); - return Status; + Status = AddrGetAddress(ConnInfo->RemoteAddress, + &ReceiveRequest->RemoteAddress, + &ReceiveRequest->RemotePort); + if (!NT_SUCCESS(Status)) + { + TcpipReleaseSpinLock(&AddrFile->Lock, OldIrql); + exFreePool(ReceiveRequest); + return Status; + } } - } + else + { + ReceiveRequest->RemotePort = 0; + AddrInitIPv4(&ReceiveRequest->RemoteAddress, 0); + } + + IoMarkIrpPending(Irp); + + ReceiveRequest->ReturnInfo = ReturnInfo; + ReceiveRequest->Buffer = BufferData; + ReceiveRequest->BufferSize = ReceiveLength; + ReceiveRequest->UserComplete = Complete; + ReceiveRequest->UserContext = Context; + ReceiveRequest->Complete = + (PDATAGRAM_COMPLETION_ROUTINE)DGReceiveComplete; + ReceiveRequest->Context = ReceiveRequest; + ReceiveRequest->AddressFile = AddrFile; + ReceiveRequest->Irp = Irp; + + /* Queue receive request */ + InsertTailList(&AddrFile->ReceiveQueue, &ReceiveRequest->ListEntry); + AF_SET_PENDING(AddrFile, AFF_RECEIVE); + + TcpipReleaseSpinLock(&AddrFile->Lock, OldIrql); + + TI_DbgPrint(MAX_TRACE, ("Leaving (pending %08x).\n", ReceiveRequest)); + + return STATUS_PENDING; + } else { - ReceiveRequest->RemotePort = 0; - AddrInitIPv4(&ReceiveRequest->RemoteAddress, 0); + Status = STATUS_INSUFFICIENT_RESOURCES; } - - IoMarkIrpPending(Irp); - - ReceiveRequest->ReturnInfo = ReturnInfo; - ReceiveRequest->Buffer = BufferData; - ReceiveRequest->BufferSize = ReceiveLength; - ReceiveRequest->UserComplete = Complete; - ReceiveRequest->UserContext = Context; - ReceiveRequest->Complete = - (PDATAGRAM_COMPLETION_ROUTINE)DGReceiveComplete; - ReceiveRequest->Context = ReceiveRequest; - ReceiveRequest->AddressFile = AddrFile; - ReceiveRequest->Irp = Irp; - - /* Queue receive request */ - InsertTailList(&AddrFile->ReceiveQueue, &ReceiveRequest->ListEntry); - - TI_DbgPrint(MAX_TRACE, ("Leaving (pending %08x).\n", ReceiveRequest)); - - KeReleaseSpinLock(&AddrFile->Lock, OldIrql); - - return STATUS_PENDING; } else { - KeReleaseSpinLock(&AddrFile->Lock, OldIrql); - Status = STATUS_INSUFFICIENT_RESOURCES; + Status = STATUS_INVALID_ADDRESS; } + TcpipReleaseSpinLock(&AddrFile->Lock, OldIrql); + TI_DbgPrint(MAX_TRACE, ("Leaving with errors (0x%X).\n", Status)); return Status; diff --git a/reactos/lib/drivers/ip/transport/rawip/rawip.c b/reactos/lib/drivers/ip/transport/rawip/rawip.c index 328337cdb38..f7b9b6dbec9 100644 --- a/reactos/lib/drivers/ip/transport/rawip/rawip.c +++ b/reactos/lib/drivers/ip/transport/rawip/rawip.c @@ -195,9 +195,6 @@ NTSTATUS RawIPSendDatagram( USHORT RemotePort; NTSTATUS Status; PNEIGHBOR_CACHE_ENTRY NCE; - KIRQL OldIrql; - - KeAcquireSpinLock(&AddrFile->Lock, &OldIrql); TI_DbgPrint(MID_TRACE,("Sending Datagram(%x %x %x %d)\n", AddrFile, ConnInfo, BufferData, DataSize)); @@ -212,17 +209,13 @@ NTSTATUS RawIPSendDatagram( break; default: - KeReleaseSpinLock(&AddrFile->Lock, OldIrql); return STATUS_UNSUCCESSFUL; } TI_DbgPrint(MID_TRACE,("About to get route to destination\n")); if(!(NCE = RouteGetRouteToDestination( &RemoteAddress ))) - { - KeReleaseSpinLock(&AddrFile->Lock, OldIrql); return STATUS_NETWORK_UNREACHABLE; - } LocalAddress = AddrFile->Address; if (AddrIsUnspecified(&LocalAddress)) @@ -244,24 +237,18 @@ NTSTATUS RawIPSendDatagram( DataSize ); if( !NT_SUCCESS(Status) ) - { - KeReleaseSpinLock(&AddrFile->Lock, OldIrql); return Status; - } TI_DbgPrint(MID_TRACE,("About to send datagram\n")); if (!NT_SUCCESS(Status = IPSendDatagram( &Packet, NCE, RawIpSendPacketComplete, NULL ))) { - KeReleaseSpinLock(&AddrFile->Lock, OldIrql); FreeNdisPacket(Packet.NdisPacket); return Status; } TI_DbgPrint(MID_TRACE,("Leaving\n")); - KeReleaseSpinLock(&AddrFile->Lock, OldIrql); - return STATUS_SUCCESS; } diff --git a/reactos/lib/drivers/ip/transport/tcp/accept.c b/reactos/lib/drivers/ip/transport/tcp/accept.c index 059d109af73..ee1f3bf38d0 100644 --- a/reactos/lib/drivers/ip/transport/tcp/accept.c +++ b/reactos/lib/drivers/ip/transport/tcp/accept.c @@ -10,7 +10,6 @@ #include "precomp.h" -/* Listener->Lock MUST be acquired */ NTSTATUS TCPServiceListeningSocket( PCONNECTION_ENDPOINT Listener, PCONNECTION_ENDPOINT Connection, PTDI_REQUEST_KERNEL Request ) { @@ -20,6 +19,8 @@ NTSTATUS TCPServiceListeningSocket( PCONNECTION_ENDPOINT Listener, PTA_IP_ADDRESS RequestAddressReturn; PTDI_CONNECTION_INFORMATION WhoIsConnecting; + ASSERT_LOCKED(&TCPLock); + /* Unpack TDI info -- We need the return connection information * struct to return the address so it can be filtered if needed * by WSAAccept -- The returned address will be passed on to @@ -30,7 +31,6 @@ NTSTATUS TCPServiceListeningSocket( PCONNECTION_ENDPOINT Listener, Status = TCPTranslateError ( OskitTCPAccept( Listener->SocketContext, &Connection->SocketContext, - Connection, &OutAddr, sizeof(OutAddr), &OutAddrLen, @@ -69,14 +69,13 @@ NTSTATUS TCPServiceListeningSocket( PCONNECTION_ENDPOINT Listener, NTSTATUS TCPListen( PCONNECTION_ENDPOINT Connection, UINT Backlog ) { NTSTATUS Status = STATUS_SUCCESS; SOCKADDR_IN AddressToBind; - KIRQL OldIrql; + + TcpipRecursiveMutexEnter( &TCPLock, TRUE ); ASSERT(Connection); ASSERT_KM_POINTER(Connection->SocketContext); ASSERT_KM_POINTER(Connection->AddressFile); - KeAcquireSpinLock(&Connection->Lock, &OldIrql); - TI_DbgPrint(DEBUG_TCP,("TCPListen started\n")); TI_DbgPrint(DEBUG_TCP,("Connection->SocketContext %x\n", @@ -97,19 +96,18 @@ NTSTATUS TCPListen( PCONNECTION_ENDPOINT Connection, UINT Backlog ) { if (NT_SUCCESS(Status)) Status = TCPTranslateError( OskitTCPListen( Connection->SocketContext, Backlog ) ); - KeReleaseSpinLock(&Connection->Lock, OldIrql); + TcpipRecursiveMutexLeave( &TCPLock ); TI_DbgPrint(DEBUG_TCP,("TCPListen finished %x\n", Status)); return Status; } -BOOLEAN TCPAbortListenForSocket( PCONNECTION_ENDPOINT Listener, +VOID TCPAbortListenForSocket( PCONNECTION_ENDPOINT Listener, PCONNECTION_ENDPOINT Connection ) { PLIST_ENTRY ListEntry; PTDI_BUCKET Bucket; KIRQL OldIrql; - BOOLEAN Found = FALSE; KeAcquireSpinLock(&Listener->Lock, &OldIrql); @@ -119,8 +117,7 @@ BOOLEAN TCPAbortListenForSocket( PCONNECTION_ENDPOINT Listener, if( Bucket->AssociatedEndpoint == Connection ) { RemoveEntryList( &Bucket->Entry ); - ExFreePoolWithTag( Bucket, TDI_BUCKET_TAG ); - Found = TRUE; + exFreePool( Bucket ); break; } @@ -128,8 +125,6 @@ BOOLEAN TCPAbortListenForSocket( PCONNECTION_ENDPOINT Listener, } KeReleaseSpinLock(&Listener->Lock, OldIrql); - - return Found; } NTSTATUS TCPAccept ( PTDI_REQUEST Request, @@ -140,27 +135,25 @@ NTSTATUS TCPAccept ( PTDI_REQUEST Request, { NTSTATUS Status; PTDI_BUCKET Bucket; - KIRQL OldIrql; TI_DbgPrint(DEBUG_TCP,("TCPAccept started\n")); - KeAcquireSpinLock(&Listener->Lock, &OldIrql); + TcpipRecursiveMutexEnter( &TCPLock, TRUE ); Status = TCPServiceListeningSocket( Listener, Connection, (PTDI_REQUEST_KERNEL)Request ); - KeReleaseSpinLock(&Listener->Lock, OldIrql); + TcpipRecursiveMutexLeave( &TCPLock ); if( Status == STATUS_PENDING ) { - Bucket = ExAllocatePoolWithTag( NonPagedPool, sizeof(*Bucket), - TDI_BUCKET_TAG ); + Bucket = exAllocatePool( NonPagedPool, sizeof(*Bucket) ); if( Bucket ) { Bucket->AssociatedEndpoint = Connection; Bucket->Request.RequestNotifyObject = Complete; Bucket->Request.RequestContext = Context; - ExInterlockedInsertTailList( &Listener->ListenRequest, &Bucket->Entry, - &Listener->Lock ); + IoMarkIrpPending((PIRP)Context); + ExInterlockedInsertTailList( &Listener->ListenRequest, &Bucket->Entry, &Listener->Lock ); } else Status = STATUS_NO_MEMORY; } diff --git a/reactos/lib/drivers/ip/transport/tcp/event.c b/reactos/lib/drivers/ip/transport/tcp/event.c index f3d5a145597..81cdbbb0ffd 100644 --- a/reactos/lib/drivers/ip/transport/tcp/event.c +++ b/reactos/lib/drivers/ip/transport/tcp/event.c @@ -16,33 +16,36 @@ int TCPSocketState(void *ClientData, OSK_UINT NewState ) { PCONNECTION_ENDPOINT Connection = WhichConnection; - TI_DbgPrint(DEBUG_TCP,("Connection: %x Flags: %c%c%c%c%c\n", - Connection, + ASSERT_LOCKED(&TCPLock); + + TI_DbgPrint(MID_TRACE,("Flags: %c%c%c%c\n", NewState & SEL_CONNECT ? 'C' : 'c', NewState & SEL_READ ? 'R' : 'r', NewState & SEL_FIN ? 'F' : 'f', - NewState & SEL_ACCEPT ? 'A' : 'a', - NewState & SEL_WRITE ? 'W' : 'w')); - - if (!Connection) - { - return 0; - } - - if (ClientInfo.Unlocked) - KeAcquireSpinLockAtDpcLevel(&Connection->Lock); + NewState & SEL_ACCEPT ? 'A' : 'a')); TI_DbgPrint(DEBUG_TCP,("Called: NewState %x (Conn %x) (Change %x)\n", NewState, Connection, - Connection->SignalState ^ NewState, + Connection ? Connection->State ^ NewState : NewState)); + if( !Connection ) { + TI_DbgPrint(DEBUG_TCP,("Socket closing.\n")); + Connection = FileFindConnectionByContext( WhichSocket ); + if( !Connection ) + return 0; + else + TI_DbgPrint(DEBUG_TCP,("Found socket %x\n", Connection)); + } + + TI_DbgPrint(MID_TRACE,("Connection signalled: %d\n", + Connection->Signalled)); + Connection->SignalState |= NewState; - - HandleSignalledConnection(Connection); - - if (ClientInfo.Unlocked) - KeReleaseSpinLockFromDpcLevel(&Connection->Lock); + if( !Connection->Signalled ) { + Connection->Signalled = TRUE; + ExInterlockedInsertTailList( &SignalledConnectionsList, &Connection->SignalList, &SignalledConnectionsLock ); + } return 0; } @@ -64,6 +67,8 @@ int TCPPacketSend(void *ClientData, OSK_PCHAR data, OSK_UINT len ) { IP_ADDRESS RemoteAddress, LocalAddress; PIPv4_HEADER Header; + ASSERT_LOCKED(&TCPLock); + if( *data == 0x45 ) { /* IPv4 */ Header = (PIPv4_HEADER)data; LocalAddress.Type = IP_ADDRESS_V4; @@ -107,6 +112,74 @@ int TCPPacketSend(void *ClientData, OSK_PCHAR data, OSK_UINT len ) { return 0; } +int TCPSleep( void *ClientData, void *token, int priority, char *msg, + int tmio ) { + PSLEEPING_THREAD SleepingThread; + LARGE_INTEGER Timeout; + + ASSERT_LOCKED(&TCPLock); + + TI_DbgPrint(DEBUG_TCP, + ("Called TSLEEP: tok = %x, pri = %d, wmesg = %s, tmio = %x\n", + token, priority, msg, tmio)); + + SleepingThread = exAllocatePool( NonPagedPool, sizeof( *SleepingThread ) ); + if( SleepingThread ) { + KeInitializeEvent( &SleepingThread->Event, NotificationEvent, FALSE ); + SleepingThread->SleepToken = token; + + /* We're going to sleep and need to release the lock, otherwise + it's impossible to re-enter oskittcp to deliver the event that's + going to wake us */ + TcpipRecursiveMutexLeave( &TCPLock ); + + TcpipAcquireFastMutex( &SleepingThreadsLock ); + InsertTailList( &SleepingThreadsList, &SleepingThread->Entry ); + TcpipReleaseFastMutex( &SleepingThreadsLock ); + + Timeout.QuadPart = Int32x32To64(tmio, -10000); + + TI_DbgPrint(DEBUG_TCP,("Waiting on %x\n", token)); + KeWaitForSingleObject( &SleepingThread->Event, + Executive, + KernelMode, + TRUE, + (tmio != 0) ? &Timeout : NULL ); + + TcpipAcquireFastMutex( &SleepingThreadsLock ); + RemoveEntryList( &SleepingThread->Entry ); + TcpipReleaseFastMutex( &SleepingThreadsLock ); + + TcpipRecursiveMutexEnter( &TCPLock, TRUE ); + + exFreePool( SleepingThread ); + } else + return OSK_ENOBUFS; + + TI_DbgPrint(DEBUG_TCP,("Waiting finished: %x\n", token)); + return 0; +} + +void TCPWakeup( void *ClientData, void *token ) { + PLIST_ENTRY Entry; + PSLEEPING_THREAD SleepingThread; + + ASSERT_LOCKED(&TCPLock); + + TcpipAcquireFastMutex( &SleepingThreadsLock ); + Entry = SleepingThreadsList.Flink; + while( Entry != &SleepingThreadsList ) { + SleepingThread = CONTAINING_RECORD(Entry, SLEEPING_THREAD, Entry); + TI_DbgPrint(DEBUG_TCP,("Sleeper @ %x\n", SleepingThread)); + if( SleepingThread->SleepToken == token ) { + TI_DbgPrint(DEBUG_TCP,("Setting event to wake %x\n", token)); + KeSetEvent( &SleepingThread->Event, IO_NETWORK_INCREMENT, FALSE ); + } + Entry = Entry->Flink; + } + TcpipReleaseFastMutex( &SleepingThreadsLock ); +} + /* Memory management routines * * By far the most requests for memory are either for 128 or 2048 byte blocks, @@ -126,6 +199,8 @@ int TCPPacketSend(void *ClientData, OSK_PCHAR data, OSK_UINT len ) { #define SIGNATURE_LARGE 'LLLL' #define SIGNATURE_SMALL 'SSSS' #define SIGNATURE_OTHER 'OOOO' +#define TCP_TAG ' PCT' + static NPAGED_LOOKASIDE_LIST LargeLookasideList; static NPAGED_LOOKASIDE_LIST SmallLookasideList; @@ -137,14 +212,14 @@ TCPMemStartup( void ) NULL, 0, LARGE_SIZE + sizeof( ULONG ), - OSK_LARGE_TAG, + TCP_TAG, 0 ); ExInitializeNPagedLookasideList( &SmallLookasideList, NULL, NULL, 0, SMALL_SIZE + sizeof( ULONG ), - OSK_SMALL_TAG, + TCP_TAG, 0 ); return STATUS_SUCCESS; @@ -155,6 +230,8 @@ void *TCPMalloc( void *ClientData, void *v; ULONG Signature; + ASSERT_LOCKED(&TCPLock); + #if 0 != MEM_PROFILE static OSK_UINT *Sizes = NULL, *Counts = NULL, ArrayAllocated = 0; static OSK_UINT ArrayUsed = 0, AllocationCount = 0; @@ -214,13 +291,13 @@ void *TCPMalloc( void *ClientData, v = ExAllocateFromNPagedLookasideList( &LargeLookasideList ); Signature = SIGNATURE_LARGE; } else { - v = ExAllocatePoolWithTag( NonPagedPool, Bytes + sizeof(ULONG), - OSK_OTHER_TAG ); + v = ExAllocatePool( NonPagedPool, Bytes + sizeof(ULONG) ); Signature = SIGNATURE_OTHER; } if( v ) { *((ULONG *) v) = Signature; v = (void *)((char *) v + sizeof(ULONG)); + TrackWithTag( FOURCC('f','b','s','d'), v, (PCHAR)File, Line ); } return v; @@ -230,6 +307,9 @@ void TCPFree( void *ClientData, void *data, OSK_PCHAR File, OSK_UINT Line ) { ULONG Signature; + ASSERT_LOCKED(&TCPLock); + + UntrackFL( (PCHAR)File, Line, data, FOURCC('f','b','s','d') ); data = (void *)((char *) data - sizeof(ULONG)); Signature = *((ULONG *) data); if ( SIGNATURE_SMALL == Signature ) { @@ -237,7 +317,7 @@ void TCPFree( void *ClientData, } else if ( SIGNATURE_LARGE == Signature ) { ExFreeToNPagedLookasideList( &LargeLookasideList, data ); } else if ( SIGNATURE_OTHER == Signature ) { - ExFreePoolWithTag( data, OSK_OTHER_TAG ); + ExFreePool( data ); } else { ASSERT( FALSE ); } diff --git a/reactos/lib/drivers/ip/transport/tcp/if.c b/reactos/lib/drivers/ip/transport/tcp/if.c index 0e5296425d1..d9598aff798 100644 --- a/reactos/lib/drivers/ip/transport/tcp/if.c +++ b/reactos/lib/drivers/ip/transport/tcp/if.c @@ -37,6 +37,8 @@ POSK_IFADDR TCPGetInterfaceData( PIP_INTERFACE IF ) { struct sockaddr_in *dstaddr_in; ASSERT(ifaddr); + ASSERT_LOCKED(&TCPLock); + RtlZeroMemory(ifaddr, sizeof(OSK_IFADDR) + 2 * sizeof( struct sockaddr_in )); addr_in = (struct sockaddr_in *)&ifaddr[1]; @@ -79,6 +81,8 @@ POSK_IFADDR TCPFindInterface( void *ClientData, struct sockaddr_in *addr_in = (struct sockaddr_in *)ReqAddr; POSK_IFADDR InterfaceData; + ASSERT_LOCKED(&TCPLock); + TI_DbgPrint(DEBUG_TCPIF,("called for type %d\n", FindType)); if( !ReqAddr ) { diff --git a/reactos/lib/drivers/ip/transport/tcp/tcp.c b/reactos/lib/drivers/ip/transport/tcp/tcp.c index fe571126379..67685366bcf 100644 --- a/reactos/lib/drivers/ip/transport/tcp/tcp.c +++ b/reactos/lib/drivers/ip/transport/tcp/tcp.c @@ -15,308 +15,291 @@ LONG TCP_IPIdentification = 0; static BOOLEAN TCPInitialized = FALSE; static NPAGED_LOOKASIDE_LIST TCPSegmentList; +LIST_ENTRY SignalledConnectionsList; +KSPIN_LOCK SignalledConnectionsLock; +LIST_ENTRY SleepingThreadsList; +FAST_MUTEX SleepingThreadsLock; +RECURSIVE_MUTEX TCPLock; PORT_SET TCPPorts; -CLIENT_DATA ClientInfo; -static VOID -ProcessCompletions(PCONNECTION_ENDPOINT Connection) -{ - PLIST_ENTRY CurrentEntry; - PTDI_BUCKET Bucket; +static VOID HandleSignalledConnection( PCONNECTION_ENDPOINT Connection ) { + NTSTATUS Status = STATUS_SUCCESS; PTCP_COMPLETION_ROUTINE Complete; + PTDI_BUCKET Bucket; + PLIST_ENTRY Entry; + PIRP Irp; + PMDL Mdl; - while ((CurrentEntry = ExInterlockedRemoveHeadList(&Connection->CompletionQueue, - &Connection->Lock))) - { - Bucket = CONTAINING_RECORD(CurrentEntry, TDI_BUCKET, Entry); - Complete = Bucket->Request.RequestNotifyObject; + ASSERT_LOCKED(&TCPLock); - Complete(Bucket->Request.RequestContext, Bucket->Status, Bucket->Information); + TI_DbgPrint(MID_TRACE,("Handling signalled state on %x (%x)\n", + Connection, Connection->SocketContext)); - ExFreePoolWithTag(Bucket, TDI_BUCKET_TAG); - } + if( Connection->SignalState & SEL_FIN ) { + TI_DbgPrint(DEBUG_TCP, ("EOF From socket\n")); - if (!Connection->SocketContext) - TCPFreeConnectionEndpoint(Connection); -} + while ((Entry = ExInterlockedRemoveHeadList( &Connection->ReceiveRequest, + &Connection->Lock )) != NULL) + { + Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry ); + Complete = Bucket->Request.RequestNotifyObject; -VOID HandleSignalledConnection(PCONNECTION_ENDPOINT Connection) -{ - PTDI_BUCKET Bucket; - PLIST_ENTRY Entry; - NTSTATUS Status; - PIRP Irp; - PMDL Mdl; - ULONG SocketError = 0; + /* We have to notify oskittcp of the abortion */ + TCPDisconnect + ( Connection, + TDI_DISCONNECT_RELEASE | TDI_DISCONNECT_ABORT, + NULL, + NULL, + Bucket->Request.RequestNotifyObject, + (PIRP)Bucket->Request.RequestContext ); - TI_DbgPrint(MID_TRACE,("Handling signalled state on %x (%x)\n", - Connection, Connection->SocketContext)); + Complete( Bucket->Request.RequestContext, STATUS_CANCELLED, 0 ); - if( !Connection->SocketContext || Connection->SignalState & SEL_FIN ) { - TI_DbgPrint(DEBUG_TCP, ("EOF From socket\n")); - - /* If OskitTCP initiated the disconnect, try to read the socket error that occurred */ - if (Connection->SocketContext) - SocketError = TCPTranslateError(OskitTCPGetSocketError(Connection->SocketContext)); - - /* Default to STATUS_CANCELLED if we initiated the disconnect or no socket error was reported */ - if (!Connection->SocketContext || !SocketError) - SocketError = STATUS_CANCELLED; - - while (!IsListEmpty(&Connection->ReceiveRequest)) - { - Entry = RemoveHeadList( &Connection->ReceiveRequest ); - - Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry ); - - Bucket->Status = SocketError; - Bucket->Information = 0; - - InsertTailList(&Connection->CompletionQueue, &Bucket->Entry); - } - - while (!IsListEmpty(&Connection->SendRequest)) - { - Entry = RemoveHeadList( &Connection->SendRequest ); - - Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry ); - - Bucket->Status = SocketError; - Bucket->Information = 0; - - InsertTailList(&Connection->CompletionQueue, &Bucket->Entry); - } - - while (!IsListEmpty(&Connection->ListenRequest)) - { - Entry = RemoveHeadList( &Connection->ListenRequest ); - - Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry ); - - Bucket->Status = SocketError; - Bucket->Information = 0; - - InsertTailList(&Connection->CompletionQueue, &Bucket->Entry); - } - - while (!IsListEmpty(&Connection->ConnectRequest)) - { - Entry = RemoveHeadList( &Connection->ConnectRequest ); - - Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry ); - - Bucket->Status = SocketError; - Bucket->Information = 0; - - InsertTailList(&Connection->CompletionQueue, &Bucket->Entry); - } - - Connection->SignalState = 0; + exFreePool(Bucket); } - /* Things that can happen when we try the initial connection */ - if( Connection->SignalState & SEL_CONNECT ) { - while (!IsListEmpty(&Connection->ConnectRequest)) { - Entry = RemoveHeadList( &Connection->ConnectRequest ); + while ((Entry = ExInterlockedRemoveHeadList( &Connection->SendRequest, + &Connection->Lock )) != NULL) + { + Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry ); + Complete = Bucket->Request.RequestNotifyObject; - Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry ); + /* We have to notify oskittcp of the abortion */ + TCPDisconnect + ( Connection, + TDI_DISCONNECT_RELEASE, + NULL, + NULL, + Bucket->Request.RequestNotifyObject, + (PIRP)Bucket->Request.RequestContext ); - Bucket->Status = STATUS_SUCCESS; - Bucket->Information = 0; + Complete( Bucket->Request.RequestContext, STATUS_CANCELLED, 0 ); - InsertTailList(&Connection->CompletionQueue, &Bucket->Entry); - } - } + exFreePool(Bucket); + } - if( Connection->SignalState & SEL_ACCEPT ) { - /* Handle readable on a listening socket -- - * TODO: Implement filtering - */ - TI_DbgPrint(DEBUG_TCP,("Accepting new connection on %x (Queue: %s)\n", - Connection, - IsListEmpty(&Connection->ListenRequest) ? - "empty" : "nonempty")); + while ((Entry = ExInterlockedRemoveHeadList( &Connection->ListenRequest, + &Connection->Lock )) != NULL) + { + Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry ); + Complete = Bucket->Request.RequestNotifyObject; - while (!IsListEmpty(&Connection->ListenRequest)) { - PIO_STACK_LOCATION IrpSp; + /* We have to notify oskittcp of the abortion */ + TCPAbortListenForSocket(Connection->AddressFile->Listener, + Connection); - Entry = RemoveHeadList( &Connection->ListenRequest ); + Complete( Bucket->Request.RequestContext, STATUS_CANCELLED, 0 ); + } - Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry ); + while ((Entry = ExInterlockedRemoveHeadList( &Connection->ConnectRequest, + &Connection->Lock )) != NULL) + { + Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry ); + Complete = Bucket->Request.RequestNotifyObject; - Irp = Bucket->Request.RequestContext; - IrpSp = IoGetCurrentIrpStackLocation( Irp ); + Complete( Bucket->Request.RequestContext, STATUS_CANCELLED, 0 ); + } - TI_DbgPrint(DEBUG_TCP,("Getting the socket\n")); + Connection->SignalState = 0; + } - Status = TCPServiceListeningSocket - ( Connection->AddressFile->Listener, - Bucket->AssociatedEndpoint, - (PTDI_REQUEST_KERNEL)&IrpSp->Parameters ); + /* Things that can happen when we try the initial connection */ + if( Connection->SignalState & SEL_CONNECT ) { + while( (Entry = ExInterlockedRemoveHeadList( &Connection->ConnectRequest, + &Connection->Lock )) != NULL ) { + + TI_DbgPrint(DEBUG_TCP, ("Connect Event\n")); - TI_DbgPrint(DEBUG_TCP,("Socket: Status: %x\n")); + Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry ); + Complete = Bucket->Request.RequestNotifyObject; + TI_DbgPrint(DEBUG_TCP, + ("Completing Request %x\n", Bucket->Request.RequestContext)); - if( Status == STATUS_PENDING ) { - InsertHeadList( &Connection->ListenRequest, &Bucket->Entry ); - break; - } else { - Bucket->Status = Status; - Bucket->Information = 0; + Complete( Bucket->Request.RequestContext, STATUS_SUCCESS, 0 ); - InsertTailList(&Connection->CompletionQueue, &Bucket->Entry); - } - } - } + /* Frees the bucket allocated in TCPConnect */ + exFreePool( Bucket ); + } + } - /* Things that happen after we're connected */ - if( Connection->SignalState & SEL_READ ) { - TI_DbgPrint(DEBUG_TCP,("Readable: irp list %s\n", - IsListEmpty(&Connection->ReceiveRequest) ? - "empty" : "nonempty")); + if( Connection->SignalState & SEL_ACCEPT ) { + /* Handle readable on a listening socket -- + * TODO: Implement filtering + */ - while (!IsListEmpty(&Connection->ReceiveRequest)) { - OSK_UINT RecvLen = 0, Received = 0; - PVOID RecvBuffer = 0; + TI_DbgPrint(DEBUG_TCP,("Accepting new connection on %x (Queue: %s)\n", + Connection, + IsListEmpty(&Connection->ListenRequest) ? + "empty" : "nonempty")); - Entry = RemoveHeadList( &Connection->ReceiveRequest ); + while( (Entry = ExInterlockedRemoveHeadList( &Connection->ListenRequest, + &Connection->Lock )) != NULL ) { + PIO_STACK_LOCATION IrpSp; - Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry ); + Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry ); + Complete = Bucket->Request.RequestNotifyObject; - Irp = Bucket->Request.RequestContext; - Mdl = Irp->MdlAddress; + Irp = Bucket->Request.RequestContext; + IrpSp = IoGetCurrentIrpStackLocation( Irp ); - TI_DbgPrint(DEBUG_TCP, - ("Getting the user buffer from %x\n", Mdl)); + TI_DbgPrint(DEBUG_TCP,("Getting the socket\n")); + Status = TCPServiceListeningSocket + ( Connection->AddressFile->Listener, + Bucket->AssociatedEndpoint, + (PTDI_REQUEST_KERNEL)&IrpSp->Parameters ); - NdisQueryBuffer( Mdl, &RecvBuffer, &RecvLen ); + TI_DbgPrint(DEBUG_TCP,("Socket: Status: %x\n")); - TI_DbgPrint(DEBUG_TCP, - ("Reading %d bytes to %x\n", RecvLen, RecvBuffer)); + if( Status == STATUS_PENDING ) { + ExInterlockedInsertHeadList( &Connection->ListenRequest, &Bucket->Entry, &Connection->Lock ); + break; + } else { + Complete( Bucket->Request.RequestContext, Status, 0 ); + exFreePool( Bucket ); + } + } + } - TI_DbgPrint(DEBUG_TCP, ("Connection: %x\n", Connection)); - TI_DbgPrint - (DEBUG_TCP, - ("Connection->SocketContext: %x\n", - Connection->SocketContext)); - TI_DbgPrint(DEBUG_TCP, ("RecvBuffer: %x\n", RecvBuffer)); + /* Things that happen after we're connected */ + if( Connection->SignalState & SEL_READ ) { + TI_DbgPrint(DEBUG_TCP,("Readable: irp list %s\n", + IsListEmpty(&Connection->ReceiveRequest) ? + "empty" : "nonempty")); - Status = TCPTranslateError - ( OskitTCPRecv( Connection->SocketContext, - RecvBuffer, - RecvLen, - &Received, - 0 ) ); + while( (Entry = ExInterlockedRemoveHeadList( &Connection->ReceiveRequest, + &Connection->Lock )) != NULL ) { + OSK_UINT RecvLen = 0, Received = 0; + PVOID RecvBuffer = 0; - TI_DbgPrint(DEBUG_TCP,("TCP Bytes: %d\n", Received)); + Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry ); + Complete = Bucket->Request.RequestNotifyObject; - if( Status == STATUS_PENDING ) { - InsertHeadList( &Connection->ReceiveRequest, &Bucket->Entry ); - break; - } else { - TI_DbgPrint(DEBUG_TCP, - ("Completing Receive request: %x %x\n", - Bucket->Request, Status)); + Irp = Bucket->Request.RequestContext; + Mdl = Irp->MdlAddress; - Bucket->Status = Status; - Bucket->Information = (Status == STATUS_SUCCESS) ? Received : 0; + TI_DbgPrint(DEBUG_TCP, + ("Getting the user buffer from %x\n", Mdl)); - InsertTailList(&Connection->CompletionQueue, &Bucket->Entry); - } - } - } - if( Connection->SignalState & SEL_WRITE ) { - TI_DbgPrint(DEBUG_TCP,("Writeable: irp list %s\n", - IsListEmpty(&Connection->SendRequest) ? - "empty" : "nonempty")); + NdisQueryBuffer( Mdl, &RecvBuffer, &RecvLen ); - while (!IsListEmpty(&Connection->SendRequest)) { - OSK_UINT SendLen = 0, Sent = 0; - PVOID SendBuffer = 0; + TI_DbgPrint(DEBUG_TCP, + ("Reading %d bytes to %x\n", RecvLen, RecvBuffer)); - Entry = RemoveHeadList( &Connection->SendRequest ); + TI_DbgPrint(DEBUG_TCP, ("Connection: %x\n", Connection)); + TI_DbgPrint + (DEBUG_TCP, + ("Connection->SocketContext: %x\n", + Connection->SocketContext)); + TI_DbgPrint(DEBUG_TCP, ("RecvBuffer: %x\n", RecvBuffer)); - Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry ); + Status = TCPTranslateError + ( OskitTCPRecv( Connection->SocketContext, + RecvBuffer, + RecvLen, + &Received, + 0 ) ); - Irp = Bucket->Request.RequestContext; - Mdl = Irp->MdlAddress; + TI_DbgPrint(DEBUG_TCP,("TCP Bytes: %d\n", Received)); - TI_DbgPrint(DEBUG_TCP, - ("Getting the user buffer from %x\n", Mdl)); + if( Status == STATUS_SUCCESS ) { + TI_DbgPrint(DEBUG_TCP,("Received %d bytes with status %x\n", + Received, Status)); - NdisQueryBuffer( Mdl, &SendBuffer, &SendLen ); + Complete( Bucket->Request.RequestContext, + STATUS_SUCCESS, Received ); + exFreePool( Bucket ); + } else if( Status == STATUS_PENDING ) { + ExInterlockedInsertHeadList + ( &Connection->ReceiveRequest, &Bucket->Entry, &Connection->Lock ); + break; + } else { + TI_DbgPrint(DEBUG_TCP, + ("Completing Receive request: %x %x\n", + Bucket->Request, Status)); + Complete( Bucket->Request.RequestContext, Status, 0 ); + exFreePool( Bucket ); + } + } + } + if( Connection->SignalState & SEL_WRITE ) { + TI_DbgPrint(DEBUG_TCP,("Writeable: irp list %s\n", + IsListEmpty(&Connection->SendRequest) ? + "empty" : "nonempty")); - TI_DbgPrint(DEBUG_TCP, - ("Writing %d bytes to %x\n", SendLen, SendBuffer)); + while( (Entry = ExInterlockedRemoveHeadList( &Connection->SendRequest, + &Connection->Lock )) != NULL ) { + OSK_UINT SendLen = 0, Sent = 0; + PVOID SendBuffer = 0; - TI_DbgPrint(DEBUG_TCP, ("Connection: %x\n", Connection)); - TI_DbgPrint + Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry ); + Complete = Bucket->Request.RequestNotifyObject; + + Irp = Bucket->Request.RequestContext; + Mdl = Irp->MdlAddress; + + TI_DbgPrint(DEBUG_TCP, + ("Getting the user buffer from %x\n", Mdl)); + + NdisQueryBuffer( Mdl, &SendBuffer, &SendLen ); + + TI_DbgPrint(DEBUG_TCP, + ("Writing %d bytes to %x\n", SendLen, SendBuffer)); + + TI_DbgPrint(DEBUG_TCP, ("Connection: %x\n", Connection)); + TI_DbgPrint (DEBUG_TCP, ("Connection->SocketContext: %x\n", Connection->SocketContext)); - Status = TCPTranslateError - ( OskitTCPSend( Connection->SocketContext, - SendBuffer, - SendLen, - &Sent, - 0 ) ); + Status = TCPTranslateError + ( OskitTCPSend( Connection->SocketContext, + SendBuffer, + SendLen, + &Sent, + 0 ) ); - TI_DbgPrint(DEBUG_TCP,("TCP Bytes: %d\n", Sent)); + TI_DbgPrint(DEBUG_TCP,("TCP Bytes: %d\n", Sent)); - if( Status == STATUS_PENDING ) { - InsertHeadList( &Connection->SendRequest, &Bucket->Entry ); - break; - } else { - TI_DbgPrint(DEBUG_TCP, - ("Completing Send request: %x %x\n", - Bucket->Request, Status)); + if( Status == STATUS_SUCCESS ) { + TI_DbgPrint(DEBUG_TCP,("Sent %d bytes with status %x\n", + Sent, Status)); - Bucket->Status = Status; - Bucket->Information = (Status == STATUS_SUCCESS) ? Sent : 0; + Complete( Bucket->Request.RequestContext, + STATUS_SUCCESS, Sent ); + exFreePool( Bucket ); + } else if( Status == STATUS_PENDING ) { + ExInterlockedInsertHeadList + ( &Connection->SendRequest, &Bucket->Entry, &Connection->Lock ); + break; + } else { + TI_DbgPrint(DEBUG_TCP, + ("Completing Send request: %x %x\n", + Bucket->Request, Status)); + Complete( Bucket->Request.RequestContext, Status, 0 ); + exFreePool( Bucket ); + } + } + } - InsertTailList(&Connection->CompletionQueue, &Bucket->Entry); - } - } - } + Connection->SignalState = 0; + Connection->Signalled = FALSE; } -static -VOID DrainSignals(VOID) { +VOID DrainSignals() { PCONNECTION_ENDPOINT Connection; - PLIST_ENTRY CurrentEntry; - KIRQL OldIrql; + PLIST_ENTRY ListEntry; - KeAcquireSpinLock(&ConnectionEndpointListLock, &OldIrql); - CurrentEntry = ConnectionEndpointListHead.Flink; - while (CurrentEntry != &ConnectionEndpointListHead) - { - Connection = CONTAINING_RECORD( CurrentEntry, CONNECTION_ENDPOINT, - ListEntry ); - CurrentEntry = CurrentEntry->Flink; - KeReleaseSpinLock(&ConnectionEndpointListLock, OldIrql); - - KeAcquireSpinLock(&Connection->Lock, &OldIrql); - if (Connection->SocketContext) - { - HandleSignalledConnection(Connection); - KeReleaseSpinLock(&Connection->Lock, OldIrql); - - ProcessCompletions(Connection); - } - else - { - KeReleaseSpinLock(&Connection->Lock, OldIrql); - } - - KeAcquireSpinLock(&ConnectionEndpointListLock, &OldIrql); + while( (ListEntry = ExInterlockedRemoveHeadList(&SignalledConnectionsList, + &SignalledConnectionsLock)) != NULL) { + Connection = CONTAINING_RECORD( ListEntry, CONNECTION_ENDPOINT, + SignalList ); + HandleSignalledConnection( Connection ); } - KeReleaseSpinLock(&ConnectionEndpointListLock, OldIrql); } PCONNECTION_ENDPOINT TCPAllocateConnectionEndpoint( PVOID ClientContext ) { PCONNECTION_ENDPOINT Connection = - ExAllocatePoolWithTag(NonPagedPool, sizeof(CONNECTION_ENDPOINT), - CONN_ENDPT_TAG); + exAllocatePool(NonPagedPool, sizeof(CONNECTION_ENDPOINT)); if (!Connection) return Connection; @@ -325,42 +308,28 @@ PCONNECTION_ENDPOINT TCPAllocateConnectionEndpoint( PVOID ClientContext ) { RtlZeroMemory(Connection, sizeof(CONNECTION_ENDPOINT)); /* Initialize spin lock that protects the connection endpoint file object */ - KeInitializeSpinLock(&Connection->Lock); + TcpipInitializeSpinLock(&Connection->Lock); InitializeListHead(&Connection->ConnectRequest); InitializeListHead(&Connection->ListenRequest); InitializeListHead(&Connection->ReceiveRequest); InitializeListHead(&Connection->SendRequest); - InitializeListHead(&Connection->CompletionQueue); /* Save client context pointer */ Connection->ClientContext = ClientContext; - /* Add connection endpoint to global list */ - ExInterlockedInsertTailList(&ConnectionEndpointListHead, - &Connection->ListEntry, - &ConnectionEndpointListLock); - return Connection; } VOID TCPFreeConnectionEndpoint( PCONNECTION_ENDPOINT Connection ) { - KIRQL OldIrql; - TI_DbgPrint(DEBUG_TCP, ("Freeing TCP Endpoint\n")); - - TcpipAcquireSpinLock(&ConnectionEndpointListLock, &OldIrql); - RemoveEntryList(&Connection->ListEntry); - TcpipReleaseSpinLock(&ConnectionEndpointListLock, OldIrql); - - ExFreePoolWithTag( Connection, CONN_ENDPT_TAG ); + exFreePool( Connection ); } NTSTATUS TCPSocket( PCONNECTION_ENDPOINT Connection, UINT Family, UINT Type, UINT Proto ) { NTSTATUS Status; - KIRQL OldIrql; - KeAcquireSpinLock(&Connection->Lock, &OldIrql); + ASSERT_LOCKED(&TCPLock); TI_DbgPrint(DEBUG_TCP,("Called: Connection %x, Family %d, Type %d, " "Proto %d\n", @@ -377,8 +346,6 @@ NTSTATUS TCPSocket( PCONNECTION_ENDPOINT Connection, TI_DbgPrint(DEBUG_TCP,("Connection->SocketContext %x\n", Connection->SocketContext)); - KeReleaseSpinLock(&Connection->Lock, OldIrql); - return Status; } @@ -391,21 +358,19 @@ VOID TCPReceive(PIP_INTERFACE Interface, PIP_PACKET IPPacket) * This is the low level interface for receiving TCP data */ { - KIRQL OldIrql; - TI_DbgPrint(DEBUG_TCP,("Sending packet %d (%d) to oskit\n", IPPacket->TotalSize, IPPacket->HeaderSize)); - KeAcquireSpinLock(&ClientInfo.Lock, &OldIrql); - ClientInfo.Unlocked = TRUE; + TcpipRecursiveMutexEnter( &TCPLock, TRUE ); OskitTCPReceiveDatagram( IPPacket->Header, IPPacket->TotalSize, IPPacket->HeaderSize ); - ClientInfo.Unlocked = FALSE; - KeReleaseSpinLock(&ClientInfo.Lock, OldIrql); + DrainSignals(); + + TcpipRecursiveMutexLeave( &TCPLock ); } /* event.c */ @@ -430,6 +395,11 @@ void TCPFree( void *ClientData, void *data, OSK_PCHAR file, OSK_UINT line ); void TCPMemShutdown( void ); +int TCPSleep( void *ClientData, void *token, int priority, char *msg, + int tmio ); + +void TCPWakeup( void *ClientData, void *token ); + OSKITTCP_EVENT_HANDLERS EventHandlers = { NULL, /* Client Data */ TCPSocketState, /* SocketState */ @@ -437,8 +407,8 @@ OSKITTCP_EVENT_HANDLERS EventHandlers = { TCPFindInterface, /* FindInterface */ TCPMalloc, /* Malloc */ TCPFree, /* Free */ - NULL, /* Sleep */ - NULL, /* Wakeup */ + TCPSleep, /* Sleep */ + TCPWakeup /* Wakeup */ }; static KEVENT TimerLoopEvent; @@ -464,7 +434,7 @@ TimerThread(PVOID Context) while ( 1 ) { if (Next == NextFast) { NextFast += 2; - } + } if (Next == NextSlow) { NextSlow += 5; } @@ -476,8 +446,12 @@ TimerThread(PVOID Context) PsTerminateSystemThread(Status); } + TcpipRecursiveMutexEnter( &TCPLock, TRUE ); TimerOskitTCP( Next == NextFast, Next == NextSlow ); - DrainSignals(); + if (Next == NextSlow) { + DrainSignals(); + } + TcpipRecursiveMutexLeave( &TCPLock ); Current = Next; if (10 <= Current) { @@ -497,6 +471,7 @@ StartTimer(VOID) TimerThread, NULL); } + NTSTATUS TCPStartup(VOID) /* * FUNCTION: Initializes the TCP subsystem @@ -506,6 +481,11 @@ NTSTATUS TCPStartup(VOID) { NTSTATUS Status; + TcpipRecursiveMutexInit( &TCPLock ); + ExInitializeFastMutex( &SleepingThreadsLock ); + KeInitializeSpinLock( &SignalledConnectionsLock ); + InitializeListHead( &SleepingThreadsList ); + InitializeListHead( &SignalledConnectionsList ); Status = TCPMemStartup(); if ( ! NT_SUCCESS(Status) ) { return Status; @@ -517,11 +497,10 @@ NTSTATUS TCPStartup(VOID) return Status; } - KeInitializeSpinLock(&ClientInfo.Lock); - ClientInfo.Unlocked = FALSE; - + TcpipRecursiveMutexEnter(&TCPLock, TRUE); RegisterOskitTCPEventHandlers( &EventHandlers ); InitOskitTCP(); + TcpipRecursiveMutexLeave(&TCPLock); /* Register this protocol with IP layer */ IPRegisterProtocol(IPPROTO_TCP, TCPReceive); @@ -582,9 +561,8 @@ NTSTATUS TCPTranslateError( int OskitError ) { case 0: Status = STATUS_SUCCESS; break; case OSK_EADDRNOTAVAIL: Status = STATUS_INVALID_ADDRESS; break; case OSK_EAFNOSUPPORT: Status = STATUS_INVALID_CONNECTION; break; - case OSK_ECONNREFUSED: Status = STATUS_REMOTE_NOT_LISTENING; break; - case OSK_ECONNRESET: - case OSK_ECONNABORTED: Status = STATUS_REMOTE_DISCONNECT; break; + case OSK_ECONNREFUSED: + case OSK_ECONNRESET: Status = STATUS_REMOTE_NOT_LISTENING; break; case OSK_EWOULDBLOCK: case OSK_EINPROGRESS: Status = STATUS_PENDING; break; case OSK_EINVAL: Status = STATUS_INVALID_PARAMETER; break; @@ -617,10 +595,11 @@ NTSTATUS TCPConnect USHORT RemotePort; PTDI_BUCKET Bucket; PNEIGHBOR_CACHE_ENTRY NCE; - KIRQL OldIrql; TI_DbgPrint(DEBUG_TCP,("TCPConnect: Called\n")); + ASSERT_LOCKED(&TCPLock); + Status = AddrBuildAddress ((PTRANSPORT_ADDRESS)ConnInfo->RemoteAddress, &RemoteAddress, @@ -636,6 +615,11 @@ NTSTATUS TCPConnect return STATUS_NETWORK_UNREACHABLE; } + if (Connection->State & SEL_FIN) + { + return STATUS_REMOTE_DISCONNECT; + } + /* Freed in TCPSocketState */ TI_DbgPrint(DEBUG_TCP, ("Connecting to address %x:%x\n", @@ -646,8 +630,6 @@ NTSTATUS TCPConnect AddressToBind = AddressToConnect; AddressToBind.sin_addr.s_addr = NCE->Interface->Unicast.Address.IPv4Address; - KeAcquireSpinLock(&Connection->Lock, &OldIrql); - Status = TCPTranslateError ( OskitTCPBind( Connection->SocketContext, &AddressToBind, @@ -661,27 +643,22 @@ NTSTATUS TCPConnect Status = TCPTranslateError ( OskitTCPConnect( Connection->SocketContext, + Connection, &AddressToConnect, sizeof(AddressToConnect) ) ); - KeReleaseSpinLock(&Connection->Lock, OldIrql); - if (Status == STATUS_PENDING) { - Bucket = ExAllocatePoolWithTag( NonPagedPool, sizeof(*Bucket), TDI_BUCKET_TAG ); - if( !Bucket ) - { - return STATUS_NO_MEMORY; - } + Bucket = exAllocatePool( NonPagedPool, sizeof(*Bucket) ); + if( !Bucket ) return STATUS_NO_MEMORY; Bucket->Request.RequestNotifyObject = (PVOID)Complete; Bucket->Request.RequestContext = Context; + + IoMarkIrpPending((PIRP)Context); - ExInterlockedInsertTailList( &Connection->ConnectRequest, &Bucket->Entry, - &Connection->Lock ); + ExInterlockedInsertTailList( &Connection->ConnectRequest, &Bucket->Entry, &Connection->Lock ); } - } else { - KeReleaseSpinLock(&Connection->Lock, OldIrql); } return Status; @@ -694,20 +671,29 @@ NTSTATUS TCPDisconnect PTDI_CONNECTION_INFORMATION ReturnInfo, PTCP_COMPLETION_ROUTINE Complete, PVOID Context ) { - NTSTATUS Status = STATUS_INVALID_PARAMETER; - KIRQL OldIrql; + NTSTATUS Status; + + ASSERT_LOCKED(&TCPLock); TI_DbgPrint(DEBUG_TCP,("started\n")); - KeAcquireSpinLock(&Connection->Lock, &OldIrql); + switch( Flags & (TDI_DISCONNECT_ABORT | TDI_DISCONNECT_RELEASE) ) { + case 0: + case TDI_DISCONNECT_ABORT: + Flags = 0; + break; - if (Flags & TDI_DISCONNECT_RELEASE) - Status = TCPTranslateError(OskitTCPDisconnect(Connection->SocketContext)); + case TDI_DISCONNECT_ABORT | TDI_DISCONNECT_RELEASE: + Flags = 2; + break; - if ((Flags & TDI_DISCONNECT_ABORT) || !Flags) - Status = TCPTranslateError(OskitTCPShutdown(Connection->SocketContext, FWRITE | FREAD)); + case TDI_DISCONNECT_RELEASE: + Flags = 1; + break; + } - KeReleaseSpinLock(&Connection->Lock, OldIrql); + Status = TCPTranslateError + ( OskitTCPShutdown( Connection->SocketContext, Flags ) ); TI_DbgPrint(DEBUG_TCP,("finished %x\n", Status)); @@ -717,20 +703,18 @@ NTSTATUS TCPDisconnect NTSTATUS TCPClose ( PCONNECTION_ENDPOINT Connection ) { NTSTATUS Status; - KIRQL OldIrql; - PVOID Socket; TI_DbgPrint(DEBUG_TCP,("TCPClose started\n")); - KeAcquireSpinLock(&Connection->Lock, &OldIrql); - Socket = Connection->SocketContext; - Connection->SocketContext = NULL; - Status = TCPTranslateError( OskitTCPClose( Socket ) ); - if (!NT_SUCCESS(Status)) - { - Connection->SocketContext = Socket; - } - KeReleaseSpinLock(&Connection->Lock, OldIrql); + ASSERT_LOCKED(&TCPLock); + + /* Make our code remove all pending IRPs */ + Connection->State |= SEL_FIN; + DrainSignals(); + + Status = TCPTranslateError( OskitTCPClose( Connection->SocketContext ) ); + if (Status == STATUS_SUCCESS) + Connection->SocketContext = NULL; TI_DbgPrint(DEBUG_TCP,("TCPClose finished %x\n", Status)); @@ -749,19 +733,25 @@ NTSTATUS TCPReceiveData UINT DataLen, Received = 0; NTSTATUS Status; PTDI_BUCKET Bucket; - KIRQL OldIrql; TI_DbgPrint(DEBUG_TCP,("Called for %d bytes (on socket %x)\n", ReceiveLength, Connection->SocketContext)); + ASSERT_LOCKED(&TCPLock); + + ASSERT_KM_POINTER(Connection->SocketContext); + + /* Closing */ + if (Connection->State & SEL_FIN) + { + *BytesReceived = 0; + return STATUS_REMOTE_DISCONNECT; + } + NdisQueryBuffer( Buffer, &DataBuffer, &DataLen ); TI_DbgPrint(DEBUG_TCP,("TCP>|< Got an MDL %x (%x:%d)\n", Buffer, DataBuffer, DataLen)); - KeAcquireSpinLock(&Connection->Lock, &OldIrql); - - ASSERT_KM_POINTER(Connection->SocketContext); - Status = TCPTranslateError ( OskitTCPRecv ( Connection->SocketContext, @@ -770,14 +760,12 @@ NTSTATUS TCPReceiveData &Received, ReceiveFlags ) ); - KeReleaseSpinLock(&Connection->Lock, OldIrql); - TI_DbgPrint(DEBUG_TCP,("OskitTCPReceive: %x, %d\n", Status, Received)); /* Keep this request around ... there was no data yet */ if( Status == STATUS_PENDING ) { /* Freed in TCPSocketState */ - Bucket = ExAllocatePoolWithTag( NonPagedPool, sizeof(*Bucket), TDI_BUCKET_TAG ); + Bucket = exAllocatePool( NonPagedPool, sizeof(*Bucket) ); if( !Bucket ) { TI_DbgPrint(DEBUG_TCP,("Failed to allocate bucket\n")); return STATUS_NO_MEMORY; @@ -787,8 +775,9 @@ NTSTATUS TCPReceiveData Bucket->Request.RequestContext = Context; *BytesReceived = 0; - ExInterlockedInsertTailList( &Connection->ReceiveRequest, &Bucket->Entry, - &Connection->Lock ); + IoMarkIrpPending((PIRP)Context); + + ExInterlockedInsertTailList( &Connection->ReceiveRequest, &Bucket->Entry, &Connection->Lock ); TI_DbgPrint(DEBUG_TCP,("Queued read irp\n")); } else { TI_DbgPrint(DEBUG_TCP,("Got status %x, bytes %d\n", Status, Received)); @@ -811,9 +800,8 @@ NTSTATUS TCPSendData UINT Sent = 0; NTSTATUS Status; PTDI_BUCKET Bucket; - KIRQL OldIrql; - KeAcquireSpinLock(&Connection->Lock, &OldIrql); + ASSERT_LOCKED(&TCPLock); TI_DbgPrint(DEBUG_TCP,("Called for %d bytes (on socket %x)\n", SendLength, Connection->SocketContext)); @@ -824,19 +812,24 @@ NTSTATUS TCPSendData TI_DbgPrint(DEBUG_TCP,("Connection->SocketContext = %x\n", Connection->SocketContext)); + /* Closing */ + if (Connection->State & SEL_FIN) + { + *BytesSent = 0; + return STATUS_REMOTE_DISCONNECT; + } + Status = TCPTranslateError ( OskitTCPSend( Connection->SocketContext, (OSK_PCHAR)BufferData, SendLength, &Sent, 0 ) ); - KeReleaseSpinLock(&Connection->Lock, OldIrql); - TI_DbgPrint(DEBUG_TCP,("OskitTCPSend: %x, %d\n", Status, Sent)); /* Keep this request around ... there was no data yet */ if( Status == STATUS_PENDING ) { /* Freed in TCPSocketState */ - Bucket = ExAllocatePoolWithTag( NonPagedPool, sizeof(*Bucket), TDI_BUCKET_TAG ); + Bucket = exAllocatePool( NonPagedPool, sizeof(*Bucket) ); if( !Bucket ) { TI_DbgPrint(DEBUG_TCP,("Failed to allocate bucket\n")); return STATUS_NO_MEMORY; @@ -845,9 +838,10 @@ NTSTATUS TCPSendData Bucket->Request.RequestNotifyObject = Complete; Bucket->Request.RequestContext = Context; *BytesSent = 0; + + IoMarkIrpPending((PIRP)Context); - ExInterlockedInsertTailList( &Connection->SendRequest, &Bucket->Entry, - &Connection->Lock ); + ExInterlockedInsertTailList( &Connection->SendRequest, &Bucket->Entry, &Connection->Lock ); TI_DbgPrint(DEBUG_TCP,("Queued write irp\n")); } else { TI_DbgPrint(DEBUG_TCP,("Got status %x, bytes %d\n", Status, Sent)); @@ -859,6 +853,10 @@ NTSTATUS TCPSendData return Status; } +VOID TCPTimeout(VOID) { + /* Now handled by TimerThread */ +} + UINT TCPAllocatePort( UINT HintPort ) { if( HintPort ) { if( AllocatePort( &TCPPorts, HintPort ) ) return HintPort; @@ -882,16 +880,12 @@ NTSTATUS TCPGetSockAddress OSK_UI16 LocalPort, RemotePort; PTA_IP_ADDRESS AddressIP = (PTA_IP_ADDRESS)Address; NTSTATUS Status; - KIRQL OldIrql; - KeAcquireSpinLock(&Connection->Lock, &OldIrql); + ASSERT_LOCKED(&TCPLock); Status = TCPTranslateError(OskitTCPGetAddress(Connection->SocketContext, &LocalAddress, &LocalPort, &RemoteAddress, &RemotePort)); - - KeReleaseSpinLock(&Connection->Lock, OldIrql); - if (!NT_SUCCESS(Status)) return Status; @@ -904,13 +898,12 @@ NTSTATUS TCPGetSockAddress return Status; } -BOOLEAN TCPRemoveIRP( PCONNECTION_ENDPOINT Endpoint, PIRP Irp ) { +VOID TCPRemoveIRP( PCONNECTION_ENDPOINT Endpoint, PIRP Irp ) { PLIST_ENTRY Entry; PLIST_ENTRY ListHead[4]; KIRQL OldIrql; PTDI_BUCKET Bucket; UINT i = 0; - BOOLEAN Found = FALSE; ListHead[0] = &Endpoint->SendRequest; ListHead[1] = &Endpoint->ReceiveRequest; @@ -929,16 +922,13 @@ BOOLEAN TCPRemoveIRP( PCONNECTION_ENDPOINT Endpoint, PIRP Irp ) { if( Bucket->Request.RequestContext == Irp ) { RemoveEntryList( &Bucket->Entry ); - ExFreePoolWithTag( Bucket, TDI_BUCKET_TAG ); - Found = TRUE; + exFreePool( Bucket ); break; } } } TcpipReleaseSpinLock( &Endpoint->Lock, OldIrql ); - - return Found; } /* EOF */ diff --git a/reactos/lib/drivers/ip/transport/udp/udp.c b/reactos/lib/drivers/ip/transport/udp/udp.c index 125e5101fc0..46366e6833d 100644 --- a/reactos/lib/drivers/ip/transport/udp/udp.c +++ b/reactos/lib/drivers/ip/transport/udp/udp.c @@ -172,9 +172,6 @@ NTSTATUS UDPSendDatagram( USHORT RemotePort; NTSTATUS Status; PNEIGHBOR_CACHE_ENTRY NCE; - KIRQL OldIrql; - - KeAcquireSpinLock(&AddrFile->Lock, &OldIrql); TI_DbgPrint(MID_TRACE,("Sending Datagram(%x %x %x %d)\n", AddrFile, ConnInfo, BufferData, DataSize)); @@ -189,12 +186,10 @@ NTSTATUS UDPSendDatagram( break; default: - KeReleaseSpinLock(&AddrFile->Lock, OldIrql); return STATUS_UNSUCCESSFUL; } if(!(NCE = RouteGetRouteToDestination( &RemoteAddress ))) { - KeReleaseSpinLock(&AddrFile->Lock, OldIrql); return STATUS_NETWORK_UNREACHABLE; } @@ -218,20 +213,14 @@ NTSTATUS UDPSendDatagram( DataSize ); if( !NT_SUCCESS(Status) ) - { - KeReleaseSpinLock(&AddrFile->Lock, OldIrql); return Status; - } if (!NT_SUCCESS(Status = IPSendDatagram( &Packet, NCE, UDPSendPacketComplete, NULL ))) { - KeReleaseSpinLock(&AddrFile->Lock, OldIrql); FreeNdisPacket(Packet.NdisPacket); return Status; } - KeReleaseSpinLock(&AddrFile->Lock, OldIrql); - return STATUS_SUCCESS; } diff --git a/reactos/lib/drivers/oskittcp/include/memtrack.h b/reactos/lib/drivers/oskittcp/include/memtrack.h new file mode 100644 index 00000000000..802ed74aed1 --- /dev/null +++ b/reactos/lib/drivers/oskittcp/include/memtrack.h @@ -0,0 +1,80 @@ +#ifndef MEMTRACK_H +#define MEMTRACK_H + +#ifndef FOURCC +#define FOURCC(a,b,c,d) (((a)<<24)|((b)<<16)|((c)<<8)|(d)) +#endif + +#define FBSD_MALLOC FOURCC('d','s','b','f') +#define EXALLOC_TAG FOURCC('E','x','A','l') + +#if DBG +#define MTMARK() TrackDumpFL(__FILE__, __LINE__) +#define NdisAllocateBuffer(x,y,z,a,b) { \ + NdisAllocateBuffer(x,y,z,a,b); \ + if( *x == NDIS_STATUS_SUCCESS ) { \ + Track(NDIS_BUFFER_TAG, *y); \ + } \ +} +#define NdisAllocatePacket(x,y,z) { \ + NdisAllocatePacket(x,y,z); \ + if( *x == NDIS_STATUS_SUCCESS ) { \ + Track(NDIS_PACKET_TAG, *y); \ + } \ +} +#define FreeNdisPacket(x) { TI_DbgPrint(MID_TRACE,("Deleting Packet %x\n", x)); FreeNdisPacketX(x); } +#define NdisFreePacket(x) { Untrack(x); NdisFreePacket(x); } +#define NdisFreeBuffer(x) { Untrack(x); NdisFreeBuffer(x); } +#define exAllocatePool(x,y) ExAllocatePoolX(x,y,__FILE__,__LINE__) +#define exAllocatePoolWithTag(x,y,z) ExAllocatePoolX(x,y,__FILE__,__LINE__) +#define exFreePool(x) ExFreePoolX(x,__FILE__,__LINE__) + +extern LIST_ENTRY AllocatedObjectsHead; +extern KSPIN_LOCK AllocatedObjectsLock; + +typedef struct _ALLOCATION_TRACKER { + LIST_ENTRY Entry; + DWORD Tag; + PVOID Thing; + PCHAR FileName; + DWORD LineNo; +} ALLOCATION_TRACKER, *PALLOCATION_TRACKER; + +VOID TrackingInit(); +VOID TrackWithTag( DWORD Tag, PVOID Thing, PCHAR File, DWORD Line ); +#define Track(Tag,Thing) TrackWithTag(Tag,Thing,__FILE__,__LINE__) +VOID UntrackFL( PCHAR File, DWORD Line, PVOID Thing ); +#define Untrack(Thing) UntrackFL(__FILE__,__LINE__,Thing) +VOID TrackDumpFL( PCHAR File, DWORD Line ); +#define TrackDump() TrackDumpFL(__FILE__,__LINE__) +VOID TrackTag( DWORD Tag ); + +static __inline PVOID ExAllocatePoolX( POOL_TYPE type, SIZE_T size, PCHAR File, ULONG Line ) { + PVOID Out = ExAllocatePool( type, size ); + if( Out ) TrackWithTag( EXALLOC_TAG, Out, File, Line ); + return Out; +} +static __inline VOID ExFreePoolX( PVOID Data, PCHAR File, ULONG Line ) { + UntrackFL(File, Line, Data); + ExFreePool(Data); +} + +#define MEMTRACK_MAX_TAGS_TO_TRACK 64 +#else +#define MTMARK() +#define Track(x,y) +#define TrackingInit() +#define TrackDump() +#define Untrack(x) +#define TrackTag(x) +#define FreeNdisPacket FreeNdisPacketX +#define exFreePool(x) ExFreePool(x) +#define exAllocatePool(x,y) ExAllocatePool(x,y) +#define exAllocatePoolWithTag(x,y,z) ExAllocatePoolWithTag(x,y,z) +#define exAllocateFromNPagedLookasideList(x) ExAllocateFromNPagedLookasideList(x) +#define exFreeToNPagedLookasideList(x,y) ExFreeToNPagedLookasideList(x,y) +#define TrackWithTag(w,x,y,z) +#define UntrackFL(w,x,y,z) +#endif + +#endif/*MEMMTRAC_H*/ diff --git a/reactos/lib/drivers/oskittcp/include/oskittcp.h b/reactos/lib/drivers/oskittcp/include/oskittcp.h index 64e587b7dad..b5242fe03a9 100644 --- a/reactos/lib/drivers/oskittcp/include/oskittcp.h +++ b/reactos/lib/drivers/oskittcp/include/oskittcp.h @@ -123,7 +123,7 @@ extern int OskitTCPSend( void *socket, OSK_UINT *OutLen, OSK_UINT Flags ); -extern int OskitTCPConnect( void *socket, +extern int OskitTCPConnect( void *socket, void *connection, void *nam, OSK_UINT namelen ); extern int OskitTCPClose( void *socket ); @@ -131,7 +131,7 @@ extern int OskitTCPBind( void *socket, void *nam, OSK_UINT namelen ); extern int OskitTCPAccept( void *socket, void **new_socket, - void *context, void *addr_out, + void *addr_out, OSK_UINT addr_len, OSK_UINT *out_addr_len, OSK_UINT finish_accept ); @@ -164,8 +164,6 @@ int OskitTCPSetSockOpt(void *socket, int OskitTCPDisconnect(void *socket); -int OskitTCPGetSocketError(void *socket); - #undef errno void *fbsd_malloc( unsigned int bytes, char *file, unsigned line, ... ); @@ -189,27 +187,4 @@ void fbsd_free( void *data, char *file, unsigned line, ... ); #define FREAD 0x0001 #define FWRITE 0x0002 -/* Don't define this unless your are insane or aicom */ -//#define LOCK_SPAM - -#ifdef LOCK_SPAM -#define OSKLock() if (!KeTryToAcquireSpinLockAtDpcLevel(&OSKLock)) \ - { \ - DbgPrint("OSKLock WAIT (%s)\n", __FUNCTION__); \ - KeAcquireSpinLockAtDpcLevel(&OSKLock); \ - } \ - DbgPrint("OSKLock >>>> (%s)\n", __FUNCTION__) - -#define OSKUnlock() KeReleaseSpinLockFromDpcLevel(&OSKLock); \ - DbgPrint("OSKLock <<<< (%s)\n", __FUNCTION__) -#else -#define OSKLock() KeAcquireSpinLockAtDpcLevel(&OSKLock) -#define OSKUnlock() KeReleaseSpinLockFromDpcLevel(&OSKLock) -#endif - -#define OSKLockAndRaise(x) KeRaiseIrql(DISPATCH_LEVEL, x); \ - OSKLock() -#define OSKUnlockAndLower(x) OSKUnlock(); \ - KeLowerIrql(x) - #endif/*OSKITTCP_H*/ diff --git a/reactos/lib/drivers/oskittcp/oskittcp/interface.c b/reactos/lib/drivers/oskittcp/oskittcp/interface.c index a925d330434..a1d3e89e3de 100644 --- a/reactos/lib/drivers/oskittcp/oskittcp/interface.c +++ b/reactos/lib/drivers/oskittcp/oskittcp/interface.c @@ -23,8 +23,6 @@ OSKITTCP_EVENT_HANDLERS OtcpEvent = { 0 }; //OSK_UINT OskitDebugTraceLevel = OSK_DEBUG_ULTRA; OSK_UINT OskitDebugTraceLevel = 0; -KSPIN_LOCK OSKLock; - /* SPL */ unsigned cpl; unsigned net_imask; @@ -47,7 +45,6 @@ void fbsd_free( void *data, char *file, unsigned line, ... ) { void InitOskitTCP() { OS_DbgPrint(OSK_MID_TRACE,("Init Called\n")); - KeInitializeSpinLock(&OSKLock); OS_DbgPrint(OSK_MID_TRACE,("MB Init\n")); mbinit(); OS_DbgPrint(OSK_MID_TRACE,("Rawip Init\n")); @@ -69,19 +66,12 @@ void DeinitOskitTCP() { } void TimerOskitTCP( int FastTimer, int SlowTimer ) { - KIRQL OldIrql; - - /* This function is a special case in which we cannot use OSKLock/OSKUnlock - * because we don't enter with the connection lock held */ - - OSKLockAndRaise(&OldIrql); if ( SlowTimer ) { tcp_slowtimo(); } if ( FastTimer ) { tcp_fasttimo(); } - OSKUnlockAndLower(OldIrql); } void RegisterOskitTCPEventHandlers( POSKITTCP_EVENT_HANDLERS EventHandlers ) { @@ -125,16 +115,12 @@ int OskitTCPSocket( void *context, int proto ) { struct socket *so; - - OSKLock(); int error = socreate(domain, &so, type, proto); if( !error ) { so->so_connection = context; so->so_state |= SS_NBIO; *aso = so; } - OSKUnlock(); - return error; } @@ -167,11 +153,8 @@ int OskitTCPRecv( void *connection, OS_DbgPrint(OSK_MID_TRACE,("Reading %d bytes from TCP:\n", Len)); - OSKLock(); error = soreceive( connection, NULL, &uio, NULL, NULL /* SCM_RIGHTS */, &tcp_flags ); - OSKUnlock(); - *OutLen = Len - uio.uio_resid; return error; @@ -199,15 +182,14 @@ int OskitTCPBind( void *socket, addr.sa_family = addr.sa_len; addr.sa_len = sizeof(struct sockaddr); - OSKLock(); error = sobind(so, &sabuf); - OSKUnlock(); OS_DbgPrint(OSK_MID_TRACE,("Ending: %08x\n", error)); return (error); } -int OskitTCPConnect( void *socket, void *nam, OSK_UINT namelen ) { +int OskitTCPConnect( void *socket, void *connection, + void *nam, OSK_UINT namelen ) { struct socket *so = socket; int error = EFAULT; struct mbuf sabuf; @@ -215,7 +197,8 @@ int OskitTCPConnect( void *socket, void *nam, OSK_UINT namelen ) { OS_DbgPrint(OSK_MID_TRACE,("Called, socket = %08x\n", socket)); - OSKLock(); + so->so_connection = connection; + if ((so->so_state & SS_NBIO) && (so->so_state & SS_ISCONNECTING)) { error = EALREADY; goto done; @@ -234,9 +217,7 @@ int OskitTCPConnect( void *socket, void *nam, OSK_UINT namelen ) { error = soconnect(so, &sabuf); - if (error == EINPROGRESS) - goto done; - else if (error) + if (error) goto bad; if ((so->so_state & SS_NBIO) && (so->so_state & SS_ISCONNECTING)) { @@ -251,54 +232,34 @@ bad: error = EINTR; done: - OSKUnlock(); OS_DbgPrint(OSK_MID_TRACE,("Ending: %08x\n", error)); return (error); } int OskitTCPDisconnect(void *socket) { - int error; - if (!socket) return OSK_ESHUTDOWN; - OSKLock(); - error = sodisconnect(socket); - OSKUnlock(); - - return error; + return sodisconnect(socket); } int OskitTCPShutdown( void *socket, int disconn_type ) { - int error; - if (!socket) return OSK_ESHUTDOWN; - OSKLock(); - error = soshutdown( socket, disconn_type ); - OSKUnlock(); - - return error; + return soshutdown( socket, disconn_type ); } int OskitTCPClose( void *socket ) { - int error; struct socket *so = socket; if (!socket) return OSK_ESHUTDOWN; - OSKLock(); - /* We have to remove the socket context here otherwise we end up - * back in HandleSignalledConnection with a freed connection context - */ - so->so_connection = NULL; - error = soclose( socket ); - OSKUnlock(); - - return error; + so->so_connection = 0; + soclose( so ); + return 0; } int OskitTCPSend( void *socket, OSK_PCHAR Data, OSK_UINT Len, @@ -320,10 +281,7 @@ int OskitTCPSend( void *socket, OSK_PCHAR Data, OSK_UINT Len, uio.uio_rw = UIO_WRITE; uio.uio_procp = NULL; - OSKLock(); error = sosend( socket, NULL, &uio, NULL, NULL, 0 ); - OSKUnlock(); - *OutLen = Len - uio.uio_resid; return error; @@ -331,7 +289,6 @@ int OskitTCPSend( void *socket, OSK_PCHAR Data, OSK_UINT Len, int OskitTCPAccept( void *socket, void **new_socket, - void *context, void *AddrOut, OSK_UINT AddrLen, OSK_UINT *OutAddrLen, @@ -360,12 +317,11 @@ int OskitTCPAccept( void *socket, /* that's a copyin actually */ namelen = *OutAddrLen; - OSKLock(); - s = splnet(); #if 0 if ((head->so_options & SO_ACCEPTCONN) == 0) { + splx(s); OS_DbgPrint(OSK_MID_TRACE,("OSKITTCP: head->so_options = %x, wanted bit %x\n", head->so_options, SO_ACCEPTCONN)); error = EINVAL; @@ -377,10 +333,39 @@ int OskitTCPAccept( void *socket, head->so_q, head->so_state)); if ((head->so_state & SS_NBIO) && head->so_q == NULL) { + splx(s); error = EWOULDBLOCK; goto out; } + OS_DbgPrint(OSK_MID_TRACE,("error = %d\n", error)); + while (head->so_q == NULL && head->so_error == 0) { + if (head->so_state & SS_CANTRCVMORE) { + head->so_error = ECONNABORTED; + break; + } + OS_DbgPrint(OSK_MID_TRACE,("error = %d\n", error)); + error = tsleep((caddr_t)&head->so_timeo, PSOCK | PCATCH, + "accept", 0); + if (error) { + splx(s); + goto out; + } + OS_DbgPrint(OSK_MID_TRACE,("error = %d\n", error)); + } + OS_DbgPrint(OSK_MID_TRACE,("error = %d\n", error)); + +#if 0 + if (head->so_error) { + OS_DbgPrint(OSK_MID_TRACE,("error = %d\n", error)); + error = head->so_error; + head->so_error = 0; + splx(s); + goto out; + } + OS_DbgPrint(OSK_MID_TRACE,("error = %d\n", error)); +#endif + /* * At this point we know that there is at least one connection * ready to be accepted. Remove it from the queue. @@ -399,20 +384,19 @@ int OskitTCPAccept( void *socket, head->so_q = so->so_q; head->so_qlen--; + *newso = so; + + /*so->so_state &= ~SS_COMP;*/ + mnam.m_data = (char *)&sa; mnam.m_len = sizeof(sa); - error = soaccept(so, &mnam); - if (error) - goto out; + (void) soaccept(so, &mnam); - so->so_state |= SS_NBIO | SS_ISCONNECTED; + so->so_state = SS_NBIO | SS_ISCONNECTED; so->so_q = so->so_q0 = NULL; so->so_qlen = 0; so->so_head = 0; - so->so_connection = context; - - *newso = so; OS_DbgPrint(OSK_MID_TRACE,("error = %d\n", error)); if (name) { @@ -422,10 +406,9 @@ int OskitTCPAccept( void *socket, *OutAddrLen = namelen; /* copyout actually */ } OS_DbgPrint(OSK_MID_TRACE,("error = %d\n", error)); + splx(s); } out: - splx(s); - OSKUnlock(); OS_DbgPrint(OSK_MID_TRACE,("OSKITTCP: Returning %d\n", error)); return (error); } @@ -438,16 +421,10 @@ out: void OskitTCPReceiveDatagram( OSK_PCHAR Data, OSK_UINT Len, OSK_UINT IpHeaderLen ) { - struct mbuf *Ip; + struct mbuf *Ip = m_devget( (char *)Data, Len, 0, NULL, NULL ); struct ip *iph; - OSKLock(); - Ip = m_devget( (char *)Data, Len, 0, NULL, NULL ); - if( !Ip ) - { - OSKUnlock(); - return; /* drop the segment */ - } + if( !Ip ) return; /* drop the segment */ //memcpy( Ip->m_data, Data, Len ); Ip->m_pkthdr.len = IpHeaderLen; @@ -462,7 +439,6 @@ void OskitTCPReceiveDatagram( OSK_PCHAR Data, OSK_UINT Len, IpHeaderLen)); tcp_input(Ip, IpHeaderLen); - OSKUnlock(); /* The buffer Ip is freed by tcp_input */ } @@ -474,7 +450,6 @@ int OskitTCPSetSockOpt(void *socket, int size) { struct mbuf *m; - int error; if (!socket) return OSK_ESHUTDOWN; @@ -482,23 +457,16 @@ int OskitTCPSetSockOpt(void *socket, if (size >= MLEN) return OSK_EINVAL; - OSKLock(); m = m_get(M_WAIT, MT_SOOPTS); if (!m) - { - OSKUnlock(); return OSK_ENOMEM; - } m->m_len = size; memcpy(m->m_data, buffer, size); /* m is freed by sosetopt */ - error = sosetopt(socket, level, optname, m); - OSKUnlock(); - - return error; + return sosetopt(socket, level, optname, m); } int OskitTCPGetSockOpt(void *socket, @@ -513,7 +481,6 @@ int OskitTCPGetSockOpt(void *socket, if (!socket) return OSK_ESHUTDOWN; - OSKLock(); error = sogetopt(socket, level, optname, &m); if (!error) { @@ -522,7 +489,6 @@ int OskitTCPGetSockOpt(void *socket, if (!buffer || oldsize < m->m_len) { m_freem(m); - OSKUnlock(); return OSK_EINVAL; } @@ -530,7 +496,6 @@ int OskitTCPGetSockOpt(void *socket, m_freem(m); } - OSKUnlock(); return error; } @@ -542,11 +507,7 @@ int OskitTCPListen( void *socket, int backlog ) { return OSK_ESHUTDOWN; OS_DbgPrint(OSK_MID_TRACE,("Called, socket = %08x\n", socket)); - - OSKLock(); error = solisten( socket, backlog ); - OSKUnlock(); - OS_DbgPrint(OSK_MID_TRACE,("Ending: %08x\n", error)); return error; @@ -563,13 +524,11 @@ int OskitTCPSetAddress( void *socket, if (!socket) return OSK_ESHUTDOWN; - OSKLock(); inp = (struct inpcb *)so->so_pcb; inp->inp_laddr.s_addr = LocalAddress; inp->inp_lport = LocalPort; inp->inp_faddr.s_addr = RemoteAddress; inp->inp_fport = RemotePort; - OSKUnlock(); return 0; } @@ -585,31 +544,15 @@ int OskitTCPGetAddress( void *socket, if (!socket) return OSK_ESHUTDOWN; - OSKLock(); inp = (struct inpcb *)so->so_pcb; *LocalAddress = inp->inp_laddr.s_addr; *LocalPort = inp->inp_lport; *RemoteAddress = inp->inp_faddr.s_addr; *RemotePort = inp->inp_fport; - OSKUnlock(); return 0; } -int OskitTCPGetSocketError(void *socket) { - struct socket *so = socket; - int error; - - if (!socket) - return OSK_ESHUTDOWN; - - OSKLock(); - error = so->so_error; - OSKUnlock(); - - return error; -} - struct ifaddr *ifa_iffind(struct sockaddr *addr, int type) { if( OtcpEvent.FindInterface ) @@ -623,7 +566,7 @@ struct ifaddr *ifa_iffind(struct sockaddr *addr, int type) void oskittcp_die( const char *file, int line ) { DbgPrint("\n\n*** OSKITTCP: Panic Called at %s:%d ***\n", file, line); - ASSERT(FALSE); + *((int *)0) = 0; } /* Stuff supporting the BSD network-interface interface */