* 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.
* @since 0.9.1
* @since 0.9.2
*/
public int getTagsToSend() { return 0; };
/**
* @since 0.9.1
* @since 0.9.2
*/
public int getLowThreshold() { return 0; };
/**
* @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) {
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
* @since 0.9.1
* @since 0.9.2
*/
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,
* 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;
/** 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 lowThreshold below this, send more. 1-128
* @since 0.9.1
* @since 0.9.2
*/
public TransientSessionKeyManager(I2PAppContext context, int tagsToSend, int lowThreshold) {
super(context);
@@ -354,21 +354,21 @@ public class TransientSessionKeyManager extends SessionKeyManager {
/**
* How many to send, IF we need to.
* @return the configured value (not adjusted for current available)
* @since 0.9.1
* @since 0.9.2
*/
@Override
public int getTagsToSend() { return _tagsToSend; };
/**
* @return the configured value
* @since 0.9.1
* @since 0.9.2
*/
@Override
public int getLowThreshold() { return _lowThreshold; };
/**
* @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
public boolean shouldSendTags(PublicKey target, SessionKey key, int lowThreshold) {

View File

@@ -96,7 +96,7 @@ class ClientConnectionRunner {
// e.g. on local access
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_THRESH = "crypto.lowTagThreshold";

View File

@@ -55,6 +55,7 @@ public class GarlicMessageBuilder {
*
* @param ctx scope
* @param config how/what to wrap
* @throws IllegalArgumentException on error
*/
private static GarlicMessage buildMessage(RouterContext ctx, GarlicConfig config) {
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
and then call skm.tagsAcked() or skm.failTags() later.
* @param skm non-null
* @throws IllegalArgumentException on error
*/
public static GarlicMessage buildMessage(RouterContext ctx, GarlicConfig config, SessionKey wrappedKey, Set<SessionTag> wrappedTags,
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
equipped to confirm delivery and call skm.tagsAcked() or skm.failTags() later.
* @param skm non-null
* @throws IllegalArgumentException on error
*/
public static GarlicMessage buildMessage(RouterContext ctx, GarlicConfig config, SessionKey wrappedKey, Set<SessionTag> wrappedTags,
int numTagsToDeliver, SessionKeyManager skm) {
@@ -120,6 +123,7 @@ public class GarlicMessageBuilder {
If this is always 0, it forces ElGamal every time.
* @param lowTagsThreshold the threshold
* @param skm non-null
* @throws IllegalArgumentException on error
*/
public static GarlicMessage buildMessage(RouterContext ctx, GarlicConfig config, SessionKey wrappedKey, Set<SessionTag> wrappedTags,
int numTagsToDeliver, int lowTagsThreshold, SessionKeyManager skm) {
@@ -173,6 +177,7 @@ public class GarlicMessageBuilder {
* know the encryptKey and encryptTag)
* @param encryptKey sessionKey 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,
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) {
ByteArrayOutputStream baos = null;
@@ -243,8 +251,6 @@ public class GarlicMessageBuilder {
// See notes below
cloves[i] = buildClove(ctx, c);
}
if (cloves[i] == null)
throw new DataFormatException("Unable to build clove");
}
int len = 1;
@@ -255,15 +261,15 @@ public class GarlicMessageBuilder {
for (int i = 0; i < cloves.length; i++)
baos.write(cloves[i]);
}
if (baos == null)
new ByteArrayOutputStream(16);
config.getCertificate().writeBytes(baos);
DataHelper.writeLong(baos, 4, config.getId());
DataHelper.writeLong(baos, DataHelper.DATE_LENGTH, config.getExpiration());
} catch (IOException ioe) {
log.error("Error building the clove set", ioe);
throw new IllegalArgumentException("Error building the clove set", ioe);
} catch (DataFormatException dfe) {
log.error("Error building the clove set", dfe);
throw new IllegalArgumentException("Error building the clove set", dfe);
}
return baos.toByteArray();
}

View File

@@ -36,13 +36,20 @@ public class GarlicMessageReceiver {
public void handleClove(DeliveryInstructions instructions, I2NPMessage data);
}
/**
* @param receiver non-null
*/
public GarlicMessageReceiver(RouterContext context, CloveReceiver receiver) {
this(context, receiver, null);
}
/**
* @param receiver non-null
*/
public GarlicMessageReceiver(RouterContext context, CloveReceiver receiver, Hash clientDestination) {
_context = context;
_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;
_parser = new GarlicMessageParser(context);
_receiver = receiver;
@@ -94,8 +101,7 @@ public class GarlicMessageReceiver {
_log.warn("Invalid clove " + clove);
return;
}
if (_receiver != null)
_receiver.handleClove(clove.getInstructions(), clove.getData());
_receiver.handleClove(clove.getInstructions(), clove.getData());
}
private boolean isValid(GarlicClove clove) {

View File

@@ -90,6 +90,9 @@ class OutboundClientMessageJobHelper {
return msg;
}
/**
* @return null on error
*/
private static GarlicConfig createGarlicConfig(RouterContext ctx, long replyToken, long expiration, PublicKey recipientPK,
PayloadGarlicConfig dataClove, Hash from, Destination dest, TunnelInfo replyTunnel, boolean requireAck,
LeaseSet bundledReplyLeaseSet) {
@@ -98,8 +101,6 @@ class OutboundClientMessageJobHelper {
log.debug("Reply token: " + replyToken);
GarlicConfig config = new GarlicConfig();
config.addClove(dataClove);
if (requireAck) {
PayloadGarlicConfig ackClove = buildAckClove(ctx, from, replyTunnel, replyToken, expiration);
if (ackClove == null)
@@ -112,6 +113,11 @@ class OutboundClientMessageJobHelper {
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();
instructions.setDeliveryMode(DeliveryInstructions.DELIVERY_MODE_LOCAL);
// defaults
@@ -137,6 +143,7 @@ class OutboundClientMessageJobHelper {
/**
* 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) {
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;
/**
* NOTE: Changed as of 0.9.1.
* NOTE: Changed as of 0.9.2.
*
* Defaults to true.
*