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 inline u16 readPeerId(u8 *packetdata)
104 return readU16(&packetdata[4]);
106 inline u8 readChannel(u8 *packetdata)
108 return readU8(&packetdata[6]);
111 #define SEQNUM_MAX 65535
112 inline bool seqnum_higher(u16 higher, u16 lower)
114 if(lower > higher && lower - higher > SEQNUM_MAX/2){
117 return (higher > lower);
120 struct BufferedPacket
122 BufferedPacket(u8 *a_data, u32 a_size):
123 data(a_data, a_size), time(0.0), totaltime(0.0)
125 BufferedPacket(u32 a_size):
126 data(a_size), time(0.0), totaltime(0.0)
128 SharedBuffer<u8> data; // Data of the packet, including headers
129 float time; // Seconds from buffering the packet or re-sending
130 float totaltime; // Seconds from buffering the packet
131 Address address; // Sender or destination
134 // This adds the base headers to the data and makes a packet out of it
135 BufferedPacket makePacket(Address &address, u8 *data, u32 datasize,
136 u32 protocol_id, u16 sender_peer_id, u8 channel);
137 BufferedPacket makePacket(Address &address, SharedBuffer<u8> &data,
138 u32 protocol_id, u16 sender_peer_id, u8 channel);
140 // Add the TYPE_ORIGINAL header to the data
141 SharedBuffer<u8> makeOriginalPacket(
142 SharedBuffer<u8> data);
144 // Split data in chunks and add TYPE_SPLIT headers to them
145 core::list<SharedBuffer<u8> > makeSplitPacket(
146 SharedBuffer<u8> data,
150 // Depending on size, make a TYPE_ORIGINAL or TYPE_SPLIT packet
151 // Increments split_seqnum if a split packet is made
152 core::list<SharedBuffer<u8> > makeAutoSplitPacket(
153 SharedBuffer<u8> data,
157 // Add the TYPE_RELIABLE header to the data
158 SharedBuffer<u8> makeReliablePacket(
159 SharedBuffer<u8> data,
162 struct IncomingSplitPacket
164 IncomingSplitPacket()
169 // Key is chunk number, value is data without headers
170 core::map<u16, SharedBuffer<u8> > chunks;
172 float time; // Seconds from adding
173 bool reliable; // If true, isn't deleted on timeout
177 return (chunks.size() == chunk_count);
184 A packet is sent through a channel to a peer with a basic header:
185 TODO: Should we have a receiver_peer_id also?
188 [4] u16 sender_peer_id
192 value 0 is reserved for making new connections
193 value 1 is reserved for server
195 The lower the number, the higher the priority is.
196 Only channels 0, 1 and 2 exist.
198 #define BASE_HEADER_SIZE 7
199 #define PEER_ID_INEXISTENT 0
200 #define PEER_ID_SERVER 1
201 #define CHANNEL_COUNT 3
205 CONTROL: This is a packet used by the protocol.
206 - When this is processed, nothing is handed to the user.
210 controltype and data description:
213 CONTROLTYPE_SET_PEER_ID
216 - There is no actual reply, but this can be sent in a reliable
217 packet to get a reply
220 #define TYPE_CONTROL 0
221 #define CONTROLTYPE_ACK 0
222 #define CONTROLTYPE_SET_PEER_ID 1
223 #define CONTROLTYPE_PING 2
224 #define CONTROLTYPE_DISCO 3
226 ORIGINAL: This is a plain packet with no control and no error
228 - When this is processed, it is directly handed to the user.
232 #define TYPE_ORIGINAL 1
233 #define ORIGINAL_HEADER_SIZE 1
235 SPLIT: These are sequences of packets forming one bigger piece of
237 - When processed and all the packet_nums 0...packet_count-1 are
238 present (this should be buffered), the resulting data shall be
239 directly handed to the user.
240 - If the data fails to come up in a reasonable time, the buffer shall
241 be silently discarded.
242 - These can be sent as-is or atop of a RELIABLE packet stream.
251 RELIABLE: Delivery of all RELIABLE packets shall be forced by ACKs,
252 and they shall be delivered in the same order as sent. This is done
253 with a buffer in the receiving and transmitting end.
254 - When this is processed, the contents of each packet is recursively
255 processed as packets.
261 #define TYPE_RELIABLE 3
262 #define RELIABLE_HEADER_SIZE 3
263 //#define SEQNUM_INITIAL 0x10
264 #define SEQNUM_INITIAL 65500
267 A buffer which stores reliable packets and sorts them internally
268 for fast access to the smallest one.
271 typedef core::list<BufferedPacket>::Iterator RPBSearchResult;
273 class ReliablePacketBuffer
280 RPBSearchResult findPacket(u16 seqnum);
281 RPBSearchResult notFound();
282 u16 getFirstSeqnum();
283 BufferedPacket popFirst();
284 BufferedPacket popSeqnum(u16 seqnum);
285 void insert(BufferedPacket &p);
286 void incrementTimeouts(float dtime);
287 void resetTimedOuts(float timeout);
288 bool anyTotaltimeReached(float timeout);
289 core::list<BufferedPacket> getTimedOuts(float timeout);
292 core::list<BufferedPacket> m_list;
296 A buffer for reconstructing split packets
299 class IncomingSplitBuffer
302 ~IncomingSplitBuffer();
304 Returns a reference counted buffer of length != 0 when a full split
305 packet is constructed. If not, returns one of length 0.
307 SharedBuffer<u8> insert(BufferedPacket &p, bool reliable);
309 void removeUnreliableTimedOuts(float dtime, float timeout);
313 core::map<u16, IncomingSplitPacket*> m_buf;
323 Processes a packet with the basic header stripped out.
325 packetdata: Data in packet (with no base headers)
326 con: The connection to which the channel is associated
327 (used for sending back stuff (ACKs))
328 peer_id: peer id of the sender of the packet in question
329 channelnum: channel on which the packet was sent
330 reliable: true if recursing into a reliable packet
332 SharedBuffer<u8> ProcessPacket(
333 SharedBuffer<u8> packetdata,
337 bool reliable=false);
339 // Returns next data from a buffer if possible
340 // throws a NoIncomingDataException if no data is available
341 // If found, sets peer_id
342 SharedBuffer<u8> CheckIncomingBuffers(Connection *con,
345 u16 next_outgoing_seqnum;
346 u16 next_incoming_seqnum;
347 u16 next_outgoing_split_seqnum;
349 // This is for buffering the incoming packets that are coming in
351 ReliablePacketBuffer incoming_reliables;
352 // This is for buffering the sent packets so that the sender can
353 // re-send them if no ACK is received
354 ReliablePacketBuffer outgoing_reliables;
356 IncomingSplitBuffer incoming_splits;
367 virtual ~PeerHandler()
372 This is called after the Peer has been inserted into the
373 Connection's peer container.
375 virtual void peerAdded(Peer *peer) = 0;
377 This is called before the Peer has been removed from the
378 Connection's peer container.
380 virtual void deletingPeer(Peer *peer, bool timeout) = 0;
387 Peer(u16 a_id, Address a_address);
391 Calculates avg_rtt and resend_timeout.
393 rtt=-1 only recalculates resend_timeout
395 void reportRTT(float rtt);
397 Channel channels[CHANNEL_COUNT];
399 // Address of the peer
401 // Unique id of the peer
403 // Seconds from last receive
404 float timeout_counter;
407 // This is changed dynamically
408 float resend_timeout;
409 // Updated when an ACK is received
411 // This is set to true when the peer has actually sent something
412 // with the id we have given to it
413 bool has_sent_with_id;
425 PeerHandler *peerhandler
428 void setTimeoutMs(int timeout){ m_socket.setTimeoutMs(timeout); }
429 // Start being a server
430 void Serve(unsigned short port);
431 // Connect to a server
432 void Connect(Address address);
438 SharedBuffer<u8> GetFromBuffers(u16 &peer_id);
440 // The peer_id of sender is stored in peer_id
441 // Return value: I guess this always throws an exception or
442 // actually gets data
443 // May call PeerHandler methods
444 u32 Receive(u16 &peer_id, u8 *data, u32 datasize);
446 // These will automatically package the data as an original or split
447 void SendToAll(u8 channelnum, SharedBuffer<u8> data, bool reliable);
448 void Send(u16 peer_id, u8 channelnum, SharedBuffer<u8> data, bool reliable);
449 // Send data as a packet; it will be wrapped in base header and
450 // optionally to a reliable packet.
451 void SendAsPacket(u16 peer_id, u8 channelnum,
452 SharedBuffer<u8> data, bool reliable);
453 // Sends a raw packet
454 void RawSend(const BufferedPacket &packet);
456 // May call PeerHandler methods
457 void RunTimeouts(float dtime);
459 // Can throw a PeerNotFoundException
460 Peer* GetPeer(u16 peer_id);
461 // returns NULL if failed
462 Peer* GetPeerNoEx(u16 peer_id);
463 core::list<Peer*> GetPeers();
465 // Calls PeerHandler::deletingPeer
466 // Returns false if peer was not found
467 bool deletePeer(u16 peer_id, bool timeout);
469 void SetPeerID(u16 id){ m_peer_id = id; }
470 u16 GetPeerID(){ return m_peer_id; }
471 u32 GetProtocolID(){ return m_protocol_id; }
473 // For debug printing
474 void PrintInfo(std::ostream &out);
481 PeerHandler *m_peerhandler;
482 core::map<u16, Peer*> m_peers;
484 //bool m_waiting_new_peer_id;
485 u32 m_max_packet_size;