1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
|
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 932b494ea2a5e849b233c73bd2472d5c85f5ba52..8536dd544876e245a611379a7ed1446b0ed06eac 100644
--- a/src/main/java/net/minecraft/network/Connection.java
+++ b/src/main/java/net/minecraft/network/Connection.java
@@ -626,6 +626,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 fa6adf12e8272c90c3376bc93350dc57eb1cd461..939745227346e6d23e50f942eb48ab97c4ab6190 100644
--- a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
+++ b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
@@ -234,6 +234,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 (!com.destroystokyo.paper.PaperConfig.velocitySupport && !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()) {
@@ -243,12 +257,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 c36089ead51d2e7dc3369d5f9a1869f58ff5391c..bfa519b9335c960a5baec50b0da95d95cd5ee958 100644
--- a/src/main/java/net/minecraft/server/network/ServerConnectionListener.java
+++ b/src/main/java/net/minecraft/server/network/ServerConnectionListener.java
@@ -78,7 +78,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) {
@@ -86,7 +91,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 {
@@ -114,7 +123,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 b5b929a504164aefd2498cd9fad66a5c7aaf59e4..97ee159867c4800c8fdec9a5fa42f648112be186 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
{
|