mirror of
https://github.com/ValveSoftware/GameNetworkingSockets.git
synced 2026-05-29 16:20:34 +00:00
Add plumbing for internal code to send specific ECN values
Added a macro to detect if the platform supports sending ECN. This is currently incorrect, in that it claims that only Win32 can do it, when obviously POSIX can, too. I left a note to come back and fix this, and when the macro is correct, I will promote it to platform_sockets.h P4:9147212
This commit is contained in:
@@ -26,7 +26,6 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
#include <tier0/memdbgoff.h>
|
||||
|
||||
// Ugggggggggg MSVC VS2013 STL bug: try_lock_for doesn't actually respect the timeout, it always ends up using an infinite timeout.
|
||||
@@ -985,11 +984,11 @@ public:
|
||||
#endif
|
||||
|
||||
// Implements IRawUDPSocket
|
||||
virtual bool BSendRawPacketGather( int nChunks, const iovec *pChunks, const netadr_t &adrTo ) const override;
|
||||
virtual bool BSendRawPacketGather( int nChunks, const iovec *pChunks, const netadr_t &adrTo, int ecn = -1 ) const override;
|
||||
virtual void Close() override;
|
||||
|
||||
//// Send a packet, for really realz right now. (No checking for fake loss or lag.)
|
||||
inline bool BReallySendRawPacket( int nChunks, const iovec *pChunks, const netadr_t &adrTo ) const
|
||||
inline bool BReallySendRawPacket( int nChunks, const iovec *pChunks, const netadr_t &adrTo, int ecn ) const
|
||||
{
|
||||
Assert( m_socket != INVALID_SOCKET );
|
||||
Assert( nChunks > 0 );
|
||||
@@ -1081,8 +1080,11 @@ public:
|
||||
|
||||
CHAR control[WSA_CMSG_SPACE(sizeof(INT))];
|
||||
|
||||
COMPILE_TIME_ASSERT( PlatformCanSendECN() );
|
||||
|
||||
// Check if we need to send ECN
|
||||
int ecn = GlobalConfig::ECN.Get();
|
||||
if ( ecn < 0 )
|
||||
ecn = GlobalConfig::ECN.Get();
|
||||
if ( ecn >= 0 )
|
||||
{
|
||||
wsaMsg.Control.len = sizeof(control);
|
||||
@@ -1126,6 +1128,8 @@ public:
|
||||
}
|
||||
#endif
|
||||
#else
|
||||
COMPILE_TIME_ASSERT( !PlatformCanSendECN() );
|
||||
|
||||
bool bResult;
|
||||
if ( nChunks == 1 )
|
||||
{
|
||||
@@ -1568,7 +1572,8 @@ public:
|
||||
iovec temp;
|
||||
temp.iov_len = pkt.m_info.m_cbPkt;
|
||||
temp.iov_base = (void *)pkt.m_pkt;
|
||||
pkt.SockOwner()->BReallySendRawPacket( 1, &temp, pkt.m_info.m_adrFrom );
|
||||
int ecn = pkt.m_info.m_tos == 0xff ? -1 : pkt.m_info.m_tos;
|
||||
pkt.SockOwner()->BReallySendRawPacket( 1, &temp, pkt.m_info.m_adrFrom, ecn );
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1776,7 +1781,7 @@ inline SteamNetworkingMicroseconds RandomJitter( const GlobalConfigValue<float>
|
||||
return (SteamNetworkingMicroseconds)( flJitterMS * 1000.0f );
|
||||
}
|
||||
|
||||
bool CRawUDPSocketImpl::BSendRawPacketGather( int nChunks, const iovec *pChunks, const netadr_t &adrTo ) const
|
||||
bool CRawUDPSocketImpl::BSendRawPacketGather( int nChunks, const iovec *pChunks, const netadr_t &adrTo, int ecn ) const
|
||||
{
|
||||
SteamNetworkingGlobalLock::AssertHeldByCurrentThread();
|
||||
|
||||
@@ -1842,28 +1847,23 @@ bool CRawUDPSocketImpl::BSendRawPacketGather( int nChunks, const iovec *pChunks,
|
||||
}
|
||||
usecWhenProcess += usecReorderLag;
|
||||
|
||||
// No special TOS.
|
||||
// Note that in the future we might want to be able to allow the caller
|
||||
// to specify an ECN value.
|
||||
constexpr uint8 tos = 0xff;
|
||||
|
||||
// Check for simulating random packet duplication
|
||||
if ( bDup )
|
||||
{
|
||||
SteamNetworkingMicroseconds usecDupLag = 1 + (SteamNetworkingMicroseconds)WeakRandomFloat( 0.0f, GlobalConfig::FakePacketDup_TimeMax.Get()*1000.0f );
|
||||
s_packetLagQueueSend.LagPacket( const_cast<CRawUDPSocketImpl *>( this ), adrTo, usecWhenProcess + usecDupLag, nChunks, pChunks, tos );
|
||||
s_packetLagQueueSend.LagPacket( const_cast<CRawUDPSocketImpl *>( this ), adrTo, usecWhenProcess + usecDupLag, nChunks, pChunks, (uint8)ecn );
|
||||
}
|
||||
|
||||
// Lag the original packet?
|
||||
if ( usecWhenProcess > usecNow )
|
||||
{
|
||||
s_packetLagQueueSend.LagPacket( const_cast<CRawUDPSocketImpl *>( this ), adrTo, usecWhenProcess, nChunks, pChunks, tos );
|
||||
s_packetLagQueueSend.LagPacket( const_cast<CRawUDPSocketImpl *>( this ), adrTo, usecWhenProcess, nChunks, pChunks, (uint8)ecn );
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Now really send it
|
||||
return BReallySendRawPacket( nChunks, pChunks, adrTo );
|
||||
return BReallySendRawPacket( nChunks, pChunks, adrTo, ecn );
|
||||
}
|
||||
|
||||
void CRawUDPSocketImpl::InternalAddToCleanupQueue()
|
||||
|
||||
@@ -100,27 +100,27 @@ public:
|
||||
/// Packets sent through this method are subject to fake loss (steamdatagram_fakepacketloss_send),
|
||||
/// lag (steamdatagram_fakepacketlag_send and steamdatagram_fakepacketreorder_send), and
|
||||
/// duplication (steamdatagram_fakepacketdup_send)
|
||||
inline bool BSendRawPacket( const void *pPkt, int cbPkt, const netadr_t &adrTo ) const
|
||||
inline bool BSendRawPacket( const void *pPkt, int cbPkt, const netadr_t &adrTo, int ecn = -1 ) const
|
||||
{
|
||||
iovec temp;
|
||||
temp.iov_len = cbPkt;
|
||||
temp.iov_base = (void *)pPkt;
|
||||
return BSendRawPacketGather( 1, &temp, adrTo );
|
||||
return BSendRawPacketGather( 1, &temp, adrTo, ecn );
|
||||
}
|
||||
inline bool BSendRawPacket( const void *pPkt, int cbPkt, const SteamNetworkingIPAddr &adrTo ) const
|
||||
inline bool BSendRawPacket( const void *pPkt, int cbPkt, const SteamNetworkingIPAddr &adrTo, int ecn = -1 ) const
|
||||
{
|
||||
netadr_t netadrTo;
|
||||
SteamNetworkingIPAddrToNetAdr( netadrTo, adrTo );
|
||||
return BSendRawPacket( pPkt, cbPkt, netadrTo );
|
||||
return BSendRawPacket( pPkt, cbPkt, netadrTo, ecn );
|
||||
}
|
||||
|
||||
/// Gather-based send. Simulated lag, loss, etc are applied
|
||||
virtual bool BSendRawPacketGather( int nChunks, const iovec *pChunks, const netadr_t &adrTo ) const = 0;
|
||||
inline bool BSendRawPacketGather( int nChunks, const iovec *pChunks, const SteamNetworkingIPAddr &adrTo ) const
|
||||
virtual bool BSendRawPacketGather( int nChunks, const iovec *pChunks, const netadr_t &adrTo, int ecn = -1 ) const = 0;
|
||||
inline bool BSendRawPacketGather( int nChunks, const iovec *pChunks, const SteamNetworkingIPAddr &adrTo, int ecn = -1 ) const
|
||||
{
|
||||
netadr_t netadrTo;
|
||||
SteamNetworkingIPAddrToNetAdr( netadrTo, adrTo );
|
||||
return BSendRawPacketGather( nChunks, pChunks, netadrTo );
|
||||
return BSendRawPacketGather( nChunks, pChunks, netadrTo, ecn );
|
||||
}
|
||||
|
||||
/// Logically close the socket. This might not actually close the socket IMMEDIATELY,
|
||||
@@ -198,15 +198,15 @@ class IBoundUDPSocket
|
||||
public:
|
||||
|
||||
/// Send a packet on this socket to the bound remote host
|
||||
inline bool BSendRawPacket( const void *pPkt, int cbPkt ) const
|
||||
inline bool BSendRawPacket( const void *pPkt, int cbPkt, int ecn = -1 ) const
|
||||
{
|
||||
return m_pRawSock->BSendRawPacket( pPkt, cbPkt, m_adr );
|
||||
return m_pRawSock->BSendRawPacket( pPkt, cbPkt, m_adr, ecn );
|
||||
}
|
||||
|
||||
/// Gather-based send to the bound remote host
|
||||
inline bool BSendRawPacketGather( int nChunks, const iovec *pChunks ) const
|
||||
inline bool BSendRawPacketGather( int nChunks, const iovec *pChunks, int ecn = -1 ) const
|
||||
{
|
||||
return m_pRawSock->BSendRawPacketGather( nChunks, pChunks, m_adr );
|
||||
return m_pRawSock->BSendRawPacketGather( nChunks, pChunks, m_adr, ecn );
|
||||
}
|
||||
|
||||
/// Close this socket and stop talking to the specified remote host
|
||||
|
||||
@@ -1094,6 +1094,25 @@ struct DataPacketSerializer : DataPacketSerializerBase
|
||||
iovec *m_iov_out;
|
||||
};
|
||||
|
||||
// Helpers for manipulating the Type-of-Service (TOS) field in the IPv4 header.
|
||||
// https://en.wikipedia.org/wiki/Type_of_service
|
||||
constexpr uint8 IPv4_TOS_DSCP_bits = 0xfc;
|
||||
constexpr uint8 IPv4_TOS_ECN_bits = 0x3;
|
||||
inline uint8 IPv4_TOS_make( uint8 dscp, uint8 ecn )
|
||||
{
|
||||
Assert( dscp < 0x40 );
|
||||
Assert( ecn < 0x4 );
|
||||
return ( (dscp<<2) | ecn );
|
||||
}
|
||||
|
||||
// FIXME POSIX supports this! Need to check console support and implement all supported platforms,
|
||||
// and then move this to platform_sockets
|
||||
#ifdef _WIN32
|
||||
#define PlatformCanSendECN() true
|
||||
#else
|
||||
#define PlatformCanSendECN() false
|
||||
#endif
|
||||
|
||||
} // namespace SteamNetworkingSocketsLib
|
||||
|
||||
#include <tier0/memdbgon.h>
|
||||
|
||||
Reference in New Issue
Block a user