camp issue causing instability to world

This Fixes .  Devn00b will test to confirm on his server.
This commit is contained in:
Image 2020-03-05 14:21:35 -05:00
parent 8befaa2c37
commit 42433f8453
2 changed files with 77 additions and 8 deletions
EQ2/source/common

View file

@ -55,18 +55,32 @@
uint16 EQStream::MaxWindowSize=2048;
void EQStream::init() {
void EQStream::init(bool resetSession) {
if (resetSession)
{
streamactive = false;
sessionAttempts = 0;
}
timeout_delays = 0;
MInUse.lock();
active_users = 0;
MInUse.unlock();
Session=0;
Key=0;
MaxLen=0;
NextInSeq=0;
NextOutSeq=0;
CombinedAppPacket=NULL;
MaxAckReceived=-1;
NextAckToSend=-1;
LastAckSent=-1;
MAcks.lock();
MaxAckReceived = -1;
NextAckToSend = -1;
LastAckSent = -1;
MAcks.unlock();
LastSeqSent=-1;
MaxSends=5;
LastPacket=Timer::GetCurrentTime2();
@ -74,8 +88,12 @@ void EQStream::init() {
oversize_length=0;
oversize_offset=0;
Factory = NULL;
MRate.lock();
RateThreshold=RATEBASE/250;
DecayRate=DECAYBASE/250;
MRate.unlock();
BytesWritten=0;
crypto->setRC4Key(0);
}
@ -198,6 +216,7 @@ void EQStream::ProcessPacket(EQProtocolPacket *p)
#endif
return;
}
//cout << "Received " << (int)p->opcode << ":\n";
//DumpPacket(p->pBuffer, p->size);
switch (p->opcode) {
@ -284,6 +303,11 @@ void EQStream::ProcessPacket(EQProtocolPacket *p)
}
break;
case OP_Packet: {
if (!p->pBuffer || (p->Size() < 4))
{
break;
}
uint16 seq=ntohs(*(uint16 *)(p->pBuffer));
sint8 check=CompareSequence(NextInSeq,seq);
if (check>0) {
@ -333,6 +357,11 @@ void EQStream::ProcessPacket(EQProtocolPacket *p)
}
break;
case OP_Fragment: {
if (!p->pBuffer || (p->Size() < 4))
{
break;
}
uint16 seq=ntohs(*(uint16 *)(p->pBuffer));
sint8 check=CompareSequence(NextInSeq,seq);
if (check>0) {
@ -404,16 +433,36 @@ void EQStream::ProcessPacket(EQProtocolPacket *p)
}
break;
case OP_Ack: {
if (!p->pBuffer || (p->Size() < 4))
{
break;
}
uint16 seq=ntohs(*(uint16 *)(p->pBuffer));
SetMaxAckReceived(seq);
}
break;
case OP_SessionRequest: {
if(GetState() == ESTABLISHED){//reset state
SetState(CLOSED);
if (p->Size() < sizeof(SessionRequest))
{
break;
}
init();
if (GetState() == ESTABLISHED) {
//_log(NET__ERROR, _L "Received OP_SessionRequest in ESTABLISHED state (%d) streamactive (%i) attempt (%i)" __L, GetState(), streamactive, sessionAttempts);
// client seems to try a max of 4 times (initial +3 retries) then gives up, giving it a few more attempts just in case
// streamactive means we identified the opcode, we cannot re-establish this connection
if (streamactive || (sessionAttempts > 30))
{
SendDisconnect(false);
SetState(CLOSED);
break;
}
}
sessionAttempts++;
init(GetState() != ESTABLISHED);
OutboundQueueClear();
SessionRequest *Request=(SessionRequest *)p->pBuffer;
Session=ntohl(Request->Session);
SetMaxLen(ntohl(Request->MaxLength));
@ -426,7 +475,13 @@ void EQStream::ProcessPacket(EQProtocolPacket *p)
}
break;
case OP_SessionResponse: {
if (p->Size() < sizeof(SessionResponse))
{
break;
}
init();
OutboundQueueClear();
SetActive(true);
SessionResponse *Response=(SessionResponse *)p->pBuffer;
SetMaxLen(ntohl(Response->MaxLength));
Key=ntohl(Response->Key);
@ -456,6 +511,10 @@ void EQStream::ProcessPacket(EQProtocolPacket *p)
}
break;
case OP_OutOfOrderAck: {
if (!p->pBuffer || (p->Size() < 4))
{
break;
}
#ifndef COLLECTOR
uint16 seq=ntohs(*(uint16 *)(p->pBuffer));
if (CompareSequence(GetMaxAckReceived(),seq)>0 && CompareSequence(NextOutSeq,seq) < 0) {
@ -465,6 +524,11 @@ void EQStream::ProcessPacket(EQProtocolPacket *p)
}
break;
case OP_ServerKeyRequest:{
if (p->Size() < sizeof(ClientSessionStats))
{
//_log(NET__ERROR, _L "Received OP_SessionStatRequest that was of malformed size" __L);
break;
}
ClientSessionStats* Stats = (ClientSessionStats*)p->pBuffer;
int16 request_id = Stats->RequestID;
AdjustRates(ntohl(Stats->average_delta));

View file

@ -127,6 +127,9 @@ class EQStream {
bool compressed,encoded;
//uint32 buffer_len;
uint16 sessionAttempts;
bool streamactive;
uint32 Session, Key;
uint16 NextInSeq;
uint16 NextOutSeq;
@ -220,7 +223,7 @@ class EQStream {
}
}
inline void SetFactory(EQStreamFactory *f) { Factory=f; }
void init();
void init(bool resetSession = true);
void SetMaxLen(uint32 length) { MaxLen=length; }
int8 getTimeoutDelays(){ return timeout_delays; }
void addTimeoutDelay(){ timeout_delays++; }
@ -242,6 +245,8 @@ class EQStream {
void CheckResend(int eq_fd);
void Write(int eq_fd);
void SetActive(bool val) { streamactive = val; }
void WritePacket(int fd,EQProtocolPacket *p);
void EncryptPacket(uchar* data, int16 size);