diff --git a/src/kube_cache.rs b/src/kube_cache.rs index 7a6b6ae..d7e56b0 100644 --- a/src/kube_cache.rs +++ b/src/kube_cache.rs @@ -83,7 +83,7 @@ pub struct McApi { } impl MinecraftAPI for McApi { - #[tracing::instrument(name = "MinecraftAPI::query_server", level = "info", skip(self))] + #[tracing::instrument(name = "MinecraftAPI::query_server", level = "info", skip(self, addr))] async fn query_server(&self, addr: &str) -> Result { let dep_name = match self.cache.query_dep_addr(&addr).await { Some(x) => x, diff --git a/src/main.rs b/src/main.rs index a1f4522..07c02e4 100644 --- a/src/main.rs +++ b/src/main.rs @@ -124,12 +124,13 @@ async fn handle_status( }; let server_addr = handshake.get_server_address(); + let server_addr = sanitize_addr(&server_addr); let commit_hash: &'static str = env!("COMMIT_HASH"); let mut status_struct = StatusStructNew::create(); status_struct.version.protocol = handshake.protocol_version.get_int(); let bye_message = format!(" - §dTami§r with §d<3§r §8(rev: {commit_hash})§r"); - let server = match api.query_server(&handshake.get_server_address()).await { + let server = match api.query_server(server_addr).await { Ok(x) => x, Err(e) => { tracing::warn!(err = e.context); @@ -186,22 +187,9 @@ async fn handle_login( handshake: &Handshake, api: impl MinecraftAPI, ) -> Result<(), OpaqueError> { - let addr = handshake.get_server_address(); - // Thanks to a buggy minecraft, when the client sends a join - // from a SRV DNS record, it will not use the address typed - // in the game, but use the address redicted *to* by the - // DNS record as the address for joining, plus a trailing "." - // - // For example: - // server.example.com (_minecraft._tcp.server.example.com) - // (the typed address) I (the DNS SRV record which gets read) - // V - // 5 25565 server.example.com - // I (the response for the DNS SRV query) - // V - // server.example.com. - // (the address used in the protocol) - let server = api.query_server(addr.trim_end_matches(".")).await?; + let server = api + .query_server(sanitize_addr(&handshake.get_server_address())) + .await?; let status = server.query_status().await?; tracing::debug!(msg = "server status", status = ?status); @@ -247,3 +235,34 @@ async fn handle_login( } Ok(()) } + +fn terminate_at_null(str: &str) -> &str { + match str.split('\0').next() { + Some(x) => x, + None => str, + } +} + +fn sanitize_addr(addr: &str) -> &str { + // Thanks to a buggy minecraft, when the client sends a join + // from a SRV DNS record, it will not use the address typed + // in the game, but use the address redicted *to* by the + // DNS record as the address for joining, plus a trailing "." + // + // For example: + // server.example.com (_minecraft._tcp.server.example.com) + // (the typed address) I (the DNS SRV record which gets read) + // V + // 5 25565 server.example.com + // I (the response for the DNS SRV query) + // V + // server.example.com. + // (the address used in the protocol) + let addr = addr.trim_end_matches("."); + + // Modded minecraft clients send null terminated strings, + // after which they have extra data. This just removes them + // from the addr lookup + let addr = terminate_at_null(addr); + addr +}