* Adapter = Pointer to LAN_ADAPTER structure to free
*/
{
- ExFreePoolWithTag(Adapter, LAN_ADAPTER_TAG);
+ exFreePool(Adapter);
}
Adapter = WorkItem->Adapter;
BytesTransferred = WorkItem->BytesTransferred;
- ExFreePoolWithTag(WorkItem, WQ_CONTEXT_TAG);
+ exFreePool(WorkItem);
IPInitializePacket(&IPPacket, 0);
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"));
WQItem->BytesTransferred = BytesTransferred;
if (!ChewCreate( LanReceiveWorker, WQItem ))
- ExFreePoolWithTag(WQItem, WQ_CONTEXT_TAG);
+ exFreePool(WQItem);
}
VOID NTAPI ProtocolTransferDataComplete(
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;
}
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));
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;
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;
}
default:
/* Unsupported media */
TI_DbgPrint(MIN_TRACE, ("Unsupported media.\n"));
- ExFreePoolWithTag(IF, LAN_ADAPTER_TAG);
+ exFreePool(IF);
return NDIS_STATUS_NOT_SUPPORTED;
}
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;
}
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;
}
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;
}
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;
}
/* 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;
}
*/
#define AddrInitIPv4(IPAddress, RawAddress) \
{ \
+ INIT_TAG((IPAddress), '4VPI'); \
(IPAddress)->Type = IP_ADDRESS_V4; \
(IPAddress)->Address.IPv4Address = (RawAddress); \
}
PVOID Context,
PIRP Irp);
-BOOLEAN DGRemoveIRP(
+VOID DGRemoveIRP(
PADDRESS_FILE AddrFile,
PIRP Irp);
#define CP CHECKPOINT
+#include <memtrack.h>
+
#define ASSERT_KM_POINTER(_x) \
ASSERT(((PVOID)_x) != (PVOID)0xcccccccc); \
ASSERT(((PVOID)_x) >= (PVOID)0x80000000);
VOID DispDoDisconnect(
PVOID Data);
-NTSTATUS IRPFinish( PIRP Irp, NTSTATUS Status );
-
#endif /* __DISPATCH_H */
/* EOF */
extern LIST_ENTRY ConnectionEndpointListHead;
extern KSPIN_LOCK ConnectionEndpointListLock;
+
NTSTATUS FileOpenAddress(
PTDI_REQUEST Request,
PTA_IP_ADDRESS AddrList,
PTDI_REQUEST Request,
PVOID ClientContext);
+PCONNECTION_ENDPOINT FileFindConnectionByContext( PVOID Context );
+
NTSTATUS FileCloseConnection(
PTDI_REQUEST Request);
/* 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) */
/* 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)*/
/* 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 */
--- /dev/null
+/*
+ * 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*/
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*/
--- /dev/null
+#ifndef MEMTRACK_H
+#define MEMTRACK_H
+
+#include <pool.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')
+#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*/
/* 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 */
#include <limits.h>
#include <ntddk.h>
#include <ntifs.h>
-#include <tags.h>
#include <tdi.h>
#include <tdistat.h>
+#include <../recmutex/recmutex.h>
#include <tcpip.h>
#include <loopback.h>
#include <ip.h>
#include <udp.h>
#include <tcp.h>
#include <arp.h>
+#include <irp.h>
#include <tilists.h>
#include <dispatch.h>
#include <fileobjs.h>
#include <lock.h>
#include <wait.h>
+#include <memtrack.h>
#include <oskittcp.h>
#include <interface.h>
#include <ports.h>
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,
+++ /dev/null
-/*
- * 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
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 */
#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,
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,
NTSTATUS TCPTranslateError( int OskitError );
+VOID TCPTimeout();
+
UINT TCPAllocatePort( UINT HintPort );
VOID TCPFreePort( UINT Port );
NTSTATUS TCPShutdown(
VOID);
-BOOLEAN TCPRemoveIRP( PCONNECTION_ENDPOINT Connection, PIRP Irp );
+VOID TCPRemoveIRP( PCONNECTION_ENDPOINT Connection, PIRP Irp );
#endif /* __TCP_H */
#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", \
#else /* DBG */
+#define DEFINE_TAG
+#define INIT_TAG(Object, Tag)
+
/*
* VOID ReferenceObject(
* PVOID Object)
/* 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 */
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 */
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
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;
--- /dev/null
+#include <ntddk.h>
+#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 );
+}
+
--- /dev/null
+#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*/
<directory name="datalink">
<file>lan.c</file>
</directory>
+ <directory name="recmutex">
+ <file>recmutex.c</file>
+ </directory>
<directory name="tcpip">
<file>ainfo.c</file>
<file>buffer.c</file>
<file>fileobjs.c</file>
<file>iinfo.c</file>
<file>info.c</file>
+ <file>irp.c</file>
<file>lock.c</file>
<file>main.c</file>
<file>ninfo.c</file>
PVOID Buffer,
UINT BufferSize)
{
- //KIRQL OldIrql;
-
switch (ID->toi_id)
{
#if 0
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:
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 );
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;
}
-VOID FreeNdisPacket
-( PNDIS_PACKET Packet )
+VOID FreeNdisPacketX
+( PNDIS_PACKET Packet,
+ PCHAR File,
+ UINT Line )
/*
* FUNCTION: Frees an NDIS packet
* ARGUMENTS:
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);
}
#include "precomp.h"
#include <pseh/pseh2.h>
-
-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,
{
PIRP Irp;
PIO_STACK_LOCATION IrpSp;
+ PTRANSPORT_CONTEXT TranContext;
KIRQL OldIrql;
TI_DbgPrint(DEBUG_IRP, ("Called for irp %x (%x, %d).\n",
Irp = Context;
IrpSp = IoGetCurrentIrpStackLocation(Irp);
+ TranContext = (PTRANSPORT_CONTEXT)IrpSp->FileObject->FsContext;
IoAcquireCancelSpinLock(&OldIrql);
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)
PTRANSPORT_CONTEXT TranContext;
PFILE_OBJECT FileObject;
UCHAR MinorFunction;
- BOOLEAN DequeuedIrp = TRUE;
-
- IoReleaseCancelSpinLock(Irp->CancelIrql);
+ PDISCONNECT_TYPE DisType;
TI_DbgPrint(DEBUG_IRP, ("Called.\n"));
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) {
break;
}
- DequeuedIrp = DGRemoveIRP(TranContext->Handle.AddressHandle, Irp);
+ DGRemoveIRP(TranContext->Handle.AddressHandle, Irp);
break;
case TDI_RECEIVE_DATAGRAM:
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"));
}
PTRANSPORT_CONTEXT TranContext;
PFILE_OBJECT FileObject;
PCONNECTION_ENDPOINT Connection;
-
- IoReleaseCancelSpinLock(Irp->CancelIrql);
+ /*NTSTATUS Status = STATUS_SUCCESS;*/
TI_DbgPrint(DEBUG_IRP, ("Called.\n"));
/* 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"));
}
PFILE_OBJECT FileObject;
PADDRESS_FILE AddrFile = NULL;
NTSTATUS Status;
- KIRQL OldIrql;
TI_DbgPrint(DEBUG_IRP, ("Called.\n"));
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(
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;
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 */
/* FIXME: Maybe do this in DispTdiDisassociateAddress() instead? */
ObDereferenceObject(FileObject);
- KeReleaseSpinLockFromDpcLevel(&AddrFile->Lock);
- KeReleaseSpinLock(&Connection->Lock, OldIrql);
-
return Status;
}
/* 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"));
}
done:
+ TcpipRecursiveMutexLeave( &TCPLock );
+
if (Status != STATUS_PENDING) {
DispDataRequestComplete(Irp, Status, 0);
} else
PCONNECTION_ENDPOINT Connection;
PTRANSPORT_CONTEXT TranContext;
PIO_STACK_LOCATION IrpSp;
- KIRQL OldIrql;
TI_DbgPrint(DEBUG_IRP, ("Called.\n"));
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;
}
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;
Irp );
done:
+ TcpipRecursiveMutexLeave( &TCPLock );
+
if (Status != STATUS_PENDING) {
DispDataRequestComplete(Irp, Status, 0);
} else
PTRANSPORT_CONTEXT TranContext;
PIO_STACK_LOCATION IrpSp;
NTSTATUS Status = STATUS_SUCCESS;
- KIRQL OldIrql;
TI_DbgPrint(DEBUG_IRP, ("Called.\n"));
/* Get associated connection endpoint file object. Quit if none exists */
+ TcpipRecursiveMutexEnter( &TCPLock, TRUE );
+
TranContext = IrpSp->FileObject->FsContext;
if (TranContext == NULL)
{
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. */
Irp );
}
- KeReleaseSpinLockFromDpcLevel(&Connection->AddressFile->Lock);
- KeReleaseSpinLock(&Connection->Lock, OldIrql);
-
done:
+ TcpipRecursiveMutexLeave( &TCPLock );
+
if (Status != STATUS_PENDING) {
DispDataRequestComplete(Irp, Status, 0);
} else
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;
}
(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;
}
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;
}
}
(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;
}
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;
}
IrpSp = IoGetCurrentIrpStackLocation(Irp);
ReceiveInfo = (PTDI_REQUEST_KERNEL_RECEIVE)&(IrpSp->Parameters);
+ TcpipRecursiveMutexEnter( &TCPLock, TRUE );
+
TranContext = IrpSp->FileObject->FsContext;
if (TranContext == NULL)
{
}
done:
+ TcpipRecursiveMutexLeave( &TCPLock );
+
if (Status != STATUS_PENDING) {
DispDataRequestComplete(Irp, Status, BytesReceived);
} else
IrpSp = IoGetCurrentIrpStackLocation(Irp);
DgramInfo = (PTDI_REQUEST_KERNEL_RECEIVEDG)&(IrpSp->Parameters);
+ TcpipRecursiveMutexEnter( &TCPLock, TRUE );
+
TranContext = IrpSp->FileObject->FsContext;
if (TranContext == NULL)
{
}
done:
+ TcpipRecursiveMutexLeave( &TCPLock );
+
if (Status != STATUS_PENDING) {
DispDataRequestComplete(Irp, Status, BytesReceived);
} else
IrpSp = IoGetCurrentIrpStackLocation(Irp);
SendInfo = (PTDI_REQUEST_KERNEL_SEND)&(IrpSp->Parameters);
+ TcpipRecursiveMutexEnter( &TCPLock, TRUE );
+
TranContext = IrpSp->FileObject->FsContext;
if (TranContext == NULL)
{
}
done:
+ TcpipRecursiveMutexLeave( &TCPLock );
+
if (Status != STATUS_PENDING) {
DispDataRequestComplete(Irp, Status, BytesSent);
} else
IrpSp = IoGetCurrentIrpStackLocation(Irp);
DgramInfo = (PTDI_REQUEST_KERNEL_SENDDG)&(IrpSp->Parameters);
+ TcpipRecursiveMutexEnter( &TCPLock, TRUE );
+
TranContext = IrpSp->FileObject->FsContext;
if (TranContext == NULL)
{
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
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.
Status = STATUS_INVALID_PARAMETER;
}
- KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
+ TcpipReleaseSpinLock(&AddrFile->Lock, OldIrql);
return Status;
}
*/
{
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,
QueryContext->Irp->IoStatus.Information = ByteCount;
QueryContext->Irp->IoStatus.Status = Status;
- ExFreePoolWithTag(QueryContext, QUERY_CONTEXT_TAG);
+ exFreePool(QueryContext);
}
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,
IoFreeMdl(OutputMdl);
}
- ExFreePoolWithTag(QueryContext, QUERY_CONTEXT_TAG);
+ exFreePool(QueryContext);
} else
Status = STATUS_INSUFFICIENT_RESOURCES;
} else if( InputBufferLength ==
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 {
if( !NT_SUCCESS(Status) || !InputMdl ) {
if( InputMdl ) IoFreeMdl( InputMdl );
- ExFreePoolWithTag(QueryContext, QUERY_CONTEXT_TAG);
+ exFreePool(QueryContext);
return Status;
}
* Object = Pointer to address file object to free
*/
{
- ExFreePoolWithTag(Object, ADDR_FILE_TAG);
+ exFreePool(Object);
}
* Object = Pointer to address file object to free
*/
{
- ExFreePoolWithTag(Object, CONTROL_CHANNEL_TAG);
+ exFreePool(Object);
}
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;
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;
}
AddrFile->Port != Address->Address[0].Address[0].sin_port) ||
AddrFile->Port == 0xffff)
{
- ExFreePoolWithTag(AddrFile, ADDR_FILE_TAG);
+ exFreePool(AddrFile);
return STATUS_INVALID_PARAMETER;
}
AddrFile->Port != Address->Address[0].Address[0].sin_port) ||
AddrFile->Port == 0xffff)
{
- ExFreePoolWithTag(AddrFile, ADDR_FILE_TAG);
+ exFreePool(AddrFile);
return STATUS_INVALID_PARAMETER;
}
/* 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;
KIRQL OldIrql;
PDATAGRAM_RECEIVE_REQUEST ReceiveRequest;
PDATAGRAM_SEND_REQUEST SendRequest;
- PLIST_ENTRY CurrentEntry;
+ PLIST_ENTRY CurrentEntry, NextEntry;
AddrFile = Request->Handle.AddressHandle;
RemoveEntryList(&AddrFile->ListEntry);
TcpipReleaseSpinLock(&AddressFileListLock, OldIrql);
+ TcpipAcquireSpinLock(&AddrFile->Lock, &OldIrql);
+
/* FIXME: Kill TCP connections on this address file object */
/* Return pending requests with error */
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:
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 );
/* 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:
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"));
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"));
PCONTROL_CHANNEL ControlChannel = Request->Handle.ControlChannel;
NTSTATUS Status = STATUS_SUCCESS;
- ExFreePoolWithTag(ControlChannel, CONTROL_CHANNEL_TAG);
+ exFreePool(ControlChannel);
Request->Handle.ControlChannel = NULL;
return Status;
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 */
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));
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
{
--- /dev/null
+/*
+ * 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;
+}
+
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 );
+}
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) &&
(&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 */
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 */
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
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;
}
if (DeviceObject != TCPDeviceObject) {
TI_DbgPrint(MIN_TRACE, ("Bad device object.\n"));
- ExFreePoolWithTag(Context, TRANS_CONTEXT_TAG);
+ exFreePool(Context);
return STATUS_INVALID_PARAMETER;
}
}
if (!NT_SUCCESS(Status))
- ExFreePoolWithTag(Context, TRANS_CONTEXT_TAG);
+ exFreePool(Context);
TI_DbgPrint(DEBUG_IRP, ("Leaving. Status = (0x%X).\n", Status));
{
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);
/* 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:
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",
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));
}
TcpipReleaseSpinLock(&AddressFileListLock, OldIrql);
#endif
+ ChewShutdown();
+
/* Cancel timer */
KeCancelTimer(&IPTimer);
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"));
}
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;
}
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;
}
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;
}
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;
}
/* 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;
}
/* 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 */
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;
}
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,
VOID TcpipReleaseFastMutex( PFAST_MUTEX Mutex ) {
}
+VOID TcpipRecursiveMutexInit( PRECURSIVE_MUTEX RecMutex ) {
+}
+
+UINT TcpipRecursiveMutexEnter( PRECURSIVE_MUTEX RecMutex, BOOL ToWrite ) {
+ return 0;
+}
+
+VOID TcpipRecursiveMutexLeave( PRECURSIVE_MUTEX RecMutex ) {
+}
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;
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;
}
Status = InfoCopyOut( (PCHAR)RouteEntries, Size, Buffer, BufferSize );
- ExFreePool( RouteEntries );
- ExFreePool( RCache );
+ exFreePool( RouteEntries );
+ exFreePool( RCache );
TI_DbgPrint(DEBUG_INFO, ("Returning %08x\n", Status));
return TDI_INVALID_PARAMETER;
}
- IPEntry = ExAllocatePool(NonPagedPool, sizeof(IPADDR_ENTRY));
+ IPEntry = exAllocatePool(NonPagedPool, sizeof(IPADDR_ENTRY));
if (!IPEntry)
{
TcpipReleaseSpinLock(&EntityListLock, OldIrql);
InfoCopyOut((PCHAR)IPEntry, sizeof(IPADDR_ENTRY),
Buffer, BufferSize);
- ExFreePool(IPEntry);
+ exFreePool(IPEntry);
return TDI_SUCCESS;
}
<file>interface.c</file>
<file>ip.c</file>
<file>loopback.c</file>
+ <file>memtrack.c</file>
<file>neighbor.c</file>
<file>ports.c</file>
<file>receive.c</file>
* Nothing
*/
{
- ExFreePoolWithTag(Object, IP_ADDRESS_TAG);
+ exFreePool(Object);
}
* Object = Pointer to an interface structure
*/
{
- ExFreePoolWithTag(Object, IP_INTERFACE_TAG);
+ exFreePool(Object);
}
PIP_PACKET IPInitializePacket(
/* FIXME: Is this needed? */
RtlZeroMemory(IPPacket, sizeof(IP_PACKET));
+ INIT_TAG(IPPacket, 'TKPI');
+
IPPacket->Free = DontFreePacket;
IPPacket->Type = Type;
/* Clean possible outdated cached neighbor addresses */
NBTimeout();
+
+ /* Call upper layer timeout routines */
+ TCPTimeout();
}
}
#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;
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;
}
RemoveTDIInterfaceEntity( IF );
#endif
- ExFreePoolWithTag(IF->TCPContext, OSKITTCP_CONTEXT_TAG);
- ExFreePoolWithTag(IF, IP_INTERFACE_TAG);
+ exFreePool(IF->TCPContext);
+ exFreePool(IF);
}
VOID IPAddInterfaceRoute( PIP_INTERFACE IF ) {
NULL, /* Free routine */
0, /* Flags */
sizeof(IPDATAGRAM_REASSEMBLY), /* Size of each entry */
- DATAGRAM_REASSEMBLY_TAG, /* Tag */
+ 'RDPI', /* Tag */
0); /* Depth */
ExInitializeNPagedLookasideList(
NULL, /* Free routine */
0, /* Flags */
sizeof(IP_FRAGMENT), /* Size of each entry */
- DATAGRAM_FRAGMENT_TAG, /* Tag */
+ 'GFPI', /* Tag */
0); /* Depth */
ExInitializeNPagedLookasideList(
NULL, /* Free routine */
0, /* Flags */
sizeof(IPDATAGRAM_HOLE), /* Size of each entry */
- DATAGRAM_HOLE_TAG, /* Tag */
+ 'LHPI', /* Tag */
0); /* Depth */
/* Start routing subsystem */
--- /dev/null
+#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 */
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"));
}
Packet->Packet,
ErrorCode );
- ExFreePoolWithTag( Packet, NEIGHBOR_PACKET_TAG );
+ exFreePool( Packet );
}
}
*PrevNCE = NCE->Next;
NBFlushPacketQueue(NCE, NDIS_STATUS_REQUEST_ABORTED);
- ExFreePoolWithTag(NCE, NCE_TAG);
+ exFreePool(NCE);
continue;
}
/* Flush wait queue */
NBFlushPacketQueue( CurNCE, NDIS_STATUS_NOT_ACCEPTED );
- ExFreePoolWithTag(CurNCE, NCE_TAG);
+ exFreePool(CurNCE);
CurNCE = NextNCE;
}
"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;
(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? */
*PrevNCE = CurNCE->Next;
NBFlushPacketQueue( CurNCE, NDIS_STATUS_REQUEST_ABORTED );
- ExFreePoolWithTag(CurNCE, NCE_TAG);
+ exFreePool(CurNCE);
break;
}
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,
}
VOID PortsShutdown( PPORT_SET PortSet ) {
- ExFreePoolWithTag( PortSet->ProtoBitBuffer, PORT_SET_TAG );
+ exFreePool( PortSet->ProtoBitBuffer );
}
VOID DeallocatePort( PPORT_SET PortSet, ULONG Port ) {
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;
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;
}
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);
}
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);
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;
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);
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;
}
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;
}
InsertTailList(&IPDR->HoleListHead, &NewHole->ListEntry);
}
- ExFreeToNPagedLookasideList(&IPHoleList, Hole);
+ exFreeToNPagedLookasideList(&IPHoleList, Hole);
/* If this is the first fragment, save the IP header */
if (FragFirst == 0) {
/* 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);
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;
}
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
* Object = Pointer to an forward information base structure
*/
{
- ExFreePoolWithTag(Object, FIB_TAG);
+ exFreePool(Object);
}
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,
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;
{
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"));
/* 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);
}
}
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;
( &IFC->NdisPacket, NULL, BufferSize );
if( !NT_SUCCESS(NdisStatus) ) {
- ExFreePoolWithTag( IFC, IFC_TAG );
+ exFreePool( IFC );
return NdisStatus;
}
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;
#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));
if (ReceiveRequest->Irp == Irp)
{
RemoveEntryList(&ReceiveRequest->ListEntry);
- ExFreePoolWithTag(ReceiveRequest, DATAGRAM_RECV_TAG);
- Found = TRUE;
+ exFreePool(ReceiveRequest);
break;
}
}
KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
TI_DbgPrint(MAX_TRACE, ("Done.\n"));
-
- return Found;
}
VOID DGDeliverData(
TI_DbgPrint(MAX_TRACE, ("Called.\n"));
- KeAcquireSpinLock(&AddrFile->Lock, &OldIrql);
+ TcpipAcquireSpinLock(&AddrFile->Lock, &OldIrql);
if (AddrFile->Protocol == IPPROTO_UDP)
{
&SrcAddress->Address.IPv4Address,
sizeof(SrcAddress->Address.IPv4Address) );
- KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
+ TcpipReleaseSpinLock(&AddrFile->Lock, OldIrql);
/* Complete the receive request */
if (Current->BufferSize < DataSize)
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)
{
ReceiveHandler = AddrFile->ReceiveDatagramHandler;
HandlerContext = AddrFile->ReceiveDatagramHandlerContext;
+ TcpipReleaseSpinLock(&AddrFile->Lock, OldIrql);
+
if (SrcAddress->Type == IP_ADDRESS_V4)
{
AddressLength = sizeof(IPv4_RAW_ADDRESS);
SourceAddress = SrcAddress->Address.IPv6Address;
}
- KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
-
Status = (*ReceiveHandler)(HandlerContext,
AddressLength,
SourceAddress,
}
else
{
- KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
+ TcpipReleaseSpinLock(&AddrFile->Lock, OldIrql);
TI_DbgPrint(MAX_TRACE, ("Discarding datagram.\n"));
}
(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"));
}
* 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);
}
- }
- else
- {
- ReceiveRequest->RemotePort = 0;
- AddrInitIPv4(&ReceiveRequest->RemoteAddress, 0);
- }
- IoMarkIrpPending(Irp);
+ IoMarkIrpPending(Irp);
- ReceiveRequest->ReturnInfo = ReturnInfo;
- ReceiveRequest->Buffer = BufferData;
- ReceiveRequest->BufferSize = ReceiveLength;
- ReceiveRequest->UserComplete = Complete;
- ReceiveRequest->UserContext = Context;
- ReceiveRequest->Complete =
+ 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;
+ ReceiveRequest->Context = ReceiveRequest;
+ ReceiveRequest->AddressFile = AddrFile;
+ ReceiveRequest->Irp = Irp;
- /* Queue receive request */
- InsertTailList(&AddrFile->ReceiveQueue, &ReceiveRequest->ListEntry);
+ /* Queue receive request */
+ InsertTailList(&AddrFile->ReceiveQueue, &ReceiveRequest->ListEntry);
+ AF_SET_PENDING(AddrFile, AFF_RECEIVE);
- TI_DbgPrint(MAX_TRACE, ("Leaving (pending %08x).\n", ReceiveRequest));
+ TcpipReleaseSpinLock(&AddrFile->Lock, OldIrql);
- KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
+ TI_DbgPrint(MAX_TRACE, ("Leaving (pending %08x).\n", ReceiveRequest));
- return STATUS_PENDING;
+ return STATUS_PENDING;
+ }
+ else
+ {
+ Status = STATUS_INSUFFICIENT_RESOURCES;
+ }
}
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;
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));
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))
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;
}
#include "precomp.h"
-/* Listener->Lock MUST be acquired */
NTSTATUS TCPServiceListeningSocket( PCONNECTION_ENDPOINT Listener,
PCONNECTION_ENDPOINT Connection,
PTDI_REQUEST_KERNEL Request ) {
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
Status = TCPTranslateError
( OskitTCPAccept( Listener->SocketContext,
&Connection->SocketContext,
- Connection,
&OutAddr,
sizeof(OutAddr),
&OutAddrLen,
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",
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);
if( Bucket->AssociatedEndpoint == Connection ) {
RemoveEntryList( &Bucket->Entry );
- ExFreePoolWithTag( Bucket, TDI_BUCKET_TAG );
- Found = TRUE;
+ exFreePool( Bucket );
break;
}
}
KeReleaseSpinLock(&Listener->Lock, OldIrql);
-
- return Found;
}
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;
}
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));
- Connection->SignalState |= 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));
+ }
- HandleSignalledConnection(Connection);
+ TI_DbgPrint(MID_TRACE,("Connection signalled: %d\n",
+ Connection->Signalled));
- if (ClientInfo.Unlocked)
- KeReleaseSpinLockFromDpcLevel(&Connection->Lock);
+ Connection->SignalState |= NewState;
+ if( !Connection->Signalled ) {
+ Connection->Signalled = TRUE;
+ ExInterlockedInsertTailList( &SignalledConnectionsList, &Connection->SignalList, &SignalledConnectionsLock );
+ }
return 0;
}
IP_ADDRESS RemoteAddress, LocalAddress;
PIPv4_HEADER Header;
+ ASSERT_LOCKED(&TCPLock);
+
if( *data == 0x45 ) { /* IPv4 */
Header = (PIPv4_HEADER)data;
LocalAddress.Type = IP_ADDRESS_V4;
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,
#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;
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;
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;
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;
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 ) {
} else if ( SIGNATURE_LARGE == Signature ) {
ExFreeToNPagedLookasideList( &LargeLookasideList, data );
} else if ( SIGNATURE_OTHER == Signature ) {
- ExFreePoolWithTag( data, OSK_OTHER_TAG );
+ ExFreePool( data );
} else {
ASSERT( FALSE );
}
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];
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 ) {
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;
-
- Complete(Bucket->Request.RequestContext, Bucket->Status, Bucket->Information);
-
- ExFreePoolWithTag(Bucket, TDI_BUCKET_TAG);
- }
-
- if (!Connection->SocketContext)
- TCPFreeConnectionEndpoint(Connection);
-}
-
-VOID HandleSignalledConnection(PCONNECTION_ENDPOINT Connection)
-{
- PTDI_BUCKET Bucket;
- PLIST_ENTRY Entry;
- NTSTATUS Status;
- PIRP Irp;
- PMDL Mdl;
- ULONG SocketError = 0;
-
- TI_DbgPrint(MID_TRACE,("Handling signalled state on %x (%x)\n",
- Connection, Connection->SocketContext));
-
- 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;
+ ASSERT_LOCKED(&TCPLock);
- InsertTailList(&Connection->CompletionQueue, &Bucket->Entry);
- }
+ TI_DbgPrint(MID_TRACE,("Handling signalled state on %x (%x)\n",
+ Connection, Connection->SocketContext));
- while (!IsListEmpty(&Connection->ListenRequest))
- {
- Entry = RemoveHeadList( &Connection->ListenRequest );
+ if( Connection->SignalState & SEL_FIN ) {
+ TI_DbgPrint(DEBUG_TCP, ("EOF From socket\n"));
- Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry );
+ while ((Entry = ExInterlockedRemoveHeadList( &Connection->ReceiveRequest,
+ &Connection->Lock )) != NULL)
+ {
+ Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry );
+ Complete = Bucket->Request.RequestNotifyObject;
- Bucket->Status = SocketError;
- Bucket->Information = 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 );
- InsertTailList(&Connection->CompletionQueue, &Bucket->Entry);
- }
+ Complete( Bucket->Request.RequestContext, STATUS_CANCELLED, 0 );
- while (!IsListEmpty(&Connection->ConnectRequest))
- {
- Entry = RemoveHeadList( &Connection->ConnectRequest );
+ exFreePool(Bucket);
+ }
- Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry );
+ while ((Entry = ExInterlockedRemoveHeadList( &Connection->SendRequest,
+ &Connection->Lock )) != NULL)
+ {
+ Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry );
+ Complete = Bucket->Request.RequestNotifyObject;
- Bucket->Status = SocketError;
- Bucket->Information = 0;
+ /* We have to notify oskittcp of the abortion */
+ TCPDisconnect
+ ( Connection,
+ TDI_DISCONNECT_RELEASE,
+ NULL,
+ NULL,
+ Bucket->Request.RequestNotifyObject,
+ (PIRP)Bucket->Request.RequestContext );
- InsertTailList(&Connection->CompletionQueue, &Bucket->Entry);
- }
+ Complete( Bucket->Request.RequestContext, STATUS_CANCELLED, 0 );
- 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 );
-
- Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry );
-
- Bucket->Status = STATUS_SUCCESS;
- Bucket->Information = 0;
-
- InsertTailList(&Connection->CompletionQueue, &Bucket->Entry);
- }
- }
+ while ((Entry = ExInterlockedRemoveHeadList( &Connection->ListenRequest,
+ &Connection->Lock )) != NULL)
+ {
+ Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry );
+ Complete = Bucket->Request.RequestNotifyObject;
- 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"));
+ /* We have to notify oskittcp of the abortion */
+ TCPAbortListenForSocket(Connection->AddressFile->Listener,
+ Connection);
- while (!IsListEmpty(&Connection->ListenRequest)) {
- PIO_STACK_LOCATION IrpSp;
+ Complete( Bucket->Request.RequestContext, STATUS_CANCELLED, 0 );
+ }
- Entry = RemoveHeadList( &Connection->ListenRequest );
+ while ((Entry = ExInterlockedRemoveHeadList( &Connection->ConnectRequest,
+ &Connection->Lock )) != NULL)
+ {
+ Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry );
+ Complete = Bucket->Request.RequestNotifyObject;
- Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry );
+ Complete( Bucket->Request.RequestContext, STATUS_CANCELLED, 0 );
+ }
- Irp = Bucket->Request.RequestContext;
- IrpSp = IoGetCurrentIrpStackLocation( Irp );
+ Connection->SignalState = 0;
+ }
- TI_DbgPrint(DEBUG_TCP,("Getting the socket\n"));
+ /* 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"));
- Status = TCPServiceListeningSocket
- ( Connection->AddressFile->Listener,
- Bucket->AssociatedEndpoint,
- (PTDI_REQUEST_KERNEL)&IrpSp->Parameters );
+ Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry );
+ Complete = Bucket->Request.RequestNotifyObject;
+ TI_DbgPrint(DEBUG_TCP,
+ ("Completing Request %x\n", Bucket->Request.RequestContext));
- TI_DbgPrint(DEBUG_TCP,("Socket: Status: %x\n"));
+ Complete( Bucket->Request.RequestContext, STATUS_SUCCESS, 0 );
- if( Status == STATUS_PENDING ) {
- InsertHeadList( &Connection->ListenRequest, &Bucket->Entry );
- break;
- } else {
- Bucket->Status = Status;
- Bucket->Information = 0;
+ /* Frees the bucket allocated in TCPConnect */
+ exFreePool( Bucket );
+ }
+ }
- InsertTailList(&Connection->CompletionQueue, &Bucket->Entry);
- }
- }
- }
+ if( Connection->SignalState & SEL_ACCEPT ) {
+ /* Handle readable on a listening socket --
+ * TODO: Implement filtering
+ */
- /* 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"));
+ TI_DbgPrint(DEBUG_TCP,("Accepting new connection on %x (Queue: %s)\n",
+ Connection,
+ IsListEmpty(&Connection->ListenRequest) ?
+ "empty" : "nonempty"));
- while (!IsListEmpty(&Connection->ReceiveRequest)) {
- OSK_UINT RecvLen = 0, Received = 0;
- PVOID RecvBuffer = 0;
+ while( (Entry = ExInterlockedRemoveHeadList( &Connection->ListenRequest,
+ &Connection->Lock )) != NULL ) {
+ PIO_STACK_LOCATION IrpSp;
- Entry = RemoveHeadList( &Connection->ReceiveRequest );
+ Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry );
+ Complete = Bucket->Request.RequestNotifyObject;
- Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry );
+ Irp = Bucket->Request.RequestContext;
+ IrpSp = IoGetCurrentIrpStackLocation( Irp );
- Irp = Bucket->Request.RequestContext;
- Mdl = Irp->MdlAddress;
+ TI_DbgPrint(DEBUG_TCP,("Getting the socket\n"));
+ Status = TCPServiceListeningSocket
+ ( Connection->AddressFile->Listener,
+ Bucket->AssociatedEndpoint,
+ (PTDI_REQUEST_KERNEL)&IrpSp->Parameters );
- TI_DbgPrint(DEBUG_TCP,
- ("Getting the user buffer from %x\n", Mdl));
+ TI_DbgPrint(DEBUG_TCP,("Socket: Status: %x\n"));
- NdisQueryBuffer( Mdl, &RecvBuffer, &RecvLen );
+ 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,
- ("Reading %d bytes to %x\n", RecvLen, 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"));
- 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));
+ while( (Entry = ExInterlockedRemoveHeadList( &Connection->ReceiveRequest,
+ &Connection->Lock )) != NULL ) {
+ OSK_UINT RecvLen = 0, Received = 0;
+ PVOID RecvBuffer = 0;
- Status = TCPTranslateError
- ( OskitTCPRecv( Connection->SocketContext,
- RecvBuffer,
- RecvLen,
- &Received,
- 0 ) );
+ Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry );
+ Complete = Bucket->Request.RequestNotifyObject;
- TI_DbgPrint(DEBUG_TCP,("TCP Bytes: %d\n", Received));
+ Irp = Bucket->Request.RequestContext;
+ Mdl = Irp->MdlAddress;
- if( Status == STATUS_PENDING ) {
- InsertHeadList( &Connection->ReceiveRequest, &Bucket->Entry );
- break;
- } else {
- TI_DbgPrint(DEBUG_TCP,
- ("Completing Receive request: %x %x\n",
- Bucket->Request, Status));
+ TI_DbgPrint(DEBUG_TCP,
+ ("Getting the user buffer from %x\n", Mdl));
- Bucket->Status = Status;
- Bucket->Information = (Status == STATUS_SUCCESS) ? Received : 0;
+ NdisQueryBuffer( Mdl, &RecvBuffer, &RecvLen );
- InsertTailList(&Connection->CompletionQueue, &Bucket->Entry);
- }
- }
- }
- if( Connection->SignalState & SEL_WRITE ) {
- TI_DbgPrint(DEBUG_TCP,("Writeable: irp list %s\n",
- IsListEmpty(&Connection->SendRequest) ?
- "empty" : "nonempty"));
+ TI_DbgPrint(DEBUG_TCP,
+ ("Reading %d bytes to %x\n", RecvLen, RecvBuffer));
- while (!IsListEmpty(&Connection->SendRequest)) {
- OSK_UINT SendLen = 0, Sent = 0;
- PVOID SendBuffer = 0;
+ 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));
+
+ Status = TCPTranslateError
+ ( OskitTCPRecv( Connection->SocketContext,
+ RecvBuffer,
+ RecvLen,
+ &Received,
+ 0 ) );
+
+ TI_DbgPrint(DEBUG_TCP,("TCP Bytes: %d\n", Received));
+
+ if( Status == STATUS_SUCCESS ) {
+ TI_DbgPrint(DEBUG_TCP,("Received %d bytes with status %x\n",
+ Received, Status));
+
+ 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"));
- Entry = RemoveHeadList( &Connection->SendRequest );
+ while( (Entry = ExInterlockedRemoveHeadList( &Connection->SendRequest,
+ &Connection->Lock )) != NULL ) {
+ OSK_UINT SendLen = 0, Sent = 0;
+ PVOID SendBuffer = 0;
- 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;
+ Mdl = Irp->MdlAddress;
- TI_DbgPrint(DEBUG_TCP,
- ("Getting the user buffer from %x\n", Mdl));
+ TI_DbgPrint(DEBUG_TCP,
+ ("Getting the user buffer from %x\n", Mdl));
- NdisQueryBuffer( Mdl, &SendBuffer, &SendLen );
+ NdisQueryBuffer( Mdl, &SendBuffer, &SendLen );
- TI_DbgPrint(DEBUG_TCP,
- ("Writing %d bytes to %x\n", SendLen, SendBuffer));
+ TI_DbgPrint(DEBUG_TCP,
+ ("Writing %d bytes to %x\n", SendLen, SendBuffer));
- TI_DbgPrint(DEBUG_TCP, ("Connection: %x\n", Connection));
- TI_DbgPrint
+ 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 ) );
-
- 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));
-
- Bucket->Status = Status;
- Bucket->Information = (Status == STATUS_SUCCESS) ? Sent : 0;
-
- InsertTailList(&Connection->CompletionQueue, &Bucket->Entry);
- }
- }
- }
+ Status = TCPTranslateError
+ ( OskitTCPSend( Connection->SocketContext,
+ SendBuffer,
+ SendLen,
+ &Sent,
+ 0 ) );
+
+ TI_DbgPrint(DEBUG_TCP,("TCP Bytes: %d\n", Sent));
+
+ if( Status == STATUS_SUCCESS ) {
+ TI_DbgPrint(DEBUG_TCP,("Sent %d bytes with status %x\n",
+ Sent, Status));
+
+ 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 );
+ }
+ }
+ }
+
+ Connection->SignalState = 0;
+ Connection->Signalled = FALSE;
}
-static
-VOID DrainSignals(VOID) {
+VOID DrainSignals() {
PCONNECTION_ENDPOINT Connection;
- PLIST_ENTRY CurrentEntry;
- KIRQL OldIrql;
-
- KeAcquireSpinLock(&ConnectionEndpointListLock, &OldIrql);
- CurrentEntry = ConnectionEndpointListHead.Flink;
- while (CurrentEntry != &ConnectionEndpointListHead)
- {
- Connection = CONTAINING_RECORD( CurrentEntry, CONNECTION_ENDPOINT,
- ListEntry );
- CurrentEntry = CurrentEntry->Flink;
- KeReleaseSpinLock(&ConnectionEndpointListLock, OldIrql);
+ PLIST_ENTRY ListEntry;
- 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;
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",
TI_DbgPrint(DEBUG_TCP,("Connection->SocketContext %x\n",
Connection->SocketContext));
- KeReleaseSpinLock(&Connection->Lock, OldIrql);
-
return Status;
}
* 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 */
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 */
TCPFindInterface, /* FindInterface */
TCPMalloc, /* Malloc */
TCPFree, /* Free */
- NULL, /* Sleep */
- NULL, /* Wakeup */
+ TCPSleep, /* Sleep */
+ TCPWakeup /* Wakeup */
};
static KEVENT TimerLoopEvent;
while ( 1 ) {
if (Next == NextFast) {
NextFast += 2;
- }
+ }
if (Next == NextSlow) {
NextSlow += 5;
}
PsTerminateSystemThread(Status);
}
+ TcpipRecursiveMutexEnter( &TCPLock, TRUE );
TimerOskitTCP( Next == NextFast, Next == NextSlow );
- DrainSignals();
+ if (Next == NextSlow) {
+ DrainSignals();
+ }
+ TcpipRecursiveMutexLeave( &TCPLock );
Current = Next;
if (10 <= Current) {
TimerThread, NULL);
}
+
NTSTATUS TCPStartup(VOID)
/*
* FUNCTION: Initializes the TCP subsystem
{
NTSTATUS Status;
+ TcpipRecursiveMutexInit( &TCPLock );
+ ExInitializeFastMutex( &SleepingThreadsLock );
+ KeInitializeSpinLock( &SignalledConnectionsLock );
+ InitializeListHead( &SleepingThreadsList );
+ InitializeListHead( &SignalledConnectionsList );
Status = TCPMemStartup();
if ( ! NT_SUCCESS(Status) ) {
return Status;
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);
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;
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,
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",
AddressToBind = AddressToConnect;
AddressToBind.sin_addr.s_addr = NCE->Interface->Unicast.Address.IPv4Address;
- KeAcquireSpinLock(&Connection->Lock, &OldIrql);
-
Status = TCPTranslateError
( OskitTCPBind( Connection->SocketContext,
&AddressToBind,
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;
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));
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));
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));
- NdisQueryBuffer( Buffer, &DataBuffer, &DataLen );
+ ASSERT_LOCKED(&TCPLock);
- TI_DbgPrint(DEBUG_TCP,("TCP>|< Got an MDL %x (%x:%d)\n", Buffer, DataBuffer, DataLen));
+ ASSERT_KM_POINTER(Connection->SocketContext);
- KeAcquireSpinLock(&Connection->Lock, &OldIrql);
+ /* Closing */
+ if (Connection->State & SEL_FIN)
+ {
+ *BytesReceived = 0;
+ return STATUS_REMOTE_DISCONNECT;
+ }
- ASSERT_KM_POINTER(Connection->SocketContext);
+ NdisQueryBuffer( Buffer, &DataBuffer, &DataLen );
+
+ TI_DbgPrint(DEBUG_TCP,("TCP>|< Got an MDL %x (%x:%d)\n", Buffer, DataBuffer, DataLen));
Status = TCPTranslateError
( OskitTCPRecv
&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;
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));
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));
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;
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));
return Status;
}
+VOID TCPTimeout(VOID) {
+ /* Now handled by TimerThread */
+}
+
UINT TCPAllocatePort( UINT HintPort ) {
if( HintPort ) {
if( AllocatePort( &TCPPorts, HintPort ) ) return HintPort;
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;
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;
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 */
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));
break;
default:
- KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
return STATUS_UNSUCCESSFUL;
}
if(!(NCE = RouteGetRouteToDestination( &RemoteAddress ))) {
- KeReleaseSpinLock(&AddrFile->Lock, OldIrql);
return STATUS_NETWORK_UNREACHABLE;
}
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;
}
--- /dev/null
+#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*/
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 );
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 );
int OskitTCPDisconnect(void *socket);
-int OskitTCPGetSocketError(void *socket);
-
#undef errno
void *fbsd_malloc( unsigned int bytes, 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*/
//OSK_UINT OskitDebugTraceLevel = OSK_DEBUG_ULTRA;
OSK_UINT OskitDebugTraceLevel = 0;
-KSPIN_LOCK OSKLock;
-
/* SPL */
unsigned cpl;
unsigned net_imask;
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"));
}
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 ) {
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;
}
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;
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;
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;
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)) {
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,
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;
int OskitTCPAccept( void *socket,
void **new_socket,
- void *context,
void *AddrOut,
OSK_UINT AddrLen,
OSK_UINT *OutAddrLen,
/* 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;
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.
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) {
*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);
}
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;
IpHeaderLen));
tcp_input(Ip, IpHeaderLen);
- OSKUnlock();
/* The buffer Ip is freed by tcp_input */
}
int size)
{
struct mbuf *m;
- int error;
if (!socket)
return OSK_ESHUTDOWN;
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,
if (!socket)
return OSK_ESHUTDOWN;
- OSKLock();
error = sogetopt(socket, level, optname, &m);
if (!error)
{
if (!buffer || oldsize < m->m_len)
{
m_freem(m);
- OSKUnlock();
return OSK_EINVAL;
}
m_freem(m);
}
- OSKUnlock();
return error;
}
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;
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;
}
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 )
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 */