3 Copyright (C) 2010 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 General Public License as published by
7 the Free Software Foundation; either version 2 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 General Public License for more details.
15 You should have received a copy of the GNU 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
26 #include "common_irrlicht.h"
29 #include "exceptions.h"
30 #include "constants.h"
38 class NotFoundException : public BaseException
41 NotFoundException(const char *s):
46 class PeerNotFoundException : public BaseException
49 PeerNotFoundException(const char *s):
54 class ConnectionException : public BaseException
57 ConnectionException(const char *s):
62 /*class ThrottlingException : public BaseException
65 ThrottlingException(const char *s):
70 class InvalidIncomingDataException : public BaseException
73 InvalidIncomingDataException(const char *s):
78 class InvalidOutgoingDataException : public BaseException
81 InvalidOutgoingDataException(const char *s):
86 class NoIncomingDataException : public BaseException
89 NoIncomingDataException(const char *s):
94 class ProcessedSilentlyException : public BaseException
97 ProcessedSilentlyException(const char *s):
102 class GotSplitPacketException
104 SharedBuffer<u8> m_data;
106 GotSplitPacketException(SharedBuffer<u8> data):
109 SharedBuffer<u8> getData()
115 inline u16 readPeerId(u8 *packetdata)
117 return readU16(&packetdata[4]);
119 inline u8 readChannel(u8 *packetdata)
121 return readU8(&packetdata[6]);
124 #define SEQNUM_MAX 65535
125 inline bool seqnum_higher(u16 higher, u16 lower)
127 if(lower > higher && lower - higher > SEQNUM_MAX/2){
130 return (higher > lower);
133 struct BufferedPacket
135 BufferedPacket(u8 *a_data, u32 a_size):
136 data(a_data, a_size), time(0.0), totaltime(0.0)
138 BufferedPacket(u32 a_size):
139 data(a_size), time(0.0), totaltime(0.0)
141 SharedBuffer<u8> data; // Data of the packet, including headers
142 float time; // Seconds from buffering the packet or re-sending
143 float totaltime; // Seconds from buffering the packet
144 Address address; // Sender or destination
147 // This adds the base headers to the data and makes a packet out of it
148 BufferedPacket makePacket(Address &address, u8 *data, u32 datasize,
149 u32 protocol_id, u16 sender_peer_id, u8 channel);
150 BufferedPacket makePacket(Address &address, SharedBuffer<u8> &data,
151 u32 protocol_id, u16 sender_peer_id, u8 channel);
153 // Add the TYPE_ORIGINAL header to the data
154 SharedBuffer<u8> makeOriginalPacket(
155 SharedBuffer<u8> data);
157 // Split data in chunks and add TYPE_SPLIT headers to them
158 core::list<SharedBuffer<u8> > makeSplitPacket(
159 SharedBuffer<u8> data,
163 // Depending on size, make a TYPE_ORIGINAL or TYPE_SPLIT packet
164 // Increments split_seqnum if a split packet is made
165 core::list<SharedBuffer<u8> > makeAutoSplitPacket(
166 SharedBuffer<u8> data,
170 // Add the TYPE_RELIABLE header to the data
171 SharedBuffer<u8> makeReliablePacket(
172 SharedBuffer<u8> data,
175 struct IncomingSplitPacket
177 IncomingSplitPacket()
182 // Key is chunk number, value is data without headers
183 core::map<u16, SharedBuffer<u8> > chunks;
185 float time; // Seconds from adding
186 bool reliable; // If true, isn't deleted on timeout
190 return (chunks.size() == chunk_count);
197 A packet is sent through a channel to a peer with a basic header:
198 TODO: Should we have a receiver_peer_id also?
201 [4] u16 sender_peer_id
205 value 0 is reserved for making new connections
206 value 1 is reserved for server
208 The lower the number, the higher the priority is.
209 Only channels 0, 1 and 2 exist.
211 #define BASE_HEADER_SIZE 7
212 #define PEER_ID_NEW 0
213 #define PEER_ID_SERVER 1
214 #define CHANNEL_COUNT 3
218 CONTROL: This is a packet used by the protocol.
219 - When this is processed, nothing is handed to the user.
223 controltype and data description:
226 CONTROLTYPE_SET_PEER_ID
229 - This can be sent in a reliable packet to get a reply
231 #define TYPE_CONTROL 0
232 #define CONTROLTYPE_ACK 0
233 #define CONTROLTYPE_SET_PEER_ID 1
234 #define CONTROLTYPE_PING 2
236 ORIGINAL: This is a plain packet with no control and no error
238 - When this is processed, it is directly handed to the user.
242 #define TYPE_ORIGINAL 1
243 #define ORIGINAL_HEADER_SIZE 1
245 SPLIT: These are sequences of packets forming one bigger piece of
247 - When processed and all the packet_nums 0...packet_count-1 are
248 present (this should be buffered), the resulting data shall be
249 directly handed to the user.
250 - If the data fails to come up in a reasonable time, the buffer shall
251 be silently discarded.
252 - These can be sent as-is or atop of a RELIABLE packet stream.
261 RELIABLE: Delivery of all RELIABLE packets shall be forced by ACKs,
262 and they shall be delivered in the same order as sent. This is done
263 with a buffer in the receiving and transmitting end.
264 - When this is processed, the contents of each packet is recursively
265 processed as packets.
271 #define TYPE_RELIABLE 3
272 #define RELIABLE_HEADER_SIZE 3
273 //#define SEQNUM_INITIAL 0x10
274 #define SEQNUM_INITIAL 65500
277 A buffer which stores reliable packets and sorts them internally
278 for fast access to the smallest one.
281 typedef core::list<BufferedPacket>::Iterator RPBSearchResult;
283 class ReliablePacketBuffer
290 RPBSearchResult findPacket(u16 seqnum);
291 RPBSearchResult notFound();
292 u16 getFirstSeqnum();
293 BufferedPacket popFirst();
294 BufferedPacket popSeqnum(u16 seqnum);
295 void insert(BufferedPacket &p);
296 void incrementTimeouts(float dtime);
297 void resetTimedOuts(float timeout);
298 bool anyTotaltimeReached(float timeout);
299 core::list<BufferedPacket> getTimedOuts(float timeout);
302 core::list<BufferedPacket> m_list;
306 A buffer for reconstructing split packets
309 class IncomingSplitBuffer
312 ~IncomingSplitBuffer();
314 This will throw a GotSplitPacketException when a full
315 split packet is constructed.
317 void insert(BufferedPacket &p, bool reliable);
319 void removeUnreliableTimedOuts(float dtime, float timeout);
323 core::map<u16, IncomingSplitPacket*> m_buf;
333 Processes a packet with the basic header stripped out.
335 packetdata: Data in packet (with no base headers)
336 con: The connection to which the channel is associated
337 (used for sending back stuff (ACKs))
338 peer_id: peer id of the sender of the packet in question
339 channelnum: channel on which the packet was sent
340 reliable: true if recursing into a reliable packet
342 SharedBuffer<u8> ProcessPacket(
343 SharedBuffer<u8> packetdata,
347 bool reliable=false);
349 // Returns next data from a buffer if possible
350 // throws a NoIncomingDataException if no data is available
351 // If found, sets peer_id
352 SharedBuffer<u8> CheckIncomingBuffers(Connection *con,
355 u16 next_outgoing_seqnum;
356 u16 next_incoming_seqnum;
357 u16 next_outgoing_split_seqnum;
359 // This is for buffering the incoming packets that are coming in
361 ReliablePacketBuffer incoming_reliables;
362 // This is for buffering the sent packets so that the sender can
363 // re-send them if no ACK is received
364 ReliablePacketBuffer outgoing_reliables;
366 IncomingSplitBuffer incoming_splits;
377 virtual ~PeerHandler()
382 This is called after the Peer has been inserted into the
383 Connection's peer container.
385 virtual void peerAdded(Peer *peer) = 0;
387 This is called before the Peer has been removed from the
388 Connection's peer container.
390 virtual void deletingPeer(Peer *peer, bool timeout) = 0;
397 Peer(u16 a_id, Address a_address);
401 Calculates avg_rtt and resend_timeout.
403 rtt=-1 only recalculates resend_timeout
405 void reportRTT(float rtt);
407 Channel channels[CHANNEL_COUNT];
409 // Address of the peer
411 // Unique id of the peer
413 // Seconds from last receive
414 float timeout_counter;
417 // This is changed dynamically
418 float resend_timeout;
419 // Updated when an ACK is received
421 // This is set to true when the peer has actually sent something
422 // with the id we have given to it
423 bool has_sent_with_id;
435 PeerHandler *peerhandler
438 void setTimeoutMs(int timeout){ m_socket.setTimeoutMs(timeout); }
439 // Start being a server
440 void Serve(unsigned short port);
441 // Connect to a server
442 void Connect(Address address);
446 SharedBuffer<u8> GetFromBuffers(u16 &peer_id);
448 // The peer_id of sender is stored in peer_id
449 // Return value: I guess this always throws an exception or
450 // actually gets data
451 u32 Receive(u16 &peer_id, u8 *data, u32 datasize);
453 // These will automatically package the data as an original or split
454 void SendToAll(u8 channelnum, SharedBuffer<u8> data, bool reliable);
455 void Send(u16 peer_id, u8 channelnum, SharedBuffer<u8> data, bool reliable);
456 // Send data as a packet; it will be wrapped in base header and
457 // optionally to a reliable packet.
458 void SendAsPacket(u16 peer_id, u8 channelnum,
459 SharedBuffer<u8> data, bool reliable);
460 // Sends a raw packet
461 void RawSend(const BufferedPacket &packet);
463 void RunTimeouts(float dtime);
464 // Can throw a PeerNotFoundException
465 Peer* GetPeer(u16 peer_id);
466 // returns NULL if failed
467 Peer* GetPeerNoEx(u16 peer_id);
468 core::list<Peer*> GetPeers();
470 void SetPeerID(u16 id){ m_peer_id = id; }
471 u16 GetPeerID(){ return m_peer_id; }
472 u32 GetProtocolID(){ return m_protocol_id; }
474 // For debug printing
475 void PrintInfo(std::ostream &out);
482 PeerHandler *m_peerhandler;
483 core::map<u16, Peer*> m_peers;
485 //bool m_waiting_new_peer_id;
486 u32 m_max_packet_size;