mirror of
https://github.com/reactos/reactos.git
synced 2025-07-01 19:01:22 +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
5 changed files with 90 additions and 31 deletions
|
@ -739,10 +739,16 @@ NTSTATUS DispTdiQueryInformation(
|
||||||
case TDI_CONNECTION_FILE:
|
case TDI_CONNECTION_FILE:
|
||||||
Endpoint =
|
Endpoint =
|
||||||
(PCONNECTION_ENDPOINT)TranContext->Handle.ConnectionContext;
|
(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(
|
RtlZeroMemory(
|
||||||
&Address->Address[0].Address[0].sin_zero,
|
&Address->Address[0].Address[0].sin_zero,
|
||||||
sizeof(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:
|
default:
|
||||||
TI_DbgPrint(MIN_TRACE, ("Invalid transport context\n"));
|
TI_DbgPrint(MIN_TRACE, ("Invalid transport context\n"));
|
||||||
|
|
|
@ -194,7 +194,10 @@ VOID AddrFileFree(
|
||||||
/* Protocol specific handling */
|
/* Protocol specific handling */
|
||||||
switch (AddrFile->Protocol) {
|
switch (AddrFile->Protocol) {
|
||||||
case IPPROTO_TCP:
|
case IPPROTO_TCP:
|
||||||
|
if (AddrFile->Port)
|
||||||
|
{
|
||||||
TCPFreePort(AddrFile->Port);
|
TCPFreePort(AddrFile->Port);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IPPROTO_UDP:
|
case IPPROTO_UDP:
|
||||||
|
@ -277,17 +280,27 @@ NTSTATUS FileOpenAddress(
|
||||||
/* Protocol specific handling */
|
/* Protocol specific handling */
|
||||||
switch (Protocol) {
|
switch (Protocol) {
|
||||||
case IPPROTO_TCP:
|
case IPPROTO_TCP:
|
||||||
AddrFile->Port =
|
if (Address->Address[0].Address[0].sin_port)
|
||||||
TCPAllocatePort(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 &&
|
/* Check for bind success */
|
||||||
AddrFile->Port != Address->Address[0].Address[0].sin_port) ||
|
if (AddrFile->Port == 0xffff)
|
||||||
AddrFile->Port == 0xffff)
|
|
||||||
{
|
{
|
||||||
ExFreePoolWithTag(AddrFile, ADDR_FILE_TAG);
|
ExFreePoolWithTag(AddrFile, ADDR_FILE_TAG);
|
||||||
return STATUS_ADDRESS_ALREADY_EXISTS;
|
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);
|
AddEntity(CO_TL_ENTITY, AddrFile, CO_TL_TCP);
|
||||||
|
|
||||||
AddrFile->Send = NULL; /* TCPSendData */
|
AddrFile->Send = NULL; /* TCPSendData */
|
||||||
|
|
|
@ -65,12 +65,14 @@ NTSTATUS TCPListen( PCONNECTION_ENDPOINT Connection, UINT Backlog ) {
|
||||||
NTSTATUS Status = STATUS_SUCCESS;
|
NTSTATUS Status = STATUS_SUCCESS;
|
||||||
SOCKADDR_IN AddressToBind;
|
SOCKADDR_IN AddressToBind;
|
||||||
KIRQL OldIrql;
|
KIRQL OldIrql;
|
||||||
|
TA_IP_ADDRESS LocalAddress;
|
||||||
|
|
||||||
ASSERT(Connection);
|
ASSERT(Connection);
|
||||||
ASSERT_KM_POINTER(Connection->AddressFile);
|
|
||||||
|
|
||||||
LockObject(Connection, &OldIrql);
|
LockObject(Connection, &OldIrql);
|
||||||
|
|
||||||
|
ASSERT_KM_POINTER(Connection->AddressFile);
|
||||||
|
|
||||||
TI_DbgPrint(DEBUG_TCP,("TCPListen started\n"));
|
TI_DbgPrint(DEBUG_TCP,("TCPListen started\n"));
|
||||||
|
|
||||||
TI_DbgPrint(DEBUG_TCP,("Connection->SocketContext %x\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,
|
Status = TCPTranslateError( OskitTCPBind( Connection->SocketContext,
|
||||||
&AddressToBind,
|
&AddressToBind,
|
||||||
sizeof(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))
|
||||||
Status = TCPTranslateError( OskitTCPListen( Connection->SocketContext, Backlog ) );
|
Status = TCPTranslateError( OskitTCPListen( Connection->SocketContext, Backlog ) );
|
||||||
|
|
|
@ -605,6 +605,7 @@ NTSTATUS TCPConnect
|
||||||
SOCKADDR_IN AddressToConnect = { 0 }, AddressToBind = { 0 };
|
SOCKADDR_IN AddressToConnect = { 0 }, AddressToBind = { 0 };
|
||||||
IP_ADDRESS RemoteAddress;
|
IP_ADDRESS RemoteAddress;
|
||||||
USHORT RemotePort;
|
USHORT RemotePort;
|
||||||
|
TA_IP_ADDRESS LocalAddress;
|
||||||
PTDI_BUCKET Bucket;
|
PTDI_BUCKET Bucket;
|
||||||
PNEIGHBOR_CACHE_ENTRY NCE;
|
PNEIGHBOR_CACHE_ENTRY NCE;
|
||||||
KIRQL OldIrql;
|
KIRQL OldIrql;
|
||||||
|
@ -653,12 +654,31 @@ NTSTATUS TCPConnect
|
||||||
AddressToBind.sin_addr.s_addr = Connection->AddressFile->Address.Address.IPv4Address;
|
AddressToBind.sin_addr.s_addr = Connection->AddressFile->Address.Address.IPv4Address;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AddressToBind.sin_port = Connection->AddressFile->Port;
|
||||||
|
|
||||||
Status = TCPTranslateError
|
Status = TCPTranslateError
|
||||||
( OskitTCPBind( Connection->SocketContext,
|
( OskitTCPBind( Connection->SocketContext,
|
||||||
&AddressToBind,
|
&AddressToBind,
|
||||||
sizeof(AddressToBind) ) );
|
sizeof(AddressToBind) ) );
|
||||||
|
|
||||||
if (NT_SUCCESS(Status)) {
|
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,
|
memcpy( &AddressToConnect.sin_addr,
|
||||||
&RemoteAddress.Address.IPv4Address,
|
&RemoteAddress.Address.IPv4Address,
|
||||||
sizeof(AddressToConnect.sin_addr) );
|
sizeof(AddressToConnect.sin_addr) );
|
||||||
|
@ -684,6 +704,7 @@ NTSTATUS TCPConnect
|
||||||
InsertTailList( &Connection->ConnectRequest, &Bucket->Entry );
|
InsertTailList( &Connection->ConnectRequest, &Bucket->Entry );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
UnlockObject(Connection, OldIrql);
|
UnlockObject(Connection, OldIrql);
|
||||||
|
|
||||||
|
|
|
@ -117,7 +117,7 @@ void OskitDumpBuffer( OSK_PCHAR Data, OSK_UINT Len )
|
||||||
void InitializeSocketFlags(struct socket *so)
|
void InitializeSocketFlags(struct socket *so)
|
||||||
{
|
{
|
||||||
so->so_state |= SS_NBIO;
|
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_snd.sb_flags |= SB_SEL;
|
||||||
so->so_rcv.sb_flags |= SB_SEL;
|
so->so_rcv.sb_flags |= SB_SEL;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue