I2P Address: [http://git.idk.i2p]

Skip to content
Snippets Groups Projects
Unverified Commit 2c534242 authored by zzz's avatar zzz
Browse files

SSU2: Relay WIP part 2

Handle relay request as bob
Send relay intro as bob
Send relay response rejection as bob
Check for valid time in relay request and relay intro
parent 8b0edde2
No related branches found
No related tags found
No related merge requests found
...@@ -18,6 +18,7 @@ import net.i2p.data.Hash; ...@@ -18,6 +18,7 @@ import net.i2p.data.Hash;
import net.i2p.data.SessionKey; import net.i2p.data.SessionKey;
import net.i2p.data.SigningPrivateKey; import net.i2p.data.SigningPrivateKey;
import net.i2p.data.SigningPublicKey; import net.i2p.data.SigningPublicKey;
import net.i2p.data.i2np.DatabaseStoreMessage;
import net.i2p.data.router.RouterAddress; import net.i2p.data.router.RouterAddress;
import net.i2p.data.router.RouterInfo; import net.i2p.data.router.RouterInfo;
import net.i2p.router.RouterContext; import net.i2p.router.RouterContext;
...@@ -106,6 +107,7 @@ class IntroductionManager { ...@@ -106,6 +107,7 @@ class IntroductionManager {
private static final int MAX_PUNCHES = 20; private static final int MAX_PUNCHES = 20;
private static final long INTRODUCER_EXPIRATION = 80*60*1000L; private static final long INTRODUCER_EXPIRATION = 80*60*1000L;
private static final String MIN_IPV6_INTRODUCER_VERSION = "0.9.50"; private static final String MIN_IPV6_INTRODUCER_VERSION = "0.9.50";
private static final long MAX_SKEW = 2*60*1000;
public IntroductionManager(RouterContext ctx, UDPTransport transport) { public IntroductionManager(RouterContext ctx, UDPTransport transport) {
_context = ctx; _context = ctx;
...@@ -667,6 +669,79 @@ class IntroductionManager { ...@@ -667,6 +669,79 @@ class IntroductionManager {
* @since 0.9.55 * @since 0.9.55
*/ */
void receiveRelayRequest(PeerState2 alice, byte[] data) { void receiveRelayRequest(PeerState2 alice, byte[] data) {
long tag = DataHelper.fromLong(data, 4, 4);
long time = DataHelper.fromLong(data, 8, 4) * 1000;
long now = _context.clock().now();
long skew = time - now;
if (skew > MAX_SKEW || skew < 0 - MAX_SKEW) {
if (_log.shouldWarn())
_log.warn("Too skewed for relay req from " + alice);
return;
}
int ver = data[12] & 0xff;
if (ver != 2) {
if (_log.shouldWarn())
_log.warn("Bad relay req version " + ver + " from " + alice);
return;
}
PeerState charlie = _outbound.get(Long.valueOf(tag));
RouterInfo aliceRI = null;
int rcode;
if (charlie == null) {
if (_log.shouldWarn())
_log.warn("Relay tag not found " + tag + " from " + alice);
rcode = SSU2Util.RELAY_REJECT_BOB_NO_TAG;
} else if (charlie.getVersion() != 2) {
return;
} else {
aliceRI = _context.netDb().lookupRouterInfoLocally(alice.getRemotePeer());
if (aliceRI != null) {
// validate signed data
SigningPublicKey spk = aliceRI.getIdentity().getSigningPublicKey();
if (SSU2Util.validateSig(_context, SSU2Util.RELAY_REQUEST_PROLOGUE,
_context.routerHash(), charlie.getRemotePeer(), data, spk)) {
rcode = SSU2Util.RELAY_ACCEPT;
} else {
if (_log.shouldWarn())
_log.warn("Signature failed relay intro\n" + aliceRI);
rcode = SSU2Util.RELAY_REJECT_BOB_SIGFAIL;
}
} else {
if (_log.shouldWarn())
_log.warn("Alice RI not found " + alice);
rcode = SSU2Util.RELAY_REJECT_BOB_UNKNOWN_ALICE;
}
}
UDPPacket packet;
if (rcode == SSU2Util.RELAY_ACCEPT) {
// Send Alice RI and forward data in a Relay Intro to Charlie
if (_log.shouldDebug())
_log.debug("Send alice RI and relay intro to " + charlie);
DatabaseStoreMessage dbsm = new DatabaseStoreMessage(_context);
dbsm.setEntry(aliceRI);
dbsm.setMessageExpiration(now + 10*1000);
_transport.send(dbsm, charlie);
packet = _builder2.buildRelayIntro(data, (PeerState2) charlie);
} else {
// send rejection to Alice
SigningPrivateKey spk = _context.keyManager().getSigningPrivateKey();
long nonce = DataHelper.fromLong(data, 0, 4);
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);
if (data == null) {
if (_log.shouldWarn())
_log.warn("sig fail");
return;
}
if (_log.shouldDebug())
_log.debug("Send relay response rejection " + rcode + " to " + alice);
packet = _builder2.buildRelayResponse(data, alice);
}
_transport.send(packet);
} }
/** /**
...@@ -682,6 +757,13 @@ class IntroductionManager { ...@@ -682,6 +757,13 @@ class IntroductionManager {
long nonce = DataHelper.fromLong(data, 0, 4); long nonce = DataHelper.fromLong(data, 0, 4);
long tag = DataHelper.fromLong(data, 4, 4); long tag = DataHelper.fromLong(data, 4, 4);
long time = DataHelper.fromLong(data, 8, 4) * 1000; long time = DataHelper.fromLong(data, 8, 4) * 1000;
long now = _context.clock().now();
long skew = time - now;
if (skew > MAX_SKEW || skew < 0 - MAX_SKEW) {
if (_log.shouldWarn())
_log.warn("Too skewed for relay intro from " + bob);
return;
}
int ver = data[12] & 0xff; int ver = data[12] & 0xff;
if (ver != 2) { if (ver != 2) {
if (_log.shouldWarn()) if (_log.shouldWarn())
......
...@@ -139,6 +139,7 @@ final class SSU2Util { ...@@ -139,6 +139,7 @@ final class SSU2Util {
public static final int RELAY_REJECT_BOB_LIMIT = 3; public static final int RELAY_REJECT_BOB_LIMIT = 3;
public static final int RELAY_REJECT_BOB_SIGFAIL = 4; public static final int RELAY_REJECT_BOB_SIGFAIL = 4;
public static final int RELAY_REJECT_BOB_NO_TAG = 5; public static final int RELAY_REJECT_BOB_NO_TAG = 5;
public static final int RELAY_REJECT_BOB_UNKNOWN_ALICE = 6;
public static final int RELAY_REJECT_CHARLIE_UNSPEC = 64; public static final int RELAY_REJECT_CHARLIE_UNSPEC = 64;
public static final int RELAY_REJECT_CHARLIE_ADDRESS = 65; public static final int RELAY_REJECT_CHARLIE_ADDRESS = 65;
public static final int RELAY_REJECT_CHARLIE_LIMIT = 66; public static final int RELAY_REJECT_CHARLIE_LIMIT = 66;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment