mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 10:04:49 +00:00
Fixed connection locking in tcp.c
Added a work item in lan.c re: dpc callback from the adapter. This keeps us from needing mdl functions at dpc level. Track IRPs to be completed with memtrack. svn path=/trunk/; revision=11051
This commit is contained in:
parent
ee0f0ee26f
commit
3725308f3e
12 changed files with 167 additions and 43 deletions
|
@ -10,11 +10,23 @@
|
|||
|
||||
#include "precomp.h"
|
||||
|
||||
typedef struct _LAN_WQ_ITEM {
|
||||
LIST_ENTRY ListEntry;
|
||||
PNDIS_PACKET Packet;
|
||||
PLAN_ADAPTER Adapter;
|
||||
UINT BytesTransferred;
|
||||
} LAN_WQ_ITEM, *PLAN_WQ_ITEM;
|
||||
|
||||
NDIS_HANDLE NdisProtocolHandle = (NDIS_HANDLE)NULL;
|
||||
BOOLEAN ProtocolRegistered = FALSE;
|
||||
LIST_ENTRY AdapterListHead;
|
||||
KSPIN_LOCK AdapterListLock;
|
||||
|
||||
/* Work around being called back into afd at Dpc level */
|
||||
KSPIN_LOCK LanWorkLock;
|
||||
LIST_ENTRY LanWorkList;
|
||||
WORK_QUEUE_ITEM LanWorkItem;
|
||||
|
||||
NDIS_STATUS NDISCall(
|
||||
PLAN_ADAPTER Adapter,
|
||||
NDIS_REQUEST_TYPE Type,
|
||||
|
@ -178,35 +190,31 @@ VOID STDCALL ProtocolSendComplete(
|
|||
TI_DbgPrint(DEBUG_DATALINK, ("Finished\n"));
|
||||
}
|
||||
|
||||
|
||||
VOID STDCALL ProtocolTransferDataComplete(
|
||||
NDIS_HANDLE BindingContext,
|
||||
PNDIS_PACKET Packet,
|
||||
NDIS_STATUS Status,
|
||||
UINT BytesTransferred)
|
||||
/*
|
||||
* FUNCTION: Called by NDIS to complete reception of data
|
||||
* ARGUMENTS:
|
||||
* BindingContext = Pointer to a device context (LAN_ADAPTER)
|
||||
* Packet = Pointer to a packet descriptor
|
||||
* Status = Status of the operation
|
||||
* BytesTransferred = Number of bytes transferred
|
||||
* NOTES:
|
||||
* If the packet was successfully received, determine the protocol
|
||||
* type and pass it to the correct receive handler
|
||||
*/
|
||||
{
|
||||
VOID STDCALL LanReceiveWorker( PVOID Context ) {
|
||||
UINT PacketType;
|
||||
PLAN_ADAPTER Adapter = (PLAN_ADAPTER)BindingContext;
|
||||
PLIST_ENTRY ListEntry;
|
||||
PLAN_WQ_ITEM WorkItem;
|
||||
PNDIS_PACKET Packet;
|
||||
PLAN_ADAPTER Adapter;
|
||||
UINT BytesTransferred;
|
||||
PNDIS_BUFFER NdisBuffer;
|
||||
IP_PACKET IPPacket;
|
||||
|
||||
|
||||
TI_DbgPrint(DEBUG_DATALINK, ("Called.\n"));
|
||||
|
||||
if (Status == NDIS_STATUS_SUCCESS) {
|
||||
PNDIS_BUFFER NdisBuffer;
|
||||
IP_PACKET IPPacket;
|
||||
while( (ListEntry =
|
||||
ExInterlockedRemoveHeadList( &LanWorkList, &LanWorkLock )) ) {
|
||||
WorkItem = CONTAINING_RECORD(ListEntry, LAN_WQ_ITEM, ListEntry);
|
||||
|
||||
Packet = WorkItem->Packet;
|
||||
Adapter = WorkItem->Adapter;
|
||||
BytesTransferred = WorkItem->BytesTransferred;
|
||||
|
||||
ExFreePool( WorkItem );
|
||||
|
||||
IPPacket.NdisPacket = Packet;
|
||||
|
||||
|
||||
NdisGetFirstBufferFromPacket(Packet,
|
||||
&NdisBuffer,
|
||||
&IPPacket.Header,
|
||||
|
@ -241,11 +249,46 @@ VOID STDCALL ProtocolTransferDataComplete(
|
|||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
FreeNdisPacket( Packet );
|
||||
FreeNdisPacket( Packet );
|
||||
}
|
||||
}
|
||||
|
||||
VOID STDCALL ProtocolTransferDataComplete(
|
||||
NDIS_HANDLE BindingContext,
|
||||
PNDIS_PACKET Packet,
|
||||
NDIS_STATUS Status,
|
||||
UINT BytesTransferred)
|
||||
/*
|
||||
* FUNCTION: Called by NDIS to complete reception of data
|
||||
* ARGUMENTS:
|
||||
* BindingContext = Pointer to a device context (LAN_ADAPTER)
|
||||
* Packet = Pointer to a packet descriptor
|
||||
* Status = Status of the operation
|
||||
* BytesTransferred = Number of bytes transferred
|
||||
* NOTES:
|
||||
* If the packet was successfully received, determine the protocol
|
||||
* type and pass it to the correct receive handler
|
||||
*/
|
||||
{
|
||||
BOOLEAN WorkStart;
|
||||
PLAN_WQ_ITEM WQItem;
|
||||
PLAN_ADAPTER Adapter = (PLAN_ADAPTER)BindingContext;
|
||||
|
||||
if( Status != NDIS_STATUS_SUCCESS ) return;
|
||||
WQItem = ExAllocatePool( NonPagedPool, sizeof(LAN_WQ_ITEM) );
|
||||
if( !WQItem ) return;
|
||||
|
||||
KeAcquireSpinLockAtDpcLevel( &LanWorkLock );
|
||||
WorkStart = IsListEmpty( &LanWorkList );
|
||||
WQItem->Packet = Packet;
|
||||
WQItem->Adapter = Adapter;
|
||||
WQItem->BytesTransferred = BytesTransferred;
|
||||
InsertTailList( &LanWorkList, &WQItem->ListEntry );
|
||||
if( WorkStart )
|
||||
ExQueueWorkItem( &LanWorkItem, CriticalWorkQueue );
|
||||
KeReleaseSpinLockFromDpcLevel( &LanWorkLock );
|
||||
}
|
||||
|
||||
NDIS_STATUS STDCALL ProtocolReceive(
|
||||
NDIS_HANDLE BindingContext,
|
||||
|
@ -313,7 +356,11 @@ NDIS_STATUS STDCALL ProtocolReceive(
|
|||
|
||||
KeAcquireSpinLockAtDpcLevel(&Adapter->Lock);
|
||||
NdisStatus = AllocatePacketWithBuffer( &NdisPacket, NULL, Adapter->MTU );
|
||||
if( NdisStatus != NDIS_STATUS_SUCCESS ) return NDIS_STATUS_NOT_ACCEPTED;
|
||||
if( NdisStatus != NDIS_STATUS_SUCCESS ) {
|
||||
KeReleaseSpinLockFromDpcLevel(&Adapter->Lock);
|
||||
return NDIS_STATUS_NOT_ACCEPTED;
|
||||
}
|
||||
|
||||
TI_DbgPrint(DEBUG_DATALINK, ("pretransfer LookaheadBufferSize %d packsize %d\n",LookaheadBufferSize,PacketSize));
|
||||
{
|
||||
UINT temp;
|
||||
|
@ -350,14 +397,15 @@ NDIS_STATUS STDCALL ProtocolReceive(
|
|||
#endif
|
||||
TI_DbgPrint(DEBUG_DATALINK, ("Calling complete\n"));
|
||||
|
||||
/* Release the packet descriptor */
|
||||
KeReleaseSpinLockFromDpcLevel(&Adapter->Lock);
|
||||
|
||||
if (NdisStatus != NDIS_STATUS_PENDING)
|
||||
ProtocolTransferDataComplete(BindingContext,
|
||||
NdisPacket,
|
||||
NdisStatus,
|
||||
PacketSize + HeaderBufferSize);
|
||||
PacketSize + HeaderBufferSize);
|
||||
|
||||
/* Release the packet descriptor */
|
||||
KeReleaseSpinLockFromDpcLevel(&Adapter->Lock);
|
||||
TI_DbgPrint(DEBUG_DATALINK, ("leaving\n"));
|
||||
|
||||
return NDIS_STATUS_SUCCESS;
|
||||
|
@ -448,6 +496,7 @@ VOID LANTransmit(
|
|||
NDIS_STATUS NdisStatus;
|
||||
PETH_HEADER EHeader;
|
||||
PVOID Data;
|
||||
KIRQL OldIrql;
|
||||
PLAN_ADAPTER Adapter = (PLAN_ADAPTER)Context;
|
||||
|
||||
TI_DbgPrint(DEBUG_DATALINK, ("Called.\n"));
|
||||
|
@ -502,7 +551,10 @@ VOID LANTransmit(
|
|||
break;
|
||||
}
|
||||
|
||||
KeAcquireSpinLock( &Adapter->Lock, &OldIrql );
|
||||
NdisSend(&NdisStatus, Adapter->NdisHandle, NdisPacket);
|
||||
KeReleaseSpinLock( &Adapter->Lock, OldIrql );
|
||||
|
||||
if (NdisStatus != NDIS_STATUS_PENDING)
|
||||
ProtocolSendComplete((NDIS_HANDLE)Context, NdisPacket, NdisStatus);
|
||||
} else {
|
||||
|
@ -1021,4 +1073,24 @@ VOID LANUnregisterProtocol(
|
|||
}
|
||||
}
|
||||
|
||||
VOID LANStartup() {
|
||||
InitializeListHead( &LanWorkList );
|
||||
ExInitializeWorkItem( &LanWorkItem, LanReceiveWorker, NULL );
|
||||
}
|
||||
|
||||
VOID LANShutdown() {
|
||||
KIRQL OldIrql;
|
||||
PLAN_WQ_ITEM WorkItem;
|
||||
PLIST_ENTRY ListEntry;
|
||||
|
||||
KeAcquireSpinLock( &LanWorkLock, &OldIrql );
|
||||
while( !IsListEmpty( &LanWorkList ) ) {
|
||||
ListEntry = RemoveHeadList( &LanWorkList );
|
||||
WorkItem = CONTAINING_RECORD(ListEntry, LAN_WQ_ITEM, ListEntry);
|
||||
FreeNdisPacket( WorkItem->Packet );
|
||||
ExFreePool( WorkItem );
|
||||
}
|
||||
KeReleaseSpinLock( &LanWorkLock, OldIrql );
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
|
|
|
@ -7,6 +7,13 @@
|
|||
#ifndef __IRP_H
|
||||
#define __IRP_H
|
||||
|
||||
VOID IRPRemember( PIRP Irp, PCHAR File, UINT Line );
|
||||
NTSTATUS IRPFinish( PIRP Irp, NTSTATUS Status );
|
||||
|
||||
#ifdef MEMTRACK
|
||||
#define RIRP(x) IRPRemember(x,__FILE__,__LINE__)
|
||||
#else
|
||||
#define RIRP(x)
|
||||
#endif
|
||||
|
||||
#endif/*__IRP_H*/
|
||||
|
|
|
@ -33,6 +33,9 @@ typedef struct ETH_HEADER {
|
|||
/* Offset of broadcast address */
|
||||
#define BCAST_ETH_OFFSET 0x00
|
||||
|
||||
/* Max packets queued for a single adapter */
|
||||
#define IP_MAX_RECV_BACKLOG 0x20
|
||||
|
||||
/* Per adapter information */
|
||||
typedef struct LAN_ADAPTER {
|
||||
LIST_ENTRY ListEntry; /* Entry on list */
|
||||
|
@ -92,6 +95,9 @@ NTSTATUS LANRegisterProtocol(
|
|||
VOID LANUnregisterProtocol(
|
||||
VOID);
|
||||
|
||||
VOID LANStartup();
|
||||
VOID LANShutdown();
|
||||
|
||||
NDIS_STATUS NDISCall(
|
||||
PLAN_ADAPTER Adapter,
|
||||
NDIS_REQUEST_TYPE Type,
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
#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 AllocatePacketWithBuffer(x,y,z) AllocatePacketWithBufferX(x,y,z,__FILE__,__LINE__)
|
||||
#define FreeNdisPacket(x) FreeNdisPacketX(x,__FILE__,__LINE__)
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#include <limits.h>
|
||||
#include <ddk/ntddk.h>
|
||||
#include <rosrtl/string.h>
|
||||
#include <rosrtl/recmutex.h>
|
||||
#include <roscfg.h>
|
||||
#include <tcpip.h>
|
||||
#include <loopback.h>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# $Id: makefile,v 1.20 2004/08/19 21:38:58 arty Exp $
|
||||
# $Id: makefile,v 1.21 2004/09/25 20:23:59 arty Exp $
|
||||
|
||||
PATH_TO_TOP = ../../..
|
||||
|
||||
|
@ -21,7 +21,9 @@ TARGET_CFLAGS = \
|
|||
-I$(PATH_TO_TOP)/w32api/include \
|
||||
-I$(PATH_TO_TOP)/include
|
||||
|
||||
TARGET_DDKLIBS = ndis.a $(PATH_TO_TOP)/dk/w32/lib/oskittcp.a
|
||||
TARGET_DDKLIBS = ndis.a \
|
||||
$(PATH_TO_TOP)/dk/w32/lib/oskittcp.a \
|
||||
$(PATH_TO_TOP)/dk/w32/lib/rosrtl.a
|
||||
|
||||
TARGET_CLEAN = \
|
||||
tcpip/*.o \
|
||||
|
|
|
@ -130,7 +130,6 @@ VOID DispCancelRequest(
|
|||
/* Try canceling the request */
|
||||
switch(MinorFunction) {
|
||||
case TDI_SEND:
|
||||
|
||||
case TDI_RECEIVE:
|
||||
/* FIXME: Close connection */
|
||||
break;
|
||||
|
|
|
@ -11,10 +11,19 @@
|
|||
|
||||
#include "precomp.h"
|
||||
|
||||
VOID IRPRemember( PIRP Irp, PCHAR File, UINT Line ) {
|
||||
#ifdef MEMTRACK
|
||||
TrackWithTag( IRP_TAG, Irp, File, Line );
|
||||
#endif
|
||||
}
|
||||
|
||||
NTSTATUS IRPFinish( PIRP Irp, NTSTATUS Status ) {
|
||||
TI_DbgPrint(MID_TRACE,("Called: Irp %x, Status %x Event %x\n", Irp, Status, Irp->UserEvent));
|
||||
|
||||
#ifdef MEMTRACK
|
||||
UntrackFL( __FILE__, __LINE__, Irp );
|
||||
#endif
|
||||
|
||||
IoSetCancelRoutine( Irp, NULL );
|
||||
|
||||
if( Status == STATUS_PENDING )
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
*/
|
||||
#include "precomp.h"
|
||||
|
||||
#define NDEBUG
|
||||
//#define NDEBUG
|
||||
|
||||
#ifndef NDEBUG
|
||||
DWORD DebugTraceLevel = 0x7fffffff;
|
||||
|
@ -425,6 +425,8 @@ TiDispatchOpenClose(
|
|||
NTSTATUS Status;
|
||||
PTRANSPORT_CONTEXT Context;
|
||||
|
||||
RIRP(Irp);
|
||||
|
||||
TI_DbgPrint(DEBUG_IRP, ("Called. DeviceObject is at (0x%X), IRP is at (0x%X).\n", DeviceObject, Irp));
|
||||
|
||||
IoMarkIrpPending(Irp);
|
||||
|
@ -483,6 +485,8 @@ TiDispatchInternal(
|
|||
BOOL Complete = TRUE;
|
||||
PIO_STACK_LOCATION IrpSp;
|
||||
|
||||
RIRP(Irp);
|
||||
|
||||
IrpSp = IoGetCurrentIrpStackLocation(Irp);
|
||||
|
||||
TI_DbgPrint(DEBUG_IRP, ("Called. DeviceObject is at (0x%X), IRP is at (0x%X) MN (%d).\n",
|
||||
|
@ -584,6 +588,8 @@ TiDispatch(
|
|||
NTSTATUS Status;
|
||||
PIO_STACK_LOCATION IrpSp;
|
||||
|
||||
RIRP(Irp);
|
||||
|
||||
IrpSp = IoGetCurrentIrpStackLocation(Irp);
|
||||
|
||||
TI_DbgPrint(DEBUG_IRP, ("Called. IRP is at (0x%X).\n", Irp));
|
||||
|
@ -658,6 +664,9 @@ VOID STDCALL TiUnload(
|
|||
/* Shutdown network level protocol subsystem */
|
||||
IPShutdown();
|
||||
|
||||
/* Shutdown the lan worker */
|
||||
LANShutdown();
|
||||
|
||||
/* Free NDIS buffer descriptors */
|
||||
if (GlobalBufferPool)
|
||||
NdisFreeBufferPool(GlobalBufferPool);
|
||||
|
@ -807,6 +816,9 @@ DriverEntry(
|
|||
InitializeListHead(&InterfaceListHead);
|
||||
KeInitializeSpinLock(&InterfaceListLock);
|
||||
|
||||
/* Initialize the lan worker */
|
||||
LANStartup();
|
||||
|
||||
/* Initialize network level protocol subsystem */
|
||||
IPStartup(DriverObject, RegistryPath);
|
||||
|
||||
|
|
|
@ -594,13 +594,13 @@ VOID FreeNdisPacketX
|
|||
|
||||
NdisGetNextBuffer(Buffer, &NextBuffer);
|
||||
NdisQueryBuffer(Buffer, &Data, &Length);
|
||||
NdisFreeBuffer(Buffer);
|
||||
UntrackFL(File,Line,Buffer);
|
||||
ExFreePool(Data);
|
||||
NdisFreeBuffer(Buffer);
|
||||
UntrackFL(File,Line,Data);
|
||||
ExFreePool(Data);
|
||||
}
|
||||
|
||||
/* Finally free the NDIS packet discriptor */
|
||||
NdisFreePacket(Packet);
|
||||
UntrackFL(File,Line,Packet);
|
||||
NdisFreePacket(Packet);
|
||||
}
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
extern ULONG TCP_IPIdentification;
|
||||
extern LIST_ENTRY SleepingThreadsList;
|
||||
extern FAST_MUTEX SleepingThreadsLock;
|
||||
extern RECURSIVE_MUTEX TcpMutex;
|
||||
|
||||
int TCPSocketState(void *ClientData,
|
||||
void *WhichSocket,
|
||||
|
|
|
@ -10,12 +10,12 @@
|
|||
|
||||
#include "precomp.h"
|
||||
|
||||
|
||||
LONG TCP_IPIdentification = 0;
|
||||
static BOOLEAN TCPInitialized = FALSE;
|
||||
static NPAGED_LOOKASIDE_LIST TCPSegmentList;
|
||||
LIST_ENTRY SleepingThreadsList;
|
||||
FAST_MUTEX SleepingThreadsLock;
|
||||
RECURSIVE_MUTEX TcpMutex;
|
||||
|
||||
VOID TCPReceive(PNET_TABLE_ENTRY NTE, PIP_PACKET IPPacket)
|
||||
/*
|
||||
|
@ -30,7 +30,7 @@ VOID TCPReceive(PNET_TABLE_ENTRY NTE, PIP_PACKET IPPacket)
|
|||
TI_DbgPrint(MID_TRACE,("Sending packet %d (%d) to oskit\n",
|
||||
IPPacket->TotalSize,
|
||||
IPPacket->HeaderSize));
|
||||
|
||||
|
||||
OskitTCPReceiveDatagram( IPPacket->Header,
|
||||
IPPacket->TotalSize,
|
||||
IPPacket->HeaderSize );
|
||||
|
@ -121,7 +121,7 @@ NTSTATUS TCPShutdown(VOID)
|
|||
TCPInitialized = FALSE;
|
||||
|
||||
DeinitOskitTCP();
|
||||
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -227,13 +227,14 @@ NTSTATUS TCPConnect
|
|||
&RemoteAddress->Address.IPv4Address,
|
||||
sizeof(AddressToConnect.sin_addr) );
|
||||
AddressToConnect.sin_port = RemotePort;
|
||||
KeReleaseSpinLock(&Connection->Lock, OldIrql);
|
||||
|
||||
|
||||
Status = OskitTCPConnect(Connection->SocketContext,
|
||||
Connection,
|
||||
&AddressToConnect,
|
||||
sizeof(AddressToConnect));
|
||||
|
||||
KeReleaseSpinLock(&Connection->Lock, OldIrql);
|
||||
|
||||
if( Status == OSK_EINPROGRESS || Status == STATUS_SUCCESS )
|
||||
return STATUS_PENDING;
|
||||
else
|
||||
|
@ -242,13 +243,18 @@ NTSTATUS TCPConnect
|
|||
|
||||
NTSTATUS TCPClose
|
||||
( PTDI_REQUEST Request ) {
|
||||
KIRQL OldIrql;
|
||||
PCONNECTION_ENDPOINT Connection;
|
||||
NTSTATUS Status;
|
||||
Connection = Request->Handle.ConnectionContext;
|
||||
|
||||
TI_DbgPrint(MID_TRACE,("TCPClose started\n"));
|
||||
|
||||
KeAcquireSpinLock(&Connection->Lock, &OldIrql);
|
||||
|
||||
Status = TCPTranslateError( OskitTCPClose( Connection->SocketContext ) );
|
||||
|
||||
KeReleaseSpinLock(&Connection->Lock, OldIrql);
|
||||
|
||||
TI_DbgPrint(MID_TRACE,("TCPClose finished %x\n", Status));
|
||||
|
||||
|
@ -259,11 +265,19 @@ NTSTATUS TCPListen
|
|||
( PTDI_REQUEST Request,
|
||||
UINT Backlog ) {
|
||||
PCONNECTION_ENDPOINT Connection;
|
||||
NTSTATUS Status;
|
||||
KIRQL OldIrql;
|
||||
|
||||
Connection = Request->Handle.ConnectionContext;
|
||||
|
||||
return TCPTranslateError( OskitTCPListen( Connection->SocketContext,
|
||||
Backlog ) );
|
||||
KeAcquireSpinLock(&Connection->Lock, &OldIrql);
|
||||
|
||||
Status = TCPTranslateError( OskitTCPListen( Connection->SocketContext,
|
||||
Backlog ) );
|
||||
|
||||
KeReleaseSpinLock(&Connection->Lock, OldIrql);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
NTSTATUS TCPAccept
|
||||
|
|
Loading…
Reference in a new issue