Split Protocol version into Handshake vs Orders.

Handshake is kept at 7.
Orders is incremented to 8 to reflect immediate order changes.
This commit is contained in:
Paul Chote
2019-05-31 19:03:49 +00:00
committed by abcdefg30
parent fe41dcb45e
commit c6232f20f9
5 changed files with 30 additions and 9 deletions

View File

@@ -167,12 +167,12 @@ namespace OpenRA.Network
{ {
var networkStream = (NetworkStream)networkStreamObject; var networkStream = (NetworkStream)networkStreamObject;
var reader = new BinaryReader(networkStream); var reader = new BinaryReader(networkStream);
var serverProtocol = reader.ReadInt32(); var handshakeProtocol = reader.ReadInt32();
if (serverProtocol != ProtocolVersion.Version) if (handshakeProtocol != ProtocolVersion.Handshake)
throw new InvalidOperationException( throw new InvalidOperationException(
"Protocol version mismatch. Server={0} Client={1}" "Handshake protocol version mismatch. Server={0} Client={1}"
.F(serverProtocol, ProtocolVersion.Version)); .F(handshakeProtocol, ProtocolVersion.Handshake));
clientId = reader.ReadInt32(); clientId = reader.ReadInt32();
connectionState = ConnectionState.Connected; connectionState = ConnectionState.Connected;

View File

@@ -41,6 +41,10 @@ namespace OpenRA.Network
public string Version; public string Version;
public string Password; public string Password;
// Default value is hardcoded to 7 so that newer servers
// (which define OrdersProtocol > 7) can detect older clients
public int OrdersProtocol = 7;
// For player authentication // For player authentication
public string Fingerprint; public string Fingerprint;
public string AuthSignature; public string AuthSignature;
@@ -74,7 +78,7 @@ namespace OpenRA.Network
{ {
var data = new List<MiniYamlNode>(); var data = new List<MiniYamlNode>();
data.Add(new MiniYamlNode("Handshake", null, data.Add(new MiniYamlNode("Handshake", null,
new string[] { "Mod", "Version", "Password", "Fingerprint", "AuthSignature" }.Select(p => FieldSaver.SaveField(this, p)).ToList())); new[] { "Mod", "Version", "Password", "Fingerprint", "AuthSignature", "OrdersProtocol" }.Select(p => FieldSaver.SaveField(this, p)).ToList()));
data.Add(new MiniYamlNode("Client", FieldSaver.Save(Client))); data.Add(new MiniYamlNode("Client", FieldSaver.Save(Client)));
return data.WriteToString(); return data.WriteToString();

View File

@@ -227,7 +227,8 @@ namespace OpenRA.Network
Mod = mod.Id, Mod = mod.Id,
Version = mod.Metadata.Version, Version = mod.Metadata.Version,
Password = orderManager.Password, Password = orderManager.Password,
Fingerprint = localProfile.Fingerprint Fingerprint = localProfile.Fingerprint,
OrdersProtocol = ProtocolVersion.Orders
}; };
if (request.AuthToken != null && response.Fingerprint != null) if (request.AuthToken != null && response.Fingerprint != null)

View File

@@ -13,7 +13,13 @@ namespace OpenRA.Server
{ {
public static class ProtocolVersion public static class ProtocolVersion
{ {
// you *must* increment this whenever you make an incompatible protocol change // The protocol for the initial handshake request and response
public static readonly int Version = 7; // Backwards incompatible changes will break runtime mod switching, so only change as a last resort!
public const int Handshake = 7;
// The protocol for server and world orders
// This applies after the handshake has completed, and is provided to support
// alternative server implementations that wish to support multiple versions in parallel
public const int Orders = 8;
} }
} }

View File

@@ -278,7 +278,7 @@ namespace OpenRA.Server
// Send handshake and client index. // Send handshake and client index.
var ms = new MemoryStream(8); var ms = new MemoryStream(8);
ms.WriteArray(BitConverter.GetBytes(ProtocolVersion.Version)); ms.WriteArray(BitConverter.GetBytes(ProtocolVersion.Handshake));
ms.WriteArray(BitConverter.GetBytes(newConn.PlayerIndex)); ms.WriteArray(BitConverter.GetBytes(newConn.PlayerIndex));
SendData(newConn.Socket, ms.ToArray()); SendData(newConn.Socket, ms.ToArray());
@@ -363,6 +363,16 @@ namespace OpenRA.Server
return; return;
} }
if (handshake.OrdersProtocol != ProtocolVersion.Orders)
{
Log.Write("server", "Rejected connection from {0}; incompatible Orders protocol version {1}.",
newConn.Socket.RemoteEndPoint, handshake.OrdersProtocol);
SendOrderTo(newConn, "ServerError", "Server is running an incompatible protocol");
DropClient(newConn);
return;
}
// Check if IP is banned // Check if IP is banned
var bans = Settings.Ban.Union(TempBans); var bans = Settings.Ban.Union(TempBans);
if (bans.Contains(client.IpAddress)) if (bans.Contains(client.IpAddress))