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 - There is no actual reply, but this can be sent in a reliable
230 packet to get a reply
233 #define TYPE_CONTROL 0
234 #define CONTROLTYPE_ACK 0
235 #define CONTROLTYPE_SET_PEER_ID 1
236 #define CONTROLTYPE_PING 2
237 #define CONTROLTYPE_DISCO 3
239 ORIGINAL: This is a plain packet with no control and no error
241 - When this is processed, it is directly handed to the user.
245 #define TYPE_ORIGINAL 1
246 #define ORIGINAL_HEADER_SIZE 1
248 SPLIT: These are sequences of packets forming one bigger piece of
250 - When processed and all the packet_nums 0...packet_count-1 are
251 present (this should be buffered), the resulting data shall be
252 directly handed to the user.
253 - If the data fails to come up in a reasonable time, the buffer shall
254 be silently discarded.
255 - These can be sent as-is or atop of a RELIABLE packet stream.
264 RELIABLE: Delivery of all RELIABLE packets shall be forced by ACKs,
265 and they shall be delivered in the same order as sent. This is done
266 with a buffer in the receiving and transmitting end.
267 - When this is processed, the contents of each packet is recursively
268 processed as packets.
274 #define TYPE_RELIABLE 3
275 #define RELIABLE_HEADER_SIZE 3
276 //#define SEQNUM_INITIAL 0x10
277 #define SEQNUM_INITIAL 65500
280 A buffer which stores reliable packets and sorts them internally
281 for fast access to the smallest one.
284 typedef core::list<BufferedPacket>::Iterator RPBSearchResult;
286 class ReliablePacketBuffer
293 RPBSearchResult findPacket(u16 seqnum);
294 RPBSearchResult notFound();
295 u16 getFirstSeqnum();
296 BufferedPacket popFirst();
297 BufferedPacket popSeqnum(u16 seqnum);
298 void insert(BufferedPacket &p);
299 void incrementTimeouts(float dtime);
300 void resetTimedOuts(float timeout);
301 bool anyTotaltimeReached(float timeout);
302 core::list<BufferedPacket> getTimedOuts(float timeout);
305 core::list<BufferedPacket> m_list;
309 A buffer for reconstructing split packets
312 class IncomingSplitBuffer
315 ~IncomingSplitBuffer();
317 This will throw a GotSplitPacketException when a full
318 split packet is constructed.
320 void insert(BufferedPacket &p, bool reliable);
322 void removeUnreliableTimedOuts(float dtime, float timeout);
326 core::map<u16, IncomingSplitPacket*> m_buf;
336 Processes a packet with the basic header stripped out.
338 packetdata: Data in packet (with no base headers)
339 con: The connection to which the channel is associated
340 (used for sending back stuff (ACKs))
341 peer_id: peer id of the sender of the packet in question
342 channelnum: channel on which the packet was sent
343 reliable: true if recursing into a reliable packet
345 SharedBuffer<u8> ProcessPacket(
346 SharedBuffer<u8> packetdata,
350 bool reliable=false);
352 // Returns next data from a buffer if possible
353 // throws a NoIncomingDataException if no data is available
354 // If found, sets peer_id
355 SharedBuffer<u8> CheckIncomingBuffers(Connection *con,
358 u16 next_outgoing_seqnum;
359 u16 next_incoming_seqnum;
360 u16 next_outgoing_split_seqnum;
362 // This is for buffering the incoming packets that are coming in
364 ReliablePacketBuffer incoming_reliables;
365 // This is for buffering the sent packets so that the sender can
366 // re-send them if no ACK is received
367 ReliablePacketBuffer outgoing_reliables;
369 IncomingSplitBuffer incoming_splits;
380 virtual ~PeerHandler()
385 This is called after the Peer has been inserted into the
386 Connection's peer container.
388 virtual void peerAdded(Peer *peer) = 0;
390 This is called before the Peer has been removed from the
391 Connection's peer container.
393 virtual void deletingPeer(Peer *peer, bool timeout) = 0;
400 Peer(u16 a_id, Address a_address);
404 Calculates avg_rtt and resend_timeout.
406 rtt=-1 only recalculates resend_timeout
408 void reportRTT(float rtt);
410 Channel channels[CHANNEL_COUNT];
412 // Address of the peer
414 // Unique id of the peer
416 // Seconds from last receive
417 float timeout_counter;
420 // This is changed dynamically
421 float resend_timeout;
422 // Updated when an ACK is received
424 // This is set to true when the peer has actually sent something
425 // with the id we have given to it
426 bool has_sent_with_id;
438 PeerHandler *peerhandler
441 void setTimeoutMs(int timeout){ m_socket.setTimeoutMs(timeout); }
442 // Start being a server
443 void Serve(unsigned short port);
444 // Connect to a server
445 void Connect(Address address);
451 SharedBuffer<u8> GetFromBuffers(u16 &peer_id);
453 // The peer_id of sender is stored in peer_id
454 // Return value: I guess this always throws an exception or
455 // actually gets data
456 // May call PeerHandler methods
457 u32 Receive(u16 &peer_id, u8 *data, u32 datasize);
459 // These will automatically package the data as an original or split
460 void SendToAll(u8 channelnum, SharedBuffer<u8> data, bool reliable);
461 void Send(u16 peer_id, u8 channelnum, SharedBuffer<u8> data, bool reliable);
462 // Send data as a packet; it will be wrapped in base header and
463 // optionally to a reliable packet.
464 void SendAsPacket(u16 peer_id, u8 channelnum,
465 SharedBuffer<u8> data, bool reliable);
466 // Sends a raw packet
467 void RawSend(const BufferedPacket &packet);
469 // May call PeerHandler methods
470 void RunTimeouts(float dtime);
472 // Can throw a PeerNotFoundException
473 Peer* GetPeer(u16 peer_id);
474 // returns NULL if failed
475 Peer* GetPeerNoEx(u16 peer_id);
476 core::list<Peer*> GetPeers();
478 // Calls PeerHandler::deletingPeer
479 // Returns false if peer was not found
480 bool deletePeer(u16 peer_id, bool timeout);
482 void SetPeerID(u16 id){ m_peer_id = id; }
483 u16 GetPeerID(){ return m_peer_id; }
484 u32 GetProtocolID(){ return m_protocol_id; }
486 // For debug printing
487 void PrintInfo(std::ostream &out);
494 PeerHandler *m_peerhandler;
495 core::map<u16, Peer*> m_peers;
497 //bool m_waiting_new_peer_id;
498 u32 m_max_packet_size;