From 370842756ab50b53ca1a9f5787b2750f3e3d9cd8 Mon Sep 17 00:00:00 2001 From: fusion32 Date: Sat, 14 Mar 2026 16:07:56 -0300 Subject: support for proxy headers + minor tweaks --- src/communication.cc | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++++ src/crnonpl.cc | 18 +++++++++++----- src/crplayer.cc | 2 +- 3 files changed, 75 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/communication.cc b/src/communication.cc index 37223d2..2bd727b 100644 --- a/src/communication.cc +++ b/src/communication.cc @@ -1130,7 +1130,12 @@ bool ReceiveCommand(TConnection *Connection){ } while(!Connection->WaitingForACK){ +#if ALLOW_LOCAL_PROXY + uint8 Help[32]; +#else uint8 Help[2]; +#endif + int BytesRead = ReadFromSocket(Connection, Help, 2); if(BytesRead == 0){ // NOTE(fusion): Peer has closed the connection and there was no @@ -1153,6 +1158,62 @@ bool ReceiveCommand(TConnection *Connection){ return false; } +#if ALLOW_LOCAL_PROXY + if(Connection->State == CONNECTION_CONNECTED){ + uint8_t *SourceAddr = NULL; + if(Help[0] == 0x0D && Help[1] == 0x0A){ + // NOTE(fusion): HAProxy-V2 header. + static const uint8_t HAProxyV2Signature[] = { + 0x0D, 0x0A, 0x0D, 0x0A, 0x00, 0x0D, 0x0A, 0x51, + 0x55, 0x49, 0x54, 0x0A, + }; + + if(ReadFromSocket(Connection, Help + 2, 26) != 26){ + error("Unable to read proxy header from %s (Socket=%d)\n", + Connection->IPAddress, Connection->GetSocket()); + return false; + } + + if(memcmp(Help, HAProxyV2Signature, 12) != 0){ + error("Invalid proxy header from %s (Socket=%d)\n", + Connection->IPAddress, Connection->GetSocket()); + return false; + } + + SourceAddr = Help + 16; + }else if(Help[0] == 0xD9 && Help[1] == 0xFF){ + // NOTE(fusion): Our custom proxy header. + if(ReadFromSocket(Connection, Help + 2, 4) != 4){ + error("Unable to read proxy header from %s (Socket=%d)\n", + Connection->IPAddress, Connection->GetSocket()); + return false; + } + + SourceAddr = Help + 2; + } + + if(SourceAddr != NULL){ + // NOTE(fusion): Ideally we'd have a list of trusted proxies to + // prevent clients from spoofing their addresses. In reality, it + // is almost always simpler to have a localhost "receiver". This + // is also the only way to get a multi-route proxy without having + // to drastically change the way connections are handled. + if(strcmp(Connection->IPAddress, "127.0.0.1") != 0){ + error("Received proxy header (%02X, %02X) from unknown host %s\n", + Help[0], Help[1], Connection->IPAddress); + return false; + } + + // NOTE(fusion): Update connection IP-Address and resume reading. + snprintf(Connection->IPAddress, sizeof(Connection->IPAddress), + "%d.%d.%d.%d", + (int)SourceAddr[0], (int)SourceAddr[1], + (int)SourceAddr[2], (int)SourceAddr[3]); + continue; + } + } +#endif + // TODO(fusion): Size is encoded as a little endian uint16. We should // have a few helper functions to assist with buffer reading. int Size = ((uint16)Help[0] | ((uint16)Help[1] << 8)); diff --git a/src/crnonpl.cc b/src/crnonpl.cc index 3a6c053..1522cab 100644 --- a/src/crnonpl.cc +++ b/src/crnonpl.cc @@ -1760,9 +1760,17 @@ void TNPC::IdleStimulus(void){ case 3: DestY += 1; break; } - if(this->MovePossible(DestX, DestY, DestZ, true, false)){ - DestFound = true; - break; + // NOTE(fusion): TNPC::MovePossible in particular doesn't throw + // exceptions so we don't need a try-catch block here like in the + // case of TMonster::IdleStimulus, nor does the original function + // has it. That said, it's still better to be safe. + try{ + if(this->MovePossible(DestX, DestY, DestZ, true, false)){ + DestFound = true; + break; + } + }catch(RESULT r){ + // no-op } } @@ -2702,7 +2710,7 @@ void TMonster::IdleStimulus(void){ // TODO(fusion): We're doing something similar to `TCombat::CanToDoAttack` // with added random steps around the attacking position. This function is // too convoluted and we should definitely split it into smaller ones. I - // don't have a problem with large functions but this it too much. + // don't have a problem with large functions but this is too much. // NOTE(fusion): Max distance. int Distance = std::max( @@ -2936,7 +2944,7 @@ bool TMonster::KickCreature(TCreature *Creature){ print(3, "%s verschiebt %s.\n", this->Name, Creature->Name); - // TODO(fusion): Declare these here so they can be used within the catch + // NOTE(fusion): Declare these here so they can be used within the catch // block to print out what's on the last position we tried to move the // creature to. int DestX = Creature->posx; diff --git a/src/crplayer.cc b/src/crplayer.cc index 4934966..8878bda 100644 --- a/src/crplayer.cc +++ b/src/crplayer.cc @@ -2845,7 +2845,7 @@ void AttachPlayerPoolSlot(TPlayerData *Slot, bool DontWait){ } PlayerDataPoolMutex.up(); - DelayThread(0,100); + DelayThread(0, 100); } } -- cgit v1.2.3