mirror of
https://github.com/EQEmu/Server.git
synced 2025-12-13 10:31:29 +00:00
Some work on congestion avoidance now uses a sliding congestion window instead of a static one
This commit is contained in:
parent
d6ac686a54
commit
5c6f684808
@ -283,6 +283,9 @@ EQ::Net::DaybreakConnection::DaybreakConnection(DaybreakConnectionManager *owner
|
|||||||
m_combined[0] = 0;
|
m_combined[0] = 0;
|
||||||
m_combined[1] = OP_Combined;
|
m_combined[1] = OP_Combined;
|
||||||
m_last_session_stats = Clock::now();
|
m_last_session_stats = Clock::now();
|
||||||
|
m_outstanding_bytes = 0;
|
||||||
|
m_cwnd = m_max_packet_size;
|
||||||
|
m_ssthresh = m_owner->m_options.max_outstanding_bytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
//new connection made as client
|
//new connection made as client
|
||||||
@ -306,6 +309,9 @@ EQ::Net::DaybreakConnection::DaybreakConnection(DaybreakConnectionManager *owner
|
|||||||
m_combined[0] = 0;
|
m_combined[0] = 0;
|
||||||
m_combined[1] = OP_Combined;
|
m_combined[1] = OP_Combined;
|
||||||
m_last_session_stats = Clock::now();
|
m_last_session_stats = Clock::now();
|
||||||
|
m_outstanding_bytes = 0;
|
||||||
|
m_cwnd = m_max_packet_size;
|
||||||
|
m_ssthresh = m_owner->m_options.max_outstanding_bytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
EQ::Net::DaybreakConnection::~DaybreakConnection()
|
EQ::Net::DaybreakConnection::~DaybreakConnection()
|
||||||
@ -464,19 +470,15 @@ void EQ::Net::DaybreakConnection::ProcessOutboundQueue()
|
|||||||
for (int i = 0; i < 4; ++i) {
|
for (int i = 0; i < 4; ++i) {
|
||||||
auto stream = &m_streams[i];
|
auto stream = &m_streams[i];
|
||||||
|
|
||||||
if (stream->outstanding_bytes == 0) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (!stream->buffered_packets.empty()) {
|
while (!stream->buffered_packets.empty()) {
|
||||||
auto &buff = stream->buffered_packets.front();
|
auto &buff = stream->buffered_packets.front();
|
||||||
|
|
||||||
if (stream->outstanding_bytes + buff.sent.packet.Length() >= m_owner->m_options.max_outstanding_bytes ||
|
if (m_outstanding_bytes + buff.sent.packet.Length() >= m_cwnd) {
|
||||||
stream->outstanding_packets.size() + 1 >= m_owner->m_options.max_outstanding_packets) {
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
stream->outstanding_bytes += buff.sent.packet.Length();
|
LogF(Logs::Detail, Logs::Netcode, "Sending buffered packet {0} on stream {1}", buff.seq, i);
|
||||||
|
m_outstanding_bytes += buff.sent.packet.Length();
|
||||||
stream->outstanding_packets.insert(std::make_pair(buff.seq, buff.sent));
|
stream->outstanding_packets.insert(std::make_pair(buff.seq, buff.sent));
|
||||||
InternalSend(buff.sent.packet);
|
InternalSend(buff.sent.packet);
|
||||||
stream->buffered_packets.pop_front();
|
stream->buffered_packets.pop_front();
|
||||||
@ -1051,7 +1053,10 @@ void EQ::Net::DaybreakConnection::ProcessResend(int stream)
|
|||||||
InternalBufferedSend(entry.second.packet);
|
InternalBufferedSend(entry.second.packet);
|
||||||
entry.second.last_sent = now;
|
entry.second.last_sent = now;
|
||||||
entry.second.times_resent++;
|
entry.second.times_resent++;
|
||||||
m_rolling_ping += 100;
|
|
||||||
|
LogF(Logs::Detail, Logs::Netcode, "Congestion detected, reducing window size");
|
||||||
|
m_ssthresh = m_cwnd / 2;
|
||||||
|
m_cwnd = m_cwnd / 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -1065,7 +1070,10 @@ void EQ::Net::DaybreakConnection::ProcessResend(int stream)
|
|||||||
InternalBufferedSend(entry.second.packet);
|
InternalBufferedSend(entry.second.packet);
|
||||||
entry.second.last_sent = now;
|
entry.second.last_sent = now;
|
||||||
entry.second.times_resent++;
|
entry.second.times_resent++;
|
||||||
m_rolling_ping += 100;
|
|
||||||
|
LogF(Logs::Detail, Logs::Netcode, "Congestion detected, reducing window size");
|
||||||
|
m_ssthresh = m_cwnd / 2;
|
||||||
|
m_cwnd = m_cwnd / 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1086,10 +1094,29 @@ void EQ::Net::DaybreakConnection::Ack(int stream, uint16_t seq)
|
|||||||
m_stats.max_ping = std::max(m_stats.max_ping, round_time);
|
m_stats.max_ping = std::max(m_stats.max_ping, round_time);
|
||||||
m_stats.min_ping = std::min(m_stats.min_ping, round_time);
|
m_stats.min_ping = std::min(m_stats.min_ping, round_time);
|
||||||
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 * 4 + round_time) / 5;
|
||||||
|
|
||||||
s->outstanding_bytes -= iter->second.packet.Length();
|
m_outstanding_bytes -= iter->second.packet.Length();
|
||||||
iter = s->outstanding_packets.erase(iter);
|
iter = s->outstanding_packets.erase(iter);
|
||||||
|
if (m_cwnd < m_ssthresh) {
|
||||||
|
//Still in slow start mode
|
||||||
|
m_cwnd *= 2;
|
||||||
|
if (m_cwnd > m_owner->m_options.max_outstanding_bytes) {
|
||||||
|
m_cwnd = m_owner->m_options.max_outstanding_bytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
LogF(Logs::Detail, Logs::Netcode, "Increasing cwnd size new size is {0}", m_cwnd);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
m_cwnd += m_max_packet_size;
|
||||||
|
|
||||||
|
if (m_cwnd > m_owner->m_options.max_outstanding_bytes) {
|
||||||
|
m_cwnd = m_owner->m_options.max_outstanding_bytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
LogF(Logs::Detail, Logs::Netcode, "Increasing cwnd size new size is {0}", m_cwnd);
|
||||||
|
}
|
||||||
|
|
||||||
ProcessOutboundQueue();
|
ProcessOutboundQueue();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -1111,8 +1138,28 @@ 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();
|
m_outstanding_bytes -= iter->second.packet.Length();
|
||||||
s->outstanding_packets.erase(iter);
|
s->outstanding_packets.erase(iter);
|
||||||
|
|
||||||
|
if (m_cwnd < m_ssthresh) {
|
||||||
|
//Still in slow start mode
|
||||||
|
m_cwnd *= 2;
|
||||||
|
if (m_cwnd > m_owner->m_options.max_outstanding_bytes) {
|
||||||
|
m_cwnd = m_owner->m_options.max_outstanding_bytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
LogF(Logs::Detail, Logs::Netcode, "Increasing cwnd size new size is {0}", m_cwnd);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
m_cwnd += m_max_packet_size;
|
||||||
|
|
||||||
|
if (m_cwnd > m_owner->m_options.max_outstanding_bytes) {
|
||||||
|
m_cwnd = m_owner->m_options.max_outstanding_bytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
LogF(Logs::Detail, Logs::Netcode, "Increasing cwnd size new size is {0}", m_cwnd);
|
||||||
|
}
|
||||||
|
|
||||||
ProcessOutboundQueue();
|
ProcessOutboundQueue();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1122,16 +1169,17 @@ void EQ::Net::DaybreakConnection::BufferPacket(int stream, uint16_t seq, Daybrea
|
|||||||
auto s = &m_streams[stream];
|
auto s = &m_streams[stream];
|
||||||
//If we can send the packet then send it
|
//If we can send the packet then send it
|
||||||
//else buffer it to be sent when we can 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) {
|
if (m_outstanding_bytes + sent.packet.Length() > m_cwnd) {
|
||||||
//Would go over one of the limits, buffer this packet.
|
//Would go over one of the limits, buffer this packet.
|
||||||
DaybreakBufferedPacket bp;
|
DaybreakBufferedPacket bp;
|
||||||
bp.sent = std::move(sent);
|
bp.sent = std::move(sent);
|
||||||
bp.seq = seq;
|
bp.seq = seq;
|
||||||
s->buffered_packets.push_back(bp);
|
s->buffered_packets.push_back(bp);
|
||||||
|
LogF(Logs::Detail, Logs::Netcode, "Buffering packet {0} on stream {1}", seq, stream);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
s->outstanding_bytes += sent.packet.Length();
|
m_outstanding_bytes += sent.packet.Length();
|
||||||
s->outstanding_packets.insert(std::make_pair(seq, sent));
|
s->outstanding_packets.insert(std::make_pair(seq, sent));
|
||||||
InternalSend(sent.packet);
|
InternalSend(sent.packet);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -136,6 +136,9 @@ namespace EQ
|
|||||||
size_t m_resend_delay;
|
size_t m_resend_delay;
|
||||||
size_t m_rolling_ping;
|
size_t m_rolling_ping;
|
||||||
Timestamp m_close_time;
|
Timestamp m_close_time;
|
||||||
|
size_t m_outstanding_bytes;
|
||||||
|
size_t m_cwnd;
|
||||||
|
size_t m_ssthresh;
|
||||||
|
|
||||||
struct DaybreakSentPacket
|
struct DaybreakSentPacket
|
||||||
{
|
{
|
||||||
@ -158,7 +161,6 @@ 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;
|
||||||
@ -171,7 +173,6 @@ namespace EQ
|
|||||||
uint32_t fragment_total_bytes;
|
uint32_t fragment_total_bytes;
|
||||||
|
|
||||||
std::unordered_map<uint16_t, DaybreakSentPacket> outstanding_packets;
|
std::unordered_map<uint16_t, DaybreakSentPacket> outstanding_packets;
|
||||||
size_t outstanding_bytes;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
DaybreakStream m_streams[4];
|
DaybreakStream m_streams[4];
|
||||||
@ -236,8 +237,7 @@ 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 = 300;
|
max_outstanding_bytes = 65535;
|
||||||
max_outstanding_bytes = 200 * 512;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t max_packet_size;
|
size_t max_packet_size;
|
||||||
@ -260,7 +260,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;
|
size_t max_outstanding_bytes;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user