Tunnels: Update profiles for tunnel peers on corrupt message at endpoint

This commit is contained in:
zzz
2021-01-24 09:38:03 -05:00
parent 451e53a674
commit cb22f31d96
3 changed files with 41 additions and 10 deletions

View File

@@ -117,8 +117,9 @@ class FragmentHandler {
* sending the resulting I2NPMessages where necessary. The received
* fragments are all verified.
*
* @return ok (false if corrupt)
*/
public void receiveTunnelMessage(byte preprocessed[], int offset, int length) {
public boolean receiveTunnelMessage(byte preprocessed[], int offset, int length) {
boolean ok = verifyPreprocessed(preprocessed, offset, length);
if (!ok) {
if (_log.shouldLog(Log.WARN))
@@ -126,7 +127,7 @@ class FragmentHandler {
+ preprocessed.length + " off=" +offset + " len=" + length);
_cache.release(new ByteArray(preprocessed));
_context.statManager().addRateData("tunnel.corruptMessage", 1);
return;
return false;
}
offset += HopProcessor.IV_LENGTH; // skip the IV
offset += 4; // skip the hash segment
@@ -139,7 +140,7 @@ class FragmentHandler {
_context.statManager().addRateData("tunnel.corruptMessage", 1);
if (_log.shouldWarn())
_log.warn("Corrupt fragment received: off = " + offset);
return;
return false;
}
padding++;
}
@@ -155,7 +156,7 @@ class FragmentHandler {
_context.statManager().addRateData("tunnel.corruptMessage", 1);
if (_log.shouldWarn())
_log.warn("Corrupt fragment received: off = " + off);
return;
return false;
}
offset = off;
}
@@ -163,10 +164,12 @@ class FragmentHandler {
_context.statManager().addRateData("tunnel.corruptMessage", 1);
if (_log.shouldWarn())
_log.warn("Corrupt fragment received: offset = " + offset, aioobe);
return false;
} catch (NullPointerException npe) {
if (_log.shouldWarn())
_log.warn("Corrupt fragment received: offset = " + offset, npe);
_context.statManager().addRateData("tunnel.corruptMessage", 1);
return false;
} catch (RuntimeException e) {
if (_log.shouldWarn())
_log.warn("Corrupt fragment received: offset = " + offset, e);
@@ -183,6 +186,7 @@ class FragmentHandler {
// let's limit the damage here and skip the:
// .transport.udp.MessageReceiver: b0rked receiving a message.. wazza huzza hmm?
//throw e;
return false;
} finally {
// each of the FragmentedMessages populated make a copy out of the
// payload, which they release separately, so we can release
@@ -192,6 +196,7 @@ class FragmentHandler {
// in order to put it in the pool, but it shouldn't cause any harm.
_cache.release(new ByteArray(preprocessed));
}
return true;
}
public int getCompleteCount() { return _completed.get(); }

View File

@@ -32,7 +32,8 @@ class OutboundTunnelEndpoint {
public void dispatch(TunnelDataMessage msg, Hash recvFrom) {
_config.incrementProcessedMessages();
boolean ok = _processor.process(msg.getData(), 0, msg.getData().length, recvFrom);
byte[] data = msg.getData();
boolean ok = _processor.process(data, 0, data.length, recvFrom);
if (!ok) {
// invalid IV
// If we pass it on to the handler, it will fail
@@ -41,7 +42,16 @@ class OutboundTunnelEndpoint {
_log.warn("Invalid IV, dropping at OBEP " + _config);
return;
}
_handler.receiveTunnelMessage(msg.getData(), 0, msg.getData().length);
ok = _handler.receiveTunnelMessage(data, 0, data.length);
if (!ok) {
// blame previous hop
Hash h = _config.getReceiveFrom();
if (h != null) {
if (_log.shouldLog(Log.WARN))
_log.warn(toString() + ": Blaming " + h + " 50%");
_context.profileManager().tunnelFailed(h, 50);
}
}
}
private class DefragmentedHandler implements FragmentHandler.DefragmentedReceiver {

View File

@@ -122,10 +122,26 @@ class TunnelParticipant {
new TimeoutJob(_context, msg), MAX_LOOKUP_TIME);
}
} else {
_inboundEndpointProcessor.getConfig().incrementProcessedMessages();
if (_log.shouldLog(Log.DEBUG))
_log.debug("Receive fragment: on " + _config + ": " + msg);
_handler.receiveTunnelMessage(data, 0, data.length);
// IBEP
TunnelCreatorConfig cfg = _inboundEndpointProcessor.getConfig();
cfg.incrementProcessedMessages();
ok = _handler.receiveTunnelMessage(data, 0, data.length);
if (ok) {
if (_log.shouldLog(Log.DEBUG))
_log.debug("Receive fragment: on " + _config + ": " + msg);
} else {
// blame everybody equally
int lenm1 = cfg.getLength() - 1;
if (lenm1 > 0) {
int pct = 100 / (lenm1);
for (int i = 0; i < lenm1; i++) {
Hash h = cfg.getPeer(i);
if (_log.shouldLog(Log.WARN))
_log.warn(toString() + ": Blaming " + h + ' ' + pct + '%');
_context.profileManager().tunnelFailed(h, pct);
}
}
}
}
}