I2P Address: [http://git.idk.i2p]

Skip to content
Snippets Groups Projects
Commit b01cf323 authored by zzz's avatar zzz
Browse files

* SendMessageOptions: Increase tag fields to 4 bits and use

                       table lookup for more flexibility
 * Streaming: Use packet type and current window size to adjust
              number of tags sent and tag threshold, to improve
              efficiency and reliability
parent 9ba6c293
No related branches found
No related tags found
No related merge requests found
......@@ -3,6 +3,7 @@ package net.i2p.client.streaming;
import net.i2p.I2PAppContext;
import net.i2p.client.I2PSession;
import net.i2p.client.I2PSessionException;
import net.i2p.client.SendMessageOptions;
import net.i2p.data.ByteArray;
import net.i2p.util.ByteCache;
import net.i2p.util.Log;
......@@ -22,6 +23,16 @@ class PacketQueue {
private final ConnectionManager _connectionManager;
private final ByteCache _cache = ByteCache.getInstance(64, 36*1024);
private static final int FLAGS_INITIAL_TAGS = Packet.FLAG_SYNCHRONIZE;
private static final int FLAGS_FINAL_TAGS = Packet.FLAG_CLOSE |
Packet.FLAG_RESET |
Packet.FLAG_ECHO;
private static final int INITIAL_TAGS_TO_SEND = 32;
private static final int MIN_TAG_THRESHOLD = 20;
private static final int TAG_WINDOW_FACTOR = 5;
private static final int FINAL_TAGS_TO_SEND = 4;
private static final int FINAL_TAG_THRESHOLD = 2;
public PacketQueue(I2PAppContext context, I2PSession session, ConnectionManager mgr) {
_context = context;
_session = session;
......@@ -88,24 +99,34 @@ class PacketQueue {
// we want the router to expire it a little before we do,
// so if we retransmit it will use a new tunnel/lease combo
expires = rpe.getNextSendTime() - 500;
SendMessageOptions options = new SendMessageOptions();
if (expires > 0)
// I2PSessionImpl2
//sent = _session.sendMessage(packet.getTo(), buf, 0, size, keyUsed, tagsSent, expires);
// I2PSessionMuxedImpl
//sent = _session.sendMessage(packet.getTo(), buf, 0, size, keyUsed, tagsSent, expires,
// I2PSession.PROTO_STREAMING, I2PSession.PORT_UNSPECIFIED, I2PSession.PORT_UNSPECIFIED);
// I2PSessionMuxedImpl no tags
sent = _session.sendMessage(packet.getTo(), buf, 0, size, null, null, expires,
I2PSession.PROTO_STREAMING, packet.getLocalPort(), packet.getRemotePort());
else
// I2PSessionImpl2
//sent = _session.sendMessage(packet.getTo(), buf, 0, size, keyUsed, tagsSent, 0);
// I2PSessionMuxedImpl
//sent = _session.sendMessage(packet.getTo(), buf, 0, size, keyUsed, tagsSent,
// I2PSession.PROTO_STREAMING, I2PSession.PORT_UNSPECIFIED, I2PSession.PORT_UNSPECIFIED);
// I2PSessionMuxedImpl no tags
sent = _session.sendMessage(packet.getTo(), buf, 0, size, null, null,
I2PSession.PROTO_STREAMING, packet.getLocalPort(), packet.getRemotePort());
options.setDate(expires);
if (packet.isFlagSet(FLAGS_INITIAL_TAGS)) {
Connection con = packet.getConnection();
if (con != null && con.isInbound())
options.setSendLeaseSet(false);
options.setTagsToSend(INITIAL_TAGS_TO_SEND);
options.setTagThreshold(MIN_TAG_THRESHOLD);
} else if (packet.isFlagSet(FLAGS_FINAL_TAGS)) {
options.setSendLeaseSet(false);
options.setTagsToSend(FINAL_TAGS_TO_SEND);
options.setTagThreshold(FINAL_TAG_THRESHOLD);
} else {
Connection con = packet.getConnection();
if (con != null) {
if (con.isInbound() && con.getLifetime() < 2*60*1000)
options.setSendLeaseSet(false);
// increase threshold with higher window sizes to prevent stalls
// after tag delivery failure
int wdw = con.getOptions().getWindowSize();
int thresh = Math.max(MIN_TAG_THRESHOLD, wdw * TAG_WINDOW_FACTOR);
options.setTagThreshold(thresh);
}
}
sent = _session.sendMessage(packet.getTo(), buf, 0, size,
I2PSession.PROTO_STREAMING, packet.getLocalPort(), packet.getRemotePort(),
options);
end = _context.clock().now();
if ( (end-begin > 1000) && (_log.shouldLog(Log.WARN)) )
......
......@@ -21,39 +21,32 @@ public class SendMessageOptions extends DateAndFlags {
/**
* 1 means don't send, 0 means default
*/
private static final int LS_MASK = 0x0001;
private static final int LS_MASK = 0x0100;
/**
* Tags to send field:
*<pre>
* 000 - default
* 001 - 2
* 010 - 4
* 011 - 8
* 100 - 16
* 101 - 32
* 110 - 64
* 111 - 128
*</pre>
* see below for possible values
*/
private static final int TAGS_SEND_MASK = 0x000e;
private static final int MAX_SEND_TAGS = 128;
private static final int TAGS_SEND_MASK = 0x000f;
/**
* Possible values. Configured values will be rounded down.
* Note that ElGamalAESEngine enforces a max of 200 on receive.
*/
private static final int[] TAGS_SEND = {
0, 2, 4, 6, 8, 12, 16, 24,
32, 40, 51, 64, 80, 100, 125, 160
};
/**
* Tags threshold field:
*<pre>
* 000 - default
* 001 - 1
* 010 - 2
* 011 - 4
* 100 - 8
* 101 - 16
* 110 - 32
* 111 - 64
*</pre>
* see below for possible values
*/
private static final int TAGS_REQD_MASK = 0x0070;
private static final int MAX_REQD_TAGS = 64;
private static final int TAGS_REQD_MASK = 0x00f0;
/** Possible values. Configured values will be rounded down. */
private static final int[] TAGS_REQD = {
0, 2, 3, 6, 9, 14, 20, 27,
35, 45, 57, 72, 92, 117, 147, 192
};
/** default true */
public void setSendLeaseSet(boolean yes) {
......@@ -76,19 +69,19 @@ public class SendMessageOptions extends DateAndFlags {
/**
* If we are low on tags, send this many.
* Power of 2 recommended - rounds down.
* default 0, meaning unset
* default 0, meaning unset, use the SKM config (default 40)
* @param tags 0 or 2 to 128
*/
public void setTagsToSend(int tags) {
if (tags < 0)
throw new IllegalArgumentException();
_flags &= ~TAGS_SEND_MASK;
_flags |= linToExp(Math.min(tags, MAX_SEND_TAGS) / 2) << 1;
_flags |= valToCode(tags, TAGS_SEND);
}
/**
* If we are low on tags, send this many.
* @return default 0, meaning unset
* @return default 0, meaning unset, use the SKM config (default 40)
*/
public int getTagsToSend() {
return getTagsToSend(_flags);
......@@ -96,29 +89,29 @@ public class SendMessageOptions extends DateAndFlags {
/**
* If we are low on tags, send this many.
* @return default 0, meaning unset
* @return default 0, meaning unset, use the SKM config (default 40)
*/
public static int getTagsToSend(int flags) {
int exp = (flags & TAGS_SEND_MASK) >> 1;
return 2 * expToLin(exp);
int exp = (flags & TAGS_SEND_MASK);
return codeToVal(exp, TAGS_SEND);
}
/**
* Low tag threshold. If less than this many, send more.
* Power of 2 recommended - rounds down.
* default 0, meaning unset
* @param tags 0 to 64
* default 0, meaning unset, use the SKM config (default 30)
* @param tags 0 to 90
*/
public void setTagThreshold(int tags) {
if (tags < 0)
throw new IllegalArgumentException();
_flags &= ~TAGS_REQD_MASK;
_flags |= linToExp(Math.min(tags, MAX_REQD_TAGS)) << 4;
_flags |= valToCode(tags, TAGS_REQD) << 4;
}
/**
* Low tag threshold. If less than this many, send more.
* @return default 0, meaning unset
* @return default 0, meaning unset, use the SKM config (default 30)
*/
public int getTagThreshold() {
return getTagThreshold(_flags);
......@@ -126,26 +119,26 @@ public class SendMessageOptions extends DateAndFlags {
/**
* Low tag threshold. If less than this many, send more.
* @return default 0, meaning unset
* @return default 0, meaning unset, use the SKM config (default 30)
*/
public static int getTagThreshold(int flags) {
int exp = (flags & TAGS_REQD_MASK) >> 4;
return expToLin(exp);
return codeToVal(exp, TAGS_REQD);
}
/** rounds down */
private static int linToExp(int lin) {
int exp = 0;
while (lin > 0) {
exp++;
lin >>= 1;
private static int valToCode(int val, int[] codes) {
// special case, round up so we don't turn it into default
if (val > 0 && val <= codes[1])
return 1;
for (int i = 1; i < codes.length; i++) {
if (val < codes[i])
return i - 1;
}
return exp;
return codes.length - 1;
}
private static int expToLin(int exp) {
if (exp <= 0)
return 0;
return 1 << (exp - 1);
private static int codeToVal(int code, int[] codes) {
return codes[code];
}
}
......@@ -38,6 +38,8 @@ public class ElGamalAESEngine {
private final Log _log;
private final static int MIN_ENCRYPTED_SIZE = 80; // smallest possible resulting size
private final I2PAppContext _context;
/** enforced since release 0.6 */
public static final int MAX_TAGS_RECEIVED = 200;
public ElGamalAESEngine(I2PAppContext ctx) {
_context = ctx;
......@@ -328,7 +330,7 @@ public class ElGamalAESEngine {
//ByteArrayInputStream bais = new ByteArrayInputStream(decrypted);
int cur = 0;
long numTags = DataHelper.fromLong(decrypted, cur, 2);
if ((numTags < 0) || (numTags > 200)) throw new Exception("Invalid number of session tags");
if ((numTags < 0) || (numTags > MAX_TAGS_RECEIVED)) throw new Exception("Invalid number of session tags");
if (numTags > 0) tags = new ArrayList((int)numTags);
cur += 2;
//_log.debug("# tags: " + numTags);
......
2012-08-26 zzz
* DataHelper: Trim trailing whitespace when loading properties
* NetDB: Increase floodfills, decrease flood redundancy
* SendMessageOptions: Increase tag fields to 4 bits and use
table lookup for more flexibility
* Streaming: Use packet type and current window size to adjust
number of tags sent and tag threshold, to improve
efficiency and reliability
2012-08-25 kytv
* Dutch and German translation updates from Transifex
* Router console typo fixes (#701)
......
......@@ -18,7 +18,7 @@ public class RouterVersion {
/** deprecated */
public final static String ID = "Monotone";
public final static String VERSION = CoreVersion.VERSION;
public final static long BUILD = 18;
public final static long BUILD = 19;
/** for example "-test" */
public final static String EXTRA = "";
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment