Luanti 5.15.0-dev
 
Loading...
Searching...
No Matches
impl.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
8#include "network/socket.h"
9#include "constants.h"
10#include "util/pointer.h"
11#include "util/container.h"
12#include "porting.h"
13#include "network/address.h"
15#include <atomic>
16#include <cfloat>
17#include <vector>
18#include <memory>
19#include <map>
20
21namespace con
22{
23
24class ConnectionReceiveThread;
25class ConnectionSendThread;
26
27class Peer;
28
30{
31public:
32 PeerHelper() = default;
33 inline PeerHelper(Peer *peer) { *this = peer; }
35
37 inline Peer* operator->() const { return m_peer; }
38 inline Peer* operator&() const { return m_peer; }
39
40 inline bool operator!() { return !m_peer; }
41 inline bool operator!=(std::nullptr_t) { return !!m_peer; }
42
43private:
44 Peer *m_peer = nullptr;
45};
46
47/*
48 Connection
49*/
50
58
59struct ConnectionEvent;
60typedef std::shared_ptr<ConnectionEvent> ConnectionEventPtr;
61
62// This is very similar to ConnectionCommand
86
87struct ConnectionCommand;
88typedef std::shared_ptr<ConnectionCommand> ConnectionCommandPtr;
89
90struct BufferedPacket;
91typedef std::shared_ptr<BufferedPacket> BufferedPacketPtr;
92
93class Connection;
94class PeerHandler;
95
96class Peer : public IPeer {
97 public:
98 friend class PeerHelper;
99
100 virtual ~Peer() {
102 FATAL_ERROR_IF(m_usage != 0, "Reference counting failure");
103 }
104
105 void Drop();
106
108 unsigned int max_packet_size) {};
109
118
119 bool isHalfOpen() const {
121 return m_half_open;
122 }
125 m_half_open = false;
126 }
127
128 virtual bool isTimedOut(float timeout, std::string &reason);
129
131
132 virtual u16 getNextSplitSequenceNumber(u8 channel) { return 0; };
133 virtual void setNextSplitSequenceNumber(u8 channel, u16 seqnum) {};
135 bool reliable)
136 {
137 FATAL_ERROR("unimplemented in abstract class");
138 }
139
140 virtual bool Ping(float dtime, SharedBuffer<u8>& data) { return false; };
141
142 virtual float getStat(rtt_stat_type type) const {
143 switch (type) {
144 case MIN_RTT:
145 return m_rtt.min_rtt;
146 case MAX_RTT:
147 return m_rtt.max_rtt;
148 case AVG_RTT:
149 return m_rtt.avg_rtt;
150 case MIN_JITTER:
151 return m_rtt.jitter_min;
152 case MAX_JITTER:
153 return m_rtt.jitter_max;
154 case AVG_JITTER:
155 return m_rtt.jitter_avg;
156 }
157 return -1;
158 }
159
160 protected:
161 Peer(session_t id, const Address &address, Connection *connection) :
162 IPeer(id),
163 m_connection(connection),
165 m_last_timeout_check(porting::getTimeMs())
166 {
167 }
168
169 virtual void reportRTT(float rtt) {};
170
171 void RTTStatistics(float rtt,
172 const std::string &profiler_id = "",
173 unsigned int num_samples = 1000);
174
175 bool IncUseCount();
176 void DecUseCount();
177
178 mutable std::mutex m_exclusive_access_mutex;
179
180 bool m_pending_deletion = false;
181
183
184 // Address of the peer
186
187 // Ping timer
188 float m_ping_timer = 0.0f;
189
190 private:
191 struct rttstats {
192 float jitter_min = FLT_MAX;
193 float jitter_max = 0.0f;
194 float jitter_avg = -1.0f;
195 float min_rtt = FLT_MAX;
196 float max_rtt = 0.0f;
197 float avg_rtt = -1.0f;
198 };
199
201 float m_last_rtt = -1.0f;
202
203 /*
204 Until the peer has communicated with us using their assigned peer id
205 the connection is considered half-open.
206 During this time we inhibit re-sending any reliables or pings. This
207 is to avoid spending too many resources on a potential DoS attack
208 and to make sure Minetest servers are not useful for UDP amplificiation.
209 */
210 bool m_half_open = true;
211
212 // current usage count
213 unsigned int m_usage = 0;
214
215 // Seconds from last receive
216 float m_timeout_counter = 0.0f;
217
219};
220
221class UDPPeer;
222
223class Connection final : public IConnection
224{
225public:
228
229 Connection(u32 max_packet_size, float timeout, bool ipv6,
230 PeerHandler *peerhandler);
231 ~Connection();
232
233 /* Interface */
234 ConnectionEventPtr waitEvent(u32 timeout_ms);
235
237
238 void Serve(Address bind_addr);
239 void Connect(Address address);
240 bool Connected();
241 void Disconnect();
242 bool ReceiveTimeoutMs(NetworkPacket *pkt, u32 timeout_ms);
243 void Send(session_t peer_id, u8 channelnum, NetworkPacket *pkt, bool reliable);
244 session_t GetPeerID() const { return m_peer_id; }
246 float getPeerStat(session_t peer_id, rtt_stat_type type);
247 float getLocalStat(rate_stat_type type);
248 u32 GetProtocolID() const { return m_protocol_id; };
249 const std::string getDesc();
250 void DisconnectPeer(session_t peer_id);
251
252protected:
254 session_t lookupPeer(const Address& sender);
255
256 session_t createPeer(const Address& sender, int fd);
257 UDPPeer* createServerPeer(const Address& sender);
258 bool deletePeer(session_t peer_id, bool timeout);
259
260 void SetPeerID(session_t id);
261
262 void doResendOne(session_t peer_id);
263
264 void sendAck(session_t peer_id, u8 channelnum, u16 seqnum);
265
266 std::vector<session_t> getPeerIDs()
267 {
269 return m_peer_ids;
270 }
271
272 u32 getActiveCount();
273
275 // Command queue: user -> SendThread
277
279
280 void TriggerSend();
281
283 {
284 return getPeerNoEx(PEER_ID_SERVER) != nullptr;
285 }
286private:
287 // Event queue: ReceiveThread -> user
289
292
293 std::map<session_t, Peer *> m_peers;
294 std::vector<session_t> m_peer_ids;
295 std::mutex m_peers_mutex;
296
297 std::unique_ptr<ConnectionSendThread> m_sendThread;
298 std::unique_ptr<ConnectionReceiveThread> m_receiveThread;
299
300 mutable std::mutex m_info_mutex;
301
302 // Backwards compatibility
304
305 std::atomic<bool> m_shutting_down = false;
306};
307
308} // namespace
Definition address.h:27
Definition pointer.h:15
Definition container.h:126
Definition networkpacket.h:16
Definition pointer.h:132
Definition socket.h:15
Definition threads.h:100
Definition threads.h:41
Definition impl.h:224
UDPPeer * createServerPeer(const Address &sender)
Definition impl.cpp:1665
std::map< session_t, Peer * > m_peers
Definition impl.h:293
u32 GetProtocolID() const
Definition impl.h:248
Address GetPeerAddress(session_t peer_id)
Definition impl.cpp:1520
void TriggerSend()
Definition impl.cpp:1332
std::mutex m_peers_mutex
Definition impl.h:295
float getPeerStat(session_t peer_id, rtt_stat_type type)
Definition impl.cpp:1529
UDPSocket m_udpSocket
Definition impl.h:274
PeerHelper getPeerNoEx(session_t peer_id)
Definition impl.cpp:1337
bool deletePeer(session_t peer_id, bool timeout)
Definition impl.cpp:1383
bool ConnectedToServer()
Definition impl.h:282
Connection(u32 max_packet_size, float timeout, bool ipv6, PeerHandler *peerhandler)
Definition impl.cpp:1286
void Connect(Address address)
Definition impl.cpp:1429
MutexedQueue< ConnectionCommandPtr > m_command_queue
Definition impl.h:276
void DisconnectPeer(session_t peer_id)
Definition impl.cpp:1628
u32 getActiveCount()
Definition impl.cpp:1368
ConnectionEventPtr waitEvent(u32 timeout_ms)
Definition impl.cpp:1407
u32 m_protocol_id
Definition impl.h:291
session_t lookupPeer(const Address &sender)
Definition impl.cpp:1353
session_t createPeer(const Address &sender, int fd)
Definition impl.cpp:1572
void sendAck(session_t peer_id, u8 channelnum, u16 seqnum)
Definition impl.cpp:1647
std::atomic< bool > m_shutting_down
Definition impl.h:305
bool ReceiveTimeoutMs(NetworkPacket *pkt, u32 timeout_ms)
Definition impl.cpp:1456
void putEvent(ConnectionEventPtr e)
Definition impl.cpp:1326
float getLocalStat(rate_stat_type type)
Definition impl.cpp:1537
std::mutex m_info_mutex
Definition impl.h:300
std::unique_ptr< ConnectionSendThread > m_sendThread
Definition impl.h:297
void Serve(Address bind_addr)
Definition impl.cpp:1424
session_t GetPeerID() const
Definition impl.h:244
void Send(session_t peer_id, u8 channelnum, NetworkPacket *pkt, bool reliable)
Definition impl.cpp:1503
bool Connected()
Definition impl.cpp:1434
session_t m_peer_id
Definition impl.h:290
void putCommand(ConnectionCommandPtr c)
Definition impl.cpp:1416
MutexedQueue< ConnectionEventPtr > m_event_queue
Definition impl.h:288
void SetPeerID(session_t id)
Definition impl.cpp:1633
~Connection()
Definition impl.cpp:1307
void doResendOne(session_t peer_id)
Definition impl.cpp:1641
std::unique_ptr< ConnectionReceiveThread > m_receiveThread
Definition impl.h:298
std::vector< session_t > m_peer_ids
Definition impl.h:294
PeerHandler * m_bc_peerhandler
Definition impl.h:303
void Disconnect()
Definition impl.cpp:1451
const std::string getDesc()
Definition impl.cpp:1621
std::vector< session_t > getPeerIDs()
Definition impl.h:266
Definition connection.h:47
Definition connection.h:34
const session_t id
Definition connection.h:37
Definition peerhandler.h:13
Definition impl.h:30
PeerHelper & operator=(Peer *peer)
Definition impl.cpp:854
PeerHelper(Peer *peer)
Definition impl.h:33
Peer * operator&() const
Definition impl.h:38
bool operator!()
Definition impl.h:40
bool operator!=(std::nullptr_t)
Definition impl.h:41
PeerHelper()=default
Peer * operator->() const
Definition impl.h:37
~PeerHelper()
Definition impl.cpp:846
Peer * m_peer
Definition impl.h:44
Definition impl.h:96
bool m_pending_deletion
Definition impl.h:180
bool isHalfOpen() const
Definition impl.h:119
unsigned int m_increment_packets_remaining
Definition impl.h:130
virtual float getStat(rtt_stat_type type) const
Definition impl.h:142
bool isPendingDeletion() const
Definition impl.h:110
void SetFullyOpen()
Definition impl.h:123
rttstats m_rtt
Definition impl.h:200
Peer(session_t id, const Address &address, Connection *connection)
Definition impl.h:161
virtual void reportRTT(float rtt)
Definition impl.h:169
u64 m_last_timeout_check
Definition impl.h:218
virtual ~Peer()
Definition impl.h:100
Connection * m_connection
Definition impl.h:182
void RTTStatistics(float rtt, const std::string &profiler_id="", unsigned int num_samples=1000)
Definition impl.cpp:889
float m_timeout_counter
Definition impl.h:216
virtual void PutReliableSendCommand(ConnectionCommandPtr &c, unsigned int max_packet_size)
Definition impl.h:107
float m_last_rtt
Definition impl.h:201
bool m_half_open
Definition impl.h:210
void DecUseCount()
Definition impl.cpp:876
Address address
Definition impl.h:185
std::mutex m_exclusive_access_mutex
Definition impl.h:178
unsigned int m_usage
Definition impl.h:213
virtual void setNextSplitSequenceNumber(u8 channel, u16 seqnum)
Definition impl.h:133
void Drop()
Definition impl.cpp:955
virtual bool isTimedOut(float timeout, std::string &reason)
Definition impl.cpp:937
bool IncUseCount()
Definition impl.cpp:864
void ResetTimeout()
Definition impl.h:114
virtual u16 getNextSplitSequenceNumber(u8 channel)
Definition impl.h:132
virtual SharedBuffer< u8 > addSplitPacket(u8 channel, BufferedPacketPtr &toadd, bool reliable)
Definition impl.h:134
float m_ping_timer
Definition impl.h:188
virtual bool Ping(float dtime, SharedBuffer< u8 > &data)
Definition impl.h:140
Definition internal.h:483
#define PEER_ID_SERVER
Definition constants.h:20
#define FATAL_ERROR_IF(expr, msg)
Definition debug.h:35
#define FATAL_ERROR(msg)
Definition debug.h:32
std::lock_guard< std::mutex > MutexAutoLock
Definition mutex_auto_lock.h:31
Definition client.h:61
rtt_stat_type
Definition connection.h:16
@ MAX_RTT
Definition connection.h:18
@ MAX_JITTER
Definition connection.h:21
@ AVG_JITTER
Definition connection.h:22
@ MIN_JITTER
Definition connection.h:20
@ MIN_RTT
Definition connection.h:17
@ AVG_RTT
Definition connection.h:19
std::shared_ptr< ConnectionEvent > ConnectionEventPtr
Definition impl.h:60
std::shared_ptr< BufferedPacket > BufferedPacketPtr
Definition impl.h:91
std::shared_ptr< ConnectionCommand > ConnectionCommandPtr
Definition impl.h:88
ConnectionEventType
Definition impl.h:51
@ CONNEVENT_PEER_REMOVED
Definition impl.h:55
@ CONNEVENT_DATA_RECEIVED
Definition impl.h:53
@ CONNEVENT_PEER_ADDED
Definition impl.h:54
@ CONNEVENT_NONE
Definition impl.h:52
@ CONNEVENT_BIND_FAILED
Definition impl.h:56
rate_stat_type
Definition connection.h:25
Definition porting.cpp:85
u16 session_t
Definition networkprotocol.h:27
Definition internal.h:195
Definition impl.h:64
static ConnectionEventPtr dataReceived(session_t peer_id, const Buffer< u8 > &data)
Definition impl.cpp:1252
static ConnectionEventPtr peerRemoved(session_t peer_id, bool is_timeout, Address address)
Definition impl.cpp:1268
static ConnectionEventPtr create(ConnectionEventType type)
Definition impl.cpp:1247
static ConnectionEventPtr bindFailed()
Definition impl.cpp:1277
const ConnectionEventType type
Definition impl.h:65
Buffer< u8 > data
Definition impl.h:67
DISABLE_CLASS_COPY(ConnectionEvent)
bool timeout
Definition impl.h:68
static ConnectionEventPtr peerAdded(session_t peer_id, Address address)
Definition impl.cpp:1260
Address address
Definition impl.h:69
const char * describe() const
Definition impl.cpp:1229
session_t peer_id
Definition impl.h:66
ConnectionEvent(ConnectionEventType type_)
Definition impl.h:83
Definition impl.h:191
float jitter_min
Definition impl.h:192
float jitter_avg
Definition impl.h:194
float max_rtt
Definition impl.h:196
float min_rtt
Definition impl.h:195
float jitter_max
Definition impl.h:193
float avg_rtt
Definition impl.h:197