SSU2: Peer Test fixes

Check for dup msg 5
Store the time msg 6 sent
Ignore msg 5 after sending msg 6
Ignore msg 7 before receiving msg 4
Validate ip/port in msg 7
Update rcv times for dups
Log tweaks
This commit is contained in:
zzz
2022-12-22 08:38:08 -05:00
parent 150a68a3e0
commit 4c8e0149f3
2 changed files with 83 additions and 23 deletions

View File

@@ -378,7 +378,9 @@ class PeerTestManager {
if (!expired()) {
if (_log.shouldLog(Log.DEBUG))
_log.debug("Sending msg 6 to Charlie: " + test);
test.setLastSendTime(_context.clock().now());
long now = _context.clock().now();
test.setLastSendTime(now);
test.setSendCharlieTime(now);
UDPPacket packet;
if (test.getBob().getVersion() == 1) {
packet = _packetBuilder.buildPeerTestFromAlice(test.getCharlieIP(), test.getCharliePort(),
@@ -1059,6 +1061,7 @@ class PeerTestManager {
_transport.send(packet);
alice.setLastSendTime(now);
state.setSendAliceTime(now);
state.setReceiveAliceTime(now);
return;
} else if (msg == 2) {
if (_log.shouldDebug())
@@ -1067,15 +1070,20 @@ class PeerTestManager {
UDPPacket packet = _packetBuilder2.buildPeerTestToBob(state.getStatus(), data, bob);
_transport.send(packet);
bob.setLastSendTime(now);
state.setReceiveBobTime(now);
// should we retx msg 5 also?
return;
} else {
// msg 1 but haven't heard from a good charlie yet
// TODO pick a new charlie
// TODO retransmit to the old charlie, or if it's been too long, pick a new charlie
}
}
if (_log.shouldWarn())
_log.warn("Dup msg " + msg + " from " + fromPeer + " on " + state);
if (_log.shouldDebug())
_log.debug("Dup msg " + msg + " from " + fromPeer + " on " + state);
if (msg == 1)
state.setReceiveAliceTime(now);
else
state.setReceiveBobTime(now);
return;
}
if (_activeTests.size() >= MAX_ACTIVE_TESTS) {
@@ -1521,6 +1529,22 @@ class PeerTestManager {
_log.warn("Test nonce mismatch? " + nonce);
return;
}
if (test.getSendCharlieTime() > 0) {
// After sending msg 6, we will ignore any msg 5 received
// we ignore completely, including any ip/port mismatch
// Do not call setCharlieReceiveTime()
if (_log.shouldDebug())
_log.debug("Ignoring msg 5 after sending msg 6, from Charlie " + from + " on " + test);
return;
}
long prev = test.getReceiveCharlieTime();
test.setReceiveCharlieTime(now);
if (prev > 0) {
// we ignore completely, including any ip/port mismatch
if (_log.shouldDebug())
_log.debug("Dup msg 5 from Charlie " + from + " on " + test);
return;
}
InetAddress charlieIP = test.getCharlieIP();
if (charlieIP == null) {
// msg 5 before msg 4
@@ -1566,7 +1590,6 @@ class PeerTestManager {
}
}
}
test.setReceiveCharlieTime(now);
// Do NOT set this here, only for msg 7, this is how testComplete() knows we got msg 7
//test.setAlicePortFromCharlie(testPort);
try {
@@ -1639,6 +1662,13 @@ class PeerTestManager {
_log.warn("Test nonce mismatch? " + nonce);
return;
}
if (test.getReceiveBobTime() <= 0) {
// can't happen, we can't send msg 6 w/o msg 4
if (_log.shouldWarn())
_log.warn("Got msg 7 w/o msg 4??? on " + test);
testComplete();
return;
}
if (test.getReceiveCharlieTime() <= 0) {
// ??
}
@@ -1646,27 +1676,40 @@ class PeerTestManager {
// Do NOT set this here, this is only for msg 5
//test.setReceiveCharlieTime(now);
// i2pd did not send address block in msg 7 until 0.9.57
if (addrBlockPort != 0) {
// use the IP/port from the address block
test.setAlicePortFromCharlie(addrBlockPort);
// Do basic validation of address block IP/port.
boolean bad = false;
if (addrBlockIP != null) {
if (_transport.isValid(addrBlockIP)) {
try {
InetAddress addr = InetAddress.getByAddress(addrBlockIP);
test.setAliceIPFromCharlie(addr);
} catch (UnknownHostException uhe) {}
} else {
bad = true;
}
} else {
// assume good
test.setAliceIPFromCharlie(test.getAliceIP());
}
if (!bad && addrBlockPort != 0) {
if (addrBlockPort >= 1024) {
// use the IP/port from the address block
test.setAlicePortFromCharlie(addrBlockPort);
} else {
bad = true;
}
} else if (!_transport.isSnatted()) {
// assume good if we aren't snatted
test.setAlicePortFromCharlie(test.getAlicePort());
}
if (addrBlockIP != null) {
try {
InetAddress addr = InetAddress.getByAddress(addrBlockIP);
test.setAliceIPFromCharlie(addr);
} catch (UnknownHostException uhe) {
if (_log.shouldWarn())
_log.warn("Charlie @ " + from + " said we were an invalid IP address: " + uhe.getMessage(), uhe);
_context.statManager().addRateData("udp.testBadIP", 1);
}
} else {
test.setAliceIPFromCharlie(test.getAliceIP());
if (bad) {
if (_log.shouldWarn())
_log.warn("Charlie said we had an invalid IP/port: " +
Addresses.toString(addrBlockIP, addrBlockPort) + " on " + test);
_context.statManager().addRateData("udp.testBadIP", 1);
// TODO ban charlie or put on a list?
}
if (test.getReceiveBobTime() > 0)
testComplete();
testComplete();
break;
}
@@ -1766,8 +1809,8 @@ class PeerTestManager {
state = new PeerTestState(CHARLIE, bob, sz == 16, nonce, now);
} else {
if (state.getReceiveBobTime() > now - (RESEND_TIMEOUT / 2)) {
if (_log.shouldLog(Log.WARN))
_log.warn("Too soon, not retransmitting: " + state);
if (_log.shouldDebug())
_log.debug("Too soon, not retransmitting: " + state);
return;
}
}

View File

@@ -43,6 +43,7 @@ class PeerTestState {
private long _receiveBobTime;
private long _receiveCharlieTime;
private long _sendAliceTime;
private long _sendCharlieTime;
private int _status;
private final AtomicInteger _packetsRelayed = new AtomicInteger();
@@ -211,6 +212,18 @@ class PeerTestState {
*/
public void setSendAliceTime(long when) { _sendAliceTime = when; }
/**
* when did we send to Charlie, SSU2 Alice only
* @since 0.9.57
*/
public long getSendCharlieTime() { return _sendCharlieTime; }
/**
* when did we send to Charlie, SSU2 Alice only
* @since 0.9.57
*/
public void setSendCharlieTime(long when) { _sendCharlieTime = when; }
/**
* what code did we send to alice, SSU2 Bob only
* @since 0.9.57
@@ -277,10 +290,14 @@ class PeerTestState {
}
if (_lastSendTime > 0)
buf.append("; last send after ").append(_lastSendTime - _beginTime);
if (_sendAliceTime > 0)
buf.append("; last send to Alice ").append(DataHelper.formatTime(_sendAliceTime));
if (_receiveAliceTime > 0)
buf.append("; rcvd from Alice after ").append(_receiveAliceTime - _beginTime);
if (_receiveBobTime > 0)
buf.append("; rcvd from Bob after ").append(_receiveBobTime - _beginTime);
if (_sendCharlieTime > 0)
buf.append("; last send to Charlie ").append(DataHelper.formatTime(_sendCharlieTime));
if (_receiveCharlieTime > 0)
buf.append("; rcvd from Charlie after ").append(_receiveCharlieTime - _beginTime);
buf.append("; pkts relayed: ").append(_packetsRelayed.get());