3 Copyright (C) 2013 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"
41 class NotFoundException : public BaseException
44 NotFoundException(const char *s):
49 class PeerNotFoundException : public BaseException
52 PeerNotFoundException(const char *s):
57 class ConnectionException : public BaseException
60 ConnectionException(const char *s):
65 class ConnectionBindFailed : public BaseException
68 ConnectionBindFailed(const char *s):
73 /*class ThrottlingException : public BaseException
76 ThrottlingException(const char *s):
81 class InvalidIncomingDataException : public BaseException
84 InvalidIncomingDataException(const char *s):
89 class InvalidOutgoingDataException : public BaseException
92 InvalidOutgoingDataException(const char *s):
97 class NoIncomingDataException : public BaseException
100 NoIncomingDataException(const char *s):
105 class ProcessedSilentlyException : public BaseException
108 ProcessedSilentlyException(const char *s):
113 #define SEQNUM_MAX 65535
114 inline bool seqnum_higher(u16 higher, u16 lower)
116 if(lower > higher && lower - higher > SEQNUM_MAX/2){
119 return (higher > lower);
122 struct BufferedPacket
124 BufferedPacket(u8 *a_data, u32 a_size):
125 data(a_data, a_size), time(0.0), totaltime(0.0)
127 BufferedPacket(u32 a_size):
128 data(a_size), time(0.0), totaltime(0.0)
130 SharedBuffer<u8> data; // Data of the packet, including headers
131 float time; // Seconds from buffering the packet or re-sending
132 float totaltime; // Seconds from buffering the packet
133 Address address; // Sender or destination
136 // This adds the base headers to the data and makes a packet out of it
137 BufferedPacket makePacket(Address &address, u8 *data, u32 datasize,
138 u32 protocol_id, u16 sender_peer_id, u8 channel);
139 BufferedPacket makePacket(Address &address, SharedBuffer<u8> &data,
140 u32 protocol_id, u16 sender_peer_id, u8 channel);
142 // Add the TYPE_ORIGINAL header to the data
143 SharedBuffer<u8> makeOriginalPacket(
144 SharedBuffer<u8> data);
146 // Split data in chunks and add TYPE_SPLIT headers to them
147 std::list<SharedBuffer<u8> > makeSplitPacket(
148 SharedBuffer<u8> data,
152 // Depending on size, make a TYPE_ORIGINAL or TYPE_SPLIT packet
153 // Increments split_seqnum if a split packet is made
154 std::list<SharedBuffer<u8> > makeAutoSplitPacket(
155 SharedBuffer<u8> data,
159 // Add the TYPE_RELIABLE header to the data
160 SharedBuffer<u8> makeReliablePacket(
161 SharedBuffer<u8> data,
164 struct IncomingSplitPacket
166 IncomingSplitPacket()
171 // Key is chunk number, value is data without headers
172 std::map<u16, SharedBuffer<u8> > chunks;
174 float time; // Seconds from adding
175 bool reliable; // If true, isn't deleted on timeout
179 return (chunks.size() == chunk_count);
186 A packet is sent through a channel to a peer with a basic header:
187 TODO: Should we have a receiver_peer_id also?
190 [4] u16 sender_peer_id
194 value 0 (PEER_ID_INEXISTENT) is reserved for making new connections
195 value 1 (PEER_ID_SERVER) is reserved for server
196 these constants are defined in constants.h
198 The lower the number, the higher the priority is.
199 Only channels 0, 1 and 2 exist.
201 #define BASE_HEADER_SIZE 7
202 #define CHANNEL_COUNT 3
206 CONTROL: This is a packet used by the protocol.
207 - When this is processed, nothing is handed to the user.
211 controltype and data description:
214 CONTROLTYPE_SET_PEER_ID
217 - There is no actual reply, but this can be sent in a reliable
218 packet to get a reply
221 #define TYPE_CONTROL 0
222 #define CONTROLTYPE_ACK 0
223 #define CONTROLTYPE_SET_PEER_ID 1
224 #define CONTROLTYPE_PING 2
225 #define CONTROLTYPE_DISCO 3
227 ORIGINAL: This is a plain packet with no control and no error
229 - When this is processed, it is directly handed to the user.
233 #define TYPE_ORIGINAL 1
234 #define ORIGINAL_HEADER_SIZE 1
236 SPLIT: These are sequences of packets forming one bigger piece of
238 - When processed and all the packet_nums 0...packet_count-1 are
239 present (this should be buffered), the resulting data shall be
240 directly handed to the user.
241 - If the data fails to come up in a reasonable time, the buffer shall
242 be silently discarded.
243 - These can be sent as-is or atop of a RELIABLE packet stream.
252 RELIABLE: Delivery of all RELIABLE packets shall be forced by ACKs,
253 and they shall be delivered in the same order as sent. This is done
254 with a buffer in the receiving and transmitting end.
255 - When this is processed, the contents of each packet is recursively
256 processed as packets.
262 #define TYPE_RELIABLE 3
263 #define RELIABLE_HEADER_SIZE 3
264 //#define SEQNUM_INITIAL 0x10
265 #define SEQNUM_INITIAL 65500
268 A buffer which stores reliable packets and sorts them internally
269 for fast access to the smallest one.
272 typedef std::list<BufferedPacket>::iterator RPBSearchResult;
274 class ReliablePacketBuffer
277 ReliablePacketBuffer();
281 RPBSearchResult findPacket(u16 seqnum);
282 RPBSearchResult notFound();
283 bool getFirstSeqnum(u16 *result);
284 BufferedPacket popFirst();
285 BufferedPacket popSeqnum(u16 seqnum);
286 void insert(BufferedPacket &p);
287 void incrementTimeouts(float dtime);
288 void resetTimedOuts(float timeout);
289 bool anyTotaltimeReached(float timeout);
290 std::list<BufferedPacket> getTimedOuts(float timeout);
293 std::list<BufferedPacket> m_list;
298 A buffer for reconstructing split packets
301 class IncomingSplitBuffer
304 ~IncomingSplitBuffer();
306 Returns a reference counted buffer of length != 0 when a full split
307 packet is constructed. If not, returns one of length 0.
309 SharedBuffer<u8> insert(BufferedPacket &p, bool reliable);
311 void removeUnreliableTimedOuts(float dtime, float timeout);
315 std::map<u16, IncomingSplitPacket*> m_buf;
325 u16 next_outgoing_seqnum;
326 u16 next_incoming_seqnum;
327 u16 next_outgoing_split_seqnum;
329 // This is for buffering the incoming packets that are coming in
331 ReliablePacketBuffer incoming_reliables;
332 // This is for buffering the sent packets so that the sender can
333 // re-send them if no ACK is received
334 ReliablePacketBuffer outgoing_reliables;
336 IncomingSplitBuffer incoming_splits;
347 virtual ~PeerHandler()
352 This is called after the Peer has been inserted into the
353 Connection's peer container.
355 virtual void peerAdded(Peer *peer) = 0;
357 This is called before the Peer has been removed from the
358 Connection's peer container.
360 virtual void deletingPeer(Peer *peer, bool timeout) = 0;
367 Peer(u16 a_id, Address a_address);
371 Calculates avg_rtt and resend_timeout.
373 rtt=-1 only recalculates resend_timeout
375 void reportRTT(float rtt);
377 Channel channels[CHANNEL_COUNT];
379 // Address of the peer
381 // Unique id of the peer
383 // Seconds from last receive
384 float timeout_counter;
387 // This is changed dynamically
388 float resend_timeout;
389 // Updated when an ACK is received
391 // This is set to true when the peer has actually sent something
392 // with the id we have given to it
393 bool has_sent_with_id;
395 float m_sendtime_accu;
396 float m_max_packets_per_second;
400 // Updated from configuration by Connection
401 float congestion_control_aim_rtt;
402 float congestion_control_max_rate;
403 float congestion_control_min_rate;
411 struct OutgoingPacket
415 SharedBuffer<u8> data;
418 OutgoingPacket(u16 peer_id_, u8 channelnum_, SharedBuffer<u8> data_,
421 channelnum(channelnum_),
428 enum ConnectionEventType{
430 CONNEVENT_DATA_RECEIVED,
431 CONNEVENT_PEER_ADDED,
432 CONNEVENT_PEER_REMOVED,
433 CONNEVENT_BIND_FAILED,
436 struct ConnectionEvent
438 enum ConnectionEventType type;
444 ConnectionEvent(): type(CONNEVENT_NONE) {}
446 std::string describe()
450 return "CONNEVENT_NONE";
451 case CONNEVENT_DATA_RECEIVED:
452 return "CONNEVENT_DATA_RECEIVED";
453 case CONNEVENT_PEER_ADDED:
454 return "CONNEVENT_PEER_ADDED";
455 case CONNEVENT_PEER_REMOVED:
456 return "CONNEVENT_PEER_REMOVED";
457 case CONNEVENT_BIND_FAILED:
458 return "CONNEVENT_BIND_FAILED";
460 return "Invalid ConnectionEvent";
463 void dataReceived(u16 peer_id_, SharedBuffer<u8> data_)
465 type = CONNEVENT_DATA_RECEIVED;
469 void peerAdded(u16 peer_id_, Address address_)
471 type = CONNEVENT_PEER_ADDED;
475 void peerRemoved(u16 peer_id_, bool timeout_, Address address_)
477 type = CONNEVENT_PEER_REMOVED;
484 type = CONNEVENT_BIND_FAILED;
488 enum ConnectionCommandType{
498 struct ConnectionCommand
500 enum ConnectionCommandType type;
508 ConnectionCommand(): type(CONNCMD_NONE) {}
510 void serve(u16 port_)
512 type = CONNCMD_SERVE;
515 void connect(Address address_)
517 type = CONNCMD_CONNECT;
522 type = CONNCMD_DISCONNECT;
524 void send(u16 peer_id_, u8 channelnum_,
525 SharedBuffer<u8> data_, bool reliable_)
529 channelnum = channelnum_;
531 reliable = reliable_;
533 void sendToAll(u8 channelnum_, SharedBuffer<u8> data_, bool reliable_)
535 type = CONNCMD_SEND_TO_ALL;
536 channelnum = channelnum_;
538 reliable = reliable_;
540 void deletePeer(u16 peer_id_)
542 type = CONNCMD_DELETE_PEER;
547 class Connection: public JThread
550 Connection(u32 protocol_id, u32 max_packet_size, float timeout, bool ipv6);
551 Connection(u32 protocol_id, u32 max_packet_size, float timeout, bool ipv6,
552 PeerHandler *peerhandler);
558 ConnectionEvent getEvent();
559 ConnectionEvent waitEvent(u32 timeout_ms);
560 void putCommand(ConnectionCommand &c);
562 void SetTimeoutMs(int timeout){ m_bc_receive_timeout = timeout; }
563 void Serve(unsigned short port);
564 void Connect(Address address);
567 u32 Receive(u16 &peer_id, SharedBuffer<u8> &data);
568 void SendToAll(u8 channelnum, SharedBuffer<u8> data, bool reliable);
569 void Send(u16 peer_id, u8 channelnum, SharedBuffer<u8> data, bool reliable);
570 void RunTimeouts(float dtime); // dummy
571 u16 GetPeerID(){ return m_peer_id; }
572 Address GetPeerAddress(u16 peer_id);
573 float GetPeerAvgRTT(u16 peer_id);
574 void DeletePeer(u16 peer_id);
577 void putEvent(ConnectionEvent &e);
578 void processCommand(ConnectionCommand &c);
579 void send(float dtime);
581 void runTimeouts(float dtime);
582 void serve(u16 port);
583 void connect(Address address);
585 void sendToAll(u8 channelnum, SharedBuffer<u8> data, bool reliable);
586 void send(u16 peer_id, u8 channelnum, SharedBuffer<u8> data, bool reliable);
587 void sendAsPacket(u16 peer_id, u8 channelnum,
588 SharedBuffer<u8> data, bool reliable);
589 void rawSendAsPacket(u16 peer_id, u8 channelnum,
590 SharedBuffer<u8> data, bool reliable);
591 void rawSend(const BufferedPacket &packet);
592 Peer* getPeer(u16 peer_id);
593 Peer* getPeerNoEx(u16 peer_id);
594 std::list<Peer*> getPeers();
595 bool getFromBuffers(u16 &peer_id, SharedBuffer<u8> &dst);
596 // Returns next data from a buffer if possible
597 // If found, returns true; if not, false.
598 // If found, sets peer_id and dst
599 bool checkIncomingBuffers(Channel *channel, u16 &peer_id,
600 SharedBuffer<u8> &dst);
602 Processes a packet with the basic header stripped out.
604 packetdata: Data in packet (with no base headers)
605 peer_id: peer id of the sender of the packet in question
606 channelnum: channel on which the packet was sent
607 reliable: true if recursing into a reliable packet
609 SharedBuffer<u8> processPacket(Channel *channel,
610 SharedBuffer<u8> packetdata, u16 peer_id,
611 u8 channelnum, bool reliable);
612 bool deletePeer(u16 peer_id, bool timeout);
614 Queue<OutgoingPacket> m_outgoing_queue;
615 MutexedQueue<ConnectionEvent> m_event_queue;
616 MutexedQueue<ConnectionCommand> m_command_queue;
619 u32 m_max_packet_size;
624 std::map<u16, Peer*> m_peers;
625 JMutex m_peers_mutex;
627 // Backwards compatibility
628 PeerHandler *m_bc_peerhandler;
629 int m_bc_receive_timeout;
631 void SetPeerID(u16 id){ m_peer_id = id; }
632 u32 GetProtocolID(){ return m_protocol_id; }
633 void PrintInfo(std::ostream &out);
635 std::string getDesc();