c67aa5feb6f1f8b1e095966c1f7e5d5c8592d8c1
[oweals/minetest.git] / src / connection.h
1 #ifndef CONNECTION_HEADER
2 #define CONNECTION_HEADER
3
4 #include <iostream>
5 #include <fstream>
6 #include "debug.h"
7 #include "common_irrlicht.h"
8 #include "socket.h"
9 #include "utility.h"
10 #include "exceptions.h"
11 #include "constants.h"
12
13 namespace con
14 {
15
16 /*
17         Exceptions
18 */
19 class NotFoundException : public BaseException
20 {
21 public:
22         NotFoundException(const char *s):
23                 BaseException(s)
24         {}
25 };
26
27 class PeerNotFoundException : public BaseException
28 {
29 public:
30         PeerNotFoundException(const char *s):
31                 BaseException(s)
32         {}
33 };
34
35 class ConnectionException : public BaseException
36 {
37 public:
38         ConnectionException(const char *s):
39                 BaseException(s)
40         {}
41 };
42
43 /*class ThrottlingException : public BaseException
44 {
45 public:
46         ThrottlingException(const char *s):
47                 BaseException(s)
48         {}
49 };*/
50
51 class InvalidIncomingDataException : public BaseException
52 {
53 public:
54         InvalidIncomingDataException(const char *s):
55                 BaseException(s)
56         {}
57 };
58
59 class InvalidOutgoingDataException : public BaseException
60 {
61 public:
62         InvalidOutgoingDataException(const char *s):
63                 BaseException(s)
64         {}
65 };
66
67 class NoIncomingDataException : public BaseException
68 {
69 public:
70         NoIncomingDataException(const char *s):
71                 BaseException(s)
72         {}
73 };
74
75 class ProcessedSilentlyException : public BaseException
76 {
77 public:
78         ProcessedSilentlyException(const char *s):
79                 BaseException(s)
80         {}
81 };
82
83 class GotSplitPacketException
84 {
85         SharedBuffer<u8> m_data;
86 public:
87         GotSplitPacketException(SharedBuffer<u8> data):
88                 m_data(data)
89         {}
90         SharedBuffer<u8> getData()
91         {
92                 return m_data;
93         }
94 };
95
96 inline u16 readPeerId(u8 *packetdata)
97 {
98         return readU16(&packetdata[4]);
99 }
100 inline u8 readChannel(u8 *packetdata)
101 {
102         return readU8(&packetdata[6]);
103 }
104
105 #define SEQNUM_MAX 65535
106 inline bool seqnum_higher(u16 higher, u16 lower)
107 {
108         if(lower > higher && lower - higher > SEQNUM_MAX/2){
109                 return true;
110         }
111         return (higher > lower);
112 }
113
114 struct BufferedPacket
115 {
116         BufferedPacket(u8 *a_data, u32 a_size):
117                 data(a_data, a_size), time(0.0), totaltime(0.0)
118         {}
119         BufferedPacket(u32 a_size):
120                 data(a_size), time(0.0), totaltime(0.0)
121         {}
122         SharedBuffer<u8> data; // Data of the packet, including headers
123         float time; // Seconds from buffering the packet or re-sending
124         float totaltime; // Seconds from buffering the packet
125         Address address; // Sender or destination
126 };
127
128 // This adds the base headers to the data and makes a packet out of it
129 BufferedPacket makePacket(Address &address, u8 *data, u32 datasize,
130                 u32 protocol_id, u16 sender_peer_id, u8 channel);
131 BufferedPacket makePacket(Address &address, SharedBuffer<u8> &data,
132                 u32 protocol_id, u16 sender_peer_id, u8 channel);
133
134 // Add the TYPE_ORIGINAL header to the data
135 SharedBuffer<u8> makeOriginalPacket(
136                 SharedBuffer<u8> data);
137
138 // Split data in chunks and add TYPE_SPLIT headers to them
139 core::list<SharedBuffer<u8> > makeSplitPacket(
140                 SharedBuffer<u8> data,
141                 u32 chunksize_max,
142                 u16 seqnum);
143
144 // Depending on size, make a TYPE_ORIGINAL or TYPE_SPLIT packet
145 // Increments split_seqnum if a split packet is made
146 core::list<SharedBuffer<u8> > makeAutoSplitPacket(
147                 SharedBuffer<u8> data,
148                 u32 chunksize_max,
149                 u16 &split_seqnum);
150
151 // Add the TYPE_RELIABLE header to the data
152 SharedBuffer<u8> makeReliablePacket(
153                 SharedBuffer<u8> data,
154                 u16 seqnum);
155
156 struct IncomingSplitPacket
157 {
158         IncomingSplitPacket()
159         {
160                 time = 0.0;
161                 reliable = false;
162         }
163         // Key is chunk number, value is data without headers
164         core::map<u16, SharedBuffer<u8> > chunks;
165         u32 chunk_count;
166         float time; // Seconds from adding
167         bool reliable; // If true, isn't deleted on timeout
168
169         bool allReceived()
170         {
171                 return (chunks.size() == chunk_count);
172         }
173 };
174
175 /*
176 === NOTES ===
177
178 A packet is sent through a channel to a peer with a basic header:
179 TODO: Should we have a receiver_peer_id also?
180         Header (7 bytes):
181         [0] u32 protocol_id
182         [4] u16 sender_peer_id
183         [6] u8 channel
184 sender_peer_id:
185         Unique to each peer.
186         value 0 is reserved for making new connections
187         value 1 is reserved for server
188 channel:
189         The lower the number, the higher the priority is.
190         Only channels 0, 1 and 2 exist.
191 */
192 #define BASE_HEADER_SIZE 7
193 #define PEER_ID_NEW 0
194 #define PEER_ID_SERVER 1
195 #define CHANNEL_COUNT 3
196 /*
197 Packet types:
198
199 CONTROL: This is a packet used by the protocol.
200 - When this is processed, nothing is handed to the user.
201         Header (2 byte):
202         [0] u8 type
203         [1] u8 controltype
204 controltype and data description:
205         CONTROLTYPE_ACK
206                 [2] u16 seqnum
207         CONTROLTYPE_SET_PEER_ID
208                 [2] u16 peer_id_new
209         CONTROLTYPE_PING
210         - This can be sent in a reliable packet to get a reply
211 */
212 #define TYPE_CONTROL 0
213 #define CONTROLTYPE_ACK 0
214 #define CONTROLTYPE_SET_PEER_ID 1
215 #define CONTROLTYPE_PING 2
216 /*
217 ORIGINAL: This is a plain packet with no control and no error
218 checking at all.
219 - When this is processed, it is directly handed to the user.
220         Header (1 byte):
221         [0] u8 type
222 */
223 #define TYPE_ORIGINAL 1
224 #define ORIGINAL_HEADER_SIZE 1
225 /*
226 SPLIT: These are sequences of packets forming one bigger piece of
227 data.
228 - When processed and all the packet_nums 0...packet_count-1 are
229   present (this should be buffered), the resulting data shall be
230   directly handed to the user.
231 - If the data fails to come up in a reasonable time, the buffer shall
232   be silently discarded.
233 - These can be sent as-is or atop of a RELIABLE packet stream.
234         Header (7 bytes):
235         [0] u8 type
236         [1] u16 seqnum
237         [3] u16 chunk_count
238         [5] u16 chunk_num
239 */
240 #define TYPE_SPLIT 2
241 /*
242 RELIABLE: Delivery of all RELIABLE packets shall be forced by ACKs,
243 and they shall be delivered in the same order as sent. This is done
244 with a buffer in the receiving and transmitting end.
245 - When this is processed, the contents of each packet is recursively
246   processed as packets.
247         Header (3 bytes):
248         [0] u8 type
249         [1] u16 seqnum
250
251 */
252 #define TYPE_RELIABLE 3
253 #define RELIABLE_HEADER_SIZE 3
254 //#define SEQNUM_INITIAL 0x10
255 #define SEQNUM_INITIAL 65500
256
257 /*
258         A buffer which stores reliable packets and sorts them internally
259         for fast access to the smallest one.
260 */
261
262 typedef core::list<BufferedPacket>::Iterator RPBSearchResult;
263
264 class ReliablePacketBuffer
265 {
266 public:
267         
268         void print();
269         bool empty();
270         u32 size();
271         RPBSearchResult findPacket(u16 seqnum);
272         RPBSearchResult notFound();
273         u16 getFirstSeqnum();
274         BufferedPacket popFirst();
275         BufferedPacket popSeqnum(u16 seqnum);
276         void insert(BufferedPacket &p);
277         void incrementTimeouts(float dtime);
278         void resetTimedOuts(float timeout);
279         bool anyTotaltimeReached(float timeout);
280         core::list<BufferedPacket> getTimedOuts(float timeout);
281
282 private:
283         core::list<BufferedPacket> m_list;
284 };
285
286 /*
287         A buffer for reconstructing split packets
288 */
289
290 class IncomingSplitBuffer
291 {
292 public:
293         ~IncomingSplitBuffer();
294         /*
295                 This will throw a GotSplitPacketException when a full
296                 split packet is constructed.
297         */
298         void insert(BufferedPacket &p, bool reliable);
299         
300         void removeUnreliableTimedOuts(float dtime, float timeout);
301         
302 private:
303         // Key is seqnum
304         core::map<u16, IncomingSplitPacket*> m_buf;
305 };
306
307 class Connection;
308
309 struct Channel
310 {
311         Channel();
312         ~Channel();
313         /*
314                 Processes a packet with the basic header stripped out.
315                 Parameters:
316                         packetdata: Data in packet (with no base headers)
317                         con: The connection to which the channel is associated
318                              (used for sending back stuff (ACKs))
319                         peer_id: peer id of the sender of the packet in question
320                         channelnum: channel on which the packet was sent
321                         reliable: true if recursing into a reliable packet
322         */
323         SharedBuffer<u8> ProcessPacket(
324                         SharedBuffer<u8> packetdata,
325                         Connection *con,
326                         u16 peer_id,
327                         u8 channelnum,
328                         bool reliable=false);
329         
330         // Returns next data from a buffer if possible
331         // throws a NoIncomingDataException if no data is available
332         // If found, sets peer_id
333         SharedBuffer<u8> CheckIncomingBuffers(Connection *con,
334                         u16 &peer_id);
335
336         u16 next_outgoing_seqnum;
337         u16 next_incoming_seqnum;
338         u16 next_outgoing_split_seqnum;
339         
340         // This is for buffering the incoming packets that are coming in
341         // the wrong order
342         ReliablePacketBuffer incoming_reliables;
343         // This is for buffering the sent packets so that the sender can
344         // re-send them if no ACK is received
345         ReliablePacketBuffer outgoing_reliables;
346
347         IncomingSplitBuffer incoming_splits;
348 };
349
350 class Peer;
351
352 class PeerHandler
353 {
354 public:
355         PeerHandler()
356         {
357         }
358         virtual ~PeerHandler()
359         {
360         }
361         
362         /*
363                 This is called after the Peer has been inserted into the
364                 Connection's peer container.
365         */
366         virtual void peerAdded(Peer *peer) = 0;
367         /*
368                 This is called before the Peer has been removed from the
369                 Connection's peer container.
370         */
371         virtual void deletingPeer(Peer *peer, bool timeout) = 0;
372 };
373
374 class Peer
375 {
376 public:
377
378         Peer(u16 a_id, Address a_address);
379         virtual ~Peer();
380         
381         /*
382                 Calculates avg_rtt and resend_timeout.
383
384                 rtt=-1 only recalculates resend_timeout
385         */
386         void reportRTT(float rtt);
387
388         Channel channels[CHANNEL_COUNT];
389
390         // Address of the peer
391         Address address;
392         // Unique id of the peer
393         u16 id;
394         // Seconds from last receive
395         float timeout_counter;
396         // Ping timer
397         float ping_timer;
398         // This is changed dynamically
399         float resend_timeout;
400         // Updated when an ACK is received
401         float avg_rtt;
402         // This is set to true when the peer has actually sent something
403         // with the id we have given to it
404         bool has_sent_with_id;
405         
406 private:
407 };
408
409 class Connection
410 {
411 public:
412         Connection(
413                 u32 protocol_id,
414                 u32 max_packet_size,
415                 float timeout,
416                 PeerHandler *peerhandler
417         );
418         ~Connection();
419         void setTimeoutMs(int timeout){ m_socket.setTimeoutMs(timeout); }
420         // Start being a server
421         void Serve(unsigned short port);
422         // Connect to a server
423         void Connect(Address address);
424         bool Connected();
425
426         // Sets peer_id
427         SharedBuffer<u8> GetFromBuffers(u16 &peer_id);
428
429         // The peer_id of sender is stored in peer_id
430         // Return value: I guess this always throws an exception or
431         //               actually gets data
432         u32 Receive(u16 &peer_id, u8 *data, u32 datasize);
433         
434         // These will automatically package the data as an original or split
435         void SendToAll(u8 channelnum, SharedBuffer<u8> data, bool reliable);
436         void Send(u16 peer_id, u8 channelnum, SharedBuffer<u8> data, bool reliable);
437         // Send data as a packet; it will be wrapped in base header and
438         // optionally to a reliable packet.
439         void SendAsPacket(u16 peer_id, u8 channelnum,
440                         SharedBuffer<u8> data, bool reliable);
441         // Sends a raw packet
442         void RawSend(const BufferedPacket &packet);
443         
444         void RunTimeouts(float dtime);
445         // Can throw a PeerNotFoundException
446         Peer* GetPeer(u16 peer_id);
447         // returns NULL if failed
448         Peer* GetPeerNoEx(u16 peer_id);
449         core::list<Peer*> GetPeers();
450
451         void SetPeerID(u16 id){ m_peer_id = id; }
452         u16 GetPeerID(){ return m_peer_id; }
453         u32 GetProtocolID(){ return m_protocol_id; }
454
455         // For debug printing
456         void PrintInfo(std::ostream &out);
457         void PrintInfo();
458         u16 m_indentation;
459
460 private:
461         u32 m_protocol_id;
462         float m_timeout;
463         PeerHandler *m_peerhandler;
464         core::map<u16, Peer*> m_peers;
465         u16 m_peer_id;
466         //bool m_waiting_new_peer_id;
467         u32 m_max_packet_size;
468         UDPSocket m_socket;
469 };
470
471 } // namespace
472
473 #endif
474