Skip to content

Commit 547dfdc

Browse files
committed
add whacky protocol version negotiation
1 parent f64ec1c commit 547dfdc

5 files changed

Lines changed: 34 additions & 13 deletions

File tree

core/src/main/java/pl/skidam/automodpack_core/protocol/DownloadClient.java

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -282,7 +282,7 @@ protected SSLSocket getSocket() {
282282
*/
283283
class Connection implements AutoCloseable {
284284

285-
private byte protocolVersion = PROTOCOL_VERSION;
285+
private byte protocolVersion = LATEST_SUPPORTED_PROTOCOL_VERSION;
286286
private byte compressionType = COMPRESSION_ZSTD;
287287
private int chunkSize = DEFAULT_CHUNK_SIZE;
288288
private final byte[] secretBytes;
@@ -513,6 +513,10 @@ private byte sendCompressionConfig(byte desiredCompression) throws IOException {
513513
out.flush();
514514

515515
byte version = in.readByte();
516+
if (version >= 1 && version < protocolVersion) {
517+
protocolVersion = version;
518+
}
519+
516520
byte type = in.readByte();
517521
if (type != CONFIGURATION_COMPRESSION_TYPE) throw new IOException("Unexpected response: " + type);
518522

@@ -534,6 +538,10 @@ private int sendChunkSizeConfig(int desiredChunkSize) throws IOException {
534538
out.flush();
535539

536540
byte version = in.readByte();
541+
if (version >= 1 && version < protocolVersion) {
542+
protocolVersion = version;
543+
}
544+
537545
byte type = in.readByte();
538546
if (type != CONFIGURATION_CHUNK_SIZE_TYPE) throw new IOException("Unexpected response: " + type);
539547

core/src/main/java/pl/skidam/automodpack_core/protocol/NetUtils.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ public class NetUtils {
3030
public static final int MAGIC_AMOK = 0x414D4F4B;
3131

3232
// Protocol versions
33-
public static final byte PROTOCOL_VERSION = 0x01;
33+
public static final byte LATEST_SUPPORTED_PROTOCOL_VERSION = 0x01;
3434

3535
// Compression types
3636
public static final byte COMPRESSION_NONE = 0x00;

core/src/main/java/pl/skidam/automodpack_core/protocol/netty/handler/ConfigurationHandler.java

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,14 @@ public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception
3131
LOGGER.debug("Message version: {}, type: {}, readable bytes: {}", version, type, in.readableBytes());
3232
if ((type & 0xF0) == 0x40) {
3333
if (type == CONFIGURATION_ECHO_TYPE) {
34+
if (version > LATEST_SUPPORTED_PROTOCOL_VERSION || version <= 0) {
35+
LOGGER.debug("Failed to negotatie protocol version with client");
36+
ctx.close();
37+
return;
38+
}
39+
ctx.channel().attr(NettyServer.PROTOCOL_VERSION).set(version);
40+
LOGGER.debug("Negotiated {} protocol version with the client", version);
41+
3442
// remove this channel from pipeline
3543
ctx.pipeline().remove(this);
3644
LOGGER.debug("Removed ConfigurationHandler from pipeline after receiving echo configuration message.");
@@ -54,7 +62,7 @@ public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception
5462
ctx.channel().attr(NettyServer.COMPRESSION_TYPE).set(negotiatedCompressionType);
5563

5664
// Send negotiated values back to client
57-
ConfigurationCompressionMessage responseMsg = new ConfigurationCompressionMessage(PROTOCOL_VERSION, negotiatedCompressionType);
65+
ConfigurationCompressionMessage responseMsg = new ConfigurationCompressionMessage(LATEST_SUPPORTED_PROTOCOL_VERSION, negotiatedCompressionType);
5866
ctx.writeAndFlush(responseMsg.toByteBuf());
5967

6068
LOGGER.debug("Negotiated configuration: compression {}", negotiatedCompressionType);
@@ -78,13 +86,13 @@ public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception
7886
ctx.channel().attr(NettyServer.CHUNK_SIZE).set(negotiatedChunkSize);
7987

8088
// Send negotiated values back to client
81-
ConfigurationChunkSizeMessage responseMsg = new ConfigurationChunkSizeMessage(PROTOCOL_VERSION, negotiatedChunkSize);
89+
ConfigurationChunkSizeMessage responseMsg = new ConfigurationChunkSizeMessage(LATEST_SUPPORTED_PROTOCOL_VERSION, negotiatedChunkSize);
8290
ctx.writeAndFlush(responseMsg.toByteBuf());
8391

8492
LOGGER.debug("Negotiated configuration: chunk size {}", negotiatedChunkSize);
8593
} else {
8694
LOGGER.debug("Received unknown configuration message type: {} version: {}", type, version);
87-
UnknownConfigurationMessage responseMsg = new UnknownConfigurationMessage(PROTOCOL_VERSION);
95+
UnknownConfigurationMessage responseMsg = new UnknownConfigurationMessage(LATEST_SUPPORTED_PROTOCOL_VERSION);
8896
ctx.writeAndFlush(responseMsg.toByteBuf());
8997
}
9098
in.release(); // Release the buffer after processing configuration message

core/src/main/java/pl/skidam/automodpack_core/protocol/netty/handler/ProtocolServerHandler.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,7 @@ private void setupPipeline(ChannelHandlerContext ctx) {
189189
}
190190

191191
ctx.channel().attr(NettyServer.REAL_REMOTE_ADDR).set(remoteAddress);
192-
ctx.channel().attr(NettyServer.PROTOCOL_VERSION).set(PROTOCOL_VERSION);
192+
ctx.channel().attr(NettyServer.PROTOCOL_VERSION).set(LATEST_SUPPORTED_PROTOCOL_VERSION);
193193
ctx.channel().attr(NettyServer.COMPRESSION_TYPE).set(COMPRESSION_ZSTD);
194194
ctx.channel().attr(NettyServer.CHUNK_SIZE).set(DEFAULT_CHUNK_SIZE);
195195

core/src/main/java/pl/skidam/automodpack_core/protocol/netty/handler/ServerMessageHandler.java

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -40,24 +40,29 @@ public void handlerRemoved(ChannelHandlerContext ctx) {
4040

4141
@Override
4242
protected void channelRead0(ChannelHandlerContext ctx, ProtocolMessage msg) throws Exception {
43+
this.protocolVersion = ctx.pipeline().channel().attr(NettyServer.PROTOCOL_VERSION).get();
44+
this.chunkSize = ctx.pipeline().channel().attr(NettyServer.CHUNK_SIZE).get();
45+
4346
byte clientProtocolVersion = msg.getVersion();
47+
48+
if (protocolVersion != clientProtocolVersion) {
49+
sendError(ctx, protocolVersion, "Protocol version mismatch");
50+
return;
51+
}
52+
4453
SocketAddress address = ctx.channel().attr(NettyServer.REAL_REMOTE_ADDR).get();
4554

4655
// Validate the secret
4756
if (!validateSecret(ctx, address, msg.getSecret())) {
48-
sendError(ctx, clientProtocolVersion, "Authentication failed");
57+
sendError(ctx, protocolVersion, "Authentication failed");
4958
return;
5059
}
5160

52-
// reassign channel attributes
53-
this.protocolVersion = ctx.pipeline().channel().attr(NettyServer.PROTOCOL_VERSION).get();
54-
this.chunkSize = ctx.pipeline().channel().attr(NettyServer.CHUNK_SIZE).get();
55-
5661
switch (msg.getType()) {
5762
case ECHO_TYPE:
5863
EchoMessage echoMsg = (EchoMessage) msg;
5964
ByteBuf echoBuf = ctx.alloc().buffer(1 + 1 + msg.getSecret().length + echoMsg.getData().length);
60-
echoBuf.writeByte(clientProtocolVersion);
65+
echoBuf.writeByte(protocolVersion);
6166
echoBuf.writeByte(ECHO_TYPE);
6267
echoBuf.writeBytes(echoMsg.getSecret());
6368
echoBuf.writeBytes(echoMsg.getData());
@@ -73,7 +78,7 @@ protected void channelRead0(ChannelHandlerContext ctx, ProtocolMessage msg) thro
7378
refreshModpackFiles(ctx, refreshRequest.getFileHashesList());
7479
break;
7580
default:
76-
sendError(ctx, clientProtocolVersion, "Unknown message type");
81+
sendError(ctx, protocolVersion, "Unknown message type");
7782
}
7883
}
7984

0 commit comments

Comments
 (0)