From 2de2bd43b1e4723ce91724a428eb591af22dfccf Mon Sep 17 00:00:00 2001 From: Demetrius Kanios Date: Sat, 6 Jun 2026 00:15:42 -0700 Subject: [PATCH] fix: RakNet frame split threshold (#2198) Signed-off-by: Demetrius Kanios --- pumpkin-protocol/src/bedrock/mod.rs | 5 ++++- pumpkin/src/net/bedrock/mod.rs | 19 ++++++++++++------- pumpkin/src/net/bedrock/open_connection.rs | 4 ++-- 3 files changed, 18 insertions(+), 10 deletions(-) diff --git a/pumpkin-protocol/src/bedrock/mod.rs b/pumpkin-protocol/src/bedrock/mod.rs index 7bb7b0724..b68cd6cb5 100644 --- a/pumpkin-protocol/src/bedrock/mod.rs +++ b/pumpkin-protocol/src/bedrock/mod.rs @@ -7,9 +7,12 @@ pub mod packet_encoder; pub mod server; pub const RAKNET_PROTOCOL_VERSION: u8 = 11; -pub const UDP_HEADER_SIZE: u16 = 28; +pub const UDP_HEADER_SIZE: usize = 28; pub const MTU: usize = 1400; +// 26 bytes is RakNet header for FrameSet containing a single, ReliableOrdered, split/fragmented frame +pub const SPLIT_FRAME_MAX_CONTENT: usize = MTU - UDP_HEADER_SIZE - 26; + pub const RAKNET_MAGIC: [u8; 16] = [ 0x00, 0xff, 0xff, 0x0, 0xfe, 0xfe, 0xfe, 0xfe, 0xfd, 0xfd, 0xfd, 0xfd, 0x12, 0x34, 0x56, 0x78, ]; diff --git a/pumpkin/src/net/bedrock/mod.rs b/pumpkin/src/net/bedrock/mod.rs index f0306e6d8..8c7c47fc1 100644 --- a/pumpkin/src/net/bedrock/mod.rs +++ b/pumpkin/src/net/bedrock/mod.rs @@ -18,7 +18,8 @@ use pumpkin_config::networking::compression::CompressionInfo; use pumpkin_protocol::{ BClientPacket, PacketDecodeError, RawPacket, bedrock::{ - MTU, RAKNET_ACK, RAKNET_GAME_PACKET, RAKNET_NACK, RakReliability, SubClient, + MTU, RAKNET_ACK, RAKNET_GAME_PACKET, RAKNET_NACK, RakReliability, SPLIT_FRAME_MAX_CONTENT, + SubClient, UDP_HEADER_SIZE, ack::Acknowledge, client::{ disconnect_player::CDisconnectPlayer, level_chunk::CLevelChunk, @@ -556,10 +557,14 @@ impl BedrockClient { let mut split_id = 0; let mut order_index = 0; - let count = if packet_buf.len() > MTU { + let mut max_content_len = + MTU - UDP_HEADER_SIZE - 12 - if reliability.is_ordered() { 4 } else { 0 }; + + let count = if packet_buf.len() > max_content_len { reliability = RakReliability::ReliableOrdered; split_id = self.output_split_number.fetch_add(1, Ordering::Relaxed); - split_size = packet_buf.len().div_ceil(MTU) as u32; + max_content_len = SPLIT_FRAME_MAX_CONTENT; + split_size = packet_buf.len().div_ceil(max_content_len) as u32; split_size as usize } else { 1 @@ -570,12 +575,12 @@ impl BedrockClient { } for i in 0..count { - let end = if i + 1 == count && !packet_buf.len().is_multiple_of(MTU) { - packet_buf.len() % MTU + let end = if i + 1 == count && !packet_buf.len().is_multiple_of(max_content_len) { + packet_buf.len() % max_content_len } else { - MTU + max_content_len }; - let chunk = &packet_buf[i * MTU..i * MTU + end]; + let chunk = &packet_buf[i * max_content_len..i * max_content_len + end]; let mut frame_set = FrameSet { sequence: u24(0), diff --git a/pumpkin/src/net/bedrock/open_connection.rs b/pumpkin/src/net/bedrock/open_connection.rs index e7b815c78..c14084206 100644 --- a/pumpkin/src/net/bedrock/open_connection.rs +++ b/pumpkin/src/net/bedrock/open_connection.rs @@ -1,7 +1,7 @@ use std::net::SocketAddr; use pumpkin_protocol::bedrock::{ - RAKNET_PROTOCOL_VERSION, + MTU, RAKNET_PROTOCOL_VERSION, client::raknet::{ incompatible_protocol::CIncompatibleProtocolVersion, open_connection::{COpenConnectionReply1, COpenConnectionReply2}, @@ -30,7 +30,7 @@ impl BedrockClient { } Self::send_offline_packet( - &COpenConnectionReply1::new(server.server_guid, false, 1400), + &COpenConnectionReply1::new(server.server_guid, false, MTU as u16), addr, socket, )