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