mojira.dev

The UDP query protocol includes a list of all players on the server. For even moderately sized servers it is very easy for this list to exceed the MTU of the network (1500 bytes on the internet). This causes the packet to be dropped and the server to appear offline.

Comments 4

Is this still an issue in the most recent versions (currently that is 1.12.2, or the latest 1.13 development snapshot 18w20c) of Minecraft? If so, please update the affected versions and help us keeping this ticket updated from time to time. If you are the owner/reporter of this ticket, you can modify the affected version(s) yourself.

Is this still a issue in the latest version of the game(currently 1.13.1)?

If so, please add it to the affected versions, thanks!

Are you able to confirm this report in the latest version/snapshot, 1.20.6, or 24w18a?

I was able to confirm this as of 26.1.2, the easiest approach to confirming this is by either using a bot framework or having a populated server.


Steps to Reproduce (bash commands):

1 - Set up a Minecraft vanilla server and edit server.properties:

enable-query=true
query.port=25565
online-mode=false
max-players=200
view-distance=2
simulation-distance=2
enable-rcon=false
motd=test

2 - Install the Rust bot framework (azalea) inside the server

curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain nightly
source ~/.cargo/env

3 - Create the bot project:

mkdir ~/mcbots && cd ~/mcbots && cargo init


4 - Write the Cargo.toml file:

[package]
name = "mcbots"
version = "0.1.0"
edition = "2021"

[dependencies]
azalea = { git = "https://github.com/azalea-rs/azalea" }
tokio = { version = "1", features = ["full"] }
anyhow = "1"


5 - Write the bot:

use azalea::prelude::*;
use azalea::swarm::prelude::*;

#[derive(Default, Clone, Component)]
struct State;

#[derive(Default, Clone, Resource)]
struct SwarmState;

#[tokio::main]
async fn main() {
    let accounts: Vec<Account> = (0..150u32)
        .map(|i| Account::offline(&format!("BotFace{:04}", i)))
        .collect();

    SwarmBuilder::new()
        .set_handler(handle)
        .set_swarm_handler(swarm_handler)
        .add_accounts(accounts)
        .start("127.0.0.1")
        .await;
}

async fn handle(_bot: Client, _event: Event, _state: State) -> anyhow::Result<()> {
    Ok(())
}

async fn swarm_handler(_swarm: Swarm, _event: SwarmEvent, _state: SwarmState) -> anyhow::Result<()> {
    Ok(())
}


6 - Start the server

7 - Build the bots:

cargo build --release 2>&1 | tail -5

8 - Run the bots:

~/mcbots/target/release/mcbots &
sleep 20 && grep -c "logged in" ~/mcserver/server.log

9 - Create the query script:

import socket, struct

def query(host, port):
    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    s.settimeout(5)
    s.sendto(b'\xFE\xFD\x09\x00\x00\x00\x01', (host, port))
    challenge_data, _ = s.recvfrom(1024)
    challenge = struct.pack('>i', int(challenge_data[5:-1]))
    payload = b'\xFE\xFD\x00\x00\x00\x00\x01' + challenge + b'\x00\x00\x00\x00'
    s.sendto(payload, (host, port))
    response = b''
    while True:
        try:
            chunk, _ = s.recvfrom(4096)
            response += chunk
        except socket.timeout:
            break
    s.close()
    print(f"Total response size: {len(response)} bytes")
    print(f"Exceeds MTU (1500): {len(response) > 1500}")
    return response

query('127.0.0.1', 25565)


10 - Run the query script:

python3 ~/query.py

Output:

Total response size: 1969 bytes
Exceeds MTU (1500): True

md_5

(Unassigned)

Community Consensus

Networking

Minecraft 1.10.2, Minecraft 1.11, Minecraft 16w50a, Minecraft 1.13.1, 1.14.4, 26.1.2

Retrieved