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

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

SSU: Speed up introductions by responding to HolePunch (ticket #1333)

parent 086381d9
No related branches found
No related tags found
No related merge requests found
......@@ -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; }
......
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) {
......
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