Split natives. Add proper disposal for natives.

This commit is contained in:
Andrew Steinborn
2018-08-01 00:20:39 -04:00
parent 284a2a67a2
commit 22dd4bbb99
15 changed files with 56 additions and 20 deletions

8
native/build.gradle Normal file
View File

@@ -0,0 +1,8 @@
plugins {
id 'java'
}
dependencies {
compile "com.google.guava:guava:${guavaVersion}"
compile "io.netty:netty-buffer:${nettyVersion}"
}

View File

@@ -0,0 +1,13 @@
package com.velocitypowered.natives;
/**
* This marker interface indicates that this object should be explicitly disposed before the object can no longer be used.
* Not disposing these objects will likely leak native resources and eventually lead to resource exhaustion.
*/
public interface Disposable {
/**
* Disposes this object. After this call returns, any use of this object becomes invalid. Multiple calls to
* this function should be safe: there should be no side-effects once an object is disposed.
*/
void dispose();
}

View File

@@ -0,0 +1,59 @@
package com.velocitypowered.natives.compression;
import com.google.common.base.Preconditions;
import io.netty.buffer.ByteBuf;
import java.util.zip.DataFormatException;
import java.util.zip.Deflater;
import java.util.zip.Inflater;
public class JavaVelocityCompressor implements VelocityCompressor {
private final Deflater deflater;
private final Inflater inflater;
private final byte[] buf;
private boolean disposed = false;
public JavaVelocityCompressor() {
this.deflater = new Deflater();
this.inflater = new Inflater();
this.buf = new byte[8192];
}
@Override
public void inflate(ByteBuf source, ByteBuf destination) throws DataFormatException {
ensureNotDisposed();
byte[] inData = new byte[source.readableBytes()];
source.readBytes(inData);
inflater.setInput(inData);
while (!inflater.finished()) {
int read = inflater.inflate(buf);
destination.writeBytes(buf, 0, read);
}
inflater.reset();
}
@Override
public void deflate(ByteBuf source, ByteBuf destination) throws DataFormatException {
ensureNotDisposed();
byte[] inData = new byte[source.readableBytes()];
source.readBytes(inData);
deflater.setInput(inData);
deflater.finish();
while (!deflater.finished()) {
int bytes = deflater.deflate(buf);
destination.writeBytes(buf, 0, bytes);
}
deflater.reset();
}
@Override
public void dispose() {
disposed = true;
}
private void ensureNotDisposed() {
Preconditions.checkState(!disposed, "Object already disposed");
}
}

View File

@@ -0,0 +1,12 @@
package com.velocitypowered.natives.compression;
import com.velocitypowered.natives.Disposable;
import io.netty.buffer.ByteBuf;
import java.util.zip.DataFormatException;
public interface VelocityCompressor extends Disposable {
void inflate(ByteBuf source, ByteBuf destination) throws DataFormatException;
void deflate(ByteBuf source, ByteBuf destination) throws DataFormatException;
}

View File

@@ -0,0 +1,42 @@
package com.velocitypowered.natives.encryption;
import com.google.common.base.Preconditions;
import io.netty.buffer.ByteBuf;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.ShortBufferException;
import javax.crypto.spec.IvParameterSpec;
import java.security.GeneralSecurityException;
public class JavaVelocityCipher implements VelocityCipher {
private final Cipher cipher;
private boolean disposed = false;
public JavaVelocityCipher(boolean encrypt, SecretKey key) throws GeneralSecurityException {
this.cipher = Cipher.getInstance("AES/CFB8/NoPadding");
this.cipher.init(encrypt ? Cipher.ENCRYPT_MODE : Cipher.DECRYPT_MODE, key, new IvParameterSpec(key.getEncoded()));
}
@Override
public void process(ByteBuf source, ByteBuf destination) throws ShortBufferException {
ensureNotDisposed();
byte[] sourceAsBytes = new byte[source.readableBytes()];
source.readBytes(sourceAsBytes);
int outputSize = cipher.getOutputSize(sourceAsBytes.length);
byte[] destinationBytes = new byte[outputSize];
cipher.update(sourceAsBytes, 0, sourceAsBytes.length, destinationBytes);
destination.writeBytes(destinationBytes);
}
@Override
public void dispose() {
disposed = true;
}
private void ensureNotDisposed() {
Preconditions.checkState(!disposed, "Object already disposed");
}
}

View File

@@ -0,0 +1,10 @@
package com.velocitypowered.natives.encryption;
import com.velocitypowered.natives.Disposable;
import io.netty.buffer.ByteBuf;
import javax.crypto.ShortBufferException;
public interface VelocityCipher extends Disposable {
void process(ByteBuf source, ByteBuf destination) throws ShortBufferException;
}