forked from I2P_Developers/i2p.i2p
I2CP: Add option for forcing gzip on/off per-message
Use option in streaming SYN and CLOSE packets
This commit is contained in:
@ -147,6 +147,10 @@ class PacketQueue implements SendMessageStatusListener, Closeable {
|
|||||||
}
|
}
|
||||||
options.setTagsToSend(sendTags);
|
options.setTagsToSend(sendTags);
|
||||||
options.setTagThreshold(tagThresh);
|
options.setTagThreshold(tagThresh);
|
||||||
|
// CLOSE, RESET, and PING packets unlikely to have a large payload
|
||||||
|
// and most of the rest of the packet is
|
||||||
|
// uncompressible: stream ids, signature
|
||||||
|
options.setGzip(packet.getPayloadSize() > 50);
|
||||||
} else if (packet.isFlagSet(FLAGS_INITIAL_TAGS)) {
|
} else if (packet.isFlagSet(FLAGS_INITIAL_TAGS)) {
|
||||||
if (con != null) {
|
if (con != null) {
|
||||||
if (con.isInbound())
|
if (con.isInbound())
|
||||||
@ -167,6 +171,11 @@ class PacketQueue implements SendMessageStatusListener, Closeable {
|
|||||||
}
|
}
|
||||||
options.setTagsToSend(sendTags);
|
options.setTagsToSend(sendTags);
|
||||||
options.setTagThreshold(tagThresh);
|
options.setTagThreshold(tagThresh);
|
||||||
|
// SYN packets are likely to have compressible payload, even if
|
||||||
|
// conn gzip option is false (e.g. snark bitfield, HTTP headers).
|
||||||
|
// If they don't have a large payload, most of the rest of the packet
|
||||||
|
// is uncompressible: stream ids, destination and signature
|
||||||
|
options.setGzip(packet.getPayloadSize() > 50);
|
||||||
} else {
|
} else {
|
||||||
if (con != null) {
|
if (con != null) {
|
||||||
if (con.isInbound() && con.getLifetime() < 2*60*1000)
|
if (con.isInbound() && con.getLifetime() < 2*60*1000)
|
||||||
|
@ -12,10 +12,15 @@ import net.i2p.data.DateAndFlags;
|
|||||||
* Static methods are for OutboundClientMessageOneShotJob to decode the
|
* Static methods are for OutboundClientMessageOneShotJob to decode the
|
||||||
* flags field on the router side.
|
* flags field on the router side.
|
||||||
*
|
*
|
||||||
|
* GzipOption flags are as of 0.9.36, are client-side only, and are
|
||||||
|
* not included in the flags field or sent to the router.
|
||||||
|
*
|
||||||
* @since 0.9.2
|
* @since 0.9.2
|
||||||
*/
|
*/
|
||||||
public class SendMessageOptions extends DateAndFlags {
|
public class SendMessageOptions extends DateAndFlags {
|
||||||
|
|
||||||
|
private GzipOption _gzip = GzipOption.DEFAULT;
|
||||||
|
|
||||||
/** all subject to change */
|
/** all subject to change */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -205,4 +210,33 @@ public class SendMessageOptions extends DateAndFlags {
|
|||||||
return Reliability.DEFAULT;
|
return Reliability.DEFAULT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Overrides i2cp.gzip session option and size threshold
|
||||||
|
* for this message only.
|
||||||
|
*
|
||||||
|
* @since 0.9.36
|
||||||
|
*/
|
||||||
|
public enum GzipOption { DEFAULT, GZIP_OFF, GZIP_ON }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Overrides i2cp.gzip session option and size threshold
|
||||||
|
* for this message only.
|
||||||
|
*
|
||||||
|
* @return non-null, DEFAULT unless setGzip() was called
|
||||||
|
* @since 0.9.36
|
||||||
|
*/
|
||||||
|
public GzipOption getGzip() {
|
||||||
|
return _gzip;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Overrides i2cp.gzip session option and size threshold
|
||||||
|
* for this message only.
|
||||||
|
*
|
||||||
|
* @since 0.9.36
|
||||||
|
*/
|
||||||
|
public void setGzip(boolean yes) {
|
||||||
|
_gzip = yes? GzipOption.GZIP_ON : GzipOption.GZIP_OFF;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -217,7 +217,7 @@ class I2PSessionMuxedImpl extends I2PSessionImpl2 {
|
|||||||
SessionKey keyUsed, Set<SessionTag> tagsSent, long expires,
|
SessionKey keyUsed, Set<SessionTag> tagsSent, long expires,
|
||||||
int proto, int fromPort, int toPort, int flags)
|
int proto, int fromPort, int toPort, int flags)
|
||||||
throws I2PSessionException {
|
throws I2PSessionException {
|
||||||
payload = prepPayload(payload, offset, size, proto, fromPort, toPort);
|
payload = prepPayload(payload, offset, size, proto, fromPort, toPort, SendMessageOptions.GzipOption.DEFAULT);
|
||||||
if (_noEffort)
|
if (_noEffort)
|
||||||
return sendNoEffort(dest, payload, expires, flags);
|
return sendNoEffort(dest, payload, expires, flags);
|
||||||
else
|
else
|
||||||
@ -242,7 +242,7 @@ class I2PSessionMuxedImpl extends I2PSessionImpl2 {
|
|||||||
@Override
|
@Override
|
||||||
public boolean sendMessage(Destination dest, byte[] payload, int offset, int size,
|
public boolean sendMessage(Destination dest, byte[] payload, int offset, int size,
|
||||||
int proto, int fromPort, int toPort, SendMessageOptions options) throws I2PSessionException {
|
int proto, int fromPort, int toPort, SendMessageOptions options) throws I2PSessionException {
|
||||||
payload = prepPayload(payload, offset, size, proto, fromPort, toPort);
|
payload = prepPayload(payload, offset, size, proto, fromPort, toPort, options.getGzip());
|
||||||
//if (_noEffort) {
|
//if (_noEffort) {
|
||||||
sendNoEffort(dest, payload, options);
|
sendNoEffort(dest, payload, options);
|
||||||
return true;
|
return true;
|
||||||
@ -266,7 +266,7 @@ class I2PSessionMuxedImpl extends I2PSessionImpl2 {
|
|||||||
public long sendMessage(Destination dest, byte[] payload, int offset, int size,
|
public long sendMessage(Destination dest, byte[] payload, int offset, int size,
|
||||||
int proto, int fromPort, int toPort,
|
int proto, int fromPort, int toPort,
|
||||||
SendMessageOptions options, SendMessageStatusListener listener) throws I2PSessionException {
|
SendMessageOptions options, SendMessageStatusListener listener) throws I2PSessionException {
|
||||||
payload = prepPayload(payload, offset, size, proto, fromPort, toPort);
|
payload = prepPayload(payload, offset, size, proto, fromPort, toPort, options.getGzip());
|
||||||
long nonce = _sendMessageNonce.incrementAndGet();
|
long nonce = _sendMessageNonce.incrementAndGet();
|
||||||
long expires = Math.max(_context.clock().now() + 60*1000L, options.getTime());
|
long expires = Math.max(_context.clock().now() + 60*1000L, options.getTime());
|
||||||
MessageState state = new MessageState(_context, nonce, this, expires, listener);
|
MessageState state = new MessageState(_context, nonce, this, expires, listener);
|
||||||
@ -279,11 +279,19 @@ class I2PSessionMuxedImpl extends I2PSessionImpl2 {
|
|||||||
* @return gzip compressed payload, ready to send
|
* @return gzip compressed payload, ready to send
|
||||||
* @since 0.9.14
|
* @since 0.9.14
|
||||||
*/
|
*/
|
||||||
private byte[] prepPayload(byte[] payload, int offset, int size, int proto, int fromPort, int toPort) throws I2PSessionException {
|
private byte[] prepPayload(byte[] payload, int offset, int size, int proto,
|
||||||
|
int fromPort, int toPort,
|
||||||
|
SendMessageOptions.GzipOption gzo) throws I2PSessionException {
|
||||||
verifyOpen();
|
verifyOpen();
|
||||||
updateActivity();
|
updateActivity();
|
||||||
|
|
||||||
if (shouldCompress(size))
|
boolean docompress;
|
||||||
|
if (gzo == SendMessageOptions.GzipOption.DEFAULT)
|
||||||
|
docompress = shouldCompress(size);
|
||||||
|
else
|
||||||
|
docompress = gzo == SendMessageOptions.GzipOption.GZIP_ON;
|
||||||
|
|
||||||
|
if (docompress)
|
||||||
payload = DataHelper.compress(payload, offset, size);
|
payload = DataHelper.compress(payload, offset, size);
|
||||||
else
|
else
|
||||||
payload = DataHelper.compress(payload, offset, size, DataHelper.NO_COMPRESSION);
|
payload = DataHelper.compress(payload, offset, size, DataHelper.NO_COMPRESSION);
|
||||||
|
Reference in New Issue
Block a user