Author: zhu Date: Tue Jun 14 19:43:03 2016 New Revision: 71637
URL: http://svn.reactos.org/svn/reactos?rev=71637&view=rev Log: Reworked message passing. Created struct TCP_CONTEXT. Moved lwip_tcp_pcb from ADDRESS_FILE to TCP_CONTEXT. Successfully binding and handshaking between server and client, but address destruction is still faulty and causes crashes.
Modified: branches/GSoC_2016/lwIP/drivers/network/tcpip/address.c branches/GSoC_2016/lwIP/drivers/network/tcpip/address.h 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/t... ============================================================================== --- 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] Tue Jun 14 19:43:03 2016 @@ -233,7 +233,22 @@ ADDRESS_FILE *AddressFile; LIST_ENTRY* ListEntry; KIRQL OldIrql; + + ULONG *temp; + USHORT Port = 1; + + temp = (ULONG*)Address; + DPRINT1("\n TcpIpCreateAddress Input Dump\n %08x %08x %08x %08x\n", + temp[3], temp[2], + temp[1], temp[0]); + + temp = IrpSp->FileObject->FsContext; + if (temp) { + DPRINT1("\n IrpSp Dump\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]); + }
/* See if this port is already taken, and find a free one if needed. */ KeAcquireSpinLock(&AddressListLock, &OldIrql); @@ -327,9 +342,17 @@ case IPPROTO_TCP: { ip_addr_t IpAddr; - ip4_addr_set_u32(&IpAddr, AddressFile->Address.in_addr); + ip4_addr_set_u32(&IpAddr, AddressFile->Address.in_addr); InsertEntityInstance(CO_TL_ENTITY, &AddressFile->Instance); - AddressFile->lwip_tcp_pcb = tcp_new(); + AddressFile->ConnectionContext = NULL; +/* tcp_bind(AddressFile->lwip_tcp_pcb, &IpAddr, lwip_ntohs(AddressFile->Address.sin_port)); + DPRINT1("\n Attempt Bind to Address\n Port: %04x\n Address: %08x\n", + AddressFile->Address.sin_port, + IpAddr);*/ + temp = (ULONG*)&AddressFile->Address; + DPRINT1("\n Dump: %08x %08x\n", + temp[1], + temp[0]); break; } case IPPROTO_UDP: @@ -378,6 +401,37 @@ }
NTSTATUS +TcpIpCreateContext( + _Inout_ PIRP Irp, + _In_ IPPROTO Protocol +) +{ + PIO_STACK_LOCATION IrpSp; + PTCP_CONTEXT Context; + + Context = ExAllocatePoolWithTag(NonPagedPool, sizeof(*Context), TAG_ADDRESS_FILE); + + if (Protocol != IPPROTO_TCP) + { + DPRINT1("Creating connection context for non-TCP protocoln"); + return STATUS_INVALID_PARAMETER; + } + Context->Protocol = Protocol; + Context->lwip_tcp_pcb = tcp_new(); + if (Context->lwip_tcp_pcb == NULL) + { + return STATUS_NO_MEMORY; + } + + IrpSp = IoGetCurrentIrpStackLocation(Irp); + + IrpSp->FileObject->FsContext = (PVOID)Context; + IrpSp->FileObject->FsContext2 = (PVOID)TDI_CONNECTION_FILE; + + return STATUS_SUCCESS; +} + +NTSTATUS TcpIpCloseAddress( _Inout_ ADDRESS_FILE* AddressFile ) @@ -397,7 +451,12 @@ /* remove the lwip pcb */ if (AddressFile->Protocol == IPPROTO_UDP) udp_remove(AddressFile->lwip_udp_pcb); - else if (AddressFile->Protocol != IPPROTO_TCP) + else if (AddressFile->Protocol == IPPROTO_TCP && AddressFile->ConnectionContext) + { + tcp_close(AddressFile->ConnectionContext->lwip_tcp_pcb); + ExFreePoolWithTag(AddressFile->ConnectionContext, TAG_ADDRESS_FILE); + } + else raw_remove(AddressFile->lwip_raw_pcb);
/* Remove from the list and free the structure */ @@ -407,7 +466,6 @@ RemoveEntityInstance(&AddressFile->Instance);
ExFreePoolWithTag(AddressFile, TAG_ADDRESS_FILE); -
return STATUS_SUCCESS; } @@ -525,10 +583,10 @@ SocketAddressInRemote->sin_addr.s_addr, SocketAddressInRemote->sin_port); DPRINT1("\n Local Address\n Address: %08x\n Port: %04x\n", - AddressFile->lwip_tcp_pcb->local_ip, - AddressFile->lwip_tcp_pcb->local_port); - - lwip_err = tcp_connect(AddressFile->lwip_tcp_pcb, + AddressFile->ConnectionContext->lwip_tcp_pcb->local_ip, + AddressFile->ConnectionContext->lwip_tcp_pcb->local_port); + + lwip_err = tcp_connect(AddressFile->ConnectionContext->lwip_tcp_pcb, (ip_addr_t *)&SocketAddressInRemote->sin_addr.s_addr, SocketAddressInRemote->sin_port, lwip_tcp_Connected_callback); @@ -566,7 +624,7 @@ case (ERR_OK) : { DPRINT1("lwip ERR_OK\n"); - tcp_arg(AddressFile->lwip_tcp_pcb, Irp); + tcp_arg(AddressFile->ConnectionContext->lwip_tcp_pcb, Irp); break; } default : @@ -586,8 +644,8 @@ _Inout_ PIRP Irp) { PIO_STACK_LOCATION IrpSp; - ADDRESS_FILE *AddressFile; - ADDRESS_FILE *BindTo; + PTCP_CONTEXT Context; + PADDRESS_FILE AddressFile; PTDI_REQUEST_KERNEL_ASSOCIATE RequestInfo; PFILE_OBJECT FileObject; @@ -596,21 +654,15 @@ IrpSp = IoGetCurrentIrpStackLocation(Irp); - /* Check this is really an address file */ - if ((ULONG_PTR)IrpSp->FileObject->FsContext2 != TDI_TRANSPORT_ADDRESS_FILE) - { - return STATUS_FILE_INVALID; - } + if (IrpSp->FileObject->FsContext2 != (PVOID)TDI_CONNECTION_FILE) + { + DPRINT1("Associating something that is not a TDI_CONNECTION_FILE\n"); + Status = STATUS_INVALID_PARAMETER; + goto LEAVE; + } + Context = IrpSp->FileObject->FsContext; /* Get address file */ - AddressFile = IrpSp->FileObject->FsContext; - - if (AddressFile->Protocol != IPPROTO_TCP) - { - DPRINT1("Received TDI_ASSOCIATE_ADDRESS for a non-TCP protocol\n"); - return STATUS_INVALID_ADDRESS; - } - RequestInfo = (PTDI_REQUEST_KERNEL_ASSOCIATE)&IrpSp->Parameters; Status = ObReferenceObjectByHandle( @@ -632,59 +684,77 @@ ObDereferenceObject(FileObject); return STATUS_INVALID_PARAMETER; } - BindTo = FileObject->FsContext; - if (BindTo->Protocol != IPPROTO_TCP) + AddressFile = FileObject->FsContext; + if (AddressFile->Protocol != IPPROTO_TCP) { DPRINT1("TCP socket association with non-TCP handle\n"); ObDereferenceObject(FileObject); return STATUS_INVALID_PARAMETER; }
+ if (AddressFile->Address.in_addr == 0) + { + AddressFile->Address.in_addr = 0x0100007f; + } + DPRINT1("\n TDI Address\n Port: %04x\n Address: %08x\n", - BindTo->Address.sin_port, - BindTo->Address.in_addr); + AddressFile->Address.sin_port, + AddressFile->Address.in_addr); /* Finally calling into lwip to perform socket bind */ lwip_err = tcp_bind( - AddressFile->lwip_tcp_pcb, - (ip_addr_t *)&BindTo->Address.in_addr, - BindTo->Address.sin_port); - + Context->lwip_tcp_pcb, + (ip_addr_t *)&AddressFile->Address.in_addr, + AddressFile->Address.sin_port); DPRINT1("lwip error %d\n TCP PCB:\n Local Address: %08x\n Local Port: %04x\n Remote Address: %08x\n Remote Port: %04x\n", lwip_err, - AddressFile->lwip_tcp_pcb->local_ip, - AddressFile->lwip_tcp_pcb->local_port, - AddressFile->lwip_tcp_pcb->remote_ip, - AddressFile->lwip_tcp_pcb->remote_port); + Context->lwip_tcp_pcb->local_ip, + Context->lwip_tcp_pcb->local_port, + Context->lwip_tcp_pcb->remote_ip, + Context->lwip_tcp_pcb->remote_port); + + IrpSp->FileObject->FsContext = AddressFile; + IrpSp->FileObject->FsContext2 = (PVOID)TDI_TRANSPORT_ADDRESS_FILE; + if (lwip_err != ERR_OK) { switch (lwip_err) { case (ERR_BUF) : { - /* Not actually sure which error I should return here - ERR_BUF means the port is already taken - fix when I figure out how to use NDIS errors */ - Status = STATUS_ADDRESS_ALREADY_EXISTS; + DPRINT1("lwIP ERR_BUFF\n"); + Status = STATUS_NO_MEMORY; goto LEAVE; } case (ERR_VAL) : { + DPRINT1("lwIP ERR_VAL\n"); Status = STATUS_INVALID_PARAMETER; goto LEAVE; } case (ERR_USE) : { + DPRINT1("lwIP ERR_USE\n"); Status = STATUS_ADDRESS_ALREADY_EXISTS; goto LEAVE; } + case (ERR_OK) : + { + DPRINT1("lwIP ERR_OK\n"); + break; + } default : { - break; + DPRINT1("lwIP unexpected error\n"); + Status = STATUS_NOT_IMPLEMENTED; + goto LEAVE; } } } - ip_set_option(AddressFile->lwip_tcp_pcb, SOF_BROADCAST); + ip_set_option(Context->lwip_tcp_pcb, SOF_BROADCAST); + + Context->AddressFile = AddressFile; + AddressFile->ConnectionContext = Context; Status = STATUS_SUCCESS; LEAVE: @@ -700,8 +770,6 @@ PIO_STACK_LOCATION IrpSp; ADDRESS_FILE *AddressFile; - err_t lwip_err; - IrpSp = IoGetCurrentIrpStackLocation(Irp); if ((ULONG)IrpSp->FileObject->FsContext2 != TDI_TRANSPORT_ADDRESS_FILE) { @@ -716,17 +784,7 @@ return STATUS_INVALID_ADDRESS; } - lwip_err = tcp_close(AddressFile->lwip_tcp_pcb); - switch (lwip_err) - { - case ERR_MEM : - return STATUS_NO_MEMORY; - case ERR_OK : - break; - default : - DPRINT1("Unexpected lwIP error\n"); - return STATUS_NOT_IMPLEMENTED; - } + /* NO-OP because we need the address to deallocate the port when the connection closes */ return STATUS_SUCCESS; } @@ -737,7 +795,8 @@ _Inout_ PIRP Irp) { PIO_STACK_LOCATION IrpSp; - ADDRESS_FILE *AddressFile; + PADDRESS_FILE AddressFile; + PTCP_CONTEXT ConnectionContext; struct tcp_pcb *lpcb; @@ -746,19 +805,21 @@ /* Check this is really an address file */ if ((ULONG_PTR)IrpSp->FileObject->FsContext2 != TDI_TRANSPORT_ADDRESS_FILE) { + DPRINT1("Not an address file\n"); return STATUS_FILE_INVALID; } /* Get address file */ AddressFile = IrpSp->FileObject->FsContext; - if (AddressFile->Protocol != IPPROTO_TCP) + ConnectionContext = AddressFile->ConnectionContext; + if (ConnectionContext->Protocol != IPPROTO_TCP) { DPRINT1("Received TDI_LISTEN for a non-TCP protocol\n"); return STATUS_INVALID_ADDRESS; } /* Call down into lwip to initiate a listen */ - lpcb = tcp_listen(AddressFile->lwip_tcp_pcb); + lpcb = tcp_listen(ConnectionContext->lwip_tcp_pcb); DPRINT1("lwip tcp_listen returned\n"); if (lpcb == NULL) { @@ -770,11 +831,11 @@ } else { - AddressFile->lwip_tcp_pcb = lpcb; - } - - tcp_accept(AddressFile->lwip_tcp_pcb, lwip_tcp_accept_callback); - tcp_arg(AddressFile->lwip_tcp_pcb, Irp); + ConnectionContext->lwip_tcp_pcb = lpcb; + } + + tcp_accept(ConnectionContext->lwip_tcp_pcb, lwip_tcp_accept_callback); + tcp_arg(ConnectionContext->lwip_tcp_pcb, Irp); return STATUS_PENDING; }
Modified: branches/GSoC_2016/lwIP/drivers/network/tcpip/address.h URL: http://svn.reactos.org/svn/reactos/branches/GSoC_2016/lwIP/drivers/network/t... ============================================================================== --- branches/GSoC_2016/lwIP/drivers/network/tcpip/address.h [iso-8859-1] (original) +++ branches/GSoC_2016/lwIP/drivers/network/tcpip/address.h [iso-8859-1] Tue Jun 14 19:43:03 2016 @@ -1,8 +1,7 @@
#pragma once
-typedef struct -{ +typedef struct _ADDRESS_FILE { LIST_ENTRY ListEntry; LONG RefCount; IPPROTO Protocol; @@ -14,9 +13,19 @@ { struct raw_pcb* lwip_raw_pcb; struct udp_pcb* lwip_udp_pcb; - struct tcp_pcb* lwip_tcp_pcb; + struct _TCP_CONTEXT *ConnectionContext; }; -} ADDRESS_FILE; +} ADDRESS_FILE, *PADDRESS_FILE; + +typedef struct _TCP_CONTEXT { + ADDRESS_FILE *AddressFile; + LIST_ENTRY ListEntry; + IPPROTO Protocol; + LONG RefCount; + KSPIN_LOCK Lock; + KIRQL OldIrql; + struct tcp_pcb* lwip_tcp_pcb; +} TCP_CONTEXT, *PTCP_CONTEXT;
void TcpIpInitializeAddresses(void); @@ -26,6 +35,12 @@ _Inout_ PIRP Irp, _In_ PTDI_ADDRESS_IP Address, _In_ IPPROTO Protocol +); + +NTSTATUS +TcpIpCreateContext( + _Inout_ PIRP Irp, + _In_ IPPROTO Protocol );
NTSTATUS
Modified: branches/GSoC_2016/lwIP/drivers/network/tcpip/main.c URL: http://svn.reactos.org/svn/reactos/branches/GSoC_2016/lwIP/drivers/network/t... ============================================================================== --- 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] Tue Jun 14 19:43:03 2016 @@ -210,8 +210,12 @@ NTSTATUS Status; PFILE_FULL_EA_INFORMATION FileInfo; IPPROTO Protocol; +// ADDRESS_FILE *AddressFile; + + ULONG *temp; + PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp); - + /* Grab the info describing the file */ FileInfo = Irp->AssociatedIrp.SystemBuffer;
@@ -223,13 +227,15 @@ Status = STATUS_SUCCESS; goto Quickie; } - + /* Validate it */ switch (FileInfo->EaNameLength) { case TDI_TRANSPORT_ADDRESS_LENGTH: { PTA_IP_ADDRESS Address; + + DPRINT1("TCPIP Create Transport Address\n");
if (strncmp(&FileInfo->EaName[0], TdiTransportAddress, TDI_TRANSPORT_ADDRESS_LENGTH) != 0) { @@ -259,20 +265,37 @@ }
/* All good. */ - Status = TcpIpCreateAddress(Irp, &Address->Address[0].Address[0], Protocol); + temp = (ULONG*)Address; + 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]); + Status = TcpIpCreateAddress(Irp, &Address->Address[0].Address[0], Protocol); + if (Status != STATUS_SUCCESS) + { + goto Quickie; + } + +/* AddressFile = IrpSp->FileObject->FsContext; + tcp_bind(AddressFile->lwip_tcp_pcb, + (ip_addr_t*)&AddressFile->Address.in_addr, + AddressFile->Address.sin_port);*/ + DPRINT1("\nPTA_IP_ADDRESS dump after\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]); break; }
case TDI_CONNECTION_CONTEXT_LENGTH: { PTA_IP_ADDRESS Address; + + DPRINT1("TCPIP Create connection Context\n"); if (strncmp(&FileInfo->EaName[0], TdiConnectionContext, TDI_CONNECTION_CONTEXT_LENGTH) != 0) { DPRINT1("TCPIP: Should maybe open file %*s.\n", FileInfo->EaNameLength, &FileInfo->EaName[0]); return STATUS_INVALID_PARAMETER; } - DPRINT1("Should create a connection!\n"); Address = (PTA_IP_ADDRESS)(&FileInfo->EaName[FileInfo->EaNameLength + 1]); @@ -284,8 +307,19 @@ goto Quickie; } + temp = (ULONG*)Protocol; + DPRINT1("\n Protocol: %08x\n", temp); + + temp = (ULONG*)Address; + /* All good. */ - Status = TcpIpCreateAddress(Irp, &Address->Address[0].Address[0], Protocol); + DPRINT1("\n PTA_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]); + Status = TcpIpCreateContext(Irp, Protocol); + DPRINT1("\n PTA_IP_ADDRESS dump after\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]); break; }
@@ -319,7 +353,7 @@ PIO_STACK_LOCATION IrpSp; NTSTATUS Status; ULONG_PTR FileType; - + IrpSp = IoGetCurrentIrpStackLocation(Irp);
FileType = (ULONG_PTR)IrpSp->FileObject->FsContext2; @@ -327,6 +361,8 @@ switch (FileType) { case TDI_TRANSPORT_ADDRESS_FILE: + DPRINT1("TCPIP Close Transport Address\n"); + if (!IrpSp->FileObject->FsContext) { DPRINT1("TCPIP: Got a close request without a file to close!\n"); @@ -362,6 +398,8 @@ NTSTATUS Status; PIO_STACK_LOCATION IrpSp;
+ DPRINT1("TcpIpDispatchInternal\n"); + IrpSp = IoGetCurrentIrpStackLocation(Irp);
switch (IrpSp->MinorFunction) @@ -372,6 +410,7 @@ break;
case TDI_RECEIVE_DATAGRAM: + DPRINT1("TCPIP: TDI_RECEIVE_DATAGRAM!\n"); return TcpIpReceiveDatagram(Irp);
case TDI_SEND: @@ -380,6 +419,7 @@ break;
case TDI_SEND_DATAGRAM: + DPRINT1("TCPIP: TDI_SEND_DATAGRAM!\n"); return TcpIpSendDatagram(Irp);
case TDI_ACCEPT: @@ -394,7 +434,7 @@
case TDI_CONNECT: DPRINT1("TCPIP: TDI_CONNECT!\n"); - Status = TcpIpConnect(Irp); + Status = TcpIpConnect(Irp); break;
case TDI_DISCONNECT: @@ -413,6 +453,7 @@ break;
case TDI_QUERY_INFORMATION: + DPRINT1("TCPIP: TDI_QUERY_INFORMATION\n"); return TcpIpQueryKernelInformation(Irp);
case TDI_SET_INFORMATION: @@ -459,7 +500,7 @@ { NTSTATUS Status; PIO_STACK_LOCATION IrpSp; - + IrpSp = IoGetCurrentIrpStackLocation(Irp);
Irp->IoStatus.Information = 0; @@ -468,26 +509,26 @@ { case IOCTL_TCP_QUERY_INFORMATION_EX: Status = TcpIpQueryInformation(Irp); - break; - - case IOCTL_TCP_SET_INFORMATION_EX: - Status = TcpIpSetInformation(Irp); - break; - - case IOCTL_SET_IP_ADDRESS: - DPRINT1("TCPIP: Should handle IOCTL_SET_IP_ADDRESS.\n"); - Status = STATUS_NOT_IMPLEMENTED; - break; - - case IOCTL_DELETE_IP_ADDRESS: - DPRINT1("TCPIP: Should handle IOCTL_DELETE_IP_ADDRESS.\n"); - Status = STATUS_NOT_IMPLEMENTED; - break; - - default: - DPRINT1("TCPIP: Unknown IOCTL 0x%#x\n", IrpSp->Parameters.DeviceIoControl.IoControlCode); - Status = STATUS_NOT_IMPLEMENTED; - break; + break; + + case IOCTL_TCP_SET_INFORMATION_EX: + Status = TcpIpSetInformation(Irp); + break; + + case IOCTL_SET_IP_ADDRESS: + DPRINT1("TCPIP: Should handle IOCTL_SET_IP_ADDRESS.\n"); + Status = STATUS_NOT_IMPLEMENTED; + break; + + case IOCTL_DELETE_IP_ADDRESS: + DPRINT1("TCPIP: Should handle IOCTL_DELETE_IP_ADDRESS.\n"); + Status = STATUS_NOT_IMPLEMENTED; + break; + + default: + DPRINT1("TCPIP: Unknown IOCTL 0x%#x\n", IrpSp->Parameters.DeviceIoControl.IoControlCode); + Status = STATUS_NOT_IMPLEMENTED; + break; }
//DPRINT("TCPIP dispatched with status 0x%08x.\n", Status);