Author: zhu Date: Wed Jul 6 20:53:31 2016 New Revision: 71835 URL: http://svn.reactos.org/svn/reactos?rev=71835&view=rev Log: Mostly cleanup. Removed abusive use of cancel spin lock, thanks to David for pointing that out for me.
Modified: branches/GSoC_2016/lwIP-tcpip/drivers/network/tcpip/address.c branches/GSoC_2016/lwIP-tcpip/drivers/network/tcpip/main.c Modified: branches/GSoC_2016/lwIP-tcpip/drivers/network/tcpip/address.c URL: http://svn.reactos.org/svn/reactos/branches/GSoC_2016/lwIP-tcpip/drivers/network/tcpip/address.c?rev=71835&r1=71834&r2=71835&view=diff ============================================================================== --- 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] Wed Jul 6 20:53:31 2016 @@ -9,6 +9,8 @@ #define NDEBUG #include <debug.h> + +volatile long int PcbCount; typedef struct { @@ -22,6 +24,7 @@ /* The pool tags we will use for all of our allocation */ #define TAG_ADDRESS_FILE 'FrdA' +#define TAG_DGRAM_REQST 'DgRq' #define TAG_TCP_CONTEXT 'TCPx' #define TAG_TCP_REQUEST 'TCPr' @@ -42,10 +45,9 @@ PTCP_CONTEXT Context; PTCP_REQUEST Request; KIRQL OldIrql; + NTSTATUS Status; DPRINT1("Prepare for cancel\n"); - - IoAcquireCancelSpinLock(&OldIrql); if (!Irp->Cancel) { @@ -53,9 +55,8 @@ if (!Request) { DPRINT1("Allocation failed, out of memory\n"); - IoReleaseCancelSpinLock(OldIrql); - - return STATUS_NO_MEMORY; + Status = STATUS_NO_MEMORY; + goto RETURN; } IrpSp = IoGetCurrentIrpStackLocation(Irp); @@ -66,31 +67,28 @@ Request->CancelMode = CancelMode; Request->PendingMode = PendingMode; - KeAcquireSpinLockAtDpcLevel(&Context->RequestListLock); + KeAcquireSpinLock(&Context->RequestListLock, &OldIrql); + IoSetCancelRoutine(Irp, CancelRoutine); InsertTailList(&Context->RequestListHead, &Request->ListEntry); - KeReleaseSpinLockFromDpcLevel(&Context->RequestListLock); + KeReleaseSpinLock(&Context->RequestListLock, OldIrql); - IoSetCancelRoutine(Irp, CancelRoutine); + Status = STATUS_SUCCESS; + DPRINT1("Prepared for cancel\n"); - IoReleaseCancelSpinLock(OldIrql); - - DPRINT1("Prepared for cancel\n"); - - return STATUS_SUCCESS; + goto RETURN; } DPRINT1("Already cancelled\n"); - - IoReleaseCancelSpinLock(OldIrql); Irp->IoStatus.Status = STATUS_CANCELLED; Irp->IoStatus.Information = 0; - return STATUS_CANCELLED; +RETURN: + return Status; } /* implementation in testing */ -/* Does not dequeue the request, simply marks it as cancelled */ +/* TODO: get rid of datagram support, or merge datagram stuff into here */ VOID NTAPI CancelRequestRoutine( @@ -123,10 +121,11 @@ } TCP_CANCEL: + KeAcquireSpinLock(&Context->RequestListLock, &OldIrql); + Irp->IoStatus.Status = STATUS_CANCELLED; Irp->IoStatus.Information = 0; - - KeAcquireSpinLock(&Context->RequestListLock, &OldIrql); + IoSetCancelRoutine(Irp, NULL); AddressFile = Context->AddressFile; DPRINT1("AddressFile at %08x\n", AddressFile); @@ -145,6 +144,8 @@ AddressFile->lwip_tcp_pcb = NULL; } tcp_abort(Context->lwip_tcp_pcb); + InterlockedDecrement(&PcbCount); + DPRINT1("\n PCB Count: %d\n", PcbCount); Context->lwip_tcp_pcb = NULL; RemoveEntryList(Entry); @@ -162,6 +163,8 @@ AddressFile->lwip_tcp_pcb = NULL; } tcp_close(Context->lwip_tcp_pcb); + InterlockedDecrement(&PcbCount); + DPRINT1("\n PCB Count: %d\n", PcbCount); Context->lwip_tcp_pcb = NULL; RemoveEntryList(Entry); @@ -194,15 +197,9 @@ DPRINT1("DGRAM_CANCEL\n"); FINISH: - DPRINT1("\n Minor Function: %08x\n", IrpSp->MinorFunction); - - IoAcquireCancelSpinLock(&OldIrql); - IoSetCancelRoutine(Irp, NULL); - IoReleaseCancelSpinLock(OldIrql); - IoCompleteRequest(Irp, IO_NETWORK_INCREMENT); - DPRINT1("\n CancelRequestRoutine Exiting\n"); + DPRINT1("CancelRequestRoutine Exiting\n"); return; } @@ -212,6 +209,8 @@ { KeInitializeSpinLock(&AddressListLock); InitializeListHead(&AddressListHead); + + PcbCount = 0; } static @@ -238,7 +237,6 @@ PLIST_ENTRY Temp; PIRP Irp; KIRQL OldIrql; - KIRQL CancelIrql; NTSTATUS Status; @@ -293,10 +291,8 @@ { if (Irp->Cancel) { - IoAcquireCancelSpinLock(&CancelIrql); Irp->Cancel = FALSE; IoSetCancelRoutine(Irp, NULL); - IoReleaseCancelSpinLock(CancelIrql); } Irp->IoStatus.Status = Status; Irp->IoStatus.Information = 0; @@ -312,22 +308,24 @@ if (Context->lwip_tcp_pcb != AddressFile->lwip_tcp_pcb) { - tcp_close(Context->lwip_tcp_pcb); + tcp_abort(Context->lwip_tcp_pcb); + InterlockedDecrement(&PcbCount); + DPRINT1("\n PCB Count\n", PcbCount); } Context->lwip_tcp_pcb = NULL; Entry = Entry->Flink; } + AddressFile->lwip_tcp_pcb = NULL; + KeReleaseSpinLock(&AddressFile->ContextListLock, OldIrql); - - AddressFile->lwip_tcp_pcb = NULL; return; case TDI_CONNECTION_FILE : Context = (PTCP_CONTEXT)arg; DPRINT1("AddressFile at %08x\n", Context->AddressFile); - KeAcquireSpinLockAtDpcLevel(&Context->RequestListLock); + KeAcquireSpinLock(&Context->RequestListLock, &OldIrql); HeadNest = &Context->RequestListHead; EntryNest = HeadNest->Flink; @@ -339,10 +337,8 @@ { if (Irp->Cancel) { - IoAcquireCancelSpinLock(&CancelIrql); Irp->Cancel = FALSE; IoSetCancelRoutine(Irp, NULL); - IoReleaseCancelSpinLock(CancelIrql); } Irp->IoStatus.Status = Status; Irp->IoStatus.Information = 0; @@ -354,9 +350,10 @@ EntryNest = Temp; } - KeReleaseSpinLockFromDpcLevel(&Context->RequestListLock); + KeReleaseSpinLock(&Context->RequestListLock, OldIrql); - if (Context->lwip_tcp_pcb == Context->AddressFile->lwip_tcp_pcb); + if (Context->AddressFile && + (Context->lwip_tcp_pcb == Context->AddressFile->lwip_tcp_pcb)) { Context->AddressFile->lwip_tcp_pcb = NULL; } @@ -388,8 +385,7 @@ DPRINT1("Receiving datagram for addr 0x%08x on port %u.\n", ip4_addr_get_u32(addr), port); /* Block any cancellation that could occur */ - IoAcquireCancelSpinLock(&OldIrql); - KeAcquireSpinLockAtDpcLevel(&AddressFile->RequestLock); + KeAcquireSpinLock(&AddressFile->RequestLock, &OldIrql); ListEntry = AddressFile->RequestListHead.Flink; while (ListEntry != &AddressFile->RequestListHead) @@ -415,8 +411,7 @@ RemoveEntryList(&Request->ListEntry); Result = TRUE; - KeReleaseSpinLockFromDpcLevel(&AddressFile->RequestLock); - IoReleaseCancelSpinLock(OldIrql); + KeReleaseSpinLock(&AddressFile->RequestLock, OldIrql); /* In case of UDP, lwip provides a pbuf directly pointing to the data. * In other case, we must skip the IP header */ @@ -439,16 +434,14 @@ Irp->IoStatus.Status = STATUS_SUCCESS; IoCompleteRequest(Irp, IO_NETWORK_INCREMENT); - ExFreePoolWithTag(Request, TAG_TCP_REQUEST); + ExFreePoolWithTag(Request, TAG_DGRAM_REQST); /* Start again from the beginning */ - IoAcquireCancelSpinLock(&OldIrql); - KeAcquireSpinLockAtDpcLevel(&AddressFile->RequestLock); + KeAcquireSpinLock(&AddressFile->RequestLock, &OldIrql); } } - KeReleaseSpinLockFromDpcLevel(&AddressFile->RequestLock); - IoReleaseCancelSpinLock(OldIrql); + KeReleaseSpinLock(&AddressFile->RequestLock, OldIrql); return Result; } @@ -488,9 +481,8 @@ DPRINT1("lwIP TCP Accept Callback\n"); - IoAcquireCancelSpinLock(&OldIrql); AddressFile = (PADDRESS_FILE)arg; - KeAcquireSpinLockAtDpcLevel(&AddressFile->ContextListLock); + KeAcquireSpinLock(&AddressFile->ContextListLock, &OldIrql); Head = &AddressFile->ContextListHead; Entry = Head->Flink; @@ -499,10 +491,12 @@ Context = CONTAINING_RECORD(Entry, TCP_CONTEXT, ListEntry); if (Context->TcpState == TCP_STATE_LISTENING) { - KeReleaseSpinLockFromDpcLevel(&AddressFile->ContextListLock); - KeAcquireSpinLockAtDpcLevel(&Context->RequestListLock); + KeReleaseSpinLock(&AddressFile->ContextListLock, OldIrql); + KeAcquireSpinLock(&Context->RequestListLock, &OldIrql); Context->lwip_tcp_pcb = newpcb; + InterlockedIncrement(&PcbCount); + DPRINT1("\n PCB Count: %d\n", PcbCount); Context->TcpState = TCP_STATE_ACCEPTED; tcp_accepted(AddressFile->lwip_tcp_pcb); Head = &Context->RequestListHead; @@ -513,10 +507,11 @@ IrpSp = IoGetCurrentIrpStackLocation(Irp); if (!Irp || IrpSp->MinorFunction != TDI_LISTEN) { - DPRINT1("Received callback for canceld TDI_LISTEN\n"); + DPRINT1("Received accept callback for cancelled TDI_LISTEN\n"); RemoveEntryList(Entry); Entry = Entry->Flink; ExFreePoolWithTag(Request, TAG_TCP_REQUEST); + KeReleaseSpinLock(&Context->RequestListLock, OldIrql); return ERR_ABRT; } @@ -525,19 +520,17 @@ IoSetCancelRoutine(Irp, NULL); Irp->Cancel = FALSE; - IoReleaseCancelSpinLock(OldIrql); + KeReleaseSpinLock(&Context->RequestListLock, OldIrql); Irp->IoStatus.Status = STATUS_SUCCESS; IoCompleteRequest(Irp, IO_NETWORK_INCREMENT); - return ERR_OK; } Entry = Entry->Flink; } - KeReleaseSpinLockFromDpcLevel(&AddressFile->ContextListLock); - IoReleaseCancelSpinLock(OldIrql); - + KeReleaseSpinLock(&AddressFile->ContextListLock, OldIrql); + DPRINT1("Did not find a valid TDI_LISTEN\n"); return ERR_ABRT; } @@ -568,8 +561,7 @@ DPRINT1("lwIP TCP Sent Callback\n"); Context = (PTCP_CONTEXT)arg; - IoAcquireCancelSpinLock(&OldIrql); - KeAcquireSpinLockAtDpcLevel(&Context->RequestListLock); + KeAcquireSpinLock(&Context->RequestListLock, &OldIrql); Head = &Context->RequestListHead; Entry = Head->Flink; @@ -584,18 +576,18 @@ } Entry = Entry->Flink; } + DPRINT1("Matching TDI_SEND request not found\n"); - KeReleaseSpinLockFromDpcLevel(&Context->RequestListLock); - IoReleaseCancelSpinLock(OldIrql); + KeReleaseSpinLock(&Context->RequestListLock, OldIrql); return ERR_ABRT; + FOUND: if (!Irp) { DPRINT1("Callback on cancelled IRP\n"); RemoveEntryList(&Request->ListEntry); ExFreePoolWithTag(Request, TAG_TCP_REQUEST); - KeReleaseSpinLockFromDpcLevel(&Context->RequestListLock); - IoReleaseCancelSpinLock(OldIrql); + KeReleaseSpinLock(&Context->RequestListLock, OldIrql); return ERR_ABRT; } @@ -630,13 +622,17 @@ IrpSp = IoGetCurrentIrpStackLocation(Irp); RequestInfo = (PTDI_REQUEST_KERNEL_SEND)&IrpSp->Parameters; lwip_err = tcp_write(Context->lwip_tcp_pcb, Buffer, RequestInfo->SendLength, 0); + PrepareIrpForCancel( + Irp, + CancelRequestRoutine, + TCP_REQUEST_CANCEL_MODE_PRESERVE, + TCP_REQUEST_PENDING_SEND); break; } Entry = Entry->Flink; } - KeReleaseSpinLockFromDpcLevel(&Context->RequestListLock); - IoReleaseCancelSpinLock(OldIrql); + KeReleaseSpinLock(&Context->RequestListLock, OldIrql); IoCompleteRequest(Irp, IO_NETWORK_INCREMENT); @@ -657,8 +653,6 @@ PNDIS_BUFFER Buffer; PTCP_CONTEXT Context; PTCP_REQUEST Request; - PIO_STACK_LOCATION IrpSp; - PTDI_REQUEST_KERNEL_RECEIVE ReceiveInfo; KIRQL OldIrql; INT CopiedLength; @@ -669,172 +663,122 @@ PLIST_ENTRY Head; PLIST_ENTRY Entry; NTSTATUS Status; + err_t lwip_err; DPRINT1("lwIP TCP Receive Callback\n"); - if (err != ERR_OK) + /* This error is currently unimplemented in lwIP */ +/* if (err != ERR_OK) { DPRINT1("lwIP Error %d\n", err); return ERR_ABRT; - } - - IoAcquireCancelSpinLock(&OldIrql); + }*/ Context = (PTCP_CONTEXT)arg; DPRINT1("Context at %08x\n", Context); DPRINT1("AddressFile at %08x\n", Context->AddressFile); - if (!(Context->TcpState & TCP_STATE_RECEIVING)) - { + if (!(Context->TcpState & TCP_STATE_RECEIVING)) { DPRINT1("Receive callback on connection that is not currently receiving\n"); - IoReleaseCancelSpinLock(OldIrql); return ERR_ARG; } - KeAcquireSpinLockAtDpcLevel(&Context->RequestListLock); + KeAcquireSpinLock(&Context->RequestListLock, &OldIrql); Head = &Context->RequestListHead; Entry = Head->Flink; Irp = NULL; - while (Entry != Head) - { + DPRINT1("Entering Loop\n"); + while (Entry != Head) { + DPRINT1("Fetching Request\n"); Request = CONTAINING_RECORD(Entry, TCP_REQUEST, ListEntry); - if (!Request->PendingIrp) - { + DPRINT1("Request Fetched. Points to %08x\n", Request); + if (!Request->PendingIrp) { + DPRINT1("IRP pointer dereferenced\n"); RemoveEntryList(Entry); + DPRINT1("Entry removed\n"); Entry = Entry->Flink; ExFreePoolWithTag(Request, TAG_TCP_REQUEST); continue; } - if (Request->PendingMode == TCP_REQUEST_PENDING_RECEIVE) - { + if (Request->PendingMode == TCP_REQUEST_PENDING_RECEIVE) { Irp = Request->PendingIrp; Entry = Entry->Flink; break; } Entry = Entry->Flink; } - if (!Irp) - { + if (!Irp) { DPRINT1("Receive callback on cancelled IRP\n"); - KeReleaseSpinLockFromDpcLevel(&Context->RequestListLock); - IoReleaseCancelSpinLock(OldIrql); + KeReleaseSpinLock(&Context->RequestListLock, OldIrql); return ERR_ABRT; } + + /* IRP found, clear out the CANCEL flag */ DPRINT1("IRP at %08x\n", Irp); - - IrpSp = IoGetCurrentIrpStackLocation(Irp); - DPRINT1("IrpSp: %08x\n", IrpSp); - IoSetCancelRoutine(Irp, NULL); Irp->Cancel = FALSE; - if (Context->lwip_tcp_pcb != tpcb) - { + if (Context->lwip_tcp_pcb != tpcb) { DPRINT1("Receive tcp_pcb mismatch\n"); tcp_abort(tpcb); + InterlockedDecrement(&PcbCount); + DPRINT1("\n PCB Count\n", PcbCount); - RemoveEntryList(&Request->ListEntry); - ExFreePoolWithTag(Request, TAG_TCP_REQUEST); - - KeReleaseSpinLockFromDpcLevel(&Context->RequestListLock); - IoReleaseCancelSpinLock(OldIrql); - - Irp->IoStatus.Status = STATUS_UNSUCCESSFUL; - Irp->IoStatus.Information = 0; - IoCompleteRequest(Irp, IO_NETWORK_INCREMENT); - - return ERR_ABRT; - } - if (!(Context->TcpState & (TCP_STATE_RECEIVING|TCP_STATE_ACCEPTED|TCP_STATE_CONNECTED))) - { + // TODO: better return code + Status = STATUS_UNSUCCESSFUL; + CopiedLength = 0; + lwip_err = ERR_ABRT; + goto BAD; + } + if (!(Context->TcpState & (TCP_STATE_RECEIVING|TCP_STATE_ACCEPTED|TCP_STATE_CONNECTED))) { DPRINT1("Invalid TCP state: %08x\n", Context->TcpState); - - KeReleaseSpinLockFromDpcLevel(&Context->RequestListLock); - IoReleaseCancelSpinLock(OldIrql); - - return ERR_ABRT; + // TODO: better return code + Status = STATUS_UNSUCCESSFUL; + lwip_err = ERR_ABRT; + goto BAD; } Buffer = (PNDIS_BUFFER)Irp->MdlAddress; - ReceiveInfo = (PTDI_REQUEST_KERNEL_RECEIVE)&IrpSp->Parameters; - - DPRINT1("NDIS Buffer: %08x\n", Buffer); - - if (Buffer->MdlFlags & (MDL_MAPPED_TO_SYSTEM_VA|MDL_SOURCE_IS_NONPAGED_POOL)) - { - DPRINT1("Option 0\n"); - CurrentDestLocation = Buffer->MappedSystemVa; - } - else - { - DPRINT1("Option 1\n"); - CurrentDestLocation = MmMapLockedPages(Buffer, KernelMode); - } -// CurrentDestLocation = MmGetSystemAddressForMdl(Buffer); - RemainingDestBytes = Buffer->ByteCount; -// NdisQueryBuffer(Buffer, &CurrentDestLocation, &RemainingDestBytes); - - if (p) - { - DPRINT1("\n PTDI_REQUEST_KERNEL_RECEIVE->ReceiveLength = %d\n NDIS_BUFFER length = %d\n pbuf->tot_len = %d\n", - ReceiveInfo->ReceiveLength, - RemainingDestBytes, - p->tot_len); - } - else - { - DPRINT1("\n The pbuf pointer p is NULL\n"); - } - - if (!p) - { + + NdisQueryBuffer(Buffer, &CurrentDestLocation, &RemainingDestBytes); + + if (!p) { + /* I believe this means the pcb was closed */ + DPRINT1("NULL pbuf pointer\n"); CopiedLength = 0; Status = STATUS_ADDRESS_CLOSED; goto BAD; } - if (RemainingDestBytes <= p->len) - { + if (RemainingDestBytes <= p->len) { RtlCopyMemory(CurrentDestLocation, p->payload, RemainingDestBytes); CopiedLength = RemainingDestBytes; Status = STATUS_SUCCESS; goto RETURN; - } - else - { + } else { CopiedLength = 0; RemainingSrceBytes = p->len; CurrentSrceLocation = p->payload; - while (1) - { - if (RemainingSrceBytes < RemainingDestBytes) - { + while (1) { + if (RemainingSrceBytes < RemainingDestBytes) { RtlCopyMemory(CurrentDestLocation, CurrentSrceLocation, RemainingSrceBytes); CopiedLength += p->len; RemainingDestBytes -= p->len; CurrentDestLocation += p->len; - if (p->next) - { + if (p->next) { RemainingSrceBytes = p->next->len; CurrentSrceLocation = p->next->payload; - pbuf_free(p); p = p->next; - continue; - } - else - { + } else { Status = STATUS_SUCCESS; goto RETURN; } - } - else - { + } else { RtlCopyMemory(CurrentDestLocation, CurrentSrceLocation, RemainingDestBytes); CopiedLength += RemainingDestBytes; - Status = STATUS_SUCCESS; goto RETURN; } @@ -845,29 +789,26 @@ DPRINT1("Receive CopiedLength = %d\n", CopiedLength); tcp_recved(tpcb, CopiedLength); - - while (Entry != Head) - { + while (Entry != Head) { Request = CONTAINING_RECORD(Entry, TCP_REQUEST, ListEntry); - if (Request->PendingMode == TCP_REQUEST_PENDING_RECEIVE) - { + if (Request->PendingMode == TCP_REQUEST_PENDING_RECEIVE) { tcp_recv(tpcb, lwip_tcp_receive_callback); break; } } + lwip_err = ERR_OK; BAD: RemoveEntryList(&Request->ListEntry); ExFreePoolWithTag(Request, TAG_TCP_REQUEST); - KeReleaseSpinLockFromDpcLevel(&Context->RequestListLock); - IoReleaseCancelSpinLock(OldIrql); + KeReleaseSpinLock(&Context->RequestListLock, OldIrql); Irp->IoStatus.Status = Status; Irp->IoStatus.Information = CopiedLength; IoCompleteRequest(Irp, IO_NETWORK_INCREMENT); - return ERR_OK; + return lwip_err; } static @@ -929,17 +870,18 @@ KIRQL OldIrql; PLIST_ENTRY Head; PLIST_ENTRY Entry; + err_t lwip_err; DPRINT1("lwIP TCP Connected Callback\n"); - IoAcquireCancelSpinLock(&OldIrql); - Context = (PTCP_CONTEXT)arg; + KeAcquireSpinLock(&Context->RequestListLock, &OldIrql); Head = &Context->RequestListHead; Entry = Head->Flink; if (Head == Entry) { DPRINT1("Request list is empty\n"); + KeReleaseSpinLock(&Context->RequestListLock, OldIrql); return ERR_ARG; } Request = CONTAINING_RECORD(Entry, TCP_REQUEST, ListEntry); @@ -947,45 +889,37 @@ if (!Irp) { DPRINT1("Callback on cancelled IRP\n"); - - KeAcquireSpinLockAtDpcLevel(&Request->Context->RequestListLock); RemoveEntryList(&Request->ListEntry); ExFreePoolWithTag(Request, TAG_TCP_REQUEST); - KeReleaseSpinLockFromDpcLevel(&Request->Context->RequestListLock); - IoReleaseCancelSpinLock(OldIrql); + KeReleaseSpinLock(&Request->Context->RequestListLock, OldIrql); return ERR_ABRT; } - - KeAcquireSpinLockAtDpcLevel(&Context->RequestListLock); - - if (Context->TcpState != TCP_STATE_CONNECTING) - { - DPRINT1("Invalid TCP state: %d\n", Context->TcpState); - - KeReleaseSpinLockFromDpcLevel(&Context->RequestListLock); - IoReleaseCancelSpinLock(OldIrql); - - return ERR_ABRT; - } - - Context->TcpState = TCP_STATE_CONNECTED; - IoSetCancelRoutine(Irp, NULL); Irp->Cancel = FALSE; + if (Context->TcpState != TCP_STATE_CONNECTING) + { + DPRINT1("Invalid TCP state: %d\n", Context->TcpState); + lwip_err = ERR_ABRT; + goto FINISH; + } + + Context->TcpState = TCP_STATE_CONNECTED; + lwip_err = ERR_OK; + +FINISH: RemoveEntryList(&Request->ListEntry); ExFreePoolWithTag(Request, TAG_TCP_REQUEST); - KeReleaseSpinLockFromDpcLevel(&Context->RequestListLock); - IoReleaseCancelSpinLock(OldIrql); + KeReleaseSpinLock(&Context->RequestListLock, OldIrql); Irp->IoStatus.Status = STATUS_SUCCESS; IoCompleteRequest(Irp, IO_NETWORK_INCREMENT); - return ERR_OK; + return lwip_err; } /* implementation in testing */ @@ -1006,6 +940,8 @@ /* See if this port is already taken, and find a free one if needed. */ KeAcquireSpinLock(&AddressListLock, &OldIrql); + DPRINT1("Search through used ports\n"); + ListEntry = AddressListHead.Flink; while (ListEntry != &AddressListHead) { @@ -1046,6 +982,8 @@ ListEntry = ListEntry->Flink; } + DPRINT1("Find local interface for address\n"); + if (!AddrIsUnspecified(Address)) { /* Find the local interface for this address */ @@ -1071,6 +1009,8 @@ } } + DPRINT1("Allocate address file\n"); + /* Allocate our new address file */ AddressFile = ExAllocatePoolWithTag(NonPagedPool, sizeof(*AddressFile), TAG_ADDRESS_FILE); if (!AddressFile) @@ -1091,6 +1031,8 @@ KeInitializeSpinLock(&AddressFile->RequestLock); InitializeListHead(&AddressFile->RequestListHead); + DPRINT1("Protocol-dependent operations\n"); + /* Give it an entity ID and open a PCB if needed. */ switch (Protocol) { @@ -1101,6 +1043,8 @@ InsertEntityInstance(CO_TL_ENTITY, &AddressFile->Instance); AddressFile->ContextCount = 0; AddressFile->lwip_tcp_pcb = tcp_new(); + InterlockedIncrement(&PcbCount); + DPRINT1("\n PCB Count: %d\n", PcbCount); tcp_arg(AddressFile->lwip_tcp_pcb, AddressFile); tcp_err(AddressFile->lwip_tcp_pcb, lwip_tcp_err_callback); break; @@ -1140,6 +1084,8 @@ } } + DPRINT1("Insert into address list\n"); + /* Insert it into the list. */ InsertTailList(&AddressListHead, &AddressFile->ListEntry); KeReleaseSpinLock(&AddressListLock, OldIrql); @@ -1225,7 +1171,17 @@ } if (AddressFile->lwip_tcp_pcb) { - lwip_err = tcp_close(AddressFile->lwip_tcp_pcb); + if (AddressFile->lwip_tcp_pcb->state == LISTEN) + { + lwip_err = tcp_close(AddressFile->lwip_tcp_pcb); + } + else + { + tcp_abort(AddressFile->lwip_tcp_pcb); + lwip_err = ERR_OK; + } + InterlockedDecrement(&PcbCount); + DPRINT1("\n PCB Count: %d\n", PcbCount); if (lwip_err != ERR_OK) { DPRINT1("lwIP tcp_close error: %d", lwip_err); @@ -1283,7 +1239,17 @@ if (Context->lwip_tcp_pcb) { - lwip_err = tcp_close(Context->lwip_tcp_pcb); + if (Context->TcpState == TCP_STATE_LISTENING) + { + lwip_err = tcp_close(Context->lwip_tcp_pcb); + } + else + { + tcp_abort(Context->lwip_tcp_pcb); + lwip_err = ERR_OK; + } + InterlockedDecrement(&PcbCount); + DPRINT1("\n PCB Count: %d\n", PcbCount); if (lwip_err != ERR_OK) { DPRINT1("lwIP tcp_close error: %d", lwip_err); @@ -1384,14 +1350,15 @@ NT_ASSERT(ListEntry != &AddressFile->RequestListHead); RemoveEntryList(&Request->ListEntry); - KeReleaseSpinLock(&AddressFile->RequestLock, OldIrql); Irp->IoStatus.Status = STATUS_CANCELLED; Irp->IoStatus.Information = 0; + + KeReleaseSpinLock(&AddressFile->RequestLock, OldIrql); IoCompleteRequest(Irp, IO_NETWORK_INCREMENT); - ExFreePoolWithTag(Request, TAG_TCP_REQUEST); + ExFreePoolWithTag(Request, TAG_DGRAM_REQST); } /* implementation in testing */ @@ -1625,14 +1592,13 @@ default : { DPRINT1("lwIP unexpected error\n"); - Status = STATUS_NOT_IMPLEMENTED; + // TODO: better return code + Status = STATUS_UNSUCCESSFUL; goto LEAVE; } } } } - - DPRINT1("TcpIpAssociateAddress Exiting\n"); Context->TcpState = TCP_STATE_BOUND; @@ -1679,14 +1645,12 @@ return STATUS_INVALID_ADDRESS; } - KeAcquireSpinLock(&AddressFile->ContextListLock, &OldIrql); - if (AddressFile->lwip_tcp_pcb == Context->lwip_tcp_pcb) { Context->lwip_tcp_pcb = NULL; } - KeAcquireSpinLockAtDpcLevel(&Context->RequestListLock); + KeAcquireSpinLock(&Context->RequestListLock, &OldIrql); if (!(IsListEmpty(&Context->RequestListHead))) { DPRINT1("Disassociating context with outstanding requests\n"); @@ -1706,12 +1670,12 @@ } } } - KeReleaseSpinLockFromDpcLevel(&Context->RequestListLock); - + KeReleaseSpinLock(&Context->RequestListLock, OldIrql); + + KeAcquireSpinLock(&AddressFile->ContextListLock, &OldIrql); RemoveEntryList(&Context->ListEntry); AddressFile->ContextCount--; Context->AddressFile = NULL; - KeReleaseSpinLock(&AddressFile->ContextListLock, OldIrql); if (AddressFile->ContextCount == 0) @@ -1766,6 +1730,7 @@ either INVALID_ADDRESS or NO_MEMORY if SO_REUSE is enabled in lwip options */ DPRINT1("lwip tcp_listen error\n"); + KeReleaseSpinLock(&AddressFile->ContextListLock, OldIrql); return STATUS_INVALID_ADDRESS; } tcp_arg(lpcb, AddressFile); @@ -1945,7 +1910,6 @@ RECEIVE_DATAGRAM_REQUEST* Request = NULL; PTDI_REQUEST_KERNEL_RECEIVEDG RequestInfo; NTSTATUS Status; - KIRQL OldIrql; /* Check this is really an address file */ if ((ULONG_PTR)IrpSp->FileObject->FsContext2 != TDI_TRANSPORT_ADDRESS_FILE) @@ -1966,7 +1930,7 @@ } /* Queue the request */ - Request = ExAllocatePoolWithTag(NonPagedPool, sizeof(*Request), TAG_TCP_REQUEST); + Request = ExAllocatePoolWithTag(NonPagedPool, sizeof(*Request), TAG_DGRAM_REQST); if (!Request) { Status = STATUS_INSUFFICIENT_RESOURCES; @@ -1997,14 +1961,10 @@ Request->ReturnInfo = RequestInfo->ReturnDatagramInformation; - /* Prepare for potential cancellation */ - IoAcquireCancelSpinLock(&OldIrql); - IoSetCancelRoutine(Irp, CancelReceiveDatagram); - IoReleaseCancelSpinLock(OldIrql); - /* Mark pending */ Irp->IoStatus.Status = STATUS_PENDING; IoMarkIrpPending(Irp); + IoSetCancelRoutine(Irp, CancelReceiveDatagram); /* We're ready to go */ ExInterlockedInsertTailList( @@ -2016,7 +1976,7 @@ Failure: if (Request) - ExFreePoolWithTag(Request, TAG_TCP_REQUEST); + ExFreePoolWithTag(Request, TAG_DGRAM_REQST); Irp->IoStatus.Status = Status; IoCompleteRequest(Irp, IO_NETWORK_INCREMENT); return Status; Modified: branches/GSoC_2016/lwIP-tcpip/drivers/network/tcpip/main.c URL: http://svn.reactos.org/svn/reactos/branches/GSoC_2016/lwIP-tcpip/drivers/network/tcpip/main.c?rev=71835&r1=71834&r2=71835&view=diff ============================================================================== --- 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] Wed Jul 6 20:53:31 2016 @@ -269,7 +269,9 @@ DPRINT1("\nPTA_IP_ADDRESS dump before\n %08x %08x %08x %08x\n %08x %08x %08x %08x\n", temp[7], temp[6], temp[5], temp[4], temp[3], temp[2], temp[1], temp[0]);*/ + DPRINT1("Call into TcpIpCreateAddress\n"); Status = TcpIpCreateAddress(Irp, &Address->Address[0].Address[0], Protocol); + DPRINT1("Returned from TcpIpCreateAddress\n"); if (Status != STATUS_SUCCESS) { goto Quickie;