Tweaks and bug fixes

This commit is contained in:
KimLS 2017-07-05 20:24:39 -07:00
parent 49505a7a45
commit a7c0e82c9e
2 changed files with 33 additions and 18 deletions

View File

@ -285,7 +285,8 @@ EQ::Net::DaybreakConnection::DaybreakConnection(DaybreakConnectionManager *owner
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_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; 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_combined[1] = OP_Combined;
m_last_session_stats = Clock::now(); m_last_session_stats = Clock::now();
m_outstanding_bytes = 0; 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; m_ssthresh = m_owner->m_options.max_outstanding_bytes;
} }
@ -373,11 +375,6 @@ void EQ::Net::DaybreakConnection::Process()
} }
ProcessInboundQueue(); 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) { 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());
@ -479,12 +476,17 @@ void EQ::Net::DaybreakConnection::ProcessOutboundQueue()
while (!stream->buffered_packets.empty()) { while (!stream->buffered_packets.empty()) {
auto &buff = stream->buffered_packets.front(); 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) { if (m_outstanding_bytes + buff.sent.packet.Length() >= m_cwnd) {
break; break;
} }
LogF(Logs::Detail, Logs::Netcode, "Sending buffered packet {0} on stream {1}", buff.seq, i); LogF(Logs::Detail, Logs::Netcode, "Sending buffered packet {0} on stream {1}", buff.seq, i);
m_outstanding_bytes += buff.sent.packet.Length(); m_outstanding_bytes += buff.sent.packet.Length();
m_outstanding_packets++;
stream->outstanding_packets.insert(std::make_pair(buff.seq, buff.sent)); stream->outstanding_packets.insert(std::make_pair(buff.seq, buff.sent));
InternalBufferedSend(buff.sent.packet); InternalBufferedSend(buff.sent.packet);
stream->buffered_packets.pop_front(); stream->buffered_packets.pop_front();
@ -495,11 +497,11 @@ void EQ::Net::DaybreakConnection::ProcessOutboundQueue()
void EQ::Net::DaybreakConnection::IncreaseCongestionWindow() void EQ::Net::DaybreakConnection::IncreaseCongestionWindow()
{ {
if (m_cwnd < m_ssthresh) { if (m_cwnd < m_ssthresh) {
m_cwnd += m_max_packet_size; m_cwnd *= 2;
} }
else { else {
size_t denom = std::max(m_cwnd, (size_t)1U); 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); 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() void EQ::Net::DaybreakConnection::ReduceCongestionWindow()
{ {
m_ssthresh = std::max((size_t)m_cwnd / 2, (size_t)m_max_packet_size * 2); 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); 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 now = Clock::now();
auto s = &m_streams[stream]; auto s = &m_streams[stream];
auto iter = s->outstanding_packets.begin(); auto iter = s->outstanding_packets.begin();
bool success = false;
while (iter != s->outstanding_packets.end()) { while (iter != s->outstanding_packets.end()) {
auto order = CompareSequence(seq, iter->first); 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_rolling_ping = (m_rolling_ping * 4 + round_time) / 5;
m_outstanding_bytes -= iter->second.packet.Length(); m_outstanding_bytes -= iter->second.packet.Length();
m_outstanding_packets--;
iter = s->outstanding_packets.erase(iter); iter = s->outstanding_packets.erase(iter);
success = true;
IncreaseCongestionWindow();
ProcessOutboundQueue();
} }
else { else {
++iter; ++iter;
} }
} }
if (success) {
IncreaseCongestionWindow();
ProcessOutboundQueue();
}
} }
void EQ::Net::DaybreakConnection::OutOfOrderAck(int stream, uint16_t seq) 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_rolling_ping = (m_rolling_ping * 2 + round_time) / 3;
m_outstanding_bytes -= iter->second.packet.Length(); m_outstanding_bytes -= iter->second.packet.Length();
m_outstanding_packets--;
s->outstanding_packets.erase(iter); s->outstanding_packets.erase(iter);
IncreaseCongestionWindow(); 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) void EQ::Net::DaybreakConnection::BufferPacket(int stream, uint16_t seq, DaybreakSentPacket &sent)
{ {
auto s = &m_streams[stream]; auto s = &m_streams[stream];
//If we can send the packet then send it if (m_outstanding_bytes + sent.packet.Length() > m_cwnd ||
//else buffer it to be sent when we can send it m_outstanding_packets + 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);
@ -1157,8 +1164,9 @@ void EQ::Net::DaybreakConnection::BufferPacket(int stream, uint16_t seq, Daybrea
} }
m_outstanding_bytes += sent.packet.Length(); m_outstanding_bytes += sent.packet.Length();
m_outstanding_packets++;
s->outstanding_packets.insert(std::make_pair(seq, sent)); 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) void EQ::Net::DaybreakConnection::SendAck(int stream_id, uint16_t seq)
@ -1212,6 +1220,10 @@ void EQ::Net::DaybreakConnection::InternalBufferedSend(Packet &p)
FlushBuffer(); FlushBuffer();
} }
if (m_buffered_packets_length == 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);

View File

@ -137,6 +137,7 @@ namespace EQ
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_outstanding_bytes;
size_t m_outstanding_packets;
size_t m_cwnd; size_t m_cwnd;
size_t m_ssthresh; size_t m_ssthresh;
@ -239,7 +240,8 @@ 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_bytes = 48000; max_outstanding_bytes = 204800;
max_outstanding_packets = 400;
} }
size_t max_packet_size; size_t max_packet_size;
@ -263,6 +265,7 @@ namespace EQ
DaybreakEncodeType encode_passes[2]; DaybreakEncodeType encode_passes[2];
int port; int port;
size_t max_outstanding_bytes; size_t max_outstanding_bytes;
size_t max_outstanding_packets;
}; };
class DaybreakConnectionManager class DaybreakConnectionManager