Age | Commit message (Collapse) | Author |
|
|
|
|
|
Fix toggling the up-to-date filter
|
|
|
|
|
|
Don't hash protocol header twice in bam.lua
|
|
This reverts commit 9892a30f8b5c465fefec84e0e391158b104597f7.
|
|
Add an 'up-to-date' server browser filter, filters out previous server versions
|
|
This was only fixed in CMake, resulting in differing nethashes.
|
|
Fix 0.6 nethash
|
|
Update zlib to 1.2.11 (for 0.6)
|
|
preceding that of the client
|
|
|
|
|
|
This reverts commit ebeb289fef90df0b9a060f6e197b58472660a515.
|
|
Previously, it would pause the game when the last player left.
|
|
(cherry picked from commit 9b27da8e4a83163aea2235a9a4ee02fdb3b72021)
|
|
|
|
It needs explicit template instantiations for
src/engine/server/server.cpp, for the Ban function.
|
|
|
|
There are two sets of variables for this ratelimit
First, there are `sv_old_clients_per_interval` and
`sv_old_clients_interval` which specify an interval and the number of
clients that can join during that time without being ratelimited.
If you get ratelimited, you get a one in `sv_old_clients_skip` chance of
still continuing the handshake.
Together, this should maintain usability while not under attack and
still being able to connect while under attack.
The defaults are a maximum of 5 connections in 20 seconds without
ratelimit and then only accepting every twentieth connection attempt.
This comes from the following calculation:
A legacy connection request packet consists of 4 bytes UDP data bytes,
the response to that weighs at most 57 UDP data bytes. This results in a
reflection rate of ~15, so 20 should be rather safe from that.
If I add the other protocol headers, I get 42 extra bytes per packet for
IPv4 and 62 extra bytes per packet for IPv6 (determined with Wireshark).
In these cases, the reflection rate is just around 3 or around 2.7,
respectively. So perhaps one could lower `sv_old_clients_skip`
furtherly.
There's an expected waiting time of `sv_old_clients_skip` / 2 seconds
for legitimate clients because those send a connection attempt every
500ms, with a geometric distribution.
|
|
This work is basically on eeeee's handshake developed for DDRace.
It works by realizing that the client will send back tick numbers sent
in snapshots. The client puts these into a field named "last acked
snapshot", aka the last snapshot the client saw (used for delta
compression). This can be abused for a challenge-response handshake.
For legacy clients (detected by a short `CTRLMSG_CONNECT` message), the
idea is, upon reception of the `CTRLMSG_CONNECT` packet, to send a
`CTRLMSG_CONNECTACCEPT` to fake accepting the connection, then send a
packet containing all of the following: the rest of the initial
connection build up (`MAP_CHANGE` to the standard dm1 map, `CON_READY`)
and three empty snapshots (`SNAPEMPTY`) with the desired challenge. Due
to client-side constraints, the token must be between 2 and `MAX_INT`.
This lowers the security by roughly one bit to around 31 bits.
If the `CTRLMSG_CONNECTACCEPT` message gets through to the client, but
the other packet does not, the client is stuck. It won't receive any
more packets from the server. If the client does not have the standard
dm1 map, it will crash, since it accepts the `CON_READY` message from
the server despite not having any map data.
No data is saved until this point.
When one receives an `INPUT` packet by a previously unknown client, the
server checks whether it contains a correct token, and if it does,
accept the new client. The client has received two vital messages from
the server so far, so it expects the next sequence number to be 3. The
client has sent an unknown amount of vital messages (might be a custom
client) so we don't know what ack numbers it wants to see. We just treat
the first vital chunk we receive as the new ack number. If we miss a
packet due to that, the handshake will be broken and the client will be
stuck. We send a `MAP_CHANGE` to the current map of the server and
continue normally.
Due to the large difference between packet sizes sent by the client to
packets sent by the server, this legacy handshake is prone to reflection
attacks due to IP spoofing. Rate limiting should be added.
|
|
|
|
|
|
Tokens are added to the protocol in order to prevent IP spoofing attacks
from being successful.
A new flag has been added to the packet header, in previously unused
space that has incorrectly been interpreted as part of the `ack` field
(which needs to be 10 bits wide but 12 bits were used).
The flags are now, in the first byte, from highest to lowest:
- Compression
- Resend requested
- Connectionless
- Control
- Token
If the token flag is present, the previously 3 bytes header is extended
by 4 bytes that contain the token[1]. This token was added in order to
prevent IP spoofing to be successful.
The connection setup now works as follows:
The client (connection initiator) sends a `NET_CTRLMSG_CONNECT` message
with a payload of at least 512 bytes, without the token flag. Bytes 5 to
8 of the payload contain the token that the server needs to play back to
the client.
The token flag isn't sent in order to maintain compatibility with
servers that do not support the flag, they would interpret it as part of
the `ack` field and drop the packet otherwise.
The size requirement is in place to make the `NET_CTRLMSG_CONNECT`
message useless for reflection attacks.
The server (connection acceptor) sends a `NET_CTRLMSG_CONNECTACCEPT`
message with the token field set to the client's token, and the first
four payload bytes being the token for the established connection.
The server does not save any data about this connection request,
instead, it combines the client's IP together with a frequently rotated
secret in order to obtain the connection token. This prevents the denial
of service attack of sending a lot of `NET_CTRLMSG_CONNECT` packets to
the server.
The client now sends its first protocol message in a packet containing a
token, if the server receives such a message, it allocates a client slot
for the new connection, or sends a close message to inform the client
that no slot is available for it.
For backward compatibility, if `sv_allow_old_clients` is set to 1, the
client continues to accept `NET_CTRLMSG_CONNECTACCEPT` messages without
the token flag.
This removes the `NET_CONNSTATE_PENDING` connection state (as that's
only implicitly tracked now) and the `NET_CTRLMSG_ACCEPT` (as that
message is unused on the other side and is unreliable anyway).
|
|
This prevents the 500ms timeout from triggering.
|
|
|
|
(cherry picked from commit 903878f4a2fe63cd7df2fa998129f517faf9ee2a)
|
|
(cherry picked from commit 6fd9bc3d3e099c300c2c13abe9b0a943e76f82fb)
|
|
Sometimes `sdl-config` and `freetype-config` might not exist despite the
libs being installed.
|
|
|
|
(cherry picked from commit 64ca2cfde9dc4857e338c3953cfee1138f3c4fb2)
|
|
This reverts commit 4c00063b2fd9c25998f3d308723e1ae65c20548d.
|
|
authentication"
This reverts commit 439483cef207f3e09f453c3406343a21eff7ba68.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Fixes and refinements
|
|
|
|
|
|
|
|
|
|
|
|
Previously, when walking with negative x-coordinate, your walking direction was
inversed.
|
|
|