https://github.com/bitcoin/bitcoin/blob/d72758c3f6c34cd835f5de3efc230964f3b1ea56/src/torcontrol.cpp#L539

If a user is running Tor proxy outside localhost (perhaps on other host inside LAN or in containerised environment) , the automatic creation of onion services ends up creating an onion service listening to hardcored 127.0.0.1 address on the Tor proxy's host instead of the private address of the bitcoind – effectively running an empty onion service listening the Tor proxy's localhost.
CAddress addrBind;
    uint32_t m_mapped_as;
    std::string m_conn_type_string;
};
/** Transport protocol agnostic message container.
 * Ideally it should only contain receive time, payload,
 * command and size.
 */
class CNetMessage {
public:
    CDataStream m_recv;                  //
    std::chrono::microseconds m_time{0}; //
    uint32_t m_message_size{0};          //
    uint32_t m_raw_message_size{0};      //
    std::string m_command;
    CNetMessage(CDataStream&& recv_in) : m_recv(std::move(recv_in)) {}
    void SetVersion(int nVersionIn)
    {
        m_recv.SetVersion(nVersionIn);
    }
};
/** The TransportDeserializer takes care of holding and deserializing the
 * network receive buffer. It can deserialize the network buffer into a
 * transport protocol agnostic CNetMessage (command & payload)
 */
class TransportDeserializer {
public:
    // 
    virtual bool Complete() const = 0;
    // 
    virtual void SetVersion(int version) = 0;
    // 
    virtual int Read(const char *data, unsigned int bytes) = 0;
    // 
    virtual Optional<CNetMessage> GetMessage(std::chrono::microseconds time, uint32_t& out_err) = 0;
    virtual ~TransportDeserializer() {}
};
class V1TransportDeserializer final : public TransportDeserializer
{
private:
    const CChainParams& m_chain_params;
    const NodeId m_node_id; // 
    mutable CHash256 hasher;
    mutable uint256 data_hash;
    bool in_data;                   // 
    CDataStream hdrbuf;             // 
    CMessageHeader hdr;             // 
    CDataStream vRecv;              // 
    unsigned int nHdrPos;
    unsigned int nDataPos;
    const uint256& GetMessageHash() const;
    int readHeader(const char *pch, unsigned int nBytes);
    int readData(const char *pch, unsigned int nBytes);
    void Reset() {
        vRecv.clear();
        hdrbuf.clear();
        hdrbuf.resize(24);
        in_data = false;
        nHdrPos = 0;
        nDataPos = 0;
        data_hash.SetNull();
        hasher.Reset();
    }
public:
    V1T