Author: zhu Date: Wed Jun 15 19:10:40 2016 New Revision: 71644 URL: http://svn.reactos.org/svn/reactos?rev=71644&view=rev Log: Implemented IRQ cancelling for listen() and connect() calls.
Modified: branches/GSoC_2016/lwIP/drivers/network/tcpip/address.c branches/GSoC_2016/lwIP/drivers/network/tcpip/main.c Modified: branches/GSoC_2016/lwIP/drivers/network/tcpip/address.c URL: http://svn.reactos.org/svn/reactos/branches/GSoC_2016/lwIP/drivers/network/tcpip/address.c?rev=71644&r1=71643&r2=71644&view=diff ============================================================================== --- branches/GSoC_2016/lwIP/drivers/network/tcpip/address.c [iso-8859-1] (original) +++ branches/GSoC_2016/lwIP/drivers/network/tcpip/address.c [iso-8859-1] Wed Jun 15 19:10:40 2016 @@ -26,6 +26,100 @@ /* The list of shared addresses */ static KSPIN_LOCK AddressListLock; static LIST_ENTRY AddressListHead; + +NTSTATUS +PrepareIrpForCancel( + PIRP Irp, + PDRIVER_CANCEL CancelRoutine +) +{ + KIRQL OldIrql; + + DPRINT1("Prepare for cancel\n"); + + IoAcquireCancelSpinLock(&OldIrql); + + if (!Irp->Cancel) + { + IoSetCancelRoutine(Irp, CancelRoutine); + IoReleaseCancelSpinLock(OldIrql); + return STATUS_SUCCESS; + } + + IoReleaseCancelSpinLock(OldIrql); + + Irp->IoStatus.Status = STATUS_CANCELLED; + Irp->IoStatus.Information = 0; + + return Irp->IoStatus.Status; +} + +VOID +NTAPI +CancelRequestRoutine( + _Inout_ struct _DEVICE_OBJECT *DeviceObject, + _Inout_ _IRQL_uses_cancel_ struct _IRP *Irp +) +{ + PIO_STACK_LOCATION IrpSp; + PADDRESS_FILE AddressFile; + UCHAR MinorFunction; + KIRQL OldIrql; + + DPRINT1("IRP Cancel\n"); + + IoReleaseCancelSpinLock(Irp->CancelIrql); + + IrpSp = IoGetCurrentIrpStackLocation(Irp); + AddressFile = (PADDRESS_FILE)IrpSp->FileObject->FsContext; + MinorFunction = IrpSp->MinorFunction; + + Irp->IoStatus.Status = STATUS_CANCELLED; + Irp->IoStatus.Information = 0; + + switch(MinorFunction) + { + case TDI_RECEIVE: + goto TCP_CANCEL; + case TDI_RECEIVE_DATAGRAM: + DPRINT1("TDI_RECEIVE_DATAGRAM cancelling is handled within TcpIpReceiveDatagram()\n"); + goto DGRAM_CANCEL; + break; + case TDI_SEND: + goto TCP_CANCEL; + case TDI_SEND_DATAGRAM: + goto DGRAM_CANCEL; + case TDI_LISTEN: + goto TCP_CANCEL; + case TDI_CONNECT: + goto TCP_CANCEL; + case TDI_DISCONNECT: + goto TCP_CANCEL; + default: + DPRINT1("Invalid MinorFunction for cancelling IRP\n"); + return; + } + +TCP_CANCEL: + if (AddressFile->ConnectionContext) + { + tcp_close(AddressFile->ConnectionContext->lwip_tcp_pcb); + DPRINT1("TCP_CANCEL\n"); + goto FINISH; + } +DGRAM_CANCEL: + DPRINT1("DGRAM_CANCEL\n"); + +FINISH: + IoAcquireCancelSpinLock(&OldIrql); + IoSetCancelRoutine(Irp, NULL); + IoReleaseCancelSpinLock(OldIrql); + + IoCompleteRequest(Irp, IO_NETWORK_INCREMENT); + + DPRINT1("\n CancelRequestRoutine\n Exiting\n"); + return; +} void TcpIpInitializeAddresses(void) @@ -149,10 +243,40 @@ err_t err) { PIRP Irp; + PIO_STACK_LOCATION IrpSp; + KIRQL OldIrql; + PADDRESS_FILE AddressFile; DPRINT1("lwIP TCP Accept Callback\n"); Irp = (PIRP)arg; + IrpSp = IoGetCurrentIrpStackLocation(Irp); + AddressFile = (PADDRESS_FILE)IrpSp->FileObject->FsContext; + + IoAcquireCancelSpinLock(&OldIrql); + IoSetCancelRoutine(Irp, NULL); + Irp->Cancel = FALSE; + IoReleaseCancelSpinLock(OldIrql); + + DPRINT1("\nnewpcb %08x\n", newpcb); + if (AddressFile->ConnectionContext) + { + if (AddressFile->ConnectionContext->lwip_tcp_pcb) + { + DPRINT1("\nlwip_tcp_pcb %08x\n", AddressFile->ConnectionContext->lwip_tcp_pcb); + } + else + { + DPRINT1("\nlwip_tcp_pcb is NULL\n"); + } + } + else + { + DPRINT1("ConnectionContext is NULL\n"); + } + + AddressFile->ConnectionContext->lwip_tcp_pcb = newpcb; + Irp->IoStatus.Status = STATUS_SUCCESS; IoCompleteRequest(Irp, IO_NETWORK_INCREMENT); @@ -212,10 +336,38 @@ err_t err) { PIRP Irp; + PIO_STACK_LOCATION IrpSp; + KIRQL OldIrql; + PADDRESS_FILE AddressFile; DPRINT1("lwIP TCP Connected Callback\n"); Irp = (PIRP)arg; + IrpSp = IoGetCurrentIrpStackLocation(Irp); + AddressFile = (PADDRESS_FILE)IrpSp->FileObject->FsContext; + + IoAcquireCancelSpinLock(&OldIrql); + IoSetCancelRoutine(Irp, NULL); + Irp->Cancel = FALSE; + IoReleaseCancelSpinLock(OldIrql); + + DPRINT1("\ntpcb %08x\n", tpcb); + if (AddressFile->ConnectionContext) + { + if (AddressFile->ConnectionContext->lwip_tcp_pcb) + { + DPRINT1("\nlwip_tcp_pcb %08x\n", AddressFile->ConnectionContext->lwip_tcp_pcb); + } + else + { + DPRINT1("\nlwip_tcp_pcb is NULL\n"); + } + } + else + { + DPRINT1("ConnectionContext is NULL\n"); + } + Irp->IoStatus.Status = STATUS_SUCCESS; IoCompleteRequest(Irp, IO_NETWORK_INCREMENT); @@ -410,6 +562,10 @@ PTCP_CONTEXT Context; Context = ExAllocatePoolWithTag(NonPagedPool, sizeof(*Context), TAG_ADDRESS_FILE); + if (!Context) + { + return STATUS_NO_MEMORY; + } if (Protocol != IPPROTO_TCP) { @@ -456,7 +612,7 @@ tcp_close(AddressFile->ConnectionContext->lwip_tcp_pcb); ExFreePoolWithTag(AddressFile->ConnectionContext, TAG_ADDRESS_FILE); } - else + else if (AddressFile->Protocol == IPPROTO_RAW) raw_remove(AddressFile->lwip_raw_pcb); /* Remove from the list and free the structure */ @@ -585,6 +741,8 @@ 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); + + PrepareIrpForCancel(Irp, CancelRequestRoutine); lwip_err = tcp_connect(AddressFile->ConnectionContext->lwip_tcp_pcb, (ip_addr_t *)&SocketAddressInRemote->sin_addr.s_addr, @@ -768,7 +926,8 @@ _Inout_ PIRP Irp) { PIO_STACK_LOCATION IrpSp; - ADDRESS_FILE *AddressFile; + PTCP_CONTEXT Context; + PADDRESS_FILE AddressFile; IrpSp = IoGetCurrentIrpStackLocation(Irp); if ((ULONG)IrpSp->FileObject->FsContext2 != TDI_TRANSPORT_ADDRESS_FILE) @@ -777,14 +936,24 @@ } AddressFile = IrpSp->FileObject->FsContext; - if (AddressFile->Protocol != IPPROTO_TCP) { DPRINT1("Received TDI_DISASSOCIATE_ADDRESS for non-TCP protocol\n"); return STATUS_INVALID_ADDRESS; } - /* NO-OP because we need the address to deallocate the port when the connection closes */ + 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"); + return STATUS_INVALID_ADDRESS; + } return STATUS_SUCCESS; } @@ -833,6 +1002,8 @@ { ConnectionContext->lwip_tcp_pcb = lpcb; } + + PrepareIrpForCancel(Irp, CancelRequestRoutine); tcp_accept(ConnectionContext->lwip_tcp_pcb, lwip_tcp_accept_callback); tcp_arg(ConnectionContext->lwip_tcp_pcb, Irp); Modified: branches/GSoC_2016/lwIP/drivers/network/tcpip/main.c URL: http://svn.reactos.org/svn/reactos/branches/GSoC_2016/lwIP/drivers/network/tcpip/main.c?rev=71644&r1=71643&r2=71644&view=diff ============================================================================== --- branches/GSoC_2016/lwIP/drivers/network/tcpip/main.c [iso-8859-1] (original) +++ branches/GSoC_2016/lwIP/drivers/network/tcpip/main.c [iso-8859-1] Wed Jun 15 19:10:40 2016 @@ -384,7 +384,9 @@ Quickie: Irp->IoStatus.Status = Status; - return Irp->IoStatus.Status; + IoCompleteRequest(Irp, IO_NETWORK_INCREMENT); + + return Irp->IoStatus.Status; } static