forked from I2P_Developers/i2p.i2p
I2NP: Remove unused InputStream parsing methods
This commit is contained in:
@ -160,61 +160,14 @@ public class DeliveryInstructions extends DataStructureImpl {
|
|||||||
*/
|
*/
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public void setDelaySeconds(long seconds) { _delaySeconds = seconds; }
|
public void setDelaySeconds(long seconds) { _delaySeconds = seconds; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @deprecated unused
|
* @deprecated unused
|
||||||
|
* @throws UnsupportedOperationException always
|
||||||
*/
|
*/
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public void readBytes(InputStream in) throws DataFormatException, IOException {
|
public void readBytes(InputStream in) {
|
||||||
long flags = DataHelper.readLong(in, 1);
|
throw new UnsupportedOperationException();
|
||||||
//if (_log.shouldLog(Log.DEBUG))
|
|
||||||
// _log.debug("Read flags: " + flags + " mode: " + flagMode(flags));
|
|
||||||
|
|
||||||
/****
|
|
||||||
if (flagEncrypted(flags)) {
|
|
||||||
SessionKey k = new SessionKey();
|
|
||||||
k.readBytes(in);
|
|
||||||
setEncryptionKey(k);
|
|
||||||
setEncrypted(true);
|
|
||||||
} else {
|
|
||||||
setEncrypted(false);
|
|
||||||
}
|
|
||||||
****/
|
|
||||||
|
|
||||||
setDeliveryMode(flagMode(flags));
|
|
||||||
switch (flagMode(flags)) {
|
|
||||||
case FLAG_MODE_LOCAL:
|
|
||||||
break;
|
|
||||||
case FLAG_MODE_DESTINATION:
|
|
||||||
//Hash destHash = new Hash();
|
|
||||||
//destHash.readBytes(in);
|
|
||||||
Hash destHash = Hash.create(in);
|
|
||||||
setDestination(destHash);
|
|
||||||
break;
|
|
||||||
case FLAG_MODE_ROUTER:
|
|
||||||
//Hash routerHash = new Hash();
|
|
||||||
//routerHash.readBytes(in);
|
|
||||||
Hash routerHash = Hash.create(in);
|
|
||||||
setRouter(routerHash);
|
|
||||||
break;
|
|
||||||
case FLAG_MODE_TUNNEL:
|
|
||||||
//Hash tunnelRouterHash = new Hash();
|
|
||||||
//tunnelRouterHash.readBytes(in);
|
|
||||||
Hash tunnelRouterHash = Hash.create(in);
|
|
||||||
setRouter(tunnelRouterHash);
|
|
||||||
TunnelId id = new TunnelId();
|
|
||||||
id.readBytes(in);
|
|
||||||
setTunnelId(id);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (flagDelay(flags)) {
|
|
||||||
long delay = DataHelper.readLong(in, 4);
|
|
||||||
setDelayRequested(true);
|
|
||||||
setDelaySeconds(delay);
|
|
||||||
} else {
|
|
||||||
setDelayRequested(false);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public int readBytes(byte data[], int offset) throws DataFormatException {
|
public int readBytes(byte data[], int offset) throws DataFormatException {
|
||||||
@ -576,11 +529,6 @@ public class DeliveryInstructions extends DataStructureImpl {
|
|||||||
throw new RuntimeException("immutable");
|
throw new RuntimeException("immutable");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void readBytes(InputStream in) throws DataFormatException, IOException {
|
|
||||||
throw new RuntimeException("immutable");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int readBytes(byte data[], int offset) throws DataFormatException {
|
public int readBytes(byte data[], int offset) throws DataFormatException {
|
||||||
throw new RuntimeException("immutable");
|
throw new RuntimeException("immutable");
|
||||||
|
@ -9,7 +9,6 @@ package net.i2p.data.i2np;
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
|
|
||||||
import net.i2p.I2PAppContext;
|
import net.i2p.I2PAppContext;
|
||||||
@ -49,26 +48,6 @@ public abstract class FastI2NPMessageImpl extends I2NPMessageImpl {
|
|||||||
super(context);
|
super(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @deprecated unused
|
|
||||||
* @throws UnsupportedOperationException
|
|
||||||
*/
|
|
||||||
@Deprecated
|
|
||||||
@Override
|
|
||||||
public void readBytes(InputStream in) throws DataFormatException, IOException {
|
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @deprecated unused
|
|
||||||
* @throws UnsupportedOperationException
|
|
||||||
*/
|
|
||||||
@Deprecated
|
|
||||||
@Override
|
|
||||||
public int readBytes(InputStream in, int type, byte buffer[]) throws I2NPMessageException, IOException {
|
|
||||||
throw new UnsupportedOperationException();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Ignore, but save, the checksum, to be used later if necessary.
|
* Ignore, but save, the checksum, to be used later if necessary.
|
||||||
*
|
*
|
||||||
|
@ -61,28 +61,8 @@ public class GarlicClove extends DataStructureImpl {
|
|||||||
* @throws UnsupportedOperationException always
|
* @throws UnsupportedOperationException always
|
||||||
*/
|
*/
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public void readBytes(InputStream in) throws DataFormatException, IOException {
|
public void readBytes(InputStream in) {
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
/****
|
|
||||||
_instructions = new DeliveryInstructions();
|
|
||||||
_instructions.readBytes(in);
|
|
||||||
if (_log.shouldLog(Log.DEBUG))
|
|
||||||
_log.debug("Read instructions: " + _instructions);
|
|
||||||
try {
|
|
||||||
_msg = _handler.readMessage(in);
|
|
||||||
} catch (I2NPMessageException ime) {
|
|
||||||
throw new DataFormatException("Unable to read the message from a garlic clove", ime);
|
|
||||||
}
|
|
||||||
_cloveId = DataHelper.readLong(in, 4);
|
|
||||||
_expiration = DataHelper.readDate(in);
|
|
||||||
if (_log.shouldLog(Log.DEBUG))
|
|
||||||
_log.debug("CloveID read: " + _cloveId + " expiration read: " + _expiration);
|
|
||||||
//_certificate = new Certificate();
|
|
||||||
//_certificate.readBytes(in);
|
|
||||||
_certificate = Certificate.create(in);
|
|
||||||
if (_log.shouldLog(Log.DEBUG))
|
|
||||||
_log.debug("Read cert: " + _certificate);
|
|
||||||
****/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -9,7 +9,6 @@ package net.i2p.data.i2np;
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
|
||||||
|
|
||||||
import net.i2p.data.DataStructure;
|
import net.i2p.data.DataStructure;
|
||||||
|
|
||||||
@ -31,26 +30,6 @@ public interface I2NPMessage extends DataStructure {
|
|||||||
*/
|
*/
|
||||||
public static final int MAX_SIZE = 64*1024;
|
public static final int MAX_SIZE = 64*1024;
|
||||||
|
|
||||||
/**
|
|
||||||
* Read the body into the data structures, after the initial type byte, using
|
|
||||||
* the current class's format as defined by the I2NP specification
|
|
||||||
*
|
|
||||||
* Unused - All transports provide encapsulation and so we have byte arrays available.
|
|
||||||
*
|
|
||||||
* @param in stream to read from
|
|
||||||
* starting at type if type is < 0 (16 byte header)
|
|
||||||
* starting at ID if type is >= 0 (15 byte header)
|
|
||||||
* @param type I2NP message type. If less than zero, read the type from data
|
|
||||||
* @param buffer scratch buffer to be used when reading and parsing
|
|
||||||
* @return size of the message read (including headers)
|
|
||||||
* @throws I2NPMessageException if the stream doesn't contain a valid message
|
|
||||||
* that this class can read.
|
|
||||||
* @throws IOException if there is a problem reading from the stream
|
|
||||||
* @deprecated unused
|
|
||||||
*/
|
|
||||||
@Deprecated
|
|
||||||
public int readBytes(InputStream in, int type, byte buffer[]) throws I2NPMessageException, IOException;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Read the body into the data structures, after the initial type byte, using
|
* Read the body into the data structures, after the initial type byte, using
|
||||||
* the current class's format as defined by the I2NP specification
|
* the current class's format as defined by the I2NP specification
|
||||||
|
@ -9,7 +9,6 @@ package net.i2p.data.i2np;
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
|
||||||
|
|
||||||
import net.i2p.I2PAppContext;
|
import net.i2p.I2PAppContext;
|
||||||
import net.i2p.data.DataFormatException;
|
import net.i2p.data.DataFormatException;
|
||||||
@ -35,40 +34,6 @@ public class I2NPMessageHandler {
|
|||||||
_lastSize = -1;
|
_lastSize = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Read an I2NPMessage from the stream and return the fully populated object.
|
|
||||||
*
|
|
||||||
* This is only called by I2NPMessageReader which is unused.
|
|
||||||
* All transports provide encapsulation and so we have byte arrays available.
|
|
||||||
*
|
|
||||||
* @deprecated use the byte array method to avoid an extra copy if you have it
|
|
||||||
*
|
|
||||||
* @throws I2NPMessageException if there is a problem handling the particular
|
|
||||||
* message - if it is an unknown type or has improper formatting, etc.
|
|
||||||
*/
|
|
||||||
@Deprecated
|
|
||||||
public I2NPMessage readMessage(InputStream in) throws IOException, I2NPMessageException {
|
|
||||||
if (_messageBuffer == null) _messageBuffer = new byte[38*1024]; // more than necessary
|
|
||||||
try {
|
|
||||||
int type = (int)DataHelper.readLong(in, 1);
|
|
||||||
_lastReadBegin = System.currentTimeMillis();
|
|
||||||
I2NPMessage msg = I2NPMessageImpl.createMessage(_context, type);
|
|
||||||
try {
|
|
||||||
_lastSize = msg.readBytes(in, type, _messageBuffer);
|
|
||||||
} catch (I2NPMessageException ime) {
|
|
||||||
throw ime;
|
|
||||||
} 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);
|
|
||||||
}
|
|
||||||
_lastReadEnd = System.currentTimeMillis();
|
|
||||||
return msg;
|
|
||||||
} catch (DataFormatException dfe) {
|
|
||||||
throw new I2NPMessageException("Error reading the message", dfe);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** clear the last message read from a byte array with an offset */
|
/** clear the last message read from a byte array with an offset */
|
||||||
public I2NPMessage lastRead() {
|
public I2NPMessage lastRead() {
|
||||||
I2NPMessage rv = _lastRead;
|
I2NPMessage rv = _lastRead;
|
||||||
@ -129,14 +94,4 @@ public class I2NPMessageHandler {
|
|||||||
public long getLastReadTime() { return _lastReadEnd - _lastReadBegin; }
|
public long getLastReadTime() { return _lastReadEnd - _lastReadBegin; }
|
||||||
public int getLastSize() { return _lastSize; }
|
public int getLastSize() { return _lastSize; }
|
||||||
|
|
||||||
/****
|
|
||||||
public static void main(String args[]) {
|
|
||||||
try {
|
|
||||||
I2NPMessage msg = new I2NPMessageHandler(I2PAppContext.getGlobalContext()).readMessage(new FileInputStream(args[0]));
|
|
||||||
System.out.println(msg);
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
****/
|
|
||||||
}
|
}
|
||||||
|
@ -72,91 +72,15 @@ public abstract class I2NPMessageImpl extends DataStructureImpl implements I2NPM
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Read the whole message but only if it's exactly 1024 bytes.
|
* Read the whole message.
|
||||||
* Unused - All transports provide encapsulation and so we have byte arrays available.
|
* Unused - All transports provide encapsulation and so we have byte arrays available.
|
||||||
*
|
*
|
||||||
* @deprecated unused
|
* @deprecated unused
|
||||||
|
* @throws UnsupportedOperationException always
|
||||||
*/
|
*/
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public void readBytes(InputStream in) throws DataFormatException, IOException {
|
public void readBytes(InputStream in) {
|
||||||
try {
|
throw new UnsupportedOperationException();
|
||||||
readBytes(in, -1, new byte[1024]);
|
|
||||||
} catch (I2NPMessageException ime) {
|
|
||||||
throw new DataFormatException("Bad bytes", ime);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Read the header, then read the rest into buffer, then call
|
|
||||||
* readMessage in the implemented message type
|
|
||||||
*
|
|
||||||
* This does a copy from the stream to the buffer, so if you already
|
|
||||||
* have a byte array, use the other readBytes() instead.
|
|
||||||
*
|
|
||||||
*<pre>
|
|
||||||
* Specifically:
|
|
||||||
* 1 byte type (if caller didn't read already, as specified by the type param
|
|
||||||
* 4 byte ID
|
|
||||||
* 8 byte expiration
|
|
||||||
* 2 byte size
|
|
||||||
* 1 byte checksum
|
|
||||||
* size bytes of payload (read by readMessage() in implementation)
|
|
||||||
*</pre>
|
|
||||||
*
|
|
||||||
* Unused - All transports provide encapsulation and so we have byte arrays available.
|
|
||||||
*
|
|
||||||
* @param type the message type or -1 if we should read it here
|
|
||||||
* @param buffer temp buffer to use
|
|
||||||
* @return total length of the message
|
|
||||||
* @deprecated unused
|
|
||||||
*/
|
|
||||||
@Deprecated
|
|
||||||
public int readBytes(InputStream in, int type, byte buffer[]) throws I2NPMessageException, IOException {
|
|
||||||
try {
|
|
||||||
if (type < 0)
|
|
||||||
type = (int)DataHelper.readLong(in, 1);
|
|
||||||
_uniqueId = DataHelper.readLong(in, 4);
|
|
||||||
_expiration = DataHelper.readLong(in, DataHelper.DATE_LENGTH);
|
|
||||||
int size = (int)DataHelper.readLong(in, 2);
|
|
||||||
byte checksum[] = new byte[CHECKSUM_LENGTH];
|
|
||||||
int read = DataHelper.read(in, checksum);
|
|
||||||
if (read != CHECKSUM_LENGTH)
|
|
||||||
throw new I2NPMessageException("checksum is too small [" + read + "]");
|
|
||||||
//Hash h = new Hash();
|
|
||||||
//h.readBytes(in);
|
|
||||||
if (buffer.length < size) {
|
|
||||||
if (size > MAX_SIZE) throw new I2NPMessageException("size=" + size);
|
|
||||||
buffer = new byte[size];
|
|
||||||
}
|
|
||||||
|
|
||||||
int cur = 0;
|
|
||||||
while (cur < size) {
|
|
||||||
int numRead = in.read(buffer, cur, size- cur);
|
|
||||||
if (numRead == -1) {
|
|
||||||
throw new I2NPMessageException("Payload is too short [" + numRead + ", wanted " + size + "]");
|
|
||||||
}
|
|
||||||
cur += numRead;
|
|
||||||
}
|
|
||||||
|
|
||||||
byte[] calc = SimpleByteCache.acquire(Hash.HASH_LENGTH);
|
|
||||||
_context.sha().calculateHash(buffer, 0, size, calc, 0);
|
|
||||||
//boolean eq = calc.equals(h);
|
|
||||||
boolean eq = DataHelper.eq(checksum, 0, calc, 0, CHECKSUM_LENGTH);
|
|
||||||
SimpleByteCache.release(calc);
|
|
||||||
if (!eq)
|
|
||||||
throw new I2NPMessageException("Bad checksum on " + size + " byte I2NP " + getClass().getSimpleName());
|
|
||||||
|
|
||||||
//long start = _context.clock().now();
|
|
||||||
if (_log.shouldLog(Log.DEBUG))
|
|
||||||
_log.debug("Reading bytes: type = " + type + " / uniqueId : " + _uniqueId + " / expiration : " + _expiration);
|
|
||||||
readMessage(buffer, 0, size, type);
|
|
||||||
//long time = _context.clock().now() - start;
|
|
||||||
//if (time > 50)
|
|
||||||
// _context.statManager().addRateData("i2np.readTime", time, time);
|
|
||||||
return CHECKSUM_LENGTH + 1 + 2 + 4 + DataHelper.DATE_LENGTH + size;
|
|
||||||
} catch (DataFormatException dfe) {
|
|
||||||
throw new I2NPMessageException("Error reading the message header", dfe);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1,213 +0,0 @@
|
|||||||
package net.i2p.data.i2np;
|
|
||||||
/*
|
|
||||||
* free (adj.): unencumbered; not under the control of others
|
|
||||||
* Written by jrandom in 2003 and released into the public domain
|
|
||||||
* with no warranty of any kind, either expressed or implied.
|
|
||||||
* It probably won't make your computer catch on fire, or eat
|
|
||||||
* your children, but it might. Use at your own risk.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.io.InterruptedIOException;
|
|
||||||
|
|
||||||
import net.i2p.router.RouterContext;
|
|
||||||
import net.i2p.util.I2PThread;
|
|
||||||
import net.i2p.util.Log;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The I2NPMessageReader reads an InputStream (using
|
|
||||||
* {@link I2NPMessageHandler I2NPMessageHandler}) and passes out events to a registered
|
|
||||||
* listener, where events are either messages being received, exceptions being
|
|
||||||
* thrown, or the connection being closed. Routers should use this rather
|
|
||||||
* than read from the stream themselves.
|
|
||||||
*
|
|
||||||
* Deprecated - unused.
|
|
||||||
* This was used by the old TCP transport.
|
|
||||||
* Both the NTCP and SSU transports provide encapsulation
|
|
||||||
* of I2NP messages, so they use I2NPMessageHandlers directly.
|
|
||||||
* If we ever add a transport that does not provide encapsulation,
|
|
||||||
* this will be useful again.
|
|
||||||
*
|
|
||||||
* @deprecated unused
|
|
||||||
*
|
|
||||||
* @author jrandom
|
|
||||||
*/
|
|
||||||
@Deprecated
|
|
||||||
public class I2NPMessageReader {
|
|
||||||
private Log _log;
|
|
||||||
private RouterContext _context;
|
|
||||||
private InputStream _stream;
|
|
||||||
private I2NPMessageEventListener _listener;
|
|
||||||
private I2NPMessageReaderRunner _reader;
|
|
||||||
private Thread _readerThread;
|
|
||||||
|
|
||||||
public I2NPMessageReader(RouterContext context, InputStream stream, I2NPMessageEventListener lsnr) {
|
|
||||||
this(context, stream, lsnr, "I2NP Reader");
|
|
||||||
}
|
|
||||||
|
|
||||||
public I2NPMessageReader(RouterContext context, InputStream stream, I2NPMessageEventListener lsnr, String name) {
|
|
||||||
_context = context;
|
|
||||||
_log = context.logManager().getLog(I2NPMessageReader.class);
|
|
||||||
_stream = stream;
|
|
||||||
setListener(lsnr);
|
|
||||||
_reader = new I2NPMessageReaderRunner();
|
|
||||||
_readerThread = new I2PThread(_reader);
|
|
||||||
_readerThread.setName(name);
|
|
||||||
_readerThread.setDaemon(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setListener(I2NPMessageEventListener lsnr) { _listener = lsnr; }
|
|
||||||
public I2NPMessageEventListener getListener() { return _listener; }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Instruct the reader to begin reading messages off the stream
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public void startReading() { _readerThread.start(); }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Have the already started reader pause its reading indefinitely
|
|
||||||
* @deprecated unused
|
|
||||||
*/
|
|
||||||
@Deprecated
|
|
||||||
public void pauseReading() { _reader.pauseRunner(); }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Resume reading after a pause
|
|
||||||
* @deprecated unused
|
|
||||||
*/
|
|
||||||
@Deprecated
|
|
||||||
public void resumeReading() { _reader.resumeRunner(); }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Cancel reading.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public void stopReading() { _reader.cancelRunner(); }
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Defines the different events the reader produces while reading the stream
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public static interface I2NPMessageEventListener {
|
|
||||||
/**
|
|
||||||
* Notify the listener that a message has been received from the given
|
|
||||||
* reader
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public void messageReceived(I2NPMessageReader reader, I2NPMessage message, long msToRead, int bytesRead);
|
|
||||||
/**
|
|
||||||
* Notify the listener that an exception was thrown while reading from the given
|
|
||||||
* reader
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public void readError(I2NPMessageReader reader, Exception error);
|
|
||||||
/**
|
|
||||||
* Notify the listener that the stream the given reader was running off
|
|
||||||
* closed
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public void disconnected(I2NPMessageReader reader);
|
|
||||||
}
|
|
||||||
|
|
||||||
private class I2NPMessageReaderRunner implements Runnable {
|
|
||||||
private boolean _doRun;
|
|
||||||
private boolean _stayAlive;
|
|
||||||
private I2NPMessageHandler _handler;
|
|
||||||
public I2NPMessageReaderRunner() {
|
|
||||||
_doRun = true;
|
|
||||||
_stayAlive = true;
|
|
||||||
_handler = new I2NPMessageHandler(_context);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** deprecated unused */
|
|
||||||
public void pauseRunner() { _doRun = false; }
|
|
||||||
|
|
||||||
/** deprecated unused */
|
|
||||||
public void resumeRunner() { _doRun = true; }
|
|
||||||
|
|
||||||
public void cancelRunner() {
|
|
||||||
_doRun = false;
|
|
||||||
_stayAlive = false;
|
|
||||||
}
|
|
||||||
public void run() {
|
|
||||||
while (_stayAlive) {
|
|
||||||
while (_doRun) {
|
|
||||||
while (!_context.throttle().acceptNetworkMessage()) {
|
|
||||||
try { Thread.sleep(500 + _context.random().nextInt(512)); } catch (InterruptedException ie) {}
|
|
||||||
}
|
|
||||||
|
|
||||||
// do read
|
|
||||||
try {
|
|
||||||
I2NPMessage msg = _handler.readMessage(_stream);
|
|
||||||
if (msg != null) {
|
|
||||||
long msToRead = _handler.getLastReadTime();
|
|
||||||
int bytesRead = _handler.getLastSize();
|
|
||||||
//msToRead += injectLag(bytesRead);
|
|
||||||
_listener.messageReceived(I2NPMessageReader.this, msg, msToRead, bytesRead);
|
|
||||||
}
|
|
||||||
} catch (I2NPMessageException ime) {
|
|
||||||
if (_log.shouldLog(Log.WARN))
|
|
||||||
_log.warn("Error handling message", ime);
|
|
||||||
_listener.readError(I2NPMessageReader.this, ime);
|
|
||||||
_listener.disconnected(I2NPMessageReader.this);
|
|
||||||
cancelRunner();
|
|
||||||
} catch (InterruptedIOException iioe) {
|
|
||||||
// not all I2NPMessageReaders support this, but some run off sockets which throw
|
|
||||||
// SocketTimeoutExceptions or InterruptedIOExceptions
|
|
||||||
if (_log.shouldLog(Log.INFO))
|
|
||||||
_log.info("Disconnecting due to inactivity", iioe);
|
|
||||||
_listener.disconnected(I2NPMessageReader.this);
|
|
||||||
cancelRunner();
|
|
||||||
} catch (IOException ioe) {
|
|
||||||
if (_log.shouldLog(Log.WARN))
|
|
||||||
_log.warn("IO Error handling message", ioe);
|
|
||||||
_listener.disconnected(I2NPMessageReader.this);
|
|
||||||
cancelRunner();
|
|
||||||
} catch (RuntimeException e) {
|
|
||||||
_log.log(Log.CRIT, "error reading msg!", e);
|
|
||||||
_listener.readError(I2NPMessageReader.this, e);
|
|
||||||
_listener.disconnected(I2NPMessageReader.this);
|
|
||||||
cancelRunner();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// ??? unused
|
|
||||||
if (_stayAlive && !_doRun) {
|
|
||||||
// pause .5 secs when we're paused
|
|
||||||
try { Thread.sleep(500); } catch (InterruptedException ie) {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// boom bye bye bad bwoy
|
|
||||||
}
|
|
||||||
|
|
||||||
/****
|
|
||||||
private final long injectLag(int size) {
|
|
||||||
if (true) {
|
|
||||||
return 0;
|
|
||||||
} else {
|
|
||||||
boolean shouldLag = _context.random().nextInt(1000) > size;
|
|
||||||
if (!shouldLag) return 0;
|
|
||||||
|
|
||||||
long readLag = getReadLag();
|
|
||||||
if (readLag > 0) {
|
|
||||||
long lag = _context.random().nextLong(readLag);
|
|
||||||
if (lag > 0) {
|
|
||||||
try { Thread.sleep(lag); } catch (InterruptedException ie) {}
|
|
||||||
return lag;
|
|
||||||
} else {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private final long getReadLag() {
|
|
||||||
return _context.getProperty("router.injectLagMs", 0L);
|
|
||||||
}
|
|
||||||
****/
|
|
||||||
}
|
|
||||||
}
|
|
Reference in New Issue
Block a user