mirror of
https://github.com/reactos/reactos.git
synced 2024-09-28 13:34:53 +00:00
[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 svn path=/trunk/; revision=52501
This commit is contained in:
parent
b062ee8583
commit
16ded1b13b
|
@ -739,10 +739,16 @@ NTSTATUS DispTdiQueryInformation(
|
|||
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"));
|
||||
|
|
|
@ -194,7 +194,10 @@ VOID AddrFileFree(
|
|||
/* Protocol specific handling */
|
||||
switch (AddrFile->Protocol) {
|
||||
case IPPROTO_TCP:
|
||||
TCPFreePort( AddrFile->Port );
|
||||
if (AddrFile->Port)
|
||||
{
|
||||
TCPFreePort(AddrFile->Port);
|
||||
}
|
||||
break;
|
||||
|
||||
case IPPROTO_UDP:
|
||||
|
@ -277,17 +280,27 @@ NTSTATUS FileOpenAddress(
|
|||
/* Protocol specific handling */
|
||||
switch (Protocol) {
|
||||
case IPPROTO_TCP:
|
||||
AddrFile->Port =
|
||||
TCPAllocatePort(Address->Address[0].Address[0].sin_port);
|
||||
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);
|
||||
|
||||
if ((Address->Address[0].Address[0].sin_port &&
|
||||
AddrFile->Port != Address->Address[0].Address[0].sin_port) ||
|
||||
AddrFile->Port == 0xffff)
|
||||
/* 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 */
|
||||
|
|
|
@ -65,12 +65,14 @@ NTSTATUS TCPListen( PCONNECTION_ENDPOINT Connection, UINT Backlog ) {
|
|||
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"));
|
||||
|
||||
TI_DbgPrint(DEBUG_TCP,("Connection->SocketContext %x\n",
|
||||
|
@ -87,6 +89,23 @@ NTSTATUS TCPListen( PCONNECTION_ENDPOINT Connection, UINT Backlog ) {
|
|||
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 ) );
|
||||
|
|
|
@ -605,6 +605,7 @@ NTSTATUS TCPConnect
|
|||
SOCKADDR_IN AddressToConnect = { 0 }, AddressToBind = { 0 };
|
||||
IP_ADDRESS RemoteAddress;
|
||||
USHORT RemotePort;
|
||||
TA_IP_ADDRESS LocalAddress;
|
||||
PTDI_BUCKET Bucket;
|
||||
PNEIGHBOR_CACHE_ENTRY NCE;
|
||||
KIRQL OldIrql;
|
||||
|
@ -653,12 +654,31 @@ NTSTATUS TCPConnect
|
|||
AddressToBind.sin_addr.s_addr = Connection->AddressFile->Address.Address.IPv4Address;
|
||||
}
|
||||
|
||||
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))
|
||||
{
|
||||
memcpy( &AddressToConnect.sin_addr,
|
||||
&RemoteAddress.Address.IPv4Address,
|
||||
sizeof(AddressToConnect.sin_addr) );
|
||||
|
@ -684,6 +704,7 @@ NTSTATUS TCPConnect
|
|||
InsertTailList( &Connection->ConnectRequest, &Bucket->Entry );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
UnlockObject(Connection, OldIrql);
|
||||
|
||||
|
|
|
@ -117,7 +117,7 @@ void OskitDumpBuffer( OSK_PCHAR Data, OSK_UINT Len )
|
|||
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;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue