Minetest 5.9.0-dev
 
Loading...
Searching...
No Matches
connection.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 "irrlichttypes.h"
23#include "peerhandler.h"
24#include "socket.h"
25#include "constants.h"
26#include "util/pointer.h"
27#include "util/container.h"
28#include "util/numeric.h"
29#include "porting.h"
30#include "networkprotocol.h"
31#include <iostream>
32#include <vector>
33#include <map>
34
35class NetworkPacket;
36
37namespace con
38{
39
40class ConnectionReceiveThread;
41class ConnectionSendThread;
42
50};
51
52class Peer;
53
54// FIXME: Peer refcounting should generally be replaced by std::shared_ptr
56{
57public:
58 PeerHelper() = default;
59 inline PeerHelper(Peer *peer) { *this = peer; }
61
63 inline Peer* operator->() const { return m_peer; }
64 inline Peer* operator&() const { return m_peer; }
65
66 inline bool operator!() { return !m_peer; }
67 inline bool operator!=(std::nullptr_t) { return !!m_peer; }
68
69private:
70 Peer *m_peer = nullptr;
71};
72
73/*
74 Connection
75*/
76
83};
84
85struct ConnectionEvent;
86typedef std::shared_ptr<ConnectionEvent> ConnectionEventPtr;
87
88// This is very similar to ConnectionCommand
90{
94 bool timeout = false;
96
97 // We don't want to copy "data"
99
105
106 const char *describe() const;
107
108private:
110 type(type_) {}
111};
112
113struct ConnectionCommand;
114typedef std::shared_ptr<ConnectionCommand> ConnectionCommandPtr;
115
116struct BufferedPacket;
117typedef std::shared_ptr<BufferedPacket> BufferedPacketPtr;
118
119class Connection;
120class PeerHandler;
121
122class Peer {
123 public:
124 friend class PeerHelper;
125
126 virtual ~Peer() {
128 FATAL_ERROR_IF(m_usage != 0, "Reference counting failure");
129 }
130
131 // Unique id of the peer
133
134 void Drop();
135
137 unsigned int max_packet_size) {};
138
139 virtual const Address &getAddress() const = 0;
140
141 bool isPendingDeletion() const {
143 return m_pending_deletion;
144 }
148 }
149
150 bool isHalfOpen() const {
152 return m_half_open;
153 }
156 m_half_open = false;
157 }
158
159 virtual bool isTimedOut(float timeout, std::string &reason);
160
162
163 virtual u16 getNextSplitSequenceNumber(u8 channel) { return 0; };
164 virtual void setNextSplitSequenceNumber(u8 channel, u16 seqnum) {};
166 bool reliable)
167 {
168 FATAL_ERROR("unimplemented in abstract class");
169 }
170
171 virtual bool Ping(float dtime, SharedBuffer<u8>& data) { return false; };
172
173 virtual float getStat(rtt_stat_type type) const {
174 switch (type) {
175 case MIN_RTT:
176 return m_rtt.min_rtt;
177 case MAX_RTT:
178 return m_rtt.max_rtt;
179 case AVG_RTT:
180 return m_rtt.avg_rtt;
181 case MIN_JITTER:
182 return m_rtt.jitter_min;
183 case MAX_JITTER:
184 return m_rtt.jitter_max;
185 case AVG_JITTER:
186 return m_rtt.jitter_avg;
187 }
188 return -1;
189 }
190
191 protected:
192 Peer(session_t id, const Address &address, Connection *connection) :
193 id(id),
194 m_connection(connection),
196 m_last_timeout_check(porting::getTimeMs())
197 {
198 }
199
200 virtual void reportRTT(float rtt) {};
201
202 void RTTStatistics(float rtt,
203 const std::string &profiler_id = "",
204 unsigned int num_samples = 1000);
205
206 bool IncUseCount();
207 void DecUseCount();
208
209 mutable std::mutex m_exclusive_access_mutex;
210
211 bool m_pending_deletion = false;
212
214
215 // Address of the peer
217
218 // Ping timer
219 float m_ping_timer = 0.0f;
220
221 private:
222 struct rttstats {
223 float jitter_min = FLT_MAX;
224 float jitter_max = 0.0f;
225 float jitter_avg = -1.0f;
226 float min_rtt = FLT_MAX;
227 float max_rtt = 0.0f;
228 float avg_rtt = -1.0f;
229 };
230
232 float m_last_rtt = -1.0f;
233
234 /*
235 Until the peer has communicated with us using their assigned peer id
236 the connection is considered half-open.
237 During this time we inhibit re-sending any reliables or pings. This
238 is to avoid spending too many resources on a potential DoS attack
239 and to make sure Minetest servers are not useful for UDP amplificiation.
240 */
241 bool m_half_open = true;
242
243 // current usage count
244 unsigned int m_usage = 0;
245
246 // Seconds from last receive
247 float m_timeout_counter = 0.0f;
248
250};
251
252class UDPPeer;
253
255{
256public:
259
260 Connection(u32 protocol_id, u32 max_packet_size, float timeout, bool ipv6,
261 PeerHandler *peerhandler);
262 ~Connection();
263
264 /* Interface */
265 ConnectionEventPtr waitEvent(u32 timeout_ms);
266
268
269 void SetTimeoutMs(u32 timeout) { m_bc_receive_timeout = timeout; }
270 void Serve(Address bind_addr);
271 void Connect(Address address);
272 bool Connected();
273 void Disconnect();
274 bool ReceiveTimeoutMs(NetworkPacket *pkt, u32 timeout_ms);
275 void Receive(NetworkPacket *pkt);
276 bool TryReceive(NetworkPacket *pkt);
277 void Send(session_t peer_id, u8 channelnum, NetworkPacket *pkt, bool reliable);
278 session_t GetPeerID() const { return m_peer_id; }
280 float getPeerStat(session_t peer_id, rtt_stat_type type);
281 float getLocalStat(rate_stat_type type);
282 u32 GetProtocolID() const { return m_protocol_id; };
283 const std::string getDesc();
284 void DisconnectPeer(session_t peer_id);
285
286protected:
288 session_t lookupPeer(const Address& sender);
289
290 session_t createPeer(const Address& sender, int fd);
291 UDPPeer* createServerPeer(const Address& sender);
292 bool deletePeer(session_t peer_id, bool timeout);
293
294 void SetPeerID(session_t id) { m_peer_id = id; }
295
296 void doResendOne(session_t peer_id);
297
298 void sendAck(session_t peer_id, u8 channelnum, u16 seqnum);
299
300 std::vector<session_t> getPeerIDs()
301 {
303 return m_peer_ids;
304 }
305
306 u32 getActiveCount();
307
309 // Command queue: user -> SendThread
311
313
314 void TriggerSend();
315
317 {
318 return getPeerNoEx(PEER_ID_SERVER) != nullptr;
319 }
320private:
321 // Event queue: ReceiveThread -> user
323
326
327 std::map<session_t, Peer *> m_peers;
328 std::vector<session_t> m_peer_ids;
329 std::mutex m_peers_mutex;
330
331 std::unique_ptr<ConnectionSendThread> m_sendThread;
332 std::unique_ptr<ConnectionReceiveThread> m_receiveThread;
333
334 mutable std::mutex m_info_mutex;
335
336 // Backwards compatibility
339
340 bool m_shutting_down = false;
341};
342
343} // namespace
Definition: address.h:43
Definition: pointer.h:44
Definition: container.h:132
Definition: networkpacket.h:27
Definition: pointer.h:162
Definition: socket.h:34
Definition: connectionthreads.h:114
Definition: connectionthreads.h:56
Definition: connection.h:255
UDPPeer * createServerPeer(const Address &sender)
Definition: connection.cpp:1655
std::map< session_t, Peer * > m_peers
Definition: connection.h:327
u32 GetProtocolID() const
Definition: connection.h:282
Address GetPeerAddress(session_t peer_id)
Definition: connection.cpp:1518
void TriggerSend()
Definition: connection.cpp:1318
std::mutex m_peers_mutex
Definition: connection.h:329
float getPeerStat(session_t peer_id, rtt_stat_type type)
Definition: connection.cpp:1527
UDPSocket m_udpSocket
Definition: connection.h:308
PeerHelper getPeerNoEx(session_t peer_id)
Definition: connection.cpp:1323
bool deletePeer(session_t peer_id, bool timeout)
Definition: connection.cpp:1369
bool ConnectedToServer()
Definition: connection.h:316
void SetTimeoutMs(u32 timeout)
Definition: connection.h:269
bool m_shutting_down
Definition: connection.h:340
void Connect(Address address)
Definition: connection.cpp:1415
u32 m_bc_receive_timeout
Definition: connection.h:338
MutexedQueue< ConnectionCommandPtr > m_command_queue
Definition: connection.h:310
void DisconnectPeer(session_t peer_id)
Definition: connection.cpp:1626
u32 getActiveCount()
Definition: connection.cpp:1354
void Receive(NetworkPacket *pkt)
Definition: connection.cpp:1489
ConnectionEventPtr waitEvent(u32 timeout_ms)
Definition: connection.cpp:1393
u32 m_protocol_id
Definition: connection.h:325
session_t lookupPeer(const Address &sender)
Definition: connection.cpp:1339
session_t createPeer(const Address &sender, int fd)
Definition: connection.cpp:1570
void sendAck(session_t peer_id, u8 channelnum, u16 seqnum)
Definition: connection.cpp:1637
bool ReceiveTimeoutMs(NetworkPacket *pkt, u32 timeout_ms)
Definition: connection.cpp:1442
void putEvent(ConnectionEventPtr e)
Definition: connection.cpp:1312
bool TryReceive(NetworkPacket *pkt)
Definition: connection.cpp:1496
float getLocalStat(rate_stat_type type)
Definition: connection.cpp:1535
std::mutex m_info_mutex
Definition: connection.h:334
std::unique_ptr< ConnectionSendThread > m_sendThread
Definition: connection.h:331
void Serve(Address bind_addr)
Definition: connection.cpp:1410
session_t GetPeerID() const
Definition: connection.h:278
void Send(session_t peer_id, u8 channelnum, NetworkPacket *pkt, bool reliable)
Definition: connection.cpp:1501
bool Connected()
Definition: connection.cpp:1420
session_t m_peer_id
Definition: connection.h:324
void putCommand(ConnectionCommandPtr c)
Definition: connection.cpp:1402
MutexedQueue< ConnectionEventPtr > m_event_queue
Definition: connection.h:322
void SetPeerID(session_t id)
Definition: connection.h:294
~Connection()
Definition: connection.cpp:1288
void doResendOne(session_t peer_id)
Definition: connection.cpp:1631
std::unique_ptr< ConnectionReceiveThread > m_receiveThread
Definition: connection.h:332
std::vector< session_t > m_peer_ids
Definition: connection.h:328
PeerHandler * m_bc_peerhandler
Definition: connection.h:337
void Disconnect()
Definition: connection.cpp:1437
const std::string getDesc()
Definition: connection.cpp:1619
std::vector< session_t > getPeerIDs()
Definition: connection.h:300
Definition: peerhandler.h:40
Definition: connection.h:56
PeerHelper & operator=(Peer *peer)
Definition: connection.cpp:843
PeerHelper(Peer *peer)
Definition: connection.h:59
Peer * operator&() const
Definition: connection.h:64
bool operator!()
Definition: connection.h:66
bool operator!=(std::nullptr_t)
Definition: connection.h:67
PeerHelper()=default
Peer * operator->() const
Definition: connection.h:63
~PeerHelper()
Definition: connection.cpp:835
Peer * m_peer
Definition: connection.h:70
Definition: connection.h:122
bool m_pending_deletion
Definition: connection.h:211
bool isHalfOpen() const
Definition: connection.h:150
unsigned int m_increment_packets_remaining
Definition: connection.h:161
virtual float getStat(rtt_stat_type type) const
Definition: connection.h:173
bool isPendingDeletion() const
Definition: connection.h:141
void SetFullyOpen()
Definition: connection.h:154
rttstats m_rtt
Definition: connection.h:231
Peer(session_t id, const Address &address, Connection *connection)
Definition: connection.h:192
virtual const Address & getAddress() const =0
virtual void reportRTT(float rtt)
Definition: connection.h:200
u64 m_last_timeout_check
Definition: connection.h:249
virtual ~Peer()
Definition: connection.h:126
const session_t id
Definition: connection.h:132
Connection * m_connection
Definition: connection.h:213
void RTTStatistics(float rtt, const std::string &profiler_id="", unsigned int num_samples=1000)
Definition: connection.cpp:878
float m_timeout_counter
Definition: connection.h:247
virtual void PutReliableSendCommand(ConnectionCommandPtr &c, unsigned int max_packet_size)
Definition: connection.h:136
float m_last_rtt
Definition: connection.h:232
bool m_half_open
Definition: connection.h:241
void DecUseCount()
Definition: connection.cpp:865
Address address
Definition: connection.h:216
std::mutex m_exclusive_access_mutex
Definition: connection.h:209
unsigned int m_usage
Definition: connection.h:244
virtual void setNextSplitSequenceNumber(u8 channel, u16 seqnum)
Definition: connection.h:164
void Drop()
Definition: connection.cpp:944
virtual bool isTimedOut(float timeout, std::string &reason)
Definition: connection.cpp:926
bool IncUseCount()
Definition: connection.cpp:853
void ResetTimeout()
Definition: connection.h:145
virtual u16 getNextSplitSequenceNumber(u8 channel)
Definition: connection.h:163
virtual SharedBuffer< u8 > addSplitPacket(u8 channel, BufferedPacketPtr &toadd, bool reliable)
Definition: connection.h:165
float m_ping_timer
Definition: connection.h:219
virtual bool Ping(float dtime, SharedBuffer< u8 > &data)
Definition: connection.h:171
Definition: connection_internal.h:444
#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:73
rate_stat_type
Definition: connection.h:43
@ CUR_LOSS_RATE
Definition: connection.h:48
@ AVG_INC_RATE
Definition: connection.h:47
@ CUR_INC_RATE
Definition: connection.h:46
@ CUR_DL_RATE
Definition: connection.h:44
@ AVG_DL_RATE
Definition: connection.h:45
@ AVG_LOSS_RATE
Definition: connection.h:49
std::shared_ptr< ConnectionEvent > ConnectionEventPtr
Definition: connection.h:86
rtt_stat_type
Definition: peerhandler.h:28
@ MAX_RTT
Definition: peerhandler.h:30
@ MAX_JITTER
Definition: peerhandler.h:33
@ AVG_JITTER
Definition: peerhandler.h:34
@ MIN_JITTER
Definition: peerhandler.h:32
@ MIN_RTT
Definition: peerhandler.h:29
@ AVG_RTT
Definition: peerhandler.h:31
std::shared_ptr< BufferedPacket > BufferedPacketPtr
Definition: connection.h:117
std::shared_ptr< ConnectionCommand > ConnectionCommandPtr
Definition: connection.h:114
ConnectionEventType
Definition: connection.h:77
@ CONNEVENT_PEER_REMOVED
Definition: connection.h:81
@ CONNEVENT_DATA_RECEIVED
Definition: connection.h:79
@ CONNEVENT_PEER_ADDED
Definition: connection.h:80
@ CONNEVENT_NONE
Definition: connection.h:78
@ CONNEVENT_BIND_FAILED
Definition: connection.h:82
Definition: porting.cpp:86
u16 session_t
Definition: networkprotocol.h:251
Definition: connection_internal.h:170
Definition: connection.h:90
static ConnectionEventPtr dataReceived(session_t peer_id, const Buffer< u8 > &data)
Definition: connection.cpp:1233
static ConnectionEventPtr peerRemoved(session_t peer_id, bool is_timeout, Address address)
Definition: connection.cpp:1249
static ConnectionEventPtr create(ConnectionEventType type)
Definition: connection.cpp:1228
static ConnectionEventPtr bindFailed()
Definition: connection.cpp:1258
const ConnectionEventType type
Definition: connection.h:91
Buffer< u8 > data
Definition: connection.h:93
DISABLE_CLASS_COPY(ConnectionEvent)
bool timeout
Definition: connection.h:94
static ConnectionEventPtr peerAdded(session_t peer_id, Address address)
Definition: connection.cpp:1241
Address address
Definition: connection.h:95
const char * describe() const
Definition: connection.cpp:1210
session_t peer_id
Definition: connection.h:92
ConnectionEvent(ConnectionEventType type_)
Definition: connection.h:109
Definition: connection.h:222
float jitter_min
Definition: connection.h:223
float jitter_avg
Definition: connection.h:225
float max_rtt
Definition: connection.h:227
float min_rtt
Definition: connection.h:226
float jitter_max
Definition: connection.h:224
float avg_rtt
Definition: connection.h:228