minetest/src/network/connection.cpp

1531 lines
38 KiB
C++
Raw Normal View History

/*
2013-02-24 18:40:43 +01:00
Minetest
2013-02-24 19:38:45 +01:00
Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>
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.
*/
#include <iomanip>
#include <cerrno>
#include <algorithm>
2018-07-26 21:49:38 +02:00
#include <cmath>
2010-11-27 00:02:21 +01:00
#include "connection.h"
#include "serialization.h"
#include "log.h"
#include "porting.h"
#include "network/connectionthreads.h"
#include "network/networkpacket.h"
#include "network/peerhandler.h"
#include "util/serialize.h"
#include "util/numeric.h"
#include "util/string.h"
#include "settings.h"
#include "profiler.h"
2010-11-27 00:02:21 +01:00
namespace con
{
/******************************************************************************/
/* defines used for debugging and profiling */
/******************************************************************************/
#ifdef NDEBUG
#define LOG(a) a
#define PROFILE(a)
#else
/* this mutex is used to achieve log message consistency */
std::mutex log_message_mutex;
#define LOG(a) \
{ \
MutexAutoLock loglock(log_message_mutex); \
a; \
}
#define PROFILE(a) a
#endif
#define PING_TIMEOUT 5.0
Various network performance improvements (#8125) * Optimize packet construction functions Some of the functions that construct packets in connection.cpp are using a const reference to get the raw packet data to package and others use a value passed parameter to do that. The ones that use the value passed parameter suffer from performance hit as the rather bulky packet data gets a temporary copy when the parameter is passed before it lands at its final destination inside the newly constructed packet. The unnecessary temporary copy hurts quite badly as the underlying class (SharedBuffer) actually allocates the space for the data in the heap. Fix the performance hit by converting all of these value passed parameters to const references. I believe that this is what the author of the relevant code actually intended to do as there is a couple of packet construction helper functions that already use a const reference to get the raw data. * Optimize packet sender thread class Most of the data sending methods of the packet sender thread class use a value passed parameter for the packet data to be sent. This causes the rather bulky data to be allocated on the heap and copied, slowing the packet sending down. Convert these parameters to const references to avoid the performance hit. * Optimize packet receiver thread class The packet receiver and processor thread class has many methods (mostly packet handlers) that receive the packed data by value. This causes a performance hit that is actually worse than the one caused by the packet sender methods because the packet is first handed to the processPacket method which looks at the packet type stored in the header and then delegates the actual handling to one of the handlers. Both, processPacket and all the handlers get the packet data by value, leading to at least two unnecessary copies of the data (with malloc and all the slow bells and whistles of bulky classes). As there already is a few methods that use a const reference parameter for the packet data, convert all this value passed packets to const references.
2019-04-14 22:56:38 +02:00
BufferedPacket makePacket(Address &address, const SharedBuffer<u8> &data,
u32 protocol_id, session_t sender_peer_id, u8 channel)
2010-11-27 00:02:21 +01:00
{
u32 packet_size = data.getSize() + BASE_HEADER_SIZE;
2010-11-27 00:02:21 +01:00
BufferedPacket p(packet_size);
p.address = address;
writeU32(&p.data[0], protocol_id);
writeU16(&p.data[4], sender_peer_id);
writeU8(&p.data[6], channel);
memcpy(&p.data[BASE_HEADER_SIZE], *data, data.getSize());
2010-11-27 00:02:21 +01:00
return p;
}
SharedBuffer<u8> makeOriginalPacket(const SharedBuffer<u8> &data)
2010-11-27 00:02:21 +01:00
{
u32 header_size = 1;
u32 packet_size = data.getSize() + header_size;
SharedBuffer<u8> b(packet_size);
writeU8(&(b[0]), PACKET_TYPE_ORIGINAL);
if (data.getSize() > 0) {
memcpy(&(b[header_size]), *data, data.getSize());
}
2010-11-27 00:02:21 +01:00
return b;
}
// Split data in chunks and add TYPE_SPLIT headers to them
void makeSplitPacket(const SharedBuffer<u8> &data, u32 chunksize_max, u16 seqnum,
std::list<SharedBuffer<u8>> *chunks)
2010-11-27 00:02:21 +01:00
{
// Chunk packets, containing the TYPE_SPLIT header
u32 chunk_header_size = 7;
u32 maximum_data_size = chunksize_max - chunk_header_size;
u32 start = 0;
u32 end = 0;
u32 chunk_num = 0;
2012-12-20 18:19:49 +01:00
u16 chunk_count = 0;
do {
2010-11-27 00:02:21 +01:00
end = start + maximum_data_size - 1;
[Patch 2/4] Network rework: packet writing, sending and cleanups NetworkPacket.cpp: * Remove some deprecated functions, we must use streaming interface * m_data converted from u8* to std::vector<u8> * Add an exporter to forge packet to Connection object * implement operator << std::wstring. n * implement operator << std::string * dynamic resize when write packet content. * fix string writing and performances. * create ServerCommandFactory, used by client to get useful informations about packet processing (sending). * Reliability * Transmit channel * Implement putRawString for some ugly char (_INIT packet), and use it. * Many packet read and write migrated * Implement oldForgePacket to interface writing with current connection * fix U8/char/bool writing * fix string writing and performances. * add some missing functions * Use v3s16 read instead of reading x,y,z separately * Add irr::video::SColor support into packets * Add some missing handlers * Add a template function to increase offset * Throw a serialization error on packet reading (must be improved) PacketFactories: * Create ServerCommandFactory, used by client to get useful informations about packet processing (sending). * Create ClientCommandFactory, used by server to get useful informations about packet processing (sending). Client.cpp: * implement NetworkPacket ::Send interface. * Move packet handlers to a dedicated file * Remove Client::Send(SharedBuffer) Server.cpp: * implement NetworkPacket ::Send interface. * Rewrite all packets using NetworkPacket * Move packet handlers to a dedicated file * Remove Server::Send(SharedBuffer) ClientIface.cpp: * Remove sendToAll(SharedBuffer<u8>) Connection.hpp rework: * Remove duplicate include * Remove duplicate negation * Remove a useless variable * Improve code performance by using a m_peers_list instead of scanning m_peers map * Remove Connection::Send(SharedBuffer) * Fix useafterfree into NetworkPacket Sending * Remove unused Connection::sendToAll Test.cpp: * Remove dead code * Update tests to use NetworkPackets Misc: * add new wrappers to Send packets in client, using NetworkPacket * Add NetworkPacket methods for Connection * coding style fix * dead code since changes cleanup * Use v3s16 read instead of reading x,y,z separately in some packets * Use different files to handle packets received by client and server * Cleanup: Remove useless includes ok @Zeno- Tested by @Zeno- @VanessaE and @nerzhul on running servers
2015-01-16 11:37:49 +01:00
if (end > data.getSize() - 1)
2010-11-27 00:02:21 +01:00
end = data.getSize() - 1;
2010-11-27 00:02:21 +01:00
u32 payload_size = end - start + 1;
u32 packet_size = chunk_header_size + payload_size;
SharedBuffer<u8> chunk(packet_size);
writeU8(&chunk[0], PACKET_TYPE_SPLIT);
2010-11-27 00:02:21 +01:00
writeU16(&chunk[1], seqnum);
// [3] u16 chunk_count is written at next stage
writeU16(&chunk[5], chunk_num);
memcpy(&chunk[chunk_header_size], &data[start], payload_size);
chunks->push_back(chunk);
2012-12-20 18:19:49 +01:00
chunk_count++;
2010-11-27 00:02:21 +01:00
start = end + 1;
chunk_num++;
}
while (end != data.getSize() - 1);
2010-11-27 00:02:21 +01:00
for (SharedBuffer<u8> &chunk : *chunks) {
2010-11-27 00:02:21 +01:00
// Write chunk_count
writeU16(&(chunk[3]), chunk_count);
2010-11-27 00:02:21 +01:00
}
}
Various network performance improvements (#8125) * Optimize packet construction functions Some of the functions that construct packets in connection.cpp are using a const reference to get the raw packet data to package and others use a value passed parameter to do that. The ones that use the value passed parameter suffer from performance hit as the rather bulky packet data gets a temporary copy when the parameter is passed before it lands at its final destination inside the newly constructed packet. The unnecessary temporary copy hurts quite badly as the underlying class (SharedBuffer) actually allocates the space for the data in the heap. Fix the performance hit by converting all of these value passed parameters to const references. I believe that this is what the author of the relevant code actually intended to do as there is a couple of packet construction helper functions that already use a const reference to get the raw data. * Optimize packet sender thread class Most of the data sending methods of the packet sender thread class use a value passed parameter for the packet data to be sent. This causes the rather bulky data to be allocated on the heap and copied, slowing the packet sending down. Convert these parameters to const references to avoid the performance hit. * Optimize packet receiver thread class The packet receiver and processor thread class has many methods (mostly packet handlers) that receive the packed data by value. This causes a performance hit that is actually worse than the one caused by the packet sender methods because the packet is first handed to the processPacket method which looks at the packet type stored in the header and then delegates the actual handling to one of the handlers. Both, processPacket and all the handlers get the packet data by value, leading to at least two unnecessary copies of the data (with malloc and all the slow bells and whistles of bulky classes). As there already is a few methods that use a const reference parameter for the packet data, convert all this value passed packets to const references.
2019-04-14 22:56:38 +02:00
void makeAutoSplitPacket(const SharedBuffer<u8> &data, u32 chunksize_max,
u16 &split_seqnum, std::list<SharedBuffer<u8>> *list)
2010-11-27 00:02:21 +01:00
{
u32 original_header_size = 1;
if (data.getSize() + original_header_size > chunksize_max) {
makeSplitPacket(data, chunksize_max, split_seqnum, list);
2010-11-27 00:02:21 +01:00
split_seqnum++;
return;
2010-11-27 00:02:21 +01:00
}
list->push_back(makeOriginalPacket(data));
2010-11-27 00:02:21 +01:00
}
Various network performance improvements (#8125) * Optimize packet construction functions Some of the functions that construct packets in connection.cpp are using a const reference to get the raw packet data to package and others use a value passed parameter to do that. The ones that use the value passed parameter suffer from performance hit as the rather bulky packet data gets a temporary copy when the parameter is passed before it lands at its final destination inside the newly constructed packet. The unnecessary temporary copy hurts quite badly as the underlying class (SharedBuffer) actually allocates the space for the data in the heap. Fix the performance hit by converting all of these value passed parameters to const references. I believe that this is what the author of the relevant code actually intended to do as there is a couple of packet construction helper functions that already use a const reference to get the raw data. * Optimize packet sender thread class Most of the data sending methods of the packet sender thread class use a value passed parameter for the packet data to be sent. This causes the rather bulky data to be allocated on the heap and copied, slowing the packet sending down. Convert these parameters to const references to avoid the performance hit. * Optimize packet receiver thread class The packet receiver and processor thread class has many methods (mostly packet handlers) that receive the packed data by value. This causes a performance hit that is actually worse than the one caused by the packet sender methods because the packet is first handed to the processPacket method which looks at the packet type stored in the header and then delegates the actual handling to one of the handlers. Both, processPacket and all the handlers get the packet data by value, leading to at least two unnecessary copies of the data (with malloc and all the slow bells and whistles of bulky classes). As there already is a few methods that use a const reference parameter for the packet data, convert all this value passed packets to const references.
2019-04-14 22:56:38 +02:00
SharedBuffer<u8> makeReliablePacket(const SharedBuffer<u8> &data, u16 seqnum)
2010-11-27 00:02:21 +01:00
{
u32 header_size = 3;
u32 packet_size = data.getSize() + header_size;
SharedBuffer<u8> b(packet_size);
writeU8(&b[0], PACKET_TYPE_RELIABLE);
2010-11-27 00:02:21 +01:00
writeU16(&b[1], seqnum);
memcpy(&b[header_size], *data, data.getSize());
return b;
}
/*
ReliablePacketBuffer
*/
void ReliablePacketBuffer::print()
{
MutexAutoLock listlock(m_list_mutex);
LOG(dout_con<<"Dump of ReliablePacketBuffer:" << std::endl);
unsigned int index = 0;
for (BufferedPacket &bufferedPacket : m_list) {
u16 s = readU16(&(bufferedPacket.data[BASE_HEADER_SIZE+1]));
LOG(dout_con<<index<< ":" << s << std::endl);
index++;
2010-11-27 00:02:21 +01:00
}
}
bool ReliablePacketBuffer::empty()
{
MutexAutoLock listlock(m_list_mutex);
2010-11-27 00:02:21 +01:00
return m_list.empty();
}
2010-11-27 00:02:21 +01:00
u32 ReliablePacketBuffer::size()
{
2012-12-20 18:19:49 +01:00
return m_list_size;
2010-11-27 00:02:21 +01:00
}
bool ReliablePacketBuffer::containsPacket(u16 seqnum)
{
return !(findPacket(seqnum) == m_list.end());
}
2010-11-27 00:02:21 +01:00
RPBSearchResult ReliablePacketBuffer::findPacket(u16 seqnum)
{
2012-12-20 18:19:49 +01:00
std::list<BufferedPacket>::iterator i = m_list.begin();
for(; i != m_list.end(); ++i)
2010-11-27 00:02:21 +01:00
{
u16 s = readU16(&(i->data[BASE_HEADER_SIZE+1]));
/*dout_con<<"findPacket(): finding seqnum="<<seqnum
<<", comparing to s="<<s<<std::endl;*/
[Patch 2/4] Network rework: packet writing, sending and cleanups NetworkPacket.cpp: * Remove some deprecated functions, we must use streaming interface * m_data converted from u8* to std::vector<u8> * Add an exporter to forge packet to Connection object * implement operator << std::wstring. n * implement operator << std::string * dynamic resize when write packet content. * fix string writing and performances. * create ServerCommandFactory, used by client to get useful informations about packet processing (sending). * Reliability * Transmit channel * Implement putRawString for some ugly char (_INIT packet), and use it. * Many packet read and write migrated * Implement oldForgePacket to interface writing with current connection * fix U8/char/bool writing * fix string writing and performances. * add some missing functions * Use v3s16 read instead of reading x,y,z separately * Add irr::video::SColor support into packets * Add some missing handlers * Add a template function to increase offset * Throw a serialization error on packet reading (must be improved) PacketFactories: * Create ServerCommandFactory, used by client to get useful informations about packet processing (sending). * Create ClientCommandFactory, used by server to get useful informations about packet processing (sending). Client.cpp: * implement NetworkPacket ::Send interface. * Move packet handlers to a dedicated file * Remove Client::Send(SharedBuffer) Server.cpp: * implement NetworkPacket ::Send interface. * Rewrite all packets using NetworkPacket * Move packet handlers to a dedicated file * Remove Server::Send(SharedBuffer) ClientIface.cpp: * Remove sendToAll(SharedBuffer<u8>) Connection.hpp rework: * Remove duplicate include * Remove duplicate negation * Remove a useless variable * Improve code performance by using a m_peers_list instead of scanning m_peers map * Remove Connection::Send(SharedBuffer) * Fix useafterfree into NetworkPacket Sending * Remove unused Connection::sendToAll Test.cpp: * Remove dead code * Update tests to use NetworkPackets Misc: * add new wrappers to Send packets in client, using NetworkPacket * Add NetworkPacket methods for Connection * coding style fix * dead code since changes cleanup * Use v3s16 read instead of reading x,y,z separately in some packets * Use different files to handle packets received by client and server * Cleanup: Remove useless includes ok @Zeno- Tested by @Zeno- @VanessaE and @nerzhul on running servers
2015-01-16 11:37:49 +01:00
if (s == seqnum)
2010-11-27 00:02:21 +01:00
break;
}
return i;
}
RPBSearchResult ReliablePacketBuffer::notFound()
{
return m_list.end();
}
bool ReliablePacketBuffer::getFirstSeqnum(u16& result)
2010-11-27 00:02:21 +01:00
{
MutexAutoLock listlock(m_list_mutex);
[Patch 2/4] Network rework: packet writing, sending and cleanups NetworkPacket.cpp: * Remove some deprecated functions, we must use streaming interface * m_data converted from u8* to std::vector<u8> * Add an exporter to forge packet to Connection object * implement operator << std::wstring. n * implement operator << std::string * dynamic resize when write packet content. * fix string writing and performances. * create ServerCommandFactory, used by client to get useful informations about packet processing (sending). * Reliability * Transmit channel * Implement putRawString for some ugly char (_INIT packet), and use it. * Many packet read and write migrated * Implement oldForgePacket to interface writing with current connection * fix U8/char/bool writing * fix string writing and performances. * add some missing functions * Use v3s16 read instead of reading x,y,z separately * Add irr::video::SColor support into packets * Add some missing handlers * Add a template function to increase offset * Throw a serialization error on packet reading (must be improved) PacketFactories: * Create ServerCommandFactory, used by client to get useful informations about packet processing (sending). * Create ClientCommandFactory, used by server to get useful informations about packet processing (sending). Client.cpp: * implement NetworkPacket ::Send interface. * Move packet handlers to a dedicated file * Remove Client::Send(SharedBuffer) Server.cpp: * implement NetworkPacket ::Send interface. * Rewrite all packets using NetworkPacket * Move packet handlers to a dedicated file * Remove Server::Send(SharedBuffer) ClientIface.cpp: * Remove sendToAll(SharedBuffer<u8>) Connection.hpp rework: * Remove duplicate include * Remove duplicate negation * Remove a useless variable * Improve code performance by using a m_peers_list instead of scanning m_peers map * Remove Connection::Send(SharedBuffer) * Fix useafterfree into NetworkPacket Sending * Remove unused Connection::sendToAll Test.cpp: * Remove dead code * Update tests to use NetworkPackets Misc: * add new wrappers to Send packets in client, using NetworkPacket * Add NetworkPacket methods for Connection * coding style fix * dead code since changes cleanup * Use v3s16 read instead of reading x,y,z separately in some packets * Use different files to handle packets received by client and server * Cleanup: Remove useless includes ok @Zeno- Tested by @Zeno- @VanessaE and @nerzhul on running servers
2015-01-16 11:37:49 +01:00
if (m_list.empty())
return false;
2010-11-27 00:02:21 +01:00
BufferedPacket p = *m_list.begin();
result = readU16(&p.data[BASE_HEADER_SIZE+1]);
return true;
2010-11-27 00:02:21 +01:00
}
2010-11-27 00:02:21 +01:00
BufferedPacket ReliablePacketBuffer::popFirst()
{
MutexAutoLock listlock(m_list_mutex);
[Patch 2/4] Network rework: packet writing, sending and cleanups NetworkPacket.cpp: * Remove some deprecated functions, we must use streaming interface * m_data converted from u8* to std::vector<u8> * Add an exporter to forge packet to Connection object * implement operator << std::wstring. n * implement operator << std::string * dynamic resize when write packet content. * fix string writing and performances. * create ServerCommandFactory, used by client to get useful informations about packet processing (sending). * Reliability * Transmit channel * Implement putRawString for some ugly char (_INIT packet), and use it. * Many packet read and write migrated * Implement oldForgePacket to interface writing with current connection * fix U8/char/bool writing * fix string writing and performances. * add some missing functions * Use v3s16 read instead of reading x,y,z separately * Add irr::video::SColor support into packets * Add some missing handlers * Add a template function to increase offset * Throw a serialization error on packet reading (must be improved) PacketFactories: * Create ServerCommandFactory, used by client to get useful informations about packet processing (sending). * Create ClientCommandFactory, used by server to get useful informations about packet processing (sending). Client.cpp: * implement NetworkPacket ::Send interface. * Move packet handlers to a dedicated file * Remove Client::Send(SharedBuffer) Server.cpp: * implement NetworkPacket ::Send interface. * Rewrite all packets using NetworkPacket * Move packet handlers to a dedicated file * Remove Server::Send(SharedBuffer) ClientIface.cpp: * Remove sendToAll(SharedBuffer<u8>) Connection.hpp rework: * Remove duplicate include * Remove duplicate negation * Remove a useless variable * Improve code performance by using a m_peers_list instead of scanning m_peers map * Remove Connection::Send(SharedBuffer) * Fix useafterfree into NetworkPacket Sending * Remove unused Connection::sendToAll Test.cpp: * Remove dead code * Update tests to use NetworkPackets Misc: * add new wrappers to Send packets in client, using NetworkPacket * Add NetworkPacket methods for Connection * coding style fix * dead code since changes cleanup * Use v3s16 read instead of reading x,y,z separately in some packets * Use different files to handle packets received by client and server * Cleanup: Remove useless includes ok @Zeno- Tested by @Zeno- @VanessaE and @nerzhul on running servers
2015-01-16 11:37:49 +01:00
if (m_list.empty())
2010-11-27 00:02:21 +01:00
throw NotFoundException("Buffer is empty");
BufferedPacket p = *m_list.begin();
2012-12-20 18:19:49 +01:00
m_list.erase(m_list.begin());
--m_list_size;
if (m_list_size == 0) {
m_oldest_non_answered_ack = 0;
} else {
m_oldest_non_answered_ack =
readU16(&(*m_list.begin()).data[BASE_HEADER_SIZE+1]);
}
2010-11-27 00:02:21 +01:00
return p;
}
BufferedPacket ReliablePacketBuffer::popSeqnum(u16 seqnum)
{
MutexAutoLock listlock(m_list_mutex);
2010-11-27 00:02:21 +01:00
RPBSearchResult r = findPacket(seqnum);
[Patch 2/4] Network rework: packet writing, sending and cleanups NetworkPacket.cpp: * Remove some deprecated functions, we must use streaming interface * m_data converted from u8* to std::vector<u8> * Add an exporter to forge packet to Connection object * implement operator << std::wstring. n * implement operator << std::string * dynamic resize when write packet content. * fix string writing and performances. * create ServerCommandFactory, used by client to get useful informations about packet processing (sending). * Reliability * Transmit channel * Implement putRawString for some ugly char (_INIT packet), and use it. * Many packet read and write migrated * Implement oldForgePacket to interface writing with current connection * fix U8/char/bool writing * fix string writing and performances. * add some missing functions * Use v3s16 read instead of reading x,y,z separately * Add irr::video::SColor support into packets * Add some missing handlers * Add a template function to increase offset * Throw a serialization error on packet reading (must be improved) PacketFactories: * Create ServerCommandFactory, used by client to get useful informations about packet processing (sending). * Create ClientCommandFactory, used by server to get useful informations about packet processing (sending). Client.cpp: * implement NetworkPacket ::Send interface. * Move packet handlers to a dedicated file * Remove Client::Send(SharedBuffer) Server.cpp: * implement NetworkPacket ::Send interface. * Rewrite all packets using NetworkPacket * Move packet handlers to a dedicated file * Remove Server::Send(SharedBuffer) ClientIface.cpp: * Remove sendToAll(SharedBuffer<u8>) Connection.hpp rework: * Remove duplicate include * Remove duplicate negation * Remove a useless variable * Improve code performance by using a m_peers_list instead of scanning m_peers map * Remove Connection::Send(SharedBuffer) * Fix useafterfree into NetworkPacket Sending * Remove unused Connection::sendToAll Test.cpp: * Remove dead code * Update tests to use NetworkPackets Misc: * add new wrappers to Send packets in client, using NetworkPacket * Add NetworkPacket methods for Connection * coding style fix * dead code since changes cleanup * Use v3s16 read instead of reading x,y,z separately in some packets * Use different files to handle packets received by client and server * Cleanup: Remove useless includes ok @Zeno- Tested by @Zeno- @VanessaE and @nerzhul on running servers
2015-01-16 11:37:49 +01:00
if (r == notFound()) {
LOG(dout_con<<"Sequence number: " << seqnum
<< " not found in reliable buffer"<<std::endl);
2010-11-27 00:02:21 +01:00
throw NotFoundException("seqnum not found in buffer");
}
BufferedPacket p = *r;
RPBSearchResult next = r;
2015-08-25 22:23:05 +02:00
++next;
if (next != notFound()) {
u16 s = readU16(&(next->data[BASE_HEADER_SIZE+1]));
m_oldest_non_answered_ack = s;
}
2010-11-27 00:02:21 +01:00
m_list.erase(r);
2012-12-20 18:19:49 +01:00
--m_list_size;
if (m_list_size == 0)
{ m_oldest_non_answered_ack = 0; }
else
{ m_oldest_non_answered_ack = readU16(&(*m_list.begin()).data[BASE_HEADER_SIZE+1]); }
2010-11-27 00:02:21 +01:00
return p;
}
void ReliablePacketBuffer::insert(BufferedPacket &p,u16 next_expected)
2010-11-27 00:02:21 +01:00
{
MutexAutoLock listlock(m_list_mutex);
if (p.data.getSize() < BASE_HEADER_SIZE + 3) {
errorstream << "ReliablePacketBuffer::insert(): Invalid data size for "
"reliable packet" << std::endl;
return;
}
u8 type = readU8(&p.data[BASE_HEADER_SIZE + 0]);
if (type != PACKET_TYPE_RELIABLE) {
errorstream << "ReliablePacketBuffer::insert(): type is not reliable"
<< std::endl;
return;
}
u16 seqnum = readU16(&p.data[BASE_HEADER_SIZE + 1]);
2010-11-27 00:02:21 +01:00
if (!seqnum_in_window(seqnum, next_expected, MAX_RELIABLE_WINDOW_SIZE)) {
errorstream << "ReliablePacketBuffer::insert(): seqnum is outside of "
"expected window " << std::endl;
return;
}
if (seqnum == next_expected) {
errorstream << "ReliablePacketBuffer::insert(): seqnum is next expected"
<< std::endl;
return;
}
2012-12-20 18:19:49 +01:00
++m_list_size;
sanity_check(m_list_size <= SEQNUM_MAX+1); // FIXME: Handle the error?
2010-11-27 00:02:21 +01:00
// Find the right place for the packet and insert it there
2010-11-27 00:02:21 +01:00
// If list is empty, just add it
[Patch 2/4] Network rework: packet writing, sending and cleanups NetworkPacket.cpp: * Remove some deprecated functions, we must use streaming interface * m_data converted from u8* to std::vector<u8> * Add an exporter to forge packet to Connection object * implement operator << std::wstring. n * implement operator << std::string * dynamic resize when write packet content. * fix string writing and performances. * create ServerCommandFactory, used by client to get useful informations about packet processing (sending). * Reliability * Transmit channel * Implement putRawString for some ugly char (_INIT packet), and use it. * Many packet read and write migrated * Implement oldForgePacket to interface writing with current connection * fix U8/char/bool writing * fix string writing and performances. * add some missing functions * Use v3s16 read instead of reading x,y,z separately * Add irr::video::SColor support into packets * Add some missing handlers * Add a template function to increase offset * Throw a serialization error on packet reading (must be improved) PacketFactories: * Create ServerCommandFactory, used by client to get useful informations about packet processing (sending). * Create ClientCommandFactory, used by server to get useful informations about packet processing (sending). Client.cpp: * implement NetworkPacket ::Send interface. * Move packet handlers to a dedicated file * Remove Client::Send(SharedBuffer) Server.cpp: * implement NetworkPacket ::Send interface. * Rewrite all packets using NetworkPacket * Move packet handlers to a dedicated file * Remove Server::Send(SharedBuffer) ClientIface.cpp: * Remove sendToAll(SharedBuffer<u8>) Connection.hpp rework: * Remove duplicate include * Remove duplicate negation * Remove a useless variable * Improve code performance by using a m_peers_list instead of scanning m_peers map * Remove Connection::Send(SharedBuffer) * Fix useafterfree into NetworkPacket Sending * Remove unused Connection::sendToAll Test.cpp: * Remove dead code * Update tests to use NetworkPackets Misc: * add new wrappers to Send packets in client, using NetworkPacket * Add NetworkPacket methods for Connection * coding style fix * dead code since changes cleanup * Use v3s16 read instead of reading x,y,z separately in some packets * Use different files to handle packets received by client and server * Cleanup: Remove useless includes ok @Zeno- Tested by @Zeno- @VanessaE and @nerzhul on running servers
2015-01-16 11:37:49 +01:00
if (m_list.empty())
2010-11-27 00:02:21 +01:00
{
m_list.push_back(p);
m_oldest_non_answered_ack = seqnum;
2010-11-27 00:02:21 +01:00
// Done.
return;
}
2010-11-27 00:02:21 +01:00
// Otherwise find the right place
2012-12-20 18:19:49 +01:00
std::list<BufferedPacket>::iterator i = m_list.begin();
2010-11-27 00:02:21 +01:00
// Find the first packet in the list which has a higher seqnum
u16 s = readU16(&(i->data[BASE_HEADER_SIZE+1]));
/* case seqnum is smaller then next_expected seqnum */
/* this is true e.g. on wrap around */
if (seqnum < next_expected) {
while(((s < seqnum) || (s >= next_expected)) && (i != m_list.end())) {
2015-08-25 22:23:05 +02:00
++i;
if (i != m_list.end())
s = readU16(&(i->data[BASE_HEADER_SIZE+1]));
2010-11-27 00:02:21 +01:00
}
}
/* non wrap around case (at least for incoming and next_expected */
else
2010-11-27 00:02:21 +01:00
{
while(((s < seqnum) && (s >= next_expected)) && (i != m_list.end())) {
2015-08-25 22:23:05 +02:00
++i;
if (i != m_list.end())
s = readU16(&(i->data[BASE_HEADER_SIZE+1]));
}
}
if (s == seqnum) {
/* nothing to do this seems to be a resent packet */
/* for paranoia reason data should be compared */
--m_list_size;
if (
(readU16(&(i->data[BASE_HEADER_SIZE+1])) != seqnum) ||
(i->data.getSize() != p.data.getSize()) ||
(i->address != p.address)
)
{
/* if this happens your maximum transfer window may be to big */
fprintf(stderr,
"Duplicated seqnum %d non matching packet detected:\n",
seqnum);
fprintf(stderr, "Old: seqnum: %05d size: %04d, address: %s\n",
readU16(&(i->data[BASE_HEADER_SIZE+1])),i->data.getSize(),
i->address.serializeString().c_str());
2015-01-10 12:05:42 +01:00
fprintf(stderr, "New: seqnum: %05d size: %04u, address: %s\n",
readU16(&(p.data[BASE_HEADER_SIZE+1])),p.data.getSize(),
p.address.serializeString().c_str());
throw IncomingDataCorruption("duplicated packet isn't same as original one");
}
}
/* insert or push back */
else if (i != m_list.end()) {
m_list.insert(i, p);
}
else {
2010-11-27 00:02:21 +01:00
m_list.push_back(p);
}
/* update last packet number */
m_oldest_non_answered_ack = readU16(&(*m_list.begin()).data[BASE_HEADER_SIZE+1]);
2010-11-27 00:02:21 +01:00
}
void ReliablePacketBuffer::incrementTimeouts(float dtime)
{
MutexAutoLock listlock(m_list_mutex);
for (BufferedPacket &bufferedPacket : m_list) {
bufferedPacket.time += dtime;
bufferedPacket.totaltime += dtime;
2010-11-27 00:02:21 +01:00
}
}
std::list<BufferedPacket> ReliablePacketBuffer::getTimedOuts(float timeout,
unsigned int max_packets)
2010-11-27 00:02:21 +01:00
{
MutexAutoLock listlock(m_list_mutex);
2012-12-20 18:19:49 +01:00
std::list<BufferedPacket> timed_outs;
for (BufferedPacket &bufferedPacket : m_list) {
if (bufferedPacket.time >= timeout) {
timed_outs.push_back(bufferedPacket);
//this packet will be sent right afterwards reset timeout here
bufferedPacket.time = 0.0f;
if (timed_outs.size() >= max_packets)
break;
}
2010-11-27 00:02:21 +01:00
}
return timed_outs;
}
/*
IncomingSplitBuffer
*/
IncomingSplitBuffer::~IncomingSplitBuffer()
{
MutexAutoLock listlock(m_map_mutex);
for (auto &i : m_buf) {
delete i.second;
2010-11-27 00:02:21 +01:00
}
}
/*
This will throw a GotSplitPacketException when a full
split packet is constructed.
*/
SharedBuffer<u8> IncomingSplitBuffer::insert(const BufferedPacket &p, bool reliable)
2010-11-27 00:02:21 +01:00
{
MutexAutoLock listlock(m_map_mutex);
2010-11-27 00:02:21 +01:00
u32 headersize = BASE_HEADER_SIZE + 7;
if (p.data.getSize() < headersize) {
errorstream << "Invalid data size for split packet" << std::endl;
return SharedBuffer<u8>();
}
2010-11-27 00:02:21 +01:00
u8 type = readU8(&p.data[BASE_HEADER_SIZE+0]);
u16 seqnum = readU16(&p.data[BASE_HEADER_SIZE+1]);
u16 chunk_count = readU16(&p.data[BASE_HEADER_SIZE+3]);
u16 chunk_num = readU16(&p.data[BASE_HEADER_SIZE+5]);
if (type != PACKET_TYPE_SPLIT) {
errorstream << "IncomingSplitBuffer::insert(): type is not split"
<< std::endl;
return SharedBuffer<u8>();
}
if (chunk_num >= chunk_count) {
errorstream << "IncomingSplitBuffer::insert(): chunk_num=" << chunk_num
<< " >= chunk_count=" << chunk_count << std::endl;
return SharedBuffer<u8>();
}
2010-11-27 00:02:21 +01:00
// Add if doesn't exist
if (m_buf.find(seqnum) == m_buf.end()) {
m_buf[seqnum] = new IncomingSplitPacket(chunk_count, reliable);
2010-11-27 00:02:21 +01:00
}
2010-11-27 00:02:21 +01:00
IncomingSplitPacket *sp = m_buf[seqnum];
if (chunk_count != sp->chunk_count) {
errorstream << "IncomingSplitBuffer::insert(): chunk_count="
<< chunk_count << " != sp->chunk_count=" << sp->chunk_count
<< std::endl;
return SharedBuffer<u8>();
}
[Patch 2/4] Network rework: packet writing, sending and cleanups NetworkPacket.cpp: * Remove some deprecated functions, we must use streaming interface * m_data converted from u8* to std::vector<u8> * Add an exporter to forge packet to Connection object * implement operator << std::wstring. n * implement operator << std::string * dynamic resize when write packet content. * fix string writing and performances. * create ServerCommandFactory, used by client to get useful informations about packet processing (sending). * Reliability * Transmit channel * Implement putRawString for some ugly char (_INIT packet), and use it. * Many packet read and write migrated * Implement oldForgePacket to interface writing with current connection * fix U8/char/bool writing * fix string writing and performances. * add some missing functions * Use v3s16 read instead of reading x,y,z separately * Add irr::video::SColor support into packets * Add some missing handlers * Add a template function to increase offset * Throw a serialization error on packet reading (must be improved) PacketFactories: * Create ServerCommandFactory, used by client to get useful informations about packet processing (sending). * Create ClientCommandFactory, used by server to get useful informations about packet processing (sending). Client.cpp: * implement NetworkPacket ::Send interface. * Move packet handlers to a dedicated file * Remove Client::Send(SharedBuffer) Server.cpp: * implement NetworkPacket ::Send interface. * Rewrite all packets using NetworkPacket * Move packet handlers to a dedicated file * Remove Server::Send(SharedBuffer) ClientIface.cpp: * Remove sendToAll(SharedBuffer<u8>) Connection.hpp rework: * Remove duplicate include * Remove duplicate negation * Remove a useless variable * Improve code performance by using a m_peers_list instead of scanning m_peers map * Remove Connection::Send(SharedBuffer) * Fix useafterfree into NetworkPacket Sending * Remove unused Connection::sendToAll Test.cpp: * Remove dead code * Update tests to use NetworkPackets Misc: * add new wrappers to Send packets in client, using NetworkPacket * Add NetworkPacket methods for Connection * coding style fix * dead code since changes cleanup * Use v3s16 read instead of reading x,y,z separately in some packets * Use different files to handle packets received by client and server * Cleanup: Remove useless includes ok @Zeno- Tested by @Zeno- @VanessaE and @nerzhul on running servers
2015-01-16 11:37:49 +01:00
if (reliable != sp->reliable)
LOG(derr_con<<"Connection: WARNING: reliable="<<reliable
2010-11-27 00:02:21 +01:00
<<" != sp->reliable="<<sp->reliable
<<std::endl);
2010-11-27 00:02:21 +01:00
// If chunk already exists, ignore it.
// Sometimes two identical packets may arrive when there is network
// lag and the server re-sends stuff.
[Patch 2/4] Network rework: packet writing, sending and cleanups NetworkPacket.cpp: * Remove some deprecated functions, we must use streaming interface * m_data converted from u8* to std::vector<u8> * Add an exporter to forge packet to Connection object * implement operator << std::wstring. n * implement operator << std::string * dynamic resize when write packet content. * fix string writing and performances. * create ServerCommandFactory, used by client to get useful informations about packet processing (sending). * Reliability * Transmit channel * Implement putRawString for some ugly char (_INIT packet), and use it. * Many packet read and write migrated * Implement oldForgePacket to interface writing with current connection * fix U8/char/bool writing * fix string writing and performances. * add some missing functions * Use v3s16 read instead of reading x,y,z separately * Add irr::video::SColor support into packets * Add some missing handlers * Add a template function to increase offset * Throw a serialization error on packet reading (must be improved) PacketFactories: * Create ServerCommandFactory, used by client to get useful informations about packet processing (sending). * Create ClientCommandFactory, used by server to get useful informations about packet processing (sending). Client.cpp: * implement NetworkPacket ::Send interface. * Move packet handlers to a dedicated file * Remove Client::Send(SharedBuffer) Server.cpp: * implement NetworkPacket ::Send interface. * Rewrite all packets using NetworkPacket * Move packet handlers to a dedicated file * Remove Server::Send(SharedBuffer) ClientIface.cpp: * Remove sendToAll(SharedBuffer<u8>) Connection.hpp rework: * Remove duplicate include * Remove duplicate negation * Remove a useless variable * Improve code performance by using a m_peers_list instead of scanning m_peers map * Remove Connection::Send(SharedBuffer) * Fix useafterfree into NetworkPacket Sending * Remove unused Connection::sendToAll Test.cpp: * Remove dead code * Update tests to use NetworkPackets Misc: * add new wrappers to Send packets in client, using NetworkPacket * Add NetworkPacket methods for Connection * coding style fix * dead code since changes cleanup * Use v3s16 read instead of reading x,y,z separately in some packets * Use different files to handle packets received by client and server * Cleanup: Remove useless includes ok @Zeno- Tested by @Zeno- @VanessaE and @nerzhul on running servers
2015-01-16 11:37:49 +01:00
if (sp->chunks.find(chunk_num) != sp->chunks.end())
return SharedBuffer<u8>();
2010-11-27 00:02:21 +01:00
// Cut chunk data out of packet
u32 chunkdatasize = p.data.getSize() - headersize;
SharedBuffer<u8> chunkdata(chunkdatasize);
memcpy(*chunkdata, &(p.data[headersize]), chunkdatasize);
2010-11-27 00:02:21 +01:00
// Set chunk data in buffer
sp->chunks[chunk_num] = chunkdata;
// If not all chunks are received, return empty buffer
if (!sp->allReceived())
return SharedBuffer<u8>();
2010-11-27 00:02:21 +01:00
// Calculate total size
u32 totalsize = 0;
for (const auto &chunk : sp->chunks) {
totalsize += chunk.second.getSize();
2010-11-27 00:02:21 +01:00
}
2010-11-27 00:02:21 +01:00
SharedBuffer<u8> fulldata(totalsize);
// Copy chunks to data buffer
u32 start = 0;
for (u32 chunk_i=0; chunk_i<sp->chunk_count; chunk_i++) {
const SharedBuffer<u8> &buf = sp->chunks[chunk_i];
u16 buf_chunkdatasize = buf.getSize();
memcpy(&fulldata[start], *buf, buf_chunkdatasize);
start += buf_chunkdatasize;
2010-11-27 00:02:21 +01:00
}
// Remove sp from buffer
2012-12-20 18:19:49 +01:00
m_buf.erase(seqnum);
2010-11-27 00:02:21 +01:00
delete sp;
return fulldata;
2010-11-27 00:02:21 +01:00
}
void IncomingSplitBuffer::removeUnreliableTimedOuts(float dtime, float timeout)
{
std::deque<u16> remove_queue;
2010-11-27 00:02:21 +01:00
{
MutexAutoLock listlock(m_map_mutex);
for (auto &i : m_buf) {
IncomingSplitPacket *p = i.second;
// Reliable ones are not removed by timeout
if (p->reliable)
continue;
p->time += dtime;
[Patch 2/4] Network rework: packet writing, sending and cleanups NetworkPacket.cpp: * Remove some deprecated functions, we must use streaming interface * m_data converted from u8* to std::vector<u8> * Add an exporter to forge packet to Connection object * implement operator << std::wstring. n * implement operator << std::string * dynamic resize when write packet content. * fix string writing and performances. * create ServerCommandFactory, used by client to get useful informations about packet processing (sending). * Reliability * Transmit channel * Implement putRawString for some ugly char (_INIT packet), and use it. * Many packet read and write migrated * Implement oldForgePacket to interface writing with current connection * fix U8/char/bool writing * fix string writing and performances. * add some missing functions * Use v3s16 read instead of reading x,y,z separately * Add irr::video::SColor support into packets * Add some missing handlers * Add a template function to increase offset * Throw a serialization error on packet reading (must be improved) PacketFactories: * Create ServerCommandFactory, used by client to get useful informations about packet processing (sending). * Create ClientCommandFactory, used by server to get useful informations about packet processing (sending). Client.cpp: * implement NetworkPacket ::Send interface. * Move packet handlers to a dedicated file * Remove Client::Send(SharedBuffer) Server.cpp: * implement NetworkPacket ::Send interface. * Rewrite all packets using NetworkPacket * Move packet handlers to a dedicated file * Remove Server::Send(SharedBuffer) ClientIface.cpp: * Remove sendToAll(SharedBuffer<u8>) Connection.hpp rework: * Remove duplicate include * Remove duplicate negation * Remove a useless variable * Improve code performance by using a m_peers_list instead of scanning m_peers map * Remove Connection::Send(SharedBuffer) * Fix useafterfree into NetworkPacket Sending * Remove unused Connection::sendToAll Test.cpp: * Remove dead code * Update tests to use NetworkPackets Misc: * add new wrappers to Send packets in client, using NetworkPacket * Add NetworkPacket methods for Connection * coding style fix * dead code since changes cleanup * Use v3s16 read instead of reading x,y,z separately in some packets * Use different files to handle packets received by client and server * Cleanup: Remove useless includes ok @Zeno- Tested by @Zeno- @VanessaE and @nerzhul on running servers
2015-01-16 11:37:49 +01:00
if (p->time >= timeout)
remove_queue.push_back(i.first);
}
2010-11-27 00:02:21 +01:00
}
for (u16 j : remove_queue) {
MutexAutoLock listlock(m_map_mutex);
LOG(dout_con<<"NOTE: Removing timed out unreliable split packet"<<std::endl);
delete m_buf[j];
m_buf.erase(j);
2010-11-27 00:02:21 +01:00
}
}
/*
ConnectionCommand
*/
void ConnectionCommand::send(session_t peer_id_, u8 channelnum_, NetworkPacket *pkt,
bool reliable_)
{
type = CONNCMD_SEND;
peer_id = peer_id_;
channelnum = channelnum_;
data = pkt->oldForgePacket();
reliable = reliable_;
}
2010-11-27 00:02:21 +01:00
/*
Channel
*/
u16 Channel::readNextIncomingSeqNum()
2010-11-27 00:02:21 +01:00
{
MutexAutoLock internal(m_internal_mutex);
return next_incoming_seqnum;
2010-11-27 00:02:21 +01:00
}
u16 Channel::incNextIncomingSeqNum()
2010-11-27 00:02:21 +01:00
{
MutexAutoLock internal(m_internal_mutex);
u16 retval = next_incoming_seqnum;
next_incoming_seqnum++;
return retval;
2010-11-27 00:02:21 +01:00
}
u16 Channel::readNextSplitSeqNum()
2010-11-27 00:02:21 +01:00
{
MutexAutoLock internal(m_internal_mutex);
return next_outgoing_split_seqnum;
2010-11-27 00:02:21 +01:00
}
void Channel::setNextSplitSeqNum(u16 seqnum)
2010-11-27 00:02:21 +01:00
{
MutexAutoLock internal(m_internal_mutex);
next_outgoing_split_seqnum = seqnum;
2010-11-27 00:02:21 +01:00
}
u16 Channel::getOutgoingSequenceNumber(bool& successful)
2010-11-27 00:02:21 +01:00
{
MutexAutoLock internal(m_internal_mutex);
u16 retval = next_outgoing_seqnum;
u16 lowest_unacked_seqnumber;
2010-11-27 00:02:21 +01:00
/* shortcut if there ain't any packet in outgoing list */
if (outgoing_reliables_sent.empty())
{
next_outgoing_seqnum++;
return retval;
}
if (outgoing_reliables_sent.getFirstSeqnum(lowest_unacked_seqnumber))
2012-03-20 16:55:34 +01:00
{
if (lowest_unacked_seqnumber < next_outgoing_seqnum) {
// ugly cast but this one is required in order to tell compiler we
// know about difference of two unsigned may be negative in general
// but we already made sure it won't happen in this case
if (((u16)(next_outgoing_seqnum - lowest_unacked_seqnumber)) > window_size) {
successful = false;
return 0;
}
}
else {
// ugly cast but this one is required in order to tell compiler we
// know about difference of two unsigned may be negative in general
// but we already made sure it won't happen in this case
if ((next_outgoing_seqnum + (u16)(SEQNUM_MAX - lowest_unacked_seqnumber)) >
window_size) {
successful = false;
return 0;
}
}
2012-03-20 16:55:34 +01:00
}
2010-11-27 00:02:21 +01:00
next_outgoing_seqnum++;
return retval;
}
u16 Channel::readOutgoingSequenceNumber()
2010-11-27 00:02:21 +01:00
{
MutexAutoLock internal(m_internal_mutex);
return next_outgoing_seqnum;
}
bool Channel::putBackSequenceNumber(u16 seqnum)
{
if (((seqnum + 1) % (SEQNUM_MAX+1)) == next_outgoing_seqnum) {
next_outgoing_seqnum = seqnum;
return true;
}
return false;
}
2010-11-27 00:02:21 +01:00
void Channel::UpdateBytesSent(unsigned int bytes, unsigned int packets)
{
MutexAutoLock internal(m_internal_mutex);
current_bytes_transfered += bytes;
2018-07-14 20:38:52 +02:00
current_packet_successful += packets;
2010-11-27 00:02:21 +01:00
}
void Channel::UpdateBytesReceived(unsigned int bytes) {
MutexAutoLock internal(m_internal_mutex);
current_bytes_received += bytes;
}
void Channel::UpdateBytesLost(unsigned int bytes)
{
MutexAutoLock internal(m_internal_mutex);
current_bytes_lost += bytes;
}
void Channel::UpdatePacketLossCounter(unsigned int count)
2010-11-27 00:02:21 +01:00
{
MutexAutoLock internal(m_internal_mutex);
current_packet_loss += count;
2010-11-27 00:02:21 +01:00
}
void Channel::UpdatePacketTooLateCounter()
2010-11-27 00:02:21 +01:00
{
MutexAutoLock internal(m_internal_mutex);
current_packet_too_late++;
}
2010-11-27 00:02:21 +01:00
2018-07-14 20:38:52 +02:00
void Channel::UpdateTimers(float dtime)
{
bpm_counter += dtime;
packet_loss_counter += dtime;
2010-11-27 00:02:21 +01:00
2018-07-14 20:38:52 +02:00
if (packet_loss_counter > 1.0f) {
packet_loss_counter -= 1.0f;
unsigned int packet_loss = 11; /* use a neutral value for initialization */
2018-07-14 20:38:52 +02:00
unsigned int packets_successful = 0;
//unsigned int packet_too_late = 0;
bool reasonable_amount_of_data_transmitted = false;
2010-11-27 00:02:21 +01:00
{
MutexAutoLock internal(m_internal_mutex);
packet_loss = current_packet_loss;
//packet_too_late = current_packet_too_late;
2018-07-14 20:38:52 +02:00
packets_successful = current_packet_successful;
2018-07-14 20:38:52 +02:00
if (current_bytes_transfered > (unsigned int) (window_size*512/2)) {
reasonable_amount_of_data_transmitted = true;
2010-11-27 00:02:21 +01:00
}
current_packet_loss = 0;
current_packet_too_late = 0;
2018-07-14 20:38:52 +02:00
current_packet_successful = 0;
}
2010-11-27 00:02:21 +01:00
2018-07-14 20:38:52 +02:00
/* dynamic window size */
float successful_to_lost_ratio = 0.0f;
bool done = false;
if (packets_successful > 0) {
successful_to_lost_ratio = packet_loss/packets_successful;
} else if (packet_loss > 0) {
window_size = std::max(
(window_size - 10),
MIN_RELIABLE_WINDOW_SIZE);
done = true;
}
2018-07-14 20:38:52 +02:00
if (!done) {
if ((successful_to_lost_ratio < 0.01f) &&
(window_size < MAX_RELIABLE_WINDOW_SIZE)) {
/* don't even think about increasing if we didn't even
* use major parts of our window */
if (reasonable_amount_of_data_transmitted)
window_size = std::min(
(window_size + 100),
MAX_RELIABLE_WINDOW_SIZE);
} else if ((successful_to_lost_ratio < 0.05f) &&
(window_size < MAX_RELIABLE_WINDOW_SIZE)) {
/* don't even think about increasing if we didn't even
* use major parts of our window */
if (reasonable_amount_of_data_transmitted)
window_size = std::min(
(window_size + 50),
MAX_RELIABLE_WINDOW_SIZE);
} else if (successful_to_lost_ratio > 0.15f) {
window_size = std::max(
(window_size - 100),
MIN_RELIABLE_WINDOW_SIZE);
} else if (successful_to_lost_ratio > 0.1f) {
window_size = std::max(
(window_size - 50),
MIN_RELIABLE_WINDOW_SIZE);
}
2010-11-27 00:02:21 +01:00
}
}
2010-11-27 00:02:21 +01:00
2018-07-14 20:38:52 +02:00
if (bpm_counter > 10.0f) {
2010-11-27 00:02:21 +01:00
{
MutexAutoLock internal(m_internal_mutex);
cur_kbps =
2018-07-14 20:38:52 +02:00
(((float) current_bytes_transfered)/bpm_counter)/1024.0f;
current_bytes_transfered = 0;
cur_kbps_lost =
2018-07-14 20:38:52 +02:00
(((float) current_bytes_lost)/bpm_counter)/1024.0f;
current_bytes_lost = 0;
cur_incoming_kbps =
2018-07-14 20:38:52 +02:00
(((float) current_bytes_received)/bpm_counter)/1024.0f;
current_bytes_received = 0;
2018-07-14 20:38:52 +02:00
bpm_counter = 0.0f;
2010-11-27 00:02:21 +01:00
}
2018-07-14 20:38:52 +02:00
if (cur_kbps > max_kbps) {
max_kbps = cur_kbps;
}
2010-11-27 00:02:21 +01:00
2018-07-14 20:38:52 +02:00
if (cur_kbps_lost > max_kbps_lost) {
max_kbps_lost = cur_kbps_lost;
}
2010-11-27 00:02:21 +01:00
if (cur_incoming_kbps > max_incoming_kbps) {
max_incoming_kbps = cur_incoming_kbps;
}
rate_samples = MYMIN(rate_samples+1,10);
float old_fraction = ((float) (rate_samples-1) )/( (float) rate_samples);
avg_kbps = avg_kbps * old_fraction +
cur_kbps * (1.0 - old_fraction);
avg_kbps_lost = avg_kbps_lost * old_fraction +
cur_kbps_lost * (1.0 - old_fraction);
avg_incoming_kbps = avg_incoming_kbps * old_fraction +
cur_incoming_kbps * (1.0 - old_fraction);
}
}
/*
Peer
*/
PeerHelper::PeerHelper(Peer* peer) :
m_peer(peer)
{
if (peer && !peer->IncUseCount())
m_peer = nullptr;
}
PeerHelper::~PeerHelper()
{
if (m_peer)
m_peer->DecUseCount();
m_peer = nullptr;
}
PeerHelper& PeerHelper::operator=(Peer* peer)
{
m_peer = peer;
if (peer && !peer->IncUseCount())
m_peer = nullptr;
return *this;
}
Peer* PeerHelper::operator->() const
{
return m_peer;
}
Peer* PeerHelper::operator&() const
{
return m_peer;
}
bool PeerHelper::operator!()
{
return ! m_peer;
}
bool PeerHelper::operator!=(void* ptr)
{
return ((void*) m_peer != ptr);
}
bool Peer::IncUseCount()
{
MutexAutoLock lock(m_exclusive_access_mutex);
if (!m_pending_deletion) {
this->m_usage++;
return true;
}
return false;
}
void Peer::DecUseCount()
{
{
MutexAutoLock lock(m_exclusive_access_mutex);
sanity_check(m_usage > 0);
m_usage--;
if (!((m_pending_deletion) && (m_usage == 0)))
return;
}
delete this;
}
void Peer::RTTStatistics(float rtt, const std::string &profiler_id,
unsigned int num_samples) {
if (m_last_rtt > 0) {
/* set min max values */
if (rtt < m_rtt.min_rtt)
m_rtt.min_rtt = rtt;
if (rtt >= m_rtt.max_rtt)
m_rtt.max_rtt = rtt;
/* do average calculation */
[Patch 2/4] Network rework: packet writing, sending and cleanups NetworkPacket.cpp: * Remove some deprecated functions, we must use streaming interface * m_data converted from u8* to std::vector<u8> * Add an exporter to forge packet to Connection object * implement operator << std::wstring. n * implement operator << std::string * dynamic resize when write packet content. * fix string writing and performances. * create ServerCommandFactory, used by client to get useful informations about packet processing (sending). * Reliability * Transmit channel * Implement putRawString for some ugly char (_INIT packet), and use it. * Many packet read and write migrated * Implement oldForgePacket to interface writing with current connection * fix U8/char/bool writing * fix string writing and performances. * add some missing functions * Use v3s16 read instead of reading x,y,z separately * Add irr::video::SColor support into packets * Add some missing handlers * Add a template function to increase offset * Throw a serialization error on packet reading (must be improved) PacketFactories: * Create ServerCommandFactory, used by client to get useful informations about packet processing (sending). * Create ClientCommandFactory, used by server to get useful informations about packet processing (sending). Client.cpp: * implement NetworkPacket ::Send interface. * Move packet handlers to a dedicated file * Remove Client::Send(SharedBuffer) Server.cpp: * implement NetworkPacket ::Send interface. * Rewrite all packets using NetworkPacket * Move packet handlers to a dedicated file * Remove Server::Send(SharedBuffer) ClientIface.cpp: * Remove sendToAll(SharedBuffer<u8>) Connection.hpp rework: * Remove duplicate include * Remove duplicate negation * Remove a useless variable * Improve code performance by using a m_peers_list instead of scanning m_peers map * Remove Connection::Send(SharedBuffer) * Fix useafterfree into NetworkPacket Sending * Remove unused Connection::sendToAll Test.cpp: * Remove dead code * Update tests to use NetworkPackets Misc: * add new wrappers to Send packets in client, using NetworkPacket * Add NetworkPacket methods for Connection * coding style fix * dead code since changes cleanup * Use v3s16 read instead of reading x,y,z separately in some packets * Use different files to handle packets received by client and server * Cleanup: Remove useless includes ok @Zeno- Tested by @Zeno- @VanessaE and @nerzhul on running servers
2015-01-16 11:37:49 +01:00
if (m_rtt.avg_rtt < 0.0)
m_rtt.avg_rtt = rtt;
else
m_rtt.avg_rtt = m_rtt.avg_rtt * (num_samples/(num_samples-1)) +
rtt * (1/num_samples);
/* do jitter calculation */
//just use some neutral value at beginning
float jitter = m_rtt.jitter_min;
if (rtt > m_last_rtt)
jitter = rtt-m_last_rtt;
if (rtt <= m_last_rtt)
jitter = m_last_rtt - rtt;
if (jitter < m_rtt.jitter_min)
m_rtt.jitter_min = jitter;
if (jitter >= m_rtt.jitter_max)
m_rtt.jitter_max = jitter;
[Patch 2/4] Network rework: packet writing, sending and cleanups NetworkPacket.cpp: * Remove some deprecated functions, we must use streaming interface * m_data converted from u8* to std::vector<u8> * Add an exporter to forge packet to Connection object * implement operator << std::wstring. n * implement operator << std::string * dynamic resize when write packet content. * fix string writing and performances. * create ServerCommandFactory, used by client to get useful informations about packet processing (sending). * Reliability * Transmit channel * Implement putRawString for some ugly char (_INIT packet), and use it. * Many packet read and write migrated * Implement oldForgePacket to interface writing with current connection * fix U8/char/bool writing * fix string writing and performances. * add some missing functions * Use v3s16 read instead of reading x,y,z separately * Add irr::video::SColor support into packets * Add some missing handlers * Add a template function to increase offset * Throw a serialization error on packet reading (must be improved) PacketFactories: * Create ServerCommandFactory, used by client to get useful informations about packet processing (sending). * Create ClientCommandFactory, used by server to get useful informations about packet processing (sending). Client.cpp: * implement NetworkPacket ::Send interface. * Move packet handlers to a dedicated file * Remove Client::Send(SharedBuffer) Server.cpp: * implement NetworkPacket ::Send interface. * Rewrite all packets using NetworkPacket * Move packet handlers to a dedicated file * Remove Server::Send(SharedBuffer) ClientIface.cpp: * Remove sendToAll(SharedBuffer<u8>) Connection.hpp rework: * Remove duplicate include * Remove duplicate negation * Remove a useless variable * Improve code performance by using a m_peers_list instead of scanning m_peers map * Remove Connection::Send(SharedBuffer) * Fix useafterfree into NetworkPacket Sending * Remove unused Connection::sendToAll Test.cpp: * Remove dead code * Update tests to use NetworkPackets Misc: * add new wrappers to Send packets in client, using NetworkPacket * Add NetworkPacket methods for Connection * coding style fix * dead code since changes cleanup * Use v3s16 read instead of reading x,y,z separately in some packets * Use different files to handle packets received by client and server * Cleanup: Remove useless includes ok @Zeno- Tested by @Zeno- @VanessaE and @nerzhul on running servers
2015-01-16 11:37:49 +01:00
if (m_rtt.jitter_avg < 0.0)
m_rtt.jitter_avg = jitter;
else
m_rtt.jitter_avg = m_rtt.jitter_avg * (num_samples/(num_samples-1)) +
jitter * (1/num_samples);
if (!profiler_id.empty()) {
g_profiler->graphAdd(profiler_id + " RTT [ms]", rtt * 1000.f);
g_profiler->graphAdd(profiler_id + " jitter [ms]", jitter * 1000.f);
}
}
/* save values required for next loop */
m_last_rtt = rtt;
}
bool Peer::isTimedOut(float timeout)
{
MutexAutoLock lock(m_exclusive_access_mutex);
u64 current_time = porting::getTimeMs();
float dtime = CALC_DTIME(m_last_timeout_check,current_time);
m_last_timeout_check = current_time;
m_timeout_counter += dtime;
return m_timeout_counter > timeout;
}
void Peer::Drop()
{
{
MutexAutoLock usage_lock(m_exclusive_access_mutex);
m_pending_deletion = true;
if (m_usage != 0)
return;
}
PROFILE(std::stringstream peerIdentifier1);
PROFILE(peerIdentifier1 << "runTimeouts[" << m_connection->getDesc()
<< ";" << id << ";RELIABLE]");
PROFILE(g_profiler->remove(peerIdentifier1.str()));
PROFILE(std::stringstream peerIdentifier2);
PROFILE(peerIdentifier2 << "sendPackets[" << m_connection->getDesc()
<< ";" << id << ";RELIABLE]");
PROFILE(ScopeProfiler peerprofiler(g_profiler, peerIdentifier2.str(), SPT_AVG));
delete this;
}
UDPPeer::UDPPeer(u16 a_id, Address a_address, Connection* connection) :
Peer(a_address,a_id,connection)
{
2018-07-14 20:38:52 +02:00
for (Channel &channel : channels)
channel.setWindowSize(g_settings->getU16("max_packets_per_iteration"));
}
bool UDPPeer::getAddress(MTProtocols type,Address& toset)
{
if ((type == MTP_UDP) || (type == MTP_MINETEST_RELIABLE_UDP) || (type == MTP_PRIMARY))
{
toset = address;
return true;
}
return false;
}
void UDPPeer::reportRTT(float rtt)
{
if (rtt < 0.0) {
return;
}
RTTStatistics(rtt,"rudp",MAX_RELIABLE_WINDOW_SIZE*10);
float timeout = getStat(AVG_RTT) * RESEND_TIMEOUT_FACTOR;
if (timeout < RESEND_TIMEOUT_MIN)
timeout = RESEND_TIMEOUT_MIN;
if (timeout > RESEND_TIMEOUT_MAX)
timeout = RESEND_TIMEOUT_MAX;
MutexAutoLock usage_lock(m_exclusive_access_mutex);
resend_timeout = timeout;
}
bool UDPPeer::Ping(float dtime,SharedBuffer<u8>& data)
{
m_ping_timer += dtime;
[Patch 2/4] Network rework: packet writing, sending and cleanups NetworkPacket.cpp: * Remove some deprecated functions, we must use streaming interface * m_data converted from u8* to std::vector<u8> * Add an exporter to forge packet to Connection object * implement operator << std::wstring. n * implement operator << std::string * dynamic resize when write packet content. * fix string writing and performances. * create ServerCommandFactory, used by client to get useful informations about packet processing (sending). * Reliability * Transmit channel * Implement putRawString for some ugly char (_INIT packet), and use it. * Many packet read and write migrated * Implement oldForgePacket to interface writing with current connection * fix U8/char/bool writing * fix string writing and performances. * add some missing functions * Use v3s16 read instead of reading x,y,z separately * Add irr::video::SColor support into packets * Add some missing handlers * Add a template function to increase offset * Throw a serialization error on packet reading (must be improved) PacketFactories: * Create ServerCommandFactory, used by client to get useful informations about packet processing (sending). * Create ClientCommandFactory, used by server to get useful informations about packet processing (sending). Client.cpp: * implement NetworkPacket ::Send interface. * Move packet handlers to a dedicated file * Remove Client::Send(SharedBuffer) Server.cpp: * implement NetworkPacket ::Send interface. * Rewrite all packets using NetworkPacket * Move packet handlers to a dedicated file * Remove Server::Send(SharedBuffer) ClientIface.cpp: * Remove sendToAll(SharedBuffer<u8>) Connection.hpp rework: * Remove duplicate include * Remove duplicate negation * Remove a useless variable * Improve code performance by using a m_peers_list instead of scanning m_peers map * Remove Connection::Send(SharedBuffer) * Fix useafterfree into NetworkPacket Sending * Remove unused Connection::sendToAll Test.cpp: * Remove dead code * Update tests to use NetworkPackets Misc: * add new wrappers to Send packets in client, using NetworkPacket * Add NetworkPacket methods for Connection * coding style fix * dead code since changes cleanup * Use v3s16 read instead of reading x,y,z separately in some packets * Use different files to handle packets received by client and server * Cleanup: Remove useless includes ok @Zeno- Tested by @Zeno- @VanessaE and @nerzhul on running servers
2015-01-16 11:37:49 +01:00
if (m_ping_timer >= PING_TIMEOUT)
{
// Create and send PING packet
writeU8(&data[0], PACKET_TYPE_CONTROL);
writeU8(&data[1], CONTROLTYPE_PING);
m_ping_timer = 0.0;
return true;
}
return false;
}
void UDPPeer::PutReliableSendCommand(ConnectionCommand &c,
unsigned int max_packet_size)
{
if (m_pending_disconnect)
return;
if ( channels[c.channelnum].queued_commands.empty() &&
/* don't queue more packets then window size */
(channels[c.channelnum].queued_reliables.size()
< (channels[c.channelnum].getWindowSize()/2))) {
LOG(dout_con<<m_connection->getDesc()
<<" processing reliable command for peer id: " << c.peer_id
<<" data size: " << c.data.getSize() << std::endl);
if (!processReliableSendCommand(c,max_packet_size)) {
channels[c.channelnum].queued_commands.push_back(c);
}
}
else {
LOG(dout_con<<m_connection->getDesc()
<<" Queueing reliable command for peer id: " << c.peer_id
<<" data size: " << c.data.getSize() <<std::endl);
channels[c.channelnum].queued_commands.push_back(c);
}
}
bool UDPPeer::processReliableSendCommand(
ConnectionCommand &c,
unsigned int max_packet_size)
{
if (m_pending_disconnect)
return true;
u32 chunksize_max = max_packet_size
- BASE_HEADER_SIZE
- RELIABLE_HEADER_SIZE;
sanity_check(c.data.getSize() < MAX_RELIABLE_WINDOW_SIZE*512);
std::list<SharedBuffer<u8>> originals;
u16 split_sequence_number = channels[c.channelnum].readNextSplitSeqNum();
if (c.raw) {
originals.emplace_back(c.data);
} else {
makeAutoSplitPacket(c.data, chunksize_max,split_sequence_number, &originals);
channels[c.channelnum].setNextSplitSeqNum(split_sequence_number);
}
bool have_sequence_number = true;
bool have_initial_sequence_number = false;
std::queue<BufferedPacket> toadd;
volatile u16 initial_sequence_number = 0;
for (SharedBuffer<u8> &original : originals) {
u16 seqnum = channels[c.channelnum].getOutgoingSequenceNumber(have_sequence_number);
/* oops, we don't have enough sequence numbers to send this packet */
if (!have_sequence_number)
break;
if (!have_initial_sequence_number)
{
initial_sequence_number = seqnum;
have_initial_sequence_number = true;
}
SharedBuffer<u8> reliable = makeReliablePacket(original, seqnum);
// Add base headers and make a packet
BufferedPacket p = con::makePacket(address, reliable,
m_connection->GetProtocolID(), m_connection->GetPeerID(),
c.channelnum);
toadd.push(p);
}
if (have_sequence_number) {
volatile u16 pcount = 0;
while (!toadd.empty()) {
BufferedPacket p = toadd.front();
toadd.pop();
// LOG(dout_con<<connection->getDesc()
// << " queuing reliable packet for peer_id: " << c.peer_id
// << " channel: " << (c.channelnum&0xFF)
// << " seqnum: " << readU16(&p.data[BASE_HEADER_SIZE+1])
// << std::endl)
channels[c.channelnum].queued_reliables.push(p);
pcount++;
}
sanity_check(channels[c.channelnum].queued_reliables.size() < 0xFFFF);
return true;
}
volatile u16 packets_available = toadd.size();
/* we didn't get a single sequence number no need to fill queue */
if (!have_initial_sequence_number) {
return false;
}
while (!toadd.empty()) {
/* remove packet */
toadd.pop();
bool successfully_put_back_sequence_number
= channels[c.channelnum].putBackSequenceNumber(
(initial_sequence_number+toadd.size() % (SEQNUM_MAX+1)));
FATAL_ERROR_IF(!successfully_put_back_sequence_number, "error");
}
LOG(dout_con<<m_connection->getDesc()
<< " Windowsize exceeded on reliable sending "
<< c.data.getSize() << " bytes"
<< std::endl << "\t\tinitial_sequence_number: "
<< initial_sequence_number
<< std::endl << "\t\tgot at most : "
<< packets_available << " packets"
<< std::endl << "\t\tpackets queued : "
<< channels[c.channelnum].outgoing_reliables_sent.size()
<< std::endl);
return false;
2010-11-27 00:02:21 +01:00
}
void UDPPeer::RunCommandQueues(
unsigned int max_packet_size,
unsigned int maxcommands,
unsigned int maxtransfer)
2010-11-27 00:02:21 +01:00
{
for (Channel &channel : channels) {
unsigned int commands_processed = 0;
if ((!channel.queued_commands.empty()) &&
(channel.queued_reliables.size() < maxtransfer) &&
(commands_processed < maxcommands)) {
try {
ConnectionCommand c = channel.queued_commands.front();
LOG(dout_con << m_connection->getDesc()
<< " processing queued reliable command " << std::endl);
// Packet is processed, remove it from queue
if (processReliableSendCommand(c,max_packet_size)) {
channel.queued_commands.pop_front();
} else {
LOG(dout_con << m_connection->getDesc()
<< " Failed to queue packets for peer_id: " << c.peer_id
<< ", delaying sending of " << c.data.getSize()
<< " bytes" << std::endl);
}
}
2014-02-27 21:12:59 +01:00
catch (ItemNotFoundException &e) {
// intentionally empty
}
}
}
}
u16 UDPPeer::getNextSplitSequenceNumber(u8 channel)
{
assert(channel < CHANNEL_COUNT); // Pre-condition
return channels[channel].readNextSplitSeqNum();
}
void UDPPeer::setNextSplitSequenceNumber(u8 channel, u16 seqnum)
{
assert(channel < CHANNEL_COUNT); // Pre-condition
channels[channel].setNextSplitSeqNum(seqnum);
}
SharedBuffer<u8> UDPPeer::addSplitPacket(u8 channel, const BufferedPacket &toadd,
bool reliable)
{
assert(channel < CHANNEL_COUNT); // Pre-condition
return channels[channel].incoming_splits.insert(toadd, reliable);
}
/*
Connection
*/
Connection::Connection(u32 protocol_id, u32 max_packet_size, float timeout,
bool ipv6, PeerHandler *peerhandler) :
m_udpSocket(ipv6),
m_protocol_id(protocol_id),
m_sendThread(new ConnectionSendThread(max_packet_size, timeout)),
m_receiveThread(new ConnectionReceiveThread(max_packet_size)),
m_bc_peerhandler(peerhandler)
{
m_udpSocket.setTimeoutMs(5);
m_sendThread->setParent(this);
m_receiveThread->setParent(this);
m_sendThread->start();
m_receiveThread->start();
}
Connection::~Connection()
{
m_shutting_down = true;
// request threads to stop
m_sendThread->stop();
m_receiveThread->stop();
//TODO for some unkonwn reason send/receive threads do not exit as they're
// supposed to be but wait on peer timeout. To speed up shutdown we reduce
// timeout to half a second.
m_sendThread->setPeerTimeout(0.5);
// wait for threads to finish
m_sendThread->wait();
m_receiveThread->wait();
// Delete peers
for (auto &peer : m_peers) {
delete peer.second;
}
}
/* Internal stuff */
void Connection::putEvent(ConnectionEvent &e)
{
assert(e.type != CONNEVENT_NONE); // Pre-condition
m_event_queue.push_back(e);
}
void Connection::TriggerSend()
{
m_sendThread->Trigger();
}
PeerHelper Connection::getPeerNoEx(session_t peer_id)
{
MutexAutoLock peerlock(m_peers_mutex);
std::map<session_t, Peer *>::iterator node = m_peers.find(peer_id);
if (node == m_peers.end()) {
return PeerHelper(NULL);
}
// Error checking
FATAL_ERROR_IF(node->second->id != peer_id, "Invalid peer id");
return PeerHelper(node->second);
}
/* find peer_id for address */
u16 Connection::lookupPeer(Address& sender)
{
MutexAutoLock peerlock(m_peers_mutex);
std::map<u16, Peer*>::iterator j;
j = m_peers.begin();
for(; j != m_peers.end(); ++j)
{
Peer *peer = j->second;
if (peer->isPendingDeletion())
continue;
Address tocheck;
if ((peer->getAddress(MTP_MINETEST_RELIABLE_UDP, tocheck)) && (tocheck == sender))
return peer->id;
if ((peer->getAddress(MTP_UDP, tocheck)) && (tocheck == sender))
return peer->id;
}
return PEER_ID_INEXISTENT;
}
bool Connection::deletePeer(session_t peer_id, bool timeout)
{
Peer *peer = 0;
/* lock list as short as possible */
{
MutexAutoLock peerlock(m_peers_mutex);
if (m_peers.find(peer_id) == m_peers.end())
return false;
peer = m_peers[peer_id];
m_peers.erase(peer_id);
m_peer_ids.remove(peer_id);
}
Address peer_address;
//any peer has a primary address this never fails!
peer->getAddress(MTP_PRIMARY, peer_address);
// Create event
ConnectionEvent e;
e.peerRemoved(peer_id, timeout, peer_address);
putEvent(e);
peer->Drop();
return true;
}
/* Interface */
ConnectionEvent Connection::waitEvent(u32 timeout_ms)
{
try {
return m_event_queue.pop_front(timeout_ms);
} catch(ItemNotFoundException &ex) {
ConnectionEvent e;
e.type = CONNEVENT_NONE;
return e;
}
}
2010-11-27 00:02:21 +01:00
void Connection::putCommand(ConnectionCommand &c)
{
if (!m_shutting_down) {
m_command_queue.push_back(c);
m_sendThread->Trigger();
}
}
2010-11-27 00:02:21 +01:00
void Connection::Serve(Address bind_addr)
{
ConnectionCommand c;
c.serve(bind_addr);
putCommand(c);
}
2010-11-27 00:02:21 +01:00
void Connection::Connect(Address address)
{
ConnectionCommand c;
c.connect(address);
putCommand(c);
}
2010-11-27 00:02:21 +01:00
bool Connection::Connected()
{
MutexAutoLock peerlock(m_peers_mutex);
2010-11-27 00:02:21 +01:00
[Patch 2/4] Network rework: packet writing, sending and cleanups NetworkPacket.cpp: * Remove some deprecated functions, we must use streaming interface * m_data converted from u8* to std::vector<u8> * Add an exporter to forge packet to Connection object * implement operator << std::wstring. n * implement operator << std::string * dynamic resize when write packet content. * fix string writing and performances. * create ServerCommandFactory, used by client to get useful informations about packet processing (sending). * Reliability * Transmit channel * Implement putRawString for some ugly char (_INIT packet), and use it. * Many packet read and write migrated * Implement oldForgePacket to interface writing with current connection * fix U8/char/bool writing * fix string writing and performances. * add some missing functions * Use v3s16 read instead of reading x,y,z separately * Add irr::video::SColor support into packets * Add some missing handlers * Add a template function to increase offset * Throw a serialization error on packet reading (must be improved) PacketFactories: * Create ServerCommandFactory, used by client to get useful informations about packet processing (sending). * Create ClientCommandFactory, used by server to get useful informations about packet processing (sending). Client.cpp: * implement NetworkPacket ::Send interface. * Move packet handlers to a dedicated file * Remove Client::Send(SharedBuffer) Server.cpp: * implement NetworkPacket ::Send interface. * Rewrite all packets using NetworkPacket * Move packet handlers to a dedicated file * Remove Server::Send(SharedBuffer) ClientIface.cpp: * Remove sendToAll(SharedBuffer<u8>) Connection.hpp rework: * Remove duplicate include * Remove duplicate negation * Remove a useless variable * Improve code performance by using a m_peers_list instead of scanning m_peers map * Remove Connection::Send(SharedBuffer) * Fix useafterfree into NetworkPacket Sending * Remove unused Connection::sendToAll Test.cpp: * Remove dead code * Update tests to use NetworkPackets Misc: * add new wrappers to Send packets in client, using NetworkPacket * Add NetworkPacket methods for Connection * coding style fix * dead code since changes cleanup * Use v3s16 read instead of reading x,y,z separately in some packets * Use different files to handle packets received by client and server * Cleanup: Remove useless includes ok @Zeno- Tested by @Zeno- @VanessaE and @nerzhul on running servers
2015-01-16 11:37:49 +01:00
if (m_peers.size() != 1)
return false;
std::map<session_t, Peer *>::iterator node = m_peers.find(PEER_ID_SERVER);
[Patch 2/4] Network rework: packet writing, sending and cleanups NetworkPacket.cpp: * Remove some deprecated functions, we must use streaming interface * m_data converted from u8* to std::vector<u8> * Add an exporter to forge packet to Connection object * implement operator << std::wstring. n * implement operator << std::string * dynamic resize when write packet content. * fix string writing and performances. * create ServerCommandFactory, used by client to get useful informations about packet processing (sending). * Reliability * Transmit channel * Implement putRawString for some ugly char (_INIT packet), and use it. * Many packet read and write migrated * Implement oldForgePacket to interface writing with current connection * fix U8/char/bool writing * fix string writing and performances. * add some missing functions * Use v3s16 read instead of reading x,y,z separately * Add irr::video::SColor support into packets * Add some missing handlers * Add a template function to increase offset * Throw a serialization error on packet reading (must be improved) PacketFactories: * Create ServerCommandFactory, used by client to get useful informations about packet processing (sending). * Create ClientCommandFactory, used by server to get useful informations about packet processing (sending). Client.cpp: * implement NetworkPacket ::Send interface. * Move packet handlers to a dedicated file * Remove Client::Send(SharedBuffer) Server.cpp: * implement NetworkPacket ::Send interface. * Rewrite all packets using NetworkPacket * Move packet handlers to a dedicated file * Remove Server::Send(SharedBuffer) ClientIface.cpp: * Remove sendToAll(SharedBuffer<u8>) Connection.hpp rework: * Remove duplicate include * Remove duplicate negation * Remove a useless variable * Improve code performance by using a m_peers_list instead of scanning m_peers map * Remove Connection::Send(SharedBuffer) * Fix useafterfree into NetworkPacket Sending * Remove unused Connection::sendToAll Test.cpp: * Remove dead code * Update tests to use NetworkPackets Misc: * add new wrappers to Send packets in client, using NetworkPacket * Add NetworkPacket methods for Connection * coding style fix * dead code since changes cleanup * Use v3s16 read instead of reading x,y,z separately in some packets * Use different files to handle packets received by client and server * Cleanup: Remove useless includes ok @Zeno- Tested by @Zeno- @VanessaE and @nerzhul on running servers
2015-01-16 11:37:49 +01:00
if (node == m_peers.end())
return false;
[Patch 2/4] Network rework: packet writing, sending and cleanups NetworkPacket.cpp: * Remove some deprecated functions, we must use streaming interface * m_data converted from u8* to std::vector<u8> * Add an exporter to forge packet to Connection object * implement operator << std::wstring. n * implement operator << std::string * dynamic resize when write packet content. * fix string writing and performances. * create ServerCommandFactory, used by client to get useful informations about packet processing (sending). * Reliability * Transmit channel * Implement putRawString for some ugly char (_INIT packet), and use it. * Many packet read and write migrated * Implement oldForgePacket to interface writing with current connection * fix U8/char/bool writing * fix string writing and performances. * add some missing functions * Use v3s16 read instead of reading x,y,z separately * Add irr::video::SColor support into packets * Add some missing handlers * Add a template function to increase offset * Throw a serialization error on packet reading (must be improved) PacketFactories: * Create ServerCommandFactory, used by client to get useful informations about packet processing (sending). * Create ClientCommandFactory, used by server to get useful informations about packet processing (sending). Client.cpp: * implement NetworkPacket ::Send interface. * Move packet handlers to a dedicated file * Remove Client::Send(SharedBuffer) Server.cpp: * implement NetworkPacket ::Send interface. * Rewrite all packets using NetworkPacket * Move packet handlers to a dedicated file * Remove Server::Send(SharedBuffer) ClientIface.cpp: * Remove sendToAll(SharedBuffer<u8>) Connection.hpp rework: * Remove duplicate include * Remove duplicate negation * Remove a useless variable * Improve code performance by using a m_peers_list instead of scanning m_peers map * Remove Connection::Send(SharedBuffer) * Fix useafterfree into NetworkPacket Sending * Remove unused Connection::sendToAll Test.cpp: * Remove dead code * Update tests to use NetworkPackets Misc: * add new wrappers to Send packets in client, using NetworkPacket * Add NetworkPacket methods for Connection * coding style fix * dead code since changes cleanup * Use v3s16 read instead of reading x,y,z separately in some packets * Use different files to handle packets received by client and server * Cleanup: Remove useless includes ok @Zeno- Tested by @Zeno- @VanessaE and @nerzhul on running servers
2015-01-16 11:37:49 +01:00
if (m_peer_id == PEER_ID_INEXISTENT)
return false;
return true;
2010-11-27 00:02:21 +01:00
}
void Connection::Disconnect()
2010-11-27 00:02:21 +01:00
{
ConnectionCommand c;
c.disconnect();
putCommand(c);
}
2010-11-27 00:02:21 +01:00
void Connection::Receive(NetworkPacket* pkt)
{
[Patch 2/4] Network rework: packet writing, sending and cleanups NetworkPacket.cpp: * Remove some deprecated functions, we must use streaming interface * m_data converted from u8* to std::vector<u8> * Add an exporter to forge packet to Connection object * implement operator << std::wstring. n * implement operator << std::string * dynamic resize when write packet content. * fix string writing and performances. * create ServerCommandFactory, used by client to get useful informations about packet processing (sending). * Reliability * Transmit channel * Implement putRawString for some ugly char (_INIT packet), and use it. * Many packet read and write migrated * Implement oldForgePacket to interface writing with current connection * fix U8/char/bool writing * fix string writing and performances. * add some missing functions * Use v3s16 read instead of reading x,y,z separately * Add irr::video::SColor support into packets * Add some missing handlers * Add a template function to increase offset * Throw a serialization error on packet reading (must be improved) PacketFactories: * Create ServerCommandFactory, used by client to get useful informations about packet processing (sending). * Create ClientCommandFactory, used by server to get useful informations about packet processing (sending). Client.cpp: * implement NetworkPacket ::Send interface. * Move packet handlers to a dedicated file * Remove Client::Send(SharedBuffer) Server.cpp: * implement NetworkPacket ::Send interface. * Rewrite all packets using NetworkPacket * Move packet handlers to a dedicated file * Remove Server::Send(SharedBuffer) ClientIface.cpp: * Remove sendToAll(SharedBuffer<u8>) Connection.hpp rework: * Remove duplicate include * Remove duplicate negation * Remove a useless variable * Improve code performance by using a m_peers_list instead of scanning m_peers map * Remove Connection::Send(SharedBuffer) * Fix useafterfree into NetworkPacket Sending * Remove unused Connection::sendToAll Test.cpp: * Remove dead code * Update tests to use NetworkPackets Misc: * add new wrappers to Send packets in client, using NetworkPacket * Add NetworkPacket methods for Connection * coding style fix * dead code since changes cleanup * Use v3s16 read instead of reading x,y,z separately in some packets * Use different files to handle packets received by client and server * Cleanup: Remove useless includes ok @Zeno- Tested by @Zeno- @VanessaE and @nerzhul on running servers
2015-01-16 11:37:49 +01:00
for(;;) {
ConnectionEvent e = waitEvent(m_bc_receive_timeout);
[Patch 2/4] Network rework: packet writing, sending and cleanups NetworkPacket.cpp: * Remove some deprecated functions, we must use streaming interface * m_data converted from u8* to std::vector<u8> * Add an exporter to forge packet to Connection object * implement operator << std::wstring. n * implement operator << std::string * dynamic resize when write packet content. * fix string writing and performances. * create ServerCommandFactory, used by client to get useful informations about packet processing (sending). * Reliability * Transmit channel * Implement putRawString for some ugly char (_INIT packet), and use it. * Many packet read and write migrated * Implement oldForgePacket to interface writing with current connection * fix U8/char/bool writing * fix string writing and performances. * add some missing functions * Use v3s16 read instead of reading x,y,z separately * Add irr::video::SColor support into packets * Add some missing handlers * Add a template function to increase offset * Throw a serialization error on packet reading (must be improved) PacketFactories: * Create ServerCommandFactory, used by client to get useful informations about packet processing (sending). * Create ClientCommandFactory, used by server to get useful informations about packet processing (sending). Client.cpp: * implement NetworkPacket ::Send interface. * Move packet handlers to a dedicated file * Remove Client::Send(SharedBuffer) Server.cpp: * implement NetworkPacket ::Send interface. * Rewrite all packets using NetworkPacket * Move packet handlers to a dedicated file * Remove Server::Send(SharedBuffer) ClientIface.cpp: * Remove sendToAll(SharedBuffer<u8>) Connection.hpp rework: * Remove duplicate include * Remove duplicate negation * Remove a useless variable * Improve code performance by using a m_peers_list instead of scanning m_peers map * Remove Connection::Send(SharedBuffer) * Fix useafterfree into NetworkPacket Sending * Remove unused Connection::sendToAll Test.cpp: * Remove dead code * Update tests to use NetworkPackets Misc: * add new wrappers to Send packets in client, using NetworkPacket * Add NetworkPacket methods for Connection * coding style fix * dead code since changes cleanup * Use v3s16 read instead of reading x,y,z separately in some packets * Use different files to handle packets received by client and server * Cleanup: Remove useless includes ok @Zeno- Tested by @Zeno- @VanessaE and @nerzhul on running servers
2015-01-16 11:37:49 +01:00
if (e.type != CONNEVENT_NONE)
LOG(dout_con << getDesc() << ": Receive: got event: "
<< e.describe() << std::endl);
[Patch 2/4] Network rework: packet writing, sending and cleanups NetworkPacket.cpp: * Remove some deprecated functions, we must use streaming interface * m_data converted from u8* to std::vector<u8> * Add an exporter to forge packet to Connection object * implement operator << std::wstring. n * implement operator << std::string * dynamic resize when write packet content. * fix string writing and performances. * create ServerCommandFactory, used by client to get useful informations about packet processing (sending). * Reliability * Transmit channel * Implement putRawString for some ugly char (_INIT packet), and use it. * Many packet read and write migrated * Implement oldForgePacket to interface writing with current connection * fix U8/char/bool writing * fix string writing and performances. * add some missing functions * Use v3s16 read instead of reading x,y,z separately * Add irr::video::SColor support into packets * Add some missing handlers * Add a template function to increase offset * Throw a serialization error on packet reading (must be improved) PacketFactories: * Create ServerCommandFactory, used by client to get useful informations about packet processing (sending). * Create ClientCommandFactory, used by server to get useful informations about packet processing (sending). Client.cpp: * implement NetworkPacket ::Send interface. * Move packet handlers to a dedicated file * Remove Client::Send(SharedBuffer) Server.cpp: * implement NetworkPacket ::Send interface. * Rewrite all packets using NetworkPacket * Move packet handlers to a dedicated file * Remove Server::Send(SharedBuffer) ClientIface.cpp: * Remove sendToAll(SharedBuffer<u8>) Connection.hpp rework: * Remove duplicate include * Remove duplicate negation * Remove a useless variable * Improve code performance by using a m_peers_list instead of scanning m_peers map * Remove Connection::Send(SharedBuffer) * Fix useafterfree into NetworkPacket Sending * Remove unused Connection::sendToAll Test.cpp: * Remove dead code * Update tests to use NetworkPackets Misc: * add new wrappers to Send packets in client, using NetworkPacket * Add NetworkPacket methods for Connection * coding style fix * dead code since changes cleanup * Use v3s16 read instead of reading x,y,z separately in some packets * Use different files to handle packets received by client and server * Cleanup: Remove useless includes ok @Zeno- Tested by @Zeno- @VanessaE and @nerzhul on running servers
2015-01-16 11:37:49 +01:00
switch(e.type) {
case CONNEVENT_NONE:
throw NoIncomingDataException("No incoming data");
case CONNEVENT_DATA_RECEIVED:
// Data size is lesser than command size, ignoring packet
if (e.data.getSize() < 2) {
continue;
}
pkt->putRawPacket(*e.data, e.data.getSize(), e.peer_id);
return;
case CONNEVENT_PEER_ADDED: {
UDPPeer tmp(e.peer_id, e.address, this);
[Patch 2/4] Network rework: packet writing, sending and cleanups NetworkPacket.cpp: * Remove some deprecated functions, we must use streaming interface * m_data converted from u8* to std::vector<u8> * Add an exporter to forge packet to Connection object * implement operator << std::wstring. n * implement operator << std::string * dynamic resize when write packet content. * fix string writing and performances. * create ServerCommandFactory, used by client to get useful informations about packet processing (sending). * Reliability * Transmit channel * Implement putRawString for some ugly char (_INIT packet), and use it. * Many packet read and write migrated * Implement oldForgePacket to interface writing with current connection * fix U8/char/bool writing * fix string writing and performances. * add some missing functions * Use v3s16 read instead of reading x,y,z separately * Add irr::video::SColor support into packets * Add some missing handlers * Add a template function to increase offset * Throw a serialization error on packet reading (must be improved) PacketFactories: * Create ServerCommandFactory, used by client to get useful informations about packet processing (sending). * Create ClientCommandFactory, used by server to get useful informations about packet processing (sending). Client.cpp: * implement NetworkPacket ::Send interface. * Move packet handlers to a dedicated file * Remove Client::Send(SharedBuffer) Server.cpp: * implement NetworkPacket ::Send interface. * Rewrite all packets using NetworkPacket * Move packet handlers to a dedicated file * Remove Server::Send(SharedBuffer) ClientIface.cpp: * Remove sendToAll(SharedBuffer<u8>) Connection.hpp rework: * Remove duplicate include * Remove duplicate negation * Remove a useless variable * Improve code performance by using a m_peers_list instead of scanning m_peers map * Remove Connection::Send(SharedBuffer) * Fix useafterfree into NetworkPacket Sending * Remove unused Connection::sendToAll Test.cpp: * Remove dead code * Update tests to use NetworkPackets Misc: * add new wrappers to Send packets in client, using NetworkPacket * Add NetworkPacket methods for Connection * coding style fix * dead code since changes cleanup * Use v3s16 read instead of reading x,y,z separately in some packets * Use different files to handle packets received by client and server * Cleanup: Remove useless includes ok @Zeno- Tested by @Zeno- @VanessaE and @nerzhul on running servers
2015-01-16 11:37:49 +01:00
if (m_bc_peerhandler)
m_bc_peerhandler->peerAdded(&tmp);
continue;
}
case CONNEVENT_PEER_REMOVED: {
UDPPeer tmp(e.peer_id, e.address, this);
[Patch 2/4] Network rework: packet writing, sending and cleanups NetworkPacket.cpp: * Remove some deprecated functions, we must use streaming interface * m_data converted from u8* to std::vector<u8> * Add an exporter to forge packet to Connection object * implement operator << std::wstring. n * implement operator << std::string * dynamic resize when write packet content. * fix string writing and performances. * create ServerCommandFactory, used by client to get useful informations about packet processing (sending). * Reliability * Transmit channel * Implement putRawString for some ugly char (_INIT packet), and use it. * Many packet read and write migrated * Implement oldForgePacket to interface writing with current connection * fix U8/char/bool writing * fix string writing and performances. * add some missing functions * Use v3s16 read instead of reading x,y,z separately * Add irr::video::SColor support into packets * Add some missing handlers * Add a template function to increase offset * Throw a serialization error on packet reading (must be improved) PacketFactories: * Create ServerCommandFactory, used by client to get useful informations about packet processing (sending). * Create ClientCommandFactory, used by server to get useful informations about packet processing (sending). Client.cpp: * implement NetworkPacket ::Send interface. * Move packet handlers to a dedicated file * Remove Client::Send(SharedBuffer) Server.cpp: * implement NetworkPacket ::Send interface. * Rewrite all packets using NetworkPacket * Move packet handlers to a dedicated file * Remove Server::Send(SharedBuffer) ClientIface.cpp: * Remove sendToAll(SharedBuffer<u8>) Connection.hpp rework: * Remove duplicate include * Remove duplicate negation * Remove a useless variable * Improve code performance by using a m_peers_list instead of scanning m_peers map * Remove Connection::Send(SharedBuffer) * Fix useafterfree into NetworkPacket Sending * Remove unused Connection::sendToAll Test.cpp: * Remove dead code * Update tests to use NetworkPackets Misc: * add new wrappers to Send packets in client, using NetworkPacket * Add NetworkPacket methods for Connection * coding style fix * dead code since changes cleanup * Use v3s16 read instead of reading x,y,z separately in some packets * Use different files to handle packets received by client and server * Cleanup: Remove useless includes ok @Zeno- Tested by @Zeno- @VanessaE and @nerzhul on running servers
2015-01-16 11:37:49 +01:00
if (m_bc_peerhandler)
m_bc_peerhandler->deletingPeer(&tmp, e.timeout);
continue;
}
case CONNEVENT_BIND_FAILED:
throw ConnectionBindFailed("Failed to bind socket "
"(port already in use?)");
}
2010-11-27 00:02:21 +01:00
}
throw NoIncomingDataException("No incoming data");
}
2010-11-27 00:02:21 +01:00
void Connection::Send(session_t peer_id, u8 channelnum,
NetworkPacket *pkt, bool reliable)
2010-11-27 00:02:21 +01:00
{
assert(channelnum < CHANNEL_COUNT); // Pre-condition
2010-11-27 00:02:21 +01:00
ConnectionCommand c;
[Patch 2/4] Network rework: packet writing, sending and cleanups NetworkPacket.cpp: * Remove some deprecated functions, we must use streaming interface * m_data converted from u8* to std::vector<u8> * Add an exporter to forge packet to Connection object * implement operator << std::wstring. n * implement operator << std::string * dynamic resize when write packet content. * fix string writing and performances. * create ServerCommandFactory, used by client to get useful informations about packet processing (sending). * Reliability * Transmit channel * Implement putRawString for some ugly char (_INIT packet), and use it. * Many packet read and write migrated * Implement oldForgePacket to interface writing with current connection * fix U8/char/bool writing * fix string writing and performances. * add some missing functions * Use v3s16 read instead of reading x,y,z separately * Add irr::video::SColor support into packets * Add some missing handlers * Add a template function to increase offset * Throw a serialization error on packet reading (must be improved) PacketFactories: * Create ServerCommandFactory, used by client to get useful informations about packet processing (sending). * Create ClientCommandFactory, used by server to get useful informations about packet processing (sending). Client.cpp: * implement NetworkPacket ::Send interface. * Move packet handlers to a dedicated file * Remove Client::Send(SharedBuffer) Server.cpp: * implement NetworkPacket ::Send interface. * Rewrite all packets using NetworkPacket * Move packet handlers to a dedicated file * Remove Server::Send(SharedBuffer) ClientIface.cpp: * Remove sendToAll(SharedBuffer<u8>) Connection.hpp rework: * Remove duplicate include * Remove duplicate negation * Remove a useless variable * Improve code performance by using a m_peers_list instead of scanning m_peers map * Remove Connection::Send(SharedBuffer) * Fix useafterfree into NetworkPacket Sending * Remove unused Connection::sendToAll Test.cpp: * Remove dead code * Update tests to use NetworkPackets Misc: * add new wrappers to Send packets in client, using NetworkPacket * Add NetworkPacket methods for Connection * coding style fix * dead code since changes cleanup * Use v3s16 read instead of reading x,y,z separately in some packets * Use different files to handle packets received by client and server * Cleanup: Remove useless includes ok @Zeno- Tested by @Zeno- @VanessaE and @nerzhul on running servers
2015-01-16 11:37:49 +01:00
c.send(peer_id, channelnum, pkt, reliable);
putCommand(c);
}
2010-11-27 00:02:21 +01:00
Address Connection::GetPeerAddress(session_t peer_id)
{
PeerHelper peer = getPeerNoEx(peer_id);
if (!peer)
throw PeerNotFoundException("No address for peer found!");
Address peer_address;
peer->getAddress(MTP_PRIMARY, peer_address);
return peer_address;
2010-11-27 00:02:21 +01:00
}
float Connection::getPeerStat(session_t peer_id, rtt_stat_type type)
2010-11-27 00:02:21 +01:00
{
PeerHelper peer = getPeerNoEx(peer_id);
if (!peer) return -1;
return peer->getStat(type);
}
float Connection::getLocalStat(rate_stat_type type)
{
PeerHelper peer = getPeerNoEx(PEER_ID_SERVER);
FATAL_ERROR_IF(!peer, "Connection::getLocalStat we couldn't get our own peer? are you serious???");
float retval = 0.0;
for (Channel &channel : dynamic_cast<UDPPeer *>(&peer)->channels) {
switch(type) {
case CUR_DL_RATE:
retval += channel.getCurrentDownloadRateKB();
break;
case AVG_DL_RATE:
retval += channel.getAvgDownloadRateKB();
break;
case CUR_INC_RATE:
retval += channel.getCurrentIncomingRateKB();
break;
case AVG_INC_RATE:
retval += channel.getAvgIncomingRateKB();
break;
case AVG_LOSS_RATE:
retval += channel.getAvgLossRateKB();
break;
case CUR_LOSS_RATE:
retval += channel.getCurrentLossRateKB();
break;
default:
FATAL_ERROR("Connection::getLocalStat Invalid stat type");
}
}
return retval;
}
u16 Connection::createPeer(Address& sender, MTProtocols protocol, int fd)
{
// Somebody wants to make a new connection
// Get a unique peer id (2 or higher)
session_t peer_id_new = m_next_remote_peer_id;
u16 overflow = MAX_UDP_PEERS;
/*
Find an unused peer id
*/
MutexAutoLock lock(m_peers_mutex);
[Patch 2/4] Network rework: packet writing, sending and cleanups NetworkPacket.cpp: * Remove some deprecated functions, we must use streaming interface * m_data converted from u8* to std::vector<u8> * Add an exporter to forge packet to Connection object * implement operator << std::wstring. n * implement operator << std::string * dynamic resize when write packet content. * fix string writing and performances. * create ServerCommandFactory, used by client to get useful informations about packet processing (sending). * Reliability * Transmit channel * Implement putRawString for some ugly char (_INIT packet), and use it. * Many packet read and write migrated * Implement oldForgePacket to interface writing with current connection * fix U8/char/bool writing * fix string writing and performances. * add some missing functions * Use v3s16 read instead of reading x,y,z separately * Add irr::video::SColor support into packets * Add some missing handlers * Add a template function to increase offset * Throw a serialization error on packet reading (must be improved) PacketFactories: * Create ServerCommandFactory, used by client to get useful informations about packet processing (sending). * Create ClientCommandFactory, used by server to get useful informations about packet processing (sending). Client.cpp: * implement NetworkPacket ::Send interface. * Move packet handlers to a dedicated file * Remove Client::Send(SharedBuffer) Server.cpp: * implement NetworkPacket ::Send interface. * Rewrite all packets using NetworkPacket * Move packet handlers to a dedicated file * Remove Server::Send(SharedBuffer) ClientIface.cpp: * Remove sendToAll(SharedBuffer<u8>) Connection.hpp rework: * Remove duplicate include * Remove duplicate negation * Remove a useless variable * Improve code performance by using a m_peers_list instead of scanning m_peers map * Remove Connection::Send(SharedBuffer) * Fix useafterfree into NetworkPacket Sending * Remove unused Connection::sendToAll Test.cpp: * Remove dead code * Update tests to use NetworkPackets Misc: * add new wrappers to Send packets in client, using NetworkPacket * Add NetworkPacket methods for Connection * coding style fix * dead code since changes cleanup * Use v3s16 read instead of reading x,y,z separately in some packets * Use different files to handle packets received by client and server * Cleanup: Remove useless includes ok @Zeno- Tested by @Zeno- @VanessaE and @nerzhul on running servers
2015-01-16 11:37:49 +01:00
bool out_of_ids = false;
for(;;) {
// Check if exists
if (m_peers.find(peer_id_new) == m_peers.end())
[Patch 2/4] Network rework: packet writing, sending and cleanups NetworkPacket.cpp: * Remove some deprecated functions, we must use streaming interface * m_data converted from u8* to std::vector<u8> * Add an exporter to forge packet to Connection object * implement operator << std::wstring. n * implement operator << std::string * dynamic resize when write packet content. * fix string writing and performances. * create ServerCommandFactory, used by client to get useful informations about packet processing (sending). * Reliability * Transmit channel * Implement putRawString for some ugly char (_INIT packet), and use it. * Many packet read and write migrated * Implement oldForgePacket to interface writing with current connection * fix U8/char/bool writing * fix string writing and performances. * add some missing functions * Use v3s16 read instead of reading x,y,z separately * Add irr::video::SColor support into packets * Add some missing handlers * Add a template function to increase offset * Throw a serialization error on packet reading (must be improved) PacketFactories: * Create ServerCommandFactory, used by client to get useful informations about packet processing (sending). * Create ClientCommandFactory, used by server to get useful informations about packet processing (sending). Client.cpp: * implement NetworkPacket ::Send interface. * Move packet handlers to a dedicated file * Remove Client::Send(SharedBuffer) Server.cpp: * implement NetworkPacket ::Send interface. * Rewrite all packets using NetworkPacket * Move packet handlers to a dedicated file * Remove Server::Send(SharedBuffer) ClientIface.cpp: * Remove sendToAll(SharedBuffer<u8>) Connection.hpp rework: * Remove duplicate include * Remove duplicate negation * Remove a useless variable * Improve code performance by using a m_peers_list instead of scanning m_peers map * Remove Connection::Send(SharedBuffer) * Fix useafterfree into NetworkPacket Sending * Remove unused Connection::sendToAll Test.cpp: * Remove dead code * Update tests to use NetworkPackets Misc: * add new wrappers to Send packets in client, using NetworkPacket * Add NetworkPacket methods for Connection * coding style fix * dead code since changes cleanup * Use v3s16 read instead of reading x,y,z separately in some packets * Use different files to handle packets received by client and server * Cleanup: Remove useless includes ok @Zeno- Tested by @Zeno- @VanessaE and @nerzhul on running servers
2015-01-16 11:37:49 +01:00
break;
// Check for overflow
if (peer_id_new == overflow) {
out_of_ids = true;
break;
}
peer_id_new++;
}
[Patch 2/4] Network rework: packet writing, sending and cleanups NetworkPacket.cpp: * Remove some deprecated functions, we must use streaming interface * m_data converted from u8* to std::vector<u8> * Add an exporter to forge packet to Connection object * implement operator << std::wstring. n * implement operator << std::string * dynamic resize when write packet content. * fix string writing and performances. * create ServerCommandFactory, used by client to get useful informations about packet processing (sending). * Reliability * Transmit channel * Implement putRawString for some ugly char (_INIT packet), and use it. * Many packet read and write migrated * Implement oldForgePacket to interface writing with current connection * fix U8/char/bool writing * fix string writing and performances. * add some missing functions * Use v3s16 read instead of reading x,y,z separately * Add irr::video::SColor support into packets * Add some missing handlers * Add a template function to increase offset * Throw a serialization error on packet reading (must be improved) PacketFactories: * Create ServerCommandFactory, used by client to get useful informations about packet processing (sending). * Create ClientCommandFactory, used by server to get useful informations about packet processing (sending). Client.cpp: * implement NetworkPacket ::Send interface. * Move packet handlers to a dedicated file * Remove Client::Send(SharedBuffer) Server.cpp: * implement NetworkPacket ::Send interface. * Rewrite all packets using NetworkPacket * Move packet handlers to a dedicated file * Remove Server::Send(SharedBuffer) ClientIface.cpp: * Remove sendToAll(SharedBuffer<u8>) Connection.hpp rework: * Remove duplicate include * Remove duplicate negation * Remove a useless variable * Improve code performance by using a m_peers_list instead of scanning m_peers map * Remove Connection::Send(SharedBuffer) * Fix useafterfree into NetworkPacket Sending * Remove unused Connection::sendToAll Test.cpp: * Remove dead code * Update tests to use NetworkPackets Misc: * add new wrappers to Send packets in client, using NetworkPacket * Add NetworkPacket methods for Connection * coding style fix * dead code since changes cleanup * Use v3s16 read instead of reading x,y,z separately in some packets * Use different files to handle packets received by client and server * Cleanup: Remove useless includes ok @Zeno- Tested by @Zeno- @VanessaE and @nerzhul on running servers
2015-01-16 11:37:49 +01:00
if (out_of_ids) {
errorstream << getDesc() << " ran out of peer ids" << std::endl;
return PEER_ID_INEXISTENT;
}
[Patch 2/4] Network rework: packet writing, sending and cleanups NetworkPacket.cpp: * Remove some deprecated functions, we must use streaming interface * m_data converted from u8* to std::vector<u8> * Add an exporter to forge packet to Connection object * implement operator << std::wstring. n * implement operator << std::string * dynamic resize when write packet content. * fix string writing and performances. * create ServerCommandFactory, used by client to get useful informations about packet processing (sending). * Reliability * Transmit channel * Implement putRawString for some ugly char (_INIT packet), and use it. * Many packet read and write migrated * Implement oldForgePacket to interface writing with current connection * fix U8/char/bool writing * fix string writing and performances. * add some missing functions * Use v3s16 read instead of reading x,y,z separately * Add irr::video::SColor support into packets * Add some missing handlers * Add a template function to increase offset * Throw a serialization error on packet reading (must be improved) PacketFactories: * Create ServerCommandFactory, used by client to get useful informations about packet processing (sending). * Create ClientCommandFactory, used by server to get useful informations about packet processing (sending). Client.cpp: * implement NetworkPacket ::Send interface. * Move packet handlers to a dedicated file * Remove Client::Send(SharedBuffer) Server.cpp: * implement NetworkPacket ::Send interface. * Rewrite all packets using NetworkPacket * Move packet handlers to a dedicated file * Remove Server::Send(SharedBuffer) ClientIface.cpp: * Remove sendToAll(SharedBuffer<u8>) Connection.hpp rework: * Remove duplicate include * Remove duplicate negation * Remove a useless variable * Improve code performance by using a m_peers_list instead of scanning m_peers map * Remove Connection::Send(SharedBuffer) * Fix useafterfree into NetworkPacket Sending * Remove unused Connection::sendToAll Test.cpp: * Remove dead code * Update tests to use NetworkPackets Misc: * add new wrappers to Send packets in client, using NetworkPacket * Add NetworkPacket methods for Connection * coding style fix * dead code since changes cleanup * Use v3s16 read instead of reading x,y,z separately in some packets * Use different files to handle packets received by client and server * Cleanup: Remove useless includes ok @Zeno- Tested by @Zeno- @VanessaE and @nerzhul on running servers
2015-01-16 11:37:49 +01:00
// Create a peer
Peer *peer = 0;
peer = new UDPPeer(peer_id_new, sender, this);
[Patch 2/4] Network rework: packet writing, sending and cleanups NetworkPacket.cpp: * Remove some deprecated functions, we must use streaming interface * m_data converted from u8* to std::vector<u8> * Add an exporter to forge packet to Connection object * implement operator << std::wstring. n * implement operator << std::string * dynamic resize when write packet content. * fix string writing and performances. * create ServerCommandFactory, used by client to get useful informations about packet processing (sending). * Reliability * Transmit channel * Implement putRawString for some ugly char (_INIT packet), and use it. * Many packet read and write migrated * Implement oldForgePacket to interface writing with current connection * fix U8/char/bool writing * fix string writing and performances. * add some missing functions * Use v3s16 read instead of reading x,y,z separately * Add irr::video::SColor support into packets * Add some missing handlers * Add a template function to increase offset * Throw a serialization error on packet reading (must be improved) PacketFactories: * Create ServerCommandFactory, used by client to get useful informations about packet processing (sending). * Create ClientCommandFactory, used by server to get useful informations about packet processing (sending). Client.cpp: * implement NetworkPacket ::Send interface. * Move packet handlers to a dedicated file * Remove Client::Send(SharedBuffer) Server.cpp: * implement NetworkPacket ::Send interface. * Rewrite all packets using NetworkPacket * Move packet handlers to a dedicated file * Remove Server::Send(SharedBuffer) ClientIface.cpp: * Remove sendToAll(SharedBuffer<u8>) Connection.hpp rework: * Remove duplicate include * Remove duplicate negation * Remove a useless variable * Improve code performance by using a m_peers_list instead of scanning m_peers map * Remove Connection::Send(SharedBuffer) * Fix useafterfree into NetworkPacket Sending * Remove unused Connection::sendToAll Test.cpp: * Remove dead code * Update tests to use NetworkPackets Misc: * add new wrappers to Send packets in client, using NetworkPacket * Add NetworkPacket methods for Connection * coding style fix * dead code since changes cleanup * Use v3s16 read instead of reading x,y,z separately in some packets * Use different files to handle packets received by client and server * Cleanup: Remove useless includes ok @Zeno- Tested by @Zeno- @VanessaE and @nerzhul on running servers
2015-01-16 11:37:49 +01:00
m_peers[peer->id] = peer;
m_peer_ids.push_back(peer->id);
m_next_remote_peer_id = (peer_id_new +1 ) % MAX_UDP_PEERS;
LOG(dout_con << getDesc()
<< "createPeer(): giving peer_id=" << peer_id_new << std::endl);
ConnectionCommand cmd;
SharedBuffer<u8> reply(4);
writeU8(&reply[0], PACKET_TYPE_CONTROL);
writeU8(&reply[1], CONTROLTYPE_SET_PEER_ID);
writeU16(&reply[2], peer_id_new);
cmd.createPeer(peer_id_new,reply);
[Patch 2/4] Network rework: packet writing, sending and cleanups NetworkPacket.cpp: * Remove some deprecated functions, we must use streaming interface * m_data converted from u8* to std::vector<u8> * Add an exporter to forge packet to Connection object * implement operator << std::wstring. n * implement operator << std::string * dynamic resize when write packet content. * fix string writing and performances. * create ServerCommandFactory, used by client to get useful informations about packet processing (sending). * Reliability * Transmit channel * Implement putRawString for some ugly char (_INIT packet), and use it. * Many packet read and write migrated * Implement oldForgePacket to interface writing with current connection * fix U8/char/bool writing * fix string writing and performances. * add some missing functions * Use v3s16 read instead of reading x,y,z separately * Add irr::video::SColor support into packets * Add some missing handlers * Add a template function to increase offset * Throw a serialization error on packet reading (must be improved) PacketFactories: * Create ServerCommandFactory, used by client to get useful informations about packet processing (sending). * Create ClientCommandFactory, used by server to get useful informations about packet processing (sending). Client.cpp: * implement NetworkPacket ::Send interface. * Move packet handlers to a dedicated file * Remove Client::Send(SharedBuffer) Server.cpp: * implement NetworkPacket ::Send interface. * Rewrite all packets using NetworkPacket * Move packet handlers to a dedicated file * Remove Server::Send(SharedBuffer) ClientIface.cpp: * Remove sendToAll(SharedBuffer<u8>) Connection.hpp rework: * Remove duplicate include * Remove duplicate negation * Remove a useless variable * Improve code performance by using a m_peers_list instead of scanning m_peers map * Remove Connection::Send(SharedBuffer) * Fix useafterfree into NetworkPacket Sending * Remove unused Connection::sendToAll Test.cpp: * Remove dead code * Update tests to use NetworkPackets Misc: * add new wrappers to Send packets in client, using NetworkPacket * Add NetworkPacket methods for Connection * coding style fix * dead code since changes cleanup * Use v3s16 read instead of reading x,y,z separately in some packets * Use different files to handle packets received by client and server * Cleanup: Remove useless includes ok @Zeno- Tested by @Zeno- @VanessaE and @nerzhul on running servers
2015-01-16 11:37:49 +01:00
putCommand(cmd);
// Create peer addition event
ConnectionEvent e;
e.peerAdded(peer_id_new, sender);
putEvent(e);
// We're now talking to a valid peer_id
return peer_id_new;
2010-11-27 00:02:21 +01:00
}
void Connection::PrintInfo(std::ostream &out)
{
m_info_mutex.lock();
out<<getDesc()<<": ";
m_info_mutex.unlock();
2010-11-27 00:02:21 +01:00
}
const std::string Connection::getDesc()
{
return std::string("con(")+
itos(m_udpSocket.GetHandle())+"/"+itos(m_peer_id)+")";
}
void Connection::DisconnectPeer(session_t peer_id)
{
ConnectionCommand discon;
discon.disconnect_peer(peer_id);
putCommand(discon);
}
void Connection::sendAck(session_t peer_id, u8 channelnum, u16 seqnum)
{
assert(channelnum < CHANNEL_COUNT); // Pre-condition
LOG(dout_con<<getDesc()
<<" Queuing ACK command to peer_id: " << peer_id <<
" channel: " << (channelnum & 0xFF) <<
" seqnum: " << seqnum << std::endl);
ConnectionCommand c;
SharedBuffer<u8> ack(4);
writeU8(&ack[0], PACKET_TYPE_CONTROL);
writeU8(&ack[1], CONTROLTYPE_ACK);
writeU16(&ack[2], seqnum);
c.ack(peer_id, channelnum, ack);
putCommand(c);
m_sendThread->Trigger();
}
UDPPeer* Connection::createServerPeer(Address& address)
{
if (getPeerNoEx(PEER_ID_SERVER) != 0)
{
throw ConnectionException("Already connected to a server");
}
UDPPeer *peer = new UDPPeer(PEER_ID_SERVER, address, this);
{
MutexAutoLock lock(m_peers_mutex);
m_peers[peer->id] = peer;
[Patch 2/4] Network rework: packet writing, sending and cleanups NetworkPacket.cpp: * Remove some deprecated functions, we must use streaming interface * m_data converted from u8* to std::vector<u8> * Add an exporter to forge packet to Connection object * implement operator << std::wstring. n * implement operator << std::string * dynamic resize when write packet content. * fix string writing and performances. * create ServerCommandFactory, used by client to get useful informations about packet processing (sending). * Reliability * Transmit channel * Implement putRawString for some ugly char (_INIT packet), and use it. * Many packet read and write migrated * Implement oldForgePacket to interface writing with current connection * fix U8/char/bool writing * fix string writing and performances. * add some missing functions * Use v3s16 read instead of reading x,y,z separately * Add irr::video::SColor support into packets * Add some missing handlers * Add a template function to increase offset * Throw a serialization error on packet reading (must be improved) PacketFactories: * Create ServerCommandFactory, used by client to get useful informations about packet processing (sending). * Create ClientCommandFactory, used by server to get useful informations about packet processing (sending). Client.cpp: * implement NetworkPacket ::Send interface. * Move packet handlers to a dedicated file * Remove Client::Send(SharedBuffer) Server.cpp: * implement NetworkPacket ::Send interface. * Rewrite all packets using NetworkPacket * Move packet handlers to a dedicated file * Remove Server::Send(SharedBuffer) ClientIface.cpp: * Remove sendToAll(SharedBuffer<u8>) Connection.hpp rework: * Remove duplicate include * Remove duplicate negation * Remove a useless variable * Improve code performance by using a m_peers_list instead of scanning m_peers map * Remove Connection::Send(SharedBuffer) * Fix useafterfree into NetworkPacket Sending * Remove unused Connection::sendToAll Test.cpp: * Remove dead code * Update tests to use NetworkPackets Misc: * add new wrappers to Send packets in client, using NetworkPacket * Add NetworkPacket methods for Connection * coding style fix * dead code since changes cleanup * Use v3s16 read instead of reading x,y,z separately in some packets * Use different files to handle packets received by client and server * Cleanup: Remove useless includes ok @Zeno- Tested by @Zeno- @VanessaE and @nerzhul on running servers
2015-01-16 11:37:49 +01:00
m_peer_ids.push_back(peer->id);
}
return peer;
}
2010-11-27 00:02:21 +01:00
} // namespace