Fix Travis/unittest broken since b662a45
[oweals/minetest.git] / src / network / connection.h
1 /*
2 Minetest
3 Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>
4
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.
9
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.
14
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.
18 */
19
20 #ifndef CONNECTION_HEADER
21 #define CONNECTION_HEADER
22
23 #include "irrlichttypes_bloated.h"
24 #include "socket.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"
32 #include <iostream>
33 #include <fstream>
34 #include <list>
35 #include <map>
36
37 class NetworkPacket;
38
39 namespace con
40 {
41
42 /*
43         Exceptions
44 */
45 class NotFoundException : public BaseException
46 {
47 public:
48         NotFoundException(const char *s):
49                 BaseException(s)
50         {}
51 };
52
53 class PeerNotFoundException : public BaseException
54 {
55 public:
56         PeerNotFoundException(const char *s):
57                 BaseException(s)
58         {}
59 };
60
61 class ConnectionException : public BaseException
62 {
63 public:
64         ConnectionException(const char *s):
65                 BaseException(s)
66         {}
67 };
68
69 class ConnectionBindFailed : public BaseException
70 {
71 public:
72         ConnectionBindFailed(const char *s):
73                 BaseException(s)
74         {}
75 };
76
77 class InvalidIncomingDataException : public BaseException
78 {
79 public:
80         InvalidIncomingDataException(const char *s):
81                 BaseException(s)
82         {}
83 };
84
85 class InvalidOutgoingDataException : public BaseException
86 {
87 public:
88         InvalidOutgoingDataException(const char *s):
89                 BaseException(s)
90         {}
91 };
92
93 class NoIncomingDataException : public BaseException
94 {
95 public:
96         NoIncomingDataException(const char *s):
97                 BaseException(s)
98         {}
99 };
100
101 class ProcessedSilentlyException : public BaseException
102 {
103 public:
104         ProcessedSilentlyException(const char *s):
105                 BaseException(s)
106         {}
107 };
108
109 class ProcessedQueued : public BaseException
110 {
111 public:
112         ProcessedQueued(const char *s):
113                 BaseException(s)
114         {}
115 };
116
117 class IncomingDataCorruption : public BaseException
118 {
119 public:
120         IncomingDataCorruption(const char *s):
121                 BaseException(s)
122         {}
123 };
124
125 typedef enum MTProtocols {
126         MTP_PRIMARY,
127         MTP_UDP,
128         MTP_MINETEST_RELIABLE_UDP
129 } MTProtocols;
130
131 #define SEQNUM_MAX 65535
132 inline bool seqnum_higher(u16 totest, u16 base)
133 {
134         if (totest > base)
135         {
136                 if ((totest - base) > (SEQNUM_MAX/2))
137                         return false;
138                 else
139                         return true;
140         }
141         else
142         {
143                 if ((base - totest) > (SEQNUM_MAX/2))
144                         return true;
145                 else
146                         return false;
147         }
148 }
149
150 inline bool seqnum_in_window(u16 seqnum, u16 next,u16 window_size)
151 {
152         u16 window_start = next;
153         u16 window_end   = ( next + window_size ) % (SEQNUM_MAX+1);
154
155         if (window_start < window_end)
156         {
157                 return ((seqnum >= window_start) && (seqnum < window_end));
158         }
159         else
160         {
161                 return ((seqnum < window_end) || (seqnum >= window_start));
162         }
163 }
164
165 struct BufferedPacket
166 {
167         BufferedPacket(u8 *a_data, u32 a_size):
168                 data(a_data, a_size), time(0.0), totaltime(0.0), absolute_send_time(-1),
169                 resend_count(0)
170         {}
171         BufferedPacket(u32 a_size):
172                 data(a_size), time(0.0), totaltime(0.0), absolute_send_time(-1),
173                 resend_count(0)
174         {}
175         Buffer<u8> data; // Data of the packet, including headers
176         float time; // Seconds from buffering the packet or re-sending
177         float totaltime; // Seconds from buffering the packet
178         u64 absolute_send_time;
179         Address address; // Sender or destination
180         unsigned int resend_count;
181 };
182
183 // This adds the base headers to the data and makes a packet out of it
184 BufferedPacket makePacket(Address &address, u8 *data, u32 datasize,
185                 u32 protocol_id, u16 sender_peer_id, u8 channel);
186 BufferedPacket makePacket(Address &address, SharedBuffer<u8> &data,
187                 u32 protocol_id, u16 sender_peer_id, u8 channel);
188
189 // Add the TYPE_ORIGINAL header to the data
190 SharedBuffer<u8> makeOriginalPacket(
191                 SharedBuffer<u8> data);
192
193 // Split data in chunks and add TYPE_SPLIT headers to them
194 std::list<SharedBuffer<u8> > makeSplitPacket(
195                 SharedBuffer<u8> data,
196                 u32 chunksize_max,
197                 u16 seqnum);
198
199 // Depending on size, make a TYPE_ORIGINAL or TYPE_SPLIT packet
200 // Increments split_seqnum if a split packet is made
201 std::list<SharedBuffer<u8> > makeAutoSplitPacket(
202                 SharedBuffer<u8> data,
203                 u32 chunksize_max,
204                 u16 &split_seqnum);
205
206 // Add the TYPE_RELIABLE header to the data
207 SharedBuffer<u8> makeReliablePacket(
208                 SharedBuffer<u8> data,
209                 u16 seqnum);
210
211 struct IncomingSplitPacket
212 {
213         IncomingSplitPacket()
214         {
215                 time = 0.0;
216                 reliable = false;
217         }
218         // Key is chunk number, value is data without headers
219         std::map<u16, SharedBuffer<u8> > chunks;
220         u32 chunk_count;
221         float time; // Seconds from adding
222         bool reliable; // If true, isn't deleted on timeout
223
224         bool allReceived()
225         {
226                 return (chunks.size() == chunk_count);
227         }
228 };
229
230 /*
231 === NOTES ===
232
233 A packet is sent through a channel to a peer with a basic header:
234 TODO: Should we have a receiver_peer_id also?
235         Header (7 bytes):
236         [0] u32 protocol_id
237         [4] u16 sender_peer_id
238         [6] u8 channel
239 sender_peer_id:
240         Unique to each peer.
241         value 0 (PEER_ID_INEXISTENT) is reserved for making new connections
242         value 1 (PEER_ID_SERVER) is reserved for server
243         these constants are defined in constants.h
244 channel:
245         The lower the number, the higher the priority is.
246         Only channels 0, 1 and 2 exist.
247 */
248 #define BASE_HEADER_SIZE 7
249 #define CHANNEL_COUNT 3
250 /*
251 Packet types:
252
253 CONTROL: This is a packet used by the protocol.
254 - When this is processed, nothing is handed to the user.
255         Header (2 byte):
256         [0] u8 type
257         [1] u8 controltype
258 controltype and data description:
259         CONTROLTYPE_ACK
260                 [2] u16 seqnum
261         CONTROLTYPE_SET_PEER_ID
262                 [2] u16 peer_id_new
263         CONTROLTYPE_PING
264         - There is no actual reply, but this can be sent in a reliable
265           packet to get a reply
266         CONTROLTYPE_DISCO
267 */
268 #define TYPE_CONTROL 0
269 #define CONTROLTYPE_ACK 0
270 #define CONTROLTYPE_SET_PEER_ID 1
271 #define CONTROLTYPE_PING 2
272 #define CONTROLTYPE_DISCO 3
273 #define CONTROLTYPE_ENABLE_BIG_SEND_WINDOW 4
274
275 /*
276 ORIGINAL: This is a plain packet with no control and no error
277 checking at all.
278 - When this is processed, it is directly handed to the user.
279         Header (1 byte):
280         [0] u8 type
281 */
282 #define TYPE_ORIGINAL 1
283 #define ORIGINAL_HEADER_SIZE 1
284 /*
285 SPLIT: These are sequences of packets forming one bigger piece of
286 data.
287 - When processed and all the packet_nums 0...packet_count-1 are
288   present (this should be buffered), the resulting data shall be
289   directly handed to the user.
290 - If the data fails to come up in a reasonable time, the buffer shall
291   be silently discarded.
292 - These can be sent as-is or atop of a RELIABLE packet stream.
293         Header (7 bytes):
294         [0] u8 type
295         [1] u16 seqnum
296         [3] u16 chunk_count
297         [5] u16 chunk_num
298 */
299 #define TYPE_SPLIT 2
300 /*
301 RELIABLE: Delivery of all RELIABLE packets shall be forced by ACKs,
302 and they shall be delivered in the same order as sent. This is done
303 with a buffer in the receiving and transmitting end.
304 - When this is processed, the contents of each packet is recursively
305   processed as packets.
306         Header (3 bytes):
307         [0] u8 type
308         [1] u16 seqnum
309
310 */
311 #define TYPE_RELIABLE 3
312 #define RELIABLE_HEADER_SIZE 3
313 #define SEQNUM_INITIAL 65500
314
315 /*
316         A buffer which stores reliable packets and sorts them internally
317         for fast access to the smallest one.
318 */
319
320 typedef std::list<BufferedPacket>::iterator RPBSearchResult;
321
322 class ReliablePacketBuffer
323 {
324 public:
325         ReliablePacketBuffer();
326
327         bool getFirstSeqnum(u16& result);
328
329         BufferedPacket popFirst();
330         BufferedPacket popSeqnum(u16 seqnum);
331         void insert(BufferedPacket &p,u16 next_expected);
332
333         void incrementTimeouts(float dtime);
334         std::list<BufferedPacket> getTimedOuts(float timeout,
335                         unsigned int max_packets);
336
337         void print();
338         bool empty();
339         bool containsPacket(u16 seqnum);
340         RPBSearchResult notFound();
341         u32 size();
342
343
344 private:
345         RPBSearchResult findPacket(u16 seqnum);
346
347         std::list<BufferedPacket> m_list;
348         u32 m_list_size;
349
350         u16 m_oldest_non_answered_ack;
351
352         Mutex m_list_mutex;
353 };
354
355 /*
356         A buffer for reconstructing split packets
357 */
358
359 class IncomingSplitBuffer
360 {
361 public:
362         ~IncomingSplitBuffer();
363         /*
364                 Returns a reference counted buffer of length != 0 when a full split
365                 packet is constructed. If not, returns one of length 0.
366         */
367         SharedBuffer<u8> insert(BufferedPacket &p, bool reliable);
368
369         void removeUnreliableTimedOuts(float dtime, float timeout);
370
371 private:
372         // Key is seqnum
373         std::map<u16, IncomingSplitPacket*> m_buf;
374
375         Mutex m_map_mutex;
376 };
377
378 struct OutgoingPacket
379 {
380         u16 peer_id;
381         u8 channelnum;
382         SharedBuffer<u8> data;
383         bool reliable;
384         bool ack;
385
386         OutgoingPacket(u16 peer_id_, u8 channelnum_, const SharedBuffer<u8> &data_,
387                         bool reliable_,bool ack_=false):
388                 peer_id(peer_id_),
389                 channelnum(channelnum_),
390                 data(data_),
391                 reliable(reliable_),
392                 ack(ack_)
393         {
394         }
395 };
396
397 enum ConnectionCommandType{
398         CONNCMD_NONE,
399         CONNCMD_SERVE,
400         CONNCMD_CONNECT,
401         CONNCMD_DISCONNECT,
402         CONNCMD_DISCONNECT_PEER,
403         CONNCMD_SEND,
404         CONNCMD_SEND_TO_ALL,
405         CONCMD_ACK,
406         CONCMD_CREATE_PEER,
407         CONCMD_DISABLE_LEGACY
408 };
409
410 struct ConnectionCommand
411 {
412         enum ConnectionCommandType type;
413         Address address;
414         u16 peer_id;
415         u8 channelnum;
416         Buffer<u8> data;
417         bool reliable;
418         bool raw;
419
420         ConnectionCommand(): type(CONNCMD_NONE), peer_id(PEER_ID_INEXISTENT), reliable(false), raw(false) {}
421
422         void serve(Address address_)
423         {
424                 type = CONNCMD_SERVE;
425                 address = address_;
426         }
427         void connect(Address address_)
428         {
429                 type = CONNCMD_CONNECT;
430                 address = address_;
431         }
432         void disconnect()
433         {
434                 type = CONNCMD_DISCONNECT;
435         }
436         void disconnect_peer(u16 peer_id_)
437         {
438                 type = CONNCMD_DISCONNECT_PEER;
439                 peer_id = peer_id_;
440         }
441         void send(u16 peer_id_, u8 channelnum_,
442                         NetworkPacket* pkt, bool reliable_)
443         {
444                 type = CONNCMD_SEND;
445                 peer_id = peer_id_;
446                 channelnum = channelnum_;
447                 data = pkt->oldForgePacket();
448                 reliable = reliable_;
449         }
450
451         void ack(u16 peer_id_, u8 channelnum_, const SharedBuffer<u8> &data_)
452         {
453                 type = CONCMD_ACK;
454                 peer_id = peer_id_;
455                 channelnum = channelnum_;
456                 data = data_;
457                 reliable = false;
458         }
459
460         void createPeer(u16 peer_id_, const SharedBuffer<u8> &data_)
461         {
462                 type = CONCMD_CREATE_PEER;
463                 peer_id = peer_id_;
464                 data = data_;
465                 channelnum = 0;
466                 reliable = true;
467                 raw = true;
468         }
469
470         void disableLegacy(u16 peer_id_, const SharedBuffer<u8> &data_)
471         {
472                 type = CONCMD_DISABLE_LEGACY;
473                 peer_id = peer_id_;
474                 data = data_;
475                 channelnum = 0;
476                 reliable = true;
477                 raw = true;
478         }
479 };
480
481 class Channel
482 {
483
484 public:
485         u16 readNextIncomingSeqNum();
486         u16 incNextIncomingSeqNum();
487
488         u16 getOutgoingSequenceNumber(bool& successfull);
489         u16 readOutgoingSequenceNumber();
490         bool putBackSequenceNumber(u16);
491
492         u16 readNextSplitSeqNum();
493         void setNextSplitSeqNum(u16 seqnum);
494
495         // This is for buffering the incoming packets that are coming in
496         // the wrong order
497         ReliablePacketBuffer incoming_reliables;
498         // This is for buffering the sent packets so that the sender can
499         // re-send them if no ACK is received
500         ReliablePacketBuffer outgoing_reliables_sent;
501
502         //queued reliable packets
503         std::queue<BufferedPacket> queued_reliables;
504
505         //queue commands prior splitting to packets
506         std::deque<ConnectionCommand> queued_commands;
507
508         IncomingSplitBuffer incoming_splits;
509
510         Channel();
511         ~Channel();
512
513         void UpdatePacketLossCounter(unsigned int count);
514         void UpdatePacketTooLateCounter();
515         void UpdateBytesSent(unsigned int bytes,unsigned int packages=1);
516         void UpdateBytesLost(unsigned int bytes);
517         void UpdateBytesReceived(unsigned int bytes);
518
519         void UpdateTimers(float dtime, bool legacy_peer);
520
521         const float getCurrentDownloadRateKB()
522                 { MutexAutoLock lock(m_internal_mutex); return cur_kbps; };
523         const float getMaxDownloadRateKB()
524                 { MutexAutoLock lock(m_internal_mutex); return max_kbps; };
525
526         const float getCurrentLossRateKB()
527                 { MutexAutoLock lock(m_internal_mutex); return cur_kbps_lost; };
528         const float getMaxLossRateKB()
529                 { MutexAutoLock lock(m_internal_mutex); return max_kbps_lost; };
530
531         const float getCurrentIncomingRateKB()
532                 { MutexAutoLock lock(m_internal_mutex); return cur_incoming_kbps; };
533         const float getMaxIncomingRateKB()
534                 { MutexAutoLock lock(m_internal_mutex); return max_incoming_kbps; };
535
536         const float getAvgDownloadRateKB()
537                 { MutexAutoLock lock(m_internal_mutex); return avg_kbps; };
538         const float getAvgLossRateKB()
539                 { MutexAutoLock lock(m_internal_mutex); return avg_kbps_lost; };
540         const float getAvgIncomingRateKB()
541                 { MutexAutoLock lock(m_internal_mutex); return avg_incoming_kbps; };
542
543         const unsigned int getWindowSize() const { return window_size; };
544
545         void setWindowSize(unsigned int size) { window_size = size; };
546 private:
547         Mutex m_internal_mutex;
548         int window_size;
549
550         u16 next_incoming_seqnum;
551
552         u16 next_outgoing_seqnum;
553         u16 next_outgoing_split_seqnum;
554
555         unsigned int current_packet_loss;
556         unsigned int current_packet_too_late;
557         unsigned int current_packet_successfull;
558         float packet_loss_counter;
559
560         unsigned int current_bytes_transfered;
561         unsigned int current_bytes_received;
562         unsigned int current_bytes_lost;
563         float max_kbps;
564         float cur_kbps;
565         float avg_kbps;
566         float max_incoming_kbps;
567         float cur_incoming_kbps;
568         float avg_incoming_kbps;
569         float max_kbps_lost;
570         float cur_kbps_lost;
571         float avg_kbps_lost;
572         float bpm_counter;
573
574         unsigned int rate_samples;
575 };
576
577 class Peer;
578
579 enum PeerChangeType
580 {
581         PEER_ADDED,
582         PEER_REMOVED
583 };
584 struct PeerChange
585 {
586         PeerChangeType type;
587         u16 peer_id;
588         bool timeout;
589 };
590
591 class PeerHandler
592 {
593 public:
594
595         PeerHandler()
596         {
597         }
598         virtual ~PeerHandler()
599         {
600         }
601
602         /*
603                 This is called after the Peer has been inserted into the
604                 Connection's peer container.
605         */
606         virtual void peerAdded(Peer *peer) = 0;
607         /*
608                 This is called before the Peer has been removed from the
609                 Connection's peer container.
610         */
611         virtual void deletingPeer(Peer *peer, bool timeout) = 0;
612 };
613
614 class PeerHelper
615 {
616 public:
617         PeerHelper();
618         PeerHelper(Peer* peer);
619         ~PeerHelper();
620
621         PeerHelper&   operator=(Peer* peer);
622         Peer*         operator->() const;
623         bool          operator!();
624         Peer*         operator&() const;
625         bool          operator!=(void* ptr);
626
627 private:
628         Peer* m_peer;
629 };
630
631 class Connection;
632
633 typedef enum {
634         MIN_RTT,
635         MAX_RTT,
636         AVG_RTT,
637         MIN_JITTER,
638         MAX_JITTER,
639         AVG_JITTER
640 } rtt_stat_type;
641
642 typedef enum {
643         CUR_DL_RATE,
644         AVG_DL_RATE,
645         CUR_INC_RATE,
646         AVG_INC_RATE,
647         CUR_LOSS_RATE,
648         AVG_LOSS_RATE,
649 } rate_stat_type;
650
651 class Peer {
652         public:
653                 friend class PeerHelper;
654
655                 Peer(Address address_,u16 id_,Connection* connection) :
656                         id(id_),
657                         m_increment_packets_remaining(9),
658                         m_increment_bytes_remaining(0),
659                         m_pending_deletion(false),
660                         m_connection(connection),
661                         address(address_),
662                         m_ping_timer(0.0),
663                         m_last_rtt(-1.0),
664                         m_usage(0),
665                         m_timeout_counter(0.0),
666                         m_last_timeout_check(porting::getTimeMs())
667                 {
668                         m_rtt.avg_rtt = -1.0;
669                         m_rtt.jitter_avg = -1.0;
670                         m_rtt.jitter_max = 0.0;
671                         m_rtt.max_rtt = 0.0;
672                         m_rtt.jitter_min = FLT_MAX;
673                         m_rtt.min_rtt = FLT_MAX;
674                 };
675
676                 virtual ~Peer() {
677                         MutexAutoLock usage_lock(m_exclusive_access_mutex);
678                         FATAL_ERROR_IF(m_usage != 0, "Reference counting failure");
679                 };
680
681                 // Unique id of the peer
682                 u16 id;
683
684                 void Drop();
685
686                 virtual void PutReliableSendCommand(ConnectionCommand &c,
687                                                 unsigned int max_packet_size) {};
688
689                 virtual bool getAddress(MTProtocols type, Address& toset) = 0;
690
691                 bool isPendingDeletion()
692                 { MutexAutoLock lock(m_exclusive_access_mutex); return m_pending_deletion; };
693
694                 void ResetTimeout()
695                         {MutexAutoLock lock(m_exclusive_access_mutex); m_timeout_counter=0.0; };
696
697                 bool isTimedOut(float timeout);
698
699                 unsigned int m_increment_packets_remaining;
700                 unsigned int m_increment_bytes_remaining;
701
702                 virtual u16 getNextSplitSequenceNumber(u8 channel) { return 0; };
703                 virtual void setNextSplitSequenceNumber(u8 channel, u16 seqnum) {};
704                 virtual SharedBuffer<u8> addSpiltPacket(u8 channel,
705                                                                                                 BufferedPacket toadd,
706                                                                                                 bool reliable)
707                                 {
708                                         fprintf(stderr,"Peer: addSplitPacket called, this is supposed to be never called!\n");
709                                         return SharedBuffer<u8>(0);
710                                 };
711
712                 virtual bool Ping(float dtime, SharedBuffer<u8>& data) { return false; };
713
714                 virtual float getStat(rtt_stat_type type) const {
715                         switch (type) {
716                                 case MIN_RTT:
717                                         return m_rtt.min_rtt;
718                                 case MAX_RTT:
719                                         return m_rtt.max_rtt;
720                                 case AVG_RTT:
721                                         return m_rtt.avg_rtt;
722                                 case MIN_JITTER:
723                                         return m_rtt.jitter_min;
724                                 case MAX_JITTER:
725                                         return m_rtt.jitter_max;
726                                 case AVG_JITTER:
727                                         return m_rtt.jitter_avg;
728                         }
729                         return -1;
730                 }
731         protected:
732                 virtual void reportRTT(float rtt) {};
733
734                 void RTTStatistics(float rtt,
735                                                         const std::string &profiler_id = "",
736                                                         unsigned int num_samples = 1000);
737
738                 bool IncUseCount();
739                 void DecUseCount();
740
741                 Mutex m_exclusive_access_mutex;
742
743                 bool m_pending_deletion;
744
745                 Connection* m_connection;
746
747                 // Address of the peer
748                 Address address;
749
750                 // Ping timer
751                 float m_ping_timer;
752         private:
753
754                 struct rttstats {
755                         float jitter_min;
756                         float jitter_max;
757                         float jitter_avg;
758                         float min_rtt;
759                         float max_rtt;
760                         float avg_rtt;
761                 };
762
763                 rttstats m_rtt;
764                 float    m_last_rtt;
765
766                 // current usage count
767                 unsigned int m_usage;
768
769                 // Seconds from last receive
770                 float m_timeout_counter;
771
772                 u32 m_last_timeout_check;
773 };
774
775 class UDPPeer : public Peer
776 {
777 public:
778
779         friend class PeerHelper;
780         friend class ConnectionReceiveThread;
781         friend class ConnectionSendThread;
782         friend class Connection;
783
784         UDPPeer(u16 a_id, Address a_address, Connection* connection);
785         virtual ~UDPPeer() {};
786
787         void PutReliableSendCommand(ConnectionCommand &c,
788                                                         unsigned int max_packet_size);
789
790         bool getAddress(MTProtocols type, Address& toset);
791
792         void setNonLegacyPeer();
793
794         bool getLegacyPeer()
795         { return m_legacy_peer; }
796
797         u16 getNextSplitSequenceNumber(u8 channel);
798         void setNextSplitSequenceNumber(u8 channel, u16 seqnum);
799
800         SharedBuffer<u8> addSpiltPacket(u8 channel,
801                                                                         BufferedPacket toadd,
802                                                                         bool reliable);
803
804
805 protected:
806         /*
807                 Calculates avg_rtt and resend_timeout.
808                 rtt=-1 only recalculates resend_timeout
809         */
810         void reportRTT(float rtt);
811
812         void RunCommandQueues(
813                                         unsigned int max_packet_size,
814                                         unsigned int maxcommands,
815                                         unsigned int maxtransfer);
816
817         float getResendTimeout()
818                 { MutexAutoLock lock(m_exclusive_access_mutex); return resend_timeout; }
819
820         void setResendTimeout(float timeout)
821                 { MutexAutoLock lock(m_exclusive_access_mutex); resend_timeout = timeout; }
822         bool Ping(float dtime,SharedBuffer<u8>& data);
823
824         Channel channels[CHANNEL_COUNT];
825         bool m_pending_disconnect;
826 private:
827         // This is changed dynamically
828         float resend_timeout;
829
830         bool processReliableSendCommand(
831                                         ConnectionCommand &c,
832                                         unsigned int max_packet_size);
833
834         bool m_legacy_peer;
835 };
836
837 /*
838         Connection
839 */
840
841 enum ConnectionEventType{
842         CONNEVENT_NONE,
843         CONNEVENT_DATA_RECEIVED,
844         CONNEVENT_PEER_ADDED,
845         CONNEVENT_PEER_REMOVED,
846         CONNEVENT_BIND_FAILED,
847 };
848
849 struct ConnectionEvent
850 {
851         enum ConnectionEventType type;
852         u16 peer_id;
853         Buffer<u8> data;
854         bool timeout;
855         Address address;
856
857         ConnectionEvent(): type(CONNEVENT_NONE), peer_id(0),
858                         timeout(false) {}
859
860         std::string describe()
861         {
862                 switch(type) {
863                 case CONNEVENT_NONE:
864                         return "CONNEVENT_NONE";
865                 case CONNEVENT_DATA_RECEIVED:
866                         return "CONNEVENT_DATA_RECEIVED";
867                 case CONNEVENT_PEER_ADDED:
868                         return "CONNEVENT_PEER_ADDED";
869                 case CONNEVENT_PEER_REMOVED:
870                         return "CONNEVENT_PEER_REMOVED";
871                 case CONNEVENT_BIND_FAILED:
872                         return "CONNEVENT_BIND_FAILED";
873                 }
874                 return "Invalid ConnectionEvent";
875         }
876
877         void dataReceived(u16 peer_id_, const SharedBuffer<u8> &data_)
878         {
879                 type = CONNEVENT_DATA_RECEIVED;
880                 peer_id = peer_id_;
881                 data = data_;
882         }
883         void peerAdded(u16 peer_id_, Address address_)
884         {
885                 type = CONNEVENT_PEER_ADDED;
886                 peer_id = peer_id_;
887                 address = address_;
888         }
889         void peerRemoved(u16 peer_id_, bool timeout_, Address address_)
890         {
891                 type = CONNEVENT_PEER_REMOVED;
892                 peer_id = peer_id_;
893                 timeout = timeout_;
894                 address = address_;
895         }
896         void bindFailed()
897         {
898                 type = CONNEVENT_BIND_FAILED;
899         }
900 };
901
902 class ConnectionSendThread : public Thread {
903
904 public:
905         friend class UDPPeer;
906
907         ConnectionSendThread(unsigned int max_packet_size, float timeout);
908
909         void *run();
910
911         void Trigger();
912
913         void setParent(Connection* parent) {
914                 assert(parent != NULL); // Pre-condition
915                 m_connection = parent;
916         }
917
918         void setPeerTimeout(float peer_timeout)
919                 { m_timeout = peer_timeout; }
920
921 private:
922         void runTimeouts    (float dtime);
923         void rawSend        (const BufferedPacket &packet);
924         bool rawSendAsPacket(u16 peer_id, u8 channelnum,
925                                                         SharedBuffer<u8> data, bool reliable);
926
927         void processReliableCommand (ConnectionCommand &c);
928         void processNonReliableCommand (ConnectionCommand &c);
929         void serve          (Address bind_address);
930         void connect        (Address address);
931         void disconnect     ();
932         void disconnect_peer(u16 peer_id);
933         void send           (u16 peer_id, u8 channelnum,
934                                                         SharedBuffer<u8> data);
935         void sendReliable   (ConnectionCommand &c);
936         void sendToAll      (u8 channelnum,
937                                                         SharedBuffer<u8> data);
938         void sendToAllReliable(ConnectionCommand &c);
939
940         void sendPackets    (float dtime);
941
942         void sendAsPacket   (u16 peer_id, u8 channelnum,
943                                                         SharedBuffer<u8> data,bool ack=false);
944
945         void sendAsPacketReliable(BufferedPacket& p, Channel* channel);
946
947         bool packetsQueued();
948
949         Connection*           m_connection;
950         unsigned int          m_max_packet_size;
951         float                 m_timeout;
952         std::queue<OutgoingPacket> m_outgoing_queue;
953         Semaphore             m_send_sleep_semaphore;
954
955         unsigned int          m_iteration_packets_avaialble;
956         unsigned int          m_max_commands_per_iteration;
957         unsigned int          m_max_data_packets_per_iteration;
958         unsigned int          m_max_packets_requeued;
959 };
960
961 class ConnectionReceiveThread : public Thread {
962 public:
963         ConnectionReceiveThread(unsigned int max_packet_size);
964
965         void *run();
966
967         void setParent(Connection *parent) {
968                 assert(parent); // Pre-condition
969                 m_connection = parent;
970         }
971
972 private:
973         void receive();
974
975         // Returns next data from a buffer if possible
976         // If found, returns true; if not, false.
977         // If found, sets peer_id and dst
978         bool getFromBuffers(u16 &peer_id, SharedBuffer<u8> &dst);
979
980         bool checkIncomingBuffers(Channel *channel, u16 &peer_id,
981                                                         SharedBuffer<u8> &dst);
982
983         /*
984                 Processes a packet with the basic header stripped out.
985                 Parameters:
986                         packetdata: Data in packet (with no base headers)
987                         peer_id: peer id of the sender of the packet in question
988                         channelnum: channel on which the packet was sent
989                         reliable: true if recursing into a reliable packet
990         */
991         SharedBuffer<u8> processPacket(Channel *channel,
992                                                         SharedBuffer<u8> packetdata, u16 peer_id,
993                                                         u8 channelnum, bool reliable);
994
995
996         Connection*           m_connection;
997 };
998
999 class Connection
1000 {
1001 public:
1002         friend class ConnectionSendThread;
1003         friend class ConnectionReceiveThread;
1004
1005         Connection(u32 protocol_id, u32 max_packet_size, float timeout, bool ipv6,
1006                         PeerHandler *peerhandler);
1007         ~Connection();
1008
1009         /* Interface */
1010         ConnectionEvent waitEvent(u32 timeout_ms);
1011         void putCommand(ConnectionCommand &c);
1012
1013         void SetTimeoutMs(int timeout) { m_bc_receive_timeout = timeout; }
1014         void Serve(Address bind_addr);
1015         void Connect(Address address);
1016         bool Connected();
1017         void Disconnect();
1018         void Receive(NetworkPacket* pkt);
1019         void Send(u16 peer_id, u8 channelnum, NetworkPacket* pkt, bool reliable);
1020         u16 GetPeerID() { return m_peer_id; }
1021         Address GetPeerAddress(u16 peer_id);
1022         float getPeerStat(u16 peer_id, rtt_stat_type type);
1023         float getLocalStat(rate_stat_type type);
1024         const u32 GetProtocolID() const { return m_protocol_id; };
1025         const std::string getDesc();
1026         void DisconnectPeer(u16 peer_id);
1027
1028 protected:
1029         PeerHelper getPeer(u16 peer_id);
1030         PeerHelper getPeerNoEx(u16 peer_id);
1031         u16   lookupPeer(Address& sender);
1032
1033         u16 createPeer(Address& sender, MTProtocols protocol, int fd);
1034         UDPPeer*  createServerPeer(Address& sender);
1035         bool deletePeer(u16 peer_id, bool timeout);
1036
1037         void SetPeerID(u16 id) { m_peer_id = id; }
1038
1039         void sendAck(u16 peer_id, u8 channelnum, u16 seqnum);
1040
1041         void PrintInfo(std::ostream &out);
1042         void PrintInfo();
1043
1044         std::list<u16> getPeerIDs()
1045         {
1046                 MutexAutoLock peerlock(m_peers_mutex);
1047                 return m_peer_ids;
1048         }
1049
1050         UDPSocket m_udpSocket;
1051         MutexedQueue<ConnectionCommand> m_command_queue;
1052
1053         void putEvent(ConnectionEvent &e);
1054
1055         void TriggerSend()
1056                 { m_sendThread.Trigger(); }
1057 private:
1058         std::list<Peer*> getPeers();
1059
1060         MutexedQueue<ConnectionEvent> m_event_queue;
1061
1062         u16 m_peer_id;
1063         u32 m_protocol_id;
1064
1065         std::map<u16, Peer*> m_peers;
1066         std::list<u16> m_peer_ids;
1067         Mutex m_peers_mutex;
1068
1069         ConnectionSendThread m_sendThread;
1070         ConnectionReceiveThread m_receiveThread;
1071
1072         Mutex m_info_mutex;
1073
1074         // Backwards compatibility
1075         PeerHandler *m_bc_peerhandler;
1076         int m_bc_receive_timeout;
1077
1078         bool m_shutting_down;
1079
1080         u16 m_next_remote_peer_id;
1081 };
1082
1083 } // namespace
1084
1085 #endif