From 22efde37e3c7ebb10d2c48ab5368c8b78e0b86bc Mon Sep 17 00:00:00 2001 From: zzz <zzz@i2pmail.org> Date: Sun, 12 Jun 2022 16:08:23 -0400 Subject: [PATCH] SSU2: Relay WIP part 15 Fix sending charlie's address in relay response Fix sending session request after introduction Send 0-length endpoint in relay response on failure Log tweaks --- .../transport/udp/EstablishmentManager.java | 16 +++++++++---- .../transport/udp/IntroductionManager.java | 23 ++++++++++++++----- .../udp/OutboundEstablishState2.java | 5 ++++ .../i2p/router/transport/udp/SSU2Util.java | 17 ++++++++++---- 4 files changed, 46 insertions(+), 15 deletions(-) diff --git a/router/java/src/net/i2p/router/transport/udp/EstablishmentManager.java b/router/java/src/net/i2p/router/transport/udp/EstablishmentManager.java index 93e5711183..2c45d9d6f5 100644 --- a/router/java/src/net/i2p/router/transport/udp/EstablishmentManager.java +++ b/router/java/src/net/i2p/router/transport/udp/EstablishmentManager.java @@ -1283,8 +1283,10 @@ class EstablishmentManager { break; case OB_STATE_INTRODUCED: - handlePendingIntro(state); - return; + if (_log.shouldDebug()) + _log.debug("Send Session Request after introduction to: " + state); + packet = _builder2.buildSessionRequestPacket(state2); + break; default: if (_log.shouldWarn()) @@ -1458,11 +1460,17 @@ class EstablishmentManager { } else { ourra = _transport.getCurrentExternalAddress(false); } - if (ourra == null) + if (ourra == null) { + if (_log.shouldWarn()) + _log.warn("No address to send in relay request"); return; + } byte[] ourIP = ourra.getIP(); - if (ourIP == null) + if (ourIP == null) { + if (_log.shouldWarn()) + _log.warn("No IP to send in relay request"); return; + } int ourPort = _transport.getRequestedPort(); byte[] data = SSU2Util.createRelayRequestData(_context, bob.getRemotePeer(), charlie.getRemoteIdentity().getHash(), charlie.getIntroNonce(), tag, ourIP, ourPort, diff --git a/router/java/src/net/i2p/router/transport/udp/IntroductionManager.java b/router/java/src/net/i2p/router/transport/udp/IntroductionManager.java index f3d2f0047a..b152969fd8 100644 --- a/router/java/src/net/i2p/router/transport/udp/IntroductionManager.java +++ b/router/java/src/net/i2p/router/transport/udp/IntroductionManager.java @@ -855,12 +855,8 @@ class IntroductionManager { } else { // send rejection to Alice SigningPrivateKey spk = _context.keyManager().getSigningPrivateKey(); - int iplen = data[13] & 0xff; - int testPort = (int) DataHelper.fromLong(data, 14, 2); - byte[] testIP = new byte[iplen - 2]; - System.arraycopy(data, 16, testIP, 0, iplen - 2); data = SSU2Util.createRelayResponseData(_context, _context.routerHash(), rcode, - nonce, testIP, testPort, spk, 0); + nonce, null, 0, spk, 0); if (data == null) { if (_log.shouldWarn()) _log.warn("sig fail"); @@ -954,6 +950,21 @@ class IntroductionManager { rcode = SSU2Util.RELAY_REJECT_CHARLIE_UNKNOWN_ALICE; } } + byte[] ourIP = null; + RouterAddress ourra = _transport.getCurrentExternalAddress(isIPv6); + if (ourra != null) { + ourIP = ourra.getIP(); + if (ourIP == null) { + if (_log.shouldWarn()) + _log.warn("No IP to send in relay response"); + rcode = SSU2Util.RELAY_REJECT_CHARLIE_ADDRESS; + } + } else { + if (_log.shouldWarn()) + _log.warn("No address to send in relay response"); + rcode = SSU2Util.RELAY_REJECT_CHARLIE_ADDRESS; + } + int ourPort = _transport.getRequestedPort(); // generate our signed data // we sign it even if rejecting, not required though @@ -967,7 +978,7 @@ class IntroductionManager { } SigningPrivateKey spk = _context.keyManager().getSigningPrivateKey(); data = SSU2Util.createRelayResponseData(_context, bob.getRemotePeer(), rcode, - nonce, testIP, testPort, spk, token); + nonce, ourIP, ourPort, spk, token); if (data == null) { if (_log.shouldWarn()) _log.warn("sig fail"); diff --git a/router/java/src/net/i2p/router/transport/udp/OutboundEstablishState2.java b/router/java/src/net/i2p/router/transport/udp/OutboundEstablishState2.java index 8ff91f9506..f3075a761e 100644 --- a/router/java/src/net/i2p/router/transport/udp/OutboundEstablishState2.java +++ b/router/java/src/net/i2p/router/transport/udp/OutboundEstablishState2.java @@ -152,6 +152,11 @@ class OutboundEstablishState2 extends OutboundEstablishState implements SSU2Payl if (_currentState != OutboundState.OB_STATE_PENDING_INTRO) return; introduced(ip, port); + try { + _bobSocketAddress = new InetSocketAddress(InetAddress.getByAddress(ip), port); + } catch (UnknownHostException uhe) { + throw new IllegalArgumentException("bad IP", uhe); + } _token = token; createNewState(_routerAddress); } diff --git a/router/java/src/net/i2p/router/transport/udp/SSU2Util.java b/router/java/src/net/i2p/router/transport/udp/SSU2Util.java index 4cc6089e55..6dbe579a34 100644 --- a/router/java/src/net/i2p/router/transport/udp/SSU2Util.java +++ b/router/java/src/net/i2p/router/transport/udp/SSU2Util.java @@ -252,7 +252,8 @@ final class SSU2Util { * Make the data for the relay response block * * @param h Bob hash to be included in sig, not included in data - * @param ip non-null + * @param ip may be null + * @param port ignored if ip is null * @param token if nonzero, append it * @return null on failure * @since 0.9.55 @@ -260,14 +261,20 @@ final class SSU2Util { public static byte[] createRelayResponseData(I2PAppContext ctx, Hash h, int code, long nonce, byte[] ip, int port, SigningPrivateKey spk, long token) { - int datalen = 12 + ip.length; + int datalen = 10; + if (ip != null) + datalen += 2 + ip.length; byte[] data = new byte[datalen]; DataHelper.toLong(data, 0, 4, nonce); DataHelper.toLong(data, 4, 4, ctx.clock().now() / 1000); data[8] = 2; // version - data[9] = (byte) (ip.length + 2); - DataHelper.toLong(data, 10, 2, port); - System.arraycopy(ip, 0, data, 12, ip.length); + if (ip != null) { + data[9] = (byte) (ip.length + 2); + DataHelper.toLong(data, 10, 2, port); + System.arraycopy(ip, 0, data, 12, ip.length); + } else { + // data[9] = 0; + } Signature sig = sign(ctx, RELAY_RESPONSE_PROLOGUE, h, null, data, datalen, spk); if (sig == null) return null; -- GitLab