geforkt von Mirrors/Velocity
Improve efficiency of Java implementation of natives.
Dieser Commit ist enthalten in:
Ursprung
566a306d18
Commit
9bbe25fc90
@ -8,7 +8,7 @@ apply from: '../gradle/checkstyle.gradle'
|
|||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
compile "com.google.guava:guava:${guavaVersion}"
|
compile "com.google.guava:guava:${guavaVersion}"
|
||||||
compile "io.netty:netty-buffer:${nettyVersion}"
|
compile "io.netty:netty-handler:${nettyVersion}"
|
||||||
compile "org.checkerframework:checker-qual:${checkerFrameworkVersion}"
|
compile "org.checkerframework:checker-qual:${checkerFrameworkVersion}"
|
||||||
|
|
||||||
testCompile "org.junit.jupiter:junit-jupiter-api:${junitVersion}"
|
testCompile "org.junit.jupiter:junit-jupiter-api:${junitVersion}"
|
||||||
|
@ -2,6 +2,7 @@ package com.velocitypowered.natives.encryption;
|
|||||||
|
|
||||||
import com.google.common.base.Preconditions;
|
import com.google.common.base.Preconditions;
|
||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
|
import io.netty.channel.ChannelHandlerContext;
|
||||||
import java.security.GeneralSecurityException;
|
import java.security.GeneralSecurityException;
|
||||||
import javax.crypto.Cipher;
|
import javax.crypto.Cipher;
|
||||||
import javax.crypto.SecretKey;
|
import javax.crypto.SecretKey;
|
||||||
@ -21,6 +22,9 @@ public class JavaVelocityCipher implements VelocityCipher {
|
|||||||
return new JavaVelocityCipher(false, key);
|
return new JavaVelocityCipher(false, key);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
private static final int INITIAL_BUFFER_SIZE = 1024 * 16;
|
||||||
|
private static final ThreadLocal<byte[]> inBufLocal = ThreadLocal.withInitial(
|
||||||
|
() -> new byte[INITIAL_BUFFER_SIZE]);
|
||||||
|
|
||||||
private final Cipher cipher;
|
private final Cipher cipher;
|
||||||
private boolean disposed = false;
|
private boolean disposed = false;
|
||||||
@ -35,13 +39,36 @@ public class JavaVelocityCipher implements VelocityCipher {
|
|||||||
public void process(ByteBuf source, ByteBuf destination) throws ShortBufferException {
|
public void process(ByteBuf source, ByteBuf destination) throws ShortBufferException {
|
||||||
ensureNotDisposed();
|
ensureNotDisposed();
|
||||||
|
|
||||||
byte[] sourceAsBytes = new byte[source.readableBytes()];
|
int inBytes = source.readableBytes();
|
||||||
source.readBytes(sourceAsBytes);
|
byte[] inBuf = slurp(source);
|
||||||
|
|
||||||
int outputSize = cipher.getOutputSize(sourceAsBytes.length);
|
int outputSize = cipher.getOutputSize(inBytes);
|
||||||
byte[] destinationBytes = new byte[outputSize];
|
byte[] outBuf = new byte[outputSize];
|
||||||
cipher.update(sourceAsBytes, 0, sourceAsBytes.length, destinationBytes);
|
cipher.update(inBuf, 0, inBytes, outBuf);
|
||||||
destination.writeBytes(destinationBytes);
|
destination.writeBytes(outBuf);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuf process(ChannelHandlerContext ctx, ByteBuf source) throws ShortBufferException {
|
||||||
|
ensureNotDisposed();
|
||||||
|
|
||||||
|
int inBytes = source.readableBytes();
|
||||||
|
byte[] inBuf = slurp(source);
|
||||||
|
|
||||||
|
ByteBuf out = ctx.alloc().heapBuffer(cipher.getOutputSize(inBytes));
|
||||||
|
out.writerIndex(cipher.update(inBuf, 0, inBytes, out.array(), out.arrayOffset()));
|
||||||
|
return out;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static byte[] slurp(ByteBuf source) {
|
||||||
|
int inBytes = source.readableBytes();
|
||||||
|
byte[] inBuf = inBufLocal.get();
|
||||||
|
if (inBuf.length <= inBytes) {
|
||||||
|
inBuf = new byte[inBytes];
|
||||||
|
inBufLocal.set(inBuf);
|
||||||
|
}
|
||||||
|
source.readBytes(inBuf, 0, inBytes);
|
||||||
|
return inBuf;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package com.velocitypowered.natives.encryption;
|
package com.velocitypowered.natives.encryption;
|
||||||
|
|
||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
|
import io.netty.channel.ChannelHandlerContext;
|
||||||
import java.security.GeneralSecurityException;
|
import java.security.GeneralSecurityException;
|
||||||
import javax.crypto.SecretKey;
|
import javax.crypto.SecretKey;
|
||||||
import javax.crypto.ShortBufferException;
|
import javax.crypto.ShortBufferException;
|
||||||
@ -45,6 +46,18 @@ public class NativeVelocityCipher implements VelocityCipher {
|
|||||||
destination.writerIndex(destination.writerIndex() + len);
|
destination.writerIndex(destination.writerIndex() + len);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ByteBuf process(ChannelHandlerContext ctx, ByteBuf source) throws ShortBufferException {
|
||||||
|
ByteBuf out = ctx.alloc().directBuffer(source.readableBytes());
|
||||||
|
try {
|
||||||
|
process(source, out);
|
||||||
|
return out;
|
||||||
|
} catch (Exception e) {
|
||||||
|
out.release();
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void dispose() {
|
public void dispose() {
|
||||||
if (!disposed) {
|
if (!disposed) {
|
||||||
|
@ -2,9 +2,12 @@ package com.velocitypowered.natives.encryption;
|
|||||||
|
|
||||||
import com.velocitypowered.natives.Disposable;
|
import com.velocitypowered.natives.Disposable;
|
||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
|
import io.netty.channel.ChannelHandlerContext;
|
||||||
import javax.crypto.ShortBufferException;
|
import javax.crypto.ShortBufferException;
|
||||||
|
|
||||||
public interface VelocityCipher extends Disposable {
|
public interface VelocityCipher extends Disposable {
|
||||||
|
|
||||||
void process(ByteBuf source, ByteBuf destination) throws ShortBufferException;
|
void process(ByteBuf source, ByteBuf destination) throws ShortBufferException;
|
||||||
|
|
||||||
|
ByteBuf process(ChannelHandlerContext ctx, ByteBuf source) throws ShortBufferException;
|
||||||
}
|
}
|
||||||
|
@ -75,11 +75,5 @@ public final class NativeCodeLoader<T> implements Supplier<T> {
|
|||||||
SETUP_FAILURE
|
SETUP_FAILURE
|
||||||
}
|
}
|
||||||
|
|
||||||
static final BooleanSupplier MACOS = () ->
|
|
||||||
System.getProperty("os.name", "").equalsIgnoreCase("Mac OS X")
|
|
||||||
&& System.getProperty("os.arch").equals("x86_64");
|
|
||||||
static final BooleanSupplier LINUX = () ->
|
|
||||||
System.getProperties().getProperty("os.name", "").equalsIgnoreCase("Linux")
|
|
||||||
&& System.getProperty("os.arch").equals("amd64");
|
|
||||||
static final BooleanSupplier ALWAYS = () -> true;
|
static final BooleanSupplier ALWAYS = () -> true;
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,19 @@
|
|||||||
|
package com.velocitypowered.natives.util;
|
||||||
|
|
||||||
|
import java.util.function.BooleanSupplier;
|
||||||
|
|
||||||
|
public class NativeConstraints {
|
||||||
|
private static final boolean NATIVES_ENABLED = !Boolean.getBoolean("velocity.natives-disabled");
|
||||||
|
|
||||||
|
static final BooleanSupplier MACOS = () -> {
|
||||||
|
return NATIVES_ENABLED
|
||||||
|
&& System.getProperty("os.name", "").equalsIgnoreCase("Mac OS X")
|
||||||
|
&& System.getProperty("os.arch").equals("x86_64");
|
||||||
|
};
|
||||||
|
|
||||||
|
static final BooleanSupplier LINUX = () -> {
|
||||||
|
return NATIVES_ENABLED
|
||||||
|
&& System.getProperty("os.name", "").equalsIgnoreCase("Linux")
|
||||||
|
&& System.getProperty("os.arch").equals("amd64");
|
||||||
|
};
|
||||||
|
}
|
@ -46,10 +46,10 @@ public class Natives {
|
|||||||
|
|
||||||
public static final NativeCodeLoader<VelocityCompressorFactory> compress = new NativeCodeLoader<>(
|
public static final NativeCodeLoader<VelocityCompressorFactory> compress = new NativeCodeLoader<>(
|
||||||
ImmutableList.of(
|
ImmutableList.of(
|
||||||
new NativeCodeLoader.Variant<>(NativeCodeLoader.MACOS,
|
new NativeCodeLoader.Variant<>(NativeConstraints.MACOS,
|
||||||
copyAndLoadNative("/macosx/velocity-compress.dylib"), "native (macOS)",
|
copyAndLoadNative("/macosx/velocity-compress.dylib"), "native (macOS)",
|
||||||
NativeVelocityCompressor.FACTORY),
|
NativeVelocityCompressor.FACTORY),
|
||||||
new NativeCodeLoader.Variant<>(NativeCodeLoader.LINUX,
|
new NativeCodeLoader.Variant<>(NativeConstraints.LINUX,
|
||||||
copyAndLoadNative("/linux_x64/velocity-compress.so"), "native (Linux amd64)",
|
copyAndLoadNative("/linux_x64/velocity-compress.so"), "native (Linux amd64)",
|
||||||
NativeVelocityCompressor.FACTORY),
|
NativeVelocityCompressor.FACTORY),
|
||||||
new NativeCodeLoader.Variant<>(NativeCodeLoader.ALWAYS, () -> {
|
new NativeCodeLoader.Variant<>(NativeCodeLoader.ALWAYS, () -> {
|
||||||
@ -59,10 +59,10 @@ public class Natives {
|
|||||||
|
|
||||||
public static final NativeCodeLoader<VelocityCipherFactory> cipher = new NativeCodeLoader<>(
|
public static final NativeCodeLoader<VelocityCipherFactory> cipher = new NativeCodeLoader<>(
|
||||||
ImmutableList.of(
|
ImmutableList.of(
|
||||||
new NativeCodeLoader.Variant<>(NativeCodeLoader.MACOS,
|
new NativeCodeLoader.Variant<>(NativeConstraints.MACOS,
|
||||||
copyAndLoadNative("/macosx/velocity-cipher.dylib"), "mbed TLS (macOS)",
|
copyAndLoadNative("/macosx/velocity-cipher.dylib"), "mbed TLS (macOS)",
|
||||||
NativeVelocityCipher.FACTORY),
|
NativeVelocityCipher.FACTORY),
|
||||||
new NativeCodeLoader.Variant<>(NativeCodeLoader.LINUX,
|
new NativeCodeLoader.Variant<>(NativeConstraints.LINUX,
|
||||||
copyAndLoadNative("/linux_x64/velocity-cipher.so"), "mbed TLS (Linux amd64)",
|
copyAndLoadNative("/linux_x64/velocity-cipher.so"), "mbed TLS (Linux amd64)",
|
||||||
NativeVelocityCipher.FACTORY),
|
NativeVelocityCipher.FACTORY),
|
||||||
new NativeCodeLoader.Variant<>(NativeCodeLoader.ALWAYS, () -> {
|
new NativeCodeLoader.Variant<>(NativeCodeLoader.ALWAYS, () -> {
|
||||||
|
@ -17,14 +17,7 @@ public class MinecraftCipherDecoder extends ByteToMessageDecoder {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
|
protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
|
||||||
ByteBuf decrypted = ctx.alloc().buffer(in.readableBytes());
|
out.add(cipher.process(ctx, in));
|
||||||
try {
|
|
||||||
cipher.process(in, decrypted);
|
|
||||||
out.add(decrypted);
|
|
||||||
} catch (Exception e) {
|
|
||||||
decrypted.release();
|
|
||||||
throw e;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren