mirror of
https://github.com/hierynomus/sshj.git
synced 2025-12-06 15:20:54 +03:00
compression cleanups
This commit is contained in:
@@ -74,7 +74,7 @@ abstract class Converter {
|
|||||||
this.mac = mac;
|
this.mac = mac;
|
||||||
this.compression = compression;
|
this.compression = compression;
|
||||||
if (compression != null)
|
if (compression != null)
|
||||||
compression.init(getCompressionType(), -1);
|
compression.init(getCompressionType());
|
||||||
this.cipherSize = cipher.getIVSize();
|
this.cipherSize = cipher.getIVSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -86,6 +86,6 @@ abstract class Converter {
|
|||||||
return compression != null && (authed || !compression.isDelayed());
|
return compression != null && (authed || !compression.isDelayed());
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract Compression.Type getCompressionType();
|
abstract Compression.Mode getCompressionType();
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -199,8 +199,8 @@ final class Decoder
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
Compression.Type getCompressionType() {
|
Compression.Mode getCompressionType() {
|
||||||
return Compression.Type.Inflater;
|
return Compression.Mode.INFLATE;
|
||||||
}
|
}
|
||||||
|
|
||||||
int getMaxPacketLength() {
|
int getMaxPacketLength() {
|
||||||
|
|||||||
@@ -160,9 +160,8 @@ final class Encoder
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
Compression.Type getCompressionType() {
|
Compression.Mode getCompressionType() {
|
||||||
return Compression.Type.Deflater;
|
return Compression.Mode.DEFLATE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -35,34 +35,26 @@
|
|||||||
*/
|
*/
|
||||||
package net.schmizz.sshj.transport.compression;
|
package net.schmizz.sshj.transport.compression;
|
||||||
|
|
||||||
import net.schmizz.sshj.common.SSHPacket;
|
import net.schmizz.sshj.common.Buffer;
|
||||||
import net.schmizz.sshj.transport.TransportException;
|
import net.schmizz.sshj.transport.TransportException;
|
||||||
|
|
||||||
/** Interface used to compress the stream of data between the SSH server and clients. */
|
/** Interface used to compress the stream of data between the SSH server and clients. */
|
||||||
public interface Compression {
|
public interface Compression {
|
||||||
|
|
||||||
/** Enum identifying if this object will be used to compress or uncompress data. */
|
/** Enum identifying if this object will be used to compress or uncompress data. */
|
||||||
enum Type {
|
enum Mode {
|
||||||
Inflater,
|
INFLATE,
|
||||||
Deflater
|
DEFLATE
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Compress the given buffer in place.
|
|
||||||
*
|
|
||||||
* @param buffer the buffer containing the data to compress s
|
|
||||||
*/
|
|
||||||
void compress(SSHPacket buffer);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize this object to either compress or uncompress data. This method must be called prior to any calls to
|
* Initialize this object to either compress or uncompress data. This method must be called prior to any calls to
|
||||||
* either <code>compress</code> or <code>uncompress</code>. Once the object has been initialized, only one of
|
* either <code>compress</code> or <code>uncompress</code>. Once the object has been initialized, only one of
|
||||||
* <code>compress</code> or <code>uncompress</code> method can be called.
|
* <code>compress</code> or <code>uncompress</code> method can be called.
|
||||||
*
|
*
|
||||||
* @param type
|
* @param mode
|
||||||
* @param level
|
|
||||||
*/
|
*/
|
||||||
void init(Type type, int level);
|
void init(Mode mode);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Delayed compression is an Open-SSH specific feature which informs both the client and server to not compress data
|
* Delayed compression is an Open-SSH specific feature which informs both the client and server to not compress data
|
||||||
@@ -72,13 +64,22 @@ public interface Compression {
|
|||||||
*/
|
*/
|
||||||
boolean isDelayed();
|
boolean isDelayed();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compress the given buffer in place.
|
||||||
|
*
|
||||||
|
* @param buffer the buffer containing the data to compress s
|
||||||
|
*/
|
||||||
|
void compress(Buffer buffer);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Uncompress the data in a buffer into another buffer.
|
* Uncompress the data in a buffer into another buffer.
|
||||||
*
|
*
|
||||||
* @param from the buffer containing the data to uncompress
|
* @param from the buffer containing the data to uncompress
|
||||||
* @param to the buffer receiving the uncompressed data
|
* @param to the buffer receiving the uncompressed data
|
||||||
|
*
|
||||||
|
* @throws TransportException
|
||||||
*/
|
*/
|
||||||
void uncompress(SSHPacket from, SSHPacket to)
|
void uncompress(Buffer from, Buffer to)
|
||||||
throws TransportException;
|
throws TransportException;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,8 +37,8 @@ package net.schmizz.sshj.transport.compression;
|
|||||||
|
|
||||||
import com.jcraft.jzlib.JZlib;
|
import com.jcraft.jzlib.JZlib;
|
||||||
import com.jcraft.jzlib.ZStream;
|
import com.jcraft.jzlib.ZStream;
|
||||||
|
import net.schmizz.sshj.common.Buffer;
|
||||||
import net.schmizz.sshj.common.DisconnectReason;
|
import net.schmizz.sshj.common.DisconnectReason;
|
||||||
import net.schmizz.sshj.common.SSHPacket;
|
|
||||||
import net.schmizz.sshj.common.SSHRuntimeException;
|
import net.schmizz.sshj.common.SSHRuntimeException;
|
||||||
import net.schmizz.sshj.transport.TransportException;
|
import net.schmizz.sshj.transport.TransportException;
|
||||||
|
|
||||||
@@ -58,64 +58,65 @@ public class ZlibCompression
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static private final int BUF_SIZE = 4096;
|
private static final int BUF_SIZE = 4096;
|
||||||
|
|
||||||
|
private final byte[] tempBuf = new byte[BUF_SIZE];
|
||||||
|
|
||||||
private ZStream stream;
|
private ZStream stream;
|
||||||
private final byte[] tmpbuf = new byte[BUF_SIZE];
|
|
||||||
|
|
||||||
/** Create a new instance of a ZLib base compression */
|
public void init(Mode mode) {
|
||||||
public ZlibCompression() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public void compress(SSHPacket buffer) {
|
|
||||||
stream.next_in = buffer.array();
|
|
||||||
stream.next_in_index = buffer.rpos();
|
|
||||||
stream.avail_in = buffer.available();
|
|
||||||
buffer.wpos(buffer.rpos());
|
|
||||||
do {
|
|
||||||
stream.next_out = tmpbuf;
|
|
||||||
stream.next_out_index = 0;
|
|
||||||
stream.avail_out = BUF_SIZE;
|
|
||||||
int status = stream.deflate(JZlib.Z_PARTIAL_FLUSH);
|
|
||||||
switch (status) {
|
|
||||||
case JZlib.Z_OK:
|
|
||||||
buffer.putRawBytes(tmpbuf, 0, BUF_SIZE - stream.avail_out);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
throw new SSHRuntimeException("compress: deflate returned " + status);
|
|
||||||
}
|
|
||||||
} while (stream.avail_out == 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void init(Type type, int level) {
|
|
||||||
stream = new ZStream();
|
stream = new ZStream();
|
||||||
if (type == Type.Deflater)
|
switch (mode) {
|
||||||
stream.deflateInit(level);
|
case DEFLATE:
|
||||||
else
|
stream.deflateInit(JZlib.Z_DEFAULT_COMPRESSION);
|
||||||
stream.inflateInit();
|
break;
|
||||||
|
case INFLATE:
|
||||||
|
stream.inflateInit();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
assert false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isDelayed() {
|
public boolean isDelayed() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void uncompress(SSHPacket from, SSHPacket to)
|
public void compress(Buffer buffer) {
|
||||||
|
stream.next_in = buffer.array();
|
||||||
|
stream.next_in_index = buffer.rpos();
|
||||||
|
stream.avail_in = buffer.available();
|
||||||
|
buffer.wpos(buffer.rpos());
|
||||||
|
do {
|
||||||
|
stream.next_out = tempBuf;
|
||||||
|
stream.next_out_index = 0;
|
||||||
|
stream.avail_out = BUF_SIZE;
|
||||||
|
final int status = stream.deflate(JZlib.Z_PARTIAL_FLUSH);
|
||||||
|
if (status == JZlib.Z_OK) {
|
||||||
|
buffer.putRawBytes(tempBuf, 0, BUF_SIZE - stream.avail_out);
|
||||||
|
} else {
|
||||||
|
throw new SSHRuntimeException("compress: deflate returned " + status);
|
||||||
|
}
|
||||||
|
} while (stream.avail_out == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void uncompress(Buffer from, Buffer to)
|
||||||
throws TransportException {
|
throws TransportException {
|
||||||
stream.next_in = from.array();
|
stream.next_in = from.array();
|
||||||
stream.next_in_index = from.rpos();
|
stream.next_in_index = from.rpos();
|
||||||
stream.avail_in = from.available();
|
stream.avail_in = from.available();
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
stream.next_out = tmpbuf;
|
stream.next_out = tempBuf;
|
||||||
stream.next_out_index = 0;
|
stream.next_out_index = 0;
|
||||||
stream.avail_out = BUF_SIZE;
|
stream.avail_out = BUF_SIZE;
|
||||||
int status = stream.inflate(JZlib.Z_PARTIAL_FLUSH);
|
final int status = stream.inflate(JZlib.Z_PARTIAL_FLUSH);
|
||||||
switch (status) {
|
switch (status) {
|
||||||
case JZlib.Z_OK:
|
case JZlib.Z_OK:
|
||||||
to.putRawBytes(tmpbuf, 0, BUF_SIZE - stream.avail_out);
|
to.putRawBytes(tempBuf, 0, BUF_SIZE - stream.avail_out);
|
||||||
break;
|
break;
|
||||||
case JZlib.Z_BUF_ERROR:
|
case JZlib.Z_BUF_ERROR:
|
||||||
return; // wtf.. but this works *head spins*
|
return;
|
||||||
default:
|
default:
|
||||||
throw new TransportException(DisconnectReason.COMPRESSION_ERROR, "uncompress: inflate returned "
|
throw new TransportException(DisconnectReason.COMPRESSION_ERROR, "uncompress: inflate returned "
|
||||||
+ status);
|
+ status);
|
||||||
|
|||||||
Reference in New Issue
Block a user