Author: zhu
Date: Thu Jun 23 15:28:39 2016
New Revision: 71661
URL:
http://svn.reactos.org/svn/reactos?rev=71661&view=rev
Log:
Backlogging successful. Server is able to simultaneously receive messages from two
different clients. Crashes on client exit due to referencing deallocated memory.
Modified:
branches/GSoC_2016/lwIP-tcpip/drivers/network/tcpip/address.c
branches/GSoC_2016/lwIP-tcpip/drivers/network/tcpip/address.h
branches/GSoC_2016/lwIP-tcpip/drivers/network/tcpip/main.c
branches/GSoC_2016/lwIP-tcpip/sdk/lib/drivers/lwip/src/include/lwip/opt.h
Modified: branches/GSoC_2016/lwIP-tcpip/drivers/network/tcpip/address.c
URL:
http://svn.reactos.org/svn/reactos/branches/GSoC_2016/lwIP-tcpip/drivers/ne…
==============================================================================
--- branches/GSoC_2016/lwIP-tcpip/drivers/network/tcpip/address.c [iso-8859-1] (original)
+++ branches/GSoC_2016/lwIP-tcpip/drivers/network/tcpip/address.c [iso-8859-1] Thu Jun 23
15:28:39 2016
@@ -31,11 +31,13 @@
NTSTATUS
PrepareIrpForCancel(
PIRP Irp,
- PDRIVER_CANCEL CancelRoutine
+ PDRIVER_CANCEL CancelRoutine,
+ UCHAR CancelMode
)
{
PIO_STACK_LOCATION IrpSp;
- PADDRESS_FILE AddressFile;
+ PTCP_CONTEXT Context;
+ PTCP_REQUEST Request;
KIRQL OldIrql;
DPRINT1("Prepare for cancel\n");
@@ -44,14 +46,27 @@
if (!Irp->Cancel)
{
+ Request = ExAllocatePoolWithTag(NonPagedPool, sizeof(*Request), TAG_ADDRESS_FILE);
+ if (!Request)
+ {
+ return STATUS_NO_MEMORY;
+ }
+ Request->PendingIrp = Irp;
+ Request->CancelMode = CancelMode;
+
IrpSp = IoGetCurrentIrpStackLocation(Irp);
- AddressFile = (PADDRESS_FILE)IrpSp->FileObject->FsContext;
- AddressFile->ConnectionContext->PendingIrp = Irp;
+ Context = (PTCP_CONTEXT)IrpSp->FileObject->FsContext;
+ InsertTailList(&Context->RequestListHead, &Request->ListEntry);
IoSetCancelRoutine(Irp, CancelRoutine);
IoReleaseCancelSpinLock(OldIrql);
+
+ DPRINT1("Prepared for cancel\n");
+
return STATUS_SUCCESS;
}
+
+ DPRINT1("Already cancelled\n");
IoReleaseCancelSpinLock(OldIrql);
@@ -70,7 +85,10 @@
)
{
PIO_STACK_LOCATION IrpSp;
- PADDRESS_FILE AddressFile;
+ PTCP_CONTEXT Context;
+ PLIST_ENTRY Head;
+ PLIST_ENTRY Entry;
+ PTCP_REQUEST Request;
UCHAR MinorFunction;
KIRQL OldIrql;
@@ -79,51 +97,68 @@
IoReleaseCancelSpinLock(Irp->CancelIrql);
IrpSp = IoGetCurrentIrpStackLocation(Irp);
- AddressFile = (PADDRESS_FILE)IrpSp->FileObject->FsContext;
+ switch ((ULONG)IrpSp->FileObject->FsContext2)
+ {
+ case TDI_TRANSPORT_ADDRESS_FILE :
+ goto DGRAM_CANCEL;
+ case TDI_CONNECTION_FILE :
+ Context = (PTCP_CONTEXT)IrpSp->FileObject->FsContext;
+ goto TCP_CANCEL;
+ default :
+ DPRINT1("Cancellation error\n");
+ goto FINISH;
+ }
+
+TCP_CANCEL:
MinorFunction = IrpSp->MinorFunction;
-
Irp->IoStatus.Status = STATUS_CANCELLED;
Irp->IoStatus.Information = 0;
-
switch(MinorFunction)
{
+ case TDI_SEND:
+ DPRINT1("TDI_SEND Cancel\n");
+ break;
+ case TDI_LISTEN:
+ DPRINT1("TDI_LISTEN Cancel\n");
+ break;
+ case TDI_CONNECT:
+ DPRINT1("TDI_CONNECT Cancel\n");
+ break;
case TDI_RECEIVE:
DPRINT1("TDI_RECEIVE Cancel\n");
- goto TCP_CANCEL;
- case TDI_RECEIVE_DATAGRAM:
- DPRINT1("TDI_RECEIVE_DATAGRAM cancelling is handled within
TcpIpReceiveDatagram()\n");
- goto DGRAM_CANCEL;
- case TDI_SEND:
- DPRINT1("TDI_SEND Cancel\n");
- goto TCP_CANCEL;
- case TDI_SEND_DATAGRAM:
- DPRINT1("TDI_SEND_DATAGRAM Cancel\n");
- goto DGRAM_CANCEL;
- case TDI_LISTEN:
- DPRINT1("TDI_LISTEN Cancel\n");
- goto TCP_CANCEL;
- case TDI_CONNECT:
- DPRINT1("TDI_CONNECT Cancel\n");
- goto TCP_CANCEL;
+ break;
case TDI_DISCONNECT:
DPRINT1("TDI_DISCONNECT Cancel\n");
- goto TCP_CANCEL;
+ break;
default:
- DPRINT1("Invalid MinorFunction for cancelling IRP\n");
- return;
- }
-
-TCP_CANCEL:
- if (AddressFile->ConnectionContext)
- {
- if (AddressFile->ConnectionContext->lwip_tcp_pcb)
+ DPRINT1("Invalid MinorFunction for TCP_CANCEL\n");
+ goto FINISH;
+ }
+
+ Head = &Context->RequestListHead;
+ Entry = Head->Flink;
+ while (Entry != Head)
+ {
+ Request = CONTAINING_RECORD(Entry, TCP_REQUEST, ListEntry);
+ if (Request->PendingIrp == Irp)
{
- tcp_abort(AddressFile->ConnectionContext->lwip_tcp_pcb);
- AddressFile->ConnectionContext->PendingIrp = NULL;
- AddressFile->ConnectionContext->lwip_tcp_pcb = NULL;
- DPRINT1("TCP_CANCEL\n");
+ RemoveEntryList(Entry);
+ switch (Request->CancelMode)
+ {
+ case TCP_REQUEST_CANCEL_MODE_ABORT:
+ tcp_abort(Context->lwip_tcp_pcb);
+ break;
+ case TCP_REQUEST_CANCEL_MODE_CLOSE:
+ tcp_close(Context->lwip_tcp_pcb);
+ break;
+ }
+ Context->lwip_tcp_pcb = NULL;
+ Request->PendingIrp = NULL;
+ goto FINISH;
}
- }
+ Entry = Entry->Flink;
+ }
+ DPRINT1("No matching TCP_REQUEST found\n");
goto FINISH;
DGRAM_CANCEL:
@@ -136,7 +171,8 @@
IoCompleteRequest(Irp, IO_NETWORK_INCREMENT);
- DPRINT1("\n CancelRequestRoutine\n Exiting\n");
+ DPRINT1("\n CancelRequestRoutine Exiting\n");
+
return;
}
@@ -263,26 +299,55 @@
err_t err)
{
PIRP Irp;
- PIO_STACK_LOCATION IrpSp;
KIRQL OldIrql;
+ PTCP_REQUEST Request;
PADDRESS_FILE AddressFile;
+ PTCP_CONTEXT Context;
+
+ PLIST_ENTRY Head;
+ PLIST_ENTRY Entry;
+ PLIST_ENTRY Temp;
DPRINT1("lwIP TCP Accept Callback\n");
AddressFile = (PADDRESS_FILE)arg;
- Irp = AddressFile->ConnectionContext->PendingIrp;
+ if (AddressFile->ContextCount == 0)
+ {
+ DPRINT1("\n Callback on address file with no contexts\n");
+ return ERR_ABRT;
+ }
+ Head = &AddressFile->ConnectionContext->ListEntry;
+ Entry = Head->Blink;
+ Irp = NULL;
+ while (Entry != Head)
+ {
+ Context = CONTAINING_RECORD(Entry, TCP_CONTEXT, ListEntry);
+ if (Context->lwip_tcp_pcb == AddressFile->ConnectionContext->lwip_tcp_pcb)
+ {
+ if (IsListEmpty(&Context->RequestListHead))
+ {
+ DPRINT1("Context has empty request list\n");
+ return ERR_ABRT;
+ }
+ Request = CONTAINING_RECORD(Context->RequestListHead.Flink,
+ TCP_REQUEST, ListEntry);
+ Irp = Request->PendingIrp;
+ if (!Irp)
+ {
+ DPRINT1("Found cancelled IRP\n");
+ Temp = Entry->Blink;
+ RemoveEntryList(Entry);
+ ExFreePoolWithTag(Request, TAG_ADDRESS_FILE);
+ Entry = Temp;
+ continue;
+ }
+ break;
+ }
+ Entry = Entry->Blink;
+ }
if (!Irp)
{
- DPRINT1("Callback on canceled IRP\n");
- return ERR_ABRT;
- }
- IrpSp = IoGetCurrentIrpStackLocation(Irp);
-
- if (AddressFile != IrpSp->FileObject->FsContext)
- {
- DPRINT1("AddressFile Mismatch\n");
- tcp_abort(AddressFile->ConnectionContext->lwip_tcp_pcb);
- AddressFile->ConnectionContext->lwip_tcp_pcb = NULL;
+ DPRINT1("Could not find a listening tcp_pcb\n");
return ERR_ABRT;
}
@@ -291,10 +356,14 @@
Irp->Cancel = FALSE;
IoReleaseCancelSpinLock(OldIrql);
- AddressFile->ConnectionContext->lwip_tcp_pcb = newpcb;
+ Context->lwip_tcp_pcb = newpcb;
+ tcp_accepted(AddressFile->ConnectionContext->lwip_tcp_pcb);
+ RemoveEntryList(&Request->ListEntry);
Irp->IoStatus.Status = STATUS_SUCCESS;
IoCompleteRequest(Irp, IO_NETWORK_INCREMENT);
+
+ ExFreePoolWithTag(Request, TAG_ADDRESS_FILE);
return ERR_OK;
}
@@ -308,17 +377,18 @@
u16_t len
)
{
- PADDRESS_FILE AddressFile;
+ PTCP_REQUEST Request;
PIRP Irp;
KIRQL OldIrql;
DPRINT1("lwIP TCP Sent Callback\n");
- AddressFile = (PADDRESS_FILE)arg;
- Irp = AddressFile->ConnectionContext->PendingIrp;
+ Request = (PTCP_REQUEST)arg;
+ Irp = Request->PendingIrp;
if (!Irp)
{
- DPRINT1("Callback on canceled IRP\n");
+ DPRINT1("Callback on cancelled IRP\n");
+ ExFreePoolWithTag(Request, TAG_ADDRESS_FILE);
return ERR_ABRT;
}
@@ -330,6 +400,9 @@
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = len;
IoCompleteRequest(Irp, IO_NETWORK_INCREMENT);
+
+ RemoveEntryList(&Request->ListEntry);
+ ExFreePoolWithTag(Request, TAG_ADDRESS_FILE);
return ERR_OK;
}
@@ -346,7 +419,8 @@
{
PIRP Irp;
PNDIS_BUFFER Buffer;
- PADDRESS_FILE AddressFile;
+ PTCP_CONTEXT Context;
+ PTCP_REQUEST Request;
PIO_STACK_LOCATION IrpSp;
PTDI_REQUEST_KERNEL_RECEIVE ReceiveInfo;
KIRQL OldIrql;
@@ -359,11 +433,36 @@
DPRINT1("lwIP TCP Receive Callback\n");
- AddressFile = (PADDRESS_FILE)arg;
- Irp = AddressFile->ConnectionContext->PendingIrp;
+ if (err != ERR_OK)
+ {
+ DPRINT1("lwIP Error %d\n", err);
+ return ERR_ABRT;
+ }
+
+ Request = (PTCP_REQUEST)arg;
+ Irp = Request->PendingIrp;
if (!Irp)
{
- DPRINT1("Callback on canceled IRP\n");
+ DPRINT1("Callback on cancelled IRP\n");
+ ExFreePoolWithTag(Request, TAG_ADDRESS_FILE);
+ return ERR_ABRT;
+ }
+ IrpSp = IoGetCurrentIrpStackLocation(Irp);
+ Context = (PTCP_CONTEXT)IrpSp->FileObject->FsContext;
+ if (!Context->lwip_tcp_pcb)
+ {
+ DPRINT1("Context pcb is NULL\n");
+ return ERR_ABRT;
+ }
+ if (Context->lwip_tcp_pcb != tpcb)
+ {
+ DPRINT1("Receive tcp_pcb mismatch\n");
+ tcp_abort(tpcb);
+ Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
+ Irp->IoStatus.Information = 0;
+ IoCompleteRequest(Irp, IO_NETWORK_INCREMENT);
+ RemoveEntryList(&Request->ListEntry);
+ ExFreePoolWithTag(Request, TAG_ADDRESS_FILE);
return ERR_ABRT;
}
@@ -373,7 +472,6 @@
IoReleaseCancelSpinLock(OldIrql);
Buffer = (PNDIS_BUFFER)Irp->MdlAddress;
- IrpSp = IoGetCurrentIrpStackLocation(Irp);
ReceiveInfo = (PTDI_REQUEST_KERNEL_RECEIVE)&IrpSp->Parameters;
NdisQueryBuffer(Buffer, &CurrentDestLocation, &RemainingDestBytes);
@@ -432,10 +530,15 @@
RETURN:
DPRINT1("Receive CopiedLength = %d\n", CopiedLength);
+
+ tcp_recved(tpcb, CopiedLength);
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = CopiedLength;
IoCompleteRequest(Irp, IO_NETWORK_INCREMENT);
+
+ RemoveEntryList(&Request->ListEntry);
+ ExFreePoolWithTag(Request, TAG_ADDRESS_FILE);
return ERR_OK;
}
@@ -493,19 +596,35 @@
struct tcp_pcb *tpcb,
err_t err)
{
- PADDRESS_FILE AddressFile;
+ PTCP_REQUEST Request;
+ PTCP_CONTEXT Context;
+ PIO_STACK_LOCATION IrpSp;
PIRP Irp;
KIRQL OldIrql;
DPRINT1("lwIP TCP Connected Callback\n");
- AddressFile = (PADDRESS_FILE)arg;
- Irp = AddressFile->ConnectionContext->PendingIrp;
+ Request = (PTCP_REQUEST)arg;
+ Irp = Request->PendingIrp;
if (!Irp)
{
- DPRINT1("Callback on canceled IRP\n");
+ DPRINT1("Callback on cancelled IRP\n");
+ ExFreePoolWithTag(Request, TAG_ADDRESS_FILE);
return ERR_ABRT;
}
+
+ IrpSp = IoGetCurrentIrpStackLocation(Irp);
+ Context = (PTCP_CONTEXT)IrpSp->FileObject->FsContext;
+ if (Context->AddressFile->ConnectionContext->lwip_tcp_pcb == tpcb)
+ {
+ DPRINT1("Same as old pcb\n");
+ }
+ else
+ {
+ DPRINT1("Connected callback assigns new pcb\n");
+ }
+ Context->lwip_tcp_pcb = tpcb;
+ Context->AddressFile->ConnectionContext->lwip_tcp_pcb = NULL;
IoAcquireCancelSpinLock(&OldIrql);
IoSetCancelRoutine(Irp, NULL);
@@ -514,6 +633,9 @@
Irp->IoStatus.Status = STATUS_SUCCESS;
IoCompleteRequest(Irp, IO_NETWORK_INCREMENT);
+
+ RemoveEntryList(&Request->ListEntry);
+ ExFreePoolWithTag(Request, TAG_ADDRESS_FILE);
return ERR_OK;
}
@@ -648,7 +770,7 @@
InitializeListHead(&TcpContext->ListEntry);
TcpContext->AddressFile = AddressFile;
TcpContext->Protocol = IPPROTO_TCP;
- TcpContext->PendingIrp = NULL;
+ InitializeListHead(&TcpContext->RequestListHead);
TcpContext->lwip_tcp_pcb = tcp_new();
AddressFile->ConnectionContext = TcpContext;
AddressFile->ContextCount = 0;
@@ -696,6 +818,7 @@
Success:
IrpSp->FileObject->FsContext = AddressFile;
IrpSp->FileObject->FsContext2 = (PVOID)TDI_TRANSPORT_ADDRESS_FILE;
+
return STATUS_SUCCESS;
}
@@ -741,6 +864,7 @@
}
Context->Protocol = Protocol;
RtlCopyMemory(&Context->RequestAddress, Address, sizeof(*Address));
+ InitializeListHead(&Context->RequestListHead);
Context->lwip_tcp_pcb = NULL;
IrpSp->FileObject->FsContext = (PVOID)Context;
@@ -776,10 +900,12 @@
/* remove the lwip pcb */
if (AddressFile->Protocol == IPPROTO_UDP)
udp_remove(AddressFile->lwip_udp_pcb);
- else if (AddressFile->Protocol == IPPROTO_TCP &&
AddressFile->ConnectionContext)
- {
+ else if (AddressFile->Protocol == IPPROTO_TCP)
+ {
+ DPRINT1("Closing TCP address\n");
if (AddressFile->ContextCount != 0)
{
+ DPRINT1("Closing open contexts\n");
Head = &AddressFile->ConnectionContext->ListEntry;
Entry = Head->Flink;
while (Entry != Head)
@@ -788,6 +914,17 @@
CurrentContext = CONTAINING_RECORD(Entry, TCP_CONTEXT, ListEntry);
RemoveEntryList(Entry);
+ if (!IsListEmpty(&CurrentContext->RequestListHead))
+ {
+ DPRINT1("Address has non-empty request queue\n");
+ return STATUS_NOT_IMPLEMENTED;
+ }
+ if (CurrentContext->lwip_tcp_pcb !=
AddressFile->ConnectionContext->lwip_tcp_pcb
+ && CurrentContext->lwip_tcp_pcb)
+ {
+ DPRINT1("Freeing connected tcp_pcb\n");
+ tcp_abort(CurrentContext->lwip_tcp_pcb);
+ }
ExFreePoolWithTag(CurrentContext, TAG_ADDRESS_FILE);
AddressFile->ContextCount--;
Entry = Temp;
@@ -801,7 +938,6 @@
if (AddressFile->ConnectionContext->lwip_tcp_pcb)
{
tcp_close(AddressFile->ConnectionContext->lwip_tcp_pcb);
- AddressFile->ConnectionContext->lwip_tcp_pcb = NULL;
}
ExFreePoolWithTag(AddressFile->ConnectionContext, TAG_ADDRESS_FILE);
}
@@ -896,7 +1032,8 @@
_Inout_ PIRP Irp)
{
PIO_STACK_LOCATION IrpSp;
- ADDRESS_FILE *AddressFile;
+ PTCP_CONTEXT Context;
+ PTCP_REQUEST Request;
PTDI_REQUEST_KERNEL_CONNECT Parameters;
PTRANSPORT_ADDRESS RemoteTransportAddress;
@@ -908,14 +1045,14 @@
IrpSp = IoGetCurrentIrpStackLocation(Irp);
/* Check this is really a connection file */
- if ((ULONG_PTR)IrpSp->FileObject->FsContext2 != TDI_TRANSPORT_ADDRESS_FILE)
- {
- DPRINT1("File object not an address file\n");
+ if ((ULONG_PTR)IrpSp->FileObject->FsContext2 != TDI_CONNECTION_FILE)
+ {
+ DPRINT1("File object not a connection context\n");
return STATUS_FILE_INVALID;
}
- AddressFile = IrpSp->FileObject->FsContext;
- if (AddressFile->Protocol != IPPROTO_TCP)
+ Context = IrpSp->FileObject->FsContext;
+ if (Context->AddressFile->Protocol != IPPROTO_TCP)
{
DPRINT1("Received TDI_CONNECT for a non-TCP protocol\n");
return STATUS_INVALID_ADDRESS;
@@ -932,10 +1069,10 @@
SocketAddressInRemote->sin_addr.s_addr,
SocketAddressInRemote->sin_port);
DPRINT1("\n Local Address\n Address: %08x\n Port: %04x\n",
- AddressFile->ConnectionContext->lwip_tcp_pcb->local_ip,
- AddressFile->ConnectionContext->lwip_tcp_pcb->local_port);
-
- lwip_err = tcp_connect(AddressFile->ConnectionContext->lwip_tcp_pcb,
+ Context->lwip_tcp_pcb->local_ip,
+ Context->lwip_tcp_pcb->local_port);
+
+ lwip_err = tcp_connect(Context->lwip_tcp_pcb,
(ip_addr_t *)&SocketAddressInRemote->sin_addr.s_addr,
SocketAddressInRemote->sin_port,
lwip_tcp_Connected_callback);
@@ -978,9 +1115,12 @@
}
case (ERR_OK) :
{
-// DPRINT1("lwip ERR_OK\n");
- PrepareIrpForCancel(Irp, CancelRequestRoutine);
- tcp_arg(AddressFile->ConnectionContext->lwip_tcp_pcb, AddressFile);
+ PrepareIrpForCancel(Irp, CancelRequestRoutine, TCP_REQUEST_CANCEL_MODE_ABORT);
+ Request = CONTAINING_RECORD(
+ Context->RequestListHead.Blink,
+ TCP_REQUEST,
+ ListEntry);
+ tcp_arg(Context->lwip_tcp_pcb, Request);
break;
}
default :
@@ -1127,9 +1267,6 @@
}
KeReleaseSpinLock(&AddressFile->RequestLock, OldIrql);
-
- IrpSp->FileObject->FsContext = AddressFile;
- IrpSp->FileObject->FsContext2 = (PVOID)TDI_TRANSPORT_ADDRESS_FILE;
Status = STATUS_SUCCESS;
LEAVE:
@@ -1144,32 +1281,23 @@
{
PIO_STACK_LOCATION IrpSp;
PTCP_CONTEXT Context;
- PTCP_CONTEXT CurrentContext;
PADDRESS_FILE AddressFile;
KIRQL OldIrql;
- LIST_ENTRY *Head;
- LIST_ENTRY *Entry;
IrpSp = IoGetCurrentIrpStackLocation(Irp);
- if ((ULONG)IrpSp->FileObject->FsContext2 != TDI_TRANSPORT_ADDRESS_FILE)
- {
+ if ((ULONG)IrpSp->FileObject->FsContext2 != TDI_CONNECTION_FILE)
+ {
+ DPRINT1("Disassociating something that is not a connection context\n");
return STATUS_FILE_INVALID;
}
- AddressFile = IrpSp->FileObject->FsContext;
+ Context = IrpSp->FileObject->FsContext;
+ AddressFile = Context->AddressFile;
if (AddressFile->Protocol != IPPROTO_TCP)
{
DPRINT1("Received TDI_DISASSOCIATE_ADDRESS for non-TCP protocol\n");
return STATUS_INVALID_ADDRESS;
}
-
- Context = AddressFile->ConnectionContext;
- if (!Context)
- {
- DPRINT1("No connection context\n");
- return STATUS_INVALID_PARAMETER;
- }
-
if (Context->Protocol != IPPROTO_TCP)
{
DPRINT1("Address File and Context have mismatching protocols\n");
@@ -1177,26 +1305,17 @@
}
KeAcquireSpinLock(&AddressFile->RequestLock, &OldIrql);
-
- Head = &AddressFile->ConnectionContext->ListEntry;
- Entry = Head->Flink;
- if (Entry == Head)
- {
- DPRINT1("Disassociating from empty context list\n");
- KeReleaseSpinLock(&AddressFile->RequestLock, OldIrql);
- return STATUS_INVALID_ADDRESS;
- }
- if (AddressFile->ContextCount < 1)
- {
- DPRINT1("Invalid ContextCount\n");
- KeReleaseSpinLock(&AddressFile->RequestLock, OldIrql);
- return STATUS_INVALID_ADDRESS;
- }
- CurrentContext = CONTAINING_RECORD(Entry, TCP_CONTEXT, ListEntry);
- RemoveEntryList(Entry);
- ExFreePoolWithTag(CurrentContext, TAG_ADDRESS_FILE);
+ RemoveEntryList(&Context->ListEntry);
+ if (!IsListEmpty(&Context->RequestListHead))
+ {
+ DPRINT1("Disassociating context with pending requests\n");
+ }
+ if (Context->lwip_tcp_pcb != AddressFile->ConnectionContext->lwip_tcp_pcb)
+ {
+ tcp_abort(Context->lwip_tcp_pcb);
+ }
+ ExFreePoolWithTag(Context, TAG_ADDRESS_FILE);
AddressFile->ContextCount--;
-
KeReleaseSpinLock(&AddressFile->RequestLock, OldIrql);
return STATUS_SUCCESS;
@@ -1211,29 +1330,31 @@
PADDRESS_FILE AddressFile;
PTCP_CONTEXT ConnectionContext;
+ KIRQL OldIrql;
+
struct tcp_pcb *lpcb;
IrpSp = IoGetCurrentIrpStackLocation(Irp);
- /* Check this is really an address file */
- if ((ULONG_PTR)IrpSp->FileObject->FsContext2 != TDI_TRANSPORT_ADDRESS_FILE)
- {
- DPRINT1("Not an address file\n");
+ /* Check this is really a context file */
+ if ((ULONG_PTR)IrpSp->FileObject->FsContext2 != TDI_CONNECTION_FILE)
+ {
+ DPRINT1("Not a connection context\n");
return STATUS_FILE_INVALID;
}
- /* Get address file */
- AddressFile = IrpSp->FileObject->FsContext;
- ConnectionContext = AddressFile->ConnectionContext;
+ /* Get context file */
+ ConnectionContext = IrpSp->FileObject->FsContext;
+ AddressFile = ConnectionContext->AddressFile;
if (ConnectionContext->Protocol != IPPROTO_TCP)
{
DPRINT1("Received TDI_LISTEN for a non-TCP protocol\n");
return STATUS_INVALID_ADDRESS;
}
- PrepareIrpForCancel(Irp, CancelRequestRoutine);
- if (AddressFile->ContextCount <= 1)
- {
+ if (AddressFile->ContextCount == 1)
+ {
+ KeAcquireSpinLock(&AddressFile->RequestLock, &OldIrql);
/* Call down into lwip to initiate a listen */
lpcb = tcp_listen(ConnectionContext->lwip_tcp_pcb);
DPRINT1("lwip tcp_listen returned\n");
@@ -1245,13 +1366,15 @@
DPRINT1("lwip tcp_listen error\n");
return STATUS_INVALID_ADDRESS;
}
- else
- {
- ConnectionContext->lwip_tcp_pcb = lpcb;
- }
+ AddressFile->ConnectionContext->lwip_tcp_pcb = lpcb;
+ ConnectionContext->lwip_tcp_pcb = lpcb;
+ tcp_arg(ConnectionContext->lwip_tcp_pcb, AddressFile);
tcp_accept(ConnectionContext->lwip_tcp_pcb, lwip_tcp_accept_callback);
- tcp_arg(ConnectionContext->lwip_tcp_pcb, AddressFile);
- }
+
+ KeReleaseSpinLock(&AddressFile->RequestLock, OldIrql);
+ }
+
+ PrepareIrpForCancel(Irp, CancelRequestRoutine, TCP_REQUEST_CANCEL_MODE_CLOSE);
return STATUS_PENDING;
}
@@ -1262,8 +1385,8 @@
{
PIO_STACK_LOCATION IrpSp;
PTDI_REQUEST_KERNEL_SEND Request;
- PADDRESS_FILE AddressFile;
PTCP_CONTEXT Context;
+ PTCP_REQUEST TcpRequest;
PVOID Buffer;
UINT Len;
@@ -1272,19 +1395,12 @@
IrpSp = IoGetCurrentIrpStackLocation(Irp);
Request = (PTDI_REQUEST_KERNEL_SEND)&IrpSp->Parameters;
- if (IrpSp->FileObject->FsContext2 != (PVOID)TDI_TRANSPORT_ADDRESS_FILE)
- {
- DPRINT1("TcpIpSend without a TDI_TRANSPORT_ADDRESS_FILE\n");
+ if (IrpSp->FileObject->FsContext2 != (PVOID)TDI_CONNECTION_FILE)
+ {
+ DPRINT1("TcpIpSend without a TDI_CONNECTION_FILE\n");
return STATUS_INVALID_PARAMETER;
}
- AddressFile = IrpSp->FileObject->FsContext;
-
- if (!AddressFile->ConnectionContext)
- {
- DPRINT1("TcpIpSend with no TCP_CONTEXT\n");
- return STATUS_INVALID_PARAMETER;
- }
- Context = AddressFile->ConnectionContext;
+ Context = IrpSp->FileObject->FsContext;
if (!Irp->MdlAddress)
{
@@ -1323,8 +1439,10 @@
return STATUS_NOT_IMPLEMENTED;
}
- PrepareIrpForCancel(Irp, CancelRequestRoutine);
- tcp_arg(Context->lwip_tcp_pcb, AddressFile);
+ PrepareIrpForCancel(Irp, CancelRequestRoutine, TCP_REQUEST_CANCEL_MODE_ABORT);
+ TcpRequest = CONTAINING_RECORD(Context->RequestListHead.Blink,
+ TCP_REQUEST, ListEntry);
+ tcp_arg(Context->lwip_tcp_pcb, TcpRequest);
tcp_sent(Context->lwip_tcp_pcb, lwip_tcp_sent_callback);
return STATUS_PENDING;
@@ -1335,39 +1453,39 @@
_Inout_ PIRP Irp)
{
PIO_STACK_LOCATION IrpSp;
- PADDRESS_FILE AddressFile;
PTCP_CONTEXT Context;
+ PTCP_REQUEST Request;
PTDI_REQUEST_KERNEL_RECEIVE RequestInfo;
IrpSp = IoGetCurrentIrpStackLocation(Irp);
- if (IrpSp->FileObject->FsContext2 != (PVOID)TDI_TRANSPORT_ADDRESS_FILE)
+ if (IrpSp->FileObject->FsContext2 != (PVOID)TDI_CONNECTION_FILE)
{
DPRINT1("TcpIpReceive on something that is not an address file\n");
return STATUS_INVALID_PARAMETER;
}
- AddressFile = IrpSp->FileObject->FsContext;
-
- if (!AddressFile->ConnectionContext)
- {
- DPRINT1("Receiving on TCP address file with no connection context\n");
- return STATUS_INVALID_ADDRESS;
- }
- Context = AddressFile->ConnectionContext;
+ Context = IrpSp->FileObject->FsContext;
if (!Context->lwip_tcp_pcb)
{
DPRINT1("Connection context does not contain a lwIP tcp_pcb\n");
return STATUS_INVALID_ADDRESS;
}
+ if (Context->lwip_tcp_pcb ==
Context->AddressFile->ConnectionContext->lwip_tcp_pcb)
+ {
+ DPRINT1("Has the pcb been assigned by a lwIP callback?\n");
+ return STATUS_INVALID_ADDRESS;
+ }
RequestInfo = (PTDI_REQUEST_KERNEL_RECEIVE)&IrpSp->Parameters;
DPRINT1("\n Request Length = %d\n", RequestInfo->ReceiveLength);
- PrepareIrpForCancel(Irp, CancelRequestRoutine);
+ PrepareIrpForCancel(Irp, CancelRequestRoutine, TCP_REQUEST_CANCEL_MODE_CLOSE);
+ Request = CONTAINING_RECORD(Context->RequestListHead.Blink,
+ TCP_REQUEST, ListEntry);
+ tcp_arg(Context->lwip_tcp_pcb, Request);
tcp_recv(Context->lwip_tcp_pcb, lwip_tcp_receive_callback);
- tcp_arg(Context->lwip_tcp_pcb, AddressFile);
return STATUS_PENDING;
}
Modified: branches/GSoC_2016/lwIP-tcpip/drivers/network/tcpip/address.h
URL:
http://svn.reactos.org/svn/reactos/branches/GSoC_2016/lwIP-tcpip/drivers/ne…
==============================================================================
--- branches/GSoC_2016/lwIP-tcpip/drivers/network/tcpip/address.h [iso-8859-1] (original)
+++ branches/GSoC_2016/lwIP-tcpip/drivers/network/tcpip/address.h [iso-8859-1] Thu Jun 23
15:28:39 2016
@@ -1,5 +1,8 @@
#pragma once
+
+#define TCP_REQUEST_CANCEL_MODE_ABORT 1
+#define TCP_REQUEST_CANCEL_MODE_CLOSE 2
typedef struct _ADDRESS_FILE {
LIST_ENTRY ListEntry;
@@ -23,9 +26,15 @@
PADDRESS_FILE AddressFile;
IPPROTO Protocol;
TDI_ADDRESS_IP RequestAddress;
- PIRP PendingIrp;
+ LIST_ENTRY RequestListHead;
struct tcp_pcb* lwip_tcp_pcb;
} TCP_CONTEXT, *PTCP_CONTEXT;
+
+typedef struct _TCP_REQUEST {
+ LIST_ENTRY ListEntry;
+ PIRP PendingIrp;
+ UCHAR CancelMode;
+} TCP_REQUEST, *PTCP_REQUEST;
void
TcpIpInitializeAddresses(void);
Modified: branches/GSoC_2016/lwIP-tcpip/drivers/network/tcpip/main.c
URL:
http://svn.reactos.org/svn/reactos/branches/GSoC_2016/lwIP-tcpip/drivers/ne…
==============================================================================
--- branches/GSoC_2016/lwIP-tcpip/drivers/network/tcpip/main.c [iso-8859-1] (original)
+++ branches/GSoC_2016/lwIP-tcpip/drivers/network/tcpip/main.c [iso-8859-1] Thu Jun 23
15:28:39 2016
@@ -346,6 +346,7 @@
)
{
PIO_STACK_LOCATION IrpSp;
+ PTCP_CONTEXT Context;
NTSTATUS Status;
ULONG_PTR FileType;
@@ -366,6 +367,11 @@
}
Status = TcpIpCloseAddress(IrpSp->FileObject->FsContext);
break;
+ case TDI_CONNECTION_FILE:
+ DPRINT1("TCPIP Close Connection Context\n");
+ Context = IrpSp->FileObject->FsContext;
+ Status = TcpIpCloseAddress(Context->AddressFile);
+ break;
case TDI_CONTROL_CHANNEL_FILE:
/* We didn't allocate anything for this. */
Status = STATUS_SUCCESS;
@@ -394,13 +400,26 @@
{
NTSTATUS Status;
PIO_STACK_LOCATION IrpSp;
+ PTCP_CONTEXT Context;
PADDRESS_FILE AddressFile;
DPRINT1("TcpIpDispatchInternal\n");
IrpSp = IoGetCurrentIrpStackLocation(Irp);
- AddressFile = IrpSp->FileObject->FsContext;
+ switch ((ULONG)IrpSp->FileObject->FsContext2)
+ {
+ case TDI_TRANSPORT_ADDRESS_FILE :
+ AddressFile = IrpSp->FileObject->FsContext;
+ break;
+ case TDI_CONNECTION_FILE :
+ Context = IrpSp->FileObject->FsContext;
+ AddressFile = Context->AddressFile;
+ break;
+ default :
+ DPRINT1("Unknown FileObject type\n");
+ break;
+ }
switch (IrpSp->MinorFunction)
{
@@ -423,7 +442,6 @@
if (Status == STATUS_NOT_IMPLEMENTED)
{
DPRINT1("Received TDI_RECEIVE for non-TCP protocol\n");
-
}
break;
case TDI_RECEIVE_DATAGRAM:
Modified: branches/GSoC_2016/lwIP-tcpip/sdk/lib/drivers/lwip/src/include/lwip/opt.h
URL:
http://svn.reactos.org/svn/reactos/branches/GSoC_2016/lwIP-tcpip/sdk/lib/dr…
==============================================================================
--- branches/GSoC_2016/lwIP-tcpip/sdk/lib/drivers/lwip/src/include/lwip/opt.h [iso-8859-1]
(original)
+++ branches/GSoC_2016/lwIP-tcpip/sdk/lib/drivers/lwip/src/include/lwip/opt.h [iso-8859-1]
Thu Jun 23 15:28:39 2016
@@ -1023,7 +1023,7 @@
* TCP_LISTEN_BACKLOG: Enable the backlog option for tcp listen pcb.
*/
#ifndef TCP_LISTEN_BACKLOG
-#define TCP_LISTEN_BACKLOG 0
+#define TCP_LISTEN_BACKLOG 1
#endif
/**