Minetest 5.10.0-dev
 
Loading...
Searching...
No Matches
internal.h
Go to the documentation of this file.
1/*
2Minetest
3Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>
4
5This program is free software; you can redistribute it and/or modify
6it under the terms of the GNU Lesser General Public License as published by
7the Free Software Foundation; either version 2.1 of the License, or
8(at your option) any later version.
9
10This program is distributed in the hope that it will be useful,
11but WITHOUT ANY WARRANTY; without even the implied warranty of
12MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13GNU Lesser General Public License for more details.
14
15You should have received a copy of the GNU Lesser General Public License along
16with this program; if not, write to the Free Software Foundation, Inc.,
1751 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18*/
19
20#pragma once
21
22#include "network/mtp/impl.h"
23
24// Constant that differentiates the protocol from random data and other protocols
25#define PROTOCOL_ID 0x4f457403
26
27#define MAX_UDP_PEERS 65535
28
29/*
30=== NOTES ===
31
32A packet is sent through a channel to a peer with a basic header:
33 Header (7 bytes):
34 [0] u32 protocol_id
35 [4] session_t sender_peer_id
36 [6] u8 channel
37sender_peer_id:
38 Unique to each peer.
39 value 0 (PEER_ID_INEXISTENT) is reserved for making new connections
40 value 1 (PEER_ID_SERVER) is reserved for server
41 these constants are defined in constants.h
42channel:
43 Channel numbers have no intrinsic meaning. Currently only 0, 1, 2 exist.
44*/
45#define BASE_HEADER_SIZE 7
46#define CHANNEL_COUNT 3
47
48/*
49Packet types:
50
51CONTROL: This is a packet used by the protocol.
52- When this is processed, nothing is handed to the user.
53 Header (2 byte):
54 [0] u8 type
55 [1] u8 controltype
56controltype and data description:
57 CONTROLTYPE_ACK
58 [2] u16 seqnum
59 CONTROLTYPE_SET_PEER_ID
60 [2] session_t peer_id_new
61 CONTROLTYPE_PING
62 - There is no actual reply, but this can be sent in a reliable
63 packet to get a reply
64 CONTROLTYPE_DISCO
65*/
72
73/*
74ORIGINAL: This is a plain packet with no control and no error
75checking at all.
76- When this is processed, it is directly handed to the user.
77 Header (1 byte):
78 [0] u8 type
79*/
80//#define TYPE_ORIGINAL 1
81#define ORIGINAL_HEADER_SIZE 1
82
83/*
84SPLIT: These are sequences of packets forming one bigger piece of
85data.
86- When processed and all the packet_nums 0...packet_count-1 are
87 present (this should be buffered), the resulting data shall be
88 directly handed to the user.
89- If the data fails to come up in a reasonable time, the buffer shall
90 be silently discarded.
91- These can be sent as-is or atop of a RELIABLE packet stream.
92 Header (7 bytes):
93 [0] u8 type
94 [1] u16 seqnum
95 [3] u16 chunk_count
96 [5] u16 chunk_num
97*/
98//#define TYPE_SPLIT 2
99
100/*
101RELIABLE: Delivery of all RELIABLE packets shall be forced by ACKs,
102and they shall be delivered in the same order as sent. This is done
103with a buffer in the receiving and transmitting end.
104- When this is processed, the contents of each packet is recursively
105 processed as packets.
106 Header (3 bytes):
107 [0] u8 type
108 [1] u16 seqnum
109
110*/
111//#define TYPE_RELIABLE 3
112#define RELIABLE_HEADER_SIZE 3
113#define SEQNUM_INITIAL 65500
114#define SEQNUM_MAX 65535
115
116namespace con
117{
118
119
127
128inline bool seqnum_higher(u16 totest, u16 base)
129{
130 if (totest > base)
131 {
132 if ((totest - base) > (SEQNUM_MAX/2))
133 return false;
134
135 return true;
136 }
137
138 if ((base - totest) > (SEQNUM_MAX/2))
139 return true;
140
141 return false;
142}
143
144inline bool seqnum_in_window(u16 seqnum, u16 next,u16 window_size)
145{
146 u16 window_start = next;
147 u16 window_end = ( next + window_size ) % (SEQNUM_MAX+1);
148
149 if (window_start < window_end) {
150 return ((seqnum >= window_start) && (seqnum < window_end));
151 }
152
153
154 return ((seqnum < window_end) || (seqnum >= window_start));
155}
156
157inline float CALC_DTIME(u64 lasttime, u64 curtime)
158{
159 float value = (curtime - lasttime) / 1000.0f;
160 return MYMAX(MYMIN(value, 0.1f), 0.0f);
161}
162
163/* Exceptions */
164
166{
167public:
168 NotFoundException(const char *s) : BaseException(s) {}
169};
170
172{
173public:
175};
176
178{
179public:
180 ProcessedQueued(const char *s) : BaseException(s) {}
181};
182
184{
185public:
187};
188
189
190/*
191 Struct for all kinds of packets. Includes following data:
192 BASE_HEADER
193 u8[] packet data (usually copied from SharedBuffer<u8>)
194*/
196 BufferedPacket(u32 a_size)
197 {
198 m_data.resize(a_size);
199 data = &m_data[0];
200 }
201
203
204 u16 getSeqnum() const;
205
206 inline size_t size() const { return m_data.size(); }
207
208 u8 *data; // Direct memory access
209 float time = 0.0f; // Seconds from buffering the packet or re-sending
210 float totaltime = 0.0f; // Seconds from buffering the packet
212 Address address; // Sender or destination
213 unsigned int resend_count = 0;
214
215private:
216 std::vector<u8> m_data; // Data of the packet, including headers
217};
218
219
220// This adds the base headers to the data and makes a packet out of it
221BufferedPacketPtr makePacket(const Address &address, const SharedBuffer<u8> &data,
222 u32 protocol_id, session_t sender_peer_id, u8 channel);
223
224// Depending on size, make a TYPE_ORIGINAL or TYPE_SPLIT packet
225// Increments split_seqnum if a split packet is made
226void makeAutoSplitPacket(const SharedBuffer<u8> &data, u32 chunksize_max,
227 u16 &split_seqnum, std::list<SharedBuffer<u8>> *list);
228
229// Add the TYPE_RELIABLE header to the data
231
233{
234 IncomingSplitPacket(u32 cc, bool r):
235 chunk_count(cc), reliable(r) {}
236
238
239 float time = 0.0f; // Seconds from adding
241 bool reliable; // If true, isn't deleted on timeout
242
243 bool allReceived() const
244 {
245 return (chunks.size() == chunk_count);
246 }
247 bool insert(u32 chunk_num, SharedBuffer<u8> &chunkdata);
249
250private:
251 // Key is chunk number, value is data without headers
252 std::map<u16, SharedBuffer<u8>> chunks;
253};
254
255/*
256 A buffer which stores reliable packets and sorts them internally
257 for fast access to the smallest one.
258*/
259
261{
262public:
263 bool getFirstSeqnum(u16 &result);
264
266 BufferedPacketPtr popSeqnum(u16 seqnum);
267 void insert(BufferedPacketPtr &p_ptr, u16 next_expected);
268
269 void incrementTimeouts(float dtime);
270 u32 getTimedOuts(float timeout);
271 // timeout relative to last resend
272 std::vector<ConstSharedPtr<BufferedPacket>> getResend(float timeout, u32 max_packets);
273
274 void print();
275 bool empty();
276 u32 size();
277
278
279private:
280 typedef std::list<BufferedPacketPtr>::iterator FindResult;
281
282 FindResult findPacketNoLock(u16 seqnum);
283
284 std::list<BufferedPacketPtr> m_list;
285
287
288 std::mutex m_list_mutex;
289};
290
291/*
292 A buffer for reconstructing split packets
293*/
294
296{
297public:
299
300 /*
301 Returns a reference counted buffer of length != 0 when a full split
302 packet is constructed. If not, returns one of length 0.
303 */
304 SharedBuffer<u8> insert(BufferedPacketPtr &p_ptr, bool reliable);
305
306 void removeUnreliableTimedOuts(float dtime, float timeout);
307
308private:
309 // Key is seqnum
310 std::map<u16, IncomingSplitPacket*> m_buf;
311
312 std::mutex m_map_mutex;
313};
314
327
328// This is very similar to ConnectionEvent
356
357/*
358 * Window sizes to use, in packets (not bytes!).
359 * 0xFFFF is theoretical maximum. don't think about
360 * touching it, the less you're away from it the more likely data corruption
361 * will occur
362 *
363 * Note: window sizes directly translate to maximum possible throughput, e.g.
364 * (2048 * 512 bytes) / 33ms = 15 MiB/s
365 */
366
367// Due to backwards compatibility we have different window sizes for what we'll
368// accept from peers vs. what we use for sending.
369#define MAX_RELIABLE_WINDOW_SIZE 0x8000
370#define MAX_RELIABLE_WINDOW_SIZE_SEND 2048
371/* starting value for window size */
372#define START_RELIABLE_WINDOW_SIZE 64
373/* minimum value for window size */
374#define MIN_RELIABLE_WINDOW_SIZE 32
375
377{
378
379public:
382
383 u16 getOutgoingSequenceNumber(bool& successful);
385 bool putBackSequenceNumber(u16);
386
388 void setNextSplitSeqNum(u16 seqnum);
389
390 // This is for buffering the incoming packets that are coming in
391 // the wrong order
393 // This is for buffering the sent packets so that the sender can
394 // re-send them if no ACK is received
396
397 //queued reliable packets
398 std::queue<BufferedPacketPtr> queued_reliables;
399
400 //queue commands prior splitting to packets
401 std::deque<ConnectionCommandPtr> queued_commands;
402
404
405 Channel() = default;
406 ~Channel() = default;
407
408 void UpdatePacketLossCounter(unsigned int count);
410 void UpdateBytesSent(unsigned int bytes,unsigned int packages=1);
411 void UpdateBytesLost(unsigned int bytes);
412 void UpdateBytesReceived(unsigned int bytes);
413
414 void UpdateTimers(float dtime);
415
420
425
430
437
438 u16 getWindowSize() const { return m_window_size; };
439
444
445private:
448
450
453
454 unsigned int current_packet_loss = 0;
455 unsigned int current_packet_too_late = 0;
458
459 unsigned int current_bytes_transfered = 0;
460 unsigned int current_bytes_received = 0;
461 unsigned int current_bytes_lost = 0;
462 float max_kbps = 0.0f;
463 float cur_kbps = 0.0f;
464 float avg_kbps = 0.0f;
465 float max_incoming_kbps = 0.0f;
466 float cur_incoming_kbps = 0.0f;
467 float avg_incoming_kbps = 0.0f;
468 float max_kbps_lost = 0.0f;
469 float cur_kbps_lost = 0.0f;
470 float avg_kbps_lost = 0.0f;
471 float bpm_counter = 0.0f;
472
473 unsigned int rate_samples = 0;
474};
475
476
477class UDPPeer final : public Peer
478{
479public:
480
481 friend class PeerHelper;
484 friend class Connection;
485
486 UDPPeer(session_t id, const Address &address, Connection *connection);
487 virtual ~UDPPeer() = default;
488
490 unsigned int max_packet_size) override;
491
492 virtual const Address &getAddress() const override {
493 return address;
494 }
495
496 u16 getNextSplitSequenceNumber(u8 channel) override;
497 void setNextSplitSequenceNumber(u8 channel, u16 seqnum) override;
498
500 bool reliable) override;
501
502 bool isTimedOut(float timeout, std::string &reason) override;
503
504protected:
505 /*
506 Calculates avg_rtt and resend_timeout.
507 rtt=-1 only recalculates resend_timeout
508 */
509 void reportRTT(float rtt) override;
510
511 void RunCommandQueues(
512 unsigned int max_packet_size,
513 unsigned int maxtransfer);
514
517
518 void setResendTimeout(float timeout)
520
521 bool Ping(float dtime, SharedBuffer<u8>& data) override;
522
525private:
526 // This is changed dynamically
527 float resend_timeout = 0.5;
528
531 unsigned int max_packet_size);
532};
533
534}
#define DISABLE_CLASS_COPY(C)
Definition basic_macros.h:41
#define MYMIN(a, b)
Definition basic_macros.h:24
#define MYMAX(a, b)
Definition basic_macros.h:26
Definition address.h:43
Definition exceptions.h:27
Definition pointer.h:44
Definition networkpacket.h:27
Definition pointer.h:162
Definition internal.h:377
void UpdateBytesLost(unsigned int bytes)
Definition impl.cpp:715
u16 getOutgoingSequenceNumber(bool &successful)
Definition impl.cpp:648
u16 m_window_size
Definition internal.h:447
unsigned int current_packet_loss
Definition internal.h:454
void UpdatePacketTooLateCounter()
Definition impl.cpp:728
float getAvgLossRateKB()
Definition internal.h:433
u16 readNextIncomingSeqNum()
Definition impl.cpp:623
float getCurrentLossRateKB()
Definition internal.h:421
float cur_incoming_kbps
Definition internal.h:466
void UpdateTimers(float dtime)
Definition impl.cpp:734
u16 getWindowSize() const
Definition internal.h:438
u16 next_outgoing_split_seqnum
Definition internal.h:452
unsigned int current_packet_too_late
Definition internal.h:455
float bpm_counter
Definition internal.h:471
float avg_incoming_kbps
Definition internal.h:467
float getMaxLossRateKB()
Definition internal.h:423
unsigned int current_packet_successful
Definition internal.h:456
float max_kbps
Definition internal.h:462
float max_incoming_kbps
Definition internal.h:465
float getAvgIncomingRateKB()
Definition internal.h:435
ReliablePacketBuffer outgoing_reliables_sent
Definition internal.h:395
~Channel()=default
float getAvgDownloadRateKB()
Definition internal.h:431
std::deque< ConnectionCommandPtr > queued_commands
Definition internal.h:401
float getMaxIncomingRateKB()
Definition internal.h:428
void UpdateBytesSent(unsigned int bytes, unsigned int packages=1)
Definition impl.cpp:703
float avg_kbps_lost
Definition internal.h:470
u16 incNextIncomingSeqNum()
Definition impl.cpp:629
bool putBackSequenceNumber(u16)
Definition impl.cpp:693
void UpdateBytesReceived(unsigned int bytes)
Definition impl.cpp:710
ReliablePacketBuffer incoming_reliables
Definition internal.h:392
float packet_loss_counter
Definition internal.h:457
u16 readNextSplitSeqNum()
Definition impl.cpp:637
float max_kbps_lost
Definition internal.h:468
u16 next_incoming_seqnum
Definition internal.h:449
unsigned int current_bytes_transfered
Definition internal.h:459
float avg_kbps
Definition internal.h:464
void setWindowSize(long size)
Definition internal.h:440
IncomingSplitBuffer incoming_splits
Definition internal.h:403
unsigned int current_bytes_lost
Definition internal.h:461
void UpdatePacketLossCounter(unsigned int count)
Definition impl.cpp:722
float getCurrentDownloadRateKB()
Definition internal.h:416
std::mutex m_internal_mutex
Definition internal.h:446
float getMaxDownloadRateKB()
Definition internal.h:418
float getCurrentIncomingRateKB()
Definition internal.h:426
void setNextSplitSeqNum(u16 seqnum)
Definition impl.cpp:642
float cur_kbps
Definition internal.h:463
std::queue< BufferedPacketPtr > queued_reliables
Definition internal.h:398
u16 next_outgoing_seqnum
Definition internal.h:451
unsigned int current_bytes_received
Definition internal.h:460
u16 readOutgoingSequenceNumber()
Definition impl.cpp:687
float cur_kbps_lost
Definition internal.h:469
Channel()=default
unsigned int rate_samples
Definition internal.h:473
Definition threads.h:114
Definition threads.h:56
Definition impl.h:238
Definition internal.h:184
IncomingDataCorruption(const char *s)
Definition internal.h:186
Definition internal.h:296
std::mutex m_map_mutex
Definition internal.h:312
std::map< u16, IncomingSplitPacket * > m_buf
Definition internal.h:310
SharedBuffer< u8 > insert(BufferedPacketPtr &p_ptr, bool reliable)
Definition impl.cpp:453
void removeUnreliableTimedOuts(float dtime, float timeout)
Definition impl.cpp:520
~IncomingSplitBuffer()
Definition impl.cpp:445
Definition internal.h:166
NotFoundException(const char *s)
Definition internal.h:168
Definition impl.h:44
Definition impl.h:110
Address address
Definition impl.h:199
std::mutex m_exclusive_access_mutex
Definition impl.h:192
Definition internal.h:178
ProcessedQueued(const char *s)
Definition internal.h:180
Definition internal.h:172
ProcessedSilentlyException(const char *s)
Definition internal.h:174
Definition internal.h:261
void incrementTimeouts(float dtime)
Definition impl.cpp:355
std::list< BufferedPacketPtr >::iterator FindResult
Definition internal.h:280
u16 m_oldest_non_answered_ack
Definition internal.h:286
BufferedPacketPtr popSeqnum(u16 seqnum)
Definition impl.cpp:230
u32 size()
Definition impl.cpp:189
std::vector< ConstSharedPtr< BufferedPacket > > getResend(float timeout, u32 max_packets)
Definition impl.cpp:376
std::mutex m_list_mutex
Definition internal.h:288
BufferedPacketPtr popFirst()
Definition impl.cpp:213
bool empty()
Definition impl.cpp:183
std::list< BufferedPacketPtr > m_list
Definition internal.h:284
void print()
Definition impl.cpp:172
u32 getTimedOuts(float timeout)
Definition impl.cpp:364
void insert(BufferedPacketPtr &p_ptr, u16 next_expected)
Definition impl.cpp:251
FindResult findPacketNoLock(u16 seqnum)
Definition impl.cpp:195
bool getFirstSeqnum(u16 &result)
Definition impl.cpp:204
Definition internal.h:478
bool processReliableSendCommand(ConnectionCommandPtr &c_ptr, unsigned int max_packet_size)
Definition impl.cpp:1066
void setNextSplitSequenceNumber(u8 channel, u16 seqnum) override
Definition impl.cpp:1207
void RunCommandQueues(unsigned int max_packet_size, unsigned int maxtransfer)
Definition impl.cpp:1169
void reportRTT(float rtt) override
Definition impl.cpp:996
bool isTimedOut(float timeout, std::string &reason) override
Definition impl.cpp:978
void PutReliableSendCommand(ConnectionCommandPtr &c, unsigned int max_packet_size) override
Definition impl.cpp:1035
UDPPeer(session_t id, const Address &address, Connection *connection)
Definition impl.cpp:971
bool m_pending_disconnect
Definition internal.h:524
Channel channels[CHANNEL_COUNT]
Definition internal.h:523
float resend_timeout
Definition internal.h:527
virtual const Address & getAddress() const override
Definition internal.h:492
u16 getNextSplitSequenceNumber(u8 channel) override
Definition impl.cpp:1201
virtual ~UDPPeer()=default
void setResendTimeout(float timeout)
Definition internal.h:518
float getResendTimeout()
Definition internal.h:515
bool Ping(float dtime, SharedBuffer< u8 > &data) override
Definition impl.cpp:1021
SharedBuffer< u8 > addSplitPacket(u8 channel, BufferedPacketPtr &toadd, bool reliable) override
Definition impl.cpp:1213
#define PEER_ID_INEXISTENT
Definition constants.h:34
#define MAX_RELIABLE_WINDOW_SIZE_SEND
Definition internal.h:370
#define SEQNUM_MAX
Definition internal.h:114
#define CHANNEL_COUNT
Definition internal.h:46
ControlType
Definition internal.h:66
@ CONTROLTYPE_PING
Definition internal.h:69
@ CONTROLTYPE_ACK
Definition internal.h:67
@ CONTROLTYPE_DISCO
Definition internal.h:70
@ CONTROLTYPE_SET_PEER_ID
Definition internal.h:68
#define MIN_RELIABLE_WINDOW_SIZE
Definition internal.h:374
#define SEQNUM_INITIAL
Definition internal.h:113
std::unique_lock< std::mutex > MutexAutoLock
Definition mutex_auto_lock.h:29
Definition client.h:72
bool seqnum_in_window(u16 seqnum, u16 next, u16 window_size)
Definition internal.h:144
SharedBuffer< u8 > makeReliablePacket(const SharedBuffer< u8 > &data, u16 seqnum)
Definition impl.cpp:154
PacketType
Definition internal.h:120
@ PACKET_TYPE_CONTROL
Definition internal.h:121
@ PACKET_TYPE_RELIABLE
Definition internal.h:124
@ PACKET_TYPE_MAX
Definition internal.h:125
@ PACKET_TYPE_SPLIT
Definition internal.h:123
@ PACKET_TYPE_ORIGINAL
Definition internal.h:122
void makeAutoSplitPacket(const SharedBuffer< u8 > &data, u32 chunksize_max, u16 &split_seqnum, std::list< SharedBuffer< u8 > > *list)
Definition impl.cpp:140
ConnectionCommandType
Definition internal.h:315
@ CONNCMD_RESEND_ONE
Definition internal.h:325
@ CONNCMD_CONNECT
Definition internal.h:318
@ CONNCMD_SEND
Definition internal.h:321
@ CONNCMD_SERVE
Definition internal.h:317
@ CONNCMD_DISCONNECT_PEER
Definition internal.h:320
@ CONNCMD_SEND_TO_ALL
Definition internal.h:322
@ CONNCMD_NONE
Definition internal.h:316
@ CONCMD_CREATE_PEER
Definition internal.h:324
@ CONNCMD_DISCONNECT
Definition internal.h:319
@ CONCMD_ACK
Definition internal.h:323
std::shared_ptr< BufferedPacket > BufferedPacketPtr
Definition impl.h:105
float CALC_DTIME(u64 lasttime, u64 curtime)
Definition internal.h:157
std::shared_ptr< ConnectionCommand > ConnectionCommandPtr
Definition impl.h:102
BufferedPacketPtr makePacket(const Address &address, const SharedBuffer< u8 > &data, u32 protocol_id, session_t sender_peer_id, u8 channel)
Definition impl.cpp:71
bool seqnum_higher(u16 totest, u16 base)
Definition internal.h:128
u16 session_t
Definition networkprotocol.h:259
#define rangelim(d, min, max)
Definition numeric.h:33
Definition internal.h:195
u8 * data
Definition internal.h:208
Address address
Definition internal.h:212
size_t size() const
Definition internal.h:206
u64 absolute_send_time
Definition internal.h:211
unsigned int resend_count
Definition internal.h:213
float time
Definition internal.h:209
std::vector< u8 > m_data
Definition internal.h:216
u16 getSeqnum() const
Definition impl.cpp:63
float totaltime
Definition internal.h:210
BufferedPacket(u32 a_size)
Definition internal.h:196
Definition internal.h:330
static ConnectionCommandPtr connect(Address address)
Definition impl.cpp:559
static ConnectionCommandPtr ack(session_t peer_id, u8 channelnum, const Buffer< u8 > &data)
Definition impl.cpp:598
static ConnectionCommandPtr create(ConnectionCommandType type)
Definition impl.cpp:547
static ConnectionCommandPtr disconnect_peer(session_t peer_id)
Definition impl.cpp:571
u8 channelnum
Definition internal.h:334
static ConnectionCommandPtr createPeer(session_t peer_id, const Buffer< u8 > &data)
Definition impl.cpp:608
Buffer< u8 > data
Definition internal.h:335
Address address
Definition internal.h:332
bool reliable
Definition internal.h:336
ConnectionCommand(ConnectionCommandType type_)
Definition internal.h:351
static ConnectionCommandPtr disconnect()
Definition impl.cpp:566
bool raw
Definition internal.h:337
static ConnectionCommandPtr send(session_t peer_id, u8 channelnum, NetworkPacket *pkt, bool reliable)
Definition impl.cpp:587
session_t peer_id
Definition internal.h:333
const ConnectionCommandType type
Definition internal.h:331
static ConnectionCommandPtr resend_one(session_t peer_id)
Definition impl.cpp:578
DISABLE_CLASS_COPY(ConnectionCommand)
static ConnectionCommandPtr serve(Address address)
Definition impl.cpp:552
Definition internal.h:233
u32 chunk_count
Definition internal.h:240
bool allReceived() const
Definition internal.h:243
SharedBuffer< u8 > reassemble()
Definition impl.cpp:419
IncomingSplitPacket(u32 cc, bool r)
Definition internal.h:234
bool reliable
Definition internal.h:241
bool insert(u32 chunk_num, SharedBuffer< u8 > &chunkdata)
Definition impl.cpp:403
std::map< u16, SharedBuffer< u8 > > chunks
Definition internal.h:252
float time
Definition internal.h:239