3 Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU Lesser General Public License as published by
7 the Free Software Foundation; either version 2.1 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public License along
16 with this program; if not, write to the Free Software Foundation, Inc.,
17 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 #ifndef CONNECTION_HEADER
21 #define CONNECTION_HEADER
23 #include "irrlichttypes_bloated.h"
25 #include "exceptions.h"
26 #include "constants.h"
27 #include "network/networkpacket.h"
28 #include "util/pointer.h"
29 #include "util/container.h"
30 #include "util/thread.h"
31 #include "util/numeric.h"
45 class NotFoundException : public BaseException
48 NotFoundException(const char *s):
53 class PeerNotFoundException : public BaseException
56 PeerNotFoundException(const char *s):
61 class ConnectionException : public BaseException
64 ConnectionException(const char *s):
69 class ConnectionBindFailed : public BaseException
72 ConnectionBindFailed(const char *s):
77 class InvalidIncomingDataException : public BaseException
80 InvalidIncomingDataException(const char *s):
85 class InvalidOutgoingDataException : public BaseException
88 InvalidOutgoingDataException(const char *s):
93 class NoIncomingDataException : public BaseException
96 NoIncomingDataException(const char *s):
101 class ProcessedSilentlyException : public BaseException
104 ProcessedSilentlyException(const char *s):
109 class ProcessedQueued : public BaseException
112 ProcessedQueued(const char *s):
117 class IncomingDataCorruption : public BaseException
120 IncomingDataCorruption(const char *s):
125 typedef enum MTProtocols {
128 MTP_MINETEST_RELIABLE_UDP
131 #define SEQNUM_MAX 65535
132 inline bool seqnum_higher(u16 totest, u16 base)
136 if ((totest - base) > (SEQNUM_MAX/2))
143 if ((base - totest) > (SEQNUM_MAX/2))
150 inline bool seqnum_in_window(u16 seqnum, u16 next,u16 window_size)
152 u16 window_start = next;
153 u16 window_end = ( next + window_size ) % (SEQNUM_MAX+1);
155 if (window_start < window_end)
157 return ((seqnum >= window_start) && (seqnum < window_end));
161 return ((seqnum < window_end) || (seqnum >= window_start));
165 struct BufferedPacket
167 BufferedPacket(u8 *a_data, u32 a_size):
170 BufferedPacket(u32 a_size):
171 data(a_size), time(0.0), totaltime(0.0), absolute_send_time(-1),
174 Buffer<u8> data; // Data of the packet, including headers
175 float time = 0.0f; // Seconds from buffering the packet or re-sending
176 float totaltime = 0.0f; // Seconds from buffering the packet
177 u64 absolute_send_time = -1;
178 Address address; // Sender or destination
179 unsigned int resend_count = 0;
182 // This adds the base headers to the data and makes a packet out of it
183 BufferedPacket makePacket(Address &address, u8 *data, u32 datasize,
184 u32 protocol_id, u16 sender_peer_id, u8 channel);
185 BufferedPacket makePacket(Address &address, SharedBuffer<u8> &data,
186 u32 protocol_id, u16 sender_peer_id, u8 channel);
188 // Add the TYPE_ORIGINAL header to the data
189 SharedBuffer<u8> makeOriginalPacket(
190 SharedBuffer<u8> data);
192 // Split data in chunks and add TYPE_SPLIT headers to them
193 std::list<SharedBuffer<u8> > makeSplitPacket(
194 SharedBuffer<u8> data,
198 // Depending on size, make a TYPE_ORIGINAL or TYPE_SPLIT packet
199 // Increments split_seqnum if a split packet is made
200 std::list<SharedBuffer<u8> > makeAutoSplitPacket(
201 SharedBuffer<u8> data,
205 // Add the TYPE_RELIABLE header to the data
206 SharedBuffer<u8> makeReliablePacket(
207 SharedBuffer<u8> data,
210 struct IncomingSplitPacket
212 IncomingSplitPacket() {}
213 // Key is chunk number, value is data without headers
214 std::map<u16, SharedBuffer<u8> > chunks;
216 float time = 0.0f; // Seconds from adding
217 bool reliable = false; // If true, isn't deleted on timeout
221 return (chunks.size() == chunk_count);
228 A packet is sent through a channel to a peer with a basic header:
229 TODO: Should we have a receiver_peer_id also?
232 [4] u16 sender_peer_id
236 value 0 (PEER_ID_INEXISTENT) is reserved for making new connections
237 value 1 (PEER_ID_SERVER) is reserved for server
238 these constants are defined in constants.h
240 The lower the number, the higher the priority is.
241 Only channels 0, 1 and 2 exist.
243 #define BASE_HEADER_SIZE 7
244 #define CHANNEL_COUNT 3
248 CONTROL: This is a packet used by the protocol.
249 - When this is processed, nothing is handed to the user.
253 controltype and data description:
256 CONTROLTYPE_SET_PEER_ID
259 - There is no actual reply, but this can be sent in a reliable
260 packet to get a reply
263 #define TYPE_CONTROL 0
264 #define CONTROLTYPE_ACK 0
265 #define CONTROLTYPE_SET_PEER_ID 1
266 #define CONTROLTYPE_PING 2
267 #define CONTROLTYPE_DISCO 3
268 #define CONTROLTYPE_ENABLE_BIG_SEND_WINDOW 4
271 ORIGINAL: This is a plain packet with no control and no error
273 - When this is processed, it is directly handed to the user.
277 #define TYPE_ORIGINAL 1
278 #define ORIGINAL_HEADER_SIZE 1
280 SPLIT: These are sequences of packets forming one bigger piece of
282 - When processed and all the packet_nums 0...packet_count-1 are
283 present (this should be buffered), the resulting data shall be
284 directly handed to the user.
285 - If the data fails to come up in a reasonable time, the buffer shall
286 be silently discarded.
287 - These can be sent as-is or atop of a RELIABLE packet stream.
296 RELIABLE: Delivery of all RELIABLE packets shall be forced by ACKs,
297 and they shall be delivered in the same order as sent. This is done
298 with a buffer in the receiving and transmitting end.
299 - When this is processed, the contents of each packet is recursively
300 processed as packets.
306 #define TYPE_RELIABLE 3
307 #define RELIABLE_HEADER_SIZE 3
308 #define SEQNUM_INITIAL 65500
311 A buffer which stores reliable packets and sorts them internally
312 for fast access to the smallest one.
315 typedef std::list<BufferedPacket>::iterator RPBSearchResult;
317 class ReliablePacketBuffer
320 ReliablePacketBuffer() {};
322 bool getFirstSeqnum(u16& result);
324 BufferedPacket popFirst();
325 BufferedPacket popSeqnum(u16 seqnum);
326 void insert(BufferedPacket &p,u16 next_expected);
328 void incrementTimeouts(float dtime);
329 std::list<BufferedPacket> getTimedOuts(float timeout,
330 unsigned int max_packets);
334 bool containsPacket(u16 seqnum);
335 RPBSearchResult notFound();
340 RPBSearchResult findPacket(u16 seqnum);
342 std::list<BufferedPacket> m_list;
345 u16 m_oldest_non_answered_ack;
347 std::mutex m_list_mutex;
351 A buffer for reconstructing split packets
354 class IncomingSplitBuffer
357 ~IncomingSplitBuffer();
359 Returns a reference counted buffer of length != 0 when a full split
360 packet is constructed. If not, returns one of length 0.
362 SharedBuffer<u8> insert(BufferedPacket &p, bool reliable);
364 void removeUnreliableTimedOuts(float dtime, float timeout);
368 std::map<u16, IncomingSplitPacket*> m_buf;
370 std::mutex m_map_mutex;
373 struct OutgoingPacket
377 SharedBuffer<u8> data;
381 OutgoingPacket(u16 peer_id_, u8 channelnum_, const SharedBuffer<u8> &data_,
382 bool reliable_,bool ack_=false):
384 channelnum(channelnum_),
392 enum ConnectionCommandType{
397 CONNCMD_DISCONNECT_PEER,
402 CONCMD_DISABLE_LEGACY
405 struct ConnectionCommand
407 enum ConnectionCommandType type = CONNCMD_NONE;
409 u16 peer_id = PEER_ID_INEXISTENT;
412 bool reliable = false;
415 ConnectionCommand() {}
417 void serve(Address address_)
419 type = CONNCMD_SERVE;
422 void connect(Address address_)
424 type = CONNCMD_CONNECT;
429 type = CONNCMD_DISCONNECT;
431 void disconnect_peer(u16 peer_id_)
433 type = CONNCMD_DISCONNECT_PEER;
436 void send(u16 peer_id_, u8 channelnum_,
437 NetworkPacket* pkt, bool reliable_)
441 channelnum = channelnum_;
442 data = pkt->oldForgePacket();
443 reliable = reliable_;
446 void ack(u16 peer_id_, u8 channelnum_, const SharedBuffer<u8> &data_)
450 channelnum = channelnum_;
455 void createPeer(u16 peer_id_, const SharedBuffer<u8> &data_)
457 type = CONCMD_CREATE_PEER;
465 void disableLegacy(u16 peer_id_, const SharedBuffer<u8> &data_)
467 type = CONCMD_DISABLE_LEGACY;
476 /* maximum window size to use, 0xFFFF is theoretical maximum don't think about
477 * touching it, the less you're away from it the more likely data corruption
480 #define MAX_RELIABLE_WINDOW_SIZE 0x8000
481 /* starting value for window size */
482 #define MIN_RELIABLE_WINDOW_SIZE 0x40
488 u16 readNextIncomingSeqNum();
489 u16 incNextIncomingSeqNum();
491 u16 getOutgoingSequenceNumber(bool& successfull);
492 u16 readOutgoingSequenceNumber();
493 bool putBackSequenceNumber(u16);
495 u16 readNextSplitSeqNum();
496 void setNextSplitSeqNum(u16 seqnum);
498 // This is for buffering the incoming packets that are coming in
500 ReliablePacketBuffer incoming_reliables;
501 // This is for buffering the sent packets so that the sender can
502 // re-send them if no ACK is received
503 ReliablePacketBuffer outgoing_reliables_sent;
505 //queued reliable packets
506 std::queue<BufferedPacket> queued_reliables;
508 //queue commands prior splitting to packets
509 std::deque<ConnectionCommand> queued_commands;
511 IncomingSplitBuffer incoming_splits;
516 void UpdatePacketLossCounter(unsigned int count);
517 void UpdatePacketTooLateCounter();
518 void UpdateBytesSent(unsigned int bytes,unsigned int packages=1);
519 void UpdateBytesLost(unsigned int bytes);
520 void UpdateBytesReceived(unsigned int bytes);
522 void UpdateTimers(float dtime, bool legacy_peer);
524 const float getCurrentDownloadRateKB()
525 { MutexAutoLock lock(m_internal_mutex); return cur_kbps; };
526 const float getMaxDownloadRateKB()
527 { MutexAutoLock lock(m_internal_mutex); return max_kbps; };
529 const float getCurrentLossRateKB()
530 { MutexAutoLock lock(m_internal_mutex); return cur_kbps_lost; };
531 const float getMaxLossRateKB()
532 { MutexAutoLock lock(m_internal_mutex); return max_kbps_lost; };
534 const float getCurrentIncomingRateKB()
535 { MutexAutoLock lock(m_internal_mutex); return cur_incoming_kbps; };
536 const float getMaxIncomingRateKB()
537 { MutexAutoLock lock(m_internal_mutex); return max_incoming_kbps; };
539 const float getAvgDownloadRateKB()
540 { MutexAutoLock lock(m_internal_mutex); return avg_kbps; };
541 const float getAvgLossRateKB()
542 { MutexAutoLock lock(m_internal_mutex); return avg_kbps_lost; };
543 const float getAvgIncomingRateKB()
544 { MutexAutoLock lock(m_internal_mutex); return avg_incoming_kbps; };
546 const unsigned int getWindowSize() const { return window_size; };
548 void setWindowSize(unsigned int size) { window_size = size; };
550 std::mutex m_internal_mutex;
551 int window_size = MIN_RELIABLE_WINDOW_SIZE;
553 u16 next_incoming_seqnum = SEQNUM_INITIAL;
555 u16 next_outgoing_seqnum = SEQNUM_INITIAL;
556 u16 next_outgoing_split_seqnum = SEQNUM_INITIAL;
558 unsigned int current_packet_loss = 0;
559 unsigned int current_packet_too_late = 0;
560 unsigned int current_packet_successfull = 0;
561 float packet_loss_counter = 0.0f;
563 unsigned int current_bytes_transfered = 0;
564 unsigned int current_bytes_received = 0;
565 unsigned int current_bytes_lost = 0;
566 float max_kbps = 0.0f;
567 float cur_kbps = 0.0f;
568 float avg_kbps = 0.0f;
569 float max_incoming_kbps = 0.0f;
570 float cur_incoming_kbps = 0.0f;
571 float avg_incoming_kbps = 0.0f;
572 float max_kbps_lost = 0.0f;
573 float cur_kbps_lost = 0.0f;
574 float avg_kbps_lost = 0.0f;
575 float bpm_counter = 0.0f;
577 unsigned int rate_samples = 0;
589 PeerChange(PeerChangeType t, u16 _peer_id, bool _timeout):
590 type(t), peer_id(_peer_id), timeout(_timeout) {}
591 PeerChange() = delete;
605 virtual ~PeerHandler()
610 This is called after the Peer has been inserted into the
611 Connection's peer container.
613 virtual void peerAdded(Peer *peer) = 0;
615 This is called before the Peer has been removed from the
616 Connection's peer container.
618 virtual void deletingPeer(Peer *peer, bool timeout) = 0;
625 PeerHelper(Peer* peer);
628 PeerHelper& operator=(Peer* peer);
629 Peer* operator->() const;
631 Peer* operator&() const;
632 bool operator!=(void* ptr);
635 Peer *m_peer = nullptr;
660 friend class PeerHelper;
662 Peer(Address address_,u16 id_,Connection* connection) :
664 m_connection(connection),
666 m_last_timeout_check(porting::getTimeMs())
671 MutexAutoLock usage_lock(m_exclusive_access_mutex);
672 FATAL_ERROR_IF(m_usage != 0, "Reference counting failure");
675 // Unique id of the peer
680 virtual void PutReliableSendCommand(ConnectionCommand &c,
681 unsigned int max_packet_size) {};
683 virtual bool getAddress(MTProtocols type, Address& toset) = 0;
685 bool isPendingDeletion()
686 { MutexAutoLock lock(m_exclusive_access_mutex); return m_pending_deletion; };
689 {MutexAutoLock lock(m_exclusive_access_mutex); m_timeout_counter = 0.0; };
691 bool isTimedOut(float timeout);
693 unsigned int m_increment_packets_remaining = 9;
694 unsigned int m_increment_bytes_remaining = 0;
696 virtual u16 getNextSplitSequenceNumber(u8 channel) { return 0; };
697 virtual void setNextSplitSequenceNumber(u8 channel, u16 seqnum) {};
698 virtual SharedBuffer<u8> addSpiltPacket(u8 channel,
699 BufferedPacket toadd,
702 fprintf(stderr,"Peer: addSplitPacket called, this is supposed to be never called!\n");
703 return SharedBuffer<u8>(0);
706 virtual bool Ping(float dtime, SharedBuffer<u8>& data) { return false; };
708 virtual float getStat(rtt_stat_type type) const {
711 return m_rtt.min_rtt;
713 return m_rtt.max_rtt;
715 return m_rtt.avg_rtt;
717 return m_rtt.jitter_min;
719 return m_rtt.jitter_max;
721 return m_rtt.jitter_avg;
726 virtual void reportRTT(float rtt) {};
728 void RTTStatistics(float rtt,
729 const std::string &profiler_id = "",
730 unsigned int num_samples = 1000);
735 std::mutex m_exclusive_access_mutex;
737 bool m_pending_deletion = false;
739 Connection* m_connection;
741 // Address of the peer
745 float m_ping_timer = 0.0f;
749 float jitter_min = FLT_MAX;
750 float jitter_max = 0.0f;
751 float jitter_avg = -1.0f;
752 float min_rtt = FLT_MAX;
753 float max_rtt = 0.0f;
754 float avg_rtt = -1.0f;
760 float m_last_rtt = -1.0f;
762 // current usage count
763 unsigned int m_usage = 0;
765 // Seconds from last receive
766 float m_timeout_counter = 0.0f;
768 u64 m_last_timeout_check;
771 class UDPPeer : public Peer
775 friend class PeerHelper;
776 friend class ConnectionReceiveThread;
777 friend class ConnectionSendThread;
778 friend class Connection;
780 UDPPeer(u16 a_id, Address a_address, Connection* connection);
781 virtual ~UDPPeer() {};
783 void PutReliableSendCommand(ConnectionCommand &c,
784 unsigned int max_packet_size);
786 bool getAddress(MTProtocols type, Address& toset);
788 void setNonLegacyPeer();
791 { return m_legacy_peer; }
793 u16 getNextSplitSequenceNumber(u8 channel);
794 void setNextSplitSequenceNumber(u8 channel, u16 seqnum);
796 SharedBuffer<u8> addSpiltPacket(u8 channel,
797 BufferedPacket toadd,
803 Calculates avg_rtt and resend_timeout.
804 rtt=-1 only recalculates resend_timeout
806 void reportRTT(float rtt);
808 void RunCommandQueues(
809 unsigned int max_packet_size,
810 unsigned int maxcommands,
811 unsigned int maxtransfer);
813 float getResendTimeout()
814 { MutexAutoLock lock(m_exclusive_access_mutex); return resend_timeout; }
816 void setResendTimeout(float timeout)
817 { MutexAutoLock lock(m_exclusive_access_mutex); resend_timeout = timeout; }
818 bool Ping(float dtime,SharedBuffer<u8>& data);
820 Channel channels[CHANNEL_COUNT];
821 bool m_pending_disconnect = false;
823 // This is changed dynamically
824 float resend_timeout = 0.5;
826 bool processReliableSendCommand(
827 ConnectionCommand &c,
828 unsigned int max_packet_size);
830 bool m_legacy_peer = true;
837 enum ConnectionEventType{
839 CONNEVENT_DATA_RECEIVED,
840 CONNEVENT_PEER_ADDED,
841 CONNEVENT_PEER_REMOVED,
842 CONNEVENT_BIND_FAILED,
845 struct ConnectionEvent
847 enum ConnectionEventType type = CONNEVENT_NONE;
850 bool timeout = false;
855 std::string describe()
859 return "CONNEVENT_NONE";
860 case CONNEVENT_DATA_RECEIVED:
861 return "CONNEVENT_DATA_RECEIVED";
862 case CONNEVENT_PEER_ADDED:
863 return "CONNEVENT_PEER_ADDED";
864 case CONNEVENT_PEER_REMOVED:
865 return "CONNEVENT_PEER_REMOVED";
866 case CONNEVENT_BIND_FAILED:
867 return "CONNEVENT_BIND_FAILED";
869 return "Invalid ConnectionEvent";
872 void dataReceived(u16 peer_id_, const SharedBuffer<u8> &data_)
874 type = CONNEVENT_DATA_RECEIVED;
878 void peerAdded(u16 peer_id_, Address address_)
880 type = CONNEVENT_PEER_ADDED;
884 void peerRemoved(u16 peer_id_, bool timeout_, Address address_)
886 type = CONNEVENT_PEER_REMOVED;
893 type = CONNEVENT_BIND_FAILED;
897 class ConnectionSendThread : public Thread {
900 friend class UDPPeer;
902 ConnectionSendThread(unsigned int max_packet_size, float timeout);
908 void setParent(Connection* parent) {
909 assert(parent != NULL); // Pre-condition
910 m_connection = parent;
913 void setPeerTimeout(float peer_timeout)
914 { m_timeout = peer_timeout; }
917 void runTimeouts (float dtime);
918 void rawSend (const BufferedPacket &packet);
919 bool rawSendAsPacket(u16 peer_id, u8 channelnum,
920 SharedBuffer<u8> data, bool reliable);
922 void processReliableCommand (ConnectionCommand &c);
923 void processNonReliableCommand (ConnectionCommand &c);
924 void serve (Address bind_address);
925 void connect (Address address);
927 void disconnect_peer(u16 peer_id);
928 void send (u16 peer_id, u8 channelnum,
929 SharedBuffer<u8> data);
930 void sendReliable (ConnectionCommand &c);
931 void sendToAll (u8 channelnum,
932 SharedBuffer<u8> data);
933 void sendToAllReliable(ConnectionCommand &c);
935 void sendPackets (float dtime);
937 void sendAsPacket (u16 peer_id, u8 channelnum,
938 SharedBuffer<u8> data,bool ack=false);
940 void sendAsPacketReliable(BufferedPacket& p, Channel* channel);
942 bool packetsQueued();
944 Connection *m_connection = nullptr;
945 unsigned int m_max_packet_size;
947 std::queue<OutgoingPacket> m_outgoing_queue;
948 Semaphore m_send_sleep_semaphore;
950 unsigned int m_iteration_packets_avaialble;
951 unsigned int m_max_commands_per_iteration = 1;
952 unsigned int m_max_data_packets_per_iteration;
953 unsigned int m_max_packets_requeued = 256;
956 class ConnectionReceiveThread : public Thread {
958 ConnectionReceiveThread(unsigned int max_packet_size);
962 void setParent(Connection *parent) {
963 assert(parent); // Pre-condition
964 m_connection = parent;
970 // Returns next data from a buffer if possible
971 // If found, returns true; if not, false.
972 // If found, sets peer_id and dst
973 bool getFromBuffers(u16 &peer_id, SharedBuffer<u8> &dst);
975 bool checkIncomingBuffers(Channel *channel, u16 &peer_id,
976 SharedBuffer<u8> &dst);
979 Processes a packet with the basic header stripped out.
981 packetdata: Data in packet (with no base headers)
982 peer_id: peer id of the sender of the packet in question
983 channelnum: channel on which the packet was sent
984 reliable: true if recursing into a reliable packet
986 SharedBuffer<u8> processPacket(Channel *channel,
987 SharedBuffer<u8> packetdata, u16 peer_id,
988 u8 channelnum, bool reliable);
991 Connection *m_connection = nullptr;
997 friend class ConnectionSendThread;
998 friend class ConnectionReceiveThread;
1000 Connection(u32 protocol_id, u32 max_packet_size, float timeout, bool ipv6,
1001 PeerHandler *peerhandler);
1005 ConnectionEvent waitEvent(u32 timeout_ms);
1006 void putCommand(ConnectionCommand &c);
1008 void SetTimeoutMs(int timeout) { m_bc_receive_timeout = timeout; }
1009 void Serve(Address bind_addr);
1010 void Connect(Address address);
1013 void Receive(NetworkPacket* pkt);
1014 void Send(u16 peer_id, u8 channelnum, NetworkPacket* pkt, bool reliable);
1015 u16 GetPeerID() { return m_peer_id; }
1016 Address GetPeerAddress(u16 peer_id);
1017 float getPeerStat(u16 peer_id, rtt_stat_type type);
1018 float getLocalStat(rate_stat_type type);
1019 const u32 GetProtocolID() const { return m_protocol_id; };
1020 const std::string getDesc();
1021 void DisconnectPeer(u16 peer_id);
1024 PeerHelper getPeer(u16 peer_id);
1025 PeerHelper getPeerNoEx(u16 peer_id);
1026 u16 lookupPeer(Address& sender);
1028 u16 createPeer(Address& sender, MTProtocols protocol, int fd);
1029 UDPPeer* createServerPeer(Address& sender);
1030 bool deletePeer(u16 peer_id, bool timeout);
1032 void SetPeerID(u16 id) { m_peer_id = id; }
1034 void sendAck(u16 peer_id, u8 channelnum, u16 seqnum);
1036 void PrintInfo(std::ostream &out);
1039 std::list<u16> getPeerIDs()
1041 MutexAutoLock peerlock(m_peers_mutex);
1045 UDPSocket m_udpSocket;
1046 MutexedQueue<ConnectionCommand> m_command_queue;
1048 void putEvent(ConnectionEvent &e);
1051 { m_sendThread.Trigger(); }
1053 std::list<Peer*> getPeers();
1055 MutexedQueue<ConnectionEvent> m_event_queue;
1060 std::map<u16, Peer*> m_peers;
1061 std::list<u16> m_peer_ids;
1062 std::mutex m_peers_mutex;
1064 ConnectionSendThread m_sendThread;
1065 ConnectionReceiveThread m_receiveThread;
1067 std::mutex m_info_mutex;
1069 // Backwards compatibility
1070 PeerHandler *m_bc_peerhandler;
1071 int m_bc_receive_timeout = 0;
1073 bool m_shutting_down = false;
1075 u16 m_next_remote_peer_id = 2;