mirror of
https://github.com/minetest/minetest.git
synced 2024-11-30 11:33:44 +01:00
Network cleanup (#6310)
* Move Connection threads to dedicated files + various cleanups * ConnectionReceiveThread::processPacket now uses function pointer table to route MT packet types * Various code style fixes * Code style with clang-format * Various SharedBuffer copy removal * SharedBuffer cannot be copied anymore using Buffer * Fix many SharedBuffer copy (thanks to delete operator)
This commit is contained in:
parent
f6a33a1a7a
commit
3cea7a349a
@ -290,7 +290,6 @@ void set_default_settings(Settings *settings)
|
|||||||
// Network
|
// Network
|
||||||
settings->setDefault("enable_ipv6", "true");
|
settings->setDefault("enable_ipv6", "true");
|
||||||
settings->setDefault("ipv6_server", "false");
|
settings->setDefault("ipv6_server", "false");
|
||||||
settings->setDefault("workaround_window_size","5");
|
|
||||||
settings->setDefault("max_packets_per_iteration","1024");
|
settings->setDefault("max_packets_per_iteration","1024");
|
||||||
settings->setDefault("port", "30000");
|
settings->setDefault("port", "30000");
|
||||||
settings->setDefault("strict_protocol_version_checking", "false");
|
settings->setDefault("strict_protocol_version_checking", "false");
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
set(common_network_SRCS
|
set(common_network_SRCS
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/address.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/address.cpp
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/connection.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/connection.cpp
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/connectionthreads.cpp
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/networkpacket.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/networkpacket.cpp
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/serverpackethandler.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/serverpackethandler.cpp
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/serveropcodes.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/serveropcodes.cpp
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -37,13 +37,19 @@ class NetworkPacket;
|
|||||||
namespace con
|
namespace con
|
||||||
{
|
{
|
||||||
|
|
||||||
|
class ConnectionReceiveThread;
|
||||||
|
class ConnectionSendThread;
|
||||||
|
|
||||||
typedef enum MTProtocols {
|
typedef enum MTProtocols {
|
||||||
MTP_PRIMARY,
|
MTP_PRIMARY,
|
||||||
MTP_UDP,
|
MTP_UDP,
|
||||||
MTP_MINETEST_RELIABLE_UDP
|
MTP_MINETEST_RELIABLE_UDP
|
||||||
} MTProtocols;
|
} MTProtocols;
|
||||||
|
|
||||||
|
#define MAX_UDP_PEERS 65535
|
||||||
|
|
||||||
#define SEQNUM_MAX 65535
|
#define SEQNUM_MAX 65535
|
||||||
|
|
||||||
inline bool seqnum_higher(u16 totest, u16 base)
|
inline bool seqnum_higher(u16 totest, u16 base)
|
||||||
{
|
{
|
||||||
if (totest > base)
|
if (totest > base)
|
||||||
@ -73,6 +79,12 @@ inline bool seqnum_in_window(u16 seqnum, u16 next,u16 window_size)
|
|||||||
return ((seqnum < window_end) || (seqnum >= window_start));
|
return ((seqnum < window_end) || (seqnum >= window_start));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline float CALC_DTIME(u64 lasttime, u64 curtime)
|
||||||
|
{
|
||||||
|
float value = ( curtime - lasttime) / 1000.0;
|
||||||
|
return MYMAX(MYMIN(value,0.1),0.0);
|
||||||
|
}
|
||||||
|
|
||||||
struct BufferedPacket
|
struct BufferedPacket
|
||||||
{
|
{
|
||||||
BufferedPacket(u8 *a_data, u32 a_size):
|
BufferedPacket(u8 *a_data, u32 a_size):
|
||||||
@ -90,44 +102,31 @@ struct BufferedPacket
|
|||||||
};
|
};
|
||||||
|
|
||||||
// This adds the base headers to the data and makes a packet out of it
|
// This adds the base headers to the data and makes a packet out of it
|
||||||
BufferedPacket makePacket(Address &address, u8 *data, u32 datasize,
|
BufferedPacket makePacket(Address &address, const SharedBuffer<u8> &data,
|
||||||
u32 protocol_id, u16 sender_peer_id, u8 channel);
|
u32 protocol_id, u16 sender_peer_id, u8 channel);
|
||||||
BufferedPacket makePacket(Address &address, SharedBuffer<u8> &data,
|
|
||||||
u32 protocol_id, u16 sender_peer_id, u8 channel);
|
|
||||||
|
|
||||||
// Add the TYPE_ORIGINAL header to the data
|
|
||||||
SharedBuffer<u8> makeOriginalPacket(
|
|
||||||
SharedBuffer<u8> data);
|
|
||||||
|
|
||||||
// Split data in chunks and add TYPE_SPLIT headers to them
|
|
||||||
std::list<SharedBuffer<u8> > makeSplitPacket(
|
|
||||||
SharedBuffer<u8> data,
|
|
||||||
u32 chunksize_max,
|
|
||||||
u16 seqnum);
|
|
||||||
|
|
||||||
// Depending on size, make a TYPE_ORIGINAL or TYPE_SPLIT packet
|
// Depending on size, make a TYPE_ORIGINAL or TYPE_SPLIT packet
|
||||||
// Increments split_seqnum if a split packet is made
|
// Increments split_seqnum if a split packet is made
|
||||||
std::list<SharedBuffer<u8> > makeAutoSplitPacket(
|
void makeAutoSplitPacket(const SharedBuffer<u8> &data, u32 chunksize_max,
|
||||||
SharedBuffer<u8> data,
|
u16 &split_seqnum, std::list<SharedBuffer<u8>> *list);
|
||||||
u32 chunksize_max,
|
|
||||||
u16 &split_seqnum);
|
|
||||||
|
|
||||||
// Add the TYPE_RELIABLE header to the data
|
// Add the TYPE_RELIABLE header to the data
|
||||||
SharedBuffer<u8> makeReliablePacket(
|
SharedBuffer<u8> makeReliablePacket(const SharedBuffer<u8> &data, u16 seqnum);
|
||||||
const SharedBuffer<u8> &data,
|
|
||||||
u16 seqnum);
|
|
||||||
|
|
||||||
struct IncomingSplitPacket
|
struct IncomingSplitPacket
|
||||||
{
|
{
|
||||||
IncomingSplitPacket() = default;
|
IncomingSplitPacket(u32 cc, bool r):
|
||||||
|
chunk_count(cc), reliable(r) {}
|
||||||
|
|
||||||
|
IncomingSplitPacket() = delete;
|
||||||
|
|
||||||
// Key is chunk number, value is data without headers
|
// Key is chunk number, value is data without headers
|
||||||
std::map<u16, SharedBuffer<u8> > chunks;
|
std::map<u16, SharedBuffer<u8>> chunks;
|
||||||
u32 chunk_count;
|
u32 chunk_count;
|
||||||
float time = 0.0f; // Seconds from adding
|
float time = 0.0f; // Seconds from adding
|
||||||
bool reliable = false; // If true, isn't deleted on timeout
|
bool reliable = false; // If true, isn't deleted on timeout
|
||||||
|
|
||||||
bool allReceived()
|
bool allReceived() const
|
||||||
{
|
{
|
||||||
return (chunks.size() == chunk_count);
|
return (chunks.size() == chunk_count);
|
||||||
}
|
}
|
||||||
@ -171,7 +170,7 @@ controltype and data description:
|
|||||||
packet to get a reply
|
packet to get a reply
|
||||||
CONTROLTYPE_DISCO
|
CONTROLTYPE_DISCO
|
||||||
*/
|
*/
|
||||||
#define TYPE_CONTROL 0
|
//#define TYPE_CONTROL 0
|
||||||
#define CONTROLTYPE_ACK 0
|
#define CONTROLTYPE_ACK 0
|
||||||
#define CONTROLTYPE_SET_PEER_ID 1
|
#define CONTROLTYPE_SET_PEER_ID 1
|
||||||
#define CONTROLTYPE_PING 2
|
#define CONTROLTYPE_PING 2
|
||||||
@ -185,7 +184,7 @@ checking at all.
|
|||||||
Header (1 byte):
|
Header (1 byte):
|
||||||
[0] u8 type
|
[0] u8 type
|
||||||
*/
|
*/
|
||||||
#define TYPE_ORIGINAL 1
|
//#define TYPE_ORIGINAL 1
|
||||||
#define ORIGINAL_HEADER_SIZE 1
|
#define ORIGINAL_HEADER_SIZE 1
|
||||||
/*
|
/*
|
||||||
SPLIT: These are sequences of packets forming one bigger piece of
|
SPLIT: These are sequences of packets forming one bigger piece of
|
||||||
@ -202,7 +201,7 @@ data.
|
|||||||
[3] u16 chunk_count
|
[3] u16 chunk_count
|
||||||
[5] u16 chunk_num
|
[5] u16 chunk_num
|
||||||
*/
|
*/
|
||||||
#define TYPE_SPLIT 2
|
//#define TYPE_SPLIT 2
|
||||||
/*
|
/*
|
||||||
RELIABLE: Delivery of all RELIABLE packets shall be forced by ACKs,
|
RELIABLE: Delivery of all RELIABLE packets shall be forced by ACKs,
|
||||||
and they shall be delivered in the same order as sent. This is done
|
and they shall be delivered in the same order as sent. This is done
|
||||||
@ -214,10 +213,17 @@ with a buffer in the receiving and transmitting end.
|
|||||||
[1] u16 seqnum
|
[1] u16 seqnum
|
||||||
|
|
||||||
*/
|
*/
|
||||||
#define TYPE_RELIABLE 3
|
//#define TYPE_RELIABLE 3
|
||||||
#define RELIABLE_HEADER_SIZE 3
|
#define RELIABLE_HEADER_SIZE 3
|
||||||
#define SEQNUM_INITIAL 65500
|
#define SEQNUM_INITIAL 65500
|
||||||
|
|
||||||
|
enum PacketType: u8 {
|
||||||
|
PACKET_TYPE_CONTROL = 0,
|
||||||
|
PACKET_TYPE_ORIGINAL = 1,
|
||||||
|
PACKET_TYPE_SPLIT = 2,
|
||||||
|
PACKET_TYPE_RELIABLE = 3,
|
||||||
|
PACKET_TYPE_MAX
|
||||||
|
};
|
||||||
/*
|
/*
|
||||||
A buffer which stores reliable packets and sorts them internally
|
A buffer which stores reliable packets and sorts them internally
|
||||||
for fast access to the smallest one.
|
for fast access to the smallest one.
|
||||||
@ -270,7 +276,7 @@ public:
|
|||||||
Returns a reference counted buffer of length != 0 when a full split
|
Returns a reference counted buffer of length != 0 when a full split
|
||||||
packet is constructed. If not, returns one of length 0.
|
packet is constructed. If not, returns one of length 0.
|
||||||
*/
|
*/
|
||||||
SharedBuffer<u8> insert(BufferedPacket &p, bool reliable);
|
SharedBuffer<u8> insert(const BufferedPacket &p, bool reliable);
|
||||||
|
|
||||||
void removeUnreliableTimedOuts(float dtime, float timeout);
|
void removeUnreliableTimedOuts(float dtime, float timeout);
|
||||||
|
|
||||||
@ -318,8 +324,8 @@ struct ConnectionCommand
|
|||||||
enum ConnectionCommandType type = CONNCMD_NONE;
|
enum ConnectionCommandType type = CONNCMD_NONE;
|
||||||
Address address;
|
Address address;
|
||||||
u16 peer_id = PEER_ID_INEXISTENT;
|
u16 peer_id = PEER_ID_INEXISTENT;
|
||||||
u8 channelnum;
|
u8 channelnum = 0;
|
||||||
Buffer<u8> data;
|
SharedBuffer<u8> data;
|
||||||
bool reliable = false;
|
bool reliable = false;
|
||||||
bool raw = false;
|
bool raw = false;
|
||||||
|
|
||||||
@ -551,8 +557,7 @@ class Peer {
|
|||||||
|
|
||||||
virtual u16 getNextSplitSequenceNumber(u8 channel) { return 0; };
|
virtual u16 getNextSplitSequenceNumber(u8 channel) { return 0; };
|
||||||
virtual void setNextSplitSequenceNumber(u8 channel, u16 seqnum) {};
|
virtual void setNextSplitSequenceNumber(u8 channel, u16 seqnum) {};
|
||||||
virtual SharedBuffer<u8> addSpiltPacket(u8 channel,
|
virtual SharedBuffer<u8> addSplitPacket(u8 channel, const BufferedPacket &toadd,
|
||||||
BufferedPacket toadd,
|
|
||||||
bool reliable)
|
bool reliable)
|
||||||
{
|
{
|
||||||
fprintf(stderr,"Peer: addSplitPacket called, this is supposed to be never called!\n");
|
fprintf(stderr,"Peer: addSplitPacket called, this is supposed to be never called!\n");
|
||||||
@ -649,11 +654,9 @@ public:
|
|||||||
u16 getNextSplitSequenceNumber(u8 channel);
|
u16 getNextSplitSequenceNumber(u8 channel);
|
||||||
void setNextSplitSequenceNumber(u8 channel, u16 seqnum);
|
void setNextSplitSequenceNumber(u8 channel, u16 seqnum);
|
||||||
|
|
||||||
SharedBuffer<u8> addSpiltPacket(u8 channel,
|
SharedBuffer<u8> addSplitPacket(u8 channel, const BufferedPacket &toadd,
|
||||||
BufferedPacket toadd,
|
|
||||||
bool reliable);
|
bool reliable);
|
||||||
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/*
|
/*
|
||||||
Calculates avg_rtt and resend_timeout.
|
Calculates avg_rtt and resend_timeout.
|
||||||
@ -750,103 +753,6 @@ struct ConnectionEvent
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class ConnectionSendThread : public Thread {
|
|
||||||
|
|
||||||
public:
|
|
||||||
friend class UDPPeer;
|
|
||||||
|
|
||||||
ConnectionSendThread(unsigned int max_packet_size, float timeout);
|
|
||||||
|
|
||||||
void *run();
|
|
||||||
|
|
||||||
void Trigger();
|
|
||||||
|
|
||||||
void setParent(Connection* parent) {
|
|
||||||
assert(parent != NULL); // Pre-condition
|
|
||||||
m_connection = parent;
|
|
||||||
}
|
|
||||||
|
|
||||||
void setPeerTimeout(float peer_timeout)
|
|
||||||
{ m_timeout = peer_timeout; }
|
|
||||||
|
|
||||||
private:
|
|
||||||
void runTimeouts (float dtime);
|
|
||||||
void rawSend (const BufferedPacket &packet);
|
|
||||||
bool rawSendAsPacket(u16 peer_id, u8 channelnum,
|
|
||||||
SharedBuffer<u8> data, bool reliable);
|
|
||||||
|
|
||||||
void processReliableCommand (ConnectionCommand &c);
|
|
||||||
void processNonReliableCommand (ConnectionCommand &c);
|
|
||||||
void serve (Address bind_address);
|
|
||||||
void connect (Address address);
|
|
||||||
void disconnect ();
|
|
||||||
void disconnect_peer(u16 peer_id);
|
|
||||||
void send (u16 peer_id, u8 channelnum,
|
|
||||||
SharedBuffer<u8> data);
|
|
||||||
void sendReliable (ConnectionCommand &c);
|
|
||||||
void sendToAll (u8 channelnum,
|
|
||||||
SharedBuffer<u8> data);
|
|
||||||
void sendToAllReliable(ConnectionCommand &c);
|
|
||||||
|
|
||||||
void sendPackets (float dtime);
|
|
||||||
|
|
||||||
void sendAsPacket (u16 peer_id, u8 channelnum,
|
|
||||||
SharedBuffer<u8> data,bool ack=false);
|
|
||||||
|
|
||||||
void sendAsPacketReliable(BufferedPacket& p, Channel* channel);
|
|
||||||
|
|
||||||
bool packetsQueued();
|
|
||||||
|
|
||||||
Connection *m_connection = nullptr;
|
|
||||||
unsigned int m_max_packet_size;
|
|
||||||
float m_timeout;
|
|
||||||
std::queue<OutgoingPacket> m_outgoing_queue;
|
|
||||||
Semaphore m_send_sleep_semaphore;
|
|
||||||
|
|
||||||
unsigned int m_iteration_packets_avaialble;
|
|
||||||
unsigned int m_max_commands_per_iteration = 1;
|
|
||||||
unsigned int m_max_data_packets_per_iteration;
|
|
||||||
unsigned int m_max_packets_requeued = 256;
|
|
||||||
};
|
|
||||||
|
|
||||||
class ConnectionReceiveThread : public Thread {
|
|
||||||
public:
|
|
||||||
ConnectionReceiveThread(unsigned int max_packet_size);
|
|
||||||
|
|
||||||
void *run();
|
|
||||||
|
|
||||||
void setParent(Connection *parent) {
|
|
||||||
assert(parent); // Pre-condition
|
|
||||||
m_connection = parent;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
void receive();
|
|
||||||
|
|
||||||
// Returns next data from a buffer if possible
|
|
||||||
// If found, returns true; if not, false.
|
|
||||||
// If found, sets peer_id and dst
|
|
||||||
bool getFromBuffers(u16 &peer_id, SharedBuffer<u8> &dst);
|
|
||||||
|
|
||||||
bool checkIncomingBuffers(Channel *channel, u16 &peer_id,
|
|
||||||
SharedBuffer<u8> &dst);
|
|
||||||
|
|
||||||
/*
|
|
||||||
Processes a packet with the basic header stripped out.
|
|
||||||
Parameters:
|
|
||||||
packetdata: Data in packet (with no base headers)
|
|
||||||
peer_id: peer id of the sender of the packet in question
|
|
||||||
channelnum: channel on which the packet was sent
|
|
||||||
reliable: true if recursing into a reliable packet
|
|
||||||
*/
|
|
||||||
SharedBuffer<u8> processPacket(Channel *channel,
|
|
||||||
SharedBuffer<u8> packetdata, u16 peer_id,
|
|
||||||
u8 channelnum, bool reliable);
|
|
||||||
|
|
||||||
|
|
||||||
Connection *m_connection = nullptr;
|
|
||||||
};
|
|
||||||
|
|
||||||
class PeerHandler;
|
class PeerHandler;
|
||||||
|
|
||||||
class Connection
|
class Connection
|
||||||
@ -863,7 +769,7 @@ public:
|
|||||||
ConnectionEvent waitEvent(u32 timeout_ms);
|
ConnectionEvent waitEvent(u32 timeout_ms);
|
||||||
void putCommand(ConnectionCommand &c);
|
void putCommand(ConnectionCommand &c);
|
||||||
|
|
||||||
void SetTimeoutMs(int timeout) { m_bc_receive_timeout = timeout; }
|
void SetTimeoutMs(u32 timeout) { m_bc_receive_timeout = timeout; }
|
||||||
void Serve(Address bind_addr);
|
void Serve(Address bind_addr);
|
||||||
void Connect(Address address);
|
void Connect(Address address);
|
||||||
bool Connected();
|
bool Connected();
|
||||||
@ -879,7 +785,6 @@ public:
|
|||||||
void DisconnectPeer(u16 peer_id);
|
void DisconnectPeer(u16 peer_id);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
PeerHelper getPeer(u16 peer_id);
|
|
||||||
PeerHelper getPeerNoEx(u16 peer_id);
|
PeerHelper getPeerNoEx(u16 peer_id);
|
||||||
u16 lookupPeer(Address& sender);
|
u16 lookupPeer(Address& sender);
|
||||||
|
|
||||||
@ -892,7 +797,6 @@ protected:
|
|||||||
void sendAck(u16 peer_id, u8 channelnum, u16 seqnum);
|
void sendAck(u16 peer_id, u8 channelnum, u16 seqnum);
|
||||||
|
|
||||||
void PrintInfo(std::ostream &out);
|
void PrintInfo(std::ostream &out);
|
||||||
void PrintInfo();
|
|
||||||
|
|
||||||
std::list<u16> getPeerIDs()
|
std::list<u16> getPeerIDs()
|
||||||
{
|
{
|
||||||
@ -905,8 +809,7 @@ protected:
|
|||||||
|
|
||||||
void putEvent(ConnectionEvent &e);
|
void putEvent(ConnectionEvent &e);
|
||||||
|
|
||||||
void TriggerSend()
|
void TriggerSend();
|
||||||
{ m_sendThread.Trigger(); }
|
|
||||||
private:
|
private:
|
||||||
std::list<Peer*> getPeers();
|
std::list<Peer*> getPeers();
|
||||||
|
|
||||||
@ -919,14 +822,14 @@ private:
|
|||||||
std::list<u16> m_peer_ids;
|
std::list<u16> m_peer_ids;
|
||||||
std::mutex m_peers_mutex;
|
std::mutex m_peers_mutex;
|
||||||
|
|
||||||
ConnectionSendThread m_sendThread;
|
std::unique_ptr<ConnectionSendThread> m_sendThread;
|
||||||
ConnectionReceiveThread m_receiveThread;
|
std::unique_ptr<ConnectionReceiveThread> m_receiveThread;
|
||||||
|
|
||||||
std::mutex m_info_mutex;
|
std::mutex m_info_mutex;
|
||||||
|
|
||||||
// Backwards compatibility
|
// Backwards compatibility
|
||||||
PeerHandler *m_bc_peerhandler;
|
PeerHandler *m_bc_peerhandler;
|
||||||
int m_bc_receive_timeout = 0;
|
u32 m_bc_receive_timeout = 0;
|
||||||
|
|
||||||
bool m_shutting_down = false;
|
bool m_shutting_down = false;
|
||||||
|
|
||||||
|
1404
src/network/connectionthreads.cpp
Normal file
1404
src/network/connectionthreads.cpp
Normal file
File diff suppressed because it is too large
Load Diff
148
src/network/connectionthreads.h
Normal file
148
src/network/connectionthreads.h
Normal file
@ -0,0 +1,148 @@
|
|||||||
|
/*
|
||||||
|
Minetest
|
||||||
|
Copyright (C) 2013-2017 celeron55, Perttu Ahola <celeron55@gmail.com>
|
||||||
|
Copyright (C) 2017 celeron55, Loic Blot <loic.blot@unix-experience.fr>
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2.1 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU Lesser General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public License along
|
||||||
|
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <cassert>
|
||||||
|
#include "../threading/thread.h"
|
||||||
|
#include "connection.h"
|
||||||
|
|
||||||
|
namespace con
|
||||||
|
{
|
||||||
|
|
||||||
|
class Connection;
|
||||||
|
|
||||||
|
class ConnectionSendThread : public Thread
|
||||||
|
{
|
||||||
|
|
||||||
|
public:
|
||||||
|
friend class UDPPeer;
|
||||||
|
|
||||||
|
ConnectionSendThread(unsigned int max_packet_size, float timeout);
|
||||||
|
|
||||||
|
void *run();
|
||||||
|
|
||||||
|
void Trigger();
|
||||||
|
|
||||||
|
void setParent(Connection *parent)
|
||||||
|
{
|
||||||
|
assert(parent != NULL); // Pre-condition
|
||||||
|
m_connection = parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setPeerTimeout(float peer_timeout) { m_timeout = peer_timeout; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
void runTimeouts(float dtime);
|
||||||
|
void rawSend(const BufferedPacket &packet);
|
||||||
|
bool rawSendAsPacket(u16 peer_id, u8 channelnum, const SharedBuffer<u8> &data,
|
||||||
|
bool reliable);
|
||||||
|
|
||||||
|
void processReliableCommand(ConnectionCommand &c);
|
||||||
|
void processNonReliableCommand(ConnectionCommand &c);
|
||||||
|
void serve(Address bind_address);
|
||||||
|
void connect(Address address);
|
||||||
|
void disconnect();
|
||||||
|
void disconnect_peer(u16 peer_id);
|
||||||
|
void send(u16 peer_id, u8 channelnum, SharedBuffer<u8> data);
|
||||||
|
void sendReliable(ConnectionCommand &c);
|
||||||
|
void sendToAll(u8 channelnum, SharedBuffer<u8> data);
|
||||||
|
void sendToAllReliable(ConnectionCommand &c);
|
||||||
|
|
||||||
|
void sendPackets(float dtime);
|
||||||
|
|
||||||
|
void sendAsPacket(u16 peer_id, u8 channelnum, SharedBuffer<u8> data,
|
||||||
|
bool ack = false);
|
||||||
|
|
||||||
|
void sendAsPacketReliable(BufferedPacket &p, Channel *channel);
|
||||||
|
|
||||||
|
bool packetsQueued();
|
||||||
|
|
||||||
|
Connection *m_connection = nullptr;
|
||||||
|
unsigned int m_max_packet_size;
|
||||||
|
float m_timeout;
|
||||||
|
std::queue<OutgoingPacket> m_outgoing_queue;
|
||||||
|
Semaphore m_send_sleep_semaphore;
|
||||||
|
|
||||||
|
unsigned int m_iteration_packets_avaialble;
|
||||||
|
unsigned int m_max_commands_per_iteration = 1;
|
||||||
|
unsigned int m_max_data_packets_per_iteration;
|
||||||
|
unsigned int m_max_packets_requeued = 256;
|
||||||
|
};
|
||||||
|
|
||||||
|
class ConnectionReceiveThread : public Thread
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ConnectionReceiveThread(unsigned int max_packet_size);
|
||||||
|
|
||||||
|
void *run();
|
||||||
|
|
||||||
|
void setParent(Connection *parent)
|
||||||
|
{
|
||||||
|
assert(parent); // Pre-condition
|
||||||
|
m_connection = parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
void receive();
|
||||||
|
|
||||||
|
// Returns next data from a buffer if possible
|
||||||
|
// If found, returns true; if not, false.
|
||||||
|
// If found, sets peer_id and dst
|
||||||
|
bool getFromBuffers(u16 &peer_id, SharedBuffer<u8> &dst);
|
||||||
|
|
||||||
|
bool checkIncomingBuffers(Channel *channel, u16 &peer_id, SharedBuffer<u8> &dst);
|
||||||
|
|
||||||
|
/*
|
||||||
|
Processes a packet with the basic header stripped out.
|
||||||
|
Parameters:
|
||||||
|
packetdata: Data in packet (with no base headers)
|
||||||
|
peer_id: peer id of the sender of the packet in question
|
||||||
|
channelnum: channel on which the packet was sent
|
||||||
|
reliable: true if recursing into a reliable packet
|
||||||
|
*/
|
||||||
|
SharedBuffer<u8> processPacket(Channel *channel, SharedBuffer<u8> &packetdata,
|
||||||
|
u16 peer_id, u8 channelnum, bool reliable);
|
||||||
|
|
||||||
|
SharedBuffer<u8> handlePacketType_Control(Channel *channel,
|
||||||
|
SharedBuffer<u8> &packetdata, Peer *peer, u8 channelnum,
|
||||||
|
bool reliable);
|
||||||
|
SharedBuffer<u8> handlePacketType_Original(Channel *channel,
|
||||||
|
SharedBuffer<u8> &packetdata, Peer *peer, u8 channelnum,
|
||||||
|
bool reliable);
|
||||||
|
SharedBuffer<u8> handlePacketType_Split(Channel *channel,
|
||||||
|
SharedBuffer<u8> &packetdata, Peer *peer, u8 channelnum,
|
||||||
|
bool reliable);
|
||||||
|
SharedBuffer<u8> handlePacketType_Reliable(Channel *channel,
|
||||||
|
SharedBuffer<u8> &packetdata, Peer *peer, u8 channelnum,
|
||||||
|
bool reliable);
|
||||||
|
|
||||||
|
struct PacketTypeHandler
|
||||||
|
{
|
||||||
|
SharedBuffer<u8> (ConnectionReceiveThread::*handler)(Channel *channel,
|
||||||
|
SharedBuffer<u8> &packet, Peer *peer, u8 channelnum,
|
||||||
|
bool reliable);
|
||||||
|
};
|
||||||
|
|
||||||
|
static const PacketTypeHandler packetTypeRouter[PACKET_TYPE_MAX];
|
||||||
|
|
||||||
|
Connection *m_connection = nullptr;
|
||||||
|
};
|
||||||
|
}
|
@ -526,9 +526,9 @@ NetworkPacket& NetworkPacket::operator<<(video::SColor src)
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
Buffer<u8> NetworkPacket::oldForgePacket()
|
SharedBuffer<u8> NetworkPacket::oldForgePacket()
|
||||||
{
|
{
|
||||||
Buffer<u8> sb(m_datasize + 2);
|
SharedBuffer<u8> sb(m_datasize + 2);
|
||||||
writeU16(&sb[0], m_command);
|
writeU16(&sb[0], m_command);
|
||||||
|
|
||||||
u8* datas = getU8Ptr(0);
|
u8* datas = getU8Ptr(0);
|
||||||
|
@ -118,7 +118,7 @@ public:
|
|||||||
NetworkPacket &operator<<(video::SColor src);
|
NetworkPacket &operator<<(video::SColor src);
|
||||||
|
|
||||||
// Temp, we remove SharedBuffer when migration finished
|
// Temp, we remove SharedBuffer when migration finished
|
||||||
Buffer<u8> oldForgePacket();
|
SharedBuffer<u8> oldForgePacket();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void checkReadOffset(u32 from_offset, u32 field_size);
|
void checkReadOffset(u32 from_offset, u32 field_size);
|
||||||
|
@ -115,7 +115,7 @@ void TestConnection::testHelpers()
|
|||||||
infostream<<"data1[0]="<<((u32)data1[0]&0xff)<<std::endl;*/
|
infostream<<"data1[0]="<<((u32)data1[0]&0xff)<<std::endl;*/
|
||||||
|
|
||||||
UASSERT(p2.getSize() == 3 + data1.getSize());
|
UASSERT(p2.getSize() == 3 + data1.getSize());
|
||||||
UASSERT(readU8(&p2[0]) == TYPE_RELIABLE);
|
UASSERT(readU8(&p2[0]) == con::PACKET_TYPE_RELIABLE);
|
||||||
UASSERT(readU16(&p2[1]) == seqnum);
|
UASSERT(readU16(&p2[1]) == seqnum);
|
||||||
UASSERT(readU8(&p2[3]) == data1[0]);
|
UASSERT(readU8(&p2[3]) == data1[0]);
|
||||||
}
|
}
|
||||||
@ -290,13 +290,13 @@ void TestConnection::testConnectSendReceive()
|
|||||||
infostream << "...";
|
infostream << "...";
|
||||||
infostream << std::endl;
|
infostream << std::endl;
|
||||||
|
|
||||||
Buffer<u8> sentdata = pkt.oldForgePacket();
|
SharedBuffer<u8> sentdata = pkt.oldForgePacket();
|
||||||
|
|
||||||
server.Send(peer_id_client, 0, &pkt, true);
|
server.Send(peer_id_client, 0, &pkt, true);
|
||||||
|
|
||||||
//sleep_ms(3000);
|
//sleep_ms(3000);
|
||||||
|
|
||||||
Buffer<u8> recvdata;
|
SharedBuffer<u8> recvdata;
|
||||||
infostream << "** running client.Receive()" << std::endl;
|
infostream << "** running client.Receive()" << std::endl;
|
||||||
u16 peer_id = 132;
|
u16 peer_id = 132;
|
||||||
u16 size = 0;
|
u16 size = 0;
|
||||||
|
@ -104,7 +104,6 @@ private:
|
|||||||
|
|
||||||
/************************************************
|
/************************************************
|
||||||
* !!! W A R N I N G !!! *
|
* !!! W A R N I N G !!! *
|
||||||
* !!! A C H T U N G !!! *
|
|
||||||
* *
|
* *
|
||||||
* This smart pointer class is NOT thread safe. *
|
* This smart pointer class is NOT thread safe. *
|
||||||
* ONLY use in a single-threaded context! *
|
* ONLY use in a single-threaded context! *
|
||||||
@ -134,7 +133,6 @@ public:
|
|||||||
}
|
}
|
||||||
SharedBuffer(const SharedBuffer &buffer)
|
SharedBuffer(const SharedBuffer &buffer)
|
||||||
{
|
{
|
||||||
//std::cout<<"SharedBuffer(const SharedBuffer &buffer)"<<std::endl;
|
|
||||||
m_size = buffer.m_size;
|
m_size = buffer.m_size;
|
||||||
data = buffer.data;
|
data = buffer.data;
|
||||||
refcount = buffer.refcount;
|
refcount = buffer.refcount;
|
||||||
@ -142,7 +140,6 @@ public:
|
|||||||
}
|
}
|
||||||
SharedBuffer & operator=(const SharedBuffer & buffer)
|
SharedBuffer & operator=(const SharedBuffer & buffer)
|
||||||
{
|
{
|
||||||
//std::cout<<"SharedBuffer & operator=(const SharedBuffer & buffer)"<<std::endl;
|
|
||||||
if(this == &buffer)
|
if(this == &buffer)
|
||||||
return *this;
|
return *this;
|
||||||
drop();
|
drop();
|
||||||
@ -171,19 +168,6 @@ public:
|
|||||||
/*
|
/*
|
||||||
Copies whole buffer
|
Copies whole buffer
|
||||||
*/
|
*/
|
||||||
SharedBuffer(const Buffer<T> &buffer)
|
|
||||||
{
|
|
||||||
m_size = buffer.getSize();
|
|
||||||
if(m_size != 0)
|
|
||||||
{
|
|
||||||
data = new T[m_size];
|
|
||||||
memcpy(data, *buffer, buffer.getSize());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
data = NULL;
|
|
||||||
refcount = new unsigned int;
|
|
||||||
(*refcount) = 1;
|
|
||||||
}
|
|
||||||
~SharedBuffer()
|
~SharedBuffer()
|
||||||
{
|
{
|
||||||
drop();
|
drop();
|
||||||
@ -220,9 +204,3 @@ private:
|
|||||||
unsigned int m_size;
|
unsigned int m_size;
|
||||||
unsigned int *refcount;
|
unsigned int *refcount;
|
||||||
};
|
};
|
||||||
|
|
||||||
inline SharedBuffer<u8> SharedBufferFromString(const char *string)
|
|
||||||
{
|
|
||||||
SharedBuffer<u8> b((u8*)string, strlen(string)+1);
|
|
||||||
return b;
|
|
||||||
}
|
|
||||||
|
@ -171,6 +171,7 @@ src/network/clientopcodes.h
|
|||||||
src/network/clientpackethandler.cpp
|
src/network/clientpackethandler.cpp
|
||||||
src/network/connection.cpp
|
src/network/connection.cpp
|
||||||
src/network/connection.h
|
src/network/connection.h
|
||||||
|
src/network/connectionthreads.cpp
|
||||||
src/network/networkpacket.cpp
|
src/network/networkpacket.cpp
|
||||||
src/network/networkprotocol.h
|
src/network/networkprotocol.h
|
||||||
src/network/serveropcodes.cpp
|
src/network/serveropcodes.cpp
|
||||||
|
Loading…
Reference in New Issue
Block a user