Skip to content

Commit 188fc5f

Browse files
author
yungyu16
committed
fix: enhance token server request handling and add max frame length validation
1 parent a08dc69 commit 188fc5f

File tree

4 files changed

+54
-43
lines changed

4 files changed

+54
-43
lines changed

sentinel-cluster/sentinel-cluster-server-default/src/main/java/com/alibaba/csp/sentinel/cluster/server/NettyTransportServer.java

Lines changed: 30 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -15,17 +15,12 @@
1515
*/
1616
package com.alibaba.csp.sentinel.cluster.server;
1717

18-
import java.util.ArrayList;
19-
import java.util.List;
20-
import java.util.concurrent.atomic.AtomicInteger;
21-
2218
import com.alibaba.csp.sentinel.cluster.server.codec.netty.NettyRequestDecoder;
2319
import com.alibaba.csp.sentinel.cluster.server.codec.netty.NettyResponseEncoder;
2420
import com.alibaba.csp.sentinel.cluster.server.connection.Connection;
2521
import com.alibaba.csp.sentinel.cluster.server.connection.ConnectionPool;
2622
import com.alibaba.csp.sentinel.cluster.server.handler.TokenServerHandler;
2723
import com.alibaba.csp.sentinel.log.RecordLog;
28-
2924
import io.netty.bootstrap.ServerBootstrap;
3025
import io.netty.buffer.PooledByteBufAllocator;
3126
import io.netty.channel.ChannelFuture;
@@ -42,7 +37,14 @@
4237
import io.netty.util.concurrent.GenericFutureListener;
4338
import io.netty.util.internal.SystemPropertyUtil;
4439

45-
import static com.alibaba.csp.sentinel.cluster.server.ServerConstants.*;
40+
import java.util.ArrayList;
41+
import java.util.List;
42+
import java.util.concurrent.atomic.AtomicInteger;
43+
44+
import static com.alibaba.csp.sentinel.cluster.server.ServerConstants.NETTY_MAX_FRAME_LENGTH;
45+
import static com.alibaba.csp.sentinel.cluster.server.ServerConstants.SERVER_STATUS_OFF;
46+
import static com.alibaba.csp.sentinel.cluster.server.ServerConstants.SERVER_STATUS_STARTED;
47+
import static com.alibaba.csp.sentinel.cluster.server.ServerConstants.SERVER_STATUS_STARTING;
4648

4749
/**
4850
* @author Eric Zhao
@@ -51,7 +53,7 @@
5153
public class NettyTransportServer implements ClusterTokenServer {
5254

5355
private static final int DEFAULT_EVENT_LOOP_THREADS = Math.max(1,
54-
SystemPropertyUtil.getInt("io.netty.eventLoopThreads", Runtime.getRuntime().availableProcessors() * 2));
56+
SystemPropertyUtil.getInt("io.netty.eventLoopThreads", Runtime.getRuntime().availableProcessors() * 2));
5557
private static final int MAX_RETRY_TIMES = 3;
5658
private static final int RETRY_SLEEP_MS = 2000;
5759

@@ -79,32 +81,32 @@ public void start() {
7981
this.bossGroup = new NioEventLoopGroup(1);
8082
this.workerGroup = new NioEventLoopGroup(DEFAULT_EVENT_LOOP_THREADS);
8183
b.group(bossGroup, workerGroup)
82-
.channel(NioServerSocketChannel.class)
83-
.option(ChannelOption.SO_BACKLOG, 128)
84-
.handler(new LoggingHandler(LogLevel.INFO))
85-
.childHandler(new ChannelInitializer<SocketChannel>() {
86-
@Override
87-
public void initChannel(SocketChannel ch) throws Exception {
88-
ChannelPipeline p = ch.pipeline();
89-
p.addLast(new LengthFieldBasedFrameDecoder(1024, 0, 2, 0, 2));
90-
p.addLast(new NettyRequestDecoder());
91-
p.addLast(new LengthFieldPrepender(2));
92-
p.addLast(new NettyResponseEncoder());
93-
p.addLast(new TokenServerHandler(connectionPool));
94-
}
95-
})
96-
.childOption(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT)
97-
.childOption(ChannelOption.SO_SNDBUF, 32 * 1024)
98-
.childOption(ChannelOption.CONNECT_TIMEOUT_MILLIS, 10000)
99-
.childOption(ChannelOption.SO_TIMEOUT, 10)
100-
.childOption(ChannelOption.TCP_NODELAY, true)
101-
.childOption(ChannelOption.SO_RCVBUF, 32 * 1024);
84+
.channel(NioServerSocketChannel.class)
85+
.option(ChannelOption.SO_BACKLOG, 128)
86+
.handler(new LoggingHandler(LogLevel.INFO))
87+
.childHandler(new ChannelInitializer<SocketChannel>() {
88+
@Override
89+
public void initChannel(SocketChannel ch) throws Exception {
90+
ChannelPipeline p = ch.pipeline();
91+
p.addLast(new LengthFieldBasedFrameDecoder(NETTY_MAX_FRAME_LENGTH, 0, 2, 0, 2));
92+
p.addLast(new NettyRequestDecoder());
93+
p.addLast(new LengthFieldPrepender(2));
94+
p.addLast(new NettyResponseEncoder());
95+
p.addLast(new TokenServerHandler(connectionPool));
96+
}
97+
})
98+
.childOption(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT)
99+
.childOption(ChannelOption.SO_SNDBUF, 32 * 1024)
100+
.childOption(ChannelOption.CONNECT_TIMEOUT_MILLIS, 10000)
101+
.childOption(ChannelOption.SO_TIMEOUT, 10)
102+
.childOption(ChannelOption.TCP_NODELAY, true)
103+
.childOption(ChannelOption.SO_RCVBUF, 32 * 1024);
102104
b.bind(port).addListener(new GenericFutureListener<ChannelFuture>() {
103105
@Override
104106
public void operationComplete(ChannelFuture future) {
105107
if (future.cause() != null) {
106108
RecordLog.info("[NettyTransportServer] Token server start failed (port=" + port + "), failedTimes: " + failedTimes.get(),
107-
future.cause());
109+
future.cause());
108110
currentState.compareAndSet(SERVER_STATUS_STARTING, SERVER_STATUS_OFF);
109111
int failCount = failedTimes.incrementAndGet();
110112
if (failCount > MAX_RETRY_TIMES) {

sentinel-cluster/sentinel-cluster-server-default/src/main/java/com/alibaba/csp/sentinel/cluster/server/ServerConstants.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,5 +27,8 @@ public final class ServerConstants {
2727

2828
public static final String DEFAULT_NAMESPACE = "default";
2929

30-
private ServerConstants() {}
30+
public static final int NETTY_MAX_FRAME_LENGTH = 1024;
31+
32+
private ServerConstants() {
33+
}
3134
}

sentinel-cluster/sentinel-cluster-server-default/src/main/java/com/alibaba/csp/sentinel/cluster/server/codec/data/ParamFlowRequestDataDecoder.java

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,15 @@
1515
*/
1616
package com.alibaba.csp.sentinel.cluster.server.codec.data;
1717

