Network/ENet: More cleanup

This commit is contained in:
Lynix 2017-01-28 12:08:35 +01:00
parent 8fc734674d
commit c9d5f2f1ac
6 changed files with 130 additions and 137 deletions

View File

@ -64,8 +64,6 @@ namespace Nz
void AddToDispatchQueue(ENetPeer* peer);
void RemoveFromDispatchQueue(ENetPeer* peer);
bool CheckTimeouts(ENetPeer* peer, ENetEvent* event);
bool DispatchIncomingCommands(ENetEvent* event);
bool HandleAcknowledge(ENetEvent* event, ENetPeer* peer, const ENetProtocol* command);

View File

@ -68,8 +68,10 @@ namespace Nz
struct IncomingCommmand;
struct OutgoingCommand;
// Protocol functions
inline void ChangeState(ENetPeerState state);
bool CheckTimeouts(ENetEvent* event);
void DispatchState(ENetPeerState state);
void DispatchIncomingReliableCommands(Channel& channel);
@ -85,6 +87,7 @@ namespace Nz
bool QueueAcknowledgement(ENetProtocol* command, UInt16 sentTime);
IncomingCommmand* QueueIncomingCommand(const ENetProtocol& command, const void* data, std::size_t dataLength, UInt32 flags, UInt32 fragmentCount);
inline void QueueOutgoingCommand(ENetProtocol& command);
void QueueOutgoingCommand(ENetProtocol& command, ENetPacketRef packet, UInt32 offset, UInt16 length);
void SetupOutgoingCommand(OutgoingCommand& outgoingCommand);

View File

@ -37,6 +37,11 @@ namespace Nz
m_state = state;
}
inline void ENetPeer::QueueOutgoingCommand(ENetProtocol& command)
{
QueueOutgoingCommand(command, ENetPacketRef(), 0, 0);
}
}
#include <Nazara/Network/DebugOff.hpp>

View File

