Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Add extra vHost data in ConnectionHandshakeEvent #1413

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -20,23 +20,33 @@ public final class ConnectionHandshakeEvent {

private final InboundConnection connection;
private final HandshakeIntent intent;
private final String extraDataInHandshake;

public ConnectionHandshakeEvent(InboundConnection connection, HandshakeIntent intent) {
/**
* Creates a new event.
*
* @param connection the inbound connection
* @param intent the intent of the handshake
* @param extraDataInHandshake the extra data in the handshake
*/
public ConnectionHandshakeEvent(InboundConnection connection, HandshakeIntent intent, String extraDataInHandshake) {
this.connection = Preconditions.checkNotNull(connection, "connection");
this.intent = Preconditions.checkNotNull(intent, "intent");
this.extraDataInHandshake = Preconditions.checkNotNull(extraDataInHandshake, "extraDataInHandshake");
}

/**
* This method is only retained to avoid breaking plugins
* that have not yet updated their integration tests.
*
* @param connection the inbound connection
* @deprecated use {@link #ConnectionHandshakeEvent(InboundConnection, HandshakeIntent)}
* @deprecated use {@link #ConnectionHandshakeEvent(InboundConnection, HandshakeIntent, String)}
*/
@Deprecated(forRemoval = true)
public ConnectionHandshakeEvent(InboundConnection connection) {
this.connection = Preconditions.checkNotNull(connection, "connection");
this.intent = HandshakeIntent.LOGIN;
this.extraDataInHandshake = "";
}

public InboundConnection getConnection() {
Expand All @@ -47,11 +57,15 @@ public HandshakeIntent getIntent() {
return this.intent;
}

public String getExtraDataInHandshake() {
return this.extraDataInHandshake;
}

@Override
public String toString() {
return "ConnectionHandshakeEvent{"
+ "connection=" + connection
+ ", intent=" + intent
+ '}';
+ "connection=" + connection
+ ", intent=" + intent
+ '}';
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ public HandshakeSessionHandler(MinecraftConnection connection, VelocityServer se
public boolean handle(LegacyPingPacket packet) {
connection.setProtocolVersion(ProtocolVersion.LEGACY);
final StatusSessionHandler handler =
new StatusSessionHandler(server, new LegacyInboundConnection(connection, packet));
new StatusSessionHandler(server, new LegacyInboundConnection(connection, packet));
connection.setActiveSessionHandler(StateRegistry.STATUS, handler);
handler.handle(packet);
return true;
Expand All @@ -79,8 +79,8 @@ public boolean handle(LegacyPingPacket packet) {
@Override
public boolean handle(LegacyHandshakePacket packet) {
connection.closeWith(LegacyDisconnect.from(Component.text(
"Your client is extremely old. Please update to a newer version of Minecraft.",
NamedTextColor.RED)
"Your client is extremely old. Please update to a newer version of Minecraft.",
NamedTextColor.RED)
));
return true;
}
Expand All @@ -104,8 +104,8 @@ public boolean handle(final HandshakePacket handshake) {

switch (nextState) {
case STATUS -> connection.setActiveSessionHandler(StateRegistry.STATUS,
new StatusSessionHandler(server, ic));
case LOGIN -> this.handleLogin(handshake, ic);
new StatusSessionHandler(server, ic));
case LOGIN -> this.handleLogin(handshake, ic, getExtraVhostData(handshake.getServerAddress()));
default ->
// If you get this, it's a bug in Velocity.
throw new AssertionError("getStateForProtocol provided invalid state!");
Expand All @@ -123,7 +123,7 @@ public boolean handle(final HandshakePacket handshake) {
};
}

private void handleLogin(HandshakePacket handshake, InitialInboundConnection ic) {
private void handleLogin(HandshakePacket handshake, InitialInboundConnection ic, String extraData) {
if (!handshake.getProtocolVersion().isSupported()) {
// Bump connection into correct protocol state so that we can send the disconnect packet.
connection.setState(StateRegistry.LOGIN);
Expand All @@ -147,19 +147,19 @@ private void handleLogin(HandshakePacket handshake, InitialInboundConnection ic)
// If the proxy is configured for modern forwarding, we must deny connections from 1.12.2
// and lower, otherwise IP information will never get forwarded.
if (server.getConfiguration().getPlayerInfoForwardingMode() == PlayerInfoForwarding.MODERN
&& handshake.getProtocolVersion().lessThan(ProtocolVersion.MINECRAFT_1_13)) {
&& handshake.getProtocolVersion().lessThan(ProtocolVersion.MINECRAFT_1_13)) {
// Bump connection into correct protocol state so that we can send the disconnect packet.
connection.setState(StateRegistry.LOGIN);
ic.disconnectQuietly(
Component.translatable("velocity.error.modern-forwarding-needs-new-client"));
Component.translatable("velocity.error.modern-forwarding-needs-new-client"));
return;
}

final LoginInboundConnection lic = new LoginInboundConnection(ic);
server.getEventManager().fireAndForget(
new ConnectionHandshakeEvent(lic, handshake.getIntent()));
new ConnectionHandshakeEvent(lic, handshake.getIntent(), extraData));
connection.setActiveSessionHandler(StateRegistry.LOGIN,
new InitialLoginSessionHandler(server, connection, lic));
new InitialLoginSessionHandler(server, connection, lic));
}

private ConnectionType getHandshakeConnectionType(HandshakePacket handshake) {
Expand All @@ -169,7 +169,7 @@ private ConnectionType getHandshakeConnectionType(HandshakePacket handshake) {
}
// Determine if we're using Forge (1.8 to 1.12, may not be the case in 1.13).
if (handshake.getServerAddress().endsWith(LegacyForgeConstants.HANDSHAKE_HOSTNAME_TOKEN)
&& handshake.getProtocolVersion().lessThan(ProtocolVersion.MINECRAFT_1_13)) {
&& handshake.getProtocolVersion().lessThan(ProtocolVersion.MINECRAFT_1_13)) {
return ConnectionTypes.LEGACY_FORGE;
} else if (handshake.getProtocolVersion().noGreaterThan(ProtocolVersion.MINECRAFT_1_7_6)) {
// 1.7 Forge will not notify us during handshake. UNDETERMINED will listen for incoming
Expand Down Expand Up @@ -206,6 +206,23 @@ static String cleanVhost(String hostname) {
return cleaned;
}

/**
* Extracts the extra data from the specified hostname.
*
* @param hostname the host name to extract the extra data from
* @return the extra data
*/
@VisibleForTesting
static String getExtraVhostData(String hostname) {
// Add extra data support
String data = "";
if (hostname.contains("\0")) {
String[] split = hostname.split("\0", 2);
data = "\0" + split[1];
}
return data;
}

@Override
public void handleGeneric(MinecraftPacket packet) {
// Unknown packet received. Better to close the connection.
Expand Down Expand Up @@ -256,10 +273,10 @@ public ProtocolVersion getProtocolVersion() {
@Override
public String toString() {
final boolean isPlayerAddressLoggingEnabled = connection.server.getConfiguration()
.isPlayerAddressLoggingEnabled();
.isPlayerAddressLoggingEnabled();
final String playerIp =
isPlayerAddressLoggingEnabled
? this.getRemoteAddress().toString() : "<ip address withheld>";
isPlayerAddressLoggingEnabled
? this.getRemoteAddress().toString() : "<ip address withheld>";
return "[legacy connection] " + playerIp;
}

Expand Down