mirror of
https://github.com/reactos/reactos.git
synced 2025-05-29 05:58:13 +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 BytesLeft; /* Number of bytes left to send */
|
||||||
UINT PathMTU; /* Path Maximum Transmission Unit */
|
UINT PathMTU; /* Path Maximum Transmission Unit */
|
||||||
PNEIGHBOR_CACHE_ENTRY NCE; /* Pointer to NCE to use */
|
PNEIGHBOR_CACHE_ENTRY NCE; /* Pointer to NCE to use */
|
||||||
PIP_TRANSMIT_COMPLETE Complete; /* Completion Routine */
|
KEVENT Event; /* Signalled when the transmission is complete */
|
||||||
PVOID Context; /* Completion Context */
|
NDIS_STATUS Status; /* Status of the transmission */
|
||||||
} IPFRAGMENT_CONTEXT, *PIPFRAGMENT_CONTEXT;
|
} IPFRAGMENT_CONTEXT, *PIPFRAGMENT_CONTEXT;
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -28,30 +28,14 @@ VOID IPSendComplete
|
||||||
*/
|
*/
|
||||||
{
|
{
|
||||||
PIPFRAGMENT_CONTEXT IFC = (PIPFRAGMENT_CONTEXT)Context;
|
PIPFRAGMENT_CONTEXT IFC = (PIPFRAGMENT_CONTEXT)Context;
|
||||||
NTSTATUS Status;
|
|
||||||
|
|
||||||
TI_DbgPrint
|
TI_DbgPrint
|
||||||
(MAX_TRACE,
|
(MAX_TRACE,
|
||||||
("Called. Context (0x%X) NdisPacket (0x%X) NdisStatus (0x%X)\n",
|
("Called. Context (0x%X) NdisPacket (0x%X) NdisStatus (0x%X)\n",
|
||||||
Context, NdisPacket, NdisStatus));
|
Context, NdisPacket, NdisStatus));
|
||||||
|
|
||||||
if (NT_SUCCESS(NdisStatus) && PrepareNextFragment(IFC)) {
|
IFC->Status = NdisStatus;
|
||||||
/* A fragment was prepared for transmission, so send it */
|
KeSetEvent(&IFC->Event, 0, FALSE);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
NTSTATUS IPSendFragment(
|
NTSTATUS IPSendFragment(
|
||||||
|
@ -202,8 +186,7 @@ NTSTATUS SendFragments(
|
||||||
IFC->Position = 0;
|
IFC->Position = 0;
|
||||||
IFC->BytesLeft = IPPacket->TotalSize - IPPacket->HeaderSize;
|
IFC->BytesLeft = IPPacket->TotalSize - IPPacket->HeaderSize;
|
||||||
IFC->Data = (PVOID)((ULONG_PTR)IFC->Header + IPPacket->HeaderSize);
|
IFC->Data = (PVOID)((ULONG_PTR)IFC->Header + IPPacket->HeaderSize);
|
||||||
IFC->Complete = Complete;
|
KeInitializeEvent(&IFC->Event, NotificationEvent, FALSE);
|
||||||
IFC->Context = Context;
|
|
||||||
|
|
||||||
TI_DbgPrint(MID_TRACE,("Copying header from %x to %x (%d)\n",
|
TI_DbgPrint(MID_TRACE,("Copying header from %x to %x (%d)\n",
|
||||||
IPPacket->Header, IFC->Header,
|
IPPacket->Header, IFC->Header,
|
||||||
|
@ -211,19 +194,27 @@ NTSTATUS SendFragments(
|
||||||
|
|
||||||
RtlCopyMemory( IFC->Header, IPPacket->Header, IPPacket->HeaderSize );
|
RtlCopyMemory( IFC->Header, IPPacket->Header, IPPacket->HeaderSize );
|
||||||
|
|
||||||
/* Prepare next fragment for transmission and send it */
|
while (PrepareNextFragment(IFC))
|
||||||
|
|
||||||
if (!PrepareNextFragment(IFC)) {
|
|
||||||
FreeNdisPacket(IFC->NdisPacket);
|
|
||||||
ExFreePoolWithTag(IFC, IFC_TAG);
|
|
||||||
return NDIS_STATUS_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!NT_SUCCESS((NdisStatus = IPSendFragment(IFC->NdisPacket, NCE, IFC))))
|
|
||||||
{
|
{
|
||||||
|
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);
|
FreeNdisPacket(IFC->NdisPacket);
|
||||||
ExFreePoolWithTag(IFC, IFC_TAG);
|
ExFreePoolWithTag(IFC, IFC_TAG);
|
||||||
}
|
|
||||||
|
Complete(Context, IPPacket->NdisPacket, NdisStatus);
|
||||||
|
|
||||||
return NdisStatus;
|
return NdisStatus;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue