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;
601 virtual ~PeerHandler()
606 This is called after the Peer has been inserted into the
607 Connection's peer container.
609 virtual void peerAdded(Peer *peer) = 0;
611 This is called before the Peer has been removed from the
612 Connection's peer container.
614 virtual void deletingPeer(Peer *peer, bool timeout) = 0;
621 PeerHelper(Peer* peer);
624 PeerHelper& operator=(Peer* peer);
625 Peer* operator->() const;
627 Peer* operator&() const;
628 bool operator!=(void* ptr);
631 Peer *m_peer = nullptr;
656 friend class PeerHelper;
658 Peer(Address address_,u16 id_,Connection* connection) :
660 m_connection(connection),
662 m_last_timeout_check(porting::getTimeMs())
667 MutexAutoLock usage_lock(m_exclusive_access_mutex);
668 FATAL_ERROR_IF(m_usage != 0, "Reference counting failure");
671 // Unique id of the peer
676 virtual void PutReliableSendCommand(ConnectionCommand &c,
677 unsigned int max_packet_size) {};
679 virtual bool getAddress(MTProtocols type, Address& toset) = 0;
681 bool isPendingDeletion()
682 { MutexAutoLock lock(m_exclusive_access_mutex); return m_pending_deletion; };
685 {MutexAutoLock lock(m_exclusive_access_mutex); m_timeout_counter = 0.0; };
687 bool isTimedOut(float timeout);
689 unsigned int m_increment_packets_remaining = 9;
690 unsigned int m_increment_bytes_remaining = 0;
692 virtual u16 getNextSplitSequenceNumber(u8 channel) { return 0; };
693 virtual void setNextSplitSequenceNumber(u8 channel, u16 seqnum) {};
694 virtual SharedBuffer<u8> addSpiltPacket(u8 channel,
695 BufferedPacket toadd,
698 fprintf(stderr,"Peer: addSplitPacket called, this is supposed to be never called!\n");
699 return SharedBuffer<u8>(0);
702 virtual bool Ping(float dtime, SharedBuffer<u8>& data) { return false; };
704 virtual float getStat(rtt_stat_type type) const {
707 return m_rtt.min_rtt;
709 return m_rtt.max_rtt;
711 return m_rtt.avg_rtt;
713 return m_rtt.jitter_min;
715 return m_rtt.jitter_max;
717 return m_rtt.jitter_avg;
722 virtual void reportRTT(float rtt) {};
724 void RTTStatistics(float rtt,
725 const std::string &profiler_id = "",
726 unsigned int num_samples = 1000);
731 std::mutex m_exclusive_access_mutex;
733 bool m_pending_deletion = false;
735 Connection* m_connection;
737 // Address of the peer
741 float m_ping_timer = 0.0f;
745 float jitter_min = FLT_MAX;
746 float jitter_max = 0.0f;
747 float jitter_avg = -1.0f;
748 float min_rtt = FLT_MAX;
749 float max_rtt = 0.0f;
750 float avg_rtt = -1.0f;
756 float m_last_rtt = -1.0f;
758 // current usage count
759 unsigned int m_usage = 0;
761 // Seconds from last receive
762 float m_timeout_counter = 0.0f;
764 u64 m_last_timeout_check;
767 class UDPPeer : public Peer
771 friend class PeerHelper;
772 friend class ConnectionReceiveThread;
773 friend class ConnectionSendThread;
774 friend class Connection;
776 UDPPeer(u16 a_id, Address a_address, Connection* connection);
777 virtual ~UDPPeer() {};
779 void PutReliableSendCommand(ConnectionCommand &c,
780 unsigned int max_packet_size);
782 bool getAddress(MTProtocols type, Address& toset);
784 void setNonLegacyPeer();
787 { return m_legacy_peer; }
789 u16 getNextSplitSequenceNumber(u8 channel);
790 void setNextSplitSequenceNumber(u8 channel, u16 seqnum);
792 SharedBuffer<u8> addSpiltPacket(u8 channel,
793 BufferedPacket toadd,
799 Calculates avg_rtt and resend_timeout.
800 rtt=-1 only recalculates resend_timeout
802 void reportRTT(float rtt);
804 void RunCommandQueues(
805 unsigned int max_packet_size,
806 unsigned int maxcommands,
807 unsigned int maxtransfer);
809 float getResendTimeout()
810 { MutexAutoLock lock(m_exclusive_access_mutex); return resend_timeout; }
812 void setResendTimeout(float timeout)
813 { MutexAutoLock lock(m_exclusive_access_mutex); resend_timeout = timeout; }
814 bool Ping(float dtime,SharedBuffer<u8>& data);
816 Channel channels[CHANNEL_COUNT];
817 bool m_pending_disconnect = false;
819 // This is changed dynamically
820 float resend_timeout = 0.5;
822 bool processReliableSendCommand(
823 ConnectionCommand &c,
824 unsigned int max_packet_size);
826 bool m_legacy_peer = true;
833 enum ConnectionEventType{
835 CONNEVENT_DATA_RECEIVED,
836 CONNEVENT_PEER_ADDED,
837 CONNEVENT_PEER_REMOVED,
838 CONNEVENT_BIND_FAILED,
841 struct ConnectionEvent
843 enum ConnectionEventType type = CONNEVENT_NONE;
846 bool timeout = false;
851 std::string describe()
855 return "CONNEVENT_NONE";
856 case CONNEVENT_DATA_RECEIVED:
857 return "CONNEVENT_DATA_RECEIVED";
858 case CONNEVENT_PEER_ADDED:
859 return "CONNEVENT_PEER_ADDED";
860 case CONNEVENT_PEER_REMOVED:
861 return "CONNEVENT_PEER_REMOVED";
862 case CONNEVENT_BIND_FAILED:
863 return "CONNEVENT_BIND_FAILED";
865 return "Invalid ConnectionEvent";
868 void dataReceived(u16 peer_id_, const SharedBuffer<u8> &data_)
870 type = CONNEVENT_DATA_RECEIVED;
874 void peerAdded(u16 peer_id_, Address address_)
876 type = CONNEVENT_PEER_ADDED;
880 void peerRemoved(u16 peer_id_, bool timeout_, Address address_)
882 type = CONNEVENT_PEER_REMOVED;
889 type = CONNEVENT_BIND_FAILED;
893 class ConnectionSendThread : public Thread {
896 friend class UDPPeer;
898 ConnectionSendThread(unsigned int max_packet_size, float timeout);
904 void setParent(Connection* parent) {
905 assert(parent != NULL); // Pre-condition
906 m_connection = parent;
909 void setPeerTimeout(float peer_timeout)
910 { m_timeout = peer_timeout; }
913 void runTimeouts (float dtime);
914 void rawSend (const BufferedPacket &packet);
915 bool rawSendAsPacket(u16 peer_id, u8 channelnum,
916 SharedBuffer<u8> data, bool reliable);
918 void processReliableCommand (ConnectionCommand &c);
919 void processNonReliableCommand (ConnectionCommand &c);
920 void serve (Address bind_address);
921 void connect (Address address);
923 void disconnect_peer(u16 peer_id);
924 void send (u16 peer_id, u8 channelnum,
925 SharedBuffer<u8> data);
926 void sendReliable (ConnectionCommand &c);
927 void sendToAll (u8 channelnum,
928 SharedBuffer<u8> data);
929 void sendToAllReliable(ConnectionCommand &c);
931 void sendPackets (float dtime);
933 void sendAsPacket (u16 peer_id, u8 channelnum,
934 SharedBuffer<u8> data,bool ack=false);
936 void sendAsPacketReliable(BufferedPacket& p, Channel* channel);
938 bool packetsQueued();
940 Connection *m_connection = nullptr;
941 unsigned int m_max_packet_size;
943 std::queue<OutgoingPacket> m_outgoing_queue;
944 Semaphore m_send_sleep_semaphore;
946 unsigned int m_iteration_packets_avaialble;
947 unsigned int m_max_commands_per_iteration = 1;
948 unsigned int m_max_data_packets_per_iteration;
949 unsigned int m_max_packets_requeued = 256;
952 class ConnectionReceiveThread : public Thread {
954 ConnectionReceiveThread(unsigned int max_packet_size);
958 void setParent(Connection *parent) {
959 assert(parent); // Pre-condition
960 m_connection = parent;
966 // Returns next data from a buffer if possible
967 // If found, returns true; if not, false.
968 // If found, sets peer_id and dst
969 bool getFromBuffers(u16 &peer_id, SharedBuffer<u8> &dst);
971 bool checkIncomingBuffers(Channel *channel, u16 &peer_id,
972 SharedBuffer<u8> &dst);
975 Processes a packet with the basic header stripped out.
977 packetdata: Data in packet (with no base headers)
978 peer_id: peer id of the sender of the packet in question
979 channelnum: channel on which the packet was sent
980 reliable: true if recursing into a reliable packet
982 SharedBuffer<u8> processPacket(Channel *channel,
983 SharedBuffer<u8> packetdata, u16 peer_id,
984 u8 channelnum, bool reliable);
987 Connection *m_connection = nullptr;
993 friend class ConnectionSendThread;
994 friend class ConnectionReceiveThread;
996 Connection(u32 protocol_id, u32 max_packet_size, float timeout, bool ipv6,
997 PeerHandler *peerhandler);
1001 ConnectionEvent waitEvent(u32 timeout_ms);
1002 void putCommand(ConnectionCommand &c);
1004 void SetTimeoutMs(int timeout) { m_bc_receive_timeout = timeout; }
1005 void Serve(Address bind_addr);
1006 void Connect(Address address);
1009 void Receive(NetworkPacket* pkt);
1010 void Send(u16 peer_id, u8 channelnum, NetworkPacket* pkt, bool reliable);
1011 u16 GetPeerID() { return m_peer_id; }
1012 Address GetPeerAddress(u16 peer_id);
1013 float getPeerStat(u16 peer_id, rtt_stat_type type);
1014 float getLocalStat(rate_stat_type type);
1015 const u32 GetProtocolID() const { return m_protocol_id; };
1016 const std::string getDesc();
1017 void DisconnectPeer(u16 peer_id);
1020 PeerHelper getPeer(u16 peer_id);
1021 PeerHelper getPeerNoEx(u16 peer_id);
1022 u16 lookupPeer(Address& sender);
1024 u16 createPeer(Address& sender, MTProtocols protocol, int fd);
1025 UDPPeer* createServerPeer(Address& sender);
1026 bool deletePeer(u16 peer_id, bool timeout);
1028 void SetPeerID(u16 id) { m_peer_id = id; }
1030 void sendAck(u16 peer_id, u8 channelnum, u16 seqnum);
1032 void PrintInfo(std::ostream &out);
1035 std::list<u16> getPeerIDs()
1037 MutexAutoLock peerlock(m_peers_mutex);
1041 UDPSocket m_udpSocket;
1042 MutexedQueue<ConnectionCommand> m_command_queue;
1044 void putEvent(ConnectionEvent &e);
1047 { m_sendThread.Trigger(); }
1049 std::list<Peer*> getPeers();
1051 MutexedQueue<ConnectionEvent> m_event_queue;
1056 std::map<u16, Peer*> m_peers;
1057 std::list<u16> m_peer_ids;
1058 std::mutex m_peers_mutex;
1060 ConnectionSendThread m_sendThread;
1061 ConnectionReceiveThread m_receiveThread;
1063 std::mutex m_info_mutex;
1065 // Backwards compatibility
1066 PeerHandler *m_bc_peerhandler;
1067 int m_bc_receive_timeout = 0;
1069 bool m_shutting_down = false;
1071 u16 m_next_remote_peer_id = 2;