use of net.i2p.data.i2np.I2NPMessageException in project i2p.i2p by i2p.
the class MessageReceiver method readMessage.
/**
* Assemble all the fragments into an I2NP message.
* This calls state.releaseResources(), do not access state after calling this.
*
* @param buf temp buffer for convenience
* @return null on error
*/
private I2NPMessage readMessage(ByteArray buf, InboundMessageState state, I2NPMessageHandler handler) {
try {
// byte buf[] = new byte[state.getCompleteSize()];
I2NPMessage m;
int numFragments = state.getFragmentCount();
if (numFragments > 1) {
ByteArray[] fragments = state.getFragments();
int off = 0;
for (int i = 0; i < numFragments; i++) {
System.arraycopy(fragments[i].getData(), 0, buf.getData(), off, fragments[i].getValid());
// if (_log.shouldLog(Log.DEBUG))
// _log.debug("Raw fragment[" + i + "] for " + state.getMessageId() + ": "
// + Base64.encode(fragments[i].getData(), 0, fragments[i].getValid())
// + " (valid: " + fragments[i].getValid()
// + " raw: " + Base64.encode(fragments[i].getData()) + ")");
off += fragments[i].getValid();
}
if (off != state.getCompleteSize()) {
if (_log.shouldLog(Log.WARN))
_log.warn("Hmm, offset of the fragments = " + off + " while the state says " + state.getCompleteSize());
return null;
}
// if (_log.shouldLog(Log.DEBUG))
// _log.debug("Raw byte array for " + state.getMessageId() + ": " + HexDump.dump(buf.getData(), 0, state.getCompleteSize()));
m = I2NPMessageImpl.fromRawByteArray(_context, buf.getData(), 0, state.getCompleteSize(), handler);
} else {
// zero copy for single fragment
m = I2NPMessageImpl.fromRawByteArray(_context, state.getFragments()[0].getData(), 0, state.getCompleteSize(), handler);
}
m.setUniqueId(state.getMessageId());
return m;
} catch (I2NPMessageException ime) {
if (_log.shouldLog(Log.WARN)) {
ByteArray ba;
if (state.getFragmentCount() > 1)
ba = buf;
else
ba = state.getFragments()[0];
byte[] data = ba.getData();
_log.warn("Message invalid: " + state + " PeerState: " + _transport.getPeerState(state.getFrom()) + "\nDUMP:\n" + HexDump.dump(data, 0, state.getCompleteSize()) + "\nRAW:\n" + Base64.encode(data, 0, state.getCompleteSize()), ime);
}
if (state.getFragments()[0].getData()[0] == DatabaseStoreMessage.MESSAGE_TYPE) {
PeerState ps = _transport.getPeerState(state.getFrom());
if (ps != null && ps.getRemotePort() == 65520) {
// distinct port of buggy router
_transport.sendDestroy(ps);
_transport.dropPeer(ps, true, "Corrupt DSM");
_context.banlist().banlistRouterForever(state.getFrom(), _x("Sent corrupt DSM"));
}
}
_context.messageHistory().droppedInboundMessage(state.getMessageId(), state.getFrom(), "error: " + ime.toString() + ": " + state.toString());
return null;
} catch (RuntimeException e) {
// e.g. AIOOBE
if (_log.shouldLog(Log.WARN))
_log.warn("Error handling a message: " + state, e);
_context.messageHistory().droppedInboundMessage(state.getMessageId(), state.getFrom(), "error: " + e.toString() + ": " + state.toString());
return null;
} finally {
state.releaseResources();
}
}
use of net.i2p.data.i2np.I2NPMessageException in project i2p.i2p by i2p.
the class FragmentHandler method receiveComplete.
private void receiveComplete(FragmentedMessage msg) {
if (msg == null)
return;
_completed++;
String stringified = null;
if (_log.shouldLog(Log.DEBUG))
stringified = msg.toString();
byte[] data = null;
try {
int fragmentCount = msg.getFragmentCount();
// toByteArray destroys the contents of the message completely
data = msg.toByteArray();
if (data == null)
// fragments already released???
throw new I2NPMessageException("null data");
if (_log.shouldLog(Log.DEBUG))
// + Base64.encode(data)
_log.debug("RECV(" + data.length + "): ");
// + " " + _context.sha().calculateHash(data).toBase64());
// TODO read in as unknown message for outbound tunnels,
// since this will just be packaged in a TunnelGatewayMessage.
// Not a big savings since most everything is a GarlicMessage
// and so the readMessage() call is fast.
// The unencrypted messages at the OBEP are (V)TBMs
// and perhaps an occasional DatabaseLookupMessage
I2NPMessage m = new I2NPMessageHandler(_context).readMessage(data);
// + msg.toString());
noteReception(m.getUniqueId(), fragmentCount - 1, "complete: ");
noteCompletion(m.getUniqueId());
_receiver.receiveComplete(m, msg.getTargetRouter(), msg.getTargetTunnel());
} catch (I2NPMessageException ime) {
if (stringified == null)
stringified = msg.toString();
if (_log.shouldLog(Log.WARN)) {
_log.warn("Error receiving fragmented message (corrupt?): " + stringified, ime);
_log.warn("DUMP:\n" + HexDump.dump(data));
_log.warn("RAW:\n" + Base64.encode(data));
}
}
}
use of net.i2p.data.i2np.I2NPMessageException in project i2p.i2p by i2p.
the class FragmentHandler method receiveComplete.
/**
* Zero-copy reception of an unfragmented message
* @since 0.9
*/
private void receiveComplete(byte[] data, int offset, int len, Hash router, TunnelId tunnelId) {
_completed++;
try {
if (_log.shouldLog(Log.DEBUG))
_log.debug("RECV unfrag(" + len + ')');
// TODO read in as unknown message for outbound tunnels,
// since this will just be packaged in a TunnelGatewayMessage.
// Not a big savings since most everything is a GarlicMessage
// and so the readMessage() call is fast.
// The unencrypted messages at the OBEP are (V)TBMs
// and perhaps an occasional DatabaseLookupMessage
I2NPMessageHandler h = new I2NPMessageHandler(_context);
h.readMessage(data, offset, len);
I2NPMessage m = h.lastRead();
// + msg.toString());
noteReception(m.getUniqueId(), 0, "complete: ");
noteCompletion(m.getUniqueId());
_receiver.receiveComplete(m, router, tunnelId);
} catch (I2NPMessageException ime) {
if (_log.shouldLog(Log.WARN)) {
_log.warn("Error receiving unfragmented message (corrupt?)", ime);
_log.warn("DUMP:\n" + HexDump.dump(data, offset, len));
_log.warn("RAW:\n" + Base64.encode(data, offset, len));
}
}
}
use of net.i2p.data.i2np.I2NPMessageException in project i2p.i2p by i2p.
the class TunnelGatewayZeroHop method add.
/**
* Add a message to be sent down the tunnel, where we are the inbound gateway.
* This requires converting the message included in the TGM from an
* UnknownI2NPMessage to the correct message class.
* See TunnelGatewayMessage for details.
*
* @param msg message received to be sent through the tunnel
*/
@Override
public void add(TunnelGatewayMessage msg) {
I2NPMessage imsg = msg.getMessage();
if (_config.isInbound()) {
if (imsg instanceof UnknownI2NPMessage) {
// Do the delayed deserializing - convert to a standard message class
try {
UnknownI2NPMessage umsg = (UnknownI2NPMessage) imsg;
imsg = umsg.convert();
} catch (I2NPMessageException ime) {
if (_log.shouldLog(Log.WARN))
_log.warn("Unable to convert to std. msg. class at zero-hop IBGW", ime);
return;
}
}
}
add(imsg, null, null);
}
Aggregations