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


Reply via email to