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/…
==============================================================================
--- 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/…
==============================================================================
--- 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/…
==============================================================================
--- 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);