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 ConnectionBindFailed : public BaseException
65 ConnectionBindFailed(const char *s):
70 /*class ThrottlingException : public BaseException
73 ThrottlingException(const char *s):
78 class InvalidIncomingDataException : public BaseException
81 InvalidIncomingDataException(const char *s):
86 class InvalidOutgoingDataException : public BaseException
89 InvalidOutgoingDataException(const char *s):
94 class NoIncomingDataException : public BaseException
97 NoIncomingDataException(const char *s):
102 class ProcessedSilentlyException : public BaseException
105 ProcessedSilentlyException(const char *s):
110 inline u16 readPeerId(u8 *packetdata)
112 return readU16(&packetdata[4]);
114 inline u8 readChannel(u8 *packetdata)
116 return readU8(&packetdata[6]);
119 #define SEQNUM_MAX 65535
120 inline bool seqnum_higher(u16 higher, u16 lower)
122 if(lower > higher && lower - higher > SEQNUM_MAX/2){
125 return (higher > lower);
128 struct BufferedPacket
130 BufferedPacket(u8 *a_data, u32 a_size):
131 data(a_data, a_size), time(0.0), totaltime(0.0)
133 BufferedPacket(u32 a_size):
134 data(a_size), time(0.0), totaltime(0.0)
136 SharedBuffer<u8> data; // Data of the packet, including headers
137 float time; // Seconds from buffering the packet or re-sending
138 float totaltime; // Seconds from buffering the packet
139 Address address; // Sender or destination
142 // This adds the base headers to the data and makes a packet out of it
143 BufferedPacket makePacket(Address &address, u8 *data, u32 datasize,
144 u32 protocol_id, u16 sender_peer_id, u8 channel);
145 BufferedPacket makePacket(Address &address, SharedBuffer<u8> &data,
146 u32 protocol_id, u16 sender_peer_id, u8 channel);
148 // Add the TYPE_ORIGINAL header to the data
149 SharedBuffer<u8> makeOriginalPacket(
150 SharedBuffer<u8> data);
152 // Split data in chunks and add TYPE_SPLIT headers to them
153 core::list<SharedBuffer<u8> > makeSplitPacket(
154 SharedBuffer<u8> data,
158 // Depending on size, make a TYPE_ORIGINAL or TYPE_SPLIT packet
159 // Increments split_seqnum if a split packet is made
160 core::list<SharedBuffer<u8> > makeAutoSplitPacket(
161 SharedBuffer<u8> data,
165 // Add the TYPE_RELIABLE header to the data
166 SharedBuffer<u8> makeReliablePacket(
167 SharedBuffer<u8> data,
170 struct IncomingSplitPacket
172 IncomingSplitPacket()
177 // Key is chunk number, value is data without headers
178 core::map<u16, SharedBuffer<u8> > chunks;
180 float time; // Seconds from adding
181 bool reliable; // If true, isn't deleted on timeout
185 return (chunks.size() == chunk_count);
192 A packet is sent through a channel to a peer with a basic header:
193 TODO: Should we have a receiver_peer_id also?
196 [4] u16 sender_peer_id
200 value 0 is reserved for making new connections
201 value 1 is reserved for server
203 The lower the number, the higher the priority is.
204 Only channels 0, 1 and 2 exist.
206 #define BASE_HEADER_SIZE 7
207 #define PEER_ID_INEXISTENT 0
208 #define PEER_ID_SERVER 1
209 #define CHANNEL_COUNT 3
213 CONTROL: This is a packet used by the protocol.
214 - When this is processed, nothing is handed to the user.
218 controltype and data description:
221 CONTROLTYPE_SET_PEER_ID
224 - There is no actual reply, but this can be sent in a reliable
225 packet to get a reply
228 #define TYPE_CONTROL 0
229 #define CONTROLTYPE_ACK 0
230 #define CONTROLTYPE_SET_PEER_ID 1
231 #define CONTROLTYPE_PING 2
232 #define CONTROLTYPE_DISCO 3
234 ORIGINAL: This is a plain packet with no control and no error
236 - When this is processed, it is directly handed to the user.
240 #define TYPE_ORIGINAL 1
241 #define ORIGINAL_HEADER_SIZE 1
243 SPLIT: These are sequences of packets forming one bigger piece of
245 - When processed and all the packet_nums 0...packet_count-1 are
246 present (this should be buffered), the resulting data shall be
247 directly handed to the user.
248 - If the data fails to come up in a reasonable time, the buffer shall
249 be silently discarded.
250 - These can be sent as-is or atop of a RELIABLE packet stream.
259 RELIABLE: Delivery of all RELIABLE packets shall be forced by ACKs,
260 and they shall be delivered in the same order as sent. This is done
261 with a buffer in the receiving and transmitting end.
262 - When this is processed, the contents of each packet is recursively
263 processed as packets.
269 #define TYPE_RELIABLE 3
270 #define RELIABLE_HEADER_SIZE 3
271 //#define SEQNUM_INITIAL 0x10
272 #define SEQNUM_INITIAL 65500
275 A buffer which stores reliable packets and sorts them internally
276 for fast access to the smallest one.
279 typedef core::list<BufferedPacket>::Iterator RPBSearchResult;
281 class ReliablePacketBuffer
288 RPBSearchResult findPacket(u16 seqnum);
289 RPBSearchResult notFound();
290 u16 getFirstSeqnum();
291 BufferedPacket popFirst();
292 BufferedPacket popSeqnum(u16 seqnum);
293 void insert(BufferedPacket &p);
294 void incrementTimeouts(float dtime);
295 void resetTimedOuts(float timeout);
296 bool anyTotaltimeReached(float timeout);
297 core::list<BufferedPacket> getTimedOuts(float timeout);
300 core::list<BufferedPacket> m_list;
304 A buffer for reconstructing split packets
307 class IncomingSplitBuffer
310 ~IncomingSplitBuffer();
312 Returns a reference counted buffer of length != 0 when a full split
313 packet is constructed. If not, returns one of length 0.
315 SharedBuffer<u8> insert(BufferedPacket &p, bool reliable);
317 void removeUnreliableTimedOuts(float dtime, float timeout);
321 core::map<u16, IncomingSplitPacket*> m_buf;
331 u16 next_outgoing_seqnum;
332 u16 next_incoming_seqnum;
333 u16 next_outgoing_split_seqnum;
335 // This is for buffering the incoming packets that are coming in
337 ReliablePacketBuffer incoming_reliables;
338 // This is for buffering the sent packets so that the sender can
339 // re-send them if no ACK is received
340 ReliablePacketBuffer outgoing_reliables;
342 IncomingSplitBuffer incoming_splits;
353 virtual ~PeerHandler()
358 This is called after the Peer has been inserted into the
359 Connection's peer container.
361 virtual void peerAdded(Peer *peer) = 0;
363 This is called before the Peer has been removed from the
364 Connection's peer container.
366 virtual void deletingPeer(Peer *peer, bool timeout) = 0;
373 Peer(u16 a_id, Address a_address);
377 Calculates avg_rtt and resend_timeout.
379 rtt=-1 only recalculates resend_timeout
381 void reportRTT(float rtt);
383 Channel channels[CHANNEL_COUNT];
385 // Address of the peer
387 // Unique id of the peer
389 // Seconds from last receive
390 float timeout_counter;
393 // This is changed dynamically
394 float resend_timeout;
395 // Updated when an ACK is received
397 // This is set to true when the peer has actually sent something
398 // with the id we have given to it
399 bool has_sent_with_id;
401 float m_sendtime_accu;
402 float m_max_packets_per_second;
413 struct OutgoingPacket
417 SharedBuffer<u8> data;
420 OutgoingPacket(u16 peer_id_, u8 channelnum_, SharedBuffer<u8> data_,
423 channelnum(channelnum_),
430 enum ConnectionEventType{
432 CONNEVENT_DATA_RECEIVED,
433 CONNEVENT_PEER_ADDED,
434 CONNEVENT_PEER_REMOVED,
435 CONNEVENT_BIND_FAILED,
438 struct ConnectionEvent
440 enum ConnectionEventType type;
446 ConnectionEvent(): type(CONNEVENT_NONE) {}
448 std::string describe()
452 return "CONNEVENT_NONE";
453 case CONNEVENT_DATA_RECEIVED:
454 return "CONNEVENT_DATA_RECEIVED";
455 case CONNEVENT_PEER_ADDED:
456 return "CONNEVENT_PEER_ADDED";
457 case CONNEVENT_PEER_REMOVED:
458 return "CONNEVENT_PEER_REMOVED";
459 case CONNEVENT_BIND_FAILED:
460 return "CONNEVENT_BIND_FAILED";
462 return "Invalid ConnectionEvent";
465 void dataReceived(u16 peer_id_, SharedBuffer<u8> data_)
467 type = CONNEVENT_DATA_RECEIVED;
471 void peerAdded(u16 peer_id_, Address address_)
473 type = CONNEVENT_PEER_ADDED;
477 void peerRemoved(u16 peer_id_, bool timeout_, Address address_)
479 type = CONNEVENT_PEER_REMOVED;
486 type = CONNEVENT_BIND_FAILED;
490 enum ConnectionCommandType{
500 struct ConnectionCommand
502 enum ConnectionCommandType type;
510 ConnectionCommand(): type(CONNCMD_NONE) {}
512 void serve(u16 port_)
514 type = CONNCMD_SERVE;
517 void connect(Address address_)
519 type = CONNCMD_CONNECT;
524 type = CONNCMD_DISCONNECT;
526 void send(u16 peer_id_, u8 channelnum_,
527 SharedBuffer<u8> data_, bool reliable_)
531 channelnum = channelnum_;
533 reliable = reliable_;
535 void sendToAll(u8 channelnum_, SharedBuffer<u8> data_, bool reliable_)
537 type = CONNCMD_SEND_TO_ALL;
538 channelnum = channelnum_;
540 reliable = reliable_;
542 void deletePeer(u16 peer_id_)
544 type = CONNCMD_DELETE_PEER;
549 class Connection: public SimpleThread
552 Connection(u32 protocol_id, u32 max_packet_size, float timeout);
553 Connection(u32 protocol_id, u32 max_packet_size, float timeout,
554 PeerHandler *peerhandler);
560 ConnectionEvent getEvent();
561 ConnectionEvent waitEvent(u32 timeout_ms);
562 void putCommand(ConnectionCommand &c);
564 void SetTimeoutMs(int timeout){ m_bc_receive_timeout = timeout; }
565 void Serve(unsigned short port);
566 void Connect(Address address);
569 u32 Receive(u16 &peer_id, SharedBuffer<u8> &data);
570 void SendToAll(u8 channelnum, SharedBuffer<u8> data, bool reliable);
571 void Send(u16 peer_id, u8 channelnum, SharedBuffer<u8> data, bool reliable);
572 void RunTimeouts(float dtime); // dummy
573 u16 GetPeerID(){ return m_peer_id; }
574 Address GetPeerAddress(u16 peer_id);
575 float GetPeerAvgRTT(u16 peer_id);
576 void DeletePeer(u16 peer_id);
579 void putEvent(ConnectionEvent &e);
580 void processCommand(ConnectionCommand &c);
581 void send(float dtime);
583 void runTimeouts(float dtime);
584 void serve(u16 port);
585 void connect(Address address);
587 void sendToAll(u8 channelnum, SharedBuffer<u8> data, bool reliable);
588 void send(u16 peer_id, u8 channelnum, SharedBuffer<u8> data, bool reliable);
589 void sendAsPacket(u16 peer_id, u8 channelnum,
590 SharedBuffer<u8> data, bool reliable);
591 void rawSendAsPacket(u16 peer_id, u8 channelnum,
592 SharedBuffer<u8> data, bool reliable);
593 void rawSend(const BufferedPacket &packet);
594 Peer* getPeer(u16 peer_id);
595 Peer* getPeerNoEx(u16 peer_id);
596 core::list<Peer*> getPeers();
597 bool getFromBuffers(u16 &peer_id, SharedBuffer<u8> &dst);
598 // Returns next data from a buffer if possible
599 // If found, returns true; if not, false.
600 // If found, sets peer_id and dst
601 bool checkIncomingBuffers(Channel *channel, u16 &peer_id,
602 SharedBuffer<u8> &dst);
604 Processes a packet with the basic header stripped out.
606 packetdata: Data in packet (with no base headers)
607 peer_id: peer id of the sender of the packet in question
608 channelnum: channel on which the packet was sent
609 reliable: true if recursing into a reliable packet
611 SharedBuffer<u8> processPacket(Channel *channel,
612 SharedBuffer<u8> packetdata, u16 peer_id,
613 u8 channelnum, bool reliable);
614 bool deletePeer(u16 peer_id, bool timeout);
616 Queue<OutgoingPacket> m_outgoing_queue;
617 MutexedQueue<ConnectionEvent> m_event_queue;
618 MutexedQueue<ConnectionCommand> m_command_queue;
621 u32 m_max_packet_size;
626 core::map<u16, Peer*> m_peers;
627 JMutex m_peers_mutex;
629 // Backwards compatibility
630 PeerHandler *m_bc_peerhandler;
631 int m_bc_receive_timeout;
633 void SetPeerID(u16 id){ m_peer_id = id; }
634 u32 GetProtocolID(){ return m_protocol_id; }
635 void PrintInfo(std::ostream &out);
637 std::string getDesc();