diff --git a/reactos/drivers/lib/ip/network/ports.c b/reactos/drivers/lib/ip/network/ports.c index f17cb1ee16f..6f0ab37468d 100644 --- a/reactos/drivers/lib/ip/network/ports.c +++ b/reactos/drivers/lib/ip/network/ports.c @@ -51,7 +51,25 @@ ULONG AllocateAnyPort( PPORT_SET PortSet ) { ExAcquireFastMutex( &PortSet->Mutex ); AllocatedPort = RtlFindClearBits( &PortSet->ProtoBitmap, 1, 0 ); if( AllocatedPort != (ULONG)-1 ) { - RtlSetBits( &PortSet->ProtoBitmap, AllocatedPort, 1 ); + RtlSetBit( &PortSet->ProtoBitmap, AllocatedPort ); + AllocatedPort += PortSet->StartingPort; + } + ExReleaseFastMutex( &PortSet->Mutex ); + + return AllocatedPort; +} + +ULONG AllocatePortFromRange( PPORT_SET PortSet, ULONG Lowest, ULONG Highest ) { + ULONG AllocatedPort; + + Lowest -= PortSet->StartingPort; + Highest -= PortSet->StartingPort; + + ExAcquireFastMutex( &PortSet->Mutex ); + AllocatedPort = RtlFindClearBits( &PortSet->ProtoBitmap, 1, Lowest ); + if( AllocatedPort != (ULONG)-1 && AllocatedPort >= Lowest && + AllocatedPort <= Highest) { + RtlSetBit( &PortSet->ProtoBitmap, AllocatedPort ); AllocatedPort += PortSet->StartingPort; } ExReleaseFastMutex( &PortSet->Mutex ); diff --git a/reactos/drivers/lib/ip/transport/tcp/tcp.c b/reactos/drivers/lib/ip/transport/tcp/tcp.c index 748f0cdec13..394ae9da642 100644 --- a/reactos/drivers/lib/ip/transport/tcp/tcp.c +++ b/reactos/drivers/lib/ip/transport/tcp/tcp.c @@ -17,6 +17,7 @@ LIST_ENTRY SignalledConnections; LIST_ENTRY SleepingThreadsList; FAST_MUTEX SleepingThreadsLock; RECURSIVE_MUTEX TCPLock; +PORT_SET TCPPorts; static VOID HandleSignalledConnection( PCONNECTION_ENDPOINT Connection, ULONG NewState ) { @@ -268,6 +269,8 @@ NTSTATUS TCPStartup(VOID) InitializeListHead( &SleepingThreadsList ); InitializeListHead( &SignalledConnections ); + PortsStartup( &TCPPorts, 1, 0xfffe ); + RegisterOskitTCPEventHandlers( &EventHandlers ); InitOskitTCP(); @@ -308,6 +311,8 @@ NTSTATUS TCPShutdown(VOID) DeinitOskitTCP(); + PortsShutdown( &TCPPorts ); + return STATUS_SUCCESS; } @@ -620,4 +625,15 @@ VOID TCPTimeout(VOID) { TcpipRecursiveMutexLeave( &TCPLock ); } +UINT TCPAllocatePort( UINT HintPort ) { + if( HintPort ) { + if( AllocatePort( &TCPPorts, HintPort ) ) return HintPort; + else return (UINT)-1; + } else return AllocatePortFromRange( &TCPPorts, 1024, 5000 ); +} + +VOID TCPFreePort( UINT Port ) { + DeallocatePort( &TCPPorts, Port ); +} + /* EOF */ diff --git a/reactos/drivers/net/tcpip/include/ports.h b/reactos/drivers/net/tcpip/include/ports.h index e71cc214a9a..874cb163e28 100644 --- a/reactos/drivers/net/tcpip/include/ports.h +++ b/reactos/drivers/net/tcpip/include/ports.h @@ -26,5 +26,6 @@ VOID PortsShutdown( PPORT_SET PortSet ); VOID DeallocatePort( PPORT_SET PortSet, ULONG Port ); BOOLEAN AllocatePort( PPORT_SET PortSet, ULONG Port ); ULONG AllocateAnyPort( PPORT_SET PortSet ); +ULONG AllocatePortFromRange( PPORT_SET PortSet, ULONG Lowest, ULONG Highest ); #endif/*_TCPIP_PORTS_H*/ diff --git a/reactos/drivers/net/tcpip/include/tcp.h b/reactos/drivers/net/tcpip/include/tcp.h index 3d7ef448fc1..23641d3cae4 100644 --- a/reactos/drivers/net/tcpip/include/tcp.h +++ b/reactos/drivers/net/tcpip/include/tcp.h @@ -151,6 +151,10 @@ NTSTATUS TCPTranslateError( int OskitError ); VOID TCPTimeout(); +UINT TCPAllocatePort( UINT HintPort ); + +VOID TCPFreePort( UINT Port ); + NTSTATUS TCPStartup( VOID); diff --git a/reactos/drivers/net/tcpip/tcpip/fileobjs.c b/reactos/drivers/net/tcpip/tcpip/fileobjs.c index 4ce6085eac0..b2547ab1270 100644 --- a/reactos/drivers/net/tcpip/tcpip/fileobjs.c +++ b/reactos/drivers/net/tcpip/tcpip/fileobjs.c @@ -268,7 +268,7 @@ NTSTATUS FileOpenAddress( switch (Protocol) { case IPPROTO_TCP: /* FIXME: If specified port is 0, a port is chosen dynamically */ - AddrFile->Port = Address->Address[0].Address[0].sin_port; + AddrFile->Port = TCPAllocatePort(Address->Address[0].Address[0].sin_port); AddrFile->Send = NULL; /* TCPSendData */ break; @@ -346,7 +346,17 @@ NTSTATUS FileCloseAddress( AF_CLR_VALID(AddrFile); TcpipReleaseSpinLock(&AddrFile->Lock, OldIrql); - UDPFreePort( AddrFile->Port ); + + /* Protocol specific handling */ + switch (AddrFile->Protocol) { + case IPPROTO_TCP: + TCPFreePort( AddrFile->Port ); + break; + + case IPPROTO_UDP: + UDPFreePort( AddrFile->Port ); + break; + } DeleteAddress(AddrFile);