18-
import java.util.ArrayList;
19-
import java.util.List;
20-
2118
import com.alibaba.csp.sentinel.cluster.ClusterConstants;
2219
import com.alibaba.csp.sentinel.cluster.codec.EntityDecoder;
2320
import com.alibaba.csp.sentinel.cluster.request.data.ParamFlowRequestData;
24-
21+
import com.alibaba.csp.sentinel.cluster.server.ServerConstants;
2522
import io.netty.buffer.ByteBuf;
2623

24+
import java.util.ArrayList;
25+
import java.util.List;
26+
2727
/**
2828
* @author jialiang.linjl
2929
* @author Eric Zhao
@@ -35,12 +35,12 @@ public class ParamFlowRequestDataDecoder implements EntityDecoder<ByteBuf, Param
3535
public ParamFlowRequestData decode(ByteBuf source) {
3636
if (source.readableBytes() >= 16) {
3737
ParamFlowRequestData requestData = new ParamFlowRequestData()
38-
.setFlowId(source.readLong())
39-
.setCount(source.readInt());
38+
.setFlowId(source.readLong())
39+
.setCount(source.readInt());
4040

4141
int amount = source.readInt();
4242
if (amount > 0) {
43-
List<Object> params = new ArrayList<>(amount);
43+
List<Object> params = new ArrayList<>(16);
4444
for (int i = 0; i < amount; i++) {
4545
decodeParam(source, params);
4646
}
@@ -61,6 +61,9 @@ private boolean decodeParam(ByteBuf source, List<Object> params) {
6161
return true;
6262
case ClusterConstants.PARAM_TYPE_STRING:
6363
int length = source.readInt();
64+
if (length > ServerConstants.NETTY_MAX_FRAME_LENGTH) {
65+
throw new IllegalStateException("[ParamFlowRequestDataDecoder] String param length (" + length + ") exceeds max frame length (" + ServerConstants.NETTY_MAX_FRAME_LENGTH + ")");
66+
}
6467
byte[] bytes = new byte[length];
6568
source.readBytes(bytes);
6669
// TODO: take care of charset?

sentinel-cluster/sentinel-cluster-server-default/src/main/java/com/alibaba/csp/sentinel/cluster/server/codec/data/PingRequestDataDecoder.java

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
package com.alibaba.csp.sentinel.cluster.server.codec.data;
1717

1818
import com.alibaba.csp.sentinel.cluster.codec.EntityDecoder;
19-
19+
import com.alibaba.csp.sentinel.log.RecordLog;
2020
import io.netty.buffer.ByteBuf;
2121

2222
/**
@@ -27,13 +27,16 @@ public class PingRequestDataDecoder implements EntityDecoder<ByteBuf, String> {
2727

2828
@Override
2929
public String decode(ByteBuf source) {
30-
if (source.readableBytes() >= 4) {
31-
int length = source.readInt();
32-
if (length > 0 && source.readableBytes() > 0) {
33-
byte[] bytes = new byte[length];
34-
source.readBytes(bytes);
35-
return new String(bytes);
30+
int readableBytes = source.readableBytes();
31+
if (readableBytes >= 4) {
32+
int packetLen = source.readInt();
33+
if (readableBytes != packetLen) { // 畸形报文,可能是端口扫描
34+
RecordLog.warn("[NettyTransportServer] Abnormal packet detected: expected length = {}, actual readableBytes = {}", packetLen, readableBytes);
35+
return null;
3636
}
37+
byte[] bytes = new byte[packetLen];
38+
source.readBytes(bytes);
39+
return new String(bytes);
3740
}
3841
return null;
3942
}

0 commit comments

Comments
 (0)