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:
parent
24f2c38093
commit
bc4ab8b99e
34 changed files with 330 additions and 439 deletions
|
@ -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();
|
||||
|
|
|
@ -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; }
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue