Commit Graph

36 Commits

Author SHA1 Message Date
Jozef Behran
007ce24a11 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 21:56:38 +01:00
ANAND
7a0e52acd6 Revert RTT fixes (#8187)
The reverted commit 968ce9af598024ec71e9ffb2d15c3997a13ad754
is suspected (through the use of bisection) of causing network slowdowns.
Revert for now as we are close to release.
2019-02-15 23:39:22 +00:00
Lars Hofhansl
ca8ec46843 Remove legacy client handling code. 2018-07-14 11:41:05 -07:00
you
968ce9af59 RTT fixes (#7428)
* Few code updates

* Do not show average RTT before timing out

* Fix unwanted integer division in RTTStatistics

* Fix float format, prettier jitter calculation

* Use +=, 0.1f -> 100.0f for stronger average updates
2018-06-23 09:16:01 +02:00
Loïc Blot
ad7daf7b52 Add session_t typedef + remove unused functions (#6470)
* Add session_t typedef + remove unused functions

u16 peer_id is used everywhere, to be more consistent and permit some evolutions on this type in the future (i'm working on a PoC), uniformize u16 peer_id to SessionId peer_id
2017-09-27 19:47:36 +02:00
Loic Blot
a3c298e1d1
Use a Buffer instead of SharedBuffer in ConnectionCommand
This fixes #6373
2017-09-05 22:14:56 +02:00
Loïc Blot
c05228fa6d Re-apply previous commit with a typo fix 2017-09-04 17:37:08 +02:00
Loïc Blot
31e0f0efe9 Revert "Network: fix a concurrency problem, by re-adding a copy in ConnectionCommand"
This reverts commit 5b04f5e7d231437b534f4cad39da78624d97c584.
2017-09-04 17:28:29 +02:00
Loïc Blot
5b04f5e7d2 Network: fix a concurrency problem, by re-adding a copy in ConnectionCommand 2017-09-04 16:46:03 +02:00
Loic Blot
eabf04bd34
Network part requires SharedBuffers to be pass as value
This can trigger unreproductible crashes due to concurrency problem on SharedBuffers

This fixes #6354
2017-09-03 19:01:53 +02:00
Loïc Blot
3cea7a349a Network cleanup (#6310)
* Move Connection threads to dedicated files + various cleanups

* ConnectionReceiveThread::processPacket now uses function pointer table to route MT packet types
* Various code style fixes

* Code style with clang-format

* Various SharedBuffer copy removal

* SharedBuffer cannot be copied anymore using Buffer
* Fix many SharedBuffer copy (thanks to delete operator)
2017-08-25 15:53:56 +02:00
Loïc Blot
c7160cb629 Network cleanup (#6302)
* Cleanup network headers

* Move peerhandler to a specific header to reduce compilation times
* Move socket.cpp/h to network folder

* More work

* Network code cleanups

* Move socket.{cpp,h} to network folder
* Move Address object to network/address.{cpp,h}
* Move network exceptions to network/networkexceptions.h
* Client: use unique_ptr for Connection
* Server/ClientIface: use shared_ptr for Connection

* Format fixes

* Remove socket.cpp socket.h from clang-format whitelist

* Also fix NetworkPacket code style & make it under clang-format
2017-08-24 08:28:54 +02:00
Loïc Blot
1c1c97cbd1 Modernize source code: last part (#6285)
* Modernize source code: last par

* Use empty when needed
* Use emplace_back instead of push_back when needed
* For range-based loops
* Initializers fixes
* constructors, destructors default
* c++ C stl includes
2017-08-20 13:30:50 +02:00
Loïc Blot
88b436e6a9 Code modernization: subfolders (#6283)
* Code modernization: subfolders

Modernize various code on subfolders client, network, script, threading, unittests, util

* empty function
* default constructor/destructor
* for range-based loops
* use emplace_back instead of push_back
* C++ STL header style
* Make connection.cpp readable in a pointed place + typo
2017-08-19 22:23:47 +02:00
Loïc Blot
921151d97a C++ modernize: Pragma once (#6264)
* Migrate cpp headers to pragma once
2017-08-17 22:19:39 +02:00
Loïc Blot
85511a642f Cleanup various headers to reduce compilation times (#6255)
* Cleanup various headers to reduce compilation times
2017-08-16 22:11:45 +02:00
Loic Blot
342e9336ae
server.cpp: code modernization
* Use more for range based loops
* Simplify some tests
* Code style fixes
* connection.h: better PeerChange constructor instead of creating uninitalized object and then affect variables
2017-08-15 09:30:31 +02:00
Vincent Glize
8daf5b5338 C++11 cleanup on constructors dir network (#6021)
* C++11 cleanup on constructors dir network
2017-06-21 08:28:57 +02:00
Loïc Blot
d4c0f91275 Use C++11 mutexes only (remove compat code) (#5922)
* Fix event LINT & remove default constructor/destructors
* remove compat code & modernize autolock header
2017-06-06 16:29:28 +02:00
SmallJoker
d99b6fed55 Time: Change old u32 timestamps to 64-bit (#5818)
MacOSX build fix + cleanups
2017-05-26 14:03:36 +02:00
SmallJoker
f727f54192 Fix Travis/unittest broken since b662a45 2017-04-29 16:40:56 +02:00
Loïc Blot
370354cc87 Fix various performance issues reported by cppcheck (#5628)
* Also remove 1 non declared but defined functions
2017-04-21 10:06:08 +02:00
Loïc Blot
f98bbe193e Fix various copy instead of const ref reported by cppcheck (part 3) (#5616)
* Also remove 2 non declared but defined functions
* Make some functions around const ref changes const
2017-04-20 00:12:52 +02:00
est31
423d8c1b0d Tolerate packet reordering in the early init process
Fixes a bug where packet reordering made the server give the
client two peer ids instead of one. This in turn confused
reliable packet sending and made connecting to the server fail.

The client usually sends three packets at init: one "dummy"
packet consisting of two 0 bytes, and the init packet as well as
its legacy counterpart. The last one can be turned off since commit
af30183124d40a969040d7de4b3a487feec466e4, but this is of lower
relevance for the bug. The relevant part here is that network
packet reorder (which is a normal occurence) can make the packets
reach the server in different order.

If reorder puts the dummy packet further behind, the following
would happen before the patch:

1. The server will get one of the init packets on channel 1 and
   assign the client a peer id, as the packet will have zero as
   peer id.

2. The server sends a CONTROLTYPE_SET_PEER_ID packet to inform
   the client of the peer id.

3. The next packet from the client will contain the peer id set by
   the server.

4. The server sets the m_has_sent_with_id member for the client's
   peer structure to true.

5. Now the dummy packet arrives. It has a peer id of zero, therefore
   the server searches whether it already has a peer id for the
   address the packet was sent from. The search fails because
   m_has_sent_with_id was set to true and the server only searched
   for peers with m_has_sent_with_id set to false.

6. In a working setup, the server would assign the dummy packet to
   the correct peer id. However the server instead now assigns a
   second peer id and peer structure to the peer, and assign the
   packet to that new peer.

7. In order to inform the peer of its peer id, the server sends a
   CONTROLTYPE_SET_PEER_ID command packet, reliably, to the peer.
   This packet uses the new peer id.

8. The client sends an ack to that packet, not with the new peer id
   but with the peer id sent in 2.

9. This packet reaches the server, but it drops the ACK as the peer
   id does not map to any un-ACK-ed packets with that seqnum. The
   same time, the server still waits for an ACK with the new peer
   id, which of course won't come. This causes the server to
   periodically re-try sending that packet, and the client ACKing it
   each time.

Steps 7-9 cause annoyances and erroneous output, but don't cause
the connection failure itself.
The actual mistake that causes the connection failure happens in 6:
The server does not assign the dummy packet to the correct peer, but
to a newly created one.
Therefore, all further packets sent by the client on channel 0 are
now buffered by the server as it waits for the dummy packet to reach
the peer, which of course doesn't happen as the server assigned
that packet to the second peer it created for the client.
This makes the connection code indefinitely buffer the
TOSERVER_CLIENT_READY packet, not passing it to higher level code,
which stalls the continuation of the further init process
indefinitely and causes the actual bug.

Maybe this can be caused by reordered init packets as well, the only
studied case was where network has reliably reordered the dummy
packet to get sent after the init packets.

The patch fixes the bug by not ignoring peers where
m_has_sent_with_id has been set anymore. The other changes of the
patch are just cleanups of unused methods and fields and additional
explanatory comments.

One could think of alternate ways to fix the bug:

* The client could simply take the new peer id and continue
  communicating with that. This is however worse than the fix as
  it requires the peer id set command to be sent reliably (which
  currently happens, but it cant be changed anymore). Also, such a
  change would require both server and client to be patched in order
  for the bug to be fixed, as right now the client ignores peer id
  set commands after the peer id is different from
  PEER_ID_INEXISTENT and the server requires modification too to
  change the peer id internally.
  And, most importantly, right now we guarantee higher level server
  code that the peer id for a certain peer does not change. This
  guarantee would have to be broken, and it would require much
  larger changes to the server than this patch means.

* One could stop sending the dummy packet. One may be unsure whether
  this is a good idea, as the meaning of the dummy packet is not
  known (it might be there for something important), and as it is
  possible that the init packets may cause this problem as well
  (although it may be possible too that they can't cause this).

Thanks to @auouymous who had originally reported this bug and who
has helped patiently in finding its cause.
2016-05-22 15:56:54 +02:00
ShadowNinja
e4bff8be94 Clean up threading
* Rename everything.
    * Strip J prefix.
    * Change UpperCamelCase functions to lowerCamelCase.
  * Remove global (!) semaphore count mutex on OSX.
  * Remove semaphore count getter (unused, unsafe, depended on internal
    API functions on Windows, and used a hack on OSX).
  * Add `Atomic<type>`.
  * Make `Thread` handle thread names.
  * Add support for C++11 multi-threading.
  * Combine pthread and win32 sources.
  * Remove `ThreadStarted` (unused, unneeded).
  * Move some includes from the headers to the sources.
  * Move all of `Event` into its header (allows inlining with no new includes).
  * Make `Event` use `Semaphore` (except on Windows).
  * Move some porting functions into `Thread`.
  * Integrate logging with `Thread`.
  * Add threading test.
2015-08-23 22:04:06 -04:00
nerzhul
c4b5561b3f Remove unused function from connection.{cpp,h} 2015-08-15 08:48:20 +02:00
kwolekr
8560ece02e Fix BufferedPacket race condition (fixes #2983)
This was caused by the use the non-threadsafe SharedBuffer in a
threaded context.
2015-08-06 02:25:35 -04:00
Břetislav Štec
79e2647556 src/network/connection.h: Fix race condition 2015-08-01 20:44:17 +02:00
Loic Blot
8ac0cf500f connection.cpp: remove unused constructor 2015-07-14 18:33:20 +02:00
Loic Blot
4235f671c1 Fix uninitialized variabled in ConnectionEvent 2015-04-05 11:13:30 +02:00
Loic Blot
1fe4256462 Connection::Receive(): receive Network Packet instead of SharedBuffer<u8>.
Because we get a Buffer<u8> from ConnectionEvent, don't convert it to SharedBuffer<u8> and return it to Server/Client::Receive which will convert it to NetworkPacket
Instead, put the Buffer<u8> directly to NetworkPacket and return it to packet processing
This remove a long existing memory copy
Also check the packet size directly into Connection::Receive instead of packet processing
2015-03-31 11:01:08 +02:00
Loic Blot
dfe00abc5a queued_commands must be a std::deque. RunCommandQueues needs to push packet on front, not back 2015-03-29 10:49:43 +02:00
Loic Blot
61f2d0ca34 Remove unused ConnectionCommand::sendToAll function. NetworkPacket::oldForgePacket returns Buffer instead of SharedBuffer and is used in ConnectionCommand instead of Connection::Send
This remove the NetworkPacket buffer => SharedBuffer => Buffer copy. Now NetworkPacket => Buffer
2015-03-22 12:18:16 +01:00
Craig Robbins
ced6d20295 For usages of assert() that are meant to persist in Release builds (when NDEBUG is defined), replace those usages with persistent alternatives 2015-03-07 22:41:47 +10:00
Loic Blot
b214cde5b4 Remove Queue class which uses std::list and use native std::queue 2015-03-05 16:49:51 +10:00
Loic Blot
ed04e8e9e4 [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-02-16 11:00:55 +01:00