diff --git a/Robust.Shared/CVars.cs b/Robust.Shared/CVars.cs index e3751ad0c2..6b61f349cf 100644 --- a/Robust.Shared/CVars.cs +++ b/Robust.Shared/CVars.cs @@ -35,6 +35,44 @@ namespace Robust.Shared public static readonly CVarDef NetMaxConnections = CVarDef.Create("net.max_connections", 256, CVar.ARCHIVE | CVar.REPLICATED | CVar.SERVER); + /// + /// How many seconds after the last message from the server or a client before we consider it timed out. + /// + public static readonly CVarDef NetConnectionTimeout = + CVarDef.Create("net.connection_timeout", 25.0f, CVar.ARCHIVE); + + /// + /// Hard max-cap of concurrent connections per client IP address. + /// Clients will always get a disconnection packet. + /// + /// + /// This cannot be bypassed in any way, since it is used by Lidgren internally. + /// + public static readonly CVarDef NetMaxIpConnections = + CVarDef.Create("net.max_ip_connections", 8, CVar.ARCHIVE); + + /// + /// Hard max-cap of connections a single client IP address can attempt in a window of net.rapid_connection_window. + /// Clients will only get a disconnection packet the first time, their packets are dropped afterwards. + /// + /// + /// This cannot be bypassed in any way, since it is used by Lidgren internally. + /// + public static readonly CVarDef NetMaxRapidConnections = + CVarDef.Create("net.max_rapid_connections", 3, CVar.ARCHIVE); + + /// + /// How many seconds until connection count decays for net.max_rapid_connections. + /// + public static readonly CVarDef NetRapidConnectionWindow = + CVarDef.Create("net.rapid_connection_window", 60.0, CVar.ARCHIVE); + + /// + /// How many connections are "forgotten" every net.rapid_connection_window seconds. + /// + public static readonly CVarDef NetRapidConnectionDecay = + CVarDef.Create("net.rapid_connection_decay", 1, CVar.ARCHIVE); + /// /// UDP port to bind to for main game networking. /// Each address specified in net.bindto is bound with this port. @@ -298,12 +336,6 @@ namespace Robust.Shared public static readonly CVarDef NetTimeStartOffset = CVarDef.Create("net.time_start_offset", 0, CVar.SERVERONLY); - /// - /// How many seconds after the last message from the server before we consider it timed out. - /// - public static readonly CVarDef ConnectionTimeout = - CVarDef.Create("net.connection_timeout", 25.0f, CVar.ARCHIVE | CVar.CLIENTONLY); - /// /// When doing the connection handshake, how long to wait before initial connection attempt packets. /// diff --git a/Robust.Shared/Network/NetManager.cs b/Robust.Shared/Network/NetManager.cs index 14a5827874..2f6b3eaa0d 100644 --- a/Robust.Shared/Network/NetManager.cs +++ b/Robust.Shared/Network/NetManager.cs @@ -273,6 +273,11 @@ namespace Robust.Shared.Network _config.OnValueChanged(CVars.NetLidgrenLogRateLimitTargets, LidgrenLogRateLimitTargetsChanged); _config.OnValueChanged(CVars.NetLidgrenLogRateLimitBurst, LidgrenLogRateLimitBurstChanged); _config.OnValueChanged(CVars.NetLidgrenLogRateLimitWindow, LidgrenLogRateLimitWindowChanged); + _config.OnValueChanged(CVars.NetConnectionTimeout, ConnectionTimeoutChanged); + _config.OnValueChanged(CVars.NetMaxIpConnections, MaxIpConnectionsChanged); + _config.OnValueChanged(CVars.NetMaxRapidConnections, MaxRapidConnectionsChanged); + _config.OnValueChanged(CVars.NetRapidConnectionWindow, RapidConnectionWindowChanged); + _config.OnValueChanged(CVars.NetRapidConnectionDecay, RapidConnectionDecayChanged); _config.OnValueChanged(CVars.NetVerbose, NetVerboseChanged); _config.OnValueChanged(CVars.NetLogging, NetLoggingChanged); @@ -352,6 +357,46 @@ namespace Robust.Shared.Network } } + private void ConnectionTimeoutChanged(float timeout) + { + foreach (var netPeer in _netPeers) + { + netPeer.Peer.Configuration.ConnectionTimeout = timeout; + } + } + + private void MaxIpConnectionsChanged(int limit) + { + foreach (var netPeer in _netPeers) + { + netPeer.Peer.Configuration.MaximumIpConnections = limit; + } + } + + private void MaxRapidConnectionsChanged(int limit) + { + foreach (var netPeer in _netPeers) + { + netPeer.Peer.Configuration.MaximumRapidConnections = limit; + } + } + + private void RapidConnectionWindowChanged(double time) + { + foreach (var netPeer in _netPeers) + { + netPeer.Peer.Configuration.RapidConnectionWindow = time; + } + } + + private void RapidConnectionDecayChanged(int decay) + { + foreach (var netPeer in _netPeers) + { + netPeer.Peer.Configuration.RapidConnectionDecay = decay; + } + } + private void OnAuthModeChanged(int mode) { Auth = (AuthMode)mode; @@ -529,6 +574,11 @@ namespace Robust.Shared.Network _config.UnsubValueChanged(CVars.NetLidgrenLogRateLimitTargets, LidgrenLogRateLimitTargetsChanged); _config.UnsubValueChanged(CVars.NetLidgrenLogRateLimitBurst, LidgrenLogRateLimitBurstChanged); _config.UnsubValueChanged(CVars.NetLidgrenLogRateLimitWindow, LidgrenLogRateLimitWindowChanged); + _config.UnsubValueChanged(CVars.NetConnectionTimeout, ConnectionTimeoutChanged); + _config.UnsubValueChanged(CVars.NetMaxIpConnections, MaxIpConnectionsChanged); + _config.UnsubValueChanged(CVars.NetMaxRapidConnections, MaxRapidConnectionsChanged); + _config.UnsubValueChanged(CVars.NetRapidConnectionWindow, RapidConnectionWindowChanged); + _config.UnsubValueChanged(CVars.NetRapidConnectionDecay, RapidConnectionDecayChanged); _serializer.ClientHandshakeComplete -= OnSerializerOnClientHandshakeComplete; @@ -732,11 +782,14 @@ namespace Robust.Shared.Network } else { - netConfig.ConnectionTimeout = _config.GetCVar(CVars.ConnectionTimeout); netConfig.ResendHandshakeInterval = _config.GetCVar(CVars.ResendHandshakeInterval); netConfig.MaximumHandshakeAttempts = _config.GetCVar(CVars.MaximumHandshakeAttempts); } - + netConfig.ConnectionTimeout = _config.GetCVar(CVars.NetConnectionTimeout); + netConfig.MaximumIpConnections = _config.GetCVar(CVars.NetMaxIpConnections); + netConfig.MaximumRapidConnections = _config.GetCVar(CVars.NetMaxRapidConnections); + netConfig.RapidConnectionWindow = _config.GetCVar(CVars.NetRapidConnectionWindow); + netConfig.RapidConnectionDecay = _config.GetCVar(CVars.NetRapidConnectionDecay); //Simulate Latency netConfig.SimulatedLoss = _config.GetCVar(CVars.NetFakeLoss);