Minetest 5.10.0-dev
 
Loading...
Searching...
No Matches
impl.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/connection.h"
23#include "network/socket.h"
24#include "constants.h"
25#include "util/pointer.h"
26#include "util/container.h"
27#include "util/numeric.h"
28#include "porting.h"
30#include <iostream>
31#include <vector>
32#include <map>
33
34namespace con
35{
36
37class ConnectionReceiveThread;
38class ConnectionSendThread;
39
40class Peer;
41
42// FIXME: Peer refcounting should generally be replaced by std::shared_ptr
44{
45public:
46 PeerHelper() = default;
47 inline PeerHelper(Peer *peer) { *this = peer; }
49
51 inline Peer* operator->() const { return m_peer; }
52 inline Peer* operator&() const { return m_peer; }
53
54 inline bool operator!() { return !m_peer; }
55 inline bool operator!=(std::nullptr_t) { return !!m_peer; }
56
57private:
58 Peer *m_peer = nullptr;
59};
60
61/*
62 Connection
63*/
64
72
73struct ConnectionEvent;
74typedef std::shared_ptr<ConnectionEvent> ConnectionEventPtr;
75
76// This is very similar to ConnectionCommand
100
101struct ConnectionCommand;
102typedef std::shared_ptr<ConnectionCommand> ConnectionCommandPtr;
103
104struct BufferedPacket;
105typedef std::shared_ptr<BufferedPacket> BufferedPacketPtr;
106
107class Connection;
108class PeerHandler;
109
110class Peer : public IPeer {
111 public:
112 friend class PeerHelper;
113
114 virtual ~Peer() {
116 FATAL_ERROR_IF(m_usage != 0, "Reference counting failure");
117 }
118
119 void Drop();
120
122 unsigned int max_packet_size) {};
123
132
133 bool isHalfOpen() const {
135 return m_half_open;
136 }
139 m_half_open = false;
140 }
141
142 virtual bool isTimedOut(float timeout, std::string &reason);
143
145
146 virtual u16 getNextSplitSequenceNumber(u8 channel) { return 0; };
147 virtual void setNextSplitSequenceNumber(u8 channel, u16 seqnum) {};
149 bool reliable)
150 {
151 FATAL_ERROR("unimplemented in abstract class");
152 }
153
154 virtual bool Ping(float dtime, SharedBuffer<u8>& data) { return false; };
155
156 virtual float getStat(rtt_stat_type type) const {
157 switch (type) {
158 case MIN_RTT:
159 return m_rtt.min_rtt;
160 case MAX_RTT:
161 return m_rtt.max_rtt;
162 case AVG_RTT:
163 return m_rtt.avg_rtt;
164 case MIN_JITTER:
165 return m_rtt.jitter_min;
166 case MAX_JITTER:
167 return m_rtt.jitter_max;
168 case AVG_JITTER:
169 return m_rtt.jitter_avg;
170 }
171 return -1;
172 }
173
174 protected:
175 Peer(session_t id, const Address &address, Connection *connection) :
176 IPeer(id),
177 m_connection(connection),
179 m_last_timeout_check(porting::getTimeMs())
180 {
181 }
182
183 virtual void reportRTT(float rtt) {};
184
185 void RTTStatistics(float rtt,
186 const std::string &profiler_id = "",
187 unsigned int num_samples = 1000);
188
189 bool IncUseCount();
190 void DecUseCount();
191
192 mutable std::mutex m_exclusive_access_mutex;
193
194 bool m_pending_deletion = false;
195
197
198 // Address of the peer
200
201 // Ping timer
202 float m_ping_timer = 0.0f;
203
204 private:
205 struct rttstats {
206 float jitter_min = FLT_MAX;
207 float jitter_max = 0.0f;
208 float jitter_avg = -1.0f;
209 float min_rtt = FLT_MAX;
210 float max_rtt = 0.0f;
211 float avg_rtt = -1.0f;
212 };
213
215 float m_last_rtt = -1.0f;
216
217 /*
218 Until the peer has communicated with us using their assigned peer id
219 the connection is considered half-open.
220 During this time we inhibit re-sending any reliables or pings. This
221 is to avoid spending too many resources on a potential DoS attack
222 and to make sure Minetest servers are not useful for UDP amplificiation.
223 */
224 bool m_half_open = true;
225
226 // current usage count
227 unsigned int m_usage = 0;
228
229 // Seconds from last receive
230 float m_timeout_counter = 0.0f;
231
233};
234
235class UDPPeer;
236
237class Connection final : public IConnection
238{
239public:
242
243 Connection(u32 max_packet_size, float timeout, bool ipv6,
244 PeerHandler *peerhandler);
245 ~Connection();
246
247 /* Interface */
248 ConnectionEventPtr waitEvent(u32 timeout_ms);
249
251
252 void Serve(Address bind_addr);
253 void Connect(Address address);
254 bool Connected();
255 void Disconnect();
256 bool ReceiveTimeoutMs(NetworkPacket *pkt, u32 timeout_ms);
257 void Send(session_t peer_id, u8 channelnum, NetworkPacket *pkt, bool reliable);
258 session_t GetPeerID() const { return m_peer_id; }
260 float getPeerStat(session_t peer_id, rtt_stat_type type);
261 float getLocalStat(rate_stat_type type);
262 u32 GetProtocolID() const { return m_protocol_id; };
263 const std::string getDesc();
264 void DisconnectPeer(session_t peer_id);
265
266protected:
268 session_t lookupPeer(const Address& sender);
269
270 session_t createPeer(const Address& sender, int fd);
271 UDPPeer* createServerPeer(const Address& sender);
272 bool deletePeer(session_t peer_id, bool timeout);
273
274 void SetPeerID(session_t id) { m_peer_id = id; }
275
276 void doResendOne(session_t peer_id);
277
278 void sendAck(session_t peer_id, u8 channelnum, u16 seqnum);
279
280 std::vector<session_t> getPeerIDs()
281 {
283 return m_peer_ids;
284 }
285
286 u32 getActiveCount();
287
289 // Command queue: user -> SendThread
291
293
294 void TriggerSend();
295
297 {
298 return getPeerNoEx(PEER_ID_SERVER) != nullptr;
299 }
300private:
301 // Event queue: ReceiveThread -> user
303
306
307 std::map<session_t, Peer *> m_peers;
308 std::vector<session_t> m_peer_ids;
309 std::mutex m_peers_mutex;
310
311 std::unique_ptr<ConnectionSendThread> m_sendThread;
312 std::unique_ptr<ConnectionReceiveThread> m_receiveThread;
313
314 mutable std::mutex m_info_mutex;
315
316 // Backwards compatibility
318
319 bool m_shutting_down = false;
320};
321
322} // namespace
Definition address.h:43
Definition pointer.h:44
Definition container.h:132
Definition networkpacket.h:27
Definition pointer.h:162
Definition socket.h:32
Definition threads.h:114
Definition threads.h:56
Definition impl.h:238
UDPPeer * createServerPeer(const Address &sender)
Definition impl.cpp:1657
std::map< session_t, Peer * > m_peers
Definition impl.h:307
u32 GetProtocolID() const
Definition impl.h:262
Address GetPeerAddress(session_t peer_id)
Definition impl.cpp:1520
void TriggerSend()
Definition impl.cpp:1332
std::mutex m_peers_mutex
Definition impl.h:309
float getPeerStat(session_t peer_id, rtt_stat_type type)
Definition impl.cpp:1529
UDPSocket m_udpSocket
Definition impl.h:288
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:296
bool m_shutting_down
Definition impl.h:319
Connection(u32 max_packet_size, float timeout, bool ipv6, PeerHandler *peerhandler)
Definition impl.cpp:1281
void Connect(Address address)
Definition impl.cpp:1429
MutexedQueue< ConnectionCommandPtr > m_command_queue
Definition impl.h:290
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:305
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:1639
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:314
std::unique_ptr< ConnectionSendThread > m_sendThread
Definition impl.h:311
void Serve(Address bind_addr)
Definition impl.cpp:1424
session_t GetPeerID() const
Definition impl.h:258
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:304
void putCommand(ConnectionCommandPtr c)
Definition impl.cpp:1416
MutexedQueue< ConnectionEventPtr > m_event_queue
Definition impl.h:302
void SetPeerID(session_t id)
Definition impl.h:274
~Connection()
Definition impl.cpp:1302
void doResendOne(session_t peer_id)
Definition impl.cpp:1633
std::unique_ptr< ConnectionReceiveThread > m_receiveThread
Definition impl.h:312
std::vector< session_t > m_peer_ids
Definition impl.h:308
PeerHandler * m_bc_peerhandler
Definition impl.h:317
void Disconnect()
Definition impl.cpp:1451
const std::string getDesc()
Definition impl.cpp:1621
std::vector< session_t > getPeerIDs()
Definition impl.h:280
Definition connection.h:47
Definition connection.h:34
const session_t id
Definition connection.h:37
Definition peerhandler.h:28
Definition impl.h:44
PeerHelper & operator=(Peer *peer)
Definition impl.cpp:849
PeerHelper(Peer *peer)
Definition impl.h:47
Peer * operator&() const
Definition impl.h:52
bool operator!()
Definition impl.h:54
bool operator!=(std::nullptr_t)
Definition impl.h:55
PeerHelper()=default
Peer * operator->() const
Definition impl.h:51
~PeerHelper()
Definition impl.cpp:841
Peer * m_peer
Definition impl.h:58
Definition impl.h:110
bool m_pending_deletion
Definition impl.h:194
bool isHalfOpen() const
Definition impl.h:133
unsigned int m_increment_packets_remaining
Definition impl.h:144
virtual float getStat(rtt_stat_type type) const
Definition impl.h:156
bool isPendingDeletion() const
Definition impl.h:124
void SetFullyOpen()
Definition impl.h:137
rttstats m_rtt
Definition impl.h:214
Peer(session_t id, const Address &address, Connection *connection)
Definition impl.h:175
virtual void reportRTT(float rtt)
Definition impl.h:183
u64 m_last_timeout_check
Definition impl.h:232
virtual ~Peer()
Definition impl.h:114
Connection * m_connection
Definition impl.h:196
void RTTStatistics(float rtt, const std::string &profiler_id="", unsigned int num_samples=1000)
Definition impl.cpp:884
float m_timeout_counter
Definition impl.h:230
virtual void PutReliableSendCommand(ConnectionCommandPtr &c, unsigned int max_packet_size)
Definition impl.h:121
float m_last_rtt
Definition impl.h:215
bool m_half_open
Definition impl.h:224
void DecUseCount()
Definition impl.cpp:871
Address address
Definition impl.h:199
std::mutex m_exclusive_access_mutex
Definition impl.h:192
unsigned int m_usage
Definition impl.h:227
virtual void setNextSplitSequenceNumber(u8 channel, u16 seqnum)
Definition impl.h:147
void Drop()
Definition impl.cpp:950
virtual bool isTimedOut(float timeout, std::string &reason)
Definition impl.cpp:932
bool IncUseCount()
Definition impl.cpp:859
void ResetTimeout()
Definition impl.h:128
virtual u16 getNextSplitSequenceNumber(u8 channel)
Definition impl.h:146
virtual SharedBuffer< u8 > addSplitPacket(u8 channel, BufferedPacketPtr &toadd, bool reliable)
Definition impl.h:148
float m_ping_timer
Definition impl.h:202
virtual bool Ping(float dtime, SharedBuffer< u8 > &data)
Definition impl.h:154
Definition internal.h:478
#define PEER_ID_SERVER
Definition constants.h:35
#define FATAL_ERROR_IF(expr, msg)
Definition debug.h:51
#define FATAL_ERROR(msg)
Definition debug.h:48
std::unique_lock< std::mutex > MutexAutoLock
Definition mutex_auto_lock.h:29
Definition client.h:72
rate_stat_type
Definition connection.h:25
std::shared_ptr< ConnectionEvent > ConnectionEventPtr
Definition impl.h:74
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:105
std::shared_ptr< ConnectionCommand > ConnectionCommandPtr
Definition impl.h:102
ConnectionEventType
Definition impl.h:65
@ CONNEVENT_PEER_REMOVED
Definition impl.h:69
@ CONNEVENT_DATA_RECEIVED
Definition impl.h:67
@ CONNEVENT_PEER_ADDED
Definition impl.h:68
@ CONNEVENT_NONE
Definition impl.h:66
@ CONNEVENT_BIND_FAILED
Definition impl.h:70
Definition porting.cpp:93
u16 session_t
Definition networkprotocol.h:259
Definition internal.h:195
Definition impl.h:78
static ConnectionEventPtr dataReceived(session_t peer_id, const Buffer< u8 > &data)
Definition impl.cpp:1247
static ConnectionEventPtr peerRemoved(session_t peer_id, bool is_timeout, Address address)
Definition impl.cpp:1263
static ConnectionEventPtr create(ConnectionEventType type)
Definition impl.cpp:1242
static ConnectionEventPtr bindFailed()
Definition impl.cpp:1272
const ConnectionEventType type
Definition impl.h:79
Buffer< u8 > data
Definition impl.h:81
DISABLE_CLASS_COPY(ConnectionEvent)
bool timeout
Definition impl.h:82
static ConnectionEventPtr peerAdded(session_t peer_id, Address address)
Definition impl.cpp:1255
Address address
Definition impl.h:83
const char * describe() const
Definition impl.cpp:1224
session_t peer_id
Definition impl.h:80
ConnectionEvent(ConnectionEventType type_)
Definition impl.h:97
Definition impl.h:205
float jitter_min
Definition impl.h:206
float jitter_avg
Definition impl.h:208
float max_rtt
Definition impl.h:210
float min_rtt
Definition impl.h:209
float jitter_max
Definition impl.h:207
float avg_rtt
Definition impl.h:211