1 #ifndef CONNECTION_HEADER
2 #define CONNECTION_HEADER
7 #include "common_irrlicht.h"
10 #include "exceptions.h"
11 #include "constants.h"
19 class NotFoundException : public BaseException
22 NotFoundException(const char *s):
27 class PeerNotFoundException : public BaseException
30 PeerNotFoundException(const char *s):
35 class ConnectionException : public BaseException
38 ConnectionException(const char *s):
43 /*class ThrottlingException : public BaseException
46 ThrottlingException(const char *s):
51 class InvalidIncomingDataException : public BaseException
54 InvalidIncomingDataException(const char *s):
59 class InvalidOutgoingDataException : public BaseException
62 InvalidOutgoingDataException(const char *s):
67 class NoIncomingDataException : public BaseException
70 NoIncomingDataException(const char *s):
75 class ProcessedSilentlyException : public BaseException
78 ProcessedSilentlyException(const char *s):
83 class GotSplitPacketException
85 SharedBuffer<u8> m_data;
87 GotSplitPacketException(SharedBuffer<u8> data):
90 SharedBuffer<u8> getData()
96 inline u16 readPeerId(u8 *packetdata)
98 return readU16(&packetdata[4]);
100 inline u8 readChannel(u8 *packetdata)
102 return readU8(&packetdata[6]);
105 #define SEQNUM_MAX 65535
106 inline bool seqnum_higher(u16 higher, u16 lower)
108 if(lower > higher && lower - higher > SEQNUM_MAX/2){
111 return (higher > lower);
114 struct BufferedPacket
116 BufferedPacket(u8 *a_data, u32 a_size):
117 data(a_data, a_size), time(0.0), totaltime(0.0)
119 BufferedPacket(u32 a_size):
120 data(a_size), time(0.0), totaltime(0.0)
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
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);
134 // Add the TYPE_ORIGINAL header to the data
135 SharedBuffer<u8> makeOriginalPacket(
136 SharedBuffer<u8> data);
138 // Split data in chunks and add TYPE_SPLIT headers to them
139 core::list<SharedBuffer<u8> > makeSplitPacket(
140 SharedBuffer<u8> data,
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,
151 // Add the TYPE_RELIABLE header to the data
152 SharedBuffer<u8> makeReliablePacket(
153 SharedBuffer<u8> data,
156 struct IncomingSplitPacket
158 IncomingSplitPacket()
163 // Key is chunk number, value is data without headers
164 core::map<u16, SharedBuffer<u8> > chunks;
166 float time; // Seconds from adding
167 bool reliable; // If true, isn't deleted on timeout
171 return (chunks.size() == chunk_count);
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?
182 [4] u16 sender_peer_id
186 value 0 is reserved for making new connections
187 value 1 is reserved for server
189 The lower the number, the higher the priority is.
190 Only channels 0, 1 and 2 exist.
192 #define BASE_HEADER_SIZE 7
193 #define PEER_ID_NEW 0
194 #define PEER_ID_SERVER 1
195 #define CHANNEL_COUNT 3
199 CONTROL: This is a packet used by the protocol.
200 - When this is processed, nothing is handed to the user.
204 controltype and data description:
207 CONTROLTYPE_SET_PEER_ID
210 - This can be sent in a reliable packet to get a reply
212 #define TYPE_CONTROL 0
213 #define CONTROLTYPE_ACK 0
214 #define CONTROLTYPE_SET_PEER_ID 1
215 #define CONTROLTYPE_PING 2
217 ORIGINAL: This is a plain packet with no control and no error
219 - When this is processed, it is directly handed to the user.
223 #define TYPE_ORIGINAL 1
224 #define ORIGINAL_HEADER_SIZE 1
226 SPLIT: These are sequences of packets forming one bigger piece of
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.
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.
252 #define TYPE_RELIABLE 3
253 #define RELIABLE_HEADER_SIZE 3
254 //#define SEQNUM_INITIAL 0x10
255 #define SEQNUM_INITIAL 65500
258 A buffer which stores reliable packets and sorts them internally
259 for fast access to the smallest one.
262 typedef core::list<BufferedPacket>::Iterator RPBSearchResult;
264 class ReliablePacketBuffer
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);
283 core::list<BufferedPacket> m_list;
287 A buffer for reconstructing split packets
290 class IncomingSplitBuffer
293 ~IncomingSplitBuffer();
295 This will throw a GotSplitPacketException when a full
296 split packet is constructed.
298 void insert(BufferedPacket &p, bool reliable);
300 void removeUnreliableTimedOuts(float dtime, float timeout);
304 core::map<u16, IncomingSplitPacket*> m_buf;
314 Processes a packet with the basic header stripped out.
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
323 SharedBuffer<u8> ProcessPacket(
324 SharedBuffer<u8> packetdata,
328 bool reliable=false);
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,
336 u16 next_outgoing_seqnum;
337 u16 next_incoming_seqnum;
338 u16 next_outgoing_split_seqnum;
340 // This is for buffering the incoming packets that are coming in
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;
347 IncomingSplitBuffer incoming_splits;
358 virtual ~PeerHandler()
363 This is called after the Peer has been inserted into the
364 Connection's peer container.
366 virtual void peerAdded(Peer *peer) = 0;
368 This is called before the Peer has been removed from the
369 Connection's peer container.
371 virtual void deletingPeer(Peer *peer, bool timeout) = 0;
378 Peer(u16 a_id, Address a_address);
382 Calculates avg_rtt and resend_timeout.
384 rtt=-1 only recalculates resend_timeout
386 void reportRTT(float rtt);
388 Channel channels[CHANNEL_COUNT];
390 // Address of the peer
392 // Unique id of the peer
394 // Seconds from last receive
395 float timeout_counter;
398 // This is changed dynamically
399 float resend_timeout;
400 // Updated when an ACK is received
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;
416 PeerHandler *peerhandler
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);
427 SharedBuffer<u8> GetFromBuffers(u16 &peer_id);
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);
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);
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();
451 void SetPeerID(u16 id){ m_peer_id = id; }
452 u16 GetPeerID(){ return m_peer_id; }
453 u32 GetProtocolID(){ return m_protocol_id; }
455 // For debug printing
456 void PrintInfo(std::ostream &out);
463 PeerHandler *m_peerhandler;
464 core::map<u16, Peer*> m_peers;
466 //bool m_waiting_new_peer_id;
467 u32 m_max_packet_size;