From a7c0e82c9ebbde140ab83e2b7358e11eef51166b Mon Sep 17 00:00:00 2001 From: KimLS Date: Wed, 5 Jul 2017 20:24:39 -0700 Subject: [PATCH] Tweaks and bug fixes --- common/net/daybreak_connection.cpp | 46 +++++++++++++++++++----------- common/net/daybreak_connection.h | 5 +++- 2 files changed, 33 insertions(+), 18 deletions(-) diff --git a/common/net/daybreak_connection.cpp b/common/net/daybreak_connection.cpp index cac63451c..34f325434 100644 --- a/common/net/daybreak_connection.cpp +++ b/common/net/daybreak_connection.cpp @@ -285,7 +285,8 @@ EQ::Net::DaybreakConnection::DaybreakConnection(DaybreakConnectionManager *owner m_combined[1] = OP_Combined; m_last_session_stats = Clock::now(); m_outstanding_bytes = 0; - m_cwnd = m_max_packet_size * 4; + m_outstanding_packets = 0; + m_cwnd = m_max_packet_size; m_ssthresh = m_owner->m_options.max_outstanding_bytes; } @@ -311,7 +312,8 @@ EQ::Net::DaybreakConnection::DaybreakConnection(DaybreakConnectionManager *owner m_combined[1] = OP_Combined; m_last_session_stats = Clock::now(); m_outstanding_bytes = 0; - m_cwnd = m_max_packet_size * 4; + m_outstanding_packets = 0; + m_cwnd = m_max_packet_size; m_ssthresh = m_owner->m_options.max_outstanding_bytes; } @@ -373,11 +375,6 @@ void EQ::Net::DaybreakConnection::Process() } ProcessInboundQueue(); - - if (m_outstanding_bytes == 0) { - m_cwnd = 4 * m_max_packet_size; - m_ssthresh = m_owner->m_options.max_outstanding_bytes; - } } catch (std::exception ex) { LogF(Logs::Detail, Logs::Netcode, "Error processing connection: {0}", ex.what()); @@ -479,12 +476,17 @@ void EQ::Net::DaybreakConnection::ProcessOutboundQueue() while (!stream->buffered_packets.empty()) { auto &buff = stream->buffered_packets.front(); + if (m_outstanding_packets + 1 >= m_owner->m_options.max_outstanding_packets) { + break; + } + if (m_outstanding_bytes + buff.sent.packet.Length() >= m_cwnd) { break; } LogF(Logs::Detail, Logs::Netcode, "Sending buffered packet {0} on stream {1}", buff.seq, i); m_outstanding_bytes += buff.sent.packet.Length(); + m_outstanding_packets++; stream->outstanding_packets.insert(std::make_pair(buff.seq, buff.sent)); InternalBufferedSend(buff.sent.packet); stream->buffered_packets.pop_front(); @@ -495,11 +497,11 @@ void EQ::Net::DaybreakConnection::ProcessOutboundQueue() void EQ::Net::DaybreakConnection::IncreaseCongestionWindow() { if (m_cwnd < m_ssthresh) { - m_cwnd += m_max_packet_size; + m_cwnd *= 2; } else { size_t denom = std::max(m_cwnd, (size_t)1U); - m_cwnd += std::max((size_t)(m_max_packet_size * m_max_packet_size / denom), (size_t)1U); + m_cwnd += m_max_packet_size; } m_cwnd = EQEmu::Clamp(m_cwnd, (size_t)m_max_packet_size, m_owner->m_options.max_outstanding_bytes); @@ -509,7 +511,7 @@ void EQ::Net::DaybreakConnection::IncreaseCongestionWindow() void EQ::Net::DaybreakConnection::ReduceCongestionWindow() { m_ssthresh = std::max((size_t)m_cwnd / 2, (size_t)m_max_packet_size * 2); - m_cwnd = (size_t)m_max_packet_size * 4; + m_cwnd = m_ssthresh; LogF(Logs::Detail, Logs::Netcode, "Reducing cwnd size new size is {0}", m_cwnd); } @@ -1097,6 +1099,7 @@ void EQ::Net::DaybreakConnection::Ack(int stream, uint16_t seq) auto now = Clock::now(); auto s = &m_streams[stream]; auto iter = s->outstanding_packets.begin(); + bool success = false; while (iter != s->outstanding_packets.end()) { auto order = CompareSequence(seq, iter->first); @@ -1109,15 +1112,19 @@ void EQ::Net::DaybreakConnection::Ack(int stream, uint16_t seq) m_rolling_ping = (m_rolling_ping * 4 + round_time) / 5; m_outstanding_bytes -= iter->second.packet.Length(); + m_outstanding_packets--; iter = s->outstanding_packets.erase(iter); - - IncreaseCongestionWindow(); - ProcessOutboundQueue(); + success = true; } else { ++iter; } } + + if (success) { + IncreaseCongestionWindow(); + ProcessOutboundQueue(); + } } void EQ::Net::DaybreakConnection::OutOfOrderAck(int stream, uint16_t seq) @@ -1134,6 +1141,7 @@ void EQ::Net::DaybreakConnection::OutOfOrderAck(int stream, uint16_t seq) m_rolling_ping = (m_rolling_ping * 2 + round_time) / 3; m_outstanding_bytes -= iter->second.packet.Length(); + m_outstanding_packets--; s->outstanding_packets.erase(iter); IncreaseCongestionWindow(); @@ -1144,9 +1152,8 @@ void EQ::Net::DaybreakConnection::OutOfOrderAck(int stream, uint16_t seq) 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 (m_outstanding_bytes + sent.packet.Length() > m_cwnd) { + if (m_outstanding_bytes + sent.packet.Length() > m_cwnd || + m_outstanding_packets + 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); @@ -1157,8 +1164,9 @@ void EQ::Net::DaybreakConnection::BufferPacket(int stream, uint16_t seq, Daybrea } m_outstanding_bytes += sent.packet.Length(); + m_outstanding_packets++; s->outstanding_packets.insert(std::make_pair(seq, sent)); - InternalSend(sent.packet); + InternalBufferedSend(sent.packet); } void EQ::Net::DaybreakConnection::SendAck(int stream_id, uint16_t seq) @@ -1212,6 +1220,10 @@ void EQ::Net::DaybreakConnection::InternalBufferedSend(Packet &p) FlushBuffer(); } + if (m_buffered_packets_length == 0) { + m_hold_time = Clock::now(); + } + DynamicPacket copy; copy.PutPacket(0, p); m_buffered_packets.push_back(copy); diff --git a/common/net/daybreak_connection.h b/common/net/daybreak_connection.h index 8cdbcb33a..0e4b5b9b8 100644 --- a/common/net/daybreak_connection.h +++ b/common/net/daybreak_connection.h @@ -137,6 +137,7 @@ namespace EQ size_t m_rolling_ping; Timestamp m_close_time; size_t m_outstanding_bytes; + size_t m_outstanding_packets; size_t m_cwnd; size_t m_ssthresh; @@ -239,7 +240,8 @@ namespace EQ tic_rate_hertz = 60.0; resend_timeout = 90000; connection_close_time = 2000; - max_outstanding_bytes = 48000; + max_outstanding_bytes = 204800; + max_outstanding_packets = 400; } size_t max_packet_size; @@ -263,6 +265,7 @@ namespace EQ DaybreakEncodeType encode_passes[2]; int port; size_t max_outstanding_bytes; + size_t max_outstanding_packets; }; class DaybreakConnectionManager