diff --git a/common/net/daybreak_connection.cpp b/common/net/daybreak_connection.cpp index 34f325434..f3329a976 100644 --- a/common/net/daybreak_connection.cpp +++ b/common/net/daybreak_connection.cpp @@ -140,9 +140,8 @@ void EQ::Net::DaybreakConnectionManager::Process() if ((size_t)time_since_last_send.count() > m_options.connect_delay_ms) { connection->SendConnect(); } - - break; } + break; case StatusConnected: { if (m_options.keepalive_delay_ms != 0) { auto time_since_last_send = std::chrono::duration_cast(now - connection->m_last_send); @@ -284,10 +283,6 @@ EQ::Net::DaybreakConnection::DaybreakConnection(DaybreakConnectionManager *owner m_combined[0] = 0; m_combined[1] = OP_Combined; m_last_session_stats = Clock::now(); - m_outstanding_bytes = 0; - m_outstanding_packets = 0; - m_cwnd = m_max_packet_size; - m_ssthresh = m_owner->m_options.max_outstanding_bytes; } //new connection made as client @@ -311,10 +306,6 @@ EQ::Net::DaybreakConnection::DaybreakConnection(DaybreakConnectionManager *owner m_combined[0] = 0; m_combined[1] = OP_Combined; m_last_session_stats = Clock::now(); - m_outstanding_bytes = 0; - m_outstanding_packets = 0; - m_cwnd = m_max_packet_size; - m_ssthresh = m_owner->m_options.max_outstanding_bytes; } EQ::Net::DaybreakConnection::~DaybreakConnection() @@ -473,49 +464,26 @@ 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 (m_outstanding_packets + 1 >= m_owner->m_options.max_outstanding_packets) { + 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; } - 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_bytes += buff.sent.packet.Length(); stream->outstanding_packets.insert(std::make_pair(buff.seq, buff.sent)); - InternalBufferedSend(buff.sent.packet); + InternalSend(buff.sent.packet); stream->buffered_packets.pop_front(); } } } -void EQ::Net::DaybreakConnection::IncreaseCongestionWindow() -{ - if (m_cwnd < m_ssthresh) { - m_cwnd *= 2; - } - else { - size_t denom = std::max(m_cwnd, (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); - LogF(Logs::Detail, Logs::Netcode, "Increasing cwnd size new size is {0}", m_cwnd); -} - -void EQ::Net::DaybreakConnection::ReduceCongestionWindow() -{ - m_ssthresh = std::max((size_t)m_cwnd / 2, (size_t)m_max_packet_size * 2); - m_cwnd = m_ssthresh; - - LogF(Logs::Detail, Logs::Netcode, "Reducing cwnd size new size is {0}", m_cwnd); -} - void EQ::Net::DaybreakConnection::RemoveFromQueue(int stream, uint16_t seq) { auto s = &m_streams[stream]; @@ -1078,17 +1046,27 @@ void EQ::Net::DaybreakConnection::ProcessResend(int stream) auto s = &m_streams[stream]; for (auto &entry : s->outstanding_packets) { auto time_since_last_send = std::chrono::duration_cast(now - entry.second.last_sent); - auto time_since_first_sent = std::chrono::duration_cast(now - entry.second.first_sent); - if (time_since_first_sent.count() >= m_owner->m_options.resend_timeout) { - Close(); - return; + if (entry.second.times_resent == 0) { + if ((size_t)time_since_last_send.count() > m_resend_delay) { + InternalBufferedSend(entry.second.packet); + entry.second.last_sent = now; + entry.second.times_resent++; + m_rolling_ping += 100; + } } + else { + auto time_since_first_sent = std::chrono::duration_cast(now - entry.second.first_sent); + if (time_since_first_sent.count() >= m_owner->m_options.resend_timeout) { + Close(); + return; + } - if ((size_t)time_since_last_send.count() > m_resend_delay) { - InternalBufferedSend(entry.second.packet); - entry.second.last_sent = now; - entry.second.times_resent++; - ReduceCongestionWindow(); + if ((size_t)time_since_last_send.count() > m_resend_delay) { + InternalBufferedSend(entry.second.packet); + entry.second.last_sent = now; + entry.second.times_resent++; + m_rolling_ping += 100; + } } } } @@ -1099,32 +1077,25 @@ 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); - if (order != SequenceFuture) { + if (order != SequenceFuture) { uint64_t round_time = (uint64_t)std::chrono::duration_cast(now - iter->second.last_sent).count(); 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.last_ping = round_time; - m_rolling_ping = (m_rolling_ping * 4 + round_time) / 5; + m_rolling_ping = (m_rolling_ping * 2 + round_time) / 3; - m_outstanding_bytes -= iter->second.packet.Length(); - m_outstanding_packets--; + s->outstanding_bytes -= iter->second.packet.Length(); iter = s->outstanding_packets.erase(iter); - success = true; + ProcessOutboundQueue(); } else { ++iter; } } - - if (success) { - IncreaseCongestionWindow(); - ProcessOutboundQueue(); - } } void EQ::Net::DaybreakConnection::OutOfOrderAck(int stream, uint16_t seq) @@ -1140,11 +1111,8 @@ void EQ::Net::DaybreakConnection::OutOfOrderAck(int stream, uint16_t seq) m_stats.last_ping = round_time; m_rolling_ping = (m_rolling_ping * 2 + round_time) / 3; - m_outstanding_bytes -= iter->second.packet.Length(); - m_outstanding_packets--; + s->outstanding_bytes -= iter->second.packet.Length(); s->outstanding_packets.erase(iter); - - IncreaseCongestionWindow(); ProcessOutboundQueue(); } } @@ -1152,21 +1120,20 @@ 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 (m_outstanding_bytes + sent.packet.Length() > m_cwnd || - m_outstanding_packets + 1 > m_owner->m_options.max_outstanding_packets) { + //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); - LogF(Logs::Detail, Logs::Netcode, "Buffering packet {0} on stream {1}", seq, stream); return; } - m_outstanding_bytes += sent.packet.Length(); - m_outstanding_packets++; + s->outstanding_bytes += sent.packet.Length(); s->outstanding_packets.insert(std::make_pair(seq, sent)); - InternalBufferedSend(sent.packet); + InternalSend(sent.packet); } void EQ::Net::DaybreakConnection::SendAck(int stream_id, uint16_t seq) @@ -1220,10 +1187,6 @@ 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); @@ -1475,4 +1438,4 @@ EQ::Net::SequenceOrder EQ::Net::DaybreakConnection::CompareSequence(uint16_t exp } return SequencePast; -} +} \ No newline at end of file diff --git a/common/net/daybreak_connection.h b/common/net/daybreak_connection.h index 0e4b5b9b8..ffda5cbae 100644 --- a/common/net/daybreak_connection.h +++ b/common/net/daybreak_connection.h @@ -136,11 +136,7 @@ namespace EQ size_t m_resend_delay; 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; - + struct DaybreakSentPacket { DynamicPacket packet; @@ -162,6 +158,7 @@ namespace EQ sequence_out = 0; fragment_current_bytes = 0; fragment_total_bytes = 0; + outstanding_bytes = 0; } uint16_t sequence_in; @@ -174,6 +171,7 @@ namespace EQ uint32_t fragment_total_bytes; std::unordered_map outstanding_packets; + size_t outstanding_bytes; }; DaybreakStream m_streams[4]; @@ -183,8 +181,6 @@ namespace EQ void ProcessPacket(Packet &p); void ProcessInboundQueue(); void ProcessOutboundQueue(); - void IncreaseCongestionWindow(); - void ReduceCongestionWindow(); void RemoveFromQueue(int stream, uint16_t seq); void AddToQueue(int stream, uint16_t seq, const Packet &p); void ProcessDecodedPacket(const Packet &p); @@ -222,9 +218,9 @@ namespace EQ max_connection_count = 0; keepalive_delay_ms = 9000; resend_delay_ms = 150; - resend_delay_factor = 1.25; - resend_delay_min = 500; - resend_delay_max = 5000; + resend_delay_factor = 1.5; + resend_delay_min = 150; + resend_delay_max = 1000; connect_delay_ms = 500; stale_connection_ms = 90000; connect_stale_ms = 5000; @@ -234,14 +230,14 @@ namespace EQ encode_passes[1] = DaybreakEncodeType::EncodeNone; port = 0; hold_size = 448; - hold_length_ms = 40; + hold_length_ms = 10; simulated_in_packet_loss = 0; simulated_out_packet_loss = 0; tic_rate_hertz = 60.0; resend_timeout = 90000; connection_close_time = 2000; - max_outstanding_bytes = 204800; - max_outstanding_packets = 400; + max_outstanding_packets = 300; + max_outstanding_bytes = 200 * 512; } size_t max_packet_size; @@ -264,8 +260,8 @@ namespace EQ size_t connection_close_time; DaybreakEncodeType encode_passes[2]; int port; - size_t max_outstanding_bytes; size_t max_outstanding_packets; + size_t max_outstanding_bytes; }; class DaybreakConnectionManager @@ -302,4 +298,4 @@ namespace EQ friend class DaybreakConnection; }; } -} +} \ No newline at end of file