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