@ -267,6 +267,14 @@ namespace Nz
union NAZARA_PACKED ENetProtocol
{
ENetProtocol() = default;
ENetProtocol(UInt8 command, UInt8 channel)
{
header.command = command;
header.channelID = channel;
}
ENetProtocolCommandHeader header;
ENetProtocolAcknowledge acknowledge;
ENetProtocolBandwidthLimit bandwidthLimit;

View File

@ -117,10 +117,7 @@ namespace Nz
ENetPeer& peer = m_peers[peerId];
peer.InitOutgoing(channelCount, remoteAddress, ++m_randomSeed, windowSize);
ENetProtocol command;
command.header.command = ENetProtocolCommand_Connect | ENetProtocolFlag_Acknowledge;
command.header.channelID = 0xFF;
ENetProtocol command(ENetProtocolCommand_Connect | ENetProtocolFlag_Acknowledge, 0xFF);
command.connect.channelCount = HostToNet(static_cast<UInt32>(channelCount));
command.connect.connectID = peer.m_connectID;
command.connect.data = HostToNet(data);
@ -134,8 +131,7 @@ namespace Nz
command.connect.packetThrottleDeceleration = HostToNet(peer.m_packetThrottleDeceleration);
command.connect.packetThrottleInterval = HostToNet(peer.m_packetThrottleInterval);
command.connect.windowSize = HostToNet(peer.m_windowSize);
peer.QueueOutgoingCommand(command, nullptr, 0, 0);
peer.QueueOutgoingCommand(command);
return &peer;
}
@ -350,52 +346,6 @@ namespace Nz
m_dispatchQueue.UnboundedReset(peer->m_incomingPeerID);
}
bool ENetHost::CheckTimeouts(ENetPeer* peer, ENetEvent* event)
{
auto currentCommand = peer->m_sentReliableCommands.begin();
while (currentCommand != peer->m_sentReliableCommands.end())
{
auto outgoingCommand = currentCommand;
++currentCommand;
if (ENET_TIME_DIFFERENCE(m_serviceTime, outgoingCommand->sentTime) < outgoingCommand->roundTripTimeout)
continue;
if (peer->m_earliestTimeout == 0 || ENET_TIME_LESS(outgoingCommand->sentTime, peer->m_earliestTimeout))
peer->m_earliestTimeout = outgoingCommand->sentTime;
if (peer->m_earliestTimeout != 0 && (ENET_TIME_DIFFERENCE(m_serviceTime, peer->m_earliestTimeout) >= peer->m_timeoutMaximum ||
(outgoingCommand->roundTripTimeout >= outgoingCommand->roundTripTimeoutLimit && ENET_TIME_DIFFERENCE(m_serviceTime, peer->m_earliestTimeout) >= peer->m_timeoutMinimum)))
{
NotifyDisconnect(peer, event);
return true;
}
if (outgoingCommand->packet)
peer->m_reliableDataInTransit -= outgoingCommand->fragmentLength;
++peer->m_packetsLost;
outgoingCommand->roundTripTimeout *= 2;
peer->m_outgoingReliableCommands.emplace_front(std::move(*outgoingCommand));
peer->m_sentReliableCommands.erase(outgoingCommand);
// Okay this should just never procs, I don't see how it would be possible
/*if (currentCommand == enet_list_begin(&peer->sentReliableCommands) &&
!enet_list_empty(&peer->sentReliableCommands))
{
outgoingCommand = (ENetOutgoingCommand *) currentCommand;
peer->nextTimeout = outgoingCommand->sentTime + outgoingCommand->roundTripTimeout;
}*/
}
return false;
}
bool ENetHost::DispatchIncomingCommands(ENetEvent* event)
{
for (std::size_t bit = m_dispatchQueue.FindFirst(); bit != m_dispatchQueue.npos; bit = m_dispatchQueue.FindNext(bit))
@ -608,9 +558,7 @@ namespace Nz
windowSize = std::max(windowSize, NetToHost(command->connect.windowSize));
windowSize = Clamp<UInt32>(windowSize, ENetConstants::ENetProtocol_MinimumWindowSize, ENetConstants::ENetProtocol_MaximumWindowSize);
ENetProtocol verifyCommand;
verifyCommand.header.command = ENetProtocolCommand_VerifyConnect | ENetProtocolFlag_Acknowledge;
verifyCommand.header.channelID = 0xFF;
ENetProtocol verifyCommand(ENetProtocolCommand_VerifyConnect | ENetProtocolFlag_Acknowledge, 0xFF);
verifyCommand.verifyConnect.outgoingPeerID = HostToNet(peer->m_incomingPeerID);
verifyCommand.verifyConnect.incomingSessionID = peer->m_outgoingSessionID;
verifyCommand.verifyConnect.outgoingSessionID = peer->m_incomingSessionID;
@ -623,8 +571,7 @@ namespace Nz
verifyCommand.verifyConnect.packetThrottleAcceleration = HostToNet(peer->m_packetThrottleAcceleration);
verifyCommand.verifyConnect.packetThrottleDeceleration = HostToNet(peer->m_packetThrottleDeceleration);
verifyCommand.verifyConnect.connectID = peer->m_connectID;
peer->QueueOutgoingCommand(verifyCommand, nullptr, 0, 0);
peer->QueueOutgoingCommand(verifyCommand);
return peer;
}
@ -930,7 +877,7 @@ namespace Nz
{
--startCommand->fragmentsRemaining;
startCommand->fragments.Set(fragmentNumber);
startCommand->fragments.Set(fragmentNumber, true);
if (fragmentOffset + fragmentLength > startCommand->packet->data.GetDataSize())
fragmentLength = startCommand->packet->data.GetDataSize() - fragmentOffset;
@ -1036,7 +983,7 @@ namespace Nz
break;
if ((incomingCommand.command.header.command & ENetProtocolCommand_Mask) != ENetProtocolCommand_SendUnreliableFragment ||
totalLength != incomingCommand.packet->data.GetDataSize() || fragmentCount != incomingCommand.fragments.size())
totalLength != incomingCommand.packet->data.GetDataSize() || fragmentCount != incomingCommand.fragments.GetSize())
return false;
startCommand = &incomingCommand;
@ -1054,7 +1001,7 @@ namespace Nz
{
--startCommand->fragmentsRemaining;
startCommand->fragments.Set(fragmentNumber);
startCommand->fragments.Set(fragmentNumber, true);
if (fragmentOffset + fragmentLength > startCommand->packet->data.GetDataSize())
fragmentLength = startCommand->packet->data.GetDataSize() - fragmentOffset;
@ -1405,8 +1352,7 @@ namespace Nz
if (!currentPeer->m_acknowledgements.empty())
SendAcknowledgements(currentPeer);
if (checkForTimeouts && !currentPeer->m_sentReliableCommands.empty() && ENET_TIME_GREATER_EQUAL(m_serviceTime, currentPeer->m_nextTimeout) &&
CheckTimeouts(currentPeer, event))
if (checkForTimeouts && !currentPeer->m_sentReliableCommands.empty() && ENET_TIME_GREATER_EQUAL(m_serviceTime, currentPeer->m_nextTimeout) && currentPeer->CheckTimeouts(event))
{
if (event && event->type != ENetEventType::None)
return 1;
@ -1617,14 +1563,7 @@ namespace Nz
if ((throttle * peer.m_outgoingDataTotal) / ENetConstants::ENetPeer_PacketThrottleScale <= peerBandwidth)
continue;
peer.m_packetThrottleLimit = (peerBandwidth * ENetConstants::ENetPeer_PacketThrottleScale) / peer.m_outgoingDataTotal;
if (peer.m_packetThrottleLimit == 0)
peer.m_packetThrottleLimit = 1;
if (peer.m_packetThrottle > peer.m_packetThrottleLimit)
peer.m_packetThrottle = peer.m_packetThrottleLimit;
peer.m_packetThrottleLimit = Clamp<UInt32>((peerBandwidth * ENetConstants::ENetPeer_PacketThrottleScale) / peer.m_outgoingDataTotal, 0, peer.m_packetThrottleLimit);
peer.m_outgoingBandwidthThrottleEpoch = currentTime;
peer.m_incomingDataTotal = 0;
@ -1650,9 +1589,7 @@ namespace Nz
continue;
peer.m_packetThrottleLimit = throttle;
if (peer.m_packetThrottle > peer.m_packetThrottleLimit)
peer.m_packetThrottle = peer.m_packetThrottleLimit;
peer.m_packetThrottle = std::min(peer.m_packetThrottle, peer.m_packetThrottleLimit);
peer.m_incomingDataTotal = 0;
peer.m_outgoingDataTotal = 0;
@ -1698,9 +1635,7 @@ namespace Nz
if (!peer.IsConnected())
continue;
ENetProtocol command;
command.header.command = ENetProtocolCommand_BandwidthLimit | ENetProtocolFlag_Acknowledge;
command.header.channelID = 0xFF;
ENetProtocol command(ENetProtocolCommand_BandwidthLimit | ENetProtocolFlag_Acknowledge, 0xFF);
command.bandwidthLimit.outgoingBandwidth = HostToNet(m_outgoingBandwidth);
if (peer.m_incomingBandwidthThrottleEpoch == currentTime)
@ -1708,7 +1643,7 @@ namespace Nz
else
command.bandwidthLimit.incomingBandwidth = HostToNet(bandwidthLimit);
peer.QueueOutgoingCommand(command, nullptr, 0, 0);
peer.QueueOutgoingCommand(command);
}
}
}

View File

@ -5,6 +5,15 @@
#include <iostream>
#include <Nazara/Network/Debug.hpp>
#define ENET_TIME_OVERFLOW 86400000
#define ENET_TIME_LESS(a, b) ((a) - (b) >= ENET_TIME_OVERFLOW)
#define ENET_TIME_GREATER(a, b) ((b) - (a) >= ENET_TIME_OVERFLOW)
#define ENET_TIME_LESS_EQUAL(a, b) (! ENET_TIME_GREATER (a, b))
#define ENET_TIME_GREATER_EQUAL(a, b) (! ENET_TIME_LESS (a, b))
#define ENET_TIME_DIFFERENCE(a, b) ((a) - (b) >= ENET_TIME_OVERFLOW ? (b) - (a) : (a) - (b))
namespace Nz
{
/// Temporary
@ -49,9 +58,7 @@ namespace Nz
ResetQueues();
ENetProtocol command;
command.header.command = ENetProtocolCommand_Disconnect;
command.header.channelID = 0xFF;
ENetProtocol command(ENetProtocolCommand_Disconnect, 0xFF);
command.disconnect.data = HostToNet(data);
if (IsConnected())
@ -59,7 +66,7 @@ namespace Nz
else
command.header.command |= ENetProtocolFlag_Unsequenced;
QueueOutgoingCommand(command, nullptr, 0, 0);
QueueOutgoingCommand(command);
if (IsConnected())
{
@ -95,12 +102,9 @@ namespace Nz
{
ResetQueues();
ENetProtocol command;
command.header.command = ENetProtocolCommand_Disconnect | ENetProtocolFlag_Unsequenced;
command.header.channelID = 0xFF;
ENetProtocol command(ENetProtocolCommand_Disconnect | ENetProtocolFlag_Unsequenced, 0xFF);
command.disconnect.data = HostToNet(data);
QueueOutgoingCommand(command, nullptr, 0, 0);
QueueOutgoingCommand(command);
m_host->Flush();
}
@ -116,8 +120,7 @@ namespace Nz
ENetProtocol command;
command.header.command = ENetProtocolCommand_Ping | ENetProtocolFlag_Acknowledge;
command.header.channelID = 0xFF;
QueueOutgoingCommand(command, nullptr, 0, 0);
QueueOutgoingCommand(command);
}
bool ENetPeer::Receive(ENetPacketRef* packet, UInt8* channelId)
@ -299,66 +302,56 @@ namespace Nz
m_packetThrottleAcceleration = acceleration;
m_packetThrottleDeceleration = deceleration;
ENetProtocol command;
command.header.command = ENetProtocolCommand_ThrottleConfigure | ENetProtocolFlag_Acknowledge;
command.header.channelID = 0xFF;
ENetProtocol command(ENetProtocolCommand_ThrottleConfigure | ENetProtocolFlag_Acknowledge, 0xFF);
command.throttleConfigure.packetThrottleInterval = HostToNet(interval);
command.throttleConfigure.packetThrottleAcceleration = HostToNet(acceleration);
command.throttleConfigure.packetThrottleDeceleration = HostToNet(deceleration);
QueueOutgoingCommand(command, nullptr, 0, 0);
QueueOutgoingCommand(command);
}
void ENetPeer::InitIncoming(std::size_t channelCount, const IpAddress& address, ENetProtocolConnect& incomingCommand)
bool ENetPeer::CheckTimeouts(ENetEvent* event)
{
m_channels.resize(channelCount);
m_address = address;
auto currentCommand = m_sentReliableCommands.begin();
while (currentCommand != m_sentReliableCommands.end())
{
auto outgoingCommand = currentCommand;
m_connectID = incomingCommand.connectID;
m_eventData = NetToHost(incomingCommand.data);
m_incomingBandwidth = NetToHost(incomingCommand.incomingBandwidth);
m_outgoingBandwidth = NetToHost(incomingCommand.outgoingBandwidth);
m_packetThrottleInterval = NetToHost(incomingCommand.packetThrottleInterval);
m_packetThrottleAcceleration = NetToHost(incomingCommand.packetThrottleAcceleration);
m_packetThrottleDeceleration = NetToHost(incomingCommand.packetThrottleDeceleration);
m_outgoingPeerID = NetToHost(incomingCommand.outgoingPeerID);
m_state = ENetPeerState::AcknowledgingConnect;
++currentCommand;
UInt8 incomingSessionId, outgoingSessionId;
if (ENET_TIME_DIFFERENCE(m_host->m_serviceTime, outgoingCommand->sentTime) < outgoingCommand->roundTripTimeout)
continue;
incomingSessionId = incomingCommand.incomingSessionID == 0xFF ? m_outgoingSessionID : incomingCommand.incomingSessionID;
incomingSessionId = (incomingSessionId + 1) & (ENetProtocolHeaderSessionMask >> ENetProtocolHeaderSessionShift);
if (incomingSessionId == m_outgoingSessionID)
incomingSessionId = (incomingSessionId + 1) & (ENetProtocolHeaderSessionMask >> ENetProtocolHeaderSessionShift);
m_outgoingSessionID = incomingSessionId;
if (m_earliestTimeout == 0 || ENET_TIME_LESS(outgoingCommand->sentTime, m_earliestTimeout))
m_earliestTimeout = outgoingCommand->sentTime;
outgoingSessionId = incomingCommand.outgoingSessionID == 0xFF ? m_incomingSessionID : incomingCommand.outgoingSessionID;
outgoingSessionId = (outgoingSessionId + 1) & (ENetProtocolHeaderSessionMask >> ENetProtocolHeaderSessionShift);
if (outgoingSessionId == m_incomingSessionID)
outgoingSessionId = (outgoingSessionId + 1) & (ENetProtocolHeaderSessionMask >> ENetProtocolHeaderSessionShift);
m_incomingSessionID = outgoingSessionId;
if (m_earliestTimeout != 0 && (ENET_TIME_DIFFERENCE(m_host->m_serviceTime, m_earliestTimeout) >= m_timeoutMaximum ||
(outgoingCommand->roundTripTimeout >= outgoingCommand->roundTripTimeoutLimit && ENET_TIME_DIFFERENCE(m_host->m_serviceTime, m_earliestTimeout) >= m_timeoutMinimum)))
{
m_host->NotifyDisconnect(this, event);
return true;
}
m_mtu = Clamp<UInt32>(NetToHost(incomingCommand.mtu), ENetConstants::ENetProtocol_MinimumMTU, ENetConstants::ENetProtocol_MaximumMTU);
if (outgoingCommand->packet)
m_reliableDataInTransit -= outgoingCommand->fragmentLength;
if (m_host->m_outgoingBandwidth == 0 && m_incomingBandwidth == 0)
m_windowSize = ENetConstants::ENetProtocol_MaximumWindowSize;
else if (m_host->m_outgoingBandwidth == 0 || m_incomingBandwidth == 0)
m_windowSize = (std::max(m_host->m_outgoingBandwidth, m_incomingBandwidth) / ENetConstants::ENetPeer_WindowSizeScale) * ENetConstants::ENetProtocol_MinimumWindowSize;
else
m_windowSize = (std::min(m_host->m_outgoingBandwidth, m_incomingBandwidth) / ENetConstants::ENetPeer_WindowSizeScale) * ENetConstants::ENetProtocol_MinimumWindowSize;
++m_packetsLost;
m_windowSize = Clamp<UInt32>(m_windowSize, ENetConstants::ENetProtocol_MinimumWindowSize, ENetConstants::ENetProtocol_MaximumWindowSize);
}
outgoingCommand->roundTripTimeout *= 2;
void ENetPeer::InitOutgoing(std::size_t channelCount, const IpAddress& address, UInt32 connectId, UInt32 windowSize)
{
m_channels.resize(channelCount);
m_outgoingReliableCommands.emplace_front(std::move(*outgoingCommand));
m_sentReliableCommands.erase(outgoingCommand);
m_address = address;
m_connectID = connectId;
m_state = ENetPeerState::Connecting;
m_windowSize = Clamp<UInt32>(windowSize, ENetConstants::ENetProtocol_MinimumWindowSize, ENetConstants::ENetProtocol_MaximumWindowSize);
// Okay this should just never procs, I don't see how it would be possible
/*if (currentCommand == enet_list_begin(&peer->sentReliableCommands) &&
!enet_list_empty(&peer->sentReliableCommands))
{
outgoingCommand = (ENetOutgoingCommand *) currentCommand;
peer->nextTimeout = outgoingCommand->sentTime + outgoingCommand->roundTripTimeout;
}*/
}
return false;
}
void ENetPeer::DispatchState(ENetPeerState state)
@ -472,6 +465,57 @@ namespace Nz
channel.incomingUnreliableCommands.erase(channel.incomingUnreliableCommands.begin(), droppedCommand);
}
void ENetPeer::InitIncoming(std::size_t channelCount, const IpAddress& address, ENetProtocolConnect& incomingCommand)
{
m_channels.resize(channelCount);
m_address = address;
m_connectID = incomingCommand.connectID;
m_eventData = NetToHost(incomingCommand.data);
m_incomingBandwidth = NetToHost(incomingCommand.incomingBandwidth);
m_outgoingBandwidth = NetToHost(incomingCommand.outgoingBandwidth);
m_packetThrottleInterval = NetToHost(incomingCommand.packetThrottleInterval);
m_packetThrottleAcceleration = NetToHost(incomingCommand.packetThrottleAcceleration);
m_packetThrottleDeceleration = NetToHost(incomingCommand.packetThrottleDeceleration);
m_outgoingPeerID = NetToHost(incomingCommand.outgoingPeerID);
m_state = ENetPeerState::AcknowledgingConnect;
UInt8 incomingSessionId, outgoingSessionId;
incomingSessionId = incomingCommand.incomingSessionID == 0xFF ? m_outgoingSessionID : incomingCommand.incomingSessionID;
incomingSessionId = (incomingSessionId + 1) & (ENetProtocolHeaderSessionMask >> ENetProtocolHeaderSessionShift);
if (incomingSessionId == m_outgoingSessionID)
incomingSessionId = (incomingSessionId + 1) & (ENetProtocolHeaderSessionMask >> ENetProtocolHeaderSessionShift);
m_outgoingSessionID = incomingSessionId;
outgoingSessionId = incomingCommand.outgoingSessionID == 0xFF ? m_incomingSessionID : incomingCommand.outgoingSessionID;
outgoingSessionId = (outgoingSessionId + 1) & (ENetProtocolHeaderSessionMask >> ENetProtocolHeaderSessionShift);
if (outgoingSessionId == m_incomingSessionID)
outgoingSessionId = (outgoingSessionId + 1) & (ENetProtocolHeaderSessionMask >> ENetProtocolHeaderSessionShift);
m_incomingSessionID = outgoingSessionId;
m_mtu = Clamp<UInt32>(NetToHost(incomingCommand.mtu), ENetConstants::ENetProtocol_MinimumMTU, ENetConstants::ENetProtocol_MaximumMTU);
if (m_host->m_outgoingBandwidth == 0 && m_incomingBandwidth == 0)
m_windowSize = ENetConstants::ENetProtocol_MaximumWindowSize;
else if (m_host->m_outgoingBandwidth == 0 || m_incomingBandwidth == 0)
m_windowSize = (std::max(m_host->m_outgoingBandwidth, m_incomingBandwidth) / ENetConstants::ENetPeer_WindowSizeScale) * ENetConstants::ENetProtocol_MinimumWindowSize;
else
m_windowSize = (std::min(m_host->m_outgoingBandwidth, m_incomingBandwidth) / ENetConstants::ENetPeer_WindowSizeScale) * ENetConstants::ENetProtocol_MinimumWindowSize;
m_windowSize = Clamp<UInt32>(m_windowSize, ENetConstants::ENetProtocol_MinimumWindowSize, ENetConstants::ENetProtocol_MaximumWindowSize);
}
void ENetPeer::InitOutgoing(std::size_t channelCount, const IpAddress& address, UInt32 connectId, UInt32 windowSize)
{
m_channels.resize(channelCount);
m_address = address;
m_connectID = connectId;
m_state = ENetPeerState::Connecting;
m_windowSize = Clamp<UInt32>(windowSize, ENetConstants::ENetProtocol_MinimumWindowSize, ENetConstants::ENetProtocol_MaximumWindowSize);
}
void ENetPeer::OnConnect()
{
if (!IsConnected())
@ -498,7 +542,7 @@ namespace Nz
{
std::list<OutgoingCommand>* commandList = nullptr;
bool found = true;
bool found = false;
auto currentCommand = m_sentReliableCommands.begin();
commandList = &m_sentReliableCommands;
for (; currentCommand != m_sentReliableCommands.end(); ++currentCommand)