forked from I2P_Developers/i2p.i2p
SSU: Speed up introductions by responding to HolePunch (ticket #1333)
This commit is contained in:
@@ -967,6 +967,32 @@ class EstablishmentManager {
|
||||
notifyActivity();
|
||||
}
|
||||
|
||||
/**
|
||||
* Called from UDPReceiver.
|
||||
* Accelerate response to RelayResponse if we haven't sent it yet.
|
||||
*
|
||||
* @since 0.9.15
|
||||
*/
|
||||
void receiveHolePunch(InetAddress from, int fromPort) {
|
||||
RemoteHostId id = new RemoteHostId(from.getAddress(), fromPort);
|
||||
OutboundEstablishState state = _outboundStates.get(id);
|
||||
if (state != null) {
|
||||
boolean sendNow = state.receiveHolePunch();
|
||||
if (sendNow) {
|
||||
if (_log.shouldLog(Log.WARN))
|
||||
_log.warn("Hole punch from " + state + ", sending SessionRequest now");
|
||||
notifyActivity();
|
||||
} else {
|
||||
if (_log.shouldLog(Log.WARN))
|
||||
_log.warn("Hole punch from " + state + ", already sent SessionRequest");
|
||||
}
|
||||
} else {
|
||||
// HolePunch received before RelayResponse, and we didn't know the IP/port, or it changed
|
||||
if (_log.shouldLog(Log.WARN))
|
||||
_log.warn("No state found for hole punch from " + from + " port " + fromPort);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Are IP and port valid? This is only for checking the relay response.
|
||||
* Reject all IPv6, for now, even if we are configured for it.
|
||||
|
||||
@@ -99,6 +99,8 @@ class OutboundEstablishState {
|
||||
/** max delay including backoff */
|
||||
private static final long MAX_DELAY = 15*1000;
|
||||
|
||||
private static final long WAIT_FOR_HOLE_PUNCH_DELAY = 500;
|
||||
|
||||
/**
|
||||
* @param claimedAddress an IP/port based RemoteHostId, or null if unknown
|
||||
* @param remoteHostId non-null, == claimedAddress if direct, or a hash-based one if indirect
|
||||
@@ -556,7 +558,7 @@ class OutboundEstablishState {
|
||||
public synchronized void introduced(byte bobIP[], int bobPort) {
|
||||
if (_currentState != OutboundState.OB_STATE_PENDING_INTRO)
|
||||
return; // we've already successfully been introduced, so don't overwrite old settings
|
||||
_nextSend = _context.clock().now() + 500; // wait briefly for the hole punching
|
||||
_nextSend = _context.clock().now() + WAIT_FOR_HOLE_PUNCH_DELAY; // wait briefly for the hole punching
|
||||
_currentState = OutboundState.OB_STATE_INTRODUCED;
|
||||
if (_claimedAddress != null && bobPort == _bobPort && DataHelper.eq(bobIP, _bobIP)) {
|
||||
// he's who he said he was
|
||||
@@ -570,6 +572,24 @@ class OutboundEstablishState {
|
||||
if (_log.shouldLog(Log.INFO))
|
||||
_log.info("Introduced to " + _remoteHostId + ", now lets get on with establishing");
|
||||
}
|
||||
|
||||
/**
|
||||
* Accelerate response to RelayResponse if we haven't sent it yet.
|
||||
*
|
||||
* @return true if we should send the SessionRequest now
|
||||
* @since 0.9.15
|
||||
*/
|
||||
synchronized boolean receiveHolePunch() {
|
||||
if (_currentState != OutboundState.OB_STATE_INTRODUCED)
|
||||
return false;
|
||||
if (_requestSentCount > 0)
|
||||
return false;
|
||||
long now = _context.clock().now();
|
||||
if (_log.shouldLog(Log.WARN))
|
||||
_log.warn(toString() + " accelerating SessionRequest by " + (_nextSend - now) + " ms");
|
||||
_nextSend = now;
|
||||
return true;
|
||||
}
|
||||
|
||||
/** how long have we been trying to establish this session? */
|
||||
public long getLifetime() { return _context.clock().now() - _establishBegin; }
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package net.i2p.router.transport.udp;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.DatagramPacket;
|
||||
import java.net.DatagramSocket;
|
||||
import java.util.Arrays;
|
||||
|
||||
@@ -220,11 +221,12 @@ class UDPReceiver {
|
||||
// _socketChanged = false;
|
||||
//}
|
||||
UDPPacket packet = UDPPacket.acquire(_context, true);
|
||||
DatagramPacket dpacket = packet.getPacket();
|
||||
|
||||
// Android ICS bug
|
||||
// http://code.google.com/p/android/issues/detail?id=24748
|
||||
if (_isAndroid)
|
||||
packet.getPacket().setLength(UDPPacket.MAX_PACKET_SIZE);
|
||||
dpacket.setLength(UDPPacket.MAX_PACKET_SIZE);
|
||||
|
||||
// block before we read...
|
||||
//if (_log.shouldLog(Log.DEBUG))
|
||||
@@ -236,9 +238,9 @@ class UDPReceiver {
|
||||
//if (_log.shouldLog(Log.INFO))
|
||||
// _log.info("Before blocking socket.receive on " + System.identityHashCode(packet));
|
||||
//synchronized (Runner.this) {
|
||||
_socket.receive(packet.getPacket());
|
||||
_socket.receive(dpacket);
|
||||
//}
|
||||
int size = packet.getPacket().getLength();
|
||||
int size = dpacket.getLength();
|
||||
if (_log.shouldLog(Log.INFO))
|
||||
_log.info("After blocking socket.receive: packet is " + size + " bytes on " + System.identityHashCode(packet));
|
||||
packet.resetBegin();
|
||||
@@ -266,7 +268,8 @@ class UDPReceiver {
|
||||
_context.statManager().addRateData("udp.receiveHolePunch", 1);
|
||||
// nat hole punch packets are 0 bytes
|
||||
if (_log.shouldLog(Log.INFO))
|
||||
_log.info("Received a 0 byte udp packet from " + packet.getPacket().getAddress() + ":" + packet.getPacket().getPort());
|
||||
_log.info("Received a 0 byte udp packet from " + dpacket.getAddress() + ":" + dpacket.getPort());
|
||||
_transport.getEstablisher().receiveHolePunch(dpacket.getAddress(), dpacket.getPort());
|
||||
packet.release();
|
||||
}
|
||||
} catch (IOException ioe) {
|
||||
|
||||
Reference in New Issue
Block a user