1
0
Fork 0
mirror of https://github.com/luanti-org/luanti.git synced 2025-08-01 17:38:41 +00:00

General code refactoring/improvements in server, treegen and connection

This commit is contained in:
sfan5 2024-03-12 14:13:24 +01:00
parent 24f2c38093
commit bc4ab8b99e
34 changed files with 330 additions and 439 deletions

View file

@ -68,7 +68,7 @@ u16 BufferedPacket::getSeqnum() const
return readU16(&data[BASE_HEADER_SIZE + 1]);
}
BufferedPacketPtr makePacket(Address &address, const SharedBuffer<u8> &data,
BufferedPacketPtr makePacket(const Address &address, const SharedBuffer<u8> &data,
u32 protocol_id, session_t sender_peer_id, u8 channel)
{
u32 packet_size = data.getSize() + BASE_HEADER_SIZE;
@ -834,13 +834,6 @@ void Channel::UpdateTimers(float dtime)
Peer
*/
PeerHelper::PeerHelper(Peer* peer) :
m_peer(peer)
{
if (peer && !peer->IncUseCount())
m_peer = nullptr;
}
PeerHelper::~PeerHelper()
{
if (m_peer)
@ -851,32 +844,14 @@ PeerHelper::~PeerHelper()
PeerHelper& PeerHelper::operator=(Peer* peer)
{
if (m_peer)
m_peer->DecUseCount();
m_peer = peer;
if (peer && !peer->IncUseCount())
m_peer = nullptr;
return *this;
}
Peer* PeerHelper::operator->() const
{
return m_peer;
}
Peer* PeerHelper::operator&() const
{
return m_peer;
}
bool PeerHelper::operator!()
{
return ! m_peer;
}
bool PeerHelper::operator!=(void* ptr)
{
return ((void*) m_peer != ptr);
}
bool Peer::IncUseCount()
{
MutexAutoLock lock(m_exclusive_access_mutex);
@ -989,8 +964,8 @@ void Peer::Drop()
delete this;
}
UDPPeer::UDPPeer(session_t a_id, Address a_address, Connection* connection) :
Peer(a_address,a_id,connection)
UDPPeer::UDPPeer(session_t id, const Address &address, Connection *connection) :
Peer(id, address, connection)
{
for (Channel &channel : channels)
channel.setWindowSize(START_RELIABLE_WINDOW_SIZE);
@ -1014,17 +989,6 @@ bool UDPPeer::isTimedOut(float timeout, std::string &reason)
return false;
}
bool UDPPeer::getAddress(MTProtocols type,Address& toset)
{
if ((type == MTP_UDP) || (type == MTP_MINETEST_RELIABLE_UDP) || (type == MTP_PRIMARY))
{
toset = address;
return true;
}
return false;
}
void UDPPeer::reportRTT(float rtt)
{
if (rtt < 0.0) {
@ -1377,20 +1341,12 @@ PeerHelper Connection::getPeerNoEx(session_t peer_id)
session_t Connection::lookupPeer(const Address& sender)
{
MutexAutoLock peerlock(m_peers_mutex);
std::map<u16, Peer*>::iterator j;
j = m_peers.begin();
for(; j != m_peers.end(); ++j)
{
Peer *peer = j->second;
for (auto &it: m_peers) {
Peer *peer = it.second;
if (peer->isPendingDeletion())
continue;
Address tocheck;
if ((peer->getAddress(MTP_MINETEST_RELIABLE_UDP, tocheck)) && (tocheck == sender))
return peer->id;
if ((peer->getAddress(MTP_UDP, tocheck)) && (tocheck == sender))
if (peer->getAddress() == sender)
return peer->id;
}
@ -1427,12 +1383,8 @@ bool Connection::deletePeer(session_t peer_id, bool timeout)
m_peer_ids.erase(it);
}
Address peer_address;
//any peer has a primary address this never fails!
peer->getAddress(MTP_PRIMARY, peer_address);
// Create event
putEvent(ConnectionEvent::peerRemoved(peer_id, timeout, peer_address));
putEvent(ConnectionEvent::peerRemoved(peer_id, timeout, peer->getAddress()));
peer->Drop();
return true;
@ -1562,15 +1514,14 @@ Address Connection::GetPeerAddress(session_t peer_id)
if (!peer)
throw PeerNotFoundException("No address for peer found!");
Address peer_address;
peer->getAddress(MTP_PRIMARY, peer_address);
return peer_address;
return peer->getAddress();
}
float Connection::getPeerStat(session_t peer_id, rtt_stat_type type)
{
PeerHelper peer = getPeerNoEx(peer_id);
if (!peer) return -1;
if (!peer)
return -1;
return peer->getStat(type);
}
@ -1580,7 +1531,7 @@ float Connection::getLocalStat(rate_stat_type type)
FATAL_ERROR_IF(!peer, "Connection::getLocalStat we couldn't get our own peer? are you serious???");
float retval = 0.0;
float retval = 0;
for (Channel &channel : dynamic_cast<UDPPeer *>(&peer)->channels) {
switch(type) {
@ -1609,7 +1560,7 @@ float Connection::getLocalStat(rate_stat_type type)
return retval;
}
session_t Connection::createPeer(Address& sender, MTProtocols protocol, int fd)
session_t Connection::createPeer(const Address &sender, int fd)
{
// Somebody wants to make a new connection
@ -1694,12 +1645,10 @@ void Connection::sendAck(session_t peer_id, u8 channelnum, u16 seqnum)
m_sendThread->Trigger();
}
UDPPeer* Connection::createServerPeer(Address& address)
UDPPeer* Connection::createServerPeer(const Address &address)
{
if (ConnectedToServer())
{
throw ConnectionException("Already connected to a server");
}
UDPPeer *peer = new UDPPeer(PEER_ID_SERVER, address, this);
peer->SetFullyOpen();

View file

@ -25,8 +25,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "constants.h"
#include "util/pointer.h"
#include "util/container.h"
#include "util/thread.h"
#include "util/numeric.h"
#include "porting.h"
#include "networkprotocol.h"
#include <iostream>
#include <vector>
@ -40,12 +40,6 @@ namespace con
class ConnectionReceiveThread;
class ConnectionSendThread;
enum MTProtocols {
MTP_PRIMARY,
MTP_UDP,
MTP_MINETEST_RELIABLE_UDP
};
enum rate_stat_type {
CUR_DL_RATE,
AVG_DL_RATE,
@ -57,18 +51,20 @@ enum rate_stat_type {
class Peer;
// FIXME: Peer refcounting should generally be replaced by std::shared_ptr
class PeerHelper
{
public:
PeerHelper() = default;
PeerHelper(Peer* peer);
inline PeerHelper(Peer *peer) { *this = peer; }
~PeerHelper();
PeerHelper& operator=(Peer* peer);
Peer* operator->() const;
bool operator!();
Peer* operator&() const;
bool operator!=(void* ptr);
PeerHelper& operator=(Peer *peer);
inline Peer* operator->() const { return m_peer; }
inline Peer* operator&() const { return m_peer; }
inline bool operator!() { return !m_peer; }
inline bool operator!=(std::nullptr_t) { return !!m_peer; }
private:
Peer *m_peer = nullptr;
@ -127,18 +123,10 @@ class Peer {
public:
friend class PeerHelper;
Peer(Address address_,session_t id_,Connection* connection) :
id(id_),
m_connection(connection),
address(address_),
m_last_timeout_check(porting::getTimeMs())
{
};
virtual ~Peer() {
MutexAutoLock usage_lock(m_exclusive_access_mutex);
FATAL_ERROR_IF(m_usage != 0, "Reference counting failure");
};
}
// Unique id of the peer
const session_t id;
@ -148,16 +136,25 @@ class Peer {
virtual void PutReliableSendCommand(ConnectionCommandPtr &c,
unsigned int max_packet_size) {};
virtual bool getAddress(MTProtocols type, Address& toset) = 0;
virtual const Address &getAddress() const = 0;
bool isPendingDeletion()
{ MutexAutoLock lock(m_exclusive_access_mutex); return m_pending_deletion; };
bool isPendingDeletion() const {
MutexAutoLock lock(m_exclusive_access_mutex);
return m_pending_deletion;
}
void ResetTimeout() {
MutexAutoLock lock(m_exclusive_access_mutex);
m_timeout_counter = 0;
}
void ResetTimeout()
{MutexAutoLock lock(m_exclusive_access_mutex); m_timeout_counter = 0.0; };
bool isHalfOpen() const { return m_half_open; }
void SetFullyOpen() { m_half_open = false; }
bool isHalfOpen() const {
MutexAutoLock lock(m_exclusive_access_mutex);
return m_half_open;
}
void SetFullyOpen() {
MutexAutoLock lock(m_exclusive_access_mutex);
m_half_open = false;
}
virtual bool isTimedOut(float timeout, std::string &reason);
@ -168,10 +165,8 @@ class Peer {
virtual SharedBuffer<u8> addSplitPacket(u8 channel, BufferedPacketPtr &toadd,
bool reliable)
{
errorstream << "Peer::addSplitPacket called,"
<< " this is supposed to be never called!" << std::endl;
return SharedBuffer<u8>(0);
};
FATAL_ERROR("unimplemented in abstract class");
}
virtual bool Ping(float dtime, SharedBuffer<u8>& data) { return false; };
@ -192,7 +187,16 @@ class Peer {
}
return -1;
}
protected:
Peer(session_t id, const Address &address, Connection *connection) :
id(id),
m_connection(connection),
address(address),
m_last_timeout_check(porting::getTimeMs())
{
}
virtual void reportRTT(float rtt) {};
void RTTStatistics(float rtt,
@ -206,15 +210,15 @@ class Peer {
bool m_pending_deletion = false;
Connection* m_connection;
Connection *m_connection;
// Address of the peer
Address address;
// Ping timer
float m_ping_timer = 0.0f;
private:
private:
struct rttstats {
float jitter_min = FLT_MAX;
float jitter_max = 0.0f;
@ -222,8 +226,6 @@ class Peer {
float min_rtt = FLT_MAX;
float max_rtt = 0.0f;
float avg_rtt = -1.0f;
rttstats() = default;
};
rttstats m_rtt;
@ -285,8 +287,8 @@ protected:
PeerHelper getPeerNoEx(session_t peer_id);
session_t lookupPeer(const Address& sender);
session_t createPeer(Address& sender, MTProtocols protocol, int fd);
UDPPeer* createServerPeer(Address& sender);
session_t createPeer(const Address& sender, int fd);
UDPPeer* createServerPeer(const Address& sender);
bool deletePeer(session_t peer_id, bool timeout);
void SetPeerID(session_t id) { m_peer_id = id; }

View file

@ -193,7 +193,7 @@ private:
// This adds the base headers to the data and makes a packet out of it
BufferedPacketPtr makePacket(Address &address, const SharedBuffer<u8> &data,
BufferedPacketPtr makePacket(const Address &address, const SharedBuffer<u8> &data,
u32 protocol_id, session_t sender_peer_id, u8 channel);
// Depending on size, make a TYPE_ORIGINAL or TYPE_SPLIT packet
@ -235,9 +235,7 @@ private:
class ReliablePacketBuffer
{
public:
ReliablePacketBuffer() = default;
bool getFirstSeqnum(u16& result);
bool getFirstSeqnum(u16 &result);
BufferedPacketPtr popFirst();
BufferedPacketPtr popSeqnum(u16 seqnum);
@ -273,6 +271,7 @@ class IncomingSplitBuffer
{
public:
~IncomingSplitBuffer();
/*
Returns a reference counted buffer of length != 0 when a full split
packet is constructed. If not, returns one of length 0.
@ -450,13 +449,15 @@ public:
friend class ConnectionSendThread;
friend class Connection;
UDPPeer(u16 id, Address address, Connection *connection);
UDPPeer(session_t id, const Address &address, Connection *connection);
virtual ~UDPPeer() = default;
void PutReliableSendCommand(ConnectionCommandPtr &c,
unsigned int max_packet_size) override;
bool getAddress(MTProtocols type, Address& toset) override;
virtual const Address &getAddress() const {
return address;
}
u16 getNextSplitSequenceNumber(u8 channel) override;
void setNextSplitSequenceNumber(u8 channel, u16 seqnum) override;

View file

@ -348,11 +348,9 @@ bool ConnectionSendThread::rawSendAsPacket(session_t peer_id, u8 channelnum,
return false;
SharedBuffer<u8> reliable = makeReliablePacket(data, seqnum);
Address peer_address;
peer->getAddress(MTP_MINETEST_RELIABLE_UDP, peer_address);
// Add base headers and make a packet
BufferedPacketPtr p = con::makePacket(peer_address, reliable,
BufferedPacketPtr p = con::makePacket(peer->getAddress(), reliable,
m_connection->GetProtocolID(), m_connection->GetPeerID(),
channelnum);
@ -374,22 +372,14 @@ bool ConnectionSendThread::rawSendAsPacket(session_t peer_id, u8 channelnum,
return false;
}
Address peer_address;
if (peer->getAddress(MTP_UDP, peer_address)) {
// Add base headers and make a packet
BufferedPacketPtr p = con::makePacket(peer_address, data,
m_connection->GetProtocolID(), m_connection->GetPeerID(),
channelnum);
// Add base headers and make a packet
BufferedPacketPtr p = con::makePacket(peer->getAddress(), data,
m_connection->GetProtocolID(), m_connection->GetPeerID(),
channelnum);
// Send the packet
rawSend(p.get());
return true;
}
LOG(dout_con << m_connection->getDesc()
<< " INFO: dropped unreliable packet for peer_id: " << peer_id
<< " because of (yet) missing udp address" << std::endl);
return false;
// Send the packet
rawSend(p.get());
return true;
}
void ConnectionSendThread::processReliableCommand(ConnectionCommandPtr &c)
@ -984,7 +974,7 @@ void ConnectionReceiveThread::receive(SharedBuffer<u8> &packetdata,
l.logged = true;
// We simply drop the packet, the client can try again.
} else {
peer_id = m_connection->createPeer(sender, MTP_MINETEST_RELIABLE_UDP, 0);
peer_id = m_connection->createPeer(sender, 0);
}
}
}
@ -999,17 +989,9 @@ void ConnectionReceiveThread::receive(SharedBuffer<u8> &packetdata,
// Validate peer address
Address peer_address;
if (peer->getAddress(MTP_UDP, peer_address)) {
if (peer_address != sender) {
LOG(derr_con << m_connection->getDesc()
<< " Peer " << peer_id << " sending from different address."
" Ignoring." << std::endl);
return;
}
} else {
if (sender != peer->getAddress()) {
LOG(derr_con << m_connection->getDesc()
<< " Peer " << peer_id << " doesn't have an address?!"
<< " Peer " << peer_id << " sending from different address."
" Ignoring." << std::endl);
return;
}
@ -1284,32 +1266,25 @@ SharedBuffer<u8> ConnectionReceiveThread::handlePacketType_Original(Channel *cha
SharedBuffer<u8> ConnectionReceiveThread::handlePacketType_Split(Channel *channel,
const SharedBuffer<u8> &packetdata, Peer *peer, u8 channelnum, bool reliable)
{
Address peer_address;
// We have to create a packet again for buffering
// This isn't actually too bad an idea.
BufferedPacketPtr packet = con::makePacket(peer->getAddress(),
packetdata,
m_connection->GetProtocolID(),
peer->id,
channelnum);
if (peer->getAddress(MTP_UDP, peer_address)) {
// We have to create a packet again for buffering
// This isn't actually too bad an idea.
BufferedPacketPtr packet = con::makePacket(peer_address,
packetdata,
m_connection->GetProtocolID(),
peer->id,
channelnum);
// Buffer the packet
SharedBuffer<u8> data = peer->addSplitPacket(channelnum, packet, reliable);
// Buffer the packet
SharedBuffer<u8> data = peer->addSplitPacket(channelnum, packet, reliable);
if (data.getSize() != 0) {
LOG(dout_con << m_connection->getDesc()
<< "RETURNING TYPE_SPLIT: Constructed full data, "
<< "size=" << data.getSize() << std::endl);
return data;
}
LOG(dout_con << m_connection->getDesc() << "BUFFERED TYPE_SPLIT" << std::endl);
throw ProcessedSilentlyException("Buffered a split packet chunk");
if (data.getSize() != 0) {
LOG(dout_con << m_connection->getDesc()
<< "RETURNING TYPE_SPLIT: Constructed full data, "
<< "size=" << data.getSize() << std::endl);
return data;
}
// We should never get here.
FATAL_ERROR("Invalid execution point");
LOG(dout_con << m_connection->getDesc() << "BUFFERED TYPE_SPLIT" << std::endl);
throw ProcessedSilentlyException("Buffered a split packet chunk");
}
SharedBuffer<u8> ConnectionReceiveThread::handlePacketType_Reliable(Channel *channel,
@ -1361,15 +1336,11 @@ SharedBuffer<u8> ConnectionReceiveThread::handlePacketType_Reliable(Channel *cha
}
if (seqnum != channel->readNextIncomingSeqNum()) {
Address peer_address;
// this is a reliable packet so we have a udp address for sure
peer->getAddress(MTP_MINETEST_RELIABLE_UDP, peer_address);
// This one comes later, buffer it.
// Actually we have to make a packet to buffer one.
// Well, we have all the ingredients, so just do it.
BufferedPacketPtr packet = con::makePacket(
peer_address,
peer->getAddress(),
packetdata,
m_connection->GetProtocolID(),
peer->id,