forked from I2P_Developers/i2p.i2p
SSU2: Refactor in-session PacketBuilder2 methods to throw IOE
Primarily for Peer Test and Relay, so the test or relay can be aborted. Previously, sends on a dead PeerState2 were not detected or prevented. Catch IOE throughout where necessary around all build() calls. Add a fail() method in PeerTestManager
This commit is contained in:
@@ -1534,9 +1534,12 @@ class EstablishmentManager {
|
||||
if (_log.shouldDebug())
|
||||
_log.debug("Found connected introducer " + bob + " for " + state);
|
||||
long tag = addr.getIntroducerTag(i);
|
||||
sendRelayRequest(tag, (PeerState2) bob, state);
|
||||
boolean ok = sendRelayRequest(tag, (PeerState2) bob, state);
|
||||
// this transitions the state
|
||||
state2.introSent(h);
|
||||
if (ok)
|
||||
state2.introSent(h);
|
||||
else
|
||||
state2.setIntroState(h, INTRO_STATE_DISCONNECTED);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -1637,9 +1640,10 @@ class EstablishmentManager {
|
||||
* SSU 2 only.
|
||||
*
|
||||
* @param charlie must be SSU2
|
||||
* @return success
|
||||
* @since 0.9.55
|
||||
*/
|
||||
private void sendRelayRequest(long tag, PeerState2 bob, OutboundEstablishState charlie) {
|
||||
private boolean sendRelayRequest(long tag, PeerState2 bob, OutboundEstablishState charlie) {
|
||||
// pick our IP based on what address we're connecting to
|
||||
UDPAddress cra = charlie.getRemoteAddress();
|
||||
RouterAddress ourra;
|
||||
@@ -1653,13 +1657,13 @@ class EstablishmentManager {
|
||||
if (ourra == null) {
|
||||
if (_log.shouldWarn())
|
||||
_log.warn("No address to send in relay request");
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
byte[] ourIP = ourra.getIP();
|
||||
if (ourIP == null) {
|
||||
if (_log.shouldWarn())
|
||||
_log.warn("No IP to send in relay request");
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
// Bob should already have our RI, especially if we just connected; we do not resend it here.
|
||||
int ourPort = _transport.getRequestedPort();
|
||||
@@ -1669,13 +1673,19 @@ class EstablishmentManager {
|
||||
if (data == null) {
|
||||
if (_log.shouldWarn())
|
||||
_log.warn("sig fail");
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
UDPPacket packet;
|
||||
try {
|
||||
packet = _builder2.buildRelayRequest(data, bob);
|
||||
} catch (IOException ioe) {
|
||||
return false;
|
||||
}
|
||||
UDPPacket packet = _builder2.buildRelayRequest(data, bob);
|
||||
if (_log.shouldDebug())
|
||||
_log.debug("Send relay request to " + bob + " for " + charlie);
|
||||
_transport.send(packet);
|
||||
bob.setLastSendTime(_context.clock().now());
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -192,13 +192,15 @@ class InboundEstablishState2 extends InboundEstablishState implements SSU2Payloa
|
||||
int reason = rie.getReason();
|
||||
PeerStateDestroyed psd = createPeerStateDestroyed(reason);
|
||||
_transport.addRecentlyClosed(psd);
|
||||
UDPPacket pkt = _transport.getBuilder2().buildSessionDestroyPacket(reason, psd);
|
||||
_transport.send(pkt);
|
||||
if (_log.shouldWarn()) {
|
||||
if (_log.shouldDebug())
|
||||
_log.debug("Sending TERMINATION reason " + reason + " to " + psd);
|
||||
_log.warn("IES2 payload error", rie);
|
||||
}
|
||||
try {
|
||||
UDPPacket pkt = _transport.getBuilder2().buildSessionDestroyPacket(reason, psd);
|
||||
_transport.send(pkt);
|
||||
if (_log.shouldWarn()) {
|
||||
if (_log.shouldDebug())
|
||||
_log.debug("Sending TERMINATION reason " + reason + " to " + psd);
|
||||
_log.warn("IES2 payload error", rie);
|
||||
}
|
||||
} catch (IOException ioe) {}
|
||||
throw new GeneralSecurityException("IES2 payload error: " + this, rie);
|
||||
} catch (DataFormatException dfe) {
|
||||
// no in-session response possible
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package net.i2p.router.transport.udp;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.InetAddress;
|
||||
import java.net.UnknownHostException;
|
||||
import java.util.ArrayList;
|
||||
@@ -527,11 +528,13 @@ class IntroductionManager {
|
||||
_log.debug("Pinging introducer: " + cur);
|
||||
cur.setLastPingTime(now);
|
||||
UDPPacket ping;
|
||||
if (cur.getVersion() == 2)
|
||||
ping = _builder2.buildPing((PeerState2) cur);
|
||||
else
|
||||
ping = _builder.buildPing(cur);
|
||||
_transport.send(ping);
|
||||
try {
|
||||
if (cur.getVersion() == 2)
|
||||
ping = _builder2.buildPing((PeerState2) cur);
|
||||
else
|
||||
ping = _builder.buildPing(cur);
|
||||
_transport.send(ping);
|
||||
} catch (IOException ioe) {}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -892,21 +895,29 @@ class IntroductionManager {
|
||||
if (gzip)
|
||||
info = gzipped;
|
||||
|
||||
if (info.length <= avail) {
|
||||
SSU2Payload.RIBlock riblock = new SSU2Payload.RIBlock(info, 0, info.length, false, gzip, 0, 1);
|
||||
UDPPacket packet = _builder2.buildRelayIntro(idata, riblock, (PeerState2) charlie);
|
||||
_transport.send(packet);
|
||||
} else {
|
||||
DatabaseStoreMessage dbsm = new DatabaseStoreMessage(_context);
|
||||
dbsm.setEntry(aliceRI);
|
||||
dbsm.setMessageExpiration(now + 10*1000);
|
||||
_transport.send(dbsm, charlie);
|
||||
UDPPacket packet = _builder2.buildRelayIntro(idata, null, (PeerState2) charlie);
|
||||
// delay because dbsm is queued, we want it to get there first
|
||||
new DelaySend(packet, 40);
|
||||
try {
|
||||
if (info.length <= avail) {
|
||||
SSU2Payload.RIBlock riblock = new SSU2Payload.RIBlock(info, 0, info.length, false, gzip, 0, 1);
|
||||
UDPPacket packet = _builder2.buildRelayIntro(idata, riblock, (PeerState2) charlie);
|
||||
_transport.send(packet);
|
||||
} else {
|
||||
DatabaseStoreMessage dbsm = new DatabaseStoreMessage(_context);
|
||||
dbsm.setEntry(aliceRI);
|
||||
dbsm.setMessageExpiration(now + 10*1000);
|
||||
_transport.send(dbsm, charlie);
|
||||
UDPPacket packet = _builder2.buildRelayIntro(idata, null, (PeerState2) charlie);
|
||||
// delay because dbsm is queued, we want it to get there first
|
||||
new DelaySend(packet, 40);
|
||||
}
|
||||
charlie.setLastSendTime(now);
|
||||
return;
|
||||
} catch (IOException ioe) {
|
||||
rcode = SSU2Util.RELAY_REJECT_BOB_UNSPEC;
|
||||
// fall thru to send reject
|
||||
}
|
||||
charlie.setLastSendTime(now);
|
||||
} else {
|
||||
}
|
||||
|
||||
try {
|
||||
// send rejection to Alice
|
||||
SigningPrivateKey spk = _context.keyManager().getSigningPrivateKey();
|
||||
data = SSU2Util.createRelayResponseData(_context, _context.routerHash(), rcode,
|
||||
@@ -921,7 +932,7 @@ class IntroductionManager {
|
||||
UDPPacket packet = _builder2.buildRelayResponse(data, alice);
|
||||
alice.setLastSendTime(now);
|
||||
_transport.send(packet);
|
||||
}
|
||||
} catch (IOException ioe) {}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1129,20 +1140,24 @@ class IntroductionManager {
|
||||
_log.warn("sig fail");
|
||||
return;
|
||||
}
|
||||
UDPPacket packet = _builder2.buildRelayResponse(data, bob);
|
||||
if (_log.shouldInfo())
|
||||
_log.info("Send relay response " + rcode + " as charlie " + " nonce " + nonce + " to bob " + bob +
|
||||
" with token " + token +
|
||||
" for alice " + Addresses.toString(testIP, testPort) + ' ' + aliceRI);
|
||||
_transport.send(packet);
|
||||
bob.setLastSendTime(now);
|
||||
try {
|
||||
UDPPacket packet = _builder2.buildRelayResponse(data, bob);
|
||||
if (_log.shouldInfo())
|
||||
_log.info("Send relay response " + rcode + " as charlie " + " nonce " + nonce + " to bob " + bob +
|
||||
" with token " + token +
|
||||
" for alice " + Addresses.toString(testIP, testPort) + ' ' + aliceRI);
|
||||
_transport.send(packet);
|
||||
bob.setLastSendTime(now);
|
||||
} catch (IOException ioe) {
|
||||
return;
|
||||
}
|
||||
if (rcode == SSU2Util.RELAY_ACCEPT) {
|
||||
// send hole punch with the same data we sent to Bob
|
||||
if (_log.shouldDebug())
|
||||
_log.debug("Send hole punch to " + Addresses.toString(testIP, testPort));
|
||||
long sendId = (nonce << 32) | nonce;
|
||||
long rcvId = ~sendId;
|
||||
packet = _builder2.buildHolePunch(aliceIP, testPort, aliceIntroKey, sendId, rcvId, data);
|
||||
UDPPacket packet = _builder2.buildHolePunch(aliceIP, testPort, aliceIntroKey, sendId, rcvId, data);
|
||||
_transport.send(packet);
|
||||
}
|
||||
}
|
||||
@@ -1205,11 +1220,13 @@ class IntroductionManager {
|
||||
//idata[0] = 0; // flag
|
||||
idata[1] = (byte) status;
|
||||
System.arraycopy(data, 0, idata, 2, data.length);
|
||||
UDPPacket packet = _builder2.buildRelayResponse(idata, alice);
|
||||
if (_log.shouldInfo())
|
||||
_log.info("Got relay response " + status + " as bob, forward " + " nonce " + nonce + " to " + alice);
|
||||
_transport.send(packet);
|
||||
alice.setLastSendTime(now);
|
||||
try {
|
||||
UDPPacket packet = _builder2.buildRelayResponse(idata, alice);
|
||||
if (_log.shouldInfo())
|
||||
_log.info("Got relay response " + status + " as bob, forward " + " nonce " + nonce + " to " + alice);
|
||||
_transport.send(packet);
|
||||
alice.setLastSendTime(now);
|
||||
} catch (IOException ioe) {}
|
||||
} else {
|
||||
// We are Alice, give to EstablishmentManager to check sig and process
|
||||
if (_log.shouldInfo())
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package net.i2p.router.transport.udp;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
@@ -507,10 +508,15 @@ class OutboundMessageFragments {
|
||||
}
|
||||
|
||||
UDPPacket pkt;
|
||||
if (peer.getVersion() == 1)
|
||||
if (peer.getVersion() == 1) {
|
||||
pkt = _builder.buildPacket(sendNext, peer, remaining, newFullAckCount, partialACKBitfields);
|
||||
else
|
||||
pkt = _builder2.buildPacket(sendNext, (PeerState2) peer);
|
||||
} else {
|
||||
try {
|
||||
pkt = _builder2.buildPacket(sendNext, (PeerState2) peer);
|
||||
} catch (IOException ioe) {
|
||||
pkt = null;
|
||||
}
|
||||
}
|
||||
if (pkt != null) {
|
||||
if (_log.shouldDebug())
|
||||
_log.debug("Built packet with " + sendNext.size() + " fragments totalling " + curTotalDataSize +
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package net.i2p.router.transport.udp;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.DatagramPacket;
|
||||
import java.net.InetAddress;
|
||||
import java.net.SocketAddress;
|
||||
@@ -129,9 +130,9 @@ class PacketBuilder2 {
|
||||
* this method writes exactly one fragment.
|
||||
* For no fragments use buildAck().
|
||||
*
|
||||
* @return null on error
|
||||
* @throws IOException if peer is dead
|
||||
*/
|
||||
public UDPPacket buildPacket(OutboundMessageState state, int fragment, PeerState2 peer) {
|
||||
public UDPPacket buildPacket(OutboundMessageState state, int fragment, PeerState2 peer) throws IOException {
|
||||
List<Fragment> frags = Collections.singletonList(new Fragment(state, fragment));
|
||||
return buildPacket(frags, peer);
|
||||
}
|
||||
@@ -139,8 +140,9 @@ class PacketBuilder2 {
|
||||
/*
|
||||
* Multiple fragments
|
||||
*
|
||||
* @throws IOException if peer is dead
|
||||
*/
|
||||
public UDPPacket buildPacket(List<Fragment> fragments, PeerState2 peer) {
|
||||
public UDPPacket buildPacket(List<Fragment> fragments, PeerState2 peer) throws IOException {
|
||||
return buildPacket(fragments, null, peer);
|
||||
}
|
||||
|
||||
@@ -148,8 +150,9 @@ class PacketBuilder2 {
|
||||
* Multiple fragments and optional other blocks.
|
||||
*
|
||||
* @param otherBlocks may be null or empty
|
||||
* @throws IOException if peer is dead
|
||||
*/
|
||||
public UDPPacket buildPacket(List<Fragment> fragments, List<Block> otherBlocks, SSU2Sender peer) {
|
||||
public UDPPacket buildPacket(List<Fragment> fragments, List<Block> otherBlocks, SSU2Sender peer) throws IOException {
|
||||
// calculate data size
|
||||
int numFragments = fragments.size();
|
||||
int dataSize = 0;
|
||||
@@ -187,6 +190,7 @@ class PacketBuilder2 {
|
||||
}
|
||||
|
||||
// make the packet
|
||||
// IOE thrown from here if peer is dead
|
||||
long pktNum = peer.getNextPacketNumber();
|
||||
UDPPacket packet = buildShortPacketHeader(peer.getSendConnID(), pktNum, DATA_FLAG_BYTE);
|
||||
DatagramPacket pkt = packet.getPacket();
|
||||
@@ -329,8 +333,11 @@ class PacketBuilder2 {
|
||||
/**
|
||||
* A DATA packet with padding only.
|
||||
* We use this for keepalive purposes.
|
||||
*
|
||||
* @throws IOException if peer is dead
|
||||
*/
|
||||
public UDPPacket buildPing(PeerState2 peer) {
|
||||
public UDPPacket buildPing(PeerState2 peer) throws IOException {
|
||||
// IOE thrown from here if peer is dead
|
||||
long pktNum = peer.getNextPacketNumber();
|
||||
UDPPacket packet = buildShortPacketHeader(peer.getSendConnID(), pktNum, DATA_FLAG_BYTE);
|
||||
DatagramPacket pkt = packet.getPacket();
|
||||
@@ -358,17 +365,19 @@ class PacketBuilder2 {
|
||||
* An ack packet is just a data packet with no data.
|
||||
* See buildPacket() for format.
|
||||
*
|
||||
*
|
||||
* @throws IOException if peer is dead
|
||||
*/
|
||||
public UDPPacket buildACK(PeerState2 peer) {
|
||||
public UDPPacket buildACK(PeerState2 peer) throws IOException {
|
||||
return buildPacket(Collections.<Fragment>emptyList(), peer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a data packet with a termination block.
|
||||
* This will also include acks, a new token block, and padding.
|
||||
*
|
||||
* @throws IOException if peer is dead
|
||||
*/
|
||||
public UDPPacket buildSessionDestroyPacket(int reason, SSU2Sender peer) {
|
||||
public UDPPacket buildSessionDestroyPacket(int reason, SSU2Sender peer) throws IOException {
|
||||
if (_log.shouldDebug())
|
||||
_log.debug("Sending termination " + reason + " to : " + peer);
|
||||
peer.setDestroyReason(reason);
|
||||
@@ -690,8 +699,9 @@ class PacketBuilder2 {
|
||||
* In-session, message 1.
|
||||
*
|
||||
* @return ready to send packet, non-null
|
||||
* @throws IOException if peer is dead
|
||||
*/
|
||||
public UDPPacket buildPeerTestFromAlice(byte[] signedData, PeerState2 bob) {
|
||||
public UDPPacket buildPeerTestFromAlice(byte[] signedData, PeerState2 bob) throws IOException {
|
||||
Block block = new SSU2Payload.PeerTestBlock(1, 0, null, signedData);
|
||||
UDPPacket rv = buildPacket(Collections.<Fragment>emptyList(), Collections.singletonList(block), bob);
|
||||
rv.setMessageType(TYPE_TFA);
|
||||
@@ -726,8 +736,9 @@ class PacketBuilder2 {
|
||||
*
|
||||
* @param charlieHash fake hash (all zeros) if rejected by bob
|
||||
* @return ready to send packet, non-null
|
||||
* @throws IOException if peer is dead
|
||||
*/
|
||||
public UDPPacket buildPeerTestToAlice(int code, Hash charlieHash, byte[] signedData, PeerState2 alice) {
|
||||
public UDPPacket buildPeerTestToAlice(int code, Hash charlieHash, byte[] signedData, PeerState2 alice) throws IOException {
|
||||
return buildPeerTestToAlice(code, charlieHash, signedData, null, alice);
|
||||
}
|
||||
|
||||
@@ -739,9 +750,10 @@ class PacketBuilder2 {
|
||||
* @param charlieHash fake hash (all zeros) if rejected by bob
|
||||
* @param riBlock to include, may be null
|
||||
* @return ready to send packet, non-null
|
||||
* @throws IOException if peer is dead
|
||||
* @since 0.9.57
|
||||
*/
|
||||
public UDPPacket buildPeerTestToAlice(int code, Hash charlieHash, byte[] signedData, Block riBlock, PeerState2 alice) {
|
||||
public UDPPacket buildPeerTestToAlice(int code, Hash charlieHash, byte[] signedData, Block riBlock, PeerState2 alice) throws IOException {
|
||||
Block block = new SSU2Payload.PeerTestBlock(4, code, charlieHash, signedData);
|
||||
List<Block> blocks;
|
||||
if (riBlock != null) {
|
||||
@@ -786,8 +798,9 @@ class PacketBuilder2 {
|
||||
*
|
||||
* @param riBlock to include, may be null
|
||||
* @return ready to send packet, non-null
|
||||
* @throws IOException if peer is dead
|
||||
*/
|
||||
public UDPPacket buildPeerTestToCharlie(Hash aliceHash, byte[] signedData, Block riBlock, PeerState2 charlie) {
|
||||
public UDPPacket buildPeerTestToCharlie(Hash aliceHash, byte[] signedData, Block riBlock, PeerState2 charlie) throws IOException {
|
||||
Block block = new SSU2Payload.PeerTestBlock(2, 0, aliceHash, signedData);
|
||||
List<Block> blocks;
|
||||
if (riBlock != null) {
|
||||
@@ -808,8 +821,9 @@ class PacketBuilder2 {
|
||||
* In-session, message 3.
|
||||
*
|
||||
* @return ready to send packet, non-null
|
||||
* @throws IOException if peer is dead
|
||||
*/
|
||||
public UDPPacket buildPeerTestToBob(int code, byte[] signedData, PeerState2 bob) {
|
||||
public UDPPacket buildPeerTestToBob(int code, byte[] signedData, PeerState2 bob) throws IOException {
|
||||
Block block = new SSU2Payload.PeerTestBlock(3, code, null, signedData);
|
||||
UDPPacket rv = buildPacket(Collections.<Fragment>emptyList(), Collections.singletonList(block), bob);
|
||||
rv.setMessageType(TYPE_TCB);
|
||||
@@ -822,8 +836,9 @@ class PacketBuilder2 {
|
||||
*
|
||||
* @param signedData flag + signed data
|
||||
* @return non-null
|
||||
* @throws IOException if peer is dead
|
||||
*/
|
||||
UDPPacket buildRelayRequest(byte[] signedData, PeerState2 bob) {
|
||||
UDPPacket buildRelayRequest(byte[] signedData, PeerState2 bob) throws IOException {
|
||||
Block block = new SSU2Payload.RelayRequestBlock(signedData);
|
||||
UDPPacket rv = buildPacket(Collections.<Fragment>emptyList(), Collections.singletonList(block), bob);
|
||||
rv.setMessageType(TYPE_RREQ);
|
||||
@@ -838,8 +853,9 @@ class PacketBuilder2 {
|
||||
* @param signedData flag + alice hash + signed data
|
||||
* @param riBlock to include, may be null
|
||||
* @return non-null
|
||||
* @throws IOException if peer is dead
|
||||
*/
|
||||
UDPPacket buildRelayIntro(byte[] signedData, Block riBlock, PeerState2 charlie) {
|
||||
UDPPacket buildRelayIntro(byte[] signedData, Block riBlock, PeerState2 charlie) throws IOException {
|
||||
Block block = new SSU2Payload.RelayIntroBlock(signedData);
|
||||
List<Block> blocks;
|
||||
if (riBlock != null) {
|
||||
@@ -862,8 +878,9 @@ class PacketBuilder2 {
|
||||
* @param signedData flag + response code + signed data + optional token
|
||||
* @param state Alice or Bob
|
||||
* @return non-null
|
||||
* @throws IOException if peer is dead
|
||||
*/
|
||||
UDPPacket buildRelayResponse(byte[] signedData, PeerState2 state) {
|
||||
UDPPacket buildRelayResponse(byte[] signedData, PeerState2 state) throws IOException {
|
||||
Block block = new SSU2Payload.RelayResponseBlock(signedData);
|
||||
UDPPacket rv = buildPacket(Collections.<Fragment>emptyList(), Collections.singletonList(block), state);
|
||||
rv.setMessageType(TYPE_RESP);
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package net.i2p.router.transport.udp;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.DatagramPacket;
|
||||
import java.net.InetAddress;
|
||||
import java.net.InetSocketAddress;
|
||||
@@ -136,8 +137,10 @@ public class PeerState2 extends PeerState implements SSU2Payload.PayloadCallback
|
||||
if (isInbound) {
|
||||
// Send immediate ack of Session Confirmed
|
||||
_receivedMessages.set(0);
|
||||
UDPPacket ack = transport.getBuilder2().buildACK(this);
|
||||
transport.send(ack);
|
||||
try {
|
||||
UDPPacket ack = transport.getBuilder2().buildACK(this);
|
||||
transport.send(ack);
|
||||
} catch (IOException ioe) {}
|
||||
} else {
|
||||
// For outbound, SessionConfirmed is packet 0
|
||||
_packetNumber.set(1);
|
||||
@@ -274,8 +277,10 @@ public class PeerState2 extends PeerState implements SSU2Payload.PayloadCallback
|
||||
// and close the session in super.finishMessages()
|
||||
if (_log.shouldWarn())
|
||||
_log.warn("Fail, no Sess Conf ACK rcvd on " + this);
|
||||
UDPPacket pkt = _transport.getBuilder2().buildSessionDestroyPacket(SSU2Util.REASON_FRAME_TIMEOUT, this);
|
||||
_transport.send(pkt);
|
||||
try {
|
||||
UDPPacket pkt = _transport.getBuilder2().buildSessionDestroyPacket(SSU2Util.REASON_FRAME_TIMEOUT, this);
|
||||
_transport.send(pkt);
|
||||
} catch (IOException ioe) {}
|
||||
_transport.dropPeer(this, true, "No Sess Conf ACK rcvd");
|
||||
_sessConfForReTX = null;
|
||||
return false;
|
||||
@@ -316,7 +321,22 @@ public class PeerState2 extends PeerState implements SSU2Payload.PayloadCallback
|
||||
* starts at 1 for Alice (0 is Session Confirmed) and 0 for Bob
|
||||
* @since public since 0.9.57 for SSU2Sender interface only
|
||||
*/
|
||||
public long getNextPacketNumber() { return _packetNumber.getAndIncrement(); }
|
||||
public long getNextPacketNumber() throws IOException {
|
||||
if (_dead) {
|
||||
IOException ioe = new IOException("Peer is dead: " + _remotePeer.toBase64());
|
||||
if (_log.shouldWarn())
|
||||
_log.warn("Dead: " + this, ioe);
|
||||
throw ioe;
|
||||
}
|
||||
return _packetNumber.getAndIncrement();
|
||||
}
|
||||
|
||||
/**
|
||||
* For PeerStateDestroyed only, after we are dead
|
||||
* @since 0.9.57
|
||||
*/
|
||||
protected long getNextPacketNumberNoThrow() { return _packetNumber.getAndIncrement(); }
|
||||
|
||||
/**
|
||||
* @since public since 0.9.57 for SSU2Sender interface only
|
||||
*/
|
||||
@@ -583,12 +603,14 @@ public class PeerState2 extends PeerState implements SSU2Payload.PayloadCallback
|
||||
blocks.add(new SSU2Payload.DateTimeBlock(_context));
|
||||
blocks.add(new SSU2Payload.AddressBlock(toIP.getAddress(), toPort));
|
||||
blocks.add(new SSU2Payload.PathChallengeBlock(_pathChallengeData));
|
||||
UDPPacket packet = _transport.getBuilder2().buildPacket(Collections.<Fragment>emptyList(), blocks, this);
|
||||
// fix up IP/port
|
||||
DatagramPacket pkt = packet.getPacket();
|
||||
pkt.setAddress(toIP);
|
||||
pkt.setPort(toPort);
|
||||
_transport.send(packet);
|
||||
try {
|
||||
UDPPacket packet = _transport.getBuilder2().buildPacket(Collections.<Fragment>emptyList(), blocks, this);
|
||||
// fix up IP/port
|
||||
DatagramPacket pkt = packet.getPacket();
|
||||
pkt.setAddress(toIP);
|
||||
pkt.setPort(toPort);
|
||||
_transport.send(packet);
|
||||
} catch (IOException ioe) {}
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////
|
||||
@@ -650,10 +672,12 @@ public class PeerState2 extends PeerState implements SSU2Payload.PayloadCallback
|
||||
}
|
||||
if (tag > 0) {
|
||||
SSU2Payload.Block block = new SSU2Payload.RelayTagBlock(tag);
|
||||
UDPPacket pkt = _transport.getBuilder2().buildPacket(Collections.<Fragment>emptyList(),
|
||||
Collections.singletonList(block),
|
||||
this);
|
||||
_transport.send(pkt);
|
||||
try {
|
||||
UDPPacket pkt = _transport.getBuilder2().buildPacket(Collections.<Fragment>emptyList(),
|
||||
Collections.singletonList(block),
|
||||
this);
|
||||
_transport.send(pkt);
|
||||
} catch (IOException ioe) {}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -826,8 +850,10 @@ public class PeerState2 extends PeerState implements SSU2Payload.PayloadCallback
|
||||
if (reason == SSU2Util.REASON_TERMINATION) {
|
||||
// this should only happen at shutdown, where we don't have a post-termination handler
|
||||
} else {
|
||||
UDPPacket pkt = _transport.getBuilder2().buildSessionDestroyPacket(SSU2Util.REASON_TERMINATION, this);
|
||||
_transport.send(pkt);
|
||||
try {
|
||||
UDPPacket pkt = _transport.getBuilder2().buildSessionDestroyPacket(SSU2Util.REASON_TERMINATION, this);
|
||||
_transport.send(pkt);
|
||||
} catch (IOException ioe) {}
|
||||
}
|
||||
if (!_dead) {
|
||||
_transport.getEstablisher().receiveSessionDestroy(_remoteHostId, this);
|
||||
@@ -839,14 +865,16 @@ public class PeerState2 extends PeerState implements SSU2Payload.PayloadCallback
|
||||
if (_log.shouldInfo())
|
||||
_log.info("Got PATH CHALLENGE block, length: " + data.length + " on " + this);
|
||||
SSU2Payload.Block block = new SSU2Payload.PathResponseBlock(data);
|
||||
UDPPacket pkt = _transport.getBuilder2().buildPacket(Collections.<Fragment>emptyList(),
|
||||
Collections.singletonList(block),
|
||||
this);
|
||||
// TODO send to from address?
|
||||
_transport.send(pkt);
|
||||
long now = _context.clock().now();
|
||||
setLastSendTime(now);
|
||||
setLastReceiveTime(now);
|
||||
try {
|
||||
UDPPacket pkt = _transport.getBuilder2().buildPacket(Collections.<Fragment>emptyList(),
|
||||
Collections.singletonList(block),
|
||||
this);
|
||||
// TODO send to from address?
|
||||
_transport.send(pkt);
|
||||
long now = _context.clock().now();
|
||||
setLastSendTime(now);
|
||||
setLastReceiveTime(now);
|
||||
} catch (IOException ioe) {}
|
||||
}
|
||||
|
||||
public void gotPathResponse(RemoteHostId from, byte[] data) {
|
||||
@@ -866,13 +894,15 @@ public class PeerState2 extends PeerState implements SSU2Payload.PayloadCallback
|
||||
if (isIPv6() || !_transport.isSnatted()) {
|
||||
EstablishmentManager.Token token = _transport.getEstablisher().getInboundToken(from);
|
||||
SSU2Payload.Block block = new SSU2Payload.NewTokenBlock(token);
|
||||
UDPPacket pkt = _transport.getBuilder2().buildPacket(Collections.<Fragment>emptyList(),
|
||||
Collections.singletonList(block),
|
||||
this);
|
||||
_transport.send(pkt);
|
||||
long now = _context.clock().now();
|
||||
setLastSendTime(now);
|
||||
setLastReceiveTime(now);
|
||||
try {
|
||||
UDPPacket pkt = _transport.getBuilder2().buildPacket(Collections.<Fragment>emptyList(),
|
||||
Collections.singletonList(block),
|
||||
this);
|
||||
_transport.send(pkt);
|
||||
long now = _context.clock().now();
|
||||
setLastSendTime(now);
|
||||
setLastReceiveTime(now);
|
||||
} catch (IOException ioe) {}
|
||||
} else {
|
||||
messagePartiallyReceived();
|
||||
}
|
||||
@@ -1109,10 +1139,12 @@ public class PeerState2 extends PeerState implements SSU2Payload.PayloadCallback
|
||||
}
|
||||
_wantACKSendSince = 0;
|
||||
}
|
||||
UDPPacket ack = _transport.getBuilder2().buildACK(PeerState2.this);
|
||||
if (_log.shouldDebug())
|
||||
_log.debug("ACKTimer sending acks to " + PeerState2.this);
|
||||
_transport.send(ack);
|
||||
try {
|
||||
UDPPacket ack = _transport.getBuilder2().buildACK(PeerState2.this);
|
||||
if (_log.shouldDebug())
|
||||
_log.debug("ACKTimer sending acks to " + PeerState2.this);
|
||||
_transport.send(ack);
|
||||
} catch (IOException ioe) {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package net.i2p.router.transport.udp;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.DatagramPacket;
|
||||
import java.net.InetAddress;
|
||||
import java.net.UnknownHostException;
|
||||
@@ -73,7 +74,7 @@ class PeerStateDestroyed implements SSU2Payload.PayloadCallback, SSU2Sender {
|
||||
_log = ctx.logManager().getLog(PeerStateDestroyed.class);
|
||||
_remoteHostId = peer.getRemoteHostId();
|
||||
_mtu = peer.getMTU();
|
||||
_packetNumber = new AtomicInteger((int) peer.getNextPacketNumber());
|
||||
_packetNumber = new AtomicInteger((int) peer.getNextPacketNumberNoThrow());
|
||||
_sendConnID = peer.getSendConnID();
|
||||
_rcvConnID = peer.getRcvConnID();
|
||||
_sendCha = peer.getSendCipher();
|
||||
@@ -370,10 +371,12 @@ class PeerStateDestroyed implements SSU2Payload.PayloadCallback, SSU2Sender {
|
||||
// If we received a destroy, send reason_termination
|
||||
// otherwise, send the original reason.
|
||||
|
||||
UDPPacket pkt = _transport.getBuilder2().buildSessionDestroyPacket(_destroyReason, PeerStateDestroyed.this);
|
||||
if (_log.shouldDebug())
|
||||
_log.debug("Sending TERMINATION reason " + _destroyReason + " to " + PeerStateDestroyed.this);
|
||||
_transport.send(pkt);
|
||||
try {
|
||||
UDPPacket pkt = _transport.getBuilder2().buildSessionDestroyPacket(_destroyReason, PeerStateDestroyed.this);
|
||||
if (_log.shouldDebug())
|
||||
_log.debug("Sending TERMINATION reason " + _destroyReason + " to " + PeerStateDestroyed.this);
|
||||
_transport.send(pkt);
|
||||
} catch (IOException ioe) {}
|
||||
if (_destroyReason != REASON_TERMINATION) {
|
||||
_delay *= 2;
|
||||
reschedule(_delay);
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package net.i2p.router.transport.udp;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.DatagramPacket;
|
||||
import java.net.InetAddress;
|
||||
import java.net.Inet6Address;
|
||||
@@ -380,7 +381,12 @@ class PeerTestManager {
|
||||
}
|
||||
test.setTestData(data);
|
||||
}
|
||||
packet = _packetBuilder2.buildPeerTestFromAlice(data, bob2);
|
||||
try {
|
||||
packet = _packetBuilder2.buildPeerTestFromAlice(data, bob2);
|
||||
} catch (IOException ioe) {
|
||||
fail();
|
||||
return;
|
||||
}
|
||||
}
|
||||
_transport.send(packet);
|
||||
long now = _context.clock().now();
|
||||
@@ -607,7 +613,25 @@ class PeerTestManager {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Reset all state and call testComplete(). We are Alice.
|
||||
*
|
||||
* call from a synchronized method
|
||||
*
|
||||
* @since 0.9.57
|
||||
*/
|
||||
private void fail() {
|
||||
// so testComplete() will return UNKNOWN
|
||||
PeerTestState test = _currentTest;
|
||||
if (test == null)
|
||||
return;
|
||||
test.setAlicePortFromCharlie(0);
|
||||
test.setReceiveCharlieTime(0);
|
||||
test.setReceiveBobTime(0);
|
||||
testComplete();
|
||||
}
|
||||
|
||||
/**
|
||||
* Evaluate the info we have and act accordingly, since the test has either timed out or
|
||||
* we have successfully received the second PeerTest from a Charlie.
|
||||
@@ -1081,21 +1105,29 @@ class PeerTestManager {
|
||||
_log.debug("Retx msg 4 to alice on " + state);
|
||||
// we already sent to alice, send it again
|
||||
PeerState2 alice = state.getAlice();
|
||||
UDPPacket packet = _packetBuilder2.buildPeerTestToAlice(state.getStatus(), state.getCharlieHash(), data, alice);
|
||||
_transport.send(packet);
|
||||
alice.setLastSendTime(now);
|
||||
state.setSendAliceTime(now);
|
||||
state.setReceiveAliceTime(now);
|
||||
try {
|
||||
UDPPacket packet = _packetBuilder2.buildPeerTestToAlice(state.getStatus(), state.getCharlieHash(), data, alice);
|
||||
_transport.send(packet);
|
||||
alice.setLastSendTime(now);
|
||||
state.setSendAliceTime(now);
|
||||
state.setReceiveAliceTime(now);
|
||||
} catch (IOException ioe) {
|
||||
_activeTests.remove(lNonce);
|
||||
}
|
||||
return;
|
||||
} else if (msg == 2) {
|
||||
if (_log.shouldDebug())
|
||||
_log.debug("Retx msg 3 to bob on " + state);
|
||||
PeerState2 bob = (PeerState2) state.getBob();
|
||||
UDPPacket packet = _packetBuilder2.buildPeerTestToBob(state.getStatus(), data, bob);
|
||||
_transport.send(packet);
|
||||
bob.setLastSendTime(now);
|
||||
state.setReceiveBobTime(now);
|
||||
// should we retx msg 5 also?
|
||||
try {
|
||||
UDPPacket packet = _packetBuilder2.buildPeerTestToBob(state.getStatus(), data, bob);
|
||||
_transport.send(packet);
|
||||
bob.setLastSendTime(now);
|
||||
state.setReceiveBobTime(now);
|
||||
// should we retx msg 5 also?
|
||||
} catch (IOException ioe) {
|
||||
_activeTests.remove(lNonce);
|
||||
}
|
||||
return;
|
||||
} else {
|
||||
// msg 1 but haven't heard from a good charlie yet
|
||||
@@ -1114,13 +1146,15 @@ class PeerTestManager {
|
||||
if (_log.shouldWarn())
|
||||
_log.warn("Too many active tests, droppping from " + Addresses.toString(fromIP, fromPort));
|
||||
UDPPacket packet;
|
||||
if (msg == 1)
|
||||
packet = _packetBuilder2.buildPeerTestToAlice(SSU2Util.TEST_REJECT_BOB_LIMIT,
|
||||
Hash.FAKE_HASH, data, fromPeer);
|
||||
else
|
||||
packet = _packetBuilder2.buildPeerTestToBob(SSU2Util.TEST_REJECT_CHARLIE_LIMIT,
|
||||
data, fromPeer);
|
||||
_transport.send(packet);
|
||||
try {
|
||||
if (msg == 1)
|
||||
packet = _packetBuilder2.buildPeerTestToAlice(SSU2Util.TEST_REJECT_BOB_LIMIT,
|
||||
Hash.FAKE_HASH, data, fromPeer);
|
||||
else
|
||||
packet = _packetBuilder2.buildPeerTestToBob(SSU2Util.TEST_REJECT_CHARLIE_LIMIT,
|
||||
data, fromPeer);
|
||||
_transport.send(packet);
|
||||
} catch (IOException ioe) {}
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
@@ -1157,18 +1191,14 @@ class PeerTestManager {
|
||||
!DataHelper.eq(fromPeer.getRemoteIP(), 0, testIP, 0, isIPv6 ? 8 : 4)) {
|
||||
if (_log.shouldWarn())
|
||||
_log.warn("Invalid PeerTest address: " + Addresses.toString(testIP, testPort));
|
||||
UDPPacket packet = _packetBuilder2.buildPeerTestToAlice(SSU2Util.TEST_REJECT_BOB_ADDRESS,
|
||||
Hash.FAKE_HASH, data, fromPeer);
|
||||
_transport.send(packet);
|
||||
sendRejectToAlice(SSU2Util.TEST_REJECT_BOB_ADDRESS, data, fromPeer);
|
||||
fromPeer.setLastSendTime(now);
|
||||
return;
|
||||
}
|
||||
if (_throttle.shouldThrottle(fromIP)) {
|
||||
if (_log.shouldLog(Log.WARN))
|
||||
_log.warn("PeerTest throttle from " + Addresses.toString(fromIP, fromPort));
|
||||
UDPPacket packet = _packetBuilder2.buildPeerTestToAlice(SSU2Util.TEST_REJECT_BOB_LIMIT,
|
||||
Hash.FAKE_HASH, data, fromPeer);
|
||||
_transport.send(packet);
|
||||
sendRejectToAlice(SSU2Util.TEST_REJECT_BOB_LIMIT, data, fromPeer);
|
||||
fromPeer.setLastSendTime(now);
|
||||
return;
|
||||
}
|
||||
@@ -1178,9 +1208,7 @@ class PeerTestManager {
|
||||
if (_log.shouldLog(Log.WARN))
|
||||
_log.warn("No alice RI");
|
||||
// send reject
|
||||
UDPPacket packet = _packetBuilder2.buildPeerTestToAlice(SSU2Util.TEST_REJECT_BOB_UNSPEC,
|
||||
Hash.FAKE_HASH, data, fromPeer);
|
||||
_transport.send(packet);
|
||||
sendRejectToAlice(SSU2Util.TEST_REJECT_BOB_UNSPEC, data, fromPeer);
|
||||
fromPeer.setLastSendTime(now);
|
||||
return;
|
||||
}
|
||||
@@ -1192,9 +1220,7 @@ class PeerTestManager {
|
||||
if (_log.shouldWarn())
|
||||
_log.warn("Signature failed msg 1\n" + aliceRI);
|
||||
// send reject
|
||||
UDPPacket packet = _packetBuilder2.buildPeerTestToAlice(SSU2Util.TEST_REJECT_BOB_SIGFAIL,
|
||||
Hash.FAKE_HASH, data, fromPeer);
|
||||
_transport.send(packet);
|
||||
sendRejectToAlice(SSU2Util.TEST_REJECT_BOB_SIGFAIL, data, fromPeer);
|
||||
fromPeer.setLastSendTime(now);
|
||||
return;
|
||||
}
|
||||
@@ -1203,9 +1229,7 @@ class PeerTestManager {
|
||||
if (_log.shouldLog(Log.WARN))
|
||||
_log.warn("Unable to pick a charlie (no peer), IPv6? " + isIPv6);
|
||||
// send reject
|
||||
UDPPacket packet = _packetBuilder2.buildPeerTestToAlice(SSU2Util.TEST_REJECT_BOB_NO_CHARLIE,
|
||||
Hash.FAKE_HASH, data, fromPeer);
|
||||
_transport.send(packet);
|
||||
sendRejectToAlice(SSU2Util.TEST_REJECT_BOB_NO_CHARLIE, data, fromPeer);
|
||||
fromPeer.setLastSendTime(now);
|
||||
return;
|
||||
}
|
||||
@@ -1229,7 +1253,12 @@ class PeerTestManager {
|
||||
if (_log.shouldDebug())
|
||||
_log.debug("Send Alice RI and msg 2 to charlie on " + state);
|
||||
// forward to charlie, don't bother to validate signed data
|
||||
sendRIandPT(aliceRI, -1, alice, data, (PeerState2) charlie, now);
|
||||
try {
|
||||
sendRIandPT(aliceRI, -1, alice, data, (PeerState2) charlie, now);
|
||||
} catch (IOException ioe) {
|
||||
sendRejectToAlice(SSU2Util.TEST_REJECT_BOB_UNSPEC, data, fromPeer);
|
||||
_activeTests.remove(lNonce);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1311,15 +1340,21 @@ class PeerTestManager {
|
||||
if (data == null) {
|
||||
if (_log.shouldWarn())
|
||||
_log.warn("sig fail");
|
||||
if (rcode == SSU2Util.TEST_ACCEPT)
|
||||
_activeTests.remove(lNonce);
|
||||
return;
|
||||
if (rcode == SSU2Util.TEST_ACCEPT)
|
||||
_activeTests.remove(lNonce);
|
||||
return;
|
||||
}
|
||||
try {
|
||||
UDPPacket packet = _packetBuilder2.buildPeerTestToBob(rcode, data, fromPeer);
|
||||
if (_log.shouldDebug())
|
||||
_log.debug("Send msg 3 response " + rcode + " nonce " + lNonce + " to " + fromPeer);
|
||||
_transport.send(packet);
|
||||
fromPeer.setLastSendTime(now);
|
||||
} catch (IOException ioe) {
|
||||
if (rcode == SSU2Util.TEST_ACCEPT)
|
||||
_activeTests.remove(lNonce);
|
||||
return;
|
||||
}
|
||||
UDPPacket packet = _packetBuilder2.buildPeerTestToBob(rcode, data, fromPeer);
|
||||
if (_log.shouldDebug())
|
||||
_log.debug("Send msg 3 response " + rcode + " nonce " + lNonce + " to " + fromPeer);
|
||||
_transport.send(packet);
|
||||
fromPeer.setLastSendTime(now);
|
||||
if (rcode == SSU2Util.TEST_ACCEPT) {
|
||||
// send msg 5
|
||||
if (_log.shouldDebug())
|
||||
@@ -1327,7 +1362,7 @@ class PeerTestManager {
|
||||
long sendId = (nonce << 32) | nonce;
|
||||
long rcvId = ~sendId;
|
||||
// send the same data we sent to Bob
|
||||
packet = _packetBuilder2.buildPeerTestToAlice(aliceIP, testPort,
|
||||
UDPPacket packet = _packetBuilder2.buildPeerTestToAlice(aliceIP, testPort,
|
||||
aliceIntroKey, true,
|
||||
sendId, rcvId, data);
|
||||
_transport.send(packet);
|
||||
@@ -1351,12 +1386,16 @@ class PeerTestManager {
|
||||
Hash alice = state.getAlice().getRemotePeer();
|
||||
RouterInfo aliceRI = _context.netDb().lookupRouterInfoLocally(alice);
|
||||
if (aliceRI != null) {
|
||||
if (_log.shouldInfo())
|
||||
_log.info("Charlie response " + status + " picked a new one " + charlie + " on " + state);
|
||||
state.setCharlie(charlie.getRemoteIPAddress(), charlie.getRemotePort(), charlie.getRemotePeer());
|
||||
state.setLastSendTime(now);
|
||||
sendRIandPT(aliceRI, -1, alice, state.getTestData(), (PeerState2) charlie, now);
|
||||
break;
|
||||
try {
|
||||
state.setCharlie(charlie.getRemoteIPAddress(), charlie.getRemotePort(), charlie.getRemotePeer());
|
||||
state.setLastSendTime(now);
|
||||
sendRIandPT(aliceRI, -1, alice, state.getTestData(), (PeerState2) charlie, now);
|
||||
if (_log.shouldInfo())
|
||||
_log.info("Charlie response " + status + " picked a new one " + charlie + " on " + state);
|
||||
break;
|
||||
} catch (IOException ioe) {
|
||||
// give up
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1391,13 +1430,16 @@ class PeerTestManager {
|
||||
// FIXME this will probably get there before the RI
|
||||
if (_log.shouldDebug())
|
||||
_log.debug("Send msg 4 status " + status + " to alice on " + state);
|
||||
sendRIandPT(charlieRI, status, charlie, data, alice, now);
|
||||
// overwrite alice-signed test data with charlie-signed data in case we need to retransmit
|
||||
state.setStatus(status);
|
||||
state.setSendAliceTime(now);
|
||||
state.setTestData(data);
|
||||
// we should be done, but stick around for possible retx to alice
|
||||
//_activeTests.remove(lNonce);
|
||||
try {
|
||||
sendRIandPT(charlieRI, status, charlie, data, alice, now);
|
||||
// overwrite alice-signed test data with charlie-signed data in case we need to retransmit
|
||||
state.setStatus(status);
|
||||
state.setSendAliceTime(now);
|
||||
state.setTestData(data);
|
||||
// we should be done, but stick around for possible retx to alice
|
||||
} catch (IOException ioe) {
|
||||
_activeTests.remove(lNonce);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1487,12 +1529,7 @@ class PeerTestManager {
|
||||
}
|
||||
}
|
||||
if (charlieIntroKey == null || charlieIP == null || charliePort <= 0) {
|
||||
// reset all state
|
||||
// so testComplete() will return UNKNOWN
|
||||
test.setAlicePortFromCharlie(0);
|
||||
test.setReceiveCharlieTime(0);
|
||||
test.setReceiveBobTime(0);
|
||||
testComplete();
|
||||
fail();
|
||||
return;
|
||||
}
|
||||
InetAddress oldIP = test.getCharlieIP();
|
||||
@@ -1769,6 +1806,18 @@ class PeerTestManager {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Send reject to Alice. We are Bob. SSU2 only.
|
||||
*
|
||||
* @since 0.9.57
|
||||
*/
|
||||
private void sendRejectToAlice(int reason, byte[] data, PeerState2 alice) {
|
||||
try {
|
||||
UDPPacket packet = _packetBuilder2.buildPeerTestToAlice(reason, Hash.FAKE_HASH, data, alice);
|
||||
_transport.send(packet);
|
||||
} catch (IOException ioe) {}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an address out of a RI. SSU2 only.
|
||||
*
|
||||
@@ -2205,8 +2254,9 @@ class PeerTestManager {
|
||||
* @param data signed peer test data
|
||||
* @param to charlie for msg 2, alice for msg 4
|
||||
* @since 0.9.57
|
||||
* @throws IOException if to peer is dead
|
||||
*/
|
||||
private void sendRIandPT(RouterInfo ri, int status, Hash hash, byte[] data, PeerState2 to, long now) {
|
||||
private void sendRIandPT(RouterInfo ri, int status, Hash hash, byte[] data, PeerState2 to, long now) throws IOException {
|
||||
boolean delay = false;
|
||||
SSU2Payload.RIBlock riblock = null;
|
||||
if (ri != null) {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package net.i2p.router.transport.udp;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.InetAddress;
|
||||
import java.util.List;
|
||||
|
||||
@@ -17,7 +18,7 @@ interface SSU2Sender {
|
||||
InetAddress getRemoteIPAddress();
|
||||
int getRemotePort();
|
||||
int getMTU();
|
||||
long getNextPacketNumber();
|
||||
long getNextPacketNumber() throws IOException;
|
||||
long getSendConnID();
|
||||
CipherState getSendCipher();
|
||||
byte[] getSendHeaderEncryptKey1();
|
||||
|
||||
@@ -1934,9 +1934,10 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority
|
||||
if (_log.shouldLog(Log.WARN))
|
||||
_log.warn("Peer already connected (PBRH): old=" + oldPeer2 + " new=" + peer);
|
||||
// transfer over the old state/inbound message fragments/etc
|
||||
// Send destroy before loadFrom(), because loadFrom() sets dead = true
|
||||
sendDestroy(oldPeer2, SSU2Util.REASON_REPLACED);
|
||||
peer.loadFrom(oldPeer2);
|
||||
oldEstablishedOn = oldPeer2.getKeyEstablishedTime();
|
||||
sendDestroy(oldPeer2, SSU2Util.REASON_REPLACED);
|
||||
oldPeer2.dropOutbound();
|
||||
_introManager.remove(oldPeer2);
|
||||
}
|
||||
@@ -2351,7 +2352,11 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority
|
||||
return;
|
||||
pkt = _packetBuilder.buildSessionDestroyPacket(peer);
|
||||
} else {
|
||||
pkt = _packetBuilder2.buildSessionDestroyPacket(reasonCode, (PeerState2) peer);
|
||||
try {
|
||||
pkt = _packetBuilder2.buildSessionDestroyPacket(reasonCode, (PeerState2) peer);
|
||||
} catch (IOException ioe) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("Sending destroy to : " + peer);
|
||||
@@ -3826,10 +3831,15 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority
|
||||
// or else session will stay open forever?
|
||||
//peer.setLastSendTime(now);
|
||||
UDPPacket ping;
|
||||
if (peer.getVersion() == 2)
|
||||
ping = _packetBuilder2.buildPing((PeerState2) peer);
|
||||
else
|
||||
if (peer.getVersion() == 2) {
|
||||
try {
|
||||
ping = _packetBuilder2.buildPing((PeerState2) peer);
|
||||
} catch (IOException ioe) {
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
ping = _packetBuilder.buildPing(peer);
|
||||
}
|
||||
send(ping);
|
||||
peer.setLastPingTime(now);
|
||||
// If external port is different, it may be changing the port for every
|
||||
|
||||
Reference in New Issue
Block a user