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

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

SSU2: Bundle RI with peer test messages 2 and 4 if possible

similar to previous checkin for relay intro
parent 4d650249
No related branches found
No related tags found
No related merge requests found
...@@ -728,8 +728,31 @@ class PacketBuilder2 { ...@@ -728,8 +728,31 @@ class PacketBuilder2 {
* @return ready to send packet, non-null * @return ready to send packet, non-null
*/ */
public UDPPacket buildPeerTestToAlice(int code, Hash charlieHash, byte[] signedData, PeerState2 alice) { public UDPPacket buildPeerTestToAlice(int code, Hash charlieHash, byte[] signedData, PeerState2 alice) {
return buildPeerTestToAlice(code, charlieHash, signedData, null, alice);
}
/**
* Build a packet as Bob to Alice, with the response from Charlie,
* or a rejection by Bob.
* In-session, message 4.
*
* @param charlieHash fake hash (all zeros) if rejected by bob
* @param riBlock to include, may be null
* @return ready to send packet, non-null
* @since 0.9.57
*/
public UDPPacket buildPeerTestToAlice(int code, Hash charlieHash, byte[] signedData, Block riBlock, PeerState2 alice) {
Block block = new SSU2Payload.PeerTestBlock(4, code, charlieHash, signedData); Block block = new SSU2Payload.PeerTestBlock(4, code, charlieHash, signedData);
UDPPacket rv = buildPacket(Collections.<Fragment>emptyList(), Collections.singletonList(block), alice); List<Block> blocks;
if (riBlock != null) {
// RouterInfo must be first
blocks = new ArrayList<Block>(2);
blocks.add(riBlock);
blocks.add(block);
} else {
blocks = Collections.singletonList(block);
}
UDPPacket rv = buildPacket(Collections.<Fragment>emptyList(), blocks, alice);
rv.setMessageType(TYPE_TTA); rv.setMessageType(TYPE_TTA);
return rv; return rv;
} }
...@@ -761,11 +784,21 @@ class PacketBuilder2 { ...@@ -761,11 +784,21 @@ class PacketBuilder2 {
* Build a packet as Bob to Charlie to help test Alice. * Build a packet as Bob to Charlie to help test Alice.
* In-session, message 2. * In-session, message 2.
* *
* @param riBlock to include, may be null
* @return ready to send packet, non-null * @return ready to send packet, non-null
*/ */
public UDPPacket buildPeerTestToCharlie(Hash aliceHash, byte[] signedData, PeerState2 charlie) { public UDPPacket buildPeerTestToCharlie(Hash aliceHash, byte[] signedData, Block riBlock, PeerState2 charlie) {
Block block = new SSU2Payload.PeerTestBlock(2, 0, aliceHash, signedData); Block block = new SSU2Payload.PeerTestBlock(2, 0, aliceHash, signedData);
UDPPacket rv = buildPacket(Collections.<Fragment>emptyList(), Collections.singletonList(block), charlie); List<Block> blocks;
if (riBlock != null) {
// RouterInfo must be first
blocks = new ArrayList<Block>(2);
blocks.add(riBlock);
blocks.add(block);
} else {
blocks = Collections.singletonList(block);
}
UDPPacket rv = buildPacket(Collections.<Fragment>emptyList(), blocks, charlie);
rv.setMessageType(TYPE_TBC); rv.setMessageType(TYPE_TBC);
return rv; return rv;
} }
......
...@@ -1193,16 +1193,8 @@ class PeerTestManager { ...@@ -1193,16 +1193,8 @@ class PeerTestManager {
// send alice RI to charlie // send alice RI to charlie
if (_log.shouldDebug()) if (_log.shouldDebug())
_log.debug("Send Alice RI and msg 2 to charlie on " + state); _log.debug("Send Alice RI and msg 2 to charlie on " + state);
// TODO see if Alide RI will compress enough to fit in the peer test packet
DatabaseStoreMessage dbsm = new DatabaseStoreMessage(_context);
dbsm.setEntry(aliceRI);
dbsm.setMessageExpiration(now + 10*1000);
_transport.send(dbsm, charlie);
// forward to charlie, don't bother to validate signed data // forward to charlie, don't bother to validate signed data
UDPPacket packet = _packetBuilder2.buildPeerTestToCharlie(alice, data, (PeerState2) charlie); sendRIandPT(aliceRI, -1, alice, data, (PeerState2) charlie, now);
// delay because dbsm is queued, we want it to get there first
new DelaySend(packet, 100);
charlie.setLastSendTime(now);
break; break;
} }
...@@ -1328,15 +1320,7 @@ class PeerTestManager { ...@@ -1328,15 +1320,7 @@ class PeerTestManager {
_log.info("Charlie response " + status + " picked a new one " + charlie + " on " + state); _log.info("Charlie response " + status + " picked a new one " + charlie + " on " + state);
state.setCharlie(charlie.getRemoteIPAddress(), charlie.getRemotePort(), charlie.getRemotePeer()); state.setCharlie(charlie.getRemoteIPAddress(), charlie.getRemotePort(), charlie.getRemotePeer());
state.setLastSendTime(now); state.setLastSendTime(now);
// TODO see if Alice RI will compress enough to fit in the peer test packet sendRIandPT(aliceRI, -1, alice, state.getTestData(), (PeerState2) charlie, now);
DatabaseStoreMessage dbsm = new DatabaseStoreMessage(_context);
dbsm.setEntry(aliceRI);
dbsm.setMessageExpiration(now + 10*1000);
_transport.send(dbsm, charlie);
UDPPacket packet = _packetBuilder2.buildPeerTestToCharlie(alice, state.getTestData(), (PeerState2) charlie);
// delay because dbsm is queued, we want it to get there first
new DelaySend(packet, 100);
charlie.setLastSendTime(now);
break; break;
} }
} }
...@@ -1353,11 +1337,6 @@ class PeerTestManager { ...@@ -1353,11 +1337,6 @@ class PeerTestManager {
// Alice would need it to verify sig, but not worth the bandwidth // Alice would need it to verify sig, but not worth the bandwidth
if (_log.shouldDebug()) if (_log.shouldDebug())
_log.debug("Send Charlie RI to alice on " + state); _log.debug("Send Charlie RI to alice on " + state);
// TODO see if Charlie RI will compress enough to fit in the peer test packet
DatabaseStoreMessage dbsm = new DatabaseStoreMessage(_context);
dbsm.setEntry(charlieRI);
dbsm.setMessageExpiration(now + 10*1000);
_transport.send(dbsm, alice);
if (true) { if (true) {
// Debug - validate signed data // Debug - validate signed data
// we forward it to alice even on failure // we forward it to alice even on failure
...@@ -1377,13 +1356,7 @@ class PeerTestManager { ...@@ -1377,13 +1356,7 @@ class PeerTestManager {
// FIXME this will probably get there before the RI // FIXME this will probably get there before the RI
if (_log.shouldDebug()) if (_log.shouldDebug())
_log.debug("Send msg 4 status " + status + " to alice on " + state); _log.debug("Send msg 4 status " + status + " to alice on " + state);
UDPPacket packet = _packetBuilder2.buildPeerTestToAlice(status, charlie, data, alice); sendRIandPT(charlieRI, status, charlie, data, alice, now);
// delay because dbsm is queued, we want it to get there first
if (charlieRI != null)
new DelaySend(packet, 100);
else
_transport.send(packet);
alice.setLastSendTime(now);
// overwrite alice-signed test data with charlie-signed data in case we need to retransmit // overwrite alice-signed test data with charlie-signed data in case we need to retransmit
state.setStatus(status); state.setStatus(status);
state.setSendAliceTime(now); state.setSendAliceTime(now);
...@@ -2126,6 +2099,67 @@ class PeerTestManager { ...@@ -2126,6 +2099,67 @@ class PeerTestManager {
} }
} }
/**
* Send RI and Peer Test. SSU2 only. We are Bob.
*
* Msg 2 Bob to Charlie with Alice's RI
* Msg 4 Bob to Alice with Charlie's RI
*
* @param ri may be null, but hopefully not
* @param status -1 for msg 2, nonnegative for msg 4
* @param hash alice for msg 2, charlie for msg 4
* @param data signed peer test data
* @param to charlie for msg 2, alice for msg 4
* @since 0.9.57
*/
private void sendRIandPT(RouterInfo ri, int status, Hash hash, byte[] data, PeerState2 to, long now) {
boolean delay = false;
SSU2Payload.RIBlock riblock = null;
if (ri != null) {
// See if the RI will compress enough to fit in the peer test packet,
// as this makes everything go smoother and faster.
// Overhead total is 183 via IPv4, 203 via IPv6 (w/ IPv4 addr in data)
// Overhead total is 195 via IPv4, 215 via IPv6 (w/ IPv6 addr in data)
int avail = to.getMTU() -
((to.isIPv6() ? PacketBuilder2.MIN_IPV6_DATA_PACKET_OVERHEAD : PacketBuilder2.MIN_DATA_PACKET_OVERHEAD) +
SSU2Payload.BLOCK_HEADER_SIZE + // peer test block header
3 + // peer test block msgnum/code/flag
Hash.HASH_LENGTH + // peer test block hash
data.length + // peer test block signed data
SSU2Payload.BLOCK_HEADER_SIZE + // RI block header
2 // RI block flag/frag bytes
);
byte[] info = ri.toByteArray();
byte[] gzipped = DataHelper.compress(info, 0, info.length, DataHelper.MAX_COMPRESSION);
if (_log.shouldDebug())
_log.debug("RI: " + info.length + " bytes uncompressed, " + gzipped.length +
" compressed, MTU " + to.getMTU() + ", available " + avail);
boolean gzip = gzipped.length < info.length;
if (gzip)
info = gzipped;
if (info.length <= avail) {
riblock = new SSU2Payload.RIBlock(info, 0, info.length, false, gzip, 0, 1);
} else {
DatabaseStoreMessage dbsm = new DatabaseStoreMessage(_context);
dbsm.setEntry(ri);
dbsm.setMessageExpiration(now + 10*1000);
_transport.send(dbsm, to);
delay = true;
}
}
UDPPacket packet;
if (status < 0)
packet = _packetBuilder2.buildPeerTestToCharlie(hash, data, riblock, to);
else
packet = _packetBuilder2.buildPeerTestToAlice(status, hash, data, riblock, to);
// delay because dbsm is queued, we want it to get there first
if (delay)
new DelaySend(packet, 100);
else
_transport.send(packet);
to.setLastSendTime(now);
}
/** /**
* Simple fix for RI getting there before PeerTest. * Simple fix for RI getting there before PeerTest.
* SSU2 only. We are Bob, for delaying msg sent after RI to Alice or Charlie. * SSU2 only. We are Bob, for delaying msg sent after RI to Alice or Charlie.
......
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