From 716ab53776b35c91380e9ad4f9a202e1d884c2a0 Mon Sep 17 00:00:00 2001 From: Cameron Gutman Date: Tue, 12 Jul 2011 21:31:36 +0000 Subject: [PATCH] [IP] - Store the address of an outgoing NIC properly (gethostname() fix) - Don't do an explicit bind if we don't have to (ws2_32_winetest sock hang fix) svn path=/trunk/; revision=52667 --- reactos/lib/drivers/ip/transport/tcp/accept.c | 36 +++++---- reactos/lib/drivers/ip/transport/tcp/tcp.c | 77 ++++++++++++------- 2 files changed, 72 insertions(+), 41 deletions(-) diff --git a/reactos/lib/drivers/ip/transport/tcp/accept.c b/reactos/lib/drivers/ip/transport/tcp/accept.c index 2454657d009..fde2711e0e5 100644 --- a/reactos/lib/drivers/ip/transport/tcp/accept.c +++ b/reactos/lib/drivers/ip/transport/tcp/accept.c @@ -78,25 +78,36 @@ NTSTATUS TCPListen( PCONNECTION_ENDPOINT Connection, UINT Backlog ) { TI_DbgPrint(DEBUG_TCP,("Connection->SocketContext %x\n", Connection->SocketContext)); - AddressToBind.sin_family = AF_INET; - memcpy( &AddressToBind.sin_addr, - &Connection->AddressFile->Address.Address.IPv4Address, - sizeof(AddressToBind.sin_addr) ); - AddressToBind.sin_port = Connection->AddressFile->Port; + if (Connection->AddressFile->Port) + { + AddressToBind.sin_family = AF_INET; + memcpy( &AddressToBind.sin_addr, + &Connection->AddressFile->Address.Address.IPv4Address, + sizeof(AddressToBind.sin_addr) ); + AddressToBind.sin_port = Connection->AddressFile->Port; + TI_DbgPrint(DEBUG_TCP,("AddressToBind - %x:%x\n", AddressToBind.sin_addr, AddressToBind.sin_port)); - TI_DbgPrint(DEBUG_TCP,("AddressToBind - %x:%x\n", AddressToBind.sin_addr, AddressToBind.sin_port)); + /* Perform an explicit bind */ + Status = TCPTranslateError(OskitTCPBind(Connection->SocketContext, + &AddressToBind, + sizeof(AddressToBind))); + } + else + { + /* An implicit bind will be performed */ + Status = STATUS_SUCCESS; + } - Status = TCPTranslateError( OskitTCPBind( Connection->SocketContext, - &AddressToBind, - sizeof(AddressToBind) ) ); + if (NT_SUCCESS(Status)) + Status = TCPTranslateError( OskitTCPListen( Connection->SocketContext, Backlog ) ); + 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)) + if (NT_SUCCESS(TCPGetSockAddress(Connection, (PTRANSPORT_ADDRESS)&LocalAddress, FALSE))) { /* Allocate the port in the port bitmap */ Connection->AddressFile->Port = TCPAllocatePort(LocalAddress.Address[0].Address[0].sin_port); @@ -107,9 +118,6 @@ NTSTATUS TCPListen( PCONNECTION_ENDPOINT Connection, UINT Backlog ) { } } - if (NT_SUCCESS(Status)) - Status = TCPTranslateError( OskitTCPListen( Connection->SocketContext, Backlog ) ); - UnlockObject(Connection, OldIrql); TI_DbgPrint(DEBUG_TCP,("TCPListen finished %x\n", Status)); diff --git a/reactos/lib/drivers/ip/transport/tcp/tcp.c b/reactos/lib/drivers/ip/transport/tcp/tcp.c index 7fac6251c58..7b25adb6317 100644 --- a/reactos/lib/drivers/ip/transport/tcp/tcp.c +++ b/reactos/lib/drivers/ip/transport/tcp/tcp.c @@ -723,7 +723,7 @@ NTSTATUS TCPConnect USHORT RemotePort; TA_IP_ADDRESS LocalAddress; PTDI_BUCKET Bucket; - PNEIGHBOR_CACHE_ENTRY NCE; + PNEIGHBOR_CACHE_ENTRY NCE = NULL; KIRQL OldIrql; TI_DbgPrint(DEBUG_TCP,("TCPConnect: Called\n")); @@ -762,37 +762,36 @@ NTSTATUS TCPConnect UnlockObject(Connection, OldIrql); return STATUS_NETWORK_UNREACHABLE; } + } - AddressToBind.sin_addr.s_addr = NCE->Interface->Unicast.Address.IPv4Address; + if (Connection->AddressFile->Port) + { + /* See if we had an unspecified bind address */ + if (NCE) + { + /* We did, so use the interface unicast address associated with the route */ + AddressToBind.sin_addr.s_addr = NCE->Interface->Unicast.Address.IPv4Address; + } + else + { + /* Bind address was explicit so use it */ + AddressToBind.sin_addr.s_addr = Connection->AddressFile->Address.Address.IPv4Address; + } + + AddressToBind.sin_port = Connection->AddressFile->Port; + + /* Perform an explicit bind */ + Status = TCPTranslateError(OskitTCPBind(Connection->SocketContext, + &AddressToBind, + sizeof(AddressToBind))); } else { - AddressToBind.sin_addr.s_addr = Connection->AddressFile->Address.Address.IPv4Address; + /* An implicit bind will be performed */ + Status = STATUS_SUCCESS; } - - AddressToBind.sin_port = Connection->AddressFile->Port; - 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)) { if (NT_SUCCESS(Status)) { memcpy( &AddressToConnect.sin_addr, @@ -804,7 +803,31 @@ NTSTATUS TCPConnect ( OskitTCPConnect( Connection->SocketContext, &AddressToConnect, sizeof(AddressToConnect) ) ); - + + 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 */ + if (NT_SUCCESS(TCPGetSockAddress(Connection, (PTRANSPORT_ADDRESS)&LocalAddress, FALSE))) + { + /* 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); + } + } + + /* Check if the address was unspecified */ + if (AddrIsUnspecified(&Connection->AddressFile->Address)) + { + /* It is, so store the address of the outgoing NIC */ + Connection->AddressFile->Address = NCE->Interface->Unicast; + } + } + if (Status == STATUS_PENDING) { Bucket = ExAllocatePoolWithTag( NonPagedPool, sizeof(*Bucket), TDI_BUCKET_TAG );