Skip to content

Commit

Permalink
Allow configuration of RakNet limits
Browse files Browse the repository at this point in the history
Signed-off-by: Joshua Castle <[email protected]>
  • Loading branch information
Kas-tle committed Mar 31, 2024
1 parent b469904 commit 307acc3
Show file tree
Hide file tree
Showing 6 changed files with 85 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,11 @@
import org.geysermc.geyser.network.CIDRMatcher;
import org.geysermc.geyser.text.AsteriskSerializer;
import org.geysermc.geyser.text.GeyserLocale;
import org.geysermc.geyser.util.WebUtils;

import java.io.IOException;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.UUID;
Expand Down Expand Up @@ -233,7 +235,18 @@ public List<CIDRMatcher> getWhitelistedIPsMatchers() {
List<CIDRMatcher> matchers = this.whitelistedIPsMatchers;
if (matchers == null) {
synchronized (this) {
this.whitelistedIPsMatchers = matchers = proxyProtocolWhitelistedIPs.stream()
// Check if proxyProtocolWhitelistedIPs contains URLs we need to fetch and parse by line
List<String> whitelistedCIDRs = new ArrayList<>();
for (String ip: proxyProtocolWhitelistedIPs) {
if (!ip.startsWith("http")) {
whitelistedCIDRs.add(ip);
continue;
}

WebUtils.getLineStream(ip).forEach(whitelistedCIDRs::add);
}

this.whitelistedIPsMatchers = matchers = whitelistedCIDRs.stream()
.map(CIDRMatcher::new)
.collect(Collectors.toList());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
import org.cloudburstmc.netty.channel.raknet.RakChannelFactory;
import org.cloudburstmc.netty.channel.raknet.config.RakChannelOption;
import org.cloudburstmc.netty.handler.codec.raknet.server.RakServerOfflineHandler;
import org.cloudburstmc.netty.handler.codec.raknet.server.RakServerRateLimiter;
import org.cloudburstmc.protocol.bedrock.BedrockPong;
import org.geysermc.geyser.GeyserImpl;
import org.geysermc.geyser.command.defaults.ConnectionTestCommand;
Expand All @@ -71,6 +72,10 @@
import java.util.function.IntFunction;
import java.util.function.Supplier;

import static org.cloudburstmc.netty.channel.raknet.RakConstants.DEFAULT_GLOBAL_PACKET_LIMIT;
import static org.cloudburstmc.netty.channel.raknet.RakConstants.DEFAULT_OFFLINE_PACKET_LIMIT;
import static org.cloudburstmc.netty.channel.raknet.RakConstants.DEFAULT_PACKET_LIMIT;

public final class GeyserServer {
private static final boolean PRINT_DEBUG_PINGS = Boolean.parseBoolean(System.getProperty("Geyser.PrintPingsInDebugMode", "true"));

Expand Down Expand Up @@ -141,23 +146,31 @@ public CompletableFuture<Void> bind(InetSocketAddress address) {
bootstrapFutures = new ChannelFuture[listenCount];
for (int i = 0; i < listenCount; i++) {
ChannelFuture future = bootstrap.bind(address);
addHandlers(future);
modifyHandlers(future);
bootstrapFutures[i] = future;
}

return Bootstraps.allOf(bootstrapFutures);
}

private void addHandlers(ChannelFuture future) {
private void modifyHandlers(ChannelFuture future) {
Channel channel = future.channel();
// Add our ping handler
channel.pipeline()
.addFirst(RakConnectionRequestHandler.NAME, new RakConnectionRequestHandler(this))
.addAfter(RakServerOfflineHandler.NAME, RakPingHandler.NAME, new RakPingHandler(this));

// Add proxy handler
if (this.geyser.getConfig().getBedrock().isEnableProxyProtocol()) {
boolean isProxyProtocol = this.geyser.getConfig().getBedrock().isEnableProxyProtocol();
if (isProxyProtocol) {
channel.pipeline().addFirst("proxy-protocol-decoder", new ProxyServerHandler());
}

boolean isWhitelistedProxyProtocol = isProxyProtocol && !this.geyser.getConfig().getBedrock().getProxyProtocolWhitelistedIPs().isEmpty();
if (Boolean.parseBoolean(System.getProperty("Geyser.RakRateLimitingDisabled", "false")) || isWhitelistedProxyProtocol) {
// We would already block any non-whitelisted IP addresses in onConnectionRequest so we can remove the rate limiter
channel.pipeline().remove(RakServerRateLimiter.NAME);
}
}

public void shutdown() {
Expand Down Expand Up @@ -199,11 +212,30 @@ private ServerBootstrap createBootstrap() {
GeyserServerInitializer serverInitializer = new GeyserServerInitializer(this.geyser);
playerGroup = serverInitializer.getEventLoopGroup();
this.geyser.getLogger().debug("Setting MTU to " + this.geyser.getConfig().getMtu());

String geyserRakPacketLimit = System.getProperty("Geyser.RakPacketLimit");
int rakPacketLimit = geyserRakPacketLimit != null ? Integer.parseInt(geyserRakPacketLimit) : DEFAULT_PACKET_LIMIT;
this.geyser.getLogger().debug("Setting RakNet packet limit to " + rakPacketLimit);

String geyserRakOfflinePacketLimit = System.getProperty("Geyser.RakOfflinePacketLimit");
boolean isWhitelistedProxyProtocol = this.geyser.getConfig().getBedrock().isEnableProxyProtocol()
&& !this.geyser.getConfig().getBedrock().getProxyProtocolWhitelistedIPs().isEmpty();
int rakOfflinePacketLimit = geyserRakOfflinePacketLimit != null ? Integer.parseInt(geyserRakOfflinePacketLimit)
: isWhitelistedProxyProtocol ? Integer.MAX_VALUE : DEFAULT_OFFLINE_PACKET_LIMIT;
this.geyser.getLogger().debug("Setting RakNet offline packet limit to " + rakOfflinePacketLimit);

String geyserRakGlobalPacketLimit = System.getProperty("Geyser.RakGlobalPacketLimit");
int rakGlobalPacketLimit = geyserRakGlobalPacketLimit != null ? Integer.parseInt(geyserRakGlobalPacketLimit) : DEFAULT_GLOBAL_PACKET_LIMIT;
this.geyser.getLogger().debug("Setting RakNet global packet limit to " + rakGlobalPacketLimit);

return new ServerBootstrap()
.channelFactory(RakChannelFactory.server(TRANSPORT.datagramChannel()))
.group(group, childGroup)
.option(RakChannelOption.RAK_HANDLE_PING, true)
.option(RakChannelOption.RAK_MAX_MTU, this.geyser.getConfig().getMtu())
.option(RakChannelOption.RAK_PACKET_LIMIT, rakPacketLimit)
.option(RakChannelOption.RAK_OFFLINE_PACKET_LIMIT, rakOfflinePacketLimit)
.option(RakChannelOption.RAK_GLOBAL_PACKET_LIMIT, rakGlobalPacketLimit)
.childHandler(serverInitializer);
}

Expand Down
3 changes: 3 additions & 0 deletions core/src/main/java/org/geysermc/geyser/util/FileUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@

import com.fasterxml.jackson.annotation.JsonSetter;
import com.fasterxml.jackson.annotation.Nulls;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
import org.geysermc.geyser.GeyserBootstrap;
Expand Down Expand Up @@ -56,6 +57,8 @@ public class FileUtils {
*/
public static <T> T loadConfig(File src, Class<T> valueType) throws IOException {
ObjectMapper objectMapper = new ObjectMapper(new YAMLFactory())
// Allow inference of single values as arrays
.enable(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY)
.setDefaultSetterInfo(JsonSetter.Value.forValueNulls(Nulls.AS_EMPTY));
return objectMapper.readValue(src, valueType);
}
Expand Down
30 changes: 30 additions & 0 deletions core/src/main/java/org/geysermc/geyser/util/WebUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.util.Map;
import java.util.stream.Stream;

public class WebUtils {

Expand Down Expand Up @@ -176,6 +177,13 @@ public static String postForm(String reqURL, Map<String, String> fields) throws
return connectionToString(con);
}

/**
* Find a SRV record for the given address
*
* @param geyser Geyser instance
* @param remoteAddress Address to find the SRV record for
* @return The SRV record or null if not found
*/
public static String @Nullable [] findSrvRecord(GeyserImpl geyser, String remoteAddress) {
try {
// Searches for a server address and a port from a SRV record of the specified host name
Expand All @@ -193,4 +201,26 @@ public static String postForm(String reqURL, Map<String, String> fields) throws
}
return null;
}

/**
* Get a stream of lines from the given URL
*
* @param reqURL URL to fetch
* @return Stream of lines from the URL or an empty stream if the request fails
*/
public static Stream<String> getLineStream(String reqURL) {
try {
URL url = new URL(reqURL);
HttpURLConnection con = (HttpURLConnection) url.openConnection();
con.setRequestMethod("GET");
con.setRequestProperty("User-Agent", "Geyser-" + GeyserImpl.getInstance().getPlatformType().toString() + "/" + GeyserImpl.VERSION); // Otherwise Java 8 fails on checking updates
con.setConnectTimeout(10000);
con.setReadTimeout(10000);

return connectionToString(con).lines();
} catch (Exception e) {
GeyserImpl.getInstance().getLogger().error("Error while trying to get a stream from " + reqURL, e);
return Stream.empty();
}
}
}
4 changes: 2 additions & 2 deletions core/src/main/resources/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@ bedrock:
# A list of allowed PROXY protocol speaking proxy IP addresses/subnets. Only effective when "enable-proxy-protocol" is enabled, and
# should really only be used when you are not able to use a proper firewall (usually true with shared hosting providers etc.).
# Keeping this list empty means there is no IP address whitelist.
# Both IP addresses and subnets are supported.
#proxy-protocol-whitelisted-ips: [ "127.0.0.1", "172.18.0.0/16" ]
# IP addresses, subnets, and links to plain text files are supported.
#proxy-protocol-whitelisted-ips: [ "127.0.0.1", "172.18.0.0/16", "https://example.com/whitelist.txt" ]
remote:
# The IP address of the remote (Java Edition) server
# If it is "auto", for standalone version the remote address will be set to 127.0.0.1,
Expand Down
2 changes: 1 addition & 1 deletion gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ gson = "2.3.1" # Provided by Spigot 1.8.8
websocket = "1.5.1"
protocol = "3.0.0.Beta1-20240313.120922-126"
protocol-connection = "3.0.0.Beta1-20240313.120922-125"
raknet = "1.0.0.CR1-20240330.101522-15"
raknet = "1.0.0.CR1-20240330.103819-16"
blockstateupdater="1.20.70-20240303.125052-2"
mcauthlib = "d9d773e"
mcprotocollib = "1.20.4-2-20240116.220521-7"
Expand Down

0 comments on commit 307acc3

Please sign in to comment.