3
0
Mirror von https://github.com/PaperMC/Velocity.git synchronisiert 2024-09-29 06:30:16 +02:00

Add support for listening and connecting to servers listening on Unix sockets

Dieser Commit ist enthalten in:
Andrew Steinborn 2020-10-22 02:01:29 -04:00
Ursprung 29890d7c20
Commit b00389029f
16 geänderte Dateien mit 183 neuen und 68 gelöschten Zeilen

Datei anzeigen

@ -3,6 +3,7 @@ package com.velocitypowered.api.proxy;
import com.velocitypowered.api.network.ProtocolVersion;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.util.Optional;
/**
@ -11,11 +12,11 @@ import java.util.Optional;
public interface InboundConnection {
/**
* Returns the player's IP address.
* Returns the player's remote address.
*
* @return the player's IP
* @return the player's remote address
*/
InetSocketAddress getRemoteAddress();
SocketAddress getRemoteAddress();
/**
* Returns the hostname that the user entered into the client, if applicable.

Datei anzeigen

@ -28,7 +28,6 @@ public interface Player extends CommandSource, Identified, InboundConnection,
*/
String getUsername();
/**
* Returns the player's UUID.
*

Datei anzeigen

@ -10,7 +10,7 @@ import com.velocitypowered.api.proxy.server.RegisteredServer;
import com.velocitypowered.api.proxy.server.ServerInfo;
import com.velocitypowered.api.scheduler.Scheduler;
import com.velocitypowered.api.util.ProxyVersion;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.util.Collection;
import java.util.Optional;
import java.util.UUID;
@ -163,7 +163,7 @@ public interface ProxyServer extends Audience {
*
* @return the address the proxy is bound to
*/
InetSocketAddress getBoundAddress();
SocketAddress getBoundAddress();
/**
* Gets the {@link ProxyConfig} instance.

Datei anzeigen

@ -2,6 +2,7 @@ package com.velocitypowered.api.proxy.server;
import com.google.common.base.Preconditions;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.util.Objects;
import org.checkerframework.checker.nullness.qual.Nullable;
@ -12,7 +13,7 @@ import org.checkerframework.checker.nullness.qual.Nullable;
public final class ServerInfo implements Comparable<ServerInfo> {
private final String name;
private final InetSocketAddress address;
private final SocketAddress address;
/**
* Creates a new ServerInfo object.
@ -20,7 +21,7 @@ public final class ServerInfo implements Comparable<ServerInfo> {
* @param name the name for the server
* @param address the address of the server to connect to
*/
public ServerInfo(String name, InetSocketAddress address) {
public ServerInfo(String name, SocketAddress address) {
this.name = Preconditions.checkNotNull(name, "name");
this.address = Preconditions.checkNotNull(address, "address");
}
@ -29,7 +30,7 @@ public final class ServerInfo implements Comparable<ServerInfo> {
return name;
}
public final InetSocketAddress getAddress() {
public final SocketAddress getAddress() {
return address;
}

Datei anzeigen

@ -47,6 +47,7 @@ import io.netty.channel.ChannelInitializer;
import io.netty.channel.EventLoopGroup;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
@ -200,16 +201,18 @@ public class VelocityServer implements ProxyServer, ForwardingAudience {
// init console permissions after plugins are loaded
console.setupPermissions();
final SocketAddress bindAddr = configuration.getBind();
final Integer port = this.options.getPort();
if (port != null) {
if (port != null && bindAddr instanceof InetSocketAddress) {
logger.debug("Overriding bind port to {} from command line option", port);
this.cm.bind(new InetSocketAddress(configuration.getBind().getHostString(), port));
this.cm.bind(new InetSocketAddress(((InetSocketAddress) bindAddr).getHostString(), port));
} else {
this.cm.bind(configuration.getBind());
}
if (configuration.isQueryEnabled()) {
this.cm.queryBind(configuration.getBind().getHostString(), configuration.getQueryPort());
if (configuration.isQueryEnabled() && bindAddr instanceof InetSocketAddress) {
this.cm.queryBind(((InetSocketAddress) bindAddr).getHostString(),
configuration.getQueryPort());
}
Metrics.VelocityMetrics.startMetrics(this, configuration.getMetrics());
@ -271,8 +274,8 @@ public class VelocityServer implements ProxyServer, ForwardingAudience {
logger.info("Loaded {} plugins", pluginManager.getPlugins().size());
}
public Bootstrap createBootstrap(@Nullable EventLoopGroup group) {
return this.cm.createWorker(group);
public Bootstrap createBootstrap(@Nullable EventLoopGroup group, SocketAddress target) {
return this.cm.createWorker(group, target);
}
public ChannelInitializer<Channel> getBackendChannelInitializer() {
@ -348,19 +351,22 @@ public class VelocityServer implements ProxyServer, ForwardingAudience {
}
// If we have a new bind address, bind to it
if (!configuration.getBind().equals(newConfiguration.getBind())) {
SocketAddress oldBind = configuration.getBind();
SocketAddress newBind = newConfiguration.getBind();
if (!configuration.getBind().equals(newBind)) {
this.cm.bind(newConfiguration.getBind());
this.cm.close(configuration.getBind());
}
if (configuration.isQueryEnabled() && (!newConfiguration.isQueryEnabled()
|| newConfiguration.getQueryPort() != configuration.getQueryPort())) {
|| newConfiguration.getQueryPort() != configuration.getQueryPort()
&& oldBind instanceof InetSocketAddress)) {
this.cm.close(new InetSocketAddress(
configuration.getBind().getHostString(), configuration.getQueryPort()));
((InetSocketAddress) oldBind).getHostString(), configuration.getQueryPort()));
}
if (newConfiguration.isQueryEnabled()) {
this.cm.queryBind(newConfiguration.getBind().getHostString(),
if (newConfiguration.isQueryEnabled() && newBind instanceof InetSocketAddress) {
this.cm.queryBind(((InetSocketAddress) newBind).getHostString(),
newConfiguration.getQueryPort());
}
@ -615,7 +621,7 @@ public class VelocityServer implements ProxyServer, ForwardingAudience {
}
@Override
public InetSocketAddress getBoundAddress() {
public SocketAddress getBoundAddress() {
if (configuration == null) {
throw new IllegalStateException(
"No configuration"); // even though you'll never get the chance... heh, heh

Datei anzeigen

@ -16,6 +16,7 @@ import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
@ -212,7 +213,7 @@ public class VelocityConfiguration implements ProxyConfig {
}
}
public InetSocketAddress getBind() {
public SocketAddress getBind() {
return AddressUtil.parseAndResolveAddress(bind);
}

Datei anzeigen

@ -16,6 +16,9 @@ import com.velocitypowered.proxy.server.VelocityRegisteredServer;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.unix.DomainSocketAddress;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.util.Optional;
import java.util.StringJoiner;
import net.kyori.adventure.identity.Identity;
@ -63,8 +66,16 @@ class BungeeCordMessageResponder {
ByteBuf buf = Unpooled.buffer();
ByteBufDataOutput out = new ByteBufDataOutput(buf);
out.writeUTF("IP");
out.writeUTF(player.getRemoteAddress().getHostString());
out.writeInt(player.getRemoteAddress().getPort());
SocketAddress address = player.getRemoteAddress();
if (address instanceof InetSocketAddress) {
InetSocketAddress serverInetAddr = (InetSocketAddress) address;
out.writeUTF(serverInetAddr.getHostString());
out.writeInt(serverInetAddr.getPort());
} else {
out.writeUTF("unix://" + ((DomainSocketAddress) address).path());
out.writeInt(0);
}
sendResponseOnConnection(buf);
}
@ -203,8 +214,15 @@ class BungeeCordMessageResponder {
out.writeUTF("IPOther");
out.writeUTF(player.getUsername());
out.writeUTF(player.getRemoteAddress().getHostString());
out.writeInt(player.getRemoteAddress().getPort());
SocketAddress address = player.getRemoteAddress();
if (address instanceof InetSocketAddress) {
InetSocketAddress serverInetAddr = (InetSocketAddress) address;
out.writeUTF(serverInetAddr.getHostString());
out.writeInt(serverInetAddr.getPort());
} else {
out.writeUTF("unix://" + ((DomainSocketAddress) address).path());
out.writeInt(0);
}
sendResponseOnConnection(buf);
});
@ -217,8 +235,15 @@ class BungeeCordMessageResponder {
out.writeUTF("ServerIP");
out.writeUTF(info.getServerInfo().getName());
out.writeUTF(info.getServerInfo().getAddress().getHostString());
out.writeShort(info.getServerInfo().getAddress().getPort());
SocketAddress address = info.getServerInfo().getAddress();
if (address instanceof InetSocketAddress) {
InetSocketAddress serverInetAddr = (InetSocketAddress) address;
out.writeUTF(serverInetAddr.getHostString());
out.writeShort(serverInetAddr.getPort());
} else {
out.writeUTF("unix://" + ((DomainSocketAddress) address).path());
out.writeShort(0);
}
sendResponseOnConnection(buf);
});

Datei anzeigen

@ -21,6 +21,7 @@ import com.velocitypowered.proxy.util.except.QuietRuntimeException;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.concurrent.CompletableFuture;
@ -128,13 +129,18 @@ public class LoginSessionHandler implements MinecraftSessionHandler {
}
}
private static String cleanRemoteAddress(InetSocketAddress address) {
String addressString = address.getAddress().getHostAddress();
int ipv6ScopeIdx = addressString.indexOf('%');
if (ipv6ScopeIdx == -1) {
return addressString;
private static String cleanRemoteAddress(SocketAddress address) {
if (address instanceof InetSocketAddress) {
String addressString = ((InetSocketAddress) address).getAddress().getHostAddress();
int ipv6ScopeIdx = addressString.indexOf('%');
if (ipv6ScopeIdx == -1) {
return addressString;
} else {
return addressString.substring(0, ipv6ScopeIdx);
}
} else {
return addressString.substring(0, ipv6ScopeIdx);
// Fake it
return "127.0.0.1";
}
}

Datei anzeigen

@ -28,6 +28,7 @@ import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelFutureListener;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.concurrent.CompletableFuture;
@ -70,9 +71,10 @@ public class VelocityServerConnection implements MinecraftConnectionAssociation,
CompletableFuture<Impl> result = new CompletableFuture<>();
// Note: we use the event loop for the connection the player is on. This reduces context
// switches.
server.createBootstrap(proxyPlayer.getConnection().eventLoop())
SocketAddress destinationAddress = registeredServer.getServerInfo().getAddress();
server.createBootstrap(proxyPlayer.getConnection().eventLoop(), destinationAddress)
.handler(server.getBackendChannelInitializer())
.connect(registeredServer.getServerInfo().getAddress())
.connect(destinationAddress)
.addListener((ChannelFutureListener) future -> {
if (future.isSuccess()) {
connection = new MinecraftConnection(future.channel(), server);
@ -95,14 +97,22 @@ public class VelocityServerConnection implements MinecraftConnectionAssociation,
return result;
}
private String getHandshakeRemoteAddress() {
return proxyPlayer.getVirtualHost().map(InetSocketAddress::getHostString).orElse("");
}
private String createLegacyForwardingAddress(UnaryOperator<List<Property>> propertiesTransform) {
// BungeeCord IP forwarding is simply a special injection after the "address" in the handshake,
// separated by \0 (the null byte). In order, you send the original host, the player's IP, their
// UUID (undashed), and if you are in online-mode, their login properties (from Mojang).
SocketAddress playerRemoteAddress = proxyPlayer.getRemoteAddress();
if (!(playerRemoteAddress instanceof InetSocketAddress)) {
return getHandshakeRemoteAddress();
}
StringBuilder data = new StringBuilder()
.append(registeredServer.getServerInfo().getAddress().getHostString())
.append(getHandshakeRemoteAddress())
.append('\0')
.append(proxyPlayer.getRemoteAddress().getHostString())
.append(((InetSocketAddress) proxyPlayer.getRemoteAddress()).getHostString())
.append('\0')
.append(proxyPlayer.getGameProfile().getUndashedId())
.append('\0');
@ -130,7 +140,6 @@ public class VelocityServerConnection implements MinecraftConnectionAssociation,
PlayerInfoForwarding forwardingMode = server.getConfiguration().getPlayerInfoForwardingMode();
// Initiate the handshake.
InetSocketAddress destAddress = registeredServer.getServerInfo().getAddress();
ProtocolVersion protocolVersion = proxyPlayer.getConnection().getProtocolVersion();
Handshake handshake = new Handshake();
handshake.setNextStatus(StateRegistry.LOGIN_ID);
@ -141,11 +150,15 @@ public class VelocityServerConnection implements MinecraftConnectionAssociation,
byte[] secret = server.getConfiguration().getForwardingSecret();
handshake.setServerAddress(createBungeeGuardForwardingAddress(secret));
} else if (proxyPlayer.getConnection().getType() == ConnectionTypes.LEGACY_FORGE) {
handshake.setServerAddress(destAddress.getHostString() + HANDSHAKE_HOSTNAME_TOKEN);
handshake.setServerAddress(getHandshakeRemoteAddress() + HANDSHAKE_HOSTNAME_TOKEN);
} else {
handshake.setServerAddress(destAddress.getHostString());
handshake.setServerAddress(getHandshakeRemoteAddress());
}
SocketAddress destinationAddr = registeredServer.getServerInfo().getAddress();
if (destinationAddr instanceof InetSocketAddress) {
handshake.setPort(((InetSocketAddress) destinationAddr).getPort());
}
handshake.setPort(destAddress.getPort());
mc.delayedWrite(handshake);
mc.setProtocolVersion(protocolVersion);

Datei anzeigen

@ -54,6 +54,7 @@ import com.velocitypowered.proxy.util.collect.CappedSet;
import io.netty.buffer.ByteBufUtil;
import io.netty.buffer.Unpooled;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
@ -202,8 +203,8 @@ public class ConnectedPlayer implements MinecraftConnectionAssociation, Player {
}
@Override
public InetSocketAddress getRemoteAddress() {
return (InetSocketAddress) connection.getRemoteAddress();
public SocketAddress getRemoteAddress() {
return connection.getRemoteAddress();
}
@Override

Datei anzeigen

@ -18,6 +18,7 @@ import io.netty.channel.WriteBufferWaterMark;
import io.netty.channel.epoll.EpollChannelOption;
import io.netty.util.concurrent.GlobalEventExecutor;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.util.HashMap;
import java.util.Map;
import org.apache.logging.log4j.LogManager;
@ -34,7 +35,7 @@ public final class ConnectionManager {
private static final WriteBufferWaterMark SERVER_WRITE_MARK = new WriteBufferWaterMark(1 << 20,
1 << 21);
private static final Logger LOGGER = LogManager.getLogger(ConnectionManager.class);
private final Map<InetSocketAddress, Channel> endpoints = new HashMap<>();
private final Map<SocketAddress, Channel> endpoints = new HashMap<>();
private final TransportType transportType;
private final EventLoopGroup bossGroup;
private final EventLoopGroup workerGroup;
@ -90,18 +91,20 @@ public final class ConnectionManager {
*
* @param address the address to bind to
*/
public void bind(final InetSocketAddress address) {
public void bind(final SocketAddress address) {
final ServerBootstrap bootstrap = new ServerBootstrap()
.channelFactory(this.transportType.serverSocketChannelFactory)
.channelFactory(this.transportType.getServerChannelFactory(address))
.group(this.bossGroup, this.workerGroup)
.childOption(ChannelOption.WRITE_BUFFER_WATER_MARK, SERVER_WRITE_MARK)
.childHandler(this.serverChannelInitializer.get())
.childOption(ChannelOption.TCP_NODELAY, true)
.childOption(ChannelOption.IP_TOS, 0x18)
.localAddress(address);
if (transportType == TransportType.EPOLL && server.getConfiguration().useTcpFastOpen()) {
bootstrap.option(EpollChannelOption.TCP_FASTOPEN, 3);
if (address instanceof InetSocketAddress) {
bootstrap.childOption(ChannelOption.TCP_NODELAY, true)
.childOption(ChannelOption.IP_TOS, 0x18);
if (transportType == TransportType.EPOLL && server.getConfiguration().useTcpFastOpen()) {
bootstrap.option(EpollChannelOption.TCP_FASTOPEN, 3);
}
}
bootstrap.bind()
@ -142,15 +145,15 @@ public final class ConnectionManager {
}
/**
* Creates a TCP {@link Bootstrap} using Velocity's event loops.
* Creates a {@link Bootstrap} using Velocity's event loops.
*
* @param group the event loop group to use. Use {@code null} for the default worker group.
*
* @param target the address the client will connect to
* @return a new {@link Bootstrap}
*/
public Bootstrap createWorker(@Nullable EventLoopGroup group) {
public Bootstrap createWorker(@Nullable EventLoopGroup group, SocketAddress target) {
Bootstrap bootstrap = new Bootstrap()
.channelFactory(this.transportType.socketChannelFactory)
.channelFactory(this.transportType.getClientChannelFactory(target))
.option(ChannelOption.TCP_NODELAY, true)
.option(ChannelOption.CONNECT_TIMEOUT_MILLIS,
this.server.getConfiguration().getConnectTimeout())
@ -167,7 +170,7 @@ public final class ConnectionManager {
*
* @param oldBind the endpoint to close
*/
public void close(InetSocketAddress oldBind) {
public void close(SocketAddress oldBind) {
Channel serverChannel = endpoints.remove(oldBind);
Preconditions.checkState(serverChannel != null, "Endpoint %s not registered", oldBind);
LOGGER.info("Closing endpoint {}", serverChannel.localAddress());

Datei anzeigen

@ -1,11 +1,15 @@
package com.velocitypowered.proxy.network;
import com.velocitypowered.proxy.util.concurrent.VelocityNettyThreadFactory;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFactory;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.ServerChannel;
import io.netty.channel.epoll.Epoll;
import io.netty.channel.epoll.EpollDatagramChannel;
import io.netty.channel.epoll.EpollDomainSocketChannel;
import io.netty.channel.epoll.EpollEventLoopGroup;
import io.netty.channel.epoll.EpollServerDomainSocketChannel;
import io.netty.channel.epoll.EpollServerSocketChannel;
import io.netty.channel.epoll.EpollSocketChannel;
import io.netty.channel.nio.NioEventLoopGroup;
@ -15,6 +19,10 @@ import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioDatagramChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.channel.unix.DomainSocketAddress;
import io.netty.channel.unix.DomainSocketChannel;
import io.netty.channel.unix.ServerDomainSocketChannel;
import java.net.SocketAddress;
import java.util.concurrent.ThreadFactory;
import java.util.function.BiFunction;
@ -22,27 +30,37 @@ enum TransportType {
NIO("NIO", NioServerSocketChannel::new,
NioSocketChannel::new,
NioDatagramChannel::new,
null,
null,
(name, type) -> new NioEventLoopGroup(0, createThreadFactory(name, type))),
EPOLL("epoll", EpollServerSocketChannel::new,
EpollSocketChannel::new,
EpollDatagramChannel::new,
EpollServerDomainSocketChannel::new,
EpollDomainSocketChannel::new,
(name, type) -> new EpollEventLoopGroup(0, createThreadFactory(name, type)));
final String name;
final ChannelFactory<? extends ServerSocketChannel> serverSocketChannelFactory;
final ChannelFactory<? extends SocketChannel> socketChannelFactory;
final ChannelFactory<? extends DatagramChannel> datagramChannelFactory;
final ChannelFactory<? extends ServerDomainSocketChannel> domainServerSocketChannelFactory;
final ChannelFactory<? extends DomainSocketChannel> domainSocketChannelFactory;
final BiFunction<String, Type, EventLoopGroup> eventLoopGroupFactory;
TransportType(final String name,
final ChannelFactory<? extends ServerSocketChannel> serverSocketChannelFactory,
final ChannelFactory<? extends SocketChannel> socketChannelFactory,
final ChannelFactory<? extends DatagramChannel> datagramChannelFactory,
final ChannelFactory<? extends ServerDomainSocketChannel> domainServerSocketChannelFactory,
final ChannelFactory<? extends DomainSocketChannel> domainSocketChannelFactory,
final BiFunction<String, Type, EventLoopGroup> eventLoopGroupFactory) {
this.name = name;
this.serverSocketChannelFactory = serverSocketChannelFactory;
this.socketChannelFactory = socketChannelFactory;
this.datagramChannelFactory = datagramChannelFactory;
this.domainServerSocketChannelFactory = domainServerSocketChannelFactory;
this.domainSocketChannelFactory = domainSocketChannelFactory;
this.eventLoopGroupFactory = eventLoopGroupFactory;
}
@ -51,6 +69,28 @@ enum TransportType {
return this.name;
}
public ChannelFactory<? extends ServerChannel> getServerChannelFactory(SocketAddress address) {
if (address instanceof DomainSocketAddress) {
if (this.domainServerSocketChannelFactory == null) {
throw new IllegalArgumentException(
"Domain sockets are not available for non-Linux platforms");
}
return this.domainServerSocketChannelFactory;
}
return this.serverSocketChannelFactory;
}
public ChannelFactory<? extends Channel> getClientChannelFactory(SocketAddress address) {
if (address instanceof DomainSocketAddress) {
if (this.domainSocketChannelFactory == null) {
throw new IllegalArgumentException(
"Domain sockets are not available for non-Linux platforms");
}
return this.domainSocketChannelFactory;
}
return this.socketChannelFactory;
}
public EventLoopGroup createEventLoopGroup(final Type type) {
return this.eventLoopGroupFactory.apply(this.name, type);
}

Datei anzeigen

@ -18,6 +18,7 @@ import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.socket.DatagramPacket;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.nio.charset.StandardCharsets;
import java.security.SecureRandom;
import java.util.ArrayList;
@ -70,8 +71,8 @@ public class GS4QueryHandler extends SimpleChannelInboundHandler<DatagramPacket>
.map(server.getConfiguration().getQueryMap())
.currentPlayers(server.getPlayerCount())
.maxPlayers(server.getConfiguration().getShowMaxPlayers())
.proxyPort(server.getConfiguration().getBind().getPort())
.proxyHost(server.getConfiguration().getBind().getHostString())
.proxyPort(((InetSocketAddress) server.getConfiguration().getBind()).getPort())
.proxyHost(((InetSocketAddress) server.getConfiguration().getBind()).getHostString())
.players(server.getAllPlayers().stream().map(Player::getUsername)
.collect(Collectors.toList()))
.proxyVersion("Velocity")

Datei anzeigen

@ -11,6 +11,8 @@ import com.velocitypowered.proxy.protocol.packet.Handshake;
import com.velocitypowered.proxy.protocol.packet.StatusRequest;
import com.velocitypowered.proxy.protocol.packet.StatusResponse;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.util.concurrent.CompletableFuture;
public class PingSessionHandler implements MinecraftSessionHandler {
@ -33,8 +35,16 @@ public class PingSessionHandler implements MinecraftSessionHandler {
public void activated() {
Handshake handshake = new Handshake();
handshake.setNextStatus(StateRegistry.STATUS_ID);
handshake.setServerAddress(server.getServerInfo().getAddress().getHostString());
handshake.setPort(server.getServerInfo().getAddress().getPort());
SocketAddress address = server.getServerInfo().getAddress();
if (address instanceof InetSocketAddress) {
InetSocketAddress socketAddr = (InetSocketAddress) address;
handshake.setServerAddress(socketAddr.getHostString());
handshake.setPort(socketAddr.getPort());
} else {
// Just fake it
handshake.setServerAddress("127.0.0.1");
}
handshake.setProtocolVersion(version);
connection.delayedWrite(handshake);

Datei anzeigen

@ -79,7 +79,7 @@ public class VelocityRegisteredServer implements RegisteredServer, ForwardingAud
throw new IllegalStateException("No Velocity proxy instance available");
}
CompletableFuture<ServerPing> pingFuture = new CompletableFuture<>();
server.createBootstrap(loop)
server.createBootstrap(loop, serverInfo.getAddress())
.handler(new ChannelInitializer<Channel>() {
@Override
protected void initChannel(Channel ch) throws Exception {

Datei anzeigen

@ -2,8 +2,11 @@ package com.velocitypowered.proxy.util;
import com.google.common.base.Preconditions;
import com.google.common.net.InetAddresses;
import io.netty.channel.epoll.Epoll;
import io.netty.channel.unix.DomainSocketAddress;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.net.URI;
public final class AddressUtil {
@ -12,14 +15,16 @@ public final class AddressUtil {
}
/**
* Attempts to parse an IP address of the form {@code 127.0.0.1:25565}. The returned
* {@link InetSocketAddress} is not resolved.
* Attempts to parse a socket address of the form {@code 127.0.0.1:25565}. The returned
* {@link SocketAddress} is not resolved if it is a {@link InetSocketAddress}.
*
* @param ip the IP to parse
* @return the parsed address
*/
public static InetSocketAddress parseAddress(String ip) {
Preconditions.checkNotNull(ip, "ip");
public static SocketAddress parseAddress(String ip) {
if (ip.startsWith("unix://") && Epoll.isAvailable()) {
return new DomainSocketAddress(ip.substring("unix://".length()));
}
URI uri = URI.create("tcp://" + ip);
try {
InetAddress ia = InetAddresses.forUriString(uri.getHost());
@ -30,13 +35,16 @@ public final class AddressUtil {
}
/**
* Attempts to parse an IP address of the form {@code 127.0.0.1:25565}. The returned
* {@link InetSocketAddress} is resolved.
* Attempts to parse a socket address of the form {@code 127.0.0.1:25565}. The returned
* {@link SocketAddress} is resolved if it is a {@link InetSocketAddress}.
*
* @param ip the IP to parse
* @return the parsed address
*/
public static InetSocketAddress parseAndResolveAddress(String ip) {
public static SocketAddress parseAndResolveAddress(String ip) {
if (ip.startsWith("unix://") && Epoll.isAvailable()) {
return new DomainSocketAddress(ip.substring("unix://".length()));
}
Preconditions.checkNotNull(ip, "ip");
URI uri = URI.create("tcp://" + ip);
return new InetSocketAddress(uri.getHost(), uri.getPort());