Author: cmihail Date: Sun Jul 3 13:34:36 2011 New Revision: 52517
URL: http://svn.reactos.org/svn/reactos?rev=52517&view=rev Log: [TCPIP] apply changes r52501 for lwIP branch
- Fix binding to an unspecified port on a connect so that it works reliably by asking the TCP library for a free port instead of assuming that one we have is free - Fix binding to an unspecified port on a listen which previously would result in the address file not having information stored about the port number assigned - Fix a nasty bug which resulted in us binding to an arbitrary port during a connect even when the client wanted a specific port
Modified: branches/GSoC_2011/TcpIpDriver/drivers/network/tcpip/tcpip/dispatch.c branches/GSoC_2011/TcpIpDriver/drivers/network/tcpip/tcpip/fileobjs.c branches/GSoC_2011/TcpIpDriver/lib/drivers/ip/transport/tcp/accept.c branches/GSoC_2011/TcpIpDriver/lib/drivers/ip/transport/tcp/event.c branches/GSoC_2011/TcpIpDriver/lib/drivers/ip/transport/tcp/if.c branches/GSoC_2011/TcpIpDriver/lib/drivers/ip/transport/tcp/tcp.c
Modified: branches/GSoC_2011/TcpIpDriver/drivers/network/tcpip/tcpip/dispatch.c URL: http://svn.reactos.org/svn/reactos/branches/GSoC_2011/TcpIpDriver/drivers/ne... ============================================================================== --- branches/GSoC_2011/TcpIpDriver/drivers/network/tcpip/tcpip/dispatch.c [iso-8859-1] (original) +++ branches/GSoC_2011/TcpIpDriver/drivers/network/tcpip/tcpip/dispatch.c [iso-8859-1] Sun Jul 3 13:34:36 2011 @@ -729,120 +729,130 @@ * Status of operation */ { - PTDI_REQUEST_KERNEL_QUERY_INFORMATION Parameters; - PTRANSPORT_CONTEXT TranContext; - PIO_STACK_LOCATION IrpSp; - - TI_DbgPrint(DEBUG_IRP, ("[TCPIP, DispTdiQueryInformation] Called\n")); - - IrpSp = IoGetCurrentIrpStackLocation(Irp); - Parameters = (PTDI_REQUEST_KERNEL_QUERY_INFORMATION)&IrpSp->Parameters; - - TranContext = IrpSp->FileObject->FsContext; - if (!TranContext) { - TI_DbgPrint(MID_TRACE, ("Bad transport context.\n")); - return STATUS_INVALID_PARAMETER; - } - - switch (Parameters->QueryType) - { - case TDI_QUERY_ADDRESS_INFO: - { - PTDI_ADDRESS_INFO AddressInfo; - PADDRESS_FILE AddrFile; - PTA_IP_ADDRESS Address; - PCONNECTION_ENDPOINT Endpoint = NULL; - - - if (MmGetMdlByteCount(Irp->MdlAddress) < - (FIELD_OFFSET(TDI_ADDRESS_INFO, Address.Address[0].Address) + - sizeof(TDI_ADDRESS_IP))) { - TI_DbgPrint(MID_TRACE, ("MDL buffer too small.\n")); - return STATUS_BUFFER_TOO_SMALL; + PTDI_REQUEST_KERNEL_QUERY_INFORMATION Parameters; + PTRANSPORT_CONTEXT TranContext; + PIO_STACK_LOCATION IrpSp; + + TI_DbgPrint(DEBUG_IRP, ("[TCPIP, DispTdiQueryInformation] Called\n")); + + IrpSp = IoGetCurrentIrpStackLocation(Irp); + Parameters = (PTDI_REQUEST_KERNEL_QUERY_INFORMATION)&IrpSp->Parameters; + + TranContext = IrpSp->FileObject->FsContext; + if (!TranContext) + { + TI_DbgPrint(MID_TRACE, ("Bad transport context.\n")); + return STATUS_INVALID_PARAMETER; + } + + switch (Parameters->QueryType) + { + case TDI_QUERY_ADDRESS_INFO: + { + PTDI_ADDRESS_INFO AddressInfo; + PADDRESS_FILE AddrFile; + PTA_IP_ADDRESS Address; + PCONNECTION_ENDPOINT Endpoint = NULL; + + if (MmGetMdlByteCount(Irp->MdlAddress) < + (FIELD_OFFSET(TDI_ADDRESS_INFO, Address.Address[0].Address) + + sizeof(TDI_ADDRESS_IP))) + { + TI_DbgPrint(MID_TRACE, ("MDL buffer too small.\n")); + return STATUS_BUFFER_TOO_SMALL; + } + + AddressInfo = (PTDI_ADDRESS_INFO)MmGetSystemAddressForMdl(Irp->MdlAddress); + Address = (PTA_IP_ADDRESS)&AddressInfo->Address; + + switch ((ULONG_PTR)IrpSp->FileObject->FsContext2) + { + case TDI_TRANSPORT_ADDRESS_FILE: + AddrFile = (PADDRESS_FILE)TranContext->Handle.AddressHandle; + + Address->TAAddressCount = 1; + Address->Address[0].AddressLength = TDI_ADDRESS_LENGTH_IP; + Address->Address[0].AddressType = TDI_ADDRESS_TYPE_IP; + Address->Address[0].Address[0].sin_port = AddrFile->Port; + Address->Address[0].Address[0].in_addr = AddrFile->Address.Address.IPv4Address; + RtlZeroMemory( + &Address->Address[0].Address[0].sin_zero, + sizeof(Address->Address[0].Address[0].sin_zero)); + return STATUS_SUCCESS; + + case TDI_CONNECTION_FILE: + Endpoint = (PCONNECTION_ENDPOINT)TranContext->Handle.ConnectionContext; + + Address->TAAddressCount = 1; + Address->Address[0].AddressLength = TDI_ADDRESS_LENGTH_IP; + Address->Address[0].AddressType = TDI_ADDRESS_TYPE_IP; + Address->Address[0].Address[0].sin_port = Endpoint->AddressFile->Port; + Address->Address[0].Address[0].in_addr = Endpoint->AddressFile->Address.Address.IPv4Address; + + RtlZeroMemory( + &Address->Address[0].Address[0].sin_zero, + sizeof(Address->Address[0].Address[0].sin_zero)); + + return STATUS_SUCCESS; + + default: + TI_DbgPrint(MIN_TRACE, ("Invalid transport context\n")); + return STATUS_INVALID_PARAMETER; + } }
- AddressInfo = (PTDI_ADDRESS_INFO)MmGetSystemAddressForMdl(Irp->MdlAddress); - Address = (PTA_IP_ADDRESS)&AddressInfo->Address; - - switch ((ULONG_PTR)IrpSp->FileObject->FsContext2) { - case TDI_TRANSPORT_ADDRESS_FILE: - AddrFile = (PADDRESS_FILE)TranContext->Handle.AddressHandle; - - Address->TAAddressCount = 1; - Address->Address[0].AddressLength = TDI_ADDRESS_LENGTH_IP; - Address->Address[0].AddressType = TDI_ADDRESS_TYPE_IP; - Address->Address[0].Address[0].sin_port = AddrFile->Port; - Address->Address[0].Address[0].in_addr = AddrFile->Address.Address.IPv4Address; - RtlZeroMemory( - &Address->Address[0].Address[0].sin_zero, - sizeof(Address->Address[0].Address[0].sin_zero)); - return STATUS_SUCCESS; - - case TDI_CONNECTION_FILE: - Endpoint = - (PCONNECTION_ENDPOINT)TranContext->Handle.ConnectionContext; - RtlZeroMemory( - &Address->Address[0].Address[0].sin_zero, - sizeof(Address->Address[0].Address[0].sin_zero)); - return TCPGetSockAddress( Endpoint, (PTRANSPORT_ADDRESS)Address, FALSE ); - - default: - TI_DbgPrint(MIN_TRACE, ("Invalid transport context\n")); - return STATUS_INVALID_PARAMETER; + case TDI_QUERY_CONNECTION_INFO: + { + PTDI_CONNECTION_INFORMATION AddressInfo; + PADDRESS_FILE AddrFile; + PCONNECTION_ENDPOINT Endpoint = NULL; + + if (MmGetMdlByteCount(Irp->MdlAddress) < + (FIELD_OFFSET(TDI_CONNECTION_INFORMATION, RemoteAddress) + + sizeof(PVOID))) { + TI_DbgPrint(MID_TRACE, ("MDL buffer too small (ptr).\n")); + return STATUS_BUFFER_TOO_SMALL; + } + + AddressInfo = (PTDI_CONNECTION_INFORMATION) + MmGetSystemAddressForMdl(Irp->MdlAddress); + + switch ((ULONG_PTR)IrpSp->FileObject->FsContext2) + { + case TDI_TRANSPORT_ADDRESS_FILE: + AddrFile = (PADDRESS_FILE)TranContext->Handle.AddressHandle; + Endpoint = AddrFile ? AddrFile->Connection : NULL; + break; + + case TDI_CONNECTION_FILE: + Endpoint = (PCONNECTION_ENDPOINT)TranContext->Handle.ConnectionContext; + break; + + default: + TI_DbgPrint(MIN_TRACE, ("Invalid transport context\n")); + return STATUS_INVALID_PARAMETER; + } + + if (!Endpoint) + { + TI_DbgPrint(MID_TRACE, ("No connection object.\n")); + return STATUS_INVALID_PARAMETER; + } + + return TCPGetSockAddress( Endpoint, AddressInfo->RemoteAddress, TRUE ); } - } - - case TDI_QUERY_CONNECTION_INFO: - { - PTDI_CONNECTION_INFORMATION AddressInfo; - PADDRESS_FILE AddrFile; - PCONNECTION_ENDPOINT Endpoint = NULL; - - if (MmGetMdlByteCount(Irp->MdlAddress) < - (FIELD_OFFSET(TDI_CONNECTION_INFORMATION, RemoteAddress) + - sizeof(PVOID))) { - TI_DbgPrint(MID_TRACE, ("MDL buffer too small (ptr).\n")); - return STATUS_BUFFER_TOO_SMALL; + + case TDI_QUERY_MAX_DATAGRAM_INFO: + { + PTDI_MAX_DATAGRAM_INFO MaxDatagramInfo = MmGetSystemAddressForMdl(Irp->MdlAddress); + + MaxDatagramInfo->MaxDatagramSize = 0xFFFF; + + return STATUS_SUCCESS; } - - AddressInfo = (PTDI_CONNECTION_INFORMATION) - MmGetSystemAddressForMdl(Irp->MdlAddress); - - switch ((ULONG_PTR)IrpSp->FileObject->FsContext2) { - case TDI_TRANSPORT_ADDRESS_FILE: - AddrFile = (PADDRESS_FILE)TranContext->Handle.AddressHandle; - Endpoint = AddrFile ? AddrFile->Connection : NULL; - break; - - case TDI_CONNECTION_FILE: - Endpoint = - (PCONNECTION_ENDPOINT)TranContext->Handle.ConnectionContext; - break; - - default: - TI_DbgPrint(MIN_TRACE, ("Invalid transport context\n")); - return STATUS_INVALID_PARAMETER; - } - - if (!Endpoint) { - TI_DbgPrint(MID_TRACE, ("No connection object.\n")); - return STATUS_INVALID_PARAMETER; - } - - return TCPGetSockAddress( Endpoint, AddressInfo->RemoteAddress, TRUE ); - } - - case TDI_QUERY_MAX_DATAGRAM_INFO: - { - PTDI_MAX_DATAGRAM_INFO MaxDatagramInfo = MmGetSystemAddressForMdl(Irp->MdlAddress); - - MaxDatagramInfo->MaxDatagramSize = 0xFFFF; - - return STATUS_SUCCESS; - } - } - - return STATUS_NOT_IMPLEMENTED; + } + + return STATUS_NOT_IMPLEMENTED; }
Modified: branches/GSoC_2011/TcpIpDriver/drivers/network/tcpip/tcpip/fileobjs.c URL: http://svn.reactos.org/svn/reactos/branches/GSoC_2011/TcpIpDriver/drivers/ne... ============================================================================== --- branches/GSoC_2011/TcpIpDriver/drivers/network/tcpip/tcpip/fileobjs.c [iso-8859-1] (original) +++ branches/GSoC_2011/TcpIpDriver/drivers/network/tcpip/tcpip/fileobjs.c [iso-8859-1] Sun Jul 3 13:34:36 2011 @@ -199,7 +199,10 @@ switch (AddrFile->Protocol) { case IPPROTO_TCP: - TCPFreePort( AddrFile->Port ); + if (AddrFile->Port) + { + TCPFreePort(AddrFile->Port); + } break;
case IPPROTO_UDP: @@ -289,8 +292,36 @@ switch (Protocol) { case IPPROTO_TCP: + if (Address->Address[0].Address[0].sin_port) + { + /* The client specified an explicit port so we force a bind to this */ + AddrFile->Port = TCPAllocatePort(Address->Address[0].Address[0].sin_port); + + /* Check for bind success */ + if (AddrFile->Port == 0xffff) + { + ExFreePoolWithTag(AddrFile, ADDR_FILE_TAG); + return STATUS_ADDRESS_ALREADY_EXISTS; + } + + /* Sanity check */ + ASSERT(Address->Address[0].Address[0].sin_port == AddrFile->Port); + } + else + { + /* The client wants an unspecified port so we wait to see what the TCP library gives us */ + AddrFile->Port = 0; + } + + AddEntity(CO_TL_ENTITY, AddrFile, CO_TL_TCP); + + AddrFile->Send = NULL; /* TCPSendData */ + break; + + case IPPROTO_UDP: + TI_DbgPrint(MID_TRACE,("Allocating udp port\n")); AddrFile->Port = - TCPAllocatePort(Address->Address[0].Address[0].sin_port); + UDPAllocatePort(Address->Address[0].Address[0].sin_port);
if ((Address->Address[0].Address[0].sin_port && AddrFile->Port != Address->Address[0].Address[0].sin_port) || @@ -300,24 +331,6 @@ return STATUS_ADDRESS_ALREADY_EXISTS; }
- AddEntity(CO_TL_ENTITY, AddrFile, CO_TL_TCP); - - AddrFile->Send = NULL; /* TCPSendData */ - break; - - case IPPROTO_UDP: - TI_DbgPrint(MID_TRACE,("Allocating udp port\n")); - AddrFile->Port = - UDPAllocatePort(Address->Address[0].Address[0].sin_port); - - if ((Address->Address[0].Address[0].sin_port && - AddrFile->Port != Address->Address[0].Address[0].sin_port) || - AddrFile->Port == 0xffff) - { - ExFreePoolWithTag(AddrFile, ADDR_FILE_TAG); - return STATUS_ADDRESS_ALREADY_EXISTS; - } - TI_DbgPrint(MID_TRACE,("Setting port %d (wanted %d)\n", AddrFile->Port, Address->Address[0].Address[0].sin_port));
Modified: branches/GSoC_2011/TcpIpDriver/lib/drivers/ip/transport/tcp/accept.c URL: http://svn.reactos.org/svn/reactos/branches/GSoC_2011/TcpIpDriver/lib/driver... ============================================================================== --- branches/GSoC_2011/TcpIpDriver/lib/drivers/ip/transport/tcp/accept.c [iso-8859-1] (original) +++ branches/GSoC_2011/TcpIpDriver/lib/drivers/ip/transport/tcp/accept.c [iso-8859-1] Sun Jul 3 13:34:36 2011 @@ -51,11 +51,13 @@ NTSTATUS Status = STATUS_SUCCESS; struct ip_addr AddressToBind; KIRQL OldIrql; + TA_IP_ADDRESS LocalAddress;
ASSERT(Connection); - ASSERT_KM_POINTER(Connection->AddressFile);
LockObject(Connection, &OldIrql); + + ASSERT_KM_POINTER(Connection->AddressFile);
TI_DbgPrint(DEBUG_TCP,("[IP, TCPListen] Called\n")); DbgPrint("[IP, TCPListen] Called\n"); @@ -68,6 +70,24 @@ Status = TCPTranslateError(LibTCPBind(Connection->SocketContext, &AddressToBind, Connection->AddressFile->Port)); + + if (NT_SUCCESS(Status)) + { + /* Check if we had an unspecified port */ + if (!Connection->AddressFile->Port) + { + /* We did, so we need to copy back the port */ + Status = TCPGetSockAddress(Connection, (PTRANSPORT_ADDRESS)&LocalAddress, FALSE); + if (NT_SUCCESS(Status)) + { + /* Allocate the port in the port bitmap */ + Connection->AddressFile->Port = TCPAllocatePort(LocalAddress.Address[0].Address[0].sin_port); + + /* This should never fail */ + ASSERT(Connection->AddressFile->Port != 0xFFFF); + } + } + }
if (NT_SUCCESS(Status)) {
Modified: branches/GSoC_2011/TcpIpDriver/lib/drivers/ip/transport/tcp/event.c URL: http://svn.reactos.org/svn/reactos/branches/GSoC_2011/TcpIpDriver/lib/driver... ============================================================================== --- branches/GSoC_2011/TcpIpDriver/lib/drivers/ip/transport/tcp/event.c [iso-8859-1] (original) +++ branches/GSoC_2011/TcpIpDriver/lib/drivers/ip/transport/tcp/event.c [iso-8859-1] Sun Jul 3 13:34:36 2011 @@ -212,7 +212,7 @@ /* sanity assert...this should never be in anything else but a CLOSED state */ ASSERT(((struct tcp_pcb*)OldSocketContext)->state == CLOSED); /* free socket context created in FileOpenConnection, as we're using a new - one; we free it asynchornously because otherwise we create a dedlock */ + one; we free it asynchornously because otherwise we create a deadlock */ ChewCreate(SocketContextCloseWorker, OldSocketContext); }
Modified: branches/GSoC_2011/TcpIpDriver/lib/drivers/ip/transport/tcp/if.c URL: http://svn.reactos.org/svn/reactos/branches/GSoC_2011/TcpIpDriver/lib/driver... ============================================================================== --- branches/GSoC_2011/TcpIpDriver/lib/drivers/ip/transport/tcp/if.c [iso-8859-1] (original) +++ branches/GSoC_2011/TcpIpDriver/lib/drivers/ip/transport/tcp/if.c [iso-8859-1] Sun Jul 3 13:34:36 2011 @@ -39,17 +39,22 @@ } else { + DbgPrint("[IP, TCPSendDataCallback] FAIL EINVAL 1\n"); return EINVAL; }
+ DbgPrint("[IP, TCPSendDataCallback] Set packet local and remore adresses\n"); + if (!(NCE = RouteGetRouteToDestination(&RemoteAddress))) { + DbgPrint("[IP, TCPSendDataCallback] FAIL EINVAL 2\n"); return EINVAL; }
NdisStatus = AllocatePacketWithBuffer(&Packet.NdisPacket, NULL, p->tot_len); if (NdisStatus != NDIS_STATUS_SUCCESS) { + DbgPrint("[IP, TCPSendDataCallback] FAIL ENOBUFS\n"); return ENOBUFS; }
@@ -60,6 +65,8 @@ ASSERT(p1); RtlCopyMemory(((PUCHAR)Packet.Header) + i, p1->payload, p1->len); } + + DbgPrint("[IP, TCPSendDataCallback] Allocated NDIS packet and set data\n");
Packet.HeaderSize = sizeof(IPv4_HEADER); Packet.TotalSize = p->tot_len; @@ -68,9 +75,12 @@
if (!NT_SUCCESS(IPSendDatagram(&Packet, NCE, TCPPacketSendComplete, NULL))) { + DbgPrint("[IP, TCPSendDataCallback] FAIL EINVAL 3\n"); FreeNdisPacket(Packet.NdisPacket); return EINVAL; } + + DbgPrint("[IP, TCPSendDataCallback] Leaving\n");
return 0; }
Modified: branches/GSoC_2011/TcpIpDriver/lib/drivers/ip/transport/tcp/tcp.c URL: http://svn.reactos.org/svn/reactos/branches/GSoC_2011/TcpIpDriver/lib/driver... ============================================================================== --- branches/GSoC_2011/TcpIpDriver/lib/drivers/ip/transport/tcp/tcp.c [iso-8859-1] (original) +++ branches/GSoC_2011/TcpIpDriver/lib/drivers/ip/transport/tcp/tcp.c [iso-8859-1] Sun Jul 3 13:34:36 2011 @@ -110,11 +110,12 @@ PVOID Socket;
LockObject(Connection, &OldIrql); + + DbgPrint("[IP, TCPClose] Called for Connection( 0x%x )->SocketConext( 0x%x )\n", Connection, Connection->SocketContext); + Socket = Connection->SocketContext; Connection->SocketContext = NULL;
- DbgPrint("[IP, TCPClose] Called\n"); - /* We should not be associated to an address file at this point */ ASSERT(!Connection->AddressFile);
@@ -122,6 +123,9 @@ if (Socket) { FlushAllQueues(Connection, STATUS_CANCELLED); + + DbgPrint("[IP, TCPClose] Socket (pcb) = 0x%x\n", Socket); + LibTCPClose(Socket); }
@@ -247,6 +251,7 @@ struct ip_addr bindaddr, connaddr; IP_ADDRESS RemoteAddress; USHORT RemotePort; + TA_IP_ADDRESS LocalAddress; PTDI_BUCKET Bucket; PNEIGHBOR_CACHE_ENTRY NCE; KIRQL OldIrql; @@ -301,39 +306,42 @@
if (NT_SUCCESS(Status)) { - connaddr.addr = RemoteAddress.Address.IPv4Address; - - Bucket = ExAllocatePoolWithTag( NonPagedPool, sizeof(*Bucket), TDI_BUCKET_TAG ); - if( !Bucket ) - { - UnlockObject(Connection, OldIrql); - return STATUS_NO_MEMORY; - } - - Bucket->Request.RequestNotifyObject = (PVOID)Complete; - Bucket->Request.RequestContext = Context; - - InsertTailList( &Connection->ConnectRequest, &Bucket->Entry ); - - Status = TCPTranslateError(LibTCPConnect(Connection->SocketContext, - &connaddr, - RemotePort)); - - DbgPrint("LibTCPConnect: 0x%x\n", Status); - - if (Status == STATUS_PENDING) - { - /*Bucket = ExAllocatePoolWithTag( NonPagedPool, sizeof(*Bucket), TDI_BUCKET_TAG ); + /* Check if we had an unspecified port */ + if (!Connection->AddressFile->Port) + { + /* We did, so we need to copy back the port */ + Status = TCPGetSockAddress(Connection, (PTRANSPORT_ADDRESS)&LocalAddress, FALSE); + if (NT_SUCCESS(Status)) + { + /* Allocate the port in the port bitmap */ + Connection->AddressFile->Port = TCPAllocatePort(LocalAddress.Address[0].Address[0].sin_port); + + /* This should never fail */ + ASSERT(Connection->AddressFile->Port != 0xFFFF); + } + } + + if (NT_SUCCESS(Status)) + { + connaddr.addr = RemoteAddress.Address.IPv4Address; + + Bucket = ExAllocatePoolWithTag( NonPagedPool, sizeof(*Bucket), TDI_BUCKET_TAG ); if( !Bucket ) { - UnlockObject(Connection, OldIrql); - return STATUS_NO_MEMORY; + UnlockObject(Connection, OldIrql); + return STATUS_NO_MEMORY; }
Bucket->Request.RequestNotifyObject = (PVOID)Complete; Bucket->Request.RequestContext = Context; - InsertTailList( &Connection->ConnectRequest, &Bucket->Entry );*/ + InsertTailList( &Connection->ConnectRequest, &Bucket->Entry ); + + Status = TCPTranslateError(LibTCPConnect(Connection->SocketContext, + &connaddr, + RemotePort)); + + DbgPrint("LibTCPConnect: 0x%x\n", Status); } }