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 {
|
||||
compile "com.google.guava:guava:${guavaVersion}"
|
||||
compile "io.netty:netty-buffer:${nettyVersion}"
|
||||
compile "io.netty:netty-handler:${nettyVersion}"
|
||||
compile "org.checkerframework:checker-qual:${checkerFrameworkVersion}"
|
||||
|
||||
testCompile "org.junit.jupiter:junit-jupiter-api:${junitVersion}"
|
||||
|
@ -2,6 +2,7 @@ package com.velocitypowered.natives.encryption;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import java.security.GeneralSecurityException;
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.SecretKey;
|
||||
@ -21,6 +22,9 @@ public class JavaVelocityCipher implements VelocityCipher {
|
||||
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 boolean disposed = false;
|
||||
@ -35,13 +39,36 @@ public class JavaVelocityCipher implements VelocityCipher {
|
||||
public void process(ByteBuf source, ByteBuf destination) throws ShortBufferException {
|
||||
ensureNotDisposed();
|
||||
|
||||
byte[] sourceAsBytes = new byte[source.readableBytes()];
|
||||
source.readBytes(sourceAsBytes);
|
||||
int inBytes = source.readableBytes();
|
||||
byte[] inBuf = slurp(source);
|
||||
|
||||
int outputSize = cipher.getOutputSize(sourceAsBytes.length);
|
||||
byte[] destinationBytes = new byte[outputSize];
|
||||
cipher.update(sourceAsBytes, 0, sourceAsBytes.length, destinationBytes);
|
||||
destination.writeBytes(destinationBytes);
|
||||
int outputSize = cipher.getOutputSize(inBytes);
|
||||
byte[] outBuf = new byte[outputSize];
|
||||
cipher.update(inBuf, 0, inBytes, outBuf);
|
||||
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
|
||||
|
@ -1,6 +1,7 @@
|
||||
package com.velocitypowered.natives.encryption;
|
||||
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import java.security.GeneralSecurityException;
|
||||
import javax.crypto.SecretKey;
|
||||
import javax.crypto.ShortBufferException;
|
||||
@ -45,6 +46,18 @@ public class NativeVelocityCipher implements VelocityCipher {
|
||||
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
|
||||
public void dispose() {
|
||||
if (!disposed) {
|
||||
|
@ -2,9 +2,12 @@ package com.velocitypowered.natives.encryption;
|
||||
|
||||
import com.velocitypowered.natives.Disposable;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import javax.crypto.ShortBufferException;
|
||||
|
||||
public interface VelocityCipher extends Disposable {
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
@ -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<>(
|
||||
ImmutableList.of(
|
||||
new NativeCodeLoader.Variant<>(NativeCodeLoader.MACOS,
|
||||
new NativeCodeLoader.Variant<>(NativeConstraints.MACOS,
|
||||
copyAndLoadNative("/macosx/velocity-compress.dylib"), "native (macOS)",
|
||||
NativeVelocityCompressor.FACTORY),
|
||||
new NativeCodeLoader.Variant<>(NativeCodeLoader.LINUX,
|
||||
new NativeCodeLoader.Variant<>(NativeConstraints.LINUX,
|
||||
copyAndLoadNative("/linux_x64/velocity-compress.so"), "native (Linux amd64)",
|
||||
NativeVelocityCompressor.FACTORY),
|
||||
new NativeCodeLoader.Variant<>(NativeCodeLoader.ALWAYS, () -> {
|
||||
@ -59,10 +59,10 @@ public class Natives {
|
||||
|
||||
public static final NativeCodeLoader<VelocityCipherFactory> cipher = new NativeCodeLoader<>(
|
||||
ImmutableList.of(
|
||||
new NativeCodeLoader.Variant<>(NativeCodeLoader.MACOS,
|
||||
new NativeCodeLoader.Variant<>(NativeConstraints.MACOS,
|
||||
copyAndLoadNative("/macosx/velocity-cipher.dylib"), "mbed TLS (macOS)",
|
||||
NativeVelocityCipher.FACTORY),
|
||||
new NativeCodeLoader.Variant<>(NativeCodeLoader.LINUX,
|
||||
new NativeCodeLoader.Variant<>(NativeConstraints.LINUX,
|
||||
copyAndLoadNative("/linux_x64/velocity-cipher.so"), "mbed TLS (Linux amd64)",
|
||||
NativeVelocityCipher.FACTORY),
|
||||
new NativeCodeLoader.Variant<>(NativeCodeLoader.ALWAYS, () -> {
|
||||
|
@ -17,14 +17,7 @@ public class MinecraftCipherDecoder extends ByteToMessageDecoder {
|
||||
|
||||
@Override
|
||||
protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
|
||||
ByteBuf decrypted = ctx.alloc().buffer(in.readableBytes());
|
||||
try {
|
||||
cipher.process(in, decrypted);
|
||||
out.add(decrypted);
|
||||
} catch (Exception e) {
|
||||
decrypted.release();
|
||||
throw e;
|
||||
}
|
||||
out.add(cipher.process(ctx, in));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren