mirror of
https://github.com/EQEmu/Server.git
synced 2025-12-15 20:51:29 +00:00
Bring back netcode to robust commit 34549a4 - proven and tested by PEQ and EZ as solid/stable with all of recent packet fixes
This commit is contained in:
parent
855796448c
commit
45b29aedf3
@ -365,7 +365,7 @@ void EQ::Net::DaybreakConnection::Process()
|
|||||||
FlushBuffer();
|
FlushBuffer();
|
||||||
}
|
}
|
||||||
|
|
||||||
ProcessInboundQueue();
|
ProcessQueue();
|
||||||
}
|
}
|
||||||
catch (std::exception ex) {
|
catch (std::exception ex) {
|
||||||
LogF(Logs::Detail, Logs::Netcode, "Error processing connection: {0}", ex.what());
|
LogF(Logs::Detail, Logs::Netcode, "Error processing connection: {0}", ex.what());
|
||||||
@ -440,7 +440,7 @@ void EQ::Net::DaybreakConnection::ProcessPacket(Packet &p)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void EQ::Net::DaybreakConnection::ProcessInboundQueue()
|
void EQ::Net::DaybreakConnection::ProcessQueue()
|
||||||
{
|
{
|
||||||
for (int i = 0; i < 4; ++i) {
|
for (int i = 0; i < 4; ++i) {
|
||||||
auto stream = &m_streams[i];
|
auto stream = &m_streams[i];
|
||||||
@ -459,31 +459,6 @@ void EQ::Net::DaybreakConnection::ProcessInboundQueue()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void EQ::Net::DaybreakConnection::ProcessOutboundQueue()
|
|
||||||
{
|
|
||||||
for (int i = 0; i < 4; ++i) {
|
|
||||||
auto stream = &m_streams[i];
|
|
||||||
|
|
||||||
if (stream->outstanding_bytes == 0) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (!stream->buffered_packets.empty()) {
|
|
||||||
auto &buff = stream->buffered_packets.front();
|
|
||||||
|
|
||||||
if (stream->outstanding_bytes + buff.sent.packet.Length() >= m_owner->m_options.max_outstanding_bytes ||
|
|
||||||
stream->outstanding_packets.size() + 1 >= m_owner->m_options.max_outstanding_packets) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
stream->outstanding_bytes += buff.sent.packet.Length();
|
|
||||||
stream->outstanding_packets.insert(std::make_pair(buff.seq, buff.sent));
|
|
||||||
InternalBufferedSend(buff.sent.packet);
|
|
||||||
stream->buffered_packets.pop_front();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void EQ::Net::DaybreakConnection::RemoveFromQueue(int stream, uint16_t seq)
|
void EQ::Net::DaybreakConnection::RemoveFromQueue(int stream, uint16_t seq)
|
||||||
{
|
{
|
||||||
auto s = &m_streams[stream];
|
auto s = &m_streams[stream];
|
||||||
@ -1044,7 +1019,7 @@ void EQ::Net::DaybreakConnection::ProcessResend(int stream)
|
|||||||
|
|
||||||
auto now = Clock::now();
|
auto now = Clock::now();
|
||||||
auto s = &m_streams[stream];
|
auto s = &m_streams[stream];
|
||||||
for (auto &entry : s->outstanding_packets) {
|
for (auto &entry : s->sent_packets) {
|
||||||
auto time_since_last_send = std::chrono::duration_cast<std::chrono::milliseconds>(now - entry.second.last_sent);
|
auto time_since_last_send = std::chrono::duration_cast<std::chrono::milliseconds>(now - entry.second.last_sent);
|
||||||
if (entry.second.times_resent == 0) {
|
if (entry.second.times_resent == 0) {
|
||||||
if ((size_t)time_since_last_send.count() > m_resend_delay) {
|
if ((size_t)time_since_last_send.count() > m_resend_delay) {
|
||||||
@ -1076,8 +1051,8 @@ void EQ::Net::DaybreakConnection::Ack(int stream, uint16_t seq)
|
|||||||
|
|
||||||
auto now = Clock::now();
|
auto now = Clock::now();
|
||||||
auto s = &m_streams[stream];
|
auto s = &m_streams[stream];
|
||||||
auto iter = s->outstanding_packets.begin();
|
auto iter = s->sent_packets.begin();
|
||||||
while (iter != s->outstanding_packets.end()) {
|
while (iter != s->sent_packets.end()) {
|
||||||
auto order = CompareSequence(seq, iter->first);
|
auto order = CompareSequence(seq, iter->first);
|
||||||
|
|
||||||
if (order != SequenceFuture) {
|
if (order != SequenceFuture) {
|
||||||
@ -1088,9 +1063,7 @@ void EQ::Net::DaybreakConnection::Ack(int stream, uint16_t seq)
|
|||||||
m_stats.last_ping = round_time;
|
m_stats.last_ping = round_time;
|
||||||
m_rolling_ping = (m_rolling_ping * 2 + round_time) / 3;
|
m_rolling_ping = (m_rolling_ping * 2 + round_time) / 3;
|
||||||
|
|
||||||
s->outstanding_bytes -= iter->second.packet.Length();
|
iter = s->sent_packets.erase(iter);
|
||||||
iter = s->outstanding_packets.erase(iter);
|
|
||||||
ProcessOutboundQueue();
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
++iter;
|
++iter;
|
||||||
@ -1102,8 +1075,8 @@ void EQ::Net::DaybreakConnection::OutOfOrderAck(int stream, uint16_t seq)
|
|||||||
{
|
{
|
||||||
auto now = Clock::now();
|
auto now = Clock::now();
|
||||||
auto s = &m_streams[stream];
|
auto s = &m_streams[stream];
|
||||||
auto iter = s->outstanding_packets.find(seq);
|
auto iter = s->sent_packets.find(seq);
|
||||||
if (iter != s->outstanding_packets.end()) {
|
if (iter != s->sent_packets.end()) {
|
||||||
uint64_t round_time = (uint64_t)std::chrono::duration_cast<std::chrono::milliseconds>(now - iter->second.last_sent).count();
|
uint64_t round_time = (uint64_t)std::chrono::duration_cast<std::chrono::milliseconds>(now - iter->second.last_sent).count();
|
||||||
|
|
||||||
m_stats.max_ping = std::max(m_stats.max_ping, round_time);
|
m_stats.max_ping = std::max(m_stats.max_ping, round_time);
|
||||||
@ -1111,31 +1084,10 @@ void EQ::Net::DaybreakConnection::OutOfOrderAck(int stream, uint16_t seq)
|
|||||||
m_stats.last_ping = round_time;
|
m_stats.last_ping = round_time;
|
||||||
m_rolling_ping = (m_rolling_ping * 2 + round_time) / 3;
|
m_rolling_ping = (m_rolling_ping * 2 + round_time) / 3;
|
||||||
|
|
||||||
s->outstanding_bytes -= iter->second.packet.Length();
|
s->sent_packets.erase(iter);
|
||||||
s->outstanding_packets.erase(iter);
|
|
||||||
ProcessOutboundQueue();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void EQ::Net::DaybreakConnection::BufferPacket(int stream, uint16_t seq, DaybreakSentPacket &sent)
|
|
||||||
{
|
|
||||||
auto s = &m_streams[stream];
|
|
||||||
//If we can send the packet then send it
|
|
||||||
//else buffer it to be sent when we can send it
|
|
||||||
if (s->outstanding_bytes + sent.packet.Length() >= m_owner->m_options.max_outstanding_bytes || s->outstanding_packets.size() + 1 >= m_owner->m_options.max_outstanding_packets) {
|
|
||||||
//Would go over one of the limits, buffer this packet.
|
|
||||||
DaybreakBufferedPacket bp;
|
|
||||||
bp.sent = std::move(sent);
|
|
||||||
bp.seq = seq;
|
|
||||||
s->buffered_packets.push_back(bp);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
s->outstanding_bytes += sent.packet.Length();
|
|
||||||
s->outstanding_packets.insert(std::make_pair(seq, sent));
|
|
||||||
InternalBufferedSend(sent.packet);
|
|
||||||
}
|
|
||||||
|
|
||||||
void EQ::Net::DaybreakConnection::SendAck(int stream_id, uint16_t seq)
|
void EQ::Net::DaybreakConnection::SendAck(int stream_id, uint16_t seq)
|
||||||
{
|
{
|
||||||
DaybreakReliableHeader ack;
|
DaybreakReliableHeader ack;
|
||||||
@ -1187,10 +1139,6 @@ void EQ::Net::DaybreakConnection::InternalBufferedSend(Packet &p)
|
|||||||
FlushBuffer();
|
FlushBuffer();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_buffered_packets.size() == 0) {
|
|
||||||
m_hold_time = Clock::now();
|
|
||||||
}
|
|
||||||
|
|
||||||
DynamicPacket copy;
|
DynamicPacket copy;
|
||||||
copy.PutPacket(0, p);
|
copy.PutPacket(0, p);
|
||||||
m_buffered_packets.push_back(copy);
|
m_buffered_packets.push_back(copy);
|
||||||
@ -1345,9 +1293,11 @@ void EQ::Net::DaybreakConnection::InternalQueuePacket(Packet &p, int stream_id,
|
|||||||
sent.last_sent = Clock::now();
|
sent.last_sent = Clock::now();
|
||||||
sent.first_sent = Clock::now();
|
sent.first_sent = Clock::now();
|
||||||
sent.times_resent = 0;
|
sent.times_resent = 0;
|
||||||
BufferPacket(stream_id, stream->sequence_out, sent);
|
stream->sent_packets.insert(std::make_pair(stream->sequence_out, sent));
|
||||||
stream->sequence_out++;
|
stream->sequence_out++;
|
||||||
|
|
||||||
|
InternalBufferedSend(first_packet);
|
||||||
|
|
||||||
while (used < length) {
|
while (used < length) {
|
||||||
auto left = length - used;
|
auto left = length - used;
|
||||||
DynamicPacket packet;
|
DynamicPacket packet;
|
||||||
@ -1371,8 +1321,10 @@ void EQ::Net::DaybreakConnection::InternalQueuePacket(Packet &p, int stream_id,
|
|||||||
sent.last_sent = Clock::now();
|
sent.last_sent = Clock::now();
|
||||||
sent.first_sent = Clock::now();
|
sent.first_sent = Clock::now();
|
||||||
sent.times_resent = 0;
|
sent.times_resent = 0;
|
||||||
BufferPacket(stream_id, stream->sequence_out, sent);
|
stream->sent_packets.insert(std::make_pair(stream->sequence_out, sent));
|
||||||
stream->sequence_out++;
|
stream->sequence_out++;
|
||||||
|
|
||||||
|
InternalBufferedSend(packet);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -1389,8 +1341,10 @@ void EQ::Net::DaybreakConnection::InternalQueuePacket(Packet &p, int stream_id,
|
|||||||
sent.last_sent = Clock::now();
|
sent.last_sent = Clock::now();
|
||||||
sent.first_sent = Clock::now();
|
sent.first_sent = Clock::now();
|
||||||
sent.times_resent = 0;
|
sent.times_resent = 0;
|
||||||
BufferPacket(stream_id, stream->sequence_out, sent);
|
stream->sent_packets.insert(std::make_pair(stream->sequence_out, sent));
|
||||||
stream->sequence_out++;
|
stream->sequence_out++;
|
||||||
|
|
||||||
|
InternalBufferedSend(packet);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -8,8 +8,7 @@
|
|||||||
#include <functional>
|
#include <functional>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <unordered_map>
|
#include <queue>
|
||||||
#include <deque>
|
|
||||||
#include <list>
|
#include <list>
|
||||||
|
|
||||||
namespace EQ
|
namespace EQ
|
||||||
@ -145,12 +144,6 @@ namespace EQ
|
|||||||
size_t times_resent;
|
size_t times_resent;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct DaybreakBufferedPacket
|
|
||||||
{
|
|
||||||
uint16_t seq;
|
|
||||||
DaybreakSentPacket sent;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct DaybreakStream
|
struct DaybreakStream
|
||||||
{
|
{
|
||||||
DaybreakStream() {
|
DaybreakStream() {
|
||||||
@ -158,20 +151,17 @@ namespace EQ
|
|||||||
sequence_out = 0;
|
sequence_out = 0;
|
||||||
fragment_current_bytes = 0;
|
fragment_current_bytes = 0;
|
||||||
fragment_total_bytes = 0;
|
fragment_total_bytes = 0;
|
||||||
outstanding_bytes = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t sequence_in;
|
uint16_t sequence_in;
|
||||||
uint16_t sequence_out;
|
uint16_t sequence_out;
|
||||||
std::unordered_map<uint16_t, Packet*> packet_queue;
|
std::map<uint16_t, Packet*> packet_queue;
|
||||||
std::deque<DaybreakBufferedPacket> buffered_packets;
|
|
||||||
|
|
||||||
DynamicPacket fragment_packet;
|
DynamicPacket fragment_packet;
|
||||||
uint32_t fragment_current_bytes;
|
uint32_t fragment_current_bytes;
|
||||||
uint32_t fragment_total_bytes;
|
uint32_t fragment_total_bytes;
|
||||||
|
|
||||||
std::unordered_map<uint16_t, DaybreakSentPacket> outstanding_packets;
|
std::map<uint16_t, DaybreakSentPacket> sent_packets;
|
||||||
size_t outstanding_bytes;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
DaybreakStream m_streams[4];
|
DaybreakStream m_streams[4];
|
||||||
@ -179,8 +169,7 @@ namespace EQ
|
|||||||
|
|
||||||
void Process();
|
void Process();
|
||||||
void ProcessPacket(Packet &p);
|
void ProcessPacket(Packet &p);
|
||||||
void ProcessInboundQueue();
|
void ProcessQueue();
|
||||||
void ProcessOutboundQueue();
|
|
||||||
void RemoveFromQueue(int stream, uint16_t seq);
|
void RemoveFromQueue(int stream, uint16_t seq);
|
||||||
void AddToQueue(int stream, uint16_t seq, const Packet &p);
|
void AddToQueue(int stream, uint16_t seq, const Packet &p);
|
||||||
void ProcessDecodedPacket(const Packet &p);
|
void ProcessDecodedPacket(const Packet &p);
|
||||||
@ -196,7 +185,6 @@ namespace EQ
|
|||||||
void ProcessResend(int stream);
|
void ProcessResend(int stream);
|
||||||
void Ack(int stream, uint16_t seq);
|
void Ack(int stream, uint16_t seq);
|
||||||
void OutOfOrderAck(int stream, uint16_t seq);
|
void OutOfOrderAck(int stream, uint16_t seq);
|
||||||
void BufferPacket(int stream, uint16_t seq, DaybreakSentPacket &sent);
|
|
||||||
|
|
||||||
void SendConnect();
|
void SendConnect();
|
||||||
void SendKeepAlive();
|
void SendKeepAlive();
|
||||||
@ -219,8 +207,8 @@ namespace EQ
|
|||||||
keepalive_delay_ms = 9000;
|
keepalive_delay_ms = 9000;
|
||||||
resend_delay_ms = 150;
|
resend_delay_ms = 150;
|
||||||
resend_delay_factor = 1.5;
|
resend_delay_factor = 1.5;
|
||||||
resend_delay_min = 300;
|
resend_delay_min = 150;
|
||||||
resend_delay_max = 3000;
|
resend_delay_max = 1000;
|
||||||
connect_delay_ms = 500;
|
connect_delay_ms = 500;
|
||||||
stale_connection_ms = 90000;
|
stale_connection_ms = 90000;
|
||||||
connect_stale_ms = 5000;
|
connect_stale_ms = 5000;
|
||||||
@ -236,8 +224,6 @@ namespace EQ
|
|||||||
tic_rate_hertz = 60.0;
|
tic_rate_hertz = 60.0;
|
||||||
resend_timeout = 90000;
|
resend_timeout = 90000;
|
||||||
connection_close_time = 2000;
|
connection_close_time = 2000;
|
||||||
max_outstanding_packets = 400;
|
|
||||||
max_outstanding_bytes = 400 * 512;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t max_packet_size;
|
size_t max_packet_size;
|
||||||
@ -260,8 +246,6 @@ namespace EQ
|
|||||||
size_t connection_close_time;
|
size_t connection_close_time;
|
||||||
DaybreakEncodeType encode_passes[2];
|
DaybreakEncodeType encode_passes[2];
|
||||||
int port;
|
int port;
|
||||||
size_t max_outstanding_packets;
|
|
||||||
size_t max_outstanding_bytes;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class DaybreakConnectionManager
|
class DaybreakConnectionManager
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user