Skip to content

Commit 5b569a5

Browse files
authored
[To dev/1.3] Optimize the configuration logic of dn_thrift_max_frame_size (#17603)
* Add thrift max frame size calculate logic * Add thrift max frame size calculate logic * fix review
1 parent a550448 commit 5b569a5

6 files changed

Lines changed: 72 additions & 35 deletions

File tree

iotdb-client/service-rpc/src/main/java/org/apache/iotdb/rpc/TCompressedElasticFramedTransport.java

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -44,13 +44,7 @@ protected TCompressedElasticFramedTransport(
4444
protected void readFrame() throws TTransportException {
4545
underlying.readAll(i32buf, 0, 4);
4646
int size = TFramedTransport.decodeFrameSize(i32buf);
47-
48-
if (size < 0) {
49-
close();
50-
throw new TTransportException(
51-
TTransportException.CORRUPTED_DATA, "Read a negative frame size (" + size + ")!");
52-
}
53-
47+
checkFrameSize(size);
5448
readBuffer.fill(underlying, size);
5549
RpcStat.readCompressedBytes.addAndGet(size);
5650
try {

iotdb-client/service-rpc/src/main/java/org/apache/iotdb/rpc/TElasticFramedTransport.java

Lines changed: 61 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -174,29 +174,71 @@ public int read(byte[] buf, int off, int len) throws TTransportException {
174174
protected void readFrame() throws TTransportException {
175175
underlying.readAll(i32buf, 0, 4);
176176
int size = TFramedTransport.decodeFrameSize(i32buf);
177+
checkFrameSize(size);
178+
readBuffer.fill(underlying, size);
179+
}
177180

178-
if (size < 0) {
179-
close();
180-
throw new TTransportException(
181-
TTransportException.CORRUPTED_DATA, "Read a negative frame size (" + size + ")!");
181+
protected void checkFrameSize(int size) throws TTransportException {
182+
final int HTTP_GET_SIGNATURE = 0x47455420; // "GET "
183+
final int HTTP_POST_SIGNATURE = 0x504F5354; // "POST"
184+
final int TLS_MIN_VERSION = 0x160300;
185+
final int TLS_MAX_VERSION = 0x160303;
186+
final int TLS_LENGTH_HIGH_MAX = 0x02;
187+
188+
FrameError error = null;
189+
if (size == HTTP_GET_SIGNATURE || size == HTTP_POST_SIGNATURE) {
190+
error = FrameError.HTTP_REQUEST;
191+
} else {
192+
int high24 = size >>> 8;
193+
if (high24 >= TLS_MIN_VERSION
194+
&& high24 <= TLS_MAX_VERSION
195+
&& (i32buf[3] & 0xFF) <= TLS_LENGTH_HIGH_MAX) {
196+
error = FrameError.TLS_REQUEST;
197+
} else if (size < 0) {
198+
error = FrameError.NEGATIVE_FRAME_SIZE;
199+
} else if (size > thriftMaxFrameSize) {
200+
error = FrameError.FRAME_SIZE_EXCEEDED;
201+
}
182202
}
183203

184-
if (size > thriftMaxFrameSize) {
185-
close();
186-
if (size == 1195725856L || size == 1347375956L) {
187-
// if someone sends HTTP GET/POST to this port, the size will be read as the following
188-
throw new TTransportException(
189-
TTransportException.CORRUPTED_DATA,
190-
"Singular frame size ("
191-
+ size
192-
+ ") detected, you may be sending HTTP GET/POST requests to the Thrift-RPC port, please confirm that you are using the right port");
193-
} else {
194-
throw new TTransportException(
195-
TTransportException.CORRUPTED_DATA,
196-
"Frame size (" + size + ") larger than protect max size (" + thriftMaxFrameSize + ")!");
197-
}
204+
if (error == null) {
205+
return;
206+
}
207+
208+
SocketAddress remoteAddress = null;
209+
if (underlying instanceof TSocket) {
210+
remoteAddress = ((TSocket) underlying).getSocket().getRemoteSocketAddress();
211+
}
212+
String remoteInfo = (remoteAddress == null) ? "" : " from " + remoteAddress;
213+
close();
214+
215+
error.throwException(size, remoteInfo, thriftMaxFrameSize);
216+
}
217+
218+
private enum FrameError {
219+
HTTP_REQUEST(
220+
"Singular frame size (%d) detected, you may be sending HTTP GET/POST%s "
221+
+ "requests to the Thrift-RPC port, please confirm that you are using the right port"),
222+
TLS_REQUEST(
223+
"Singular frame size (%d) detected, you may be sending TLS ClientHello "
224+
+ "requests%s to the Non-SSL Thrift-RPC port, please confirm that you are using "
225+
+ "the right configuration"),
226+
NEGATIVE_FRAME_SIZE("Read a negative frame size (%d)%s!"),
227+
FRAME_SIZE_EXCEEDED("Frame size (%d) larger than protect max size (%d)%s!");
228+
229+
private final String messageFormat;
230+
231+
FrameError(String messageFormat) {
232+
this.messageFormat = messageFormat;
233+
}
234+
235+
void throwException(int size, String remoteInfo, int maxSize) throws TTransportException {
236+
String message =
237+
(this == FRAME_SIZE_EXCEEDED)
238+
? String.format(messageFormat, size, maxSize, remoteInfo)
239+
: String.format(messageFormat, size, remoteInfo);
240+
throw new TTransportException(TTransportException.CORRUPTED_DATA, message);
198241
}
199-
readBuffer.fill(underlying, size);
200242
}
201243

202244
protected void checkWriteFrameSize(int size) throws TTransportException {

iotdb-core/datanode/src/main/java/org/apache/iotdb/db/conf/IoTDBConfig.java

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -868,7 +868,7 @@ public class IoTDBConfig {
868868
private float udfCollectorMemoryBudgetInMB = (float) (1.0 / 3 * udfMemoryBudgetInMB);
869869

870870
/** Unit: byte */
871-
private int thriftMaxFrameSize = 536870912;
871+
private int thriftMaxFrameSize = getDefaultThriftMaxFrameSize();
872872

873873
private int thriftDefaultBufferSize = RpcUtils.THRIFT_DEFAULT_BUF_CAPACITY;
874874

@@ -2784,10 +2784,16 @@ public int getThriftMaxFrameSize() {
27842784
}
27852785

27862786
public void setThriftMaxFrameSize(int thriftMaxFrameSize) {
2787-
this.thriftMaxFrameSize = thriftMaxFrameSize;
2787+
this.thriftMaxFrameSize =
2788+
thriftMaxFrameSize <= 0 ? getDefaultThriftMaxFrameSize() : thriftMaxFrameSize;
27882789
BaseRpcTransportFactory.setThriftMaxFrameSize(this.thriftMaxFrameSize);
27892790
}
27902791

2792+
private static int getDefaultThriftMaxFrameSize() {
2793+
return Math.min(
2794+
64 * 1024 * 1024, (int) Math.min(Runtime.getRuntime().maxMemory() / 64, Integer.MAX_VALUE));
2795+
}
2796+
27912797
public int getThriftDefaultBufferSize() {
27922798
return thriftDefaultBufferSize;
27932799
}

iotdb-core/datanode/src/main/java/org/apache/iotdb/db/conf/IoTDBDescriptor.java

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -861,10 +861,6 @@ public void loadProperties(TrimProperties properties) throws BadNodeUrlException
861861
properties.getProperty(
862862
"dn_thrift_max_frame_size", String.valueOf(conf.getThriftMaxFrameSize()))));
863863

864-
if (conf.getThriftMaxFrameSize() < IoTDBConstant.LEFT_SIZE_IN_REQUEST * 2) {
865-
conf.setThriftMaxFrameSize(IoTDBConstant.LEFT_SIZE_IN_REQUEST * 2);
866-
}
867-
868864
conf.setThriftDefaultBufferSize(
869865
Integer.parseInt(
870866
properties.getProperty(

iotdb-core/node-commons/src/assembly/resources/conf/iotdb-system.properties.template

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -509,10 +509,10 @@ dn_rpc_min_concurrent_client_num=1
509509
# Datatype: int
510510
dn_rpc_max_concurrent_client_num=1000
511511

512-
# thrift max frame size, 512MB by default
512+
# thrift max frame size in bytes. When set to 0, use min(64MB, datanode heap memory / 64)
513513
# effectiveMode: restart
514514
# Datatype: int
515-
dn_thrift_max_frame_size=536870912
515+
dn_thrift_max_frame_size=0
516516

517517
# thrift init buffer size
518518
# effectiveMode: restart

iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/conf/IoTDBConstant.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -268,7 +268,6 @@ private IoTDBConstant() {}
268268
public static final String MQTT_MAX_MESSAGE_SIZE = "mqtt_max_message_size";
269269

270270
// thrift
271-
public static final int LEFT_SIZE_IN_REQUEST = 4 * 1024 * 1024;
272271
public static final int DEFAULT_FETCH_SIZE = 5000;
273272
public static final int DEFAULT_CONNECTION_TIMEOUT_MS = 0;
274273

0 commit comments

Comments
 (0)