mirror of
https://github.com/GeyserMC/Geyser.git
synced 2024-08-14 23:57:35 +00:00
Fix connection request handler
This commit is contained in:
parent
05a88f7693
commit
be48b83c28
3 changed files with 126 additions and 27 deletions
|
@ -43,32 +43,6 @@ public class GeyserServerInitializer extends BedrockServerInitializer {
|
||||||
this.geyser = geyser;
|
this.geyser = geyser;
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO
|
|
||||||
/*
|
|
||||||
@Override
|
|
||||||
public boolean onConnectionRequest(InetSocketAddress inetSocketAddress) {
|
|
||||||
List<String> allowedProxyIPs = geyser.getConfig().getBedrock().getProxyProtocolWhitelistedIPs();
|
|
||||||
if (geyser.getConfig().getBedrock().isEnableProxyProtocol() && !allowedProxyIPs.isEmpty()) {
|
|
||||||
boolean isWhitelistedIP = false;
|
|
||||||
for (CIDRMatcher matcher : geyser.getConfig().getBedrock().getWhitelistedIPsMatchers()) {
|
|
||||||
if (matcher.matches(inetSocketAddress.getAddress())) {
|
|
||||||
isWhitelistedIP = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!isWhitelistedIP) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
String ip = geyser.getConfig().isLogPlayerIpAddresses() ? inetSocketAddress.toString() : "<IP address withheld>";
|
|
||||||
geyser.getLogger().info(GeyserLocale.getLocaleStringLog("geyser.network.attempt_connect", ip));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void initSession(@Nonnull BedrockServerSession bedrockServerSession) {
|
public void initSession(@Nonnull BedrockServerSession bedrockServerSession) {
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -44,6 +44,7 @@ import org.cloudburstmc.netty.handler.codec.raknet.server.RakServerOfflineHandle
|
||||||
import org.cloudburstmc.protocol.bedrock.BedrockPong;
|
import org.cloudburstmc.protocol.bedrock.BedrockPong;
|
||||||
import org.geysermc.geyser.GeyserImpl;
|
import org.geysermc.geyser.GeyserImpl;
|
||||||
import org.geysermc.geyser.configuration.GeyserConfiguration;
|
import org.geysermc.geyser.configuration.GeyserConfiguration;
|
||||||
|
import org.geysermc.geyser.network.CIDRMatcher;
|
||||||
import org.geysermc.geyser.network.GameProtocol;
|
import org.geysermc.geyser.network.GameProtocol;
|
||||||
import org.geysermc.geyser.network.GeyserServerInitializer;
|
import org.geysermc.geyser.network.GeyserServerInitializer;
|
||||||
import org.geysermc.geyser.ping.GeyserPingInfo;
|
import org.geysermc.geyser.ping.GeyserPingInfo;
|
||||||
|
@ -53,6 +54,7 @@ import org.geysermc.geyser.translator.text.MessageTranslator;
|
||||||
|
|
||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.util.List;
|
||||||
import java.util.concurrent.CompletableFuture;
|
import java.util.concurrent.CompletableFuture;
|
||||||
import java.util.function.IntFunction;
|
import java.util.function.IntFunction;
|
||||||
|
|
||||||
|
@ -95,7 +97,9 @@ public final class GeyserServer {
|
||||||
});
|
});
|
||||||
|
|
||||||
// Add our ping handler
|
// Add our ping handler
|
||||||
this.future.channel().pipeline().addAfter(RakServerOfflineHandler.NAME, RakPingHandler.NAME, new RakPingHandler(this));
|
this.future.channel().pipeline()
|
||||||
|
.addFirst(RakConnectionRequestHandler.NAME, new RakConnectionRequestHandler(this))
|
||||||
|
.addAfter(RakServerOfflineHandler.NAME, RakPingHandler.NAME, new RakPingHandler(this));
|
||||||
return future;
|
return future;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -126,6 +130,27 @@ public final class GeyserServer {
|
||||||
.childHandler(new GeyserServerInitializer(this.geyser));
|
.childHandler(new GeyserServerInitializer(this.geyser));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean onConnectionRequest(InetSocketAddress inetSocketAddress) {
|
||||||
|
List<String> allowedProxyIPs = geyser.getConfig().getBedrock().getProxyProtocolWhitelistedIPs();
|
||||||
|
if (geyser.getConfig().getBedrock().isEnableProxyProtocol() && !allowedProxyIPs.isEmpty()) {
|
||||||
|
boolean isWhitelistedIP = false;
|
||||||
|
for (CIDRMatcher matcher : geyser.getConfig().getBedrock().getWhitelistedIPsMatchers()) {
|
||||||
|
if (matcher.matches(inetSocketAddress.getAddress())) {
|
||||||
|
isWhitelistedIP = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isWhitelistedIP) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
String ip = geyser.getConfig().isLogPlayerIpAddresses() ? inetSocketAddress.toString() : "<IP address withheld>";
|
||||||
|
geyser.getLogger().info(GeyserLocale.getLocaleStringLog("geyser.network.attempt_connect", ip));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
public BedrockPong onQuery(InetSocketAddress inetSocketAddress) {
|
public BedrockPong onQuery(InetSocketAddress inetSocketAddress) {
|
||||||
if (geyser.getConfig().isDebugMode() && PRINT_DEBUG_PINGS) {
|
if (geyser.getConfig().isDebugMode() && PRINT_DEBUG_PINGS) {
|
||||||
String ip = geyser.getConfig().isLogPlayerIpAddresses() ? inetSocketAddress.toString() : "<IP address withheld>";
|
String ip = geyser.getConfig().isLogPlayerIpAddresses() ? inetSocketAddress.toString() : "<IP address withheld>";
|
||||||
|
|
|
@ -0,0 +1,100 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2019-2023 GeyserMC. http://geysermc.org
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*
|
||||||
|
* @author GeyserMC
|
||||||
|
* @link https://github.com/GeyserMC/Geyser
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.geysermc.geyser.network.netty;
|
||||||
|
|
||||||
|
import io.netty.buffer.ByteBuf;
|
||||||
|
import io.netty.buffer.ByteBufUtil;
|
||||||
|
import io.netty.channel.ChannelHandler;
|
||||||
|
import io.netty.channel.ChannelHandlerContext;
|
||||||
|
import io.netty.channel.ChannelInboundHandlerAdapter;
|
||||||
|
import io.netty.channel.socket.DatagramPacket;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||||
|
import org.cloudburstmc.netty.channel.raknet.config.RakChannelOption;
|
||||||
|
|
||||||
|
import java.net.InetSocketAddress;
|
||||||
|
|
||||||
|
import static org.cloudburstmc.netty.channel.raknet.RakConstants.ID_CONNECTION_BANNED;
|
||||||
|
import static org.cloudburstmc.netty.channel.raknet.RakConstants.ID_OPEN_CONNECTION_REQUEST_1;
|
||||||
|
|
||||||
|
@ChannelHandler.Sharable
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class RakConnectionRequestHandler extends ChannelInboundHandlerAdapter {
|
||||||
|
public static final String NAME = "rak-connection-request-handler";
|
||||||
|
|
||||||
|
private final GeyserServer server;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void channelRead(@NonNull ChannelHandlerContext ctx, @NonNull Object msg) throws Exception {
|
||||||
|
if (!(msg instanceof DatagramPacket packet)) {
|
||||||
|
ctx.fireChannelRead(msg);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ByteBuf buf = packet.content();
|
||||||
|
if (!buf.isReadable()) {
|
||||||
|
return; // No packet ID
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean readableMagic = true;
|
||||||
|
int startIndex = buf.readerIndex();
|
||||||
|
try {
|
||||||
|
int packetId = buf.readUnsignedByte();
|
||||||
|
if (packetId == ID_OPEN_CONNECTION_REQUEST_1) {
|
||||||
|
ByteBuf magicBuf = ctx.channel().config().getOption(RakChannelOption.RAK_UNCONNECTED_MAGIC);
|
||||||
|
if (!buf.isReadable(magicBuf.readableBytes()) || !ByteBufUtil.equals(buf.readSlice(magicBuf.readableBytes()), magicBuf)) {
|
||||||
|
readableMagic = false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
readableMagic = false;
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
buf.readerIndex(startIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!readableMagic) {
|
||||||
|
ctx.fireChannelRead(msg);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ByteBuf magicBuf = ctx.channel().config().getOption(RakChannelOption.RAK_UNCONNECTED_MAGIC);
|
||||||
|
long guid = ctx.channel().config().getOption(RakChannelOption.RAK_GUID);
|
||||||
|
|
||||||
|
if (!this.server.onConnectionRequest(packet.sender())) {
|
||||||
|
this.sendConnectionBanned(ctx, packet.sender(), magicBuf, guid);
|
||||||
|
} else {
|
||||||
|
ctx.fireChannelRead(msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void sendConnectionBanned(ChannelHandlerContext ctx, InetSocketAddress recipient, ByteBuf magicBuf, long guid) {
|
||||||
|
ByteBuf buffer = ctx.alloc().ioBuffer(25, 25);
|
||||||
|
buffer.writeByte(ID_CONNECTION_BANNED);
|
||||||
|
buffer.writeBytes(magicBuf, magicBuf.readerIndex(), magicBuf.readableBytes());
|
||||||
|
buffer.writeLong(guid);
|
||||||
|
ctx.writeAndFlush(new DatagramPacket(buffer, recipient));
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue