mirror of
https://github.com/reactos/reactos.git
synced 2025-05-25 12:14:32 +00:00
[TCPIP]
- Do not transmit fragments recursively since it can cause a kernel stack overflow with large packets - Big thanks to hto for his work on this bug which has eluded me since last year See issue #5796 for more details. svn path=/trunk/; revision=54169
This commit is contained in:
parent
9e9b67bc8f
commit
fa391315db
2 changed files with 25 additions and 34 deletions
|
@ -25,8 +25,8 @@ typedef struct IPFRAGMENT_CONTEXT {
|
|||
UINT BytesLeft; /* Number of bytes left to send */
|
||||
UINT PathMTU; /* Path Maximum Transmission Unit */
|
||||
PNEIGHBOR_CACHE_ENTRY NCE; /* Pointer to NCE to use */
|
||||
PIP_TRANSMIT_COMPLETE Complete; /* Completion Routine */
|
||||
PVOID Context; /* Completion Context */
|
||||
KEVENT Event; /* Signalled when the transmission is complete */
|
||||
NDIS_STATUS Status; /* Status of the transmission */
|
||||
} IPFRAGMENT_CONTEXT, *PIPFRAGMENT_CONTEXT;
|
||||
|
||||
|
||||
|
|
|
@ -28,30 +28,14 @@ VOID IPSendComplete
|
|||
*/
|
||||
{
|
||||
PIPFRAGMENT_CONTEXT IFC = (PIPFRAGMENT_CONTEXT)Context;
|
||||
NTSTATUS Status;
|
||||
|
||||
TI_DbgPrint
|
||||
(MAX_TRACE,
|
||||
("Called. Context (0x%X) NdisPacket (0x%X) NdisStatus (0x%X)\n",
|
||||
Context, NdisPacket, NdisStatus));
|
||||
|
||||
if (NT_SUCCESS(NdisStatus) && PrepareNextFragment(IFC)) {
|
||||
/* A fragment was prepared for transmission, so send it */
|
||||
Status = IPSendFragment(IFC->NdisPacket, IFC->NCE, IFC);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
FreeNdisPacket(IFC->NdisPacket);
|
||||
IFC->Complete(IFC->Context, IFC->Datagram, Status);
|
||||
ExFreePoolWithTag(IFC, IFC_TAG);
|
||||
}
|
||||
} 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);
|
||||
}
|
||||
|
||||
IFC->Status = NdisStatus;
|
||||
KeSetEvent(&IFC->Event, 0, FALSE);
|
||||
}
|
||||
|
||||
NTSTATUS IPSendFragment(
|
||||
|
@ -202,8 +186,7 @@ NTSTATUS SendFragments(
|
|||
IFC->Position = 0;
|
||||
IFC->BytesLeft = IPPacket->TotalSize - IPPacket->HeaderSize;
|
||||
IFC->Data = (PVOID)((ULONG_PTR)IFC->Header + IPPacket->HeaderSize);
|
||||
IFC->Complete = Complete;
|
||||
IFC->Context = Context;
|
||||
KeInitializeEvent(&IFC->Event, NotificationEvent, FALSE);
|
||||
|
||||
TI_DbgPrint(MID_TRACE,("Copying header from %x to %x (%d)\n",
|
||||
IPPacket->Header, IFC->Header,
|
||||
|
@ -211,20 +194,28 @@ NTSTATUS SendFragments(
|
|||
|
||||
RtlCopyMemory( IFC->Header, IPPacket->Header, IPPacket->HeaderSize );
|
||||
|
||||
/* Prepare next fragment for transmission and send it */
|
||||
|
||||
if (!PrepareNextFragment(IFC)) {
|
||||
FreeNdisPacket(IFC->NdisPacket);
|
||||
ExFreePoolWithTag(IFC, IFC_TAG);
|
||||
return NDIS_STATUS_FAILURE;
|
||||
}
|
||||
|
||||
if (!NT_SUCCESS((NdisStatus = IPSendFragment(IFC->NdisPacket, NCE, IFC))))
|
||||
while (PrepareNextFragment(IFC))
|
||||
{
|
||||
FreeNdisPacket(IFC->NdisPacket);
|
||||
ExFreePoolWithTag(IFC, IFC_TAG);
|
||||
NdisStatus = IPSendFragment(IFC->NdisPacket, NCE, IFC);
|
||||
if (NT_SUCCESS(NdisStatus))
|
||||
{
|
||||
KeWaitForSingleObject(&IFC->Event,
|
||||
Executive,
|
||||
KernelMode,
|
||||
FALSE,
|
||||
NULL);
|
||||
NdisStatus = IFC->Status;
|
||||
}
|
||||
|
||||
if (!NT_SUCCESS(NdisStatus))
|
||||
break;
|
||||
}
|
||||
|
||||
FreeNdisPacket(IFC->NdisPacket);
|
||||
ExFreePoolWithTag(IFC, IFC_TAG);
|
||||
|
||||
Complete(Context, IPPacket->NdisPacket, NdisStatus);
|
||||
|
||||
return NdisStatus;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue