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/tcpip/dispatch.c?rev=52501&r1=52500&r2=52501&view=diff
==============================================================================
--- 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/tcpip/fileobjs.c?rev=52501&r1=52500&r2=52501&view=diff
==============================================================================
--- 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/tcp/accept.c?rev=52501&r1=52500&r2=52501&view=diff
==============================================================================
--- 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/tcp/tcp.c?rev=52501&r1=52500&r2=52501&view=diff
==============================================================================
--- 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/oskittcp/interface.c?rev=52501&r1=52500&r2=52501&view=diff
==============================================================================
--- 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;
 }


Reply via email to