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