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 Lesser General Public License as published by
7 the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser 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
23 #include "irrlichttypes_bloated.h"
25 #include "exceptions.h"
26 #include "constants.h"
27 #include "util/pointer.h"
28 #include "util/container.h"
29 #include "util/thread.h"
39 class NotFoundException : public BaseException
42 NotFoundException(const char *s):
47 class PeerNotFoundException : public BaseException
50 PeerNotFoundException(const char *s):
55 class ConnectionException : public BaseException
58 ConnectionException(const char *s):
63 class ConnectionBindFailed : public BaseException
66 ConnectionBindFailed(const char *s):
71 /*class ThrottlingException : public BaseException
74 ThrottlingException(const char *s):
79 class InvalidIncomingDataException : public BaseException
82 InvalidIncomingDataException(const char *s):
87 class InvalidOutgoingDataException : public BaseException
90 InvalidOutgoingDataException(const char *s):
95 class NoIncomingDataException : public BaseException
98 NoIncomingDataException(const char *s):
103 class ProcessedSilentlyException : public BaseException
106 ProcessedSilentlyException(const char *s):
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 u16 next_outgoing_seqnum;
324 u16 next_incoming_seqnum;
325 u16 next_outgoing_split_seqnum;
327 // This is for buffering the incoming packets that are coming in
329 ReliablePacketBuffer incoming_reliables;
330 // This is for buffering the sent packets so that the sender can
331 // re-send them if no ACK is received
332 ReliablePacketBuffer outgoing_reliables;
334 IncomingSplitBuffer incoming_splits;
345 virtual ~PeerHandler()
350 This is called after the Peer has been inserted into the
351 Connection's peer container.
353 virtual void peerAdded(Peer *peer) = 0;
355 This is called before the Peer has been removed from the
356 Connection's peer container.
358 virtual void deletingPeer(Peer *peer, bool timeout) = 0;
365 Peer(u16 a_id, Address a_address);
369 Calculates avg_rtt and resend_timeout.
371 rtt=-1 only recalculates resend_timeout
373 void reportRTT(float rtt);
375 Channel channels[CHANNEL_COUNT];
377 // Address of the peer
379 // Unique id of the peer
381 // Seconds from last receive
382 float timeout_counter;
385 // This is changed dynamically
386 float resend_timeout;
387 // Updated when an ACK is received
389 // This is set to true when the peer has actually sent something
390 // with the id we have given to it
391 bool has_sent_with_id;
393 float m_sendtime_accu;
394 float m_max_packets_per_second;
398 // Updated from configuration by Connection
399 float congestion_control_aim_rtt;
400 float congestion_control_max_rate;
401 float congestion_control_min_rate;
409 struct OutgoingPacket
413 SharedBuffer<u8> data;
416 OutgoingPacket(u16 peer_id_, u8 channelnum_, SharedBuffer<u8> data_,
419 channelnum(channelnum_),
426 enum ConnectionEventType{
428 CONNEVENT_DATA_RECEIVED,
429 CONNEVENT_PEER_ADDED,
430 CONNEVENT_PEER_REMOVED,
431 CONNEVENT_BIND_FAILED,
434 struct ConnectionEvent
436 enum ConnectionEventType type;
442 ConnectionEvent(): type(CONNEVENT_NONE) {}
444 std::string describe()
448 return "CONNEVENT_NONE";
449 case CONNEVENT_DATA_RECEIVED:
450 return "CONNEVENT_DATA_RECEIVED";
451 case CONNEVENT_PEER_ADDED:
452 return "CONNEVENT_PEER_ADDED";
453 case CONNEVENT_PEER_REMOVED:
454 return "CONNEVENT_PEER_REMOVED";
455 case CONNEVENT_BIND_FAILED:
456 return "CONNEVENT_BIND_FAILED";
458 return "Invalid ConnectionEvent";
461 void dataReceived(u16 peer_id_, SharedBuffer<u8> data_)
463 type = CONNEVENT_DATA_RECEIVED;
467 void peerAdded(u16 peer_id_, Address address_)
469 type = CONNEVENT_PEER_ADDED;
473 void peerRemoved(u16 peer_id_, bool timeout_, Address address_)
475 type = CONNEVENT_PEER_REMOVED;
482 type = CONNEVENT_BIND_FAILED;
486 enum ConnectionCommandType{
496 struct ConnectionCommand
498 enum ConnectionCommandType type;
506 ConnectionCommand(): type(CONNCMD_NONE) {}
508 void serve(u16 port_)
510 type = CONNCMD_SERVE;
513 void connect(Address address_)
515 type = CONNCMD_CONNECT;
520 type = CONNCMD_DISCONNECT;
522 void send(u16 peer_id_, u8 channelnum_,
523 SharedBuffer<u8> data_, bool reliable_)
527 channelnum = channelnum_;
529 reliable = reliable_;
531 void sendToAll(u8 channelnum_, SharedBuffer<u8> data_, bool reliable_)
533 type = CONNCMD_SEND_TO_ALL;
534 channelnum = channelnum_;
536 reliable = reliable_;
538 void deletePeer(u16 peer_id_)
540 type = CONNCMD_DELETE_PEER;
545 class Connection: public SimpleThread
548 Connection(u32 protocol_id, u32 max_packet_size, float timeout);
549 Connection(u32 protocol_id, u32 max_packet_size, float timeout,
550 PeerHandler *peerhandler);
556 ConnectionEvent getEvent();
557 ConnectionEvent waitEvent(u32 timeout_ms);
558 void putCommand(ConnectionCommand &c);
560 void SetTimeoutMs(int timeout){ m_bc_receive_timeout = timeout; }
561 void Serve(unsigned short port);
562 void Connect(Address address);
565 u32 Receive(u16 &peer_id, SharedBuffer<u8> &data);
566 void SendToAll(u8 channelnum, SharedBuffer<u8> data, bool reliable);
567 void Send(u16 peer_id, u8 channelnum, SharedBuffer<u8> data, bool reliable);
568 void RunTimeouts(float dtime); // dummy
569 u16 GetPeerID(){ return m_peer_id; }
570 Address GetPeerAddress(u16 peer_id);
571 float GetPeerAvgRTT(u16 peer_id);
572 void DeletePeer(u16 peer_id);
575 void putEvent(ConnectionEvent &e);
576 void processCommand(ConnectionCommand &c);
577 void send(float dtime);
579 void runTimeouts(float dtime);
580 void serve(u16 port);
581 void connect(Address address);
583 void sendToAll(u8 channelnum, SharedBuffer<u8> data, bool reliable);
584 void send(u16 peer_id, u8 channelnum, SharedBuffer<u8> data, bool reliable);
585 void sendAsPacket(u16 peer_id, u8 channelnum,
586 SharedBuffer<u8> data, bool reliable);
587 void rawSendAsPacket(u16 peer_id, u8 channelnum,
588 SharedBuffer<u8> data, bool reliable);
589 void rawSend(const BufferedPacket &packet);
590 Peer* getPeer(u16 peer_id);
591 Peer* getPeerNoEx(u16 peer_id);
592 core::list<Peer*> getPeers();
593 bool getFromBuffers(u16 &peer_id, SharedBuffer<u8> &dst);
594 // Returns next data from a buffer if possible
595 // If found, returns true; if not, false.
596 // If found, sets peer_id and dst
597 bool checkIncomingBuffers(Channel *channel, u16 &peer_id,
598 SharedBuffer<u8> &dst);
600 Processes a packet with the basic header stripped out.
602 packetdata: Data in packet (with no base headers)
603 peer_id: peer id of the sender of the packet in question
604 channelnum: channel on which the packet was sent
605 reliable: true if recursing into a reliable packet
607 SharedBuffer<u8> processPacket(Channel *channel,
608 SharedBuffer<u8> packetdata, u16 peer_id,
609 u8 channelnum, bool reliable);
610 bool deletePeer(u16 peer_id, bool timeout);
612 Queue<OutgoingPacket> m_outgoing_queue;
613 MutexedQueue<ConnectionEvent> m_event_queue;
614 MutexedQueue<ConnectionCommand> m_command_queue;
617 u32 m_max_packet_size;
622 core::map<u16, Peer*> m_peers;
623 JMutex m_peers_mutex;
625 // Backwards compatibility
626 PeerHandler *m_bc_peerhandler;
627 int m_bc_receive_timeout;
629 void SetPeerID(u16 id){ m_peer_id = id; }
630 u32 GetProtocolID(){ return m_protocol_id; }
631 void PrintInfo(std::ostream &out);
633 std::string getDesc();