With my fix from 9eb2478b2 ("C4NetIOUDP: Fix timeout during non-MC
connection"), C4NetIOUDP would send data packets to the master server
before the ConnOK packet. The server would then discard these data
packets, resulting in a one-second delay until retransmission.
The "normal" connection process is a three-way handshake (Conn->,
<-Conn, ConnOK->). When establishing a multicast connection, this
handshake is repeated via the MC address. However, the code always
expected that second handshake to happen and thus ran into a timeout on
the client in the non-MC case, repeating the handshake a second time. In
the end, it usually still worked as the server supports reconnecting,
but packets may be lost in the process.
A follow-up on a previous PR GH-41. The discussion in the forum can be
viewed at http://forum.openclonk.org/topic_show.pl?pid=33086.
Run clang-tidy (without auto, pass-by-value and using checks) to fix the
header files not modified in the previous PR.
Summary of the changes:
- C++11 member initialization.
- nullptr instead of 0 for pointers.
- override for functions declared virtual in base class.
- default trivial special member functions
Consolidate the include statements scattered across the code in accordance
with the comment in C4Include.h. The advantages are listed in the same
comment.
Furthermore, it follows llvm-include-order which is the logical
extrapolation of the project's style guideline wherever possible
(C4Include.h being the most-frequent exception).
Instead of "Compiler" and "Decompiler", which make me look up what's
even going on each time I see them, use the standard terms "serializer"
and "deserializer".
We don't benefit at all from privacy addresses as we're publishing all
local addresses in any case. By preferring stable addresses, we can
avoid reconnection issues after the preferred address changes.
This API is defined in RFC5014, but apparently only implemented in
Linux.
In contrast to getifaddrs(), /proc/net/if_inet6 allows filtering
deprecated privacy addresses. As these addresses generally won't be
useful for new connections, there's no reason to include them and they
only cause unnecessary connection attempts.
On Linux, all IPv6 sockets are dual-stack per default; on Windows, they
are not. It's still a good idea to set the option on Linux as well as
the default value can be changed.
When connecting via TCP, C4NetIO still creates IPv4 sockets, so no dual
stack option is required there.
It's not actually used anywhere, but it's not broken now!
This also moves the low-level and OS-specific GetLocalAddresses code to
C4NetIO where it's fitting better than in C4Network2Client.
We use ff02::1 as discovery multicast address.
This "all nodes" multicast address is good enough for discovery in the
local network as packets there are likely broadcasted over ethernet
anyways.
The C++ standard library comes with perfectly fine implementations of
these functions, so there's no point in reimplementing them just for the
hell of it.
We already require support for std::unique_ptr, which itself requires
support for rvalue references. As such, we know we can use rvalue
references, and thus don't have to keep carrying dead code around.
As discussed in http://forum.openclonk.org/topic_show.pl?tid=2917, I
have merged all copyright notices into a single file and referenced that
merged file from each source file.
For the updated source files, the timeline has been split into three
parts:
1. Pre-RWD code (before 2001)
2. RWD code (2001 through 2009)
3. OpenClonk code (2009 and later)
All pre-RWD copyright notices have been left intact, as have RWD-era
copyright notices where the file did not have a RedWolf design copyright
notice but only individual author ones. All copyright notices of the
OpenClonk era have been replaced by a single notice ranging from the
first recorded year to the current year (2013). Mape code did not get a
OpenClonk Team copyright notice because it is somewhat separate from the
main OpenClonk codebase and has only been touched by Armin Burgmeier.
The new type C4TimeMilliseconds behaves for the most part like a uint32_t but is overflow-proof in comparisons.
In some places, a 0-value (or uint_max) of the variable storing the time had the special meaning "not set yet". This has been resolved by having it as a pointer to C4TimeMilliseconds with NULL meaning that it has not been set yet.
The network used to cast GetTime() to int, but GetTime() is an unsigned long. This might cause problems if GetTime() returns big integers (see #251). To solve this, the StdSchedulerProc interface had to be extended with another function in order to eliminate the magic return value -1 of GetNextTick for "no scheduled execution".
Given that SimpleUDP makes no promises on delivering data anyway, it's okay
to just drop packets silently.
While I'm at it, it's probably a good idea for non-Windows system to
set sockets as non-blocking too, as well as C4NetIOUDP to be more
consistent with its handling of errors along these lines.