* GarlicMessage:

- Put data clove last to speed acks and leaseset store on far end
  - Change release target
  - Javadocs and cleanups
This commit is contained in:
zzz
2012-06-24 14:41:50 +00:00
parent e497859587
commit fe53501990
7 changed files with 40 additions and 21 deletions

View File

@@ -88,18 +88,18 @@ public class SessionKeyManager {
/** /**
* How many to send, IF we need to. * How many to send, IF we need to.
* @since 0.9.1 * @since 0.9.2
*/ */
public int getTagsToSend() { return 0; }; public int getTagsToSend() { return 0; };
/** /**
* @since 0.9.1 * @since 0.9.2
*/ */
public int getLowThreshold() { return 0; }; public int getLowThreshold() { return 0; };
/** /**
* @return true if we have less than the threshold or what we have is about to expire * @return true if we have less than the threshold or what we have is about to expire
* @since 0.9.1 * @since 0.9.2
*/ */
public boolean shouldSendTags(PublicKey target, SessionKey key) { public boolean shouldSendTags(PublicKey target, SessionKey key) {
return shouldSendTags(target, key, getLowThreshold()); return shouldSendTags(target, key, getLowThreshold());
@@ -107,7 +107,7 @@ public class SessionKeyManager {
/** /**
* @return true if we have less than the threshold or what we have is about to expire * @return true if we have less than the threshold or what we have is about to expire
* @since 0.9.1 * @since 0.9.2
*/ */
public boolean shouldSendTags(PublicKey target, SessionKey key, int lowThreshold) { return false; } public boolean shouldSendTags(PublicKey target, SessionKey key, int lowThreshold) { return false; }

View File

@@ -147,7 +147,7 @@ public class TransientSessionKeyManager extends SessionKeyManager {
* Use care when adjusting these values. See ConnectionOptions in streaming, * Use care when adjusting these values. See ConnectionOptions in streaming,
* and TransientSessionKeyManager in crypto, for more information. * and TransientSessionKeyManager in crypto, for more information.
* *
* @since 0.9.1 moved from GarlicMessageBuilder to per-SKM config * @since 0.9.2 moved from GarlicMessageBuilder to per-SKM config
*/ */
public static final int DEFAULT_TAGS = 40; public static final int DEFAULT_TAGS = 40;
/** ditto */ /** ditto */
@@ -166,7 +166,7 @@ public class TransientSessionKeyManager extends SessionKeyManager {
/** /**
* @param tagsToSend how many to send at a time, may be lower or higher than lowThreshold. 1-128 * @param tagsToSend how many to send at a time, may be lower or higher than lowThreshold. 1-128
* @param lowThreshold below this, send more. 1-128 * @param lowThreshold below this, send more. 1-128
* @since 0.9.1 * @since 0.9.2
*/ */
public TransientSessionKeyManager(I2PAppContext context, int tagsToSend, int lowThreshold) { public TransientSessionKeyManager(I2PAppContext context, int tagsToSend, int lowThreshold) {
super(context); super(context);
@@ -354,21 +354,21 @@ public class TransientSessionKeyManager extends SessionKeyManager {
/** /**
* How many to send, IF we need to. * How many to send, IF we need to.
* @return the configured value (not adjusted for current available) * @return the configured value (not adjusted for current available)
* @since 0.9.1 * @since 0.9.2
*/ */
@Override @Override
public int getTagsToSend() { return _tagsToSend; }; public int getTagsToSend() { return _tagsToSend; };
/** /**
* @return the configured value * @return the configured value
* @since 0.9.1 * @since 0.9.2
*/ */
@Override @Override
public int getLowThreshold() { return _lowThreshold; }; public int getLowThreshold() { return _lowThreshold; };
/** /**
* @return true if we have less than the threshold or what we have is about to expire * @return true if we have less than the threshold or what we have is about to expire
* @since 0.9.1 * @since 0.9.2
*/ */
@Override @Override
public boolean shouldSendTags(PublicKey target, SessionKey key, int lowThreshold) { public boolean shouldSendTags(PublicKey target, SessionKey key, int lowThreshold) {

View File

@@ -96,7 +96,7 @@ class ClientConnectionRunner {
// e.g. on local access // e.g. on local access
private static final int MAX_MESSAGE_ID = 0x4000000; private static final int MAX_MESSAGE_ID = 0x4000000;
/** @since 0.9.1 */ /** @since 0.9.2 */
private static final String PROP_TAGS = "crypto.tagsToSend"; private static final String PROP_TAGS = "crypto.tagsToSend";
private static final String PROP_THRESH = "crypto.lowTagThreshold"; private static final String PROP_THRESH = "crypto.lowTagThreshold";

View File

@@ -55,6 +55,7 @@ public class GarlicMessageBuilder {
* *
* @param ctx scope * @param ctx scope
* @param config how/what to wrap * @param config how/what to wrap
* @throws IllegalArgumentException on error
*/ */
private static GarlicMessage buildMessage(RouterContext ctx, GarlicConfig config) { private static GarlicMessage buildMessage(RouterContext ctx, GarlicConfig config) {
Log log = ctx.logManager().getLog(GarlicMessageBuilder.class); Log log = ctx.logManager().getLog(GarlicMessageBuilder.class);
@@ -72,6 +73,7 @@ public class GarlicMessageBuilder {
If non-empty on return you must call skm.tagsDelivered() when sent If non-empty on return you must call skm.tagsDelivered() when sent
and then call skm.tagsAcked() or skm.failTags() later. and then call skm.tagsAcked() or skm.failTags() later.
* @param skm non-null * @param skm non-null
* @throws IllegalArgumentException on error
*/ */
public static GarlicMessage buildMessage(RouterContext ctx, GarlicConfig config, SessionKey wrappedKey, Set<SessionTag> wrappedTags, public static GarlicMessage buildMessage(RouterContext ctx, GarlicConfig config, SessionKey wrappedKey, Set<SessionTag> wrappedTags,
SessionKeyManager skm) { SessionKeyManager skm) {
@@ -99,6 +101,7 @@ public class GarlicMessageBuilder {
Set to zero to disable tag delivery. You must set to zero if you are not Set to zero to disable tag delivery. You must set to zero if you are not
equipped to confirm delivery and call skm.tagsAcked() or skm.failTags() later. equipped to confirm delivery and call skm.tagsAcked() or skm.failTags() later.
* @param skm non-null * @param skm non-null
* @throws IllegalArgumentException on error
*/ */
public static GarlicMessage buildMessage(RouterContext ctx, GarlicConfig config, SessionKey wrappedKey, Set<SessionTag> wrappedTags, public static GarlicMessage buildMessage(RouterContext ctx, GarlicConfig config, SessionKey wrappedKey, Set<SessionTag> wrappedTags,
int numTagsToDeliver, SessionKeyManager skm) { int numTagsToDeliver, SessionKeyManager skm) {
@@ -120,6 +123,7 @@ public class GarlicMessageBuilder {
If this is always 0, it forces ElGamal every time. If this is always 0, it forces ElGamal every time.
* @param lowTagsThreshold the threshold * @param lowTagsThreshold the threshold
* @param skm non-null * @param skm non-null
* @throws IllegalArgumentException on error
*/ */
public static GarlicMessage buildMessage(RouterContext ctx, GarlicConfig config, SessionKey wrappedKey, Set<SessionTag> wrappedTags, public static GarlicMessage buildMessage(RouterContext ctx, GarlicConfig config, SessionKey wrappedKey, Set<SessionTag> wrappedTags,
int numTagsToDeliver, int lowTagsThreshold, SessionKeyManager skm) { int numTagsToDeliver, int lowTagsThreshold, SessionKeyManager skm) {
@@ -173,6 +177,7 @@ public class GarlicMessageBuilder {
* know the encryptKey and encryptTag) * know the encryptKey and encryptTag)
* @param encryptKey sessionKey used to encrypt the current message * @param encryptKey sessionKey used to encrypt the current message
* @param encryptTag sessionTag used to encrypt the current message * @param encryptTag sessionTag used to encrypt the current message
* @throws IllegalArgumentException on error
*/ */
public static GarlicMessage buildMessage(RouterContext ctx, GarlicConfig config, SessionKey wrappedKey, Set<SessionTag> wrappedTags, public static GarlicMessage buildMessage(RouterContext ctx, GarlicConfig config, SessionKey wrappedKey, Set<SessionTag> wrappedTags,
PublicKey target, SessionKey encryptKey, SessionTag encryptTag) { PublicKey target, SessionKey encryptKey, SessionTag encryptTag) {
@@ -219,8 +224,11 @@ public class GarlicMessageBuilder {
****/ ****/
/** /**
* Build an unencrypted set of cloves specified by the config. * Build the unencrypted GarlicMessage specified by the config.
* It contains the number of cloves, followed by each clove,
* followed by a certificate, ID, and expiration date.
* *
* @throws IllegalArgumentException on error
*/ */
private static byte[] buildCloveSet(RouterContext ctx, GarlicConfig config) { private static byte[] buildCloveSet(RouterContext ctx, GarlicConfig config) {
ByteArrayOutputStream baos = null; ByteArrayOutputStream baos = null;
@@ -243,8 +251,6 @@ public class GarlicMessageBuilder {
// See notes below // See notes below
cloves[i] = buildClove(ctx, c); cloves[i] = buildClove(ctx, c);
} }
if (cloves[i] == null)
throw new DataFormatException("Unable to build clove");
} }
int len = 1; int len = 1;
@@ -255,15 +261,15 @@ public class GarlicMessageBuilder {
for (int i = 0; i < cloves.length; i++) for (int i = 0; i < cloves.length; i++)
baos.write(cloves[i]); baos.write(cloves[i]);
} }
if (baos == null)
new ByteArrayOutputStream(16);
config.getCertificate().writeBytes(baos); config.getCertificate().writeBytes(baos);
DataHelper.writeLong(baos, 4, config.getId()); DataHelper.writeLong(baos, 4, config.getId());
DataHelper.writeLong(baos, DataHelper.DATE_LENGTH, config.getExpiration()); DataHelper.writeLong(baos, DataHelper.DATE_LENGTH, config.getExpiration());
} catch (IOException ioe) { } catch (IOException ioe) {
log.error("Error building the clove set", ioe); log.error("Error building the clove set", ioe);
throw new IllegalArgumentException("Error building the clove set", ioe);
} catch (DataFormatException dfe) { } catch (DataFormatException dfe) {
log.error("Error building the clove set", dfe); log.error("Error building the clove set", dfe);
throw new IllegalArgumentException("Error building the clove set", dfe);
} }
return baos.toByteArray(); return baos.toByteArray();
} }

View File

@@ -36,13 +36,20 @@ public class GarlicMessageReceiver {
public void handleClove(DeliveryInstructions instructions, I2NPMessage data); public void handleClove(DeliveryInstructions instructions, I2NPMessage data);
} }
/**
* @param receiver non-null
*/
public GarlicMessageReceiver(RouterContext context, CloveReceiver receiver) { public GarlicMessageReceiver(RouterContext context, CloveReceiver receiver) {
this(context, receiver, null); this(context, receiver, null);
} }
/**
* @param receiver non-null
*/
public GarlicMessageReceiver(RouterContext context, CloveReceiver receiver, Hash clientDestination) { public GarlicMessageReceiver(RouterContext context, CloveReceiver receiver, Hash clientDestination) {
_context = context; _context = context;
_log = context.logManager().getLog(GarlicMessageReceiver.class); _log = context.logManager().getLog(GarlicMessageReceiver.class);
_context.statManager().createRateStat("crypto.garlic.decryptFail", "How often garlic messages are undecryptable", "Encryption", new long[] { 5*60*1000, 60*60*1000, 24*60*60*1000 }); _context.statManager().createRateStat("crypto.garlic.decryptFail", "How often garlic messages are undecryptable", "Encryption", new long[] { 60*60*1000, 24*60*60*1000 });
_clientDestination = clientDestination; _clientDestination = clientDestination;
_parser = new GarlicMessageParser(context); _parser = new GarlicMessageParser(context);
_receiver = receiver; _receiver = receiver;
@@ -94,7 +101,6 @@ public class GarlicMessageReceiver {
_log.warn("Invalid clove " + clove); _log.warn("Invalid clove " + clove);
return; return;
} }
if (_receiver != null)
_receiver.handleClove(clove.getInstructions(), clove.getData()); _receiver.handleClove(clove.getInstructions(), clove.getData());
} }

View File

@@ -90,6 +90,9 @@ class OutboundClientMessageJobHelper {
return msg; return msg;
} }
/**
* @return null on error
*/
private static GarlicConfig createGarlicConfig(RouterContext ctx, long replyToken, long expiration, PublicKey recipientPK, private static GarlicConfig createGarlicConfig(RouterContext ctx, long replyToken, long expiration, PublicKey recipientPK,
PayloadGarlicConfig dataClove, Hash from, Destination dest, TunnelInfo replyTunnel, boolean requireAck, PayloadGarlicConfig dataClove, Hash from, Destination dest, TunnelInfo replyTunnel, boolean requireAck,
LeaseSet bundledReplyLeaseSet) { LeaseSet bundledReplyLeaseSet) {
@@ -98,8 +101,6 @@ class OutboundClientMessageJobHelper {
log.debug("Reply token: " + replyToken); log.debug("Reply token: " + replyToken);
GarlicConfig config = new GarlicConfig(); GarlicConfig config = new GarlicConfig();
config.addClove(dataClove);
if (requireAck) { if (requireAck) {
PayloadGarlicConfig ackClove = buildAckClove(ctx, from, replyTunnel, replyToken, expiration); PayloadGarlicConfig ackClove = buildAckClove(ctx, from, replyTunnel, replyToken, expiration);
if (ackClove == null) if (ackClove == null)
@@ -112,6 +113,11 @@ class OutboundClientMessageJobHelper {
config.addClove(leaseSetClove); config.addClove(leaseSetClove);
} }
// As of 0.9.2, since the receiver processes them in-order,
// put data clove last to speed up the ack,
// and get the leaseset stored before handling the data
config.addClove(dataClove);
DeliveryInstructions instructions = new DeliveryInstructions(); DeliveryInstructions instructions = new DeliveryInstructions();
instructions.setDeliveryMode(DeliveryInstructions.DELIVERY_MODE_LOCAL); instructions.setDeliveryMode(DeliveryInstructions.DELIVERY_MODE_LOCAL);
// defaults // defaults
@@ -137,6 +143,7 @@ class OutboundClientMessageJobHelper {
/** /**
* Build a clove that sends a DeliveryStatusMessage to us * Build a clove that sends a DeliveryStatusMessage to us
* @return null on error
*/ */
private static PayloadGarlicConfig buildAckClove(RouterContext ctx, Hash from, TunnelInfo replyToTunnel, long replyToken, long expiration) { private static PayloadGarlicConfig buildAckClove(RouterContext ctx, Hash from, TunnelInfo replyToTunnel, long replyToken, long expiration) {
Log log = ctx.logManager().getLog(OutboundClientMessageJobHelper.class); Log log = ctx.logManager().getLog(OutboundClientMessageJobHelper.class);

View File

@@ -78,7 +78,7 @@ public class OutboundClientMessageOneShotJob extends JobImpl {
private final static long OVERALL_TIMEOUT_MS_MIN = 8*1000; private final static long OVERALL_TIMEOUT_MS_MIN = 8*1000;
/** /**
* NOTE: Changed as of 0.9.1. * NOTE: Changed as of 0.9.2.
* *
* Defaults to true. * Defaults to true.
* *