### FEATURE REQUEST

Currently, when a bitcoin node is set up with a connection to both TOR and normal IPv4/6 internet, the 8 outbound-only connection slots, almost always get filled with nodes connecting over IP.
Adding a config option, which would try to ballance these connections based on what kind of network they go through, would be benefficial in many ways:

1. It would add edges between bitcoin network on TOR and normal internet, reducing delays, and the risks associated with an attacker isolating a part of TOR-bitcoin-network from the rest of the world
(Or an ISP/government man-in-the-middling all the normal IP connections)

2. It would help hide/annonymise normal user's transactions from his/her ISP, by mixing them with TOR-outbound ones

3. It would reduce the stress on normal general purpose TOR exit nodes, as users would more likely/reliably connect to TOR-IPv4/6 bitcoin nodes instead of exiting into normal internet first, and then connecting to default IPv4/6-only bitcoin nodes

I understand it is possible to create such bridges already, by forcing connections to TOR-only nodes, or by just running a node with lots of inbound slots, but I think the proposed option, would greatly increase the number of such relays, and remove the need for user to maintain a TOR-node whitelist, by handing this work off to normal bitcoind connection finding algorithm.

This could be implemented as a minimum number of connections for each network, or just a simple evening boolean switch. (Which could be enabled by default for bitcoind installs with TOR connectivity)

In the future, if bitcoin was to support a new network type (for example cjdns/I2P/GNUnet), this option would help establish a presence on the new network faster

bitcoind: 0.15
std::string addrLocal;
    // 
    CAddress addr;
    // 
    CAddress addrBind;
    // 
    Network m_network;
    uint32_t m_mapped_as;
    ConnectionType m_conn_type;
};
/** 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(Span<const uint8_t>& msg_bytes) = 0;
    // 
    virtual std::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(Span<const uint8_t> msg_bytes);
    int readData(Span<const uint8_t> msg_bytes);
    void Reset() {
        vRecv.clear();
        hdrbuf.clear();
        hdrbuf.resize(24);
        in_data = false;
        nHdrPos = 0;
        nDataPos = 0;
 