Author: cgutman
Date: Sat Jul 2 15:37:37 2011
New Revision: 52501
URL:
http://svn.reactos.org/svn/reactos?rev=52501&view=rev
Log:
[TCPIP]
- 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
- Revert the hack that partially fixed this before
Modified:
trunk/reactos/drivers/network/tcpip/tcpip/dispatch.c
trunk/reactos/drivers/network/tcpip/tcpip/fileobjs.c
trunk/reactos/lib/drivers/ip/transport/tcp/accept.c
trunk/reactos/lib/drivers/ip/transport/tcp/tcp.c
trunk/reactos/lib/drivers/oskittcp/oskittcp/interface.c
Modified: trunk/reactos/drivers/network/tcpip/tcpip/dispatch.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/network/tcpip/tcpi…
==============================================================================
--- trunk/reactos/drivers/network/tcpip/tcpip/dispatch.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/network/tcpip/tcpip/dispatch.c [iso-8859-1] Sat Jul 2 15:37:37
2011
@@ -739,10 +739,16 @@
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 TCPGetSockAddress( Endpoint, (PTRANSPORT_ADDRESS)Address, FALSE );
+ return STATUS_SUCCESS;
default:
TI_DbgPrint(MIN_TRACE, ("Invalid transport context\n"));
Modified: trunk/reactos/drivers/network/tcpip/tcpip/fileobjs.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/network/tcpip/tcpi…
==============================================================================
--- trunk/reactos/drivers/network/tcpip/tcpip/fileobjs.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/network/tcpip/tcpip/fileobjs.c [iso-8859-1] Sat Jul 2 15:37:37
2011
@@ -194,7 +194,10 @@
/* Protocol specific handling */
switch (AddrFile->Protocol) {
case IPPROTO_TCP:
- TCPFreePort( AddrFile->Port );
+ if (AddrFile->Port)
+ {
+ TCPFreePort(AddrFile->Port);
+ }
break;
case IPPROTO_UDP:
@@ -277,8 +280,36 @@
/* Protocol specific handling */
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) ||
@@ -288,24 +319,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: trunk/reactos/lib/drivers/ip/transport/tcp/accept.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/lib/drivers/ip/transport/t…
==============================================================================
--- trunk/reactos/lib/drivers/ip/transport/tcp/accept.c [iso-8859-1] (original)
+++ trunk/reactos/lib/drivers/ip/transport/tcp/accept.c [iso-8859-1] Sat Jul 2 15:37:37
2011
@@ -65,11 +65,13 @@
NTSTATUS Status = STATUS_SUCCESS;
SOCKADDR_IN 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,("TCPListen started\n"));
@@ -87,6 +89,23 @@
Status = TCPTranslateError( OskitTCPBind( Connection->SocketContext,
&AddressToBind,
sizeof(AddressToBind) ) );
+ 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))
Status = TCPTranslateError( OskitTCPListen( Connection->SocketContext, Backlog
) );
Modified: trunk/reactos/lib/drivers/ip/transport/tcp/tcp.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/lib/drivers/ip/transport/t…
==============================================================================
--- trunk/reactos/lib/drivers/ip/transport/tcp/tcp.c [iso-8859-1] (original)
+++ trunk/reactos/lib/drivers/ip/transport/tcp/tcp.c [iso-8859-1] Sat Jul 2 15:37:37
2011
@@ -605,6 +605,7 @@
SOCKADDR_IN AddressToConnect = { 0 }, AddressToBind = { 0 };
IP_ADDRESS RemoteAddress;
USHORT RemotePort;
+ TA_IP_ADDRESS LocalAddress;
PTDI_BUCKET Bucket;
PNEIGHBOR_CACHE_ENTRY NCE;
KIRQL OldIrql;
@@ -652,6 +653,8 @@
{
AddressToBind.sin_addr.s_addr =
Connection->AddressFile->Address.Address.IPv4Address;
}
+
+ AddressToBind.sin_port = Connection->AddressFile->Port;
Status = TCPTranslateError
( OskitTCPBind( Connection->SocketContext,
@@ -659,29 +662,47 @@
sizeof(AddressToBind) ) );
if (NT_SUCCESS(Status)) {
- memcpy( &AddressToConnect.sin_addr,
- &RemoteAddress.Address.IPv4Address,
- sizeof(AddressToConnect.sin_addr) );
- AddressToConnect.sin_port = RemotePort;
-
- Status = TCPTranslateError
+ /* 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))
+ {
+ memcpy( &AddressToConnect.sin_addr,
+ &RemoteAddress.Address.IPv4Address,
+ sizeof(AddressToConnect.sin_addr) );
+ AddressToConnect.sin_port = RemotePort;
+
+ Status = TCPTranslateError
( OskitTCPConnect( Connection->SocketContext,
- &AddressToConnect,
- sizeof(AddressToConnect) ) );
-
- if (Status == STATUS_PENDING)
- {
- Bucket = ExAllocatePoolWithTag( NonPagedPool, sizeof(*Bucket), TDI_BUCKET_TAG
);
- if( !Bucket )
+ &AddressToConnect,
+ sizeof(AddressToConnect) ) );
+
+ if (Status == STATUS_PENDING)
{
- UnlockObject(Connection, OldIrql);
- return STATUS_NO_MEMORY;
+ 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
);
}
-
- Bucket->Request.RequestNotifyObject = (PVOID)Complete;
- Bucket->Request.RequestContext = Context;
-
- InsertTailList( &Connection->ConnectRequest, &Bucket->Entry );
}
}
Modified: trunk/reactos/lib/drivers/oskittcp/oskittcp/interface.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/lib/drivers/oskittcp/oskit…
==============================================================================
--- trunk/reactos/lib/drivers/oskittcp/oskittcp/interface.c [iso-8859-1] (original)
+++ trunk/reactos/lib/drivers/oskittcp/oskittcp/interface.c [iso-8859-1] Sat Jul 2
15:37:37 2011
@@ -117,7 +117,7 @@
void InitializeSocketFlags(struct socket *so)
{
so->so_state |= SS_NBIO;
- so->so_options |= SO_DONTROUTE | SO_REUSEPORT;
+ so->so_options |= SO_DONTROUTE;
so->so_snd.sb_flags |= SB_SEL;
so->so_rcv.sb_flags |= SB_SEL;
}