Skip to content

Commit

Permalink
Merge branch 'ssu2-relay-tag' into 'master'
Browse files Browse the repository at this point in the history
SSU2: Delay sending relay tag

See merge request i2p-hackers/i2p.i2p!169
  • Loading branch information
zzz committed Jan 10, 2024
2 parents a0d8f5f + 014d39c commit af24f91
Show file tree
Hide file tree
Showing 3 changed files with 81 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -842,14 +842,18 @@ void receiveSessionOrTokenRequest(RemoteHostId from, InboundEstablishState2 stat
else
_log.debug("Receive DUP session/token request from: " + state);
}

// Wait until we have RI
// sentRelayTag remains 0 and will not be sent in SessionConfirmed
// See InboundEstablishState2
// call for both Session and Token request, why not
if (state.isIntroductionRequested() &&
state.getSentRelayTag() == 0 && // only set once
state.getSentPort() >= 1024 &&
_transport.canIntroduce(state.getSentIP().length == 16)) {
long tag = 1 + _context.random().nextLong(MAX_TAG_VALUE);
state.setSentRelayTag(tag);
}
//if (state.isIntroductionRequested() &&
// state.getSentRelayTag() == 0 && // only set once
// state.getSentPort() >= 1024 &&
// _transport.canIntroduce(state.getSentIP().length == 16)) {
// long tag = 1 + _context.random().nextLong(MAX_TAG_VALUE);
// state.setSentRelayTag(tag);
//}
notifyActivity();
}

Expand Down Expand Up @@ -1175,11 +1179,13 @@ private void handleCompletelyEstablished(InboundEstablishState state) {
peer = new PeerState(_context, _transport,
state.getSentIP(), state.getSentPort(), remote.calculateHash(), true, state.getRTT(),
state.getCipherKey(), state.getMACKey());
peer.setWeRelayToThemAs(state.getSentRelayTag());
} else {
InboundEstablishState2 state2 = (InboundEstablishState2) state;
peer = state2.getPeerState();
// now handled in IES2.createPeerState()
//peer.setWeRelayToThemAs(state.getSentRelayTag());
}
peer.setWeRelayToThemAs(state.getSentRelayTag());

if (version == 1) {
// Lookup the peer's MTU from the netdb, since it isn't included in the protocol setup (yet)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,14 @@
import net.i2p.data.i2np.I2NPMessage;
import net.i2p.data.router.RouterAddress;
import net.i2p.data.router.RouterInfo;
import net.i2p.router.Router;
import net.i2p.router.RouterContext;
import net.i2p.router.networkdb.kademlia.FloodfillNetworkDatabaseFacade;
import net.i2p.router.transport.TransportImpl;
import static net.i2p.router.transport.udp.SSU2Util.*;
import net.i2p.util.Addresses;
import net.i2p.util.Log;
import net.i2p.util.VersionComparator;

/**
* Data for a new connection being established, where the remote peer has
Expand Down Expand Up @@ -63,6 +65,8 @@ class InboundEstablishState2 extends InboundEstablishState implements SSU2Payloa
// testing
private static final boolean ENFORCE_TOKEN = true;
private static final long MAX_SKEW = 2*60*1000L;
// SSU2 fixes (2.1.0)
private static final String MIN_RELAY_VERSION = "0.9.57";


/**
Expand Down Expand Up @@ -398,6 +402,32 @@ public void gotRI(RouterInfo ri, boolean isHandshake, boolean flood) throws Data
}

_receivedConfirmedIdentity = _receivedUnconfirmedIdentity;
// deferred relay tag request handling, now that we have the RI
// formerly in EstablishmentManager.receiveSessionOrTokenReques()
if (_introductionRequested) {
if (getSentPort() < 1024 ||
!_transport.canIntroduce(isIPv6)) {
_introductionRequested = false;
} else if (VersionComparator.comp(ri.getVersion(), MIN_RELAY_VERSION) < 0) {
_introductionRequested = false;
String caps = ri.getCapabilities();
if (_log.shouldWarn())
_log.warn("Not offering to relay to router version " + ri.getVersion() + " caps " + caps + ": " + this);
} else {
String caps = ri.getCapabilities();
// may be requesting relay for ipv4/6 if reachable on the other
// or may be starting up and not know if reachable or not
if (caps.indexOf(Router.CAPABILITY_REACHABLE) < 0 ||
_context.random().nextInt(4) == 0) {
// leave it set to true; createPeerState() will copy to PS2,
// who will send the relay tag with ACK 0
} else {
_introductionRequested = false;
if (_log.shouldWarn())
_log.warn("Not offering to relay to router version " + ri.getVersion() + " caps " + caps + ": " + this);
}
}
}
createPeerState();
//_sendHeaderEncryptKey2 calculated below
}
Expand All @@ -419,7 +449,7 @@ public void gotAddress(byte[] ip, int port) {

public void gotRelayTagRequest() {
if (_log.shouldDebug())
_log.debug("Got relay tag request");
_log.debug("Got relay tag request on " + this);
_introductionRequested = true;
}

Expand Down Expand Up @@ -877,6 +907,12 @@ private void createPeerState() {
RouterAddress ra = _transport.getCurrentExternalAddress(isIPv6);
if (ra != null)
_pstate.setOurAddress(ra.getIP(), ra.getPort());
if (_introductionRequested) {
long tag = 1 + _context.random().nextLong(EstablishmentManager.MAX_TAG_VALUE);
setSentRelayTag(tag);
_pstate.setWeRelayToThemAs(tag);
}
_pstate.sendAck0();
}

/**
Expand Down
35 changes: 30 additions & 5 deletions router/java/src/net/i2p/router/transport/udp/PeerState2.java
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,8 @@ private enum MigrationState {


/**
* If inbound, caller MUST immediately call setWeRelayToThemAs() (if nonzero) and sendAck0().
*
* @param rtt from the EstablishState, or 0 if not available
*/
public PeerState2(RouterContext ctx, UDPTransport transport,
Expand All @@ -135,19 +137,42 @@ public PeerState2(RouterContext ctx, UDPTransport transport,
_sentMessages = new ConcurrentHashMap<Long, List<PacketBuilder.Fragment>>(32);
_sentMessagesLastExpired = _keyEstablishedTime;
if (isInbound) {
// Send immediate ack of Session Confirmed
// Prep for immediate ack of Session Confirmed
_receivedMessages.set(0);
try {
UDPPacket ack = transport.getBuilder2().buildACK(this);
transport.send(ack);
} catch (IOException ioe) {}
// ACK 0 now sent in sendAck0() below
} else {
// For outbound, SessionConfirmed is packet 0
_packetNumber.set(1);
}
_ackTimer = new ACKTimer();
}

/**
* Send immediate ACK 0 of Session Confirmed. Inbound only.
* Bundle relay tag if requested, see InboundEstablishState2.
*
* @since 0.9.62
*/
void sendAck0() {
if (!_isInbound)
return;
long tag = getWeRelayToThemAs();
try {
UDPPacket pkt;
if (tag > 0) {
SSU2Payload.Block block = new SSU2Payload.RelayTagBlock(tag);
pkt = _transport.getBuilder2().buildPacket(Collections.<Fragment>emptyList(),
Collections.singletonList(block),
this);
if (_log.shouldInfo())
_log.info("Sending ack 0 with tag " + tag + " on " + this);
} else {
pkt = _transport.getBuilder2().buildACK(this);
}
_transport.send(pkt);
} catch (IOException ioe) {}
}

// SSU 1 overrides

@Override
Expand Down

0 comments on commit af24f91

Please sign in to comment.