Network cleanup (#6302)
[oweals/minetest.git] / src / network / connection.h
index fe2c9819d3e82c8b82c4947ce7141c6202567225..3d3a502aafb55a2c2292eb78d55208cf8baebf52 100644 (file)
@@ -17,14 +17,12 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */
 
-#ifndef CONNECTION_HEADER
-#define CONNECTION_HEADER
+#pragma once
 
 #include "irrlichttypes_bloated.h"
+#include "peerhandler.h"
 #include "socket.h"
-#include "exceptions.h"
 #include "constants.h"
-#include "network/networkpacket.h"
 #include "util/pointer.h"
 #include "util/container.h"
 #include "util/thread.h"
@@ -39,89 +37,6 @@ class NetworkPacket;
 namespace con
 {
 
-/*
-       Exceptions
-*/
-class NotFoundException : public BaseException
-{
-public:
-       NotFoundException(const char *s):
-               BaseException(s)
-       {}
-};
-
-class PeerNotFoundException : public BaseException
-{
-public:
-       PeerNotFoundException(const char *s):
-               BaseException(s)
-       {}
-};
-
-class ConnectionException : public BaseException
-{
-public:
-       ConnectionException(const char *s):
-               BaseException(s)
-       {}
-};
-
-class ConnectionBindFailed : public BaseException
-{
-public:
-       ConnectionBindFailed(const char *s):
-               BaseException(s)
-       {}
-};
-
-class InvalidIncomingDataException : public BaseException
-{
-public:
-       InvalidIncomingDataException(const char *s):
-               BaseException(s)
-       {}
-};
-
-class InvalidOutgoingDataException : public BaseException
-{
-public:
-       InvalidOutgoingDataException(const char *s):
-               BaseException(s)
-       {}
-};
-
-class NoIncomingDataException : public BaseException
-{
-public:
-       NoIncomingDataException(const char *s):
-               BaseException(s)
-       {}
-};
-
-class ProcessedSilentlyException : public BaseException
-{
-public:
-       ProcessedSilentlyException(const char *s):
-               BaseException(s)
-       {}
-};
-
-class ProcessedQueued : public BaseException
-{
-public:
-       ProcessedQueued(const char *s):
-               BaseException(s)
-       {}
-};
-
-class IncomingDataCorruption : public BaseException
-{
-public:
-       IncomingDataCorruption(const char *s):
-               BaseException(s)
-       {}
-};
-
 typedef enum MTProtocols {
        MTP_PRIMARY,
        MTP_UDP,
@@ -135,16 +50,14 @@ inline bool seqnum_higher(u16 totest, u16 base)
        {
                if ((totest - base) > (SEQNUM_MAX/2))
                        return false;
-               else
-                       return true;
-       }
-       else
-       {
-               if ((base - totest) > (SEQNUM_MAX/2))
-                       return true;
-               else
-                       return false;
+
+               return true;
        }
+
+       if ((base - totest) > (SEQNUM_MAX/2))
+               return true;
+
+       return false;
 }
 
 inline bool seqnum_in_window(u16 seqnum, u16 next,u16 window_size)
@@ -152,32 +65,28 @@ inline bool seqnum_in_window(u16 seqnum, u16 next,u16 window_size)
        u16 window_start = next;
        u16 window_end   = ( next + window_size ) % (SEQNUM_MAX+1);
 
-       if (window_start < window_end)
-       {
+       if (window_start < window_end) {
                return ((seqnum >= window_start) && (seqnum < window_end));
        }
-       else
-       {
-               return ((seqnum < window_end) || (seqnum >= window_start));
-       }
+
+
+       return ((seqnum < window_end) || (seqnum >= window_start));
 }
 
 struct BufferedPacket
 {
        BufferedPacket(u8 *a_data, u32 a_size):
-               data(a_data, a_size), time(0.0), totaltime(0.0), absolute_send_time(-1),
-               resend_count(0)
+               data(a_data, a_size)
        {}
        BufferedPacket(u32 a_size):
-               data(a_size), time(0.0), totaltime(0.0), absolute_send_time(-1),
-               resend_count(0)
+               data(a_size)
        {}
        Buffer<u8> data; // Data of the packet, including headers
-       float time; // Seconds from buffering the packet or re-sending
-       float totaltime; // Seconds from buffering the packet
-       unsigned int absolute_send_time;
+       float time = 0.0f; // Seconds from buffering the packet or re-sending
+       float totaltime = 0.0f; // Seconds from buffering the packet
+       u64 absolute_send_time = -1;
        Address address; // Sender or destination
-       unsigned int resend_count;
+       unsigned int resend_count = 0;
 };
 
 // This adds the base headers to the data and makes a packet out of it
@@ -205,21 +114,18 @@ std::list<SharedBuffer<u8> > makeAutoSplitPacket(
 
 // Add the TYPE_RELIABLE header to the data
 SharedBuffer<u8> makeReliablePacket(
-               SharedBuffer<u8> data,
+               const SharedBuffer<u8> &data,
                u16 seqnum);
 
 struct IncomingSplitPacket
 {
-       IncomingSplitPacket()
-       {
-               time = 0.0;
-               reliable = false;
-       }
+       IncomingSplitPacket() = default;
+
        // Key is chunk number, value is data without headers
        std::map<u16, SharedBuffer<u8> > chunks;
        u32 chunk_count;
-       float time; // Seconds from adding
-       bool reliable; // If true, isn't deleted on timeout
+       float time = 0.0f; // Seconds from adding
+       bool reliable = false; // If true, isn't deleted on timeout
 
        bool allReceived()
        {
@@ -322,7 +228,7 @@ typedef std::list<BufferedPacket>::iterator RPBSearchResult;
 class ReliablePacketBuffer
 {
 public:
-       ReliablePacketBuffer();
+       ReliablePacketBuffer() = default;
 
        bool getFirstSeqnum(u16& result);
 
@@ -345,11 +251,11 @@ private:
        RPBSearchResult findPacket(u16 seqnum);
 
        std::list<BufferedPacket> m_list;
-       u32 m_list_size;
+       u32 m_list_size = 0;
 
        u16 m_oldest_non_answered_ack;
 
-       Mutex m_list_mutex;
+       std::mutex m_list_mutex;
 };
 
 /*
@@ -372,7 +278,7 @@ private:
        // Key is seqnum
        std::map<u16, IncomingSplitPacket*> m_buf;
 
-       Mutex m_map_mutex;
+       std::mutex m_map_mutex;
 };
 
 struct OutgoingPacket
@@ -383,7 +289,7 @@ struct OutgoingPacket
        bool reliable;
        bool ack;
 
-       OutgoingPacket(u16 peer_id_, u8 channelnum_, SharedBuffer<u8> data_,
+       OutgoingPacket(u16 peer_id_, u8 channelnum_, const SharedBuffer<u8> &data_,
                        bool reliable_,bool ack_=false):
                peer_id(peer_id_),
                channelnum(channelnum_),
@@ -409,15 +315,15 @@ enum ConnectionCommandType{
 
 struct ConnectionCommand
 {
-       enum ConnectionCommandType type;
+       enum ConnectionCommandType type = CONNCMD_NONE;
        Address address;
-       u16 peer_id;
+       u16 peer_id = PEER_ID_INEXISTENT;
        u8 channelnum;
        Buffer<u8> data;
-       bool reliable;
-       bool raw;
+       bool reliable = false;
+       bool raw = false;
 
-       ConnectionCommand(): type(CONNCMD_NONE), peer_id(PEER_ID_INEXISTENT), reliable(false), raw(false) {}
+       ConnectionCommand() = default;
 
        void serve(Address address_)
        {
@@ -438,17 +344,10 @@ struct ConnectionCommand
                type = CONNCMD_DISCONNECT_PEER;
                peer_id = peer_id_;
        }
-       void send(u16 peer_id_, u8 channelnum_,
-                       NetworkPacket* pkt, bool reliable_)
-       {
-               type = CONNCMD_SEND;
-               peer_id = peer_id_;
-               channelnum = channelnum_;
-               data = pkt->oldForgePacket();
-               reliable = reliable_;
-       }
 
-       void ack(u16 peer_id_, u8 channelnum_, SharedBuffer<u8> data_)
+       void send(u16 peer_id_, u8 channelnum_, NetworkPacket* pkt, bool reliable_);
+
+       void ack(u16 peer_id_, u8 channelnum_, const SharedBuffer<u8> &data_)
        {
                type = CONCMD_ACK;
                peer_id = peer_id_;
@@ -457,7 +356,7 @@ struct ConnectionCommand
                reliable = false;
        }
 
-       void createPeer(u16 peer_id_, SharedBuffer<u8> data_)
+       void createPeer(u16 peer_id_, const SharedBuffer<u8> &data_)
        {
                type = CONCMD_CREATE_PEER;
                peer_id = peer_id_;
@@ -467,7 +366,7 @@ struct ConnectionCommand
                raw = true;
        }
 
-       void disableLegacy(u16 peer_id_, SharedBuffer<u8> data_)
+       void disableLegacy(u16 peer_id_, const SharedBuffer<u8> &data_)
        {
                type = CONCMD_DISABLE_LEGACY;
                peer_id = peer_id_;
@@ -478,6 +377,14 @@ struct ConnectionCommand
        }
 };
 
+/* maximum window size to use, 0xFFFF is theoretical maximum  don't think about
+ * touching it, the less you're away from it the more likely data corruption
+ * will occur
+ */
+#define MAX_RELIABLE_WINDOW_SIZE 0x8000
+       /* starting value for window size */
+#define MIN_RELIABLE_WINDOW_SIZE 0x40
+
 class Channel
 {
 
@@ -507,8 +414,8 @@ public:
 
        IncomingSplitBuffer incoming_splits;
 
-       Channel();
-       ~Channel();
+       Channel() = default;
+       ~Channel() = default;
 
        void UpdatePacketLossCounter(unsigned int count);
        void UpdatePacketTooLateCounter();
@@ -544,77 +451,42 @@ public:
 
        void setWindowSize(unsigned int size) { window_size = size; };
 private:
-       Mutex m_internal_mutex;
-       int window_size;
-
-       u16 next_incoming_seqnum;
-
-       u16 next_outgoing_seqnum;
-       u16 next_outgoing_split_seqnum;
-
-       unsigned int current_packet_loss;
-       unsigned int current_packet_too_late;
-       unsigned int current_packet_successfull;
-       float packet_loss_counter;
-
-       unsigned int current_bytes_transfered;
-       unsigned int current_bytes_received;
-       unsigned int current_bytes_lost;
-       float max_kbps;
-       float cur_kbps;
-       float avg_kbps;
-       float max_incoming_kbps;
-       float cur_incoming_kbps;
-       float avg_incoming_kbps;
-       float max_kbps_lost;
-       float cur_kbps_lost;
-       float avg_kbps_lost;
-       float bpm_counter;
-
-       unsigned int rate_samples;
+       std::mutex m_internal_mutex;
+       int window_size = MIN_RELIABLE_WINDOW_SIZE;
+
+       u16 next_incoming_seqnum = SEQNUM_INITIAL;
+
+       u16 next_outgoing_seqnum = SEQNUM_INITIAL;
+       u16 next_outgoing_split_seqnum = SEQNUM_INITIAL;
+
+       unsigned int current_packet_loss = 0;
+       unsigned int current_packet_too_late = 0;
+       unsigned int current_packet_successfull = 0;
+       float packet_loss_counter = 0.0f;
+
+       unsigned int current_bytes_transfered = 0;
+       unsigned int current_bytes_received = 0;
+       unsigned int current_bytes_lost = 0;
+       float max_kbps = 0.0f;
+       float cur_kbps = 0.0f;
+       float avg_kbps = 0.0f;
+       float max_incoming_kbps = 0.0f;
+       float cur_incoming_kbps = 0.0f;
+       float avg_incoming_kbps = 0.0f;
+       float max_kbps_lost = 0.0f;
+       float cur_kbps_lost = 0.0f;
+       float avg_kbps_lost = 0.0f;
+       float bpm_counter = 0.0f;
+
+       unsigned int rate_samples = 0;
 };
 
 class Peer;
 
-enum PeerChangeType
-{
-       PEER_ADDED,
-       PEER_REMOVED
-};
-struct PeerChange
-{
-       PeerChangeType type;
-       u16 peer_id;
-       bool timeout;
-};
-
-class PeerHandler
-{
-public:
-
-       PeerHandler()
-       {
-       }
-       virtual ~PeerHandler()
-       {
-       }
-
-       /*
-               This is called after the Peer has been inserted into the
-               Connection's peer container.
-       */
-       virtual void peerAdded(Peer *peer) = 0;
-       /*
-               This is called before the Peer has been removed from the
-               Connection's peer container.
-       */
-       virtual void deletingPeer(Peer *peer, bool timeout) = 0;
-};
-
 class PeerHelper
 {
 public:
-       PeerHelper();
+       PeerHelper() = default;
        PeerHelper(Peer* peer);
        ~PeerHelper();
 
@@ -625,20 +497,11 @@ public:
        bool          operator!=(void* ptr);
 
 private:
-       Peer* m_peer;
+       Peer *m_peer = nullptr;
 };
 
 class Connection;
 
-typedef enum {
-       MIN_RTT,
-       MAX_RTT,
-       AVG_RTT,
-       MIN_JITTER,
-       MAX_JITTER,
-       AVG_JITTER
-} rtt_stat_type;
-
 typedef enum {
        CUR_DL_RATE,
        AVG_DL_RATE,
@@ -654,24 +517,10 @@ class Peer {
 
                Peer(Address address_,u16 id_,Connection* connection) :
                        id(id_),
-                       m_increment_packets_remaining(9),
-                       m_increment_bytes_remaining(0),
-                       m_pending_deletion(false),
                        m_connection(connection),
                        address(address_),
-                       m_ping_timer(0.0),
-                       m_last_rtt(-1.0),
-                       m_usage(0),
-                       m_timeout_counter(0.0),
-                       m_last_timeout_check(porting::getTimeMs()),
-                       m_has_sent_with_id(false)
+                       m_last_timeout_check(porting::getTimeMs())
                {
-                       m_rtt.avg_rtt = -1.0;
-                       m_rtt.jitter_avg = -1.0;
-                       m_rtt.jitter_max = 0.0;
-                       m_rtt.max_rtt = 0.0;
-                       m_rtt.jitter_min = FLT_MAX;
-                       m_rtt.min_rtt = FLT_MAX;
                };
 
                virtual ~Peer() {
@@ -687,23 +536,18 @@ class Peer {
                virtual void PutReliableSendCommand(ConnectionCommand &c,
                                                unsigned int max_packet_size) {};
 
-               virtual bool isActive() { return false; };
-
                virtual bool getAddress(MTProtocols type, Address& toset) = 0;
 
+               bool isPendingDeletion()
+               { MutexAutoLock lock(m_exclusive_access_mutex); return m_pending_deletion; };
+
                void ResetTimeout()
-                       {MutexAutoLock lock(m_exclusive_access_mutex); m_timeout_counter=0.0; };
+                       {MutexAutoLock lock(m_exclusive_access_mutex); m_timeout_counter = 0.0; };
 
                bool isTimedOut(float timeout);
 
-               void setSentWithID()
-               { MutexAutoLock lock(m_exclusive_access_mutex); m_has_sent_with_id = true; };
-
-               bool hasSentWithID()
-               { MutexAutoLock lock(m_exclusive_access_mutex); return m_has_sent_with_id; };
-
-               unsigned int m_increment_packets_remaining;
-               unsigned int m_increment_bytes_remaining;
+               unsigned int m_increment_packets_remaining = 9;
+               unsigned int m_increment_bytes_remaining = 0;
 
                virtual u16 getNextSplitSequenceNumber(u8 channel) { return 0; };
                virtual void setNextSplitSequenceNumber(u8 channel, u16 seqnum) {};
@@ -738,15 +582,15 @@ class Peer {
                virtual void reportRTT(float rtt) {};
 
                void RTTStatistics(float rtt,
-                                                       std::string profiler_id="",
-                                                       unsigned int num_samples=1000);
+                                                       const std::string &profiler_id = "",
+                                                       unsigned int num_samples = 1000);
 
                bool IncUseCount();
                void DecUseCount();
 
-               Mutex m_exclusive_access_mutex;
+               std::mutex m_exclusive_access_mutex;
 
-               bool m_pending_deletion;
+               bool m_pending_deletion = false;
 
                Connection* m_connection;
 
@@ -754,30 +598,30 @@ class Peer {
                Address address;
 
                // Ping timer
-               float m_ping_timer;
+               float m_ping_timer = 0.0f;
        private:
 
                struct rttstats {
-                       float jitter_min;
-                       float jitter_max;
-                       float jitter_avg;
-                       float min_rtt;
-                       float max_rtt;
-                       float avg_rtt;
+                       float jitter_min = FLT_MAX;
+                       float jitter_max = 0.0f;
+                       float jitter_avg = -1.0f;
+                       float min_rtt = FLT_MAX;
+                       float max_rtt = 0.0f;
+                       float avg_rtt = -1.0f;
+
+                       rttstats() = default;
                };
 
                rttstats m_rtt;
-               float    m_last_rtt;
+               float m_last_rtt = -1.0f;
 
                // current usage count
-               unsigned int m_usage;
+               unsigned int m_usage = 0;
 
                // Seconds from last receive
-               float m_timeout_counter;
-
-               u32 m_last_timeout_check;
+               float m_timeout_counter = 0.0f;
 
-               bool m_has_sent_with_id;
+               u64 m_last_timeout_check;
 };
 
 class UDPPeer : public Peer
@@ -790,14 +634,11 @@ public:
        friend class Connection;
 
        UDPPeer(u16 a_id, Address a_address, Connection* connection);
-       virtual ~UDPPeer() {};
+       virtual ~UDPPeer() = default;
 
        void PutReliableSendCommand(ConnectionCommand &c,
                                                        unsigned int max_packet_size);
 
-       bool isActive()
-       { return ((hasSentWithID()) && (!m_pending_deletion)); };
-
        bool getAddress(MTProtocols type, Address& toset);
 
        void setNonLegacyPeer();
@@ -833,16 +674,16 @@ protected:
        bool Ping(float dtime,SharedBuffer<u8>& data);
 
        Channel channels[CHANNEL_COUNT];
-       bool m_pending_disconnect;
+       bool m_pending_disconnect = false;
 private:
        // This is changed dynamically
-       float resend_timeout;
+       float resend_timeout = 0.5;
 
        bool processReliableSendCommand(
                                        ConnectionCommand &c,
                                        unsigned int max_packet_size);
 
-       bool m_legacy_peer;
+       bool m_legacy_peer = true;
 };
 
 /*
@@ -859,14 +700,13 @@ enum ConnectionEventType{
 
 struct ConnectionEvent
 {
-       enum ConnectionEventType type;
-       u16 peer_id;
+       enum ConnectionEventType type = CONNEVENT_NONE;
+       u16 peer_id = 0;
        Buffer<u8> data;
-       bool timeout;
+       bool timeout = false;
        Address address;
 
-       ConnectionEvent(): type(CONNEVENT_NONE), peer_id(0),
-                       timeout(false) {}
+       ConnectionEvent() = default;
 
        std::string describe()
        {
@@ -885,7 +725,7 @@ struct ConnectionEvent
                return "Invalid ConnectionEvent";
        }
 
-       void dataReceived(u16 peer_id_, SharedBuffer<u8> data_)
+       void dataReceived(u16 peer_id_, const SharedBuffer<u8> &data_)
        {
                type = CONNEVENT_DATA_RECEIVED;
                peer_id = peer_id_;
@@ -957,16 +797,16 @@ private:
 
        bool packetsQueued();
 
-       Connection*           m_connection;
+       Connection           *m_connection = nullptr;
        unsigned int          m_max_packet_size;
        float                 m_timeout;
        std::queue<OutgoingPacket> m_outgoing_queue;
        Semaphore             m_send_sleep_semaphore;
 
        unsigned int          m_iteration_packets_avaialble;
-       unsigned int          m_max_commands_per_iteration;
+       unsigned int          m_max_commands_per_iteration = 1;
        unsigned int          m_max_data_packets_per_iteration;
-       unsigned int          m_max_packets_requeued;
+       unsigned int          m_max_packets_requeued = 256;
 };
 
 class ConnectionReceiveThread : public Thread {
@@ -1004,9 +844,11 @@ private:
                                                        u8 channelnum, bool reliable);
 
 
-       Connection*           m_connection;
+       Connection *m_connection = nullptr;
 };
 
+class PeerHandler;
+
 class Connection
 {
 public:
@@ -1070,27 +912,25 @@ private:
 
        MutexedQueue<ConnectionEvent> m_event_queue;
 
-       u16 m_peer_id;
+       u16 m_peer_id = 0;
        u32 m_protocol_id;
 
        std::map<u16, Peer*> m_peers;
        std::list<u16> m_peer_ids;
-       Mutex m_peers_mutex;
+       std::mutex m_peers_mutex;
 
        ConnectionSendThread m_sendThread;
        ConnectionReceiveThread m_receiveThread;
 
-       Mutex m_info_mutex;
+       std::mutex m_info_mutex;
 
        // Backwards compatibility
        PeerHandler *m_bc_peerhandler;
-       int m_bc_receive_timeout;
+       int m_bc_receive_timeout = 0;
 
-       bool m_shutting_down;
+       bool m_shutting_down = false;
 
-       u16 m_next_remote_peer_id;
+       u16 m_next_remote_peer_id = 2;
 };
 
 } // namespace
-
-#endif