Paper/patches/server/0626-Add-Unix-domain-socket-support.patch
Jake Potrebic 9147456fc9
Updated Upstream (CraftBukkit/Spigot) (#8815)
Upstream has released updates that appear to apply and compile correctly.
This update has not been tested by PaperMC and as with ANY update, please do your own testing

CraftBukkit Changes:
ab8ace685 SPIGOT-7236: Bone meal doesn't increase use statistic
7dcb59b8e Avoid switch on material in previous commit

Spigot Changes:
19641c75 SPIGOT-7235: World.Spigot#strikeLightningEffect doesn't do anything
2023-01-27 12:52:04 -08:00

142 lines
9.0 KiB
Diff

From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Andrew Steinborn <git@steinborn.me>
Date: Tue, 11 May 2021 17:39:22 -0400
Subject: [PATCH] Add Unix domain socket support
For Windows and ARM support, JEP-380 is required:
https://inside.java/2021/02/03/jep380-unix-domain-sockets-channels/
This will be possible as of the Minecraft 1.17 Java version bump.
Tested-by: Mariell Hoversholm <proximyst@proximyst.com>
Reviewed-by: Mariell Hoversholm <proximyst@proximyst.com>
diff --git a/src/main/java/net/minecraft/network/Connection.java b/src/main/java/net/minecraft/network/Connection.java
index 779a3639d3caafd49d87b99449add5b46897a8ba..9042f2953b1cf21969faf33883d3c845553e937e 100644
--- a/src/main/java/net/minecraft/network/Connection.java
+++ b/src/main/java/net/minecraft/network/Connection.java
@@ -690,6 +690,11 @@ public class Connection extends SimpleChannelInboundHandler<Packet<?>> {
// Spigot Start
public SocketAddress getRawAddress()
{
+ // Paper start - this can be nullable in the case of a Unix domain socket, so if it is, fake something
+ if (this.channel.remoteAddress() == null) {
+ return new java.net.InetSocketAddress(java.net.InetAddress.getLoopbackAddress(), 0);
+ }
+ // Paper end
return this.channel.remoteAddress();
}
// Spigot End
diff --git a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
index 8eb18e794845a2e7df5e7e6bc11134e4d132e06e..7dcffb49a982a8db00d66441a03e2951b1d29ff9 100644
--- a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
+++ b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
@@ -219,6 +219,20 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface
this.setEnforceWhitelist(dedicatedserverproperties.enforceWhitelist);
// this.worldData.setGameType(dedicatedserverproperties.gamemode); // CraftBukkit - moved to world loading
DedicatedServer.LOGGER.info("Default game type: {}", dedicatedserverproperties.gamemode);
+ // Paper start - Unix domain socket support
+ java.net.SocketAddress bindAddress;
+ if (this.getLocalIp().startsWith("unix:")) {
+ if (!io.netty.channel.epoll.Epoll.isAvailable()) {
+ DedicatedServer.LOGGER.error("**** INVALID CONFIGURATION!");
+ DedicatedServer.LOGGER.error("You are trying to use a Unix domain socket but you're not on a supported OS.");
+ return false;
+ } else if (!io.papermc.paper.configuration.GlobalConfiguration.get().proxies.velocity.enabled && !org.spigotmc.SpigotConfig.bungee) {
+ DedicatedServer.LOGGER.error("**** INVALID CONFIGURATION!");
+ DedicatedServer.LOGGER.error("Unix domain sockets require IPs to be forwarded from a proxy.");
+ return false;
+ }
+ bindAddress = new io.netty.channel.unix.DomainSocketAddress(this.getLocalIp().substring("unix:".length()));
+ } else {
InetAddress inetaddress = null;
if (!this.getLocalIp().isEmpty()) {
@@ -228,12 +242,15 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface
if (this.getPort() < 0) {
this.setPort(dedicatedserverproperties.serverPort);
}
+ bindAddress = new java.net.InetSocketAddress(inetaddress, this.getPort());
+ }
+ // Paper end
this.initializeKeyPair();
DedicatedServer.LOGGER.info("Starting Minecraft server on {}:{}", this.getLocalIp().isEmpty() ? "*" : this.getLocalIp(), this.getPort());
try {
- this.getConnection().startTcpServerListener(inetaddress, this.getPort());
+ this.getConnection().bind(bindAddress); // Paper - Unix domain socket support
} catch (IOException ioexception) {
DedicatedServer.LOGGER.warn("**** FAILED TO BIND TO PORT!");
DedicatedServer.LOGGER.warn("The exception was: {}", ioexception.toString());
diff --git a/src/main/java/net/minecraft/server/network/ServerConnectionListener.java b/src/main/java/net/minecraft/server/network/ServerConnectionListener.java
index 83af90fb0dcb4b1a5a68f655cf66d101b472e8e7..b80aedd2002959b4026c27ce76b3ed17f0acfb5b 100644
--- a/src/main/java/net/minecraft/server/network/ServerConnectionListener.java
+++ b/src/main/java/net/minecraft/server/network/ServerConnectionListener.java
@@ -80,7 +80,12 @@ public class ServerConnectionListener {
this.running = true;
}
+ // Paper start
public void startTcpServerListener(@Nullable InetAddress address, int port) throws IOException {
+ bind(new java.net.InetSocketAddress(address, port));
+ }
+ public void bind(java.net.SocketAddress address) throws IOException {
+ // Paper end
List list = this.channels;
synchronized (this.channels) {
@@ -88,7 +93,11 @@ public class ServerConnectionListener {
LazyLoadedValue lazyinitvar;
if (Epoll.isAvailable() && this.server.isEpollEnabled()) {
+ if (address instanceof io.netty.channel.unix.DomainSocketAddress) {
+ oclass = io.netty.channel.epoll.EpollServerDomainSocketChannel.class;
+ } else {
oclass = EpollServerSocketChannel.class;
+ }
lazyinitvar = ServerConnectionListener.SERVER_EPOLL_EVENT_GROUP;
ServerConnectionListener.LOGGER.info("Using epoll channel type");
} else {
@@ -116,7 +125,7 @@ public class ServerConnectionListener {
((Connection) object).setListener(new ServerHandshakePacketListenerImpl(ServerConnectionListener.this.server, (Connection) object));
io.papermc.paper.network.ChannelInitializeListenerHolder.callListeners(channel); // Paper
}
- }).group((EventLoopGroup) lazyinitvar.get()).localAddress(address, port)).option(ChannelOption.AUTO_READ, false).bind().syncUninterruptibly()); // CraftBukkit
+ }).group((EventLoopGroup) lazyinitvar.get()).localAddress(address)).option(ChannelOption.AUTO_READ, false).bind().syncUninterruptibly()); // CraftBukkit // Paper
}
}
diff --git a/src/main/java/net/minecraft/server/network/ServerHandshakePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerHandshakePacketListenerImpl.java
index bce2f0f66f9e5493184fd0b5d2758e136a0e05b5..446a5fb08691a45a54bed3b5e7e68842f21e60d0 100644
--- a/src/main/java/net/minecraft/server/network/ServerHandshakePacketListenerImpl.java
+++ b/src/main/java/net/minecraft/server/network/ServerHandshakePacketListenerImpl.java
@@ -44,6 +44,7 @@ public class ServerHandshakePacketListenerImpl implements ServerHandshakePacketL
this.connection.setProtocol(ConnectionProtocol.LOGIN);
// CraftBukkit start - Connection throttle
try {
+ if (!(this.connection.channel.localAddress() instanceof io.netty.channel.unix.DomainSocketAddress)) { // Paper - the connection throttle is useless when you have a Unix domain socket
long currentTime = System.currentTimeMillis();
long connectionThrottle = this.server.server.getConnectionThrottle();
InetAddress address = ((java.net.InetSocketAddress) this.connection.getRemoteAddress()).getAddress();
@@ -72,6 +73,7 @@ public class ServerHandshakePacketListenerImpl implements ServerHandshakePacketL
}
}
}
+ } // Paper - add closing bracket for if check above
} catch (Throwable t) {
org.apache.logging.log4j.LogManager.getLogger().debug("Failed to check connection throttle", t);
}
@@ -120,8 +122,11 @@ public class ServerHandshakePacketListenerImpl implements ServerHandshakePacketL
// Paper end
// if (org.spigotmc.SpigotConfig.bungee) { // Paper - comment out, we check above!
if ( ( split.length == 3 || split.length == 4 ) && ( ServerHandshakePacketListenerImpl.BYPASS_HOSTCHECK || ServerHandshakePacketListenerImpl.HOST_PATTERN.matcher( split[1] ).matches() ) ) { // Paper
+ // Paper start - Unix domain socket support
+ java.net.SocketAddress socketAddress = connection.getRemoteAddress();
packet.hostName = split[0];
- connection.address = new java.net.InetSocketAddress(split[1], ((java.net.InetSocketAddress) this.connection.getRemoteAddress()).getPort());
+ connection.address = new java.net.InetSocketAddress(split[1], socketAddress instanceof java.net.InetSocketAddress ? ((java.net.InetSocketAddress) socketAddress).getPort() : 0);
+ // Paper end
connection.spoofedUUID = com.mojang.util.UUIDTypeAdapter.fromString( split[2] );
} else
{