forked from I2P_Developers/i2p.i2p
propagate from branch 'i2p.i2p.zzz.test2' (head 8fa44268a1dd2b7baaf01806e6994281ab031870)
to branch 'i2p.i2p' (head 44afdaa15ce8a95c112c7d58a5908f401c1a0145)
This commit is contained in:
@ -68,7 +68,7 @@ public class DatabaseSearchReplyMessage extends FastI2NPMessageImpl {
|
||||
curIndex += Hash.HASH_LENGTH;
|
||||
//_key = new Hash(keyData);
|
||||
|
||||
int num = (int)DataHelper.fromLong(data, curIndex, 1);
|
||||
int num = data[curIndex] & 0xff;
|
||||
curIndex++;
|
||||
|
||||
_peerHashes.clear();
|
||||
|
@ -209,7 +209,7 @@ public class DeliveryInstructions extends DataStructureImpl {
|
||||
|
||||
public int readBytes(byte data[], int offset) throws DataFormatException {
|
||||
int cur = offset;
|
||||
long flags = DataHelper.fromLong(data, cur, 1);
|
||||
int flags = data[cur] & 0xff;
|
||||
cur++;
|
||||
//if (_log.shouldLog(Log.DEBUG))
|
||||
// _log.debug("Read flags: " + flags + " mode: " + flagMode(flags));
|
||||
|
@ -85,7 +85,7 @@ public abstract class FastI2NPMessageImpl extends I2NPMessageImpl {
|
||||
throw new I2NPMessageException("Payload is too short " + maxLen);
|
||||
int cur = offset;
|
||||
if (type < 0) {
|
||||
type = (int)DataHelper.fromLong(data, cur, 1);
|
||||
type = data[cur] & 0xff;
|
||||
cur++;
|
||||
}
|
||||
_uniqueId = DataHelper.fromLong(data, cur, 4);
|
||||
|
@ -158,7 +158,7 @@ public class GarlicClove extends DataStructureImpl {
|
||||
if (m.length <= 0)
|
||||
throw new RuntimeException("foo, returned 0 length");
|
||||
out.write(m);
|
||||
} catch (Exception e) {
|
||||
} catch (RuntimeException e) {
|
||||
throw new DataFormatException("Unable to write the clove: " + _msg + " to " + out, e);
|
||||
}
|
||||
DataHelper.writeLong(out, 4, _cloveId);
|
||||
@ -187,7 +187,7 @@ public class GarlicClove extends DataStructureImpl {
|
||||
byte m[] = _msg.toByteArray();
|
||||
System.arraycopy(m, 0, rv, offset, m.length);
|
||||
offset += m.length;
|
||||
} catch (Exception e) { throw new RuntimeException("Unable to write: " + _msg + ": " + e.getMessage()); }
|
||||
} catch (RuntimeException e) { throw new RuntimeException("Unable to write: " + _msg + ": " + e.getMessage()); }
|
||||
DataHelper.toLong(rv, offset, 4, _cloveId);
|
||||
offset += 4;
|
||||
DataHelper.toDate(rv, offset, _expiration.getTime());
|
||||
|
@ -59,7 +59,7 @@ public class I2NPMessageHandler {
|
||||
_lastSize = msg.readBytes(in, type, _messageBuffer);
|
||||
} catch (I2NPMessageException ime) {
|
||||
throw ime;
|
||||
} catch (Exception e) {
|
||||
} catch (RuntimeException e) {
|
||||
if (_log.shouldLog(Log.WARN))
|
||||
_log.warn("Error reading the stream", e);
|
||||
throw new I2NPMessageException("Unknown error reading the " + msg.getClass().getSimpleName(), e);
|
||||
@ -109,7 +109,7 @@ public class I2NPMessageHandler {
|
||||
public int readMessage(byte data[], int offset, int maxLen) throws I2NPMessageException {
|
||||
int cur = offset;
|
||||
// we will assume that maxLen is >= 1 here. It's checked to be >= 16 in readBytes()
|
||||
int type = (int)DataHelper.fromLong(data, cur, 1);
|
||||
int type = data[cur] & 0xff;
|
||||
cur++;
|
||||
_lastReadBegin = System.currentTimeMillis();
|
||||
I2NPMessage msg = I2NPMessageImpl.createMessage(_context, type);
|
||||
@ -131,7 +131,7 @@ public class I2NPMessageHandler {
|
||||
cur += _lastSize;
|
||||
} catch (I2NPMessageException ime) {
|
||||
throw ime;
|
||||
} catch (Exception e) {
|
||||
} catch (RuntimeException e) {
|
||||
if (_log.shouldLog(Log.WARN))
|
||||
_log.warn("Error reading the stream", e);
|
||||
throw new I2NPMessageException("Unknown error reading the " + msg.getClass().getSimpleName(), e);
|
||||
|
@ -197,7 +197,7 @@ public abstract class I2NPMessageImpl extends DataStructureImpl implements I2NPM
|
||||
throw new I2NPMessageException("Payload is too short " + maxLen);
|
||||
int cur = offset;
|
||||
if (type < 0) {
|
||||
type = (int)DataHelper.fromLong(data, cur, 1);
|
||||
type = data[cur] & 0xff;
|
||||
cur++;
|
||||
}
|
||||
_uniqueId = DataHelper.fromLong(data, cur, 4);
|
||||
@ -413,7 +413,7 @@ public abstract class I2NPMessageImpl extends DataStructureImpl implements I2NPM
|
||||
*/
|
||||
public static I2NPMessage fromRawByteArray(I2PAppContext ctx, byte buffer[], int offset,
|
||||
int len, I2NPMessageHandler handler) throws I2NPMessageException {
|
||||
int type = (int)DataHelper.fromLong(buffer, offset, 1);
|
||||
int type = buffer[offset] & 0xff;
|
||||
offset++;
|
||||
I2NPMessage msg = createMessage(ctx, type);
|
||||
if (msg == null)
|
||||
|
@ -163,7 +163,7 @@ public class I2NPMessageReader {
|
||||
_log.warn("IO Error handling message", ioe);
|
||||
_listener.disconnected(I2NPMessageReader.this);
|
||||
cancelRunner();
|
||||
} catch (Exception e) {
|
||||
} catch (RuntimeException e) {
|
||||
_log.log(Log.CRIT, "error reading msg!", e);
|
||||
_listener.readError(I2NPMessageReader.this, e);
|
||||
_listener.disconnected(I2NPMessageReader.this);
|
||||
|
@ -29,7 +29,7 @@ public class VariableTunnelBuildMessage extends TunnelBuildMessage {
|
||||
@Override
|
||||
public void readMessage(byte[] data, int offset, int dataSize, int type) throws I2NPMessageException {
|
||||
// message type will be checked in super()
|
||||
int r = (int)DataHelper.fromLong(data, offset, 1);
|
||||
int r = data[offset] & 0xff;
|
||||
if (r <= 0 || r > MAX_RECORD_COUNT)
|
||||
throw new I2NPMessageException("Bad record count " + r);
|
||||
RECORD_COUNT = r;
|
||||
|
@ -31,7 +31,7 @@ public class VariableTunnelBuildReplyMessage extends TunnelBuildReplyMessage {
|
||||
@Override
|
||||
public void readMessage(byte[] data, int offset, int dataSize, int type) throws I2NPMessageException {
|
||||
// message type will be checked in super()
|
||||
int r = (int)DataHelper.fromLong(data, offset, 1);
|
||||
int r = data[offset] & 0xff;
|
||||
if (r <= 0 || r > MAX_RECORD_COUNT)
|
||||
throw new I2NPMessageException("Bad record count " + r);
|
||||
RECORD_COUNT = r;
|
||||
|
@ -724,7 +724,10 @@ public class RouterInfo extends DatabaseEntry {
|
||||
System.err.println("Router info " + args[i] + " is invalid");
|
||||
fail = true;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
} catch (IOException e) {
|
||||
System.err.println("Error reading " + args[i] + ": " + e);
|
||||
fail = true;
|
||||
} catch (DataFormatException e) {
|
||||
System.err.println("Error reading " + args[i] + ": " + e);
|
||||
fail = true;
|
||||
} finally {
|
||||
|
@ -434,7 +434,7 @@ public class InNetMessagePool implements Service {
|
||||
|
||||
} catch (OutOfMemoryError oome) {
|
||||
throw oome;
|
||||
} catch (Exception e) {
|
||||
} catch (RuntimeException e) {
|
||||
if (_log.shouldLog(Log.CRIT))
|
||||
_log.log(Log.CRIT, "Error in the tunnel gateway dispatcher", e);
|
||||
}
|
||||
@ -467,7 +467,7 @@ public class InNetMessagePool implements Service {
|
||||
|
||||
} catch (OutOfMemoryError oome) {
|
||||
throw oome;
|
||||
} catch (Exception e) {
|
||||
} catch (RuntimeException e) {
|
||||
if (_log.shouldLog(Log.CRIT))
|
||||
_log.log(Log.CRIT, "Error in the tunnel data dispatcher", e);
|
||||
}
|
||||
|
@ -16,7 +16,7 @@ import net.i2p.util.Clock;
|
||||
*
|
||||
* For use by the router only. Not to be used by applications or plugins.
|
||||
*/
|
||||
public class JobTiming implements Clock.ClockUpdateListener, RouterClock.ClockShiftListener {
|
||||
public class JobTiming implements Clock.ClockUpdateListener {
|
||||
private volatile long _start;
|
||||
private volatile long _actualStart;
|
||||
private volatile long _actualEnd;
|
||||
@ -82,8 +82,4 @@ public class JobTiming implements Clock.ClockUpdateListener, RouterClock.ClockSh
|
||||
if (_actualEnd != 0)
|
||||
_actualEnd += delta;
|
||||
}
|
||||
|
||||
public void clockShift(long delta) {
|
||||
offsetChanged(delta);
|
||||
}
|
||||
}
|
||||
|
@ -9,6 +9,7 @@ package net.i2p.router;
|
||||
*/
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
@ -648,7 +649,7 @@ public class Router implements RouterClock.ClockShiftListener {
|
||||
//else
|
||||
// System.err.println("WARNING: Configuration file " + filename + " does not exist");
|
||||
}
|
||||
} catch (Exception ioe) {
|
||||
} catch (IOException ioe) {
|
||||
if (log != null)
|
||||
log.error("Error loading the router configuration from " + filename, ioe);
|
||||
else
|
||||
@ -1351,7 +1352,7 @@ public class Router implements RouterClock.ClockShiftListener {
|
||||
ordered.putAll(_config);
|
||||
DataHelper.storeProps(ordered, new File(_configFilename));
|
||||
}
|
||||
} catch (Exception ioe) {
|
||||
} catch (IOException ioe) {
|
||||
// warning, _log will be null when called from constructor
|
||||
if (_log != null)
|
||||
_log.error("Error saving the config to " + _configFilename, ioe);
|
||||
|
@ -8,6 +8,7 @@ import java.util.Map;
|
||||
|
||||
import net.i2p.data.Hash;
|
||||
import net.i2p.data.i2np.I2NPMessage;
|
||||
import net.i2p.data.i2np.I2NPMessageException;
|
||||
import net.i2p.data.i2np.I2NPMessageHandler;
|
||||
import net.i2p.router.CommSystemFacade;
|
||||
import net.i2p.router.JobImpl;
|
||||
@ -121,7 +122,7 @@ public class VMCommSystem extends CommSystemFacade {
|
||||
ReceiveJob.this.getContext().statManager().addRateData("transport.receiveMessageLarge", 1, 1);
|
||||
|
||||
_ctx.inNetMessagePool().add(msg, null, _from);
|
||||
} catch (Exception e) {
|
||||
} catch (I2NPMessageException e) {
|
||||
_log.error("Error reading/formatting a VM message? Something is not right...", e);
|
||||
}
|
||||
}
|
||||
|
@ -75,7 +75,7 @@ public class GarlicMessageParser {
|
||||
private CloveSet readCloveSet(byte data[]) throws DataFormatException {
|
||||
int offset = 0;
|
||||
|
||||
int numCloves = (int)DataHelper.fromLong(data, offset, 1);
|
||||
int numCloves = data[offset] & 0xff;
|
||||
offset++;
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("# cloves to read: " + numCloves);
|
||||
|
@ -949,15 +949,19 @@ public class OutboundClientMessageOneShotJob extends JobImpl {
|
||||
if (_outTunnel.getLength() > 0)
|
||||
size = ((size + 1023) / 1024) * 1024; // messages are in ~1KB blocks
|
||||
|
||||
for (int i = 0; i < _outTunnel.getLength(); i++) {
|
||||
// skip ourselves at first hop
|
||||
for (int i = 1; i < _outTunnel.getLength(); i++) {
|
||||
getContext().profileManager().tunnelTestSucceeded(_outTunnel.getPeer(i), sendTime);
|
||||
getContext().profileManager().tunnelDataPushed(_outTunnel.getPeer(i), sendTime, size);
|
||||
}
|
||||
_outTunnel.incrementVerifiedBytesTransferred(size);
|
||||
}
|
||||
if (_inTunnel != null)
|
||||
for (int i = 0; i < _inTunnel.getLength(); i++)
|
||||
if (_inTunnel != null) {
|
||||
// skip ourselves at last hop
|
||||
for (int i = 0; i < _inTunnel.getLength() - 1; i++) {
|
||||
getContext().profileManager().tunnelTestSucceeded(_inTunnel.getPeer(i), sendTime);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void setMessage(I2NPMessage msg) {}
|
||||
|
@ -543,7 +543,7 @@ public class PersistentDataStore extends TransientDataStore {
|
||||
if (_log.shouldLog(Log.INFO))
|
||||
_log.info("Unable to read the router reference in " + _routerFile.getName(), ioe);
|
||||
corrupt = true;
|
||||
} catch (Exception e) {
|
||||
} catch (RuntimeException e) {
|
||||
// key certificate problems, etc., don't let one bad RI kill the whole thing
|
||||
if (_log.shouldLog(Log.INFO))
|
||||
_log.info("Unable to read the router reference in " + _routerFile.getName(), e);
|
||||
@ -666,7 +666,7 @@ public class PersistentDataStore extends TransientDataStore {
|
||||
return null;
|
||||
Hash h = Hash.create(b);
|
||||
return h;
|
||||
} catch (Exception e) {
|
||||
} catch (RuntimeException e) {
|
||||
// static
|
||||
//_log.warn("Unable to fetch the key from [" + filename + "]", e);
|
||||
return null;
|
||||
|
@ -3,7 +3,7 @@ package net.i2p.router.networkdb.reseed;
|
||||
import java.io.File;
|
||||
import java.io.InputStream;
|
||||
import java.io.IOException;
|
||||
import java.net.URL;
|
||||
import java.net.URI;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
import net.i2p.data.DataHelper;
|
||||
@ -131,7 +131,7 @@ public class ReseedChecker {
|
||||
* @throws IllegalArgumentException if it doesn't end with zip or su3
|
||||
* @since 0.9.19
|
||||
*/
|
||||
public boolean requestReseed(URL url) throws IllegalArgumentException {
|
||||
public boolean requestReseed(URI url) throws IllegalArgumentException {
|
||||
if (_inProgress.compareAndSet(false, true)) {
|
||||
Reseeder reseeder = new Reseeder(_context, this);
|
||||
try {
|
||||
|
@ -7,10 +7,8 @@ import java.io.FileOutputStream;
|
||||
import java.io.InputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.net.URL;
|
||||
import java.util.Arrays;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
@ -152,7 +150,7 @@ public class Reseeder {
|
||||
* @throws IllegalArgumentException if it doesn't end with zip or su3
|
||||
* @since 0.9.19
|
||||
*/
|
||||
void requestReseed(URL url) throws IllegalArgumentException {
|
||||
void requestReseed(URI url) throws IllegalArgumentException {
|
||||
ReseedRunner reseedRunner = new ReseedRunner(url);
|
||||
// set to daemon so it doesn't hang a shutdown
|
||||
Thread reseed = new I2PAppThread(reseedRunner, "Reseed", true);
|
||||
@ -238,7 +236,7 @@ public class Reseeder {
|
||||
/** bytes per sec for each su3 downloaded */
|
||||
private final List<Long> _bandwidths;
|
||||
private static final int MAX_DATE_SETS = 2;
|
||||
private final URL _url;
|
||||
private final URI _url;
|
||||
|
||||
/**
|
||||
* Start a reseed from the default URL list
|
||||
@ -255,7 +253,7 @@ public class Reseeder {
|
||||
* @throws IllegalArgumentException if it doesn't end with zip or su3
|
||||
* @since 0.9.19
|
||||
*/
|
||||
public ReseedRunner(URL url) throws IllegalArgumentException {
|
||||
public ReseedRunner(URI url) throws IllegalArgumentException {
|
||||
String lc = url.getPath().toLowerCase(Locale.US);
|
||||
if (!(lc.endsWith(".zip") || lc.endsWith(".su3")))
|
||||
throw new IllegalArgumentException("Reseed URL must end with .zip or .su3");
|
||||
@ -411,7 +409,7 @@ public class Reseeder {
|
||||
* @return count of routerinfos successfully fetched, or -1 if no valid URLs
|
||||
*/
|
||||
private int reseed(boolean echoStatus) {
|
||||
List<URL> URLList = new ArrayList<URL>();
|
||||
List<URI> URLList = new ArrayList<URI>();
|
||||
String URLs = _context.getProperty(PROP_RESEED_URL);
|
||||
boolean defaulted = URLs == null;
|
||||
boolean SSLDisable = _context.getBooleanProperty(PROP_SSL_DISABLE);
|
||||
@ -428,29 +426,29 @@ public class Reseeder {
|
||||
if (!u.endsWith("/"))
|
||||
u = u + '/';
|
||||
try {
|
||||
URLList.add(new URL(u));
|
||||
} catch (MalformedURLException mue) {}
|
||||
URLList.add(new URI(u));
|
||||
} catch (URISyntaxException mue) {}
|
||||
}
|
||||
Collections.shuffle(URLList, _context.random());
|
||||
if (!SSLDisable && !SSLRequired) {
|
||||
// put the non-SSL at the end of the SSL
|
||||
List<URL> URLList2 = new ArrayList<URL>();
|
||||
List<URI> URLList2 = new ArrayList<URI>();
|
||||
tok = new StringTokenizer(DEFAULT_SEED_URL, " ,");
|
||||
while (tok.hasMoreTokens()) {
|
||||
String u = tok.nextToken().trim();
|
||||
if (!u.endsWith("/"))
|
||||
u = u + '/';
|
||||
try {
|
||||
URLList2.add(new URL(u));
|
||||
} catch (MalformedURLException mue) {}
|
||||
URLList2.add(new URI(u));
|
||||
} catch (URISyntaxException mue) {}
|
||||
}
|
||||
Collections.shuffle(URLList2, _context.random());
|
||||
URLList.addAll(URLList2);
|
||||
}
|
||||
} else {
|
||||
// custom list given
|
||||
List<URL> SSLList = new ArrayList<URL>();
|
||||
List<URL> nonSSLList = new ArrayList<URL>();
|
||||
List<URI> SSLList = new ArrayList<URI>();
|
||||
List<URI> nonSSLList = new ArrayList<URI>();
|
||||
StringTokenizer tok = new StringTokenizer(URLs, " ,");
|
||||
while (tok.hasMoreTokens()) {
|
||||
// format tokens
|
||||
@ -460,12 +458,12 @@ public class Reseeder {
|
||||
// check if ssl or not then add to respective list
|
||||
if (u.startsWith("https")) {
|
||||
try {
|
||||
SSLList.add(new URL(u));
|
||||
} catch (MalformedURLException mue) {}
|
||||
SSLList.add(new URI(u));
|
||||
} catch (URISyntaxException mue) {}
|
||||
} else {
|
||||
try {
|
||||
nonSSLList.add(new URL(u));
|
||||
} catch (MalformedURLException mue) {}
|
||||
nonSSLList.add(new URI(u));
|
||||
} catch (URISyntaxException mue) {}
|
||||
}
|
||||
}
|
||||
// shuffle lists
|
||||
@ -481,8 +479,8 @@ public class Reseeder {
|
||||
}
|
||||
if (!isSNISupported()) {
|
||||
try {
|
||||
URLList.remove(new URL("https://netdb.i2p2.no/"));
|
||||
} catch (MalformedURLException mue) {}
|
||||
URLList.remove(new URI("https://netdb.i2p2.no/"));
|
||||
} catch (URISyntaxException mue) {}
|
||||
}
|
||||
if (URLList.isEmpty()) {
|
||||
System.out.println("No valid reseed URLs");
|
||||
@ -500,19 +498,19 @@ public class Reseeder {
|
||||
* @param echoStatus apparently always false
|
||||
* @return count of routerinfos successfully fetched
|
||||
*/
|
||||
private int reseed(List<URL> URLList, boolean echoStatus) {
|
||||
private int reseed(List<URI> URLList, boolean echoStatus) {
|
||||
int total = 0;
|
||||
for (int i = 0; i < URLList.size() && _isRunning; i++) {
|
||||
if (_context.router().gracefulShutdownInProgress()) {
|
||||
System.out.println("Reseed aborted, shutdown in progress");
|
||||
return total;
|
||||
}
|
||||
URL url = URLList.get(i);
|
||||
URI url = URLList.get(i);
|
||||
int dl = 0;
|
||||
if (ENABLE_SU3) {
|
||||
try {
|
||||
dl = reseedSU3(new URL(url.toString() + SU3_FILENAME), echoStatus);
|
||||
} catch (MalformedURLException mue) {}
|
||||
dl = reseedSU3(new URI(url.toString() + SU3_FILENAME), echoStatus);
|
||||
} catch (URISyntaxException mue) {}
|
||||
}
|
||||
if (ENABLE_NON_SU3) {
|
||||
if (dl <= 0)
|
||||
@ -556,7 +554,7 @@ public class Reseeder {
|
||||
* @param echoStatus apparently always false
|
||||
* @return count of routerinfos successfully fetched
|
||||
**/
|
||||
private int reseedOne(URL seedURL, boolean echoStatus) {
|
||||
private int reseedOne(URI seedURL, boolean echoStatus) {
|
||||
try {
|
||||
// Don't use context clock as we may be adjusting the time
|
||||
final long timeLimit = System.currentTimeMillis() + MAX_TIME_PER_HOST;
|
||||
@ -627,7 +625,7 @@ public class Reseeder {
|
||||
if (fetched % 60 == 0)
|
||||
System.out.println();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
} catch (RuntimeException e) {
|
||||
if (_log.shouldLog(Log.INFO))
|
||||
_log.info("Failed fetch", e);
|
||||
errors++;
|
||||
@ -658,7 +656,7 @@ public class Reseeder {
|
||||
* @return count of routerinfos successfully fetched
|
||||
* @since 0.9.14
|
||||
**/
|
||||
public int reseedSU3(URL seedURL, boolean echoStatus) {
|
||||
public int reseedSU3(URI seedURL, boolean echoStatus) {
|
||||
return reseedSU3OrZip(seedURL, true, echoStatus);
|
||||
}
|
||||
|
||||
@ -672,7 +670,7 @@ public class Reseeder {
|
||||
* @return count of routerinfos successfully fetched
|
||||
* @since 0.9.19
|
||||
**/
|
||||
public int reseedZip(URL seedURL, boolean echoStatus) {
|
||||
public int reseedZip(URI seedURL, boolean echoStatus) {
|
||||
return reseedSU3OrZip(seedURL, false, echoStatus);
|
||||
}
|
||||
|
||||
@ -686,7 +684,7 @@ public class Reseeder {
|
||||
* @return count of routerinfos successfully fetched
|
||||
* @since 0.9.19
|
||||
**/
|
||||
private int reseedSU3OrZip(URL seedURL, boolean isSU3, boolean echoStatus) {
|
||||
private int reseedSU3OrZip(URI seedURL, boolean isSU3, boolean echoStatus) {
|
||||
int fetched = 0;
|
||||
int errors = 0;
|
||||
File contentRaw = null;
|
||||
@ -868,7 +866,7 @@ public class Reseeder {
|
||||
if (ourHash != null && DataHelper.eq(hash, ourHash.getData()))
|
||||
return false;
|
||||
|
||||
URL url = new URL(seedURL + (seedURL.endsWith("/") ? "" : "/") + ROUTERINFO_PREFIX + peer + ROUTERINFO_SUFFIX);
|
||||
URI url = new URI(seedURL + (seedURL.endsWith("/") ? "" : "/") + ROUTERINFO_PREFIX + peer + ROUTERINFO_SUFFIX);
|
||||
|
||||
byte data[] = readURL(url);
|
||||
if (data == null || data.length <= 0)
|
||||
@ -877,7 +875,7 @@ public class Reseeder {
|
||||
}
|
||||
|
||||
/** @return null on error */
|
||||
private byte[] readURL(URL url) throws IOException {
|
||||
private byte[] readURL(URI url) throws IOException {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream(4*1024);
|
||||
EepGet get;
|
||||
boolean ssl = url.toString().startsWith("https");
|
||||
@ -922,7 +920,7 @@ public class Reseeder {
|
||||
* @return null on error
|
||||
* @since 0.9.14
|
||||
*/
|
||||
private File fetchURL(URL url) throws IOException {
|
||||
private File fetchURL(URI url) throws IOException {
|
||||
File out = new File(_context.getTempDir(), "reseed-" + _context.random().nextInt() + ".tmp");
|
||||
EepGet get;
|
||||
boolean ssl = url.toString().startsWith("https");
|
||||
|
@ -156,6 +156,11 @@ public class ProfileOrganizer {
|
||||
* Blocking if a reorganize is happening.
|
||||
*/
|
||||
public PeerProfile getProfile(Hash peer) {
|
||||
if (peer.equals(_us)) {
|
||||
if (_log.shouldWarn())
|
||||
_log.warn("Who wanted our own profile?", new Exception("I did"));
|
||||
return null;
|
||||
}
|
||||
getReadLock();
|
||||
try {
|
||||
return locked_getProfile(peer);
|
||||
@ -168,6 +173,11 @@ public class ProfileOrganizer {
|
||||
* @since 0.8.12
|
||||
*/
|
||||
public PeerProfile getProfileNonblocking(Hash peer) {
|
||||
if (peer.equals(_us)) {
|
||||
if (_log.shouldWarn())
|
||||
_log.warn("Who wanted our own profile?", new Exception("I did"));
|
||||
return null;
|
||||
}
|
||||
if (tryReadLock()) {
|
||||
try {
|
||||
return locked_getProfile(peer);
|
||||
@ -184,6 +194,11 @@ public class ProfileOrganizer {
|
||||
if (profile == null) return null;
|
||||
|
||||
Hash peer = profile.getPeer();
|
||||
if (peer.equals(_us)) {
|
||||
if (_log.shouldWarn())
|
||||
_log.warn("Who added our own profile?", new Exception("I did"));
|
||||
return null;
|
||||
}
|
||||
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("New profile created for " + peer);
|
||||
|
@ -301,7 +301,7 @@ class ProfilePersistenceHelper {
|
||||
_log.debug("Loaded the profile for " + peer.toBase64() + " from " + file.getName());
|
||||
|
||||
return profile;
|
||||
} catch (Exception e) {
|
||||
} catch (IOException e) {
|
||||
if (_log.shouldLog(Log.WARN))
|
||||
_log.warn("Error loading properties from " + file.getAbsolutePath(), e);
|
||||
file.delete();
|
||||
@ -369,7 +369,7 @@ class ProfilePersistenceHelper {
|
||||
return null;
|
||||
Hash h = Hash.create(b);
|
||||
return h;
|
||||
} catch (Exception dfe) {
|
||||
} catch (RuntimeException dfe) {
|
||||
_log.warn("Invalid base64 [" + key + "]", dfe);
|
||||
return null;
|
||||
}
|
||||
|
@ -98,7 +98,13 @@ class RebuildRouterInfoJob extends JobImpl {
|
||||
KeyData kd = LoadRouterInfoJob.readKeyData(keyFile, keyFile2);
|
||||
info = new RouterInfo();
|
||||
info.setIdentity(kd.routerIdentity);
|
||||
} catch (Exception e) {
|
||||
} catch (DataFormatException e) {
|
||||
_log.log(Log.CRIT, "Error reading in the key data from " + keyFile.getAbsolutePath(), e);
|
||||
keyFile.delete();
|
||||
keyFile2.delete();
|
||||
rebuildRouterInfo(alreadyRunning);
|
||||
return;
|
||||
} catch (IOException e) {
|
||||
_log.log(Log.CRIT, "Error reading in the key data from " + keyFile.getAbsolutePath(), e);
|
||||
keyFile.delete();
|
||||
keyFile2.delete();
|
||||
|
@ -211,7 +211,7 @@ public class WorkingDir {
|
||||
String[] files = dir.list();
|
||||
if (files == null)
|
||||
return false;
|
||||
String migrated[] = MIGRATE_BASE.split(",");
|
||||
String migrated[] = DataHelper.split(MIGRATE_BASE, ",");
|
||||
for (String file: files) {
|
||||
for (int i = 0; i < migrated.length; i++) {
|
||||
if (file.equals(migrated[i]))
|
||||
@ -282,7 +282,7 @@ public class WorkingDir {
|
||||
|
||||
private static boolean migrate(String list, File olddir, File todir) {
|
||||
boolean rv = true;
|
||||
String files[] = list.split(",");
|
||||
String files[] = DataHelper.split(list, ",");
|
||||
for (int i = 0; i < files.length; i++) {
|
||||
File from = new File(olddir, files[i]);
|
||||
if (!copy(from, todir)) {
|
||||
|
@ -10,6 +10,7 @@ import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
import net.i2p.I2PAppContext;
|
||||
import net.i2p.data.DataHelper;
|
||||
import net.i2p.router.transport.GeoIP;
|
||||
|
||||
/**
|
||||
@ -105,7 +106,7 @@ class Zones {
|
||||
try {
|
||||
if (line.charAt(0) == '#')
|
||||
continue;
|
||||
String[] s = line.split(",");
|
||||
String[] s = DataHelper.split(line, ",");
|
||||
String ucContinent = s[1].toUpperCase(Locale.US).trim();
|
||||
String zone = _continentToZone.get(ucContinent);
|
||||
if (zone == null)
|
||||
|
@ -17,6 +17,7 @@ import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
import net.i2p.I2PAppContext;
|
||||
import net.i2p.data.DataHelper;
|
||||
import net.i2p.data.Hash;
|
||||
import net.i2p.router.Router;
|
||||
import net.i2p.router.RouterContext;
|
||||
@ -209,7 +210,7 @@ public class GeoIP {
|
||||
if (line.charAt(0) == '#') {
|
||||
continue;
|
||||
}
|
||||
String[] s = line.split(",");
|
||||
String[] s = DataHelper.split(line, ",");
|
||||
String lc = s[0].toLowerCase(Locale.US);
|
||||
_codeToName.put(lc, s[1]);
|
||||
_codeCache.put(lc, lc);
|
||||
@ -274,7 +275,7 @@ public class GeoIP {
|
||||
if (buf.charAt(0) == '#') {
|
||||
continue;
|
||||
}
|
||||
String[] s = buf.split(",");
|
||||
String[] s = DataHelper.split(buf, ",");
|
||||
long ip1 = Long.parseLong(s[0]);
|
||||
long ip2 = Long.parseLong(s[1]);
|
||||
while (idx < search.length && search[idx].longValue() < ip1) {
|
||||
|
@ -170,7 +170,7 @@ class GeoIPv6 {
|
||||
if (buf.charAt(0) == '#') {
|
||||
continue;
|
||||
}
|
||||
String[] s = buf.split(",");
|
||||
String[] s = DataHelper.split(buf, ",");
|
||||
String ips1 = s[0].replace("\"", "").trim();
|
||||
String ips2 = s[1].replace("\"", "").trim();
|
||||
byte[] ip1 = InetAddress.getByName(ips1).getAddress();
|
||||
|
@ -4,9 +4,9 @@
|
||||
package net.i2p.router.transport;
|
||||
|
||||
import java.net.InetAddress;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.UnknownHostException;
|
||||
import java.net.URL;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
@ -224,7 +224,7 @@ class UPnP extends ControlPoint implements DeviceChangeListener, EventListener {
|
||||
boolean ignore = false;
|
||||
String toIgnore = _context.getProperty(PROP_IGNORE);
|
||||
if (toIgnore != null) {
|
||||
String[] ignores = toIgnore.split("[,; \r\n\t]");
|
||||
String[] ignores = DataHelper.split(toIgnore, "[,; \r\n\t]");
|
||||
for (int i = 0; i < ignores.length; i++) {
|
||||
if (ignores[i].equals(udn)) {
|
||||
ignore = true;
|
||||
@ -476,7 +476,7 @@ class UPnP extends ControlPoint implements DeviceChangeListener, EventListener {
|
||||
ServiceStateTable table;
|
||||
try {
|
||||
table = serv.getServiceStateTable();
|
||||
} catch (Exception e) {
|
||||
} catch (RuntimeException e) {
|
||||
// getSCPDNode() returns null,
|
||||
// NPE at org.cybergarage.upnp.Service.getServiceStateTable(Service.java:526)
|
||||
sb.append(" : no state");
|
||||
@ -823,17 +823,17 @@ class UPnP extends ControlPoint implements DeviceChangeListener, EventListener {
|
||||
String him = _router.getURLBase();
|
||||
if (him != null && him.length() > 0) {
|
||||
try {
|
||||
URL url = new URL(him);
|
||||
URI url = new URI(him);
|
||||
hisIP = url.getHost();
|
||||
} catch (MalformedURLException mue) {}
|
||||
} catch (URISyntaxException use) {}
|
||||
}
|
||||
if (hisIP == null) {
|
||||
him = _router.getLocation();
|
||||
if (him != null && him.length() > 0) {
|
||||
try {
|
||||
URL url = new URL(him);
|
||||
URI url = new URI(him);
|
||||
hisIP = url.getHost();
|
||||
} catch (MalformedURLException mue) {}
|
||||
} catch (URISyntaxException use) {}
|
||||
}
|
||||
}
|
||||
if (hisIP == null)
|
||||
|
@ -88,7 +88,7 @@ class UPnPManager {
|
||||
_isRunning = _upnp.runPlugin();
|
||||
if (_log.shouldLog(Log.INFO))
|
||||
_log.info("UPnP runPlugin took " + (_context.clock().now() - b));
|
||||
} catch (Exception e) {
|
||||
} catch (RuntimeException e) {
|
||||
// NPE in UPnP (ticket #728), can't let it bring us down
|
||||
if (!_errorLogged) {
|
||||
_log.error("UPnP error, please report", e);
|
||||
|
@ -335,7 +335,7 @@ class EventPumper implements Runnable {
|
||||
con.close();
|
||||
key.cancel();
|
||||
}
|
||||
} catch (Exception ke) {
|
||||
} catch (IOException ke) {
|
||||
_log.error("Error closing key " + key + " on pumper shutdown", ke);
|
||||
}
|
||||
}
|
||||
@ -344,7 +344,7 @@ class EventPumper implements Runnable {
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("Closing down the event pumper with no selection keys remaining");
|
||||
}
|
||||
} catch (Exception e) {
|
||||
} catch (IOException e) {
|
||||
_log.error("Error closing keys on pumper shutdown", e);
|
||||
}
|
||||
_wantsConRegister.clear();
|
||||
|
@ -463,7 +463,7 @@ class NTCPConnection implements Closeable {
|
||||
_transport.afterSend(msg, successful, allowRequeue, msg.getLifetime());
|
||||
if (_consecutiveBacklog > 10) { // waaay too backlogged
|
||||
boolean wantsWrite = false;
|
||||
try { wantsWrite = ( (_conKey.interestOps() & SelectionKey.OP_WRITE) != 0); } catch (Exception e) {}
|
||||
try { wantsWrite = ( (_conKey.interestOps() & SelectionKey.OP_WRITE) != 0); } catch (RuntimeException e) {}
|
||||
if (_log.shouldLog(Log.WARN)) {
|
||||
int blocks = _writeBufs.size();
|
||||
_log.warn("Too backlogged for too long (" + _consecutiveBacklog + " messages for " + DataHelper.formatDuration(queueTime()) + ", sched? " + wantsWrite + ", blocks: " + blocks + ") sending to " + _remotePeer.calculateHash());
|
||||
@ -521,7 +521,7 @@ class NTCPConnection implements Closeable {
|
||||
+ ", wantsWrite? " + (0 != (_conKey.interestOps()&SelectionKey.OP_WRITE))
|
||||
+ ", currentOut set? " + currentOutboundSet
|
||||
+ ", writeBufs: " + writeBufs + " on " + toString());
|
||||
} catch (Exception e) {} // java.nio.channels.CancelledKeyException
|
||||
} catch (RuntimeException e) {} // java.nio.channels.CancelledKeyException
|
||||
}
|
||||
//_context.statManager().addRateData("ntcp.sendBacklogTime", queueTime);
|
||||
return true;
|
||||
|
@ -148,7 +148,7 @@ class ACKSender implements Runnable {
|
||||
try {
|
||||
// bulk operations may throw an exception
|
||||
_peersToACK.addAll(notYet);
|
||||
} catch (Exception e) {}
|
||||
} catch (RuntimeException e) {}
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("sleeping, pending size = " + notYet.size());
|
||||
notYet.clear();
|
||||
|
@ -29,6 +29,7 @@ import net.i2p.router.util.DecayingBloomFilter;
|
||||
import net.i2p.util.Addresses;
|
||||
import net.i2p.util.I2PThread;
|
||||
import net.i2p.util.Log;
|
||||
import net.i2p.util.VersionComparator;
|
||||
|
||||
/**
|
||||
* Coordinate the establishment of new sessions - both inbound and outbound.
|
||||
@ -126,6 +127,19 @@ class EstablishmentManager {
|
||||
/** for the DSM and or netdb store */
|
||||
private static final int DATA_MESSAGE_TIMEOUT = 10*1000;
|
||||
|
||||
/**
|
||||
* Java I2P has always parsed the length of the extended options field,
|
||||
* but i2pd hasn't recognized it until this release.
|
||||
* No matter, the options weren't defined until this release anyway.
|
||||
*
|
||||
**********************************************************************************************************
|
||||
* FIXME 0.9.23 for testing, change to 0.9.24 for release
|
||||
*
|
||||
*/
|
||||
private static final String VERSION_ALLOW_EXTENDED_OPTIONS = "0.9.23";
|
||||
private static final String PROP_DISABLE_EXT_OPTS = "i2np.udp.disableExtendedOptions";
|
||||
|
||||
|
||||
public EstablishmentManager(RouterContext ctx, UDPTransport transport) {
|
||||
_context = ctx;
|
||||
_log = ctx.logManager().getLog(EstablishmentManager.class);
|
||||
@ -356,8 +370,16 @@ class EstablishmentManager {
|
||||
_transport.failed(msg, "Peer has bad key, cannot establish");
|
||||
return;
|
||||
}
|
||||
boolean allowExtendedOptions = VersionComparator.comp(toRouterInfo.getVersion(),
|
||||
VERSION_ALLOW_EXTENDED_OPTIONS) >= 0
|
||||
&& !_context.getBooleanProperty(PROP_DISABLE_EXT_OPTS);
|
||||
// w/o ext options, it's always 'requested', no need to set
|
||||
// don't ask if they are indirect
|
||||
boolean requestIntroduction = allowExtendedOptions && !isIndirect &&
|
||||
_transport.introducersMaybeRequired();
|
||||
state = new OutboundEstablishState(_context, maybeTo, to,
|
||||
toIdentity,
|
||||
toIdentity, allowExtendedOptions,
|
||||
requestIntroduction,
|
||||
sessionKey, addr, _transport.getDHFactory());
|
||||
OutboundEstablishState oldState = _outboundStates.putIfAbsent(to, state);
|
||||
boolean isNew = oldState == null;
|
||||
@ -477,7 +499,9 @@ class EstablishmentManager {
|
||||
// Don't offer to relay to privileged ports.
|
||||
// Only offer for an IPv4 session.
|
||||
// TODO if already we have their RI, only offer if they need it (no 'C' cap)
|
||||
if (_transport.canIntroduce() && state.getSentPort() >= 1024 &&
|
||||
// if extended options, only if they asked for it
|
||||
if (state.isIntroductionRequested() &&
|
||||
_transport.canIntroduce() && state.getSentPort() >= 1024 &&
|
||||
state.getSentIP().length == 4) {
|
||||
// ensure > 0
|
||||
long tag = 1 + _context.random().nextLong(MAX_TAG_VALUE);
|
||||
|
@ -62,6 +62,8 @@ class InboundEstablishState {
|
||||
private final Queue<OutNetMessage> _queuedMessages;
|
||||
// count for backoff
|
||||
private int _createdSentCount;
|
||||
// default true
|
||||
private boolean _introductionRequested = true;
|
||||
|
||||
public enum InboundState {
|
||||
/** nothin known yet */
|
||||
@ -150,6 +152,12 @@ class InboundEstablishState {
|
||||
if (_bobIP == null)
|
||||
_bobIP = new byte[req.readIPSize()];
|
||||
req.readIP(_bobIP, 0);
|
||||
byte[] ext = req.readExtendedOptions();
|
||||
if (ext != null && ext.length >= UDPPacket.SESS_REQ_MIN_EXT_OPTIONS_LENGTH) {
|
||||
_introductionRequested = (ext[1] & (byte) UDPPacket.SESS_REQ_EXT_FLAG_REQUEST_RELAY_TAG) != 0;
|
||||
if (_log.shouldInfo())
|
||||
_log.info("got sess req. w/ ext. options, need intro? " + _introductionRequested + ' ' + this);
|
||||
}
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("Receive sessionRequest, BobIP = " + Addresses.toString(_bobIP));
|
||||
if (_currentState == InboundState.IB_STATE_UNKNOWN)
|
||||
@ -160,6 +168,12 @@ class InboundEstablishState {
|
||||
public synchronized boolean sessionRequestReceived() { return _receivedX != null; }
|
||||
public synchronized byte[] getReceivedX() { return _receivedX; }
|
||||
public synchronized byte[] getReceivedOurIP() { return _bobIP; }
|
||||
/**
|
||||
* True (default) if no extended options in session request,
|
||||
* or value of flag bit in the extended options.
|
||||
* @since 0.9.24
|
||||
*/
|
||||
public synchronized boolean isIntroductionRequested() { return _introductionRequested; }
|
||||
|
||||
/**
|
||||
* Generates session key and mac key.
|
||||
|
@ -243,7 +243,7 @@ class MessageReceiver {
|
||||
}
|
||||
_context.messageHistory().droppedInboundMessage(state.getMessageId(), state.getFrom(), "error: " + ime.toString() + ": " + state.toString());
|
||||
return null;
|
||||
} catch (Exception e) {
|
||||
} catch (RuntimeException e) {
|
||||
// e.g. AIOOBE
|
||||
if (_log.shouldLog(Log.WARN))
|
||||
_log.warn("Error handling a message: " + state, e);
|
||||
|
@ -56,6 +56,8 @@ class OutboundEstablishState {
|
||||
private RemoteHostId _remoteHostId;
|
||||
private final RemoteHostId _claimedAddress;
|
||||
private final RouterIdentity _remotePeer;
|
||||
private final boolean _allowExtendedOptions;
|
||||
private final boolean _needIntroduction;
|
||||
private final SessionKey _introKey;
|
||||
private final Queue<OutNetMessage> _queuedMessages;
|
||||
private OutboundState _currentState;
|
||||
@ -107,12 +109,17 @@ class OutboundEstablishState {
|
||||
* @param claimedAddress an IP/port based RemoteHostId, or null if unknown
|
||||
* @param remoteHostId non-null, == claimedAddress if direct, or a hash-based one if indirect
|
||||
* @param remotePeer must have supported sig type
|
||||
* @param allowExtenededOptions are we allowed to send extended options to Bob?
|
||||
* @param needIntroduction should we ask Bob to be an introducer for us?
|
||||
ignored unless allowExtendedOptions is true
|
||||
* @param introKey Bob's introduction key, as published in the netdb
|
||||
* @param addr non-null
|
||||
*/
|
||||
public OutboundEstablishState(RouterContext ctx, RemoteHostId claimedAddress,
|
||||
RemoteHostId remoteHostId,
|
||||
RouterIdentity remotePeer, SessionKey introKey, UDPAddress addr,
|
||||
RouterIdentity remotePeer, boolean allowExtendedOptions,
|
||||
boolean needIntroduction,
|
||||
SessionKey introKey, UDPAddress addr,
|
||||
DHSessionKeyBuilder.Factory dh) {
|
||||
_context = ctx;
|
||||
_log = ctx.logManager().getLog(OutboundEstablishState.class);
|
||||
@ -125,6 +132,8 @@ class OutboundEstablishState {
|
||||
}
|
||||
_claimedAddress = claimedAddress;
|
||||
_remoteHostId = remoteHostId;
|
||||
_allowExtendedOptions = allowExtendedOptions;
|
||||
_needIntroduction = needIntroduction;
|
||||
_remotePeer = remotePeer;
|
||||
_introKey = introKey;
|
||||
_queuedMessages = new LinkedBlockingQueue<OutNetMessage>();
|
||||
@ -157,6 +166,19 @@ class OutboundEstablishState {
|
||||
|
||||
/** @return -1 if unset */
|
||||
public long getIntroNonce() { return _introductionNonce; }
|
||||
|
||||
/**
|
||||
* Are we allowed to send extended options to this peer?
|
||||
* @since 0.9.24
|
||||
*/
|
||||
public boolean isExtendedOptionsAllowed() { return _allowExtendedOptions; }
|
||||
|
||||
/**
|
||||
* Should we ask this peer to be an introducer for us?
|
||||
* Ignored unless allowExtendedOptions is true
|
||||
* @since 0.9.24
|
||||
*/
|
||||
public boolean needIntroduction() { return _needIntroduction; }
|
||||
|
||||
/**
|
||||
* Queue a message to be sent after the session is established.
|
||||
|
@ -57,10 +57,11 @@ to the various messages - a one byte flag and a four byte sending
|
||||
timestamp (*seconds* since the unix epoch). The flag byte contains
|
||||
the following bitfields:</p>
|
||||
<pre>
|
||||
bits 0-3: payload type
|
||||
bit 4: rekey?
|
||||
bit 5: extended options included
|
||||
bits 6-7: reserved
|
||||
Bit order: 76543210
|
||||
bits 7-4: payload type
|
||||
bit 3: rekey?
|
||||
bit 2: extended options included
|
||||
bits 1-0: reserved
|
||||
</pre>
|
||||
|
||||
<p>If the rekey flag is set, 64 bytes of keying material follow the
|
||||
@ -166,6 +167,19 @@ class PacketBuilder {
|
||||
private static final String PROP_PADDING = "i2np.udp.padding";
|
||||
private static final boolean DEFAULT_ENABLE_PADDING = true;
|
||||
|
||||
/**
|
||||
* The nine message types, 0-8, shifted to bits 7-4 for convenience
|
||||
*/
|
||||
private static final byte SESSION_REQUEST_FLAG_BYTE = UDPPacket.PAYLOAD_TYPE_SESSION_REQUEST << 4;
|
||||
private static final byte SESSION_CREATED_FLAG_BYTE = UDPPacket.PAYLOAD_TYPE_SESSION_CREATED << 4;
|
||||
private static final byte SESSION_CONFIRMED_FLAG_BYTE = UDPPacket.PAYLOAD_TYPE_SESSION_CONFIRMED << 4;
|
||||
private static final byte PEER_RELAY_REQUEST_FLAG_BYTE = UDPPacket.PAYLOAD_TYPE_RELAY_REQUEST << 4;
|
||||
private static final byte PEER_RELAY_RESPONSE_FLAG_BYTE = UDPPacket.PAYLOAD_TYPE_RELAY_RESPONSE << 4;
|
||||
private static final byte PEER_RELAY_INTRO_FLAG_BYTE = UDPPacket.PAYLOAD_TYPE_RELAY_INTRO << 4;
|
||||
private static final byte DATA_FLAG_BYTE = UDPPacket.PAYLOAD_TYPE_DATA << 4;
|
||||
private static final byte PEER_TEST_FLAG_BYTE = UDPPacket.PAYLOAD_TYPE_TEST << 4;
|
||||
private static final byte SESSION_DESTROY_FLAG_BYTE = (byte) (UDPPacket.PAYLOAD_TYPE_SESSION_DESTROY << 4);
|
||||
|
||||
/**
|
||||
* @param transport may be null for unit testing only
|
||||
*/
|
||||
@ -332,7 +346,7 @@ class PacketBuilder {
|
||||
int availableForExplicitAcks = availableForAcks;
|
||||
|
||||
// make the packet
|
||||
UDPPacket packet = buildPacketHeader((byte)(UDPPacket.PAYLOAD_TYPE_DATA << 4));
|
||||
UDPPacket packet = buildPacketHeader(DATA_FLAG_BYTE);
|
||||
DatagramPacket pkt = packet.getPacket();
|
||||
byte data[] = pkt.getData();
|
||||
int off = HEADER_SIZE;
|
||||
@ -573,7 +587,7 @@ class PacketBuilder {
|
||||
* @param ackBitfields list of ACKBitfield instances to either fully or partially ACK
|
||||
*/
|
||||
public UDPPacket buildACK(PeerState peer, List<ACKBitfield> ackBitfields) {
|
||||
UDPPacket packet = buildPacketHeader((byte)(UDPPacket.PAYLOAD_TYPE_DATA << 4));
|
||||
UDPPacket packet = buildPacketHeader(DATA_FLAG_BYTE);
|
||||
DatagramPacket pkt = packet.getPacket();
|
||||
byte data[] = pkt.getData();
|
||||
int off = HEADER_SIZE;
|
||||
@ -667,12 +681,6 @@ class PacketBuilder {
|
||||
return packet;
|
||||
}
|
||||
|
||||
/**
|
||||
* full flag info for a sessionCreated message. this can be fixed,
|
||||
* since we never rekey on startup, and don't need any extended options
|
||||
*/
|
||||
private static final byte SESSION_CREATED_FLAG_BYTE = (UDPPacket.PAYLOAD_TYPE_SESSION_CREATED << 4);
|
||||
|
||||
/**
|
||||
* Build a new SessionCreated packet for the given peer, encrypting it
|
||||
* as necessary.
|
||||
@ -768,12 +776,6 @@ class PacketBuilder {
|
||||
return packet;
|
||||
}
|
||||
|
||||
/**
|
||||
* full flag info for a sessionRequest message. this can be fixed,
|
||||
* since we never rekey on startup, and don't need any extended options
|
||||
*/
|
||||
private static final byte SESSION_REQUEST_FLAG_BYTE = (UDPPacket.PAYLOAD_TYPE_SESSION_REQUEST << 4);
|
||||
|
||||
/**
|
||||
* Build a new SessionRequest packet for the given peer, encrypting it
|
||||
* as necessary.
|
||||
@ -781,10 +783,23 @@ class PacketBuilder {
|
||||
* @return ready to send packet, or null if there was a problem
|
||||
*/
|
||||
public UDPPacket buildSessionRequestPacket(OutboundEstablishState state) {
|
||||
UDPPacket packet = buildPacketHeader(SESSION_REQUEST_FLAG_BYTE);
|
||||
int off = HEADER_SIZE;
|
||||
byte[] options;
|
||||
boolean ext = state.isExtendedOptionsAllowed();
|
||||
if (ext) {
|
||||
options = new byte[UDPPacket.SESS_REQ_MIN_EXT_OPTIONS_LENGTH];
|
||||
boolean intro = state.needIntroduction();
|
||||
if (intro)
|
||||
options[1] = (byte) UDPPacket.SESS_REQ_EXT_FLAG_REQUEST_RELAY_TAG;
|
||||
if (_log.shouldInfo())
|
||||
_log.info("send sess req. w/ ext. options, need intro? " + intro + ' ' + state);
|
||||
off += UDPPacket.SESS_REQ_MIN_EXT_OPTIONS_LENGTH + 1;
|
||||
} else {
|
||||
options = null;
|
||||
}
|
||||
UDPPacket packet = buildPacketHeader(SESSION_REQUEST_FLAG_BYTE, options);
|
||||
DatagramPacket pkt = packet.getPacket();
|
||||
byte data[] = pkt.getData();
|
||||
int off = HEADER_SIZE;
|
||||
|
||||
byte toIP[] = state.getSentIP();
|
||||
if (!_transport.isValid(toIP)) {
|
||||
@ -854,13 +869,6 @@ class PacketBuilder {
|
||||
return packets;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* full flag info for a sessionConfirmed message. this can be fixed,
|
||||
* since we never rekey on startup, and don't need any extended options
|
||||
*/
|
||||
private static final byte SESSION_CONFIRMED_FLAG_BYTE = (UDPPacket.PAYLOAD_TYPE_SESSION_CONFIRMED << 4);
|
||||
|
||||
/**
|
||||
* Build a new SessionConfirmed packet for the given peer
|
||||
*
|
||||
@ -1018,7 +1026,7 @@ class PacketBuilder {
|
||||
* @since 0.9.2
|
||||
*/
|
||||
private UDPPacket buildSessionDestroyPacket(SessionKey cipherKey, SessionKey macKey, InetAddress addr, int port) {
|
||||
UDPPacket packet = buildPacketHeader((byte)(UDPPacket.PAYLOAD_TYPE_SESSION_DESTROY << 4));
|
||||
UDPPacket packet = buildPacketHeader(SESSION_DESTROY_FLAG_BYTE);
|
||||
int off = HEADER_SIZE;
|
||||
|
||||
// no body in this message
|
||||
@ -1034,12 +1042,6 @@ class PacketBuilder {
|
||||
return packet;
|
||||
}
|
||||
|
||||
/**
|
||||
* full flag info for a peerTest message. this can be fixed,
|
||||
* since we never rekey on test, and don't need any extended options
|
||||
*/
|
||||
private static final byte PEER_TEST_FLAG_BYTE = (UDPPacket.PAYLOAD_TYPE_TEST << 4);
|
||||
|
||||
/**
|
||||
* Build a packet as if we are Alice and we either want Bob to begin a
|
||||
* peer test or Charlie to finish a peer test.
|
||||
@ -1197,12 +1199,6 @@ class PacketBuilder {
|
||||
packet.setMessageType(TYPE_TCB);
|
||||
return packet;
|
||||
}
|
||||
|
||||
/**
|
||||
* full flag info for a relay request message. this can be fixed,
|
||||
* since we never rekey on relay request, and don't need any extended options
|
||||
*/
|
||||
private static final byte PEER_RELAY_REQUEST_FLAG_BYTE = (UDPPacket.PAYLOAD_TYPE_RELAY_REQUEST << 4);
|
||||
|
||||
// specify these if we know what our external receive ip/port is and if its different
|
||||
// from what bob is going to think
|
||||
@ -1330,12 +1326,6 @@ class PacketBuilder {
|
||||
return packet;
|
||||
}
|
||||
|
||||
/**
|
||||
* full flag info for a relay intro message. this can be fixed,
|
||||
* since we never rekey on relay request, and don't need any extended options
|
||||
*/
|
||||
private static final byte PEER_RELAY_INTRO_FLAG_BYTE = (UDPPacket.PAYLOAD_TYPE_RELAY_INTRO << 4);
|
||||
|
||||
UDPPacket buildRelayIntro(RemoteHostId alice, PeerState charlie, UDPPacketReader.RelayRequestReader request) {
|
||||
UDPPacket packet = buildPacketHeader(PEER_RELAY_INTRO_FLAG_BYTE);
|
||||
DatagramPacket pkt = packet.getPacket();
|
||||
@ -1370,12 +1360,6 @@ class PacketBuilder {
|
||||
packet.setMessageType(TYPE_INTRO);
|
||||
return packet;
|
||||
}
|
||||
|
||||
/**
|
||||
* full flag info for a relay response message. this can be fixed,
|
||||
* since we never rekey on relay response, and don't need any extended options
|
||||
*/
|
||||
private static final byte PEER_RELAY_RESPONSE_FLAG_BYTE = (UDPPacket.PAYLOAD_TYPE_RELAY_RESPONSE << 4);
|
||||
|
||||
UDPPacket buildRelayResponse(RemoteHostId alice, PeerState charlie, long nonce,
|
||||
SessionKey cipherKey, SessionKey macKey) {
|
||||
@ -1462,24 +1446,50 @@ class PacketBuilder {
|
||||
/**
|
||||
* Create a new packet and add the flag byte and the time stamp.
|
||||
* Caller should add data starting at HEADER_SIZE.
|
||||
* At this point, adding support for extended options and rekeying is unlikely,
|
||||
* but if we do, we'll have to change this.
|
||||
* Does not include extended options or rekeying.
|
||||
*
|
||||
* @param flagByte contains type and flags
|
||||
* @since 0.8.1
|
||||
*/
|
||||
private UDPPacket buildPacketHeader(byte flagByte) {
|
||||
return buildPacketHeader(flagByte, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new packet and add the flag byte and the time stamp.
|
||||
* Caller should add data starting at HEADER_SIZE.
|
||||
* (if extendedOptions != null, at HEADER_SIZE + 1 + extendedOptions.length)
|
||||
* Does not include rekeying.
|
||||
*
|
||||
* @param flagByte contains type and flags
|
||||
* @param extendedOptions May be null. If non-null, we will add the associated flag here.
|
||||
* 255 bytes max.
|
||||
* @since 0.9.24
|
||||
*/
|
||||
private UDPPacket buildPacketHeader(byte flagByte, byte[] extendedOptions) {
|
||||
UDPPacket packet = UDPPacket.acquire(_context, false);
|
||||
byte data[] = packet.getPacket().getData();
|
||||
Arrays.fill(data, 0, data.length, (byte)0x0);
|
||||
int off = UDPPacket.MAC_SIZE + UDPPacket.IV_SIZE;
|
||||
|
||||
// header
|
||||
if (extendedOptions != null)
|
||||
flagByte |= UDPPacket.HEADER_FLAG_EXTENDED_OPTIONS;
|
||||
data[off] = flagByte;
|
||||
off++;
|
||||
// Note, this is unsigned, so we're good until February 2106
|
||||
long now = (_context.clock().now() + 500) / 1000;
|
||||
DataHelper.toLong(data, off, 4, now);
|
||||
// todo: add support for rekeying and extended options
|
||||
// todo: add support for rekeying
|
||||
// extended options
|
||||
if (extendedOptions != null) {
|
||||
off+= 4;
|
||||
int len = extendedOptions.length;
|
||||
if (len > 255)
|
||||
throw new IllegalArgumentException();
|
||||
data[off++] = (byte) len;
|
||||
System.arraycopy(extendedOptions, 0, data, off, len);
|
||||
}
|
||||
return packet;
|
||||
}
|
||||
|
||||
|
@ -215,7 +215,7 @@ class PacketHandler {
|
||||
_state = 5;
|
||||
handlePacket(_reader, packet);
|
||||
_state = 6;
|
||||
} catch (Exception e) {
|
||||
} catch (RuntimeException e) {
|
||||
_state = 7;
|
||||
if (_log.shouldLog(Log.ERROR))
|
||||
_log.error("Crazy error handling a packet: " + packet, e);
|
||||
|
@ -43,7 +43,7 @@ class PacketPusher implements Runnable {
|
||||
send(packets.get(i));
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
} catch (RuntimeException e) {
|
||||
_log.error("SSU Output Queue Error", e);
|
||||
}
|
||||
}
|
||||
|
@ -85,18 +85,38 @@ class UDPPacket implements CDQEntry {
|
||||
public static final int PAYLOAD_TYPE_RELAY_INTRO = 5;
|
||||
public static final int PAYLOAD_TYPE_DATA = 6;
|
||||
public static final int PAYLOAD_TYPE_TEST = 7;
|
||||
public static final int MAX_PAYLOAD_TYPE = PAYLOAD_TYPE_TEST;
|
||||
/** @since 0.8.1 */
|
||||
public static final int PAYLOAD_TYPE_SESSION_DESTROY = 8;
|
||||
public static final int MAX_PAYLOAD_TYPE = PAYLOAD_TYPE_SESSION_DESTROY;
|
||||
|
||||
// various flag fields for use in the header
|
||||
/**
|
||||
* Defined in the spec from the beginning, Unused
|
||||
* @since 0.9.24
|
||||
*/
|
||||
public static final byte HEADER_FLAG_REKEY = (1 << 3);
|
||||
/**
|
||||
* Defined in the spec from the beginning, Used starting in 0.9.24
|
||||
* @since 0.9.24
|
||||
*/
|
||||
public static final byte HEADER_FLAG_EXTENDED_OPTIONS = (1 << 2);
|
||||
|
||||
// Extended options for session request
|
||||
public static final int SESS_REQ_MIN_EXT_OPTIONS_LENGTH = 2;
|
||||
// bytes 0-1 are flags
|
||||
/**
|
||||
* set to 1 to request a session tag, i.e. we want him to be an introducer for us
|
||||
*/
|
||||
public static final int SESS_REQ_EXT_FLAG_REQUEST_RELAY_TAG = 0x01;
|
||||
|
||||
// various flag fields for use in the data packets
|
||||
public static final byte DATA_FLAG_EXPLICIT_ACK = (byte)(1 << 7);
|
||||
public static final byte DATA_FLAG_ACK_BITFIELDS = (1 << 6);
|
||||
// unused
|
||||
/** unused */
|
||||
public static final byte DATA_FLAG_ECN = (1 << 4);
|
||||
public static final byte DATA_FLAG_WANT_ACKS = (1 << 3);
|
||||
public static final byte DATA_FLAG_WANT_REPLY = (1 << 2);
|
||||
// unused
|
||||
/** unused */
|
||||
public static final byte DATA_FLAG_EXTENDED = (1 << 1);
|
||||
|
||||
public static final byte BITFIELD_CONTINUATION = (byte)(1 << 7);
|
||||
|
@ -67,33 +67,68 @@ class UDPPacketReader {
|
||||
return (_message[_payloadBeginOffset] & 0xFF) >>> 4;
|
||||
}
|
||||
|
||||
/** does this packet include rekeying data? */
|
||||
public boolean readRekeying() {
|
||||
return (_message[_payloadBeginOffset] & (1 << 3)) != 0;
|
||||
/**
|
||||
* Does this packet include rekeying data in the header?
|
||||
* Unused, should always be false.
|
||||
*/
|
||||
public boolean isRekeyingIncluded() {
|
||||
return (_message[_payloadBeginOffset] & UDPPacket.HEADER_FLAG_REKEY) != 0;
|
||||
}
|
||||
|
||||
public boolean readExtendedOptionsIncluded() {
|
||||
return (_message[_payloadBeginOffset] & (1 << 2)) != 0;
|
||||
/**
|
||||
* Does this packet include extended options in the header?
|
||||
*/
|
||||
public boolean isExtendedOptionsIncluded() {
|
||||
return (_message[_payloadBeginOffset] & UDPPacket.HEADER_FLAG_EXTENDED_OPTIONS) != 0;
|
||||
}
|
||||
|
||||
/** @return seconds */
|
||||
public long readTimestamp() {
|
||||
// Note, this is unsigned, so we're good until February 2106
|
||||
return DataHelper.fromLong(_message, _payloadBeginOffset + 1, 4);
|
||||
}
|
||||
|
||||
public void readKeyingMaterial(byte target[], int targetOffset) {
|
||||
if (!readRekeying())
|
||||
throw new IllegalStateException("This packet is not rekeying!");
|
||||
System.arraycopy(_message, _payloadBeginOffset + 1 + 4, target, targetOffset, KEYING_MATERIAL_LENGTH);
|
||||
/**
|
||||
* Returns rekeying data (64 bytes), or null if none.
|
||||
* Unused, should always return null.
|
||||
*
|
||||
* @deprecated unused
|
||||
*/
|
||||
@Deprecated
|
||||
public byte[] readKeyingMaterial() {
|
||||
if (!isRekeyingIncluded())
|
||||
return null;
|
||||
byte[] rv = new byte[KEYING_MATERIAL_LENGTH];
|
||||
System.arraycopy(_message, _payloadBeginOffset + 1 + 4, rv, 0, KEYING_MATERIAL_LENGTH);
|
||||
return rv;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns extended option data, 0-255 bytes, or null if none.
|
||||
* Returned array does NOT include the length byte.
|
||||
*
|
||||
* @return extended options or null if none is included
|
||||
* @since 0.9.24
|
||||
*/
|
||||
public byte[] readExtendedOptions() {
|
||||
if (!isExtendedOptionsIncluded())
|
||||
return null;
|
||||
int offset = _payloadBeginOffset + 1 + 4;
|
||||
if (isRekeyingIncluded())
|
||||
offset += KEYING_MATERIAL_LENGTH;
|
||||
int optionsSize = _message[offset++] & 0xff;
|
||||
byte[] rv = new byte[optionsSize];
|
||||
System.arraycopy(_message, offset, rv, 0, optionsSize);
|
||||
return rv;
|
||||
}
|
||||
|
||||
/** index into the message where the body begins */
|
||||
private int readBodyOffset() {
|
||||
int offset = _payloadBeginOffset + 1 + 4;
|
||||
if (readRekeying())
|
||||
if (isRekeyingIncluded())
|
||||
offset += KEYING_MATERIAL_LENGTH;
|
||||
if (readExtendedOptionsIncluded()) {
|
||||
int optionsSize = (int)DataHelper.fromLong(_message, offset, 1);
|
||||
if (isExtendedOptionsIncluded()) {
|
||||
int optionsSize = _message[offset] & 0xff;
|
||||
offset += optionsSize + 1;
|
||||
}
|
||||
return offset;
|
||||
@ -142,8 +177,26 @@ class UDPPacketReader {
|
||||
|
||||
/* ------- Begin Reader Classes ------- */
|
||||
|
||||
/**
|
||||
* Base
|
||||
*
|
||||
* @since 0.9.24
|
||||
*/
|
||||
public abstract class Reader {
|
||||
/**
|
||||
* Returns extended option data from the header, 0-255 bytes, or null if none.
|
||||
* Returned array does NOT include the length byte.
|
||||
*
|
||||
* @return extended options or null if none is included
|
||||
* @since 0.9.24
|
||||
*/
|
||||
public byte[] readExtendedOptions() {
|
||||
return UDPPacketReader.this.readExtendedOptions();
|
||||
}
|
||||
}
|
||||
|
||||
/** Help read the SessionRequest payload */
|
||||
public class SessionRequestReader {
|
||||
public class SessionRequestReader extends Reader {
|
||||
public static final int X_LENGTH = 256;
|
||||
public void readX(byte target[], int targetOffset) {
|
||||
int readOffset = readBodyOffset();
|
||||
@ -152,20 +205,20 @@ class UDPPacketReader {
|
||||
|
||||
public int readIPSize() {
|
||||
int offset = readBodyOffset() + X_LENGTH;
|
||||
return (int)DataHelper.fromLong(_message, offset, 1);
|
||||
return _message[offset] & 0xff;
|
||||
}
|
||||
|
||||
/** what IP bob is reachable on */
|
||||
public void readIP(byte target[], int targetOffset) {
|
||||
int offset = readBodyOffset() + X_LENGTH;
|
||||
int size = (int)DataHelper.fromLong(_message, offset, 1);
|
||||
int size = _message[offset] & 0xff;
|
||||
offset++;
|
||||
System.arraycopy(_message, offset, target, targetOffset, size);
|
||||
}
|
||||
}
|
||||
|
||||
/** Help read the SessionCreated payload */
|
||||
public class SessionCreatedReader {
|
||||
public class SessionCreatedReader extends Reader {
|
||||
public static final int Y_LENGTH = 256;
|
||||
public void readY(byte target[], int targetOffset) {
|
||||
int readOffset = readBodyOffset();
|
||||
@ -175,13 +228,13 @@ class UDPPacketReader {
|
||||
/** sizeof(IP) */
|
||||
public int readIPSize() {
|
||||
int offset = readBodyOffset() + Y_LENGTH;
|
||||
return (int)DataHelper.fromLong(_message, offset, 1);
|
||||
return _message[offset] & 0xff;
|
||||
}
|
||||
|
||||
/** what IP do they think we are coming on? */
|
||||
public void readIP(byte target[], int targetOffset) {
|
||||
int offset = readBodyOffset() + Y_LENGTH;
|
||||
int size = (int)DataHelper.fromLong(_message, offset, 1);
|
||||
int size = _message[offset] & 0xff;
|
||||
offset++;
|
||||
System.arraycopy(_message, offset, target, targetOffset, size);
|
||||
}
|
||||
@ -220,7 +273,7 @@ class UDPPacketReader {
|
||||
}
|
||||
|
||||
/** parse out the confirmed message */
|
||||
public class SessionConfirmedReader {
|
||||
public class SessionConfirmedReader extends Reader {
|
||||
/** which fragment is this? */
|
||||
public int readCurrentFragmentNum() {
|
||||
int readOffset = readBodyOffset();
|
||||
@ -273,7 +326,7 @@ class UDPPacketReader {
|
||||
}
|
||||
|
||||
/** parse out the data message */
|
||||
public class DataReader {
|
||||
public class DataReader extends Reader {
|
||||
|
||||
/**
|
||||
* @return the data size, NOT including IP header, UDP header, IV, or MAC
|
||||
@ -307,7 +360,7 @@ class UDPPacketReader {
|
||||
public int readACKCount() {
|
||||
if (!readACKsIncluded()) return 0;
|
||||
int off = readBodyOffset() + 1;
|
||||
return (int)DataHelper.fromLong(_message, off, 1);
|
||||
return _message[off] & 0xff;
|
||||
}
|
||||
|
||||
public long readACK(int index) {
|
||||
@ -322,12 +375,12 @@ class UDPPacketReader {
|
||||
if (!readACKBitfieldsIncluded()) return null;
|
||||
int off = readBodyOffset() + 1;
|
||||
if (readACKsIncluded()) {
|
||||
int numACKs = (int)DataHelper.fromLong(_message, off, 1);
|
||||
int numACKs = _message[off] & 0xff;
|
||||
off++;
|
||||
off += 4 * numACKs;
|
||||
}
|
||||
|
||||
int numBitfields = (int)DataHelper.fromLong(_message, off, 1);
|
||||
int numBitfields = _message[off] & 0xff;
|
||||
off++;
|
||||
|
||||
PacketACKBitfield rv[] = new PacketACKBitfield[numBitfields];
|
||||
@ -341,12 +394,12 @@ class UDPPacketReader {
|
||||
public int readFragmentCount() throws DataFormatException {
|
||||
int off = readBodyOffset() + 1;
|
||||
if (readACKsIncluded()) {
|
||||
int numACKs = (int)DataHelper.fromLong(_message, off, 1);
|
||||
int numACKs = _message[off] & 0xff;
|
||||
off++;
|
||||
off += 4 * numACKs;
|
||||
}
|
||||
if (readACKBitfieldsIncluded()) {
|
||||
int numBitfields = (int)DataHelper.fromLong(_message, off, 1);
|
||||
int numBitfields = _message[off] & 0xff;
|
||||
off++;
|
||||
|
||||
for (int i = 0; i < numBitfields; i++) {
|
||||
@ -355,7 +408,7 @@ class UDPPacketReader {
|
||||
}
|
||||
}
|
||||
if (readExtendedDataIncluded()) {
|
||||
int size = (int)DataHelper.fromLong(_message, off, 1);
|
||||
int size = _message[off] & 0xff;
|
||||
off++;
|
||||
off += size;
|
||||
}
|
||||
@ -397,12 +450,12 @@ class UDPPacketReader {
|
||||
private int getFragmentBegin(int fragmentNum) throws DataFormatException {
|
||||
int off = readBodyOffset() + 1;
|
||||
if (readACKsIncluded()) {
|
||||
int numACKs = (int)DataHelper.fromLong(_message, off, 1);
|
||||
int numACKs = _message[off] & 0xff;
|
||||
off++;
|
||||
off += 4 * numACKs;
|
||||
}
|
||||
if (readACKBitfieldsIncluded()) {
|
||||
int numBitfields = (int)DataHelper.fromLong(_message, off, 1);
|
||||
int numBitfields = _message[off] & 0xff;
|
||||
off++;
|
||||
|
||||
PacketACKBitfield bf[] = new PacketACKBitfield[numBitfields];
|
||||
@ -412,7 +465,7 @@ class UDPPacketReader {
|
||||
}
|
||||
}
|
||||
if (readExtendedDataIncluded()) {
|
||||
int size = (int)DataHelper.fromLong(_message, off, 1);
|
||||
int size = _message[off] & 0xff;
|
||||
off++;
|
||||
off += size;
|
||||
}
|
||||
@ -443,7 +496,7 @@ class UDPPacketReader {
|
||||
buf.append(" ");
|
||||
int off = readBodyOffset() + 1;
|
||||
if (readACKsIncluded()) {
|
||||
int numACKs = (int)DataHelper.fromLong(_message, off, 1);
|
||||
int numACKs = _message[off] & 0xff;
|
||||
off++;
|
||||
buf.append("with ACKs for ");
|
||||
for (int i = 0; i < numACKs; i++) {
|
||||
@ -452,7 +505,7 @@ class UDPPacketReader {
|
||||
}
|
||||
}
|
||||
if (readACKBitfieldsIncluded()) {
|
||||
int numBitfields = (int)DataHelper.fromLong(_message, off, 1);
|
||||
int numBitfields = _message[off] & 0xff;
|
||||
off++;
|
||||
buf.append("with partial ACKs for ");
|
||||
|
||||
@ -468,7 +521,7 @@ class UDPPacketReader {
|
||||
}
|
||||
}
|
||||
if (readExtendedDataIncluded()) {
|
||||
int size = (int)DataHelper.fromLong(_message, off, 1);
|
||||
int size = _message[off] & 0xff;
|
||||
off++;
|
||||
buf.append("with extended size of ");
|
||||
buf.append(size);
|
||||
@ -476,7 +529,7 @@ class UDPPacketReader {
|
||||
off += size;
|
||||
}
|
||||
|
||||
int numFragments = (int)DataHelper.fromLong(_message, off, 1);
|
||||
int numFragments = _message[off] & 0xff;
|
||||
off++;
|
||||
buf.append("with fragmentCount of ");
|
||||
buf.append(numFragments);
|
||||
@ -506,8 +559,7 @@ class UDPPacketReader {
|
||||
buf.append(" payload: ");
|
||||
|
||||
int off = getFragmentBegin(0); // first fragment
|
||||
off += 4; // messageId
|
||||
off++; // fragment info
|
||||
off += 4 + 1; // messageId + fragment info
|
||||
int size = ((int)DataHelper.fromLong(_message, off, 2)) & 0x3FFF;
|
||||
off += 2;
|
||||
buf.append(Base64.encode(_message, off, size));
|
||||
@ -610,7 +662,7 @@ class UDPPacketReader {
|
||||
}
|
||||
|
||||
/** Help read the PeerTest payload */
|
||||
public class PeerTestReader {
|
||||
public class PeerTestReader extends Reader {
|
||||
private static final int NONCE_LENGTH = 4;
|
||||
|
||||
public long readNonce() {
|
||||
@ -620,13 +672,13 @@ class UDPPacketReader {
|
||||
|
||||
public int readIPSize() {
|
||||
int offset = readBodyOffset() + NONCE_LENGTH;
|
||||
return (int)DataHelper.fromLong(_message, offset, 1);
|
||||
return _message[offset] & 0xff;
|
||||
}
|
||||
|
||||
/** what IP Alice is reachable on */
|
||||
public void readIP(byte target[], int targetOffset) {
|
||||
int offset = readBodyOffset() + NONCE_LENGTH;
|
||||
int size = (int)DataHelper.fromLong(_message, offset, 1);
|
||||
int size = _message[offset] & 0xff;
|
||||
offset++;
|
||||
System.arraycopy(_message, offset, target, targetOffset, size);
|
||||
}
|
||||
@ -634,7 +686,7 @@ class UDPPacketReader {
|
||||
/** what IP Alice is reachable on */
|
||||
public int readPort() {
|
||||
int offset = readBodyOffset() + NONCE_LENGTH;
|
||||
int size = (int)DataHelper.fromLong(_message, offset, 1);
|
||||
int size = _message[offset] & 0xff;
|
||||
offset++;
|
||||
offset += size; // skip the IP
|
||||
return (int)DataHelper.fromLong(_message, offset, 2);
|
||||
@ -643,16 +695,15 @@ class UDPPacketReader {
|
||||
/** what Alice's intro key is (if known - if unknown, the key is INVALID_KEY) */
|
||||
public void readIntroKey(byte target[], int targetOffset) {
|
||||
int offset = readBodyOffset() + NONCE_LENGTH;
|
||||
int size = (int)DataHelper.fromLong(_message, offset, 1);
|
||||
offset++;
|
||||
int size = _message[offset] & 0xff;
|
||||
offset += 1 + 2; // skip the size + port
|
||||
offset += size; // skip the IP
|
||||
offset += 2; // skip the port
|
||||
System.arraycopy(_message, offset, target, targetOffset, SessionKey.KEYSIZE_BYTES);
|
||||
}
|
||||
}
|
||||
|
||||
/** Help read the RelayRequest payload */
|
||||
public class RelayRequestReader {
|
||||
public class RelayRequestReader extends Reader {
|
||||
public long readTag() {
|
||||
long rv = DataHelper.fromLong(_message, readBodyOffset(), 4);
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
@ -661,7 +712,7 @@ class UDPPacketReader {
|
||||
}
|
||||
public int readIPSize() {
|
||||
int offset = readBodyOffset() + 4;
|
||||
int rv = (int)DataHelper.fromLong(_message, offset, 1);
|
||||
int rv = _message[offset] & 0xff;
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("read alice ip size: " + rv);
|
||||
return rv;
|
||||
@ -670,7 +721,7 @@ class UDPPacketReader {
|
||||
/** what IP Alice is reachable on */
|
||||
public void readIP(byte target[], int targetOffset) {
|
||||
int offset = readBodyOffset() + 4;
|
||||
int size = (int)DataHelper.fromLong(_message, offset, 1);
|
||||
int size = _message[offset] & 0xff;
|
||||
offset++;
|
||||
System.arraycopy(_message, offset, target, targetOffset, size);
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
@ -678,7 +729,7 @@ class UDPPacketReader {
|
||||
}
|
||||
public int readPort() {
|
||||
int offset = readBodyOffset() + 4;
|
||||
offset += DataHelper.fromLong(_message, offset, 1);
|
||||
offset += _message[offset] & 0xff;
|
||||
offset++;
|
||||
int rv = (int)DataHelper.fromLong(_message, offset, 2);
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
@ -689,10 +740,9 @@ class UDPPacketReader {
|
||||
/** unused */
|
||||
public int readChallengeSize() {
|
||||
int offset = readBodyOffset() + 4;
|
||||
offset += DataHelper.fromLong(_message, offset, 1);
|
||||
offset++;
|
||||
offset += 2;
|
||||
int rv = (int)DataHelper.fromLong(_message, offset, 1);
|
||||
offset += _message[offset] & 0xff;
|
||||
offset += 1 + 2;
|
||||
int rv = _message[offset] & 0xff;
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("read challenge size: " + rv);
|
||||
return rv;
|
||||
@ -701,10 +751,9 @@ class UDPPacketReader {
|
||||
/** unused */
|
||||
public void readChallengeSize(byte target[], int targetOffset) {
|
||||
int offset = readBodyOffset() + 4;
|
||||
offset += DataHelper.fromLong(_message, offset, 1);
|
||||
offset++;
|
||||
offset += 2;
|
||||
int sz = (int)DataHelper.fromLong(_message, offset, 1);
|
||||
offset += _message[offset] & 0xff;
|
||||
offset += 1 + 2;
|
||||
int sz = _message[offset] & 0xff;
|
||||
offset++;
|
||||
System.arraycopy(_message, offset, target, targetOffset, sz);
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
@ -712,10 +761,9 @@ class UDPPacketReader {
|
||||
}
|
||||
public void readAliceIntroKey(byte target[], int targetOffset) {
|
||||
int offset = readBodyOffset() + 4;
|
||||
offset += DataHelper.fromLong(_message, offset, 1);
|
||||
offset++;
|
||||
offset += 2;
|
||||
int sz = (int)DataHelper.fromLong(_message, offset, 1);
|
||||
offset += _message[offset] & 0xff;
|
||||
offset += 1 + 2;
|
||||
int sz = _message[offset] & 0xff;
|
||||
offset++;
|
||||
offset += sz;
|
||||
System.arraycopy(_message, offset, target, targetOffset, SessionKey.KEYSIZE_BYTES);
|
||||
@ -725,10 +773,9 @@ class UDPPacketReader {
|
||||
}
|
||||
public long readNonce() {
|
||||
int offset = readBodyOffset() + 4;
|
||||
offset += DataHelper.fromLong(_message, offset, 1);
|
||||
offset++;
|
||||
offset += 2;
|
||||
int sz = (int)DataHelper.fromLong(_message, offset, 1);
|
||||
offset += _message[offset] & 0xff;
|
||||
offset += 1 + 2;
|
||||
int sz = _message[offset] & 0xff;
|
||||
offset++;
|
||||
offset += sz;
|
||||
offset += SessionKey.KEYSIZE_BYTES;
|
||||
@ -740,22 +787,22 @@ class UDPPacketReader {
|
||||
}
|
||||
|
||||
/** Help read the RelayIntro payload */
|
||||
public class RelayIntroReader {
|
||||
public class RelayIntroReader extends Reader {
|
||||
public int readIPSize() {
|
||||
int offset = readBodyOffset();
|
||||
return (int)DataHelper.fromLong(_message, offset, 1);
|
||||
return _message[offset] & 0xff;
|
||||
}
|
||||
|
||||
/** what IP Alice is reachable on */
|
||||
public void readIP(byte target[], int targetOffset) {
|
||||
int offset = readBodyOffset();
|
||||
int size = (int)DataHelper.fromLong(_message, offset, 1);
|
||||
int size = _message[offset] & 0xff;
|
||||
offset++;
|
||||
System.arraycopy(_message, offset, target, targetOffset, size);
|
||||
}
|
||||
public int readPort() {
|
||||
int offset = readBodyOffset();
|
||||
offset += DataHelper.fromLong(_message, offset, 1);
|
||||
offset += _message[offset] & 0xff;
|
||||
offset++;
|
||||
return (int)DataHelper.fromLong(_message, offset, 2);
|
||||
}
|
||||
@ -763,19 +810,17 @@ class UDPPacketReader {
|
||||
/** unused */
|
||||
public int readChallengeSize() {
|
||||
int offset = readBodyOffset();
|
||||
offset += DataHelper.fromLong(_message, offset, 1);
|
||||
offset++;
|
||||
offset += 2;
|
||||
return (int)DataHelper.fromLong(_message, offset, 1);
|
||||
offset += _message[offset] & 0xff;
|
||||
offset += 1 + 2;
|
||||
return _message[offset] & 0xff;
|
||||
}
|
||||
|
||||
/** unused */
|
||||
public void readChallengeSize(byte target[], int targetOffset) {
|
||||
int offset = readBodyOffset();
|
||||
offset += DataHelper.fromLong(_message, offset, 1);
|
||||
offset++;
|
||||
offset += 2;
|
||||
int sz = (int)DataHelper.fromLong(_message, offset, 1);
|
||||
offset += _message[offset] & 0xff;
|
||||
offset += 1 + 2;
|
||||
int sz = _message[offset] & 0xff;
|
||||
offset++;
|
||||
System.arraycopy(_message, offset, target, targetOffset, sz);
|
||||
}
|
||||
@ -783,22 +828,22 @@ class UDPPacketReader {
|
||||
|
||||
|
||||
/** Help read the RelayResponse payload */
|
||||
public class RelayResponseReader {
|
||||
public class RelayResponseReader extends Reader {
|
||||
public int readCharlieIPSize() {
|
||||
int offset = readBodyOffset();
|
||||
return (int)DataHelper.fromLong(_message, offset, 1);
|
||||
return _message[offset] & 0xff;
|
||||
}
|
||||
/** what IP charlie is reachable on */
|
||||
public void readCharlieIP(byte target[], int targetOffset) {
|
||||
int offset = readBodyOffset();
|
||||
int size = (int)DataHelper.fromLong(_message, offset, 1);
|
||||
int size = _message[offset] & 0xff;
|
||||
offset++;
|
||||
System.arraycopy(_message, offset, target, targetOffset, size);
|
||||
}
|
||||
/** what port charlie is reachable on */
|
||||
public int readCharliePort() {
|
||||
int offset = readBodyOffset();
|
||||
offset += DataHelper.fromLong(_message, offset, 1);
|
||||
offset += _message[offset] & 0xff;
|
||||
offset++;
|
||||
return (int)DataHelper.fromLong(_message, offset, 2);
|
||||
}
|
||||
@ -806,41 +851,36 @@ class UDPPacketReader {
|
||||
/** @deprecated unused */
|
||||
public int readAliceIPSize() {
|
||||
int offset = readBodyOffset();
|
||||
offset += DataHelper.fromLong(_message, offset, 1);
|
||||
offset++;
|
||||
offset += 2;
|
||||
return (int)DataHelper.fromLong(_message, offset, 1);
|
||||
offset += _message[offset] & 0xff;
|
||||
offset += 1 + 2;
|
||||
return _message[offset] & 0xff;
|
||||
}
|
||||
/** @deprecated unused */
|
||||
public void readAliceIP(byte target[], int targetOffset) {
|
||||
int offset = readBodyOffset();
|
||||
offset += DataHelper.fromLong(_message, offset, 1);
|
||||
offset++;
|
||||
offset += 2;
|
||||
int sz = (int)DataHelper.fromLong(_message, offset, 1);
|
||||
offset += _message[offset] & 0xff;
|
||||
offset += 1 + 2;
|
||||
int sz = _message[offset] & 0xff;
|
||||
offset++;
|
||||
System.arraycopy(_message, offset, target, targetOffset, sz);
|
||||
}
|
||||
/** @deprecated unused */
|
||||
public int readAlicePort() {
|
||||
int offset = readBodyOffset();
|
||||
offset += DataHelper.fromLong(_message, offset, 1);
|
||||
offset++;
|
||||
offset += 2;
|
||||
int sz = (int)DataHelper.fromLong(_message, offset, 1);
|
||||
offset += _message[offset] & 0xff;
|
||||
offset += 1 + 2;
|
||||
int sz = _message[offset] & 0xff;
|
||||
offset++;
|
||||
offset += sz;
|
||||
return (int)DataHelper.fromLong(_message, offset, 2);
|
||||
}
|
||||
public long readNonce() {
|
||||
int offset = readBodyOffset();
|
||||
offset += DataHelper.fromLong(_message, offset, 1);
|
||||
offset++;
|
||||
offset += 2;
|
||||
int sz = (int)DataHelper.fromLong(_message, offset, 1);
|
||||
offset++;
|
||||
offset += _message[offset] & 0xff;
|
||||
offset += 1 + 2;
|
||||
int sz = _message[offset] & 0xff;
|
||||
offset += 1 + 2; // sz + port
|
||||
offset += sz;
|
||||
offset += 2;
|
||||
return DataHelper.fromLong(_message, offset, 4);
|
||||
}
|
||||
}
|
||||
|
@ -340,7 +340,7 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority
|
||||
|
||||
List<InetAddress> bindToAddrs = new ArrayList<InetAddress>(4);
|
||||
if (bindTo != null) {
|
||||
String[] bta = bindTo.split("[,; \r\n\t]");
|
||||
String[] bta = DataHelper.split(bindTo, "[,; \r\n\t]");
|
||||
for (int i = 0; i < bta.length; i++) {
|
||||
String bt = bta[i];
|
||||
if (bt.length() <= 0)
|
||||
@ -1896,7 +1896,7 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority
|
||||
if (explicitAddressSpecified()) {
|
||||
host = _context.getProperty(PROP_EXTERNAL_HOST);
|
||||
if (host != null) {
|
||||
String[] hosts = host.split("[,; \r\n\t]");
|
||||
String[] hosts = DataHelper.split(host, "[,; \r\n\t]");
|
||||
RouterAddress rv = null;
|
||||
for (int i = 0; i < hosts.length; i++) {
|
||||
String h = hosts[i];
|
||||
@ -2216,6 +2216,7 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("Require introducers, because our status is " + status);
|
||||
return true;
|
||||
|
||||
default:
|
||||
if (!allowDirectUDP()) {
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
@ -2226,6 +2227,30 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* MIGHT we require introducers?
|
||||
* This is like introducersRequired, but if we aren't sure, this returns true.
|
||||
* Used only by EstablishmentManager.
|
||||
*
|
||||
* @since 0.9.24
|
||||
*/
|
||||
boolean introducersMaybeRequired() {
|
||||
Status status = getReachabilityStatus();
|
||||
switch (status) {
|
||||
case REJECT_UNSOLICITED:
|
||||
case DIFFERENT:
|
||||
case IPV4_FIREWALLED_IPV6_OK:
|
||||
case IPV4_FIREWALLED_IPV6_UNKNOWN:
|
||||
case IPV4_UNKNOWN_IPV6_OK:
|
||||
case IPV4_UNKNOWN_IPV6_FIREWALLED:
|
||||
case UNKNOWN:
|
||||
return true;
|
||||
|
||||
default:
|
||||
return !allowDirectUDP();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* For EstablishmentManager
|
||||
* @since 0.9.3
|
||||
|
@ -120,7 +120,7 @@ public class BuildReplyHandler {
|
||||
return -1;
|
||||
} else {
|
||||
SimpleByteCache.release(h);
|
||||
int rv = (int)DataHelper.fromLong(data, TunnelBuildReplyMessage.RECORD_SIZE - 1, 1);
|
||||
int rv = data[TunnelBuildReplyMessage.RECORD_SIZE - 1] & 0xff;
|
||||
if (log.shouldLog(Log.DEBUG))
|
||||
log.debug(reply.getUniqueId() + ": Verified: " + rv + " for record " + recordNum + "/" + hop);
|
||||
return rv;
|
||||
|
@ -340,7 +340,7 @@ class FragmentHandler {
|
||||
offset += 4;
|
||||
}
|
||||
if (extended) {
|
||||
int extendedSize = (int)DataHelper.fromLong(preprocessed, offset, 1);
|
||||
int extendedSize = preprocessed[offset] & 0xff;
|
||||
offset++;
|
||||
offset += extendedSize; // we don't interpret these yet, but skip them for now
|
||||
}
|
||||
|
@ -51,12 +51,14 @@ public class HopConfig {
|
||||
public void setReceiveTunnelId(byte id[]) { _receiveTunnelId = id; }
|
||||
public void setReceiveTunnelId(TunnelId id) { _receiveTunnelId = DataHelper.toLong(4, id.getTunnelId()); }
|
||||
|
||||
/** what is the previous peer in the tunnel (if any)? */
|
||||
/** what is the previous peer in the tunnel (null if gateway) */
|
||||
public Hash getReceiveFrom() { return _receiveFrom; }
|
||||
public void setReceiveFrom(Hash from) { _receiveFrom = from; }
|
||||
|
||||
/** what is the next tunnel ID we are sending to? */
|
||||
/** what is the next tunnel ID we are sending to? (null if endpoint) */
|
||||
public byte[] getSendTunnelId() { return _sendTunnelId; }
|
||||
|
||||
/** what is the next tunnel we are sending to? (null if endpoint) */
|
||||
public TunnelId getSendTunnel() {
|
||||
if (_sendTunnel == null)
|
||||
_sendTunnel = getTunnel(_sendTunnelId);
|
||||
@ -71,7 +73,7 @@ public class HopConfig {
|
||||
return new TunnelId(DataHelper.fromLong(id, 0, id.length));
|
||||
}
|
||||
|
||||
/** what is the next peer in the tunnel (if any)? */
|
||||
/** what is the next peer in the tunnel (null if endpoint) */
|
||||
public Hash getSendTo() { return _sendTo; }
|
||||
public void setSendTo(Hash to) { _sendTo = to; }
|
||||
|
||||
|
@ -30,16 +30,32 @@ public class TunnelCreatorConfig implements TunnelInfo {
|
||||
private long _replyMessageId;
|
||||
private final boolean _isInbound;
|
||||
private int _messagesProcessed;
|
||||
private volatile long _verifiedBytesTransferred;
|
||||
private long _verifiedBytesTransferred;
|
||||
private boolean _failed;
|
||||
private int _failures;
|
||||
private boolean _reused;
|
||||
private int _priority;
|
||||
//private static final int THROUGHPUT_COUNT = 3;
|
||||
// Fastest 1 minute throughput, in bytes per minute, ordered with fastest first.
|
||||
//private final double _peakThroughput[] = new double[THROUGHPUT_COUNT];
|
||||
private long _peakThroughputCurrentTotal;
|
||||
private long _peakThroughputLastCoallesce = System.currentTimeMillis();
|
||||
// Make configurable? - but can't easily get to pool options from here
|
||||
private static final int MAX_CONSECUTIVE_TEST_FAILURES = 3;
|
||||
private static final SimpleDateFormat _fmt = new SimpleDateFormat("HH:mm:ss", Locale.UK);
|
||||
|
||||
/**
|
||||
* For exploratory only (null destination)
|
||||
* @param length 1 minimum (0 hop is length 1)
|
||||
*/
|
||||
public TunnelCreatorConfig(RouterContext ctx, int length, boolean isInbound) {
|
||||
this(ctx, length, isInbound, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param length 1 minimum (0 hop is length 1)
|
||||
* @param destination null for exploratory
|
||||
*/
|
||||
public TunnelCreatorConfig(RouterContext ctx, int length, boolean isInbound, Hash destination) {
|
||||
_context = ctx;
|
||||
if (length <= 0)
|
||||
@ -131,10 +147,14 @@ public class TunnelCreatorConfig implements TunnelInfo {
|
||||
public void setReplyMessageId(long id) { _replyMessageId = id; }
|
||||
|
||||
/** take note of a message being pumped through this tunnel */
|
||||
public void incrementProcessedMessages() { _messagesProcessed++; }
|
||||
public int getProcessedMessagesCount() { return _messagesProcessed; }
|
||||
public synchronized void incrementProcessedMessages() { _messagesProcessed++; }
|
||||
public synchronized int getProcessedMessagesCount() { return _messagesProcessed; }
|
||||
|
||||
public void incrementVerifiedBytesTransferred(int bytes) {
|
||||
/**
|
||||
* This calls profile manager tunnelDataPushed1m() for each peer
|
||||
* @return null for exploratory
|
||||
*/
|
||||
public synchronized void incrementVerifiedBytesTransferred(int bytes) {
|
||||
_verifiedBytesTransferred += bytes;
|
||||
_peakThroughputCurrentTotal += bytes;
|
||||
long now = System.currentTimeMillis();
|
||||
@ -144,38 +164,34 @@ public class TunnelCreatorConfig implements TunnelInfo {
|
||||
double normalized = tot * 60d*1000d / timeSince;
|
||||
_peakThroughputLastCoallesce = now;
|
||||
_peakThroughputCurrentTotal = 0;
|
||||
if (_context != null)
|
||||
for (int i = 0; i < _peers.length; i++)
|
||||
if (_context != null) {
|
||||
// skip ourselves
|
||||
int start = _isInbound ? 0 : 1;
|
||||
int end = _isInbound ? _peers.length - 1 : _peers.length;
|
||||
for (int i = start; i < end; i++) {
|
||||
_context.profileManager().tunnelDataPushed1m(_peers[i], (int)normalized);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public long getVerifiedBytesTransferred() { return _verifiedBytesTransferred; }
|
||||
public synchronized long getVerifiedBytesTransferred() { return _verifiedBytesTransferred; }
|
||||
|
||||
private static final int THROUGHPUT_COUNT = 3;
|
||||
/**
|
||||
* fastest 1 minute throughput, in bytes per minute, ordered with fastest
|
||||
* first.
|
||||
*/
|
||||
private final double _peakThroughput[] = new double[THROUGHPUT_COUNT];
|
||||
private volatile long _peakThroughputCurrentTotal;
|
||||
private volatile long _peakThroughputLastCoallesce = System.currentTimeMillis();
|
||||
public double getPeakThroughputKBps() {
|
||||
/**** unused
|
||||
public synchronized double getPeakThroughputKBps() {
|
||||
double rv = 0;
|
||||
for (int i = 0; i < THROUGHPUT_COUNT; i++)
|
||||
rv += _peakThroughput[i];
|
||||
rv /= (60d*1024d*THROUGHPUT_COUNT);
|
||||
return rv;
|
||||
}
|
||||
public void setPeakThroughputKBps(double kBps) {
|
||||
|
||||
public synchronized void setPeakThroughputKBps(double kBps) {
|
||||
_peakThroughput[0] = kBps*60*1024;
|
||||
//for (int i = 0; i < THROUGHPUT_COUNT; i++)
|
||||
// _peakThroughput[i] = kBps*60;
|
||||
}
|
||||
|
||||
|
||||
// Make configurable? - but can't easily get to pool options from here
|
||||
private static final int MAX_CONSECUTIVE_TEST_FAILURES = 3;
|
||||
****/
|
||||
|
||||
/**
|
||||
* The tunnel failed a test, so (maybe) stop using it
|
||||
@ -264,11 +280,10 @@ public class TunnelCreatorConfig implements TunnelInfo {
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
private static final SimpleDateFormat _fmt = new SimpleDateFormat("HH:mm:ss", Locale.UK);
|
||||
|
||||
private String getExpirationString() {
|
||||
return format(_expiration);
|
||||
}
|
||||
|
||||
static String format(long date) {
|
||||
Date d = new Date(date);
|
||||
synchronized (_fmt) {
|
||||
|
@ -457,7 +457,8 @@ public class TunnelDispatcher implements Service {
|
||||
_inboundGateways.remove(recvId);
|
||||
} else {
|
||||
// update stats based off getCompleteCount() + getFailedCount()
|
||||
for (int i = 0; i < cfg.getLength(); i++) {
|
||||
// skip last hop (us)
|
||||
for (int i = 0; i < cfg.getLength() - 1; i++) {
|
||||
Hash peer = cfg.getPeer(i);
|
||||
PeerProfile profile = _context.profileOrganizer().getProfile(peer);
|
||||
if (profile != null) {
|
||||
|
@ -213,7 +213,7 @@ class BuildHandler implements Runnable {
|
||||
while (_isRunning && !_manager.isShutdown()) {
|
||||
try {
|
||||
handleInboundRequest();
|
||||
} catch (Exception e) {
|
||||
} catch (RuntimeException e) {
|
||||
_log.log(Log.CRIT, "B0rked in the tunnel handler", e);
|
||||
}
|
||||
}
|
||||
@ -795,7 +795,8 @@ class BuildHandler implements Runnable {
|
||||
cfg.setIVKey(req.readIVKey());
|
||||
cfg.setLayerKey(req.readLayerKey());
|
||||
if (isInGW) {
|
||||
cfg.setReceiveFrom(null);
|
||||
// default
|
||||
//cfg.setReceiveFrom(null);
|
||||
} else {
|
||||
if (state.fromHash != null) {
|
||||
cfg.setReceiveFrom(state.fromHash);
|
||||
@ -808,8 +809,9 @@ class BuildHandler implements Runnable {
|
||||
}
|
||||
cfg.setReceiveTunnelId(DataHelper.toLong(4, ourId));
|
||||
if (isOutEnd) {
|
||||
cfg.setSendTo(null);
|
||||
cfg.setSendTunnelId(null);
|
||||
// default
|
||||
//cfg.setSendTo(null);
|
||||
//cfg.setSendTunnelId(null);
|
||||
} else {
|
||||
cfg.setSendTo(nextPeer);
|
||||
cfg.setSendTunnelId(DataHelper.toLong(4, nextId));
|
||||
|
@ -1168,7 +1168,7 @@ public class TunnelPool {
|
||||
int j = peers.size() - 1 - i;
|
||||
cfg.setPeer(j, peers.get(i));
|
||||
HopConfig hop = cfg.getConfig(j);
|
||||
hop.setCreation(_context.clock().now());
|
||||
hop.setCreation(now);
|
||||
hop.setExpiration(expiration);
|
||||
hop.setIVKey(_context.keyGenerator().generateSessionKey());
|
||||
hop.setLayerKey(_context.keyGenerator().generateSessionKey());
|
||||
|
@ -13,6 +13,7 @@ import java.util.SortedMap;
|
||||
import java.util.TreeMap;
|
||||
|
||||
import net.i2p.I2PAppContext;
|
||||
import net.i2p.data.DataHelper;
|
||||
import net.i2p.util.SecureFileOutputStream;
|
||||
|
||||
/**
|
||||
@ -125,7 +126,7 @@ public class EventLog {
|
||||
String line = null;
|
||||
while ( (line = br.readLine()) != null) {
|
||||
try {
|
||||
String[] s = line.split(" ", 3);
|
||||
String[] s = DataHelper.split(line, " ", 3);
|
||||
if (!s[1].equals(event))
|
||||
continue;
|
||||
long time = Long.parseLong(s[0]);
|
||||
@ -167,7 +168,7 @@ public class EventLog {
|
||||
String line = null;
|
||||
while ( (line = br.readLine()) != null) {
|
||||
try {
|
||||
String[] s = line.split(" ", 2);
|
||||
String[] s = DataHelper.split(line, " ", 2);
|
||||
if (s.length < 2)
|
||||
continue;
|
||||
long time = Long.parseLong(s[0]);
|
||||
|
Reference in New Issue
Block a user