Change resend timeout to 1 min instead of 10 missed packets, added a close buffer for end of connection

This commit is contained in:
KimLS 2017-03-14 21:15:41 -07:00
parent 159706efa9
commit 1ce1073930
2 changed files with 46 additions and 26 deletions

View File

@ -105,10 +105,14 @@ void EQ::Net::DaybreakConnectionManager::Process()
auto status = connection->m_status;
if (status == StatusDisconnecting) {
iter = m_connections.erase(iter);
connection->FlushBuffer();
connection->ChangeStatus(StatusDisconnected);
continue;
auto time_since_close = std::chrono::duration_cast<std::chrono::milliseconds>(now - connection->m_close_time);
if (time_since_close.count() > m_options.connection_close_time) {
connection->FlushBuffer();
connection->SendDisconnect();
connection->ChangeStatus(StatusDisconnected);
iter = m_connections.erase(iter);
continue;
}
}
if (status == StatusConnecting) {
@ -310,16 +314,10 @@ EQ::Net::DaybreakConnection::~DaybreakConnection()
void EQ::Net::DaybreakConnection::Close()
{
if (m_status == StatusConnected) {
DaybreakDisconnect disconnect;
disconnect.zero = 0;
disconnect.opcode = OP_SessionDisconnect;
disconnect.connect_code = HostToNetwork(m_connect_code);
DynamicPacket out;
out.PutSerialize(0, disconnect);
FlushBuffer();
InternalSend(out);
SendDisconnect();
m_close_time = Clock::now();
ChangeStatus(StatusDisconnecting);
}
else {
@ -489,6 +487,11 @@ void EQ::Net::DaybreakConnection::ProcessDecodedPacket(const Packet &p)
switch (p.GetInt8(1)) {
case OP_Combined: {
if (m_status == StatusDisconnecting) {
SendDisconnect();
return;
}
char *current = (char*)p.Data() + 2;
char *end = (char*)p.Data() + p.Length();
while (current < end) {
@ -507,6 +510,11 @@ void EQ::Net::DaybreakConnection::ProcessDecodedPacket(const Packet &p)
case OP_AppCombined:
{
if (m_status == StatusDisconnecting) {
SendDisconnect();
return;
}
uint8_t *current = (uint8_t*)p.Data() + 2;
uint8_t *end = (uint8_t*)p.Data() + p.Length();
@ -597,6 +605,11 @@ void EQ::Net::DaybreakConnection::ProcessDecodedPacket(const Packet &p)
case OP_Packet3:
case OP_Packet4:
{
if (m_status == StatusDisconnecting) {
SendDisconnect();
return;
}
auto header = p.GetSerialize<DaybreakReliableHeader>(0);
auto sequence = NetworkToHost(header.sequence);
auto stream_id = header.opcode - OP_Packet;
@ -702,15 +715,8 @@ void EQ::Net::DaybreakConnection::ProcessDecodedPacket(const Packet &p)
case OP_SessionDisconnect:
{
if (m_status == StatusConnected || m_status == StatusDisconnecting) {
DaybreakDisconnect disconnect;
disconnect.zero = 0;
disconnect.opcode = OP_SessionDisconnect;
disconnect.connect_code = HostToNetwork(m_connect_code);
DynamicPacket out;
out.PutSerialize(0, disconnect);
FlushBuffer();
InternalSend(out);
SendDisconnect();
}
ChangeStatus(StatusDisconnecting);
@ -1002,7 +1008,7 @@ void EQ::Net::DaybreakConnection::ProcessResend()
void EQ::Net::DaybreakConnection::ProcessResend(int stream)
{
if (m_status == DbProtocolStatus::StatusDisconnected || m_status == DbProtocolStatus::StatusDisconnecting) {
if (m_status == DbProtocolStatus::StatusDisconnected) {
return;
}
@ -1018,13 +1024,12 @@ void EQ::Net::DaybreakConnection::ProcessResend(int stream)
}
}
else {
if (entry.second.times_resent >= m_owner->m_options.max_resend_count) {
auto time_since_first_sent = std::chrono::duration_cast<std::chrono::milliseconds>(now - entry.second.first_sent);
if (time_since_first_sent.count() >= m_owner->m_options.resend_timeout) {
Close();
return;
}
auto adjusted_resend = std::max((uint32_t)(m_resend_delay / (entry.second.times_resent + 1)), (uint32_t)m_owner->m_options.resend_delay_min);
if ((size_t)time_since_last_send.count() > m_resend_delay) {
InternalBufferedSend(entry.second.packet);
entry.second.last_sent = now;
@ -1099,6 +1104,17 @@ void EQ::Net::DaybreakConnection::SendOutOfOrderAck(int stream_id, uint16_t seq)
InternalBufferedSend(p);
}
void EQ::Net::DaybreakConnection::SendDisconnect()
{
DaybreakDisconnect disconnect;
disconnect.zero = 0;
disconnect.opcode = OP_SessionDisconnect;
disconnect.connect_code = HostToNetwork(m_connect_code);
DynamicPacket out;
out.PutSerialize(0, disconnect);
InternalSend(out);
}
void EQ::Net::DaybreakConnection::InternalBufferedSend(Packet &p)
{
if (p.Length() > 0xFFU) {

View File

@ -138,6 +138,7 @@ namespace EQ
Timestamp m_last_session_stats;
size_t m_resend_delay;
size_t m_rolling_ping;
Timestamp m_close_time;
struct DaybreakSentPacket
{
@ -193,6 +194,7 @@ namespace EQ
void SendKeepAlive();
void SendAck(int stream, uint16_t seq);
void SendOutOfOrderAck(int stream, uint16_t seq);
void SendDisconnect();
void InternalBufferedSend(Packet &p);
void InternalSend(Packet &p);
void InternalQueuePacket(Packet &p, int stream_id, bool reliable);
@ -224,7 +226,8 @@ namespace EQ
simulated_in_packet_loss = 0;
simulated_out_packet_loss = 0;
tic_rate_hertz = 60.0;
max_resend_count = 10;
resend_timeout = 60000;
connection_close_time = 2000;
}
size_t max_packet_size;
@ -243,7 +246,8 @@ namespace EQ
size_t simulated_in_packet_loss;
size_t simulated_out_packet_loss;
double tic_rate_hertz;
size_t max_resend_count;
size_t resend_timeout;
size_t connection_close_time;
DaybreakEncodeType encode_passes[2];
int port;
};