forked from I2P_Developers/i2p.i2p
Transport: Hooks for pluggable transports (ticket #1170)
This commit is contained in:
@ -14,6 +14,8 @@ import java.util.Collections;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import net.i2p.data.Hash;
|
import net.i2p.data.Hash;
|
||||||
import net.i2p.data.router.RouterAddress;
|
import net.i2p.data.router.RouterAddress;
|
||||||
|
import net.i2p.router.transport.Transport;
|
||||||
|
import net.i2p.router.transport.crypto.DHSessionKeyBuilder;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Manages the communication subsystem between peers, including connections,
|
* Manages the communication subsystem between peers, including connections,
|
||||||
@ -85,6 +87,24 @@ public abstract class CommSystemFacade implements Service {
|
|||||||
*/
|
*/
|
||||||
public void notifyReplaceAddress(RouterAddress UDPAddr) {}
|
public void notifyReplaceAddress(RouterAddress UDPAddr) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pluggable transport
|
||||||
|
* @since 0.9.16
|
||||||
|
*/
|
||||||
|
public void registerTransport(Transport t) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pluggable transport
|
||||||
|
* @since 0.9.16
|
||||||
|
*/
|
||||||
|
public void unregisterTransport(Transport t) {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hook for pluggable transport creation.
|
||||||
|
* @since 0.9.16
|
||||||
|
*/
|
||||||
|
public DHSessionKeyBuilder.Factory getDHFactory() { return null; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* These must be increasing in "badness" (see TransportManager.java),
|
* These must be increasing in "badness" (see TransportManager.java),
|
||||||
* but UNKNOWN must be last.
|
* but UNKNOWN must be last.
|
||||||
|
@ -22,6 +22,7 @@ import net.i2p.data.router.RouterInfo;
|
|||||||
import net.i2p.router.CommSystemFacade;
|
import net.i2p.router.CommSystemFacade;
|
||||||
import net.i2p.router.OutNetMessage;
|
import net.i2p.router.OutNetMessage;
|
||||||
import net.i2p.router.RouterContext;
|
import net.i2p.router.RouterContext;
|
||||||
|
import net.i2p.router.transport.crypto.DHSessionKeyBuilder;
|
||||||
import net.i2p.router.transport.udp.UDPTransport;
|
import net.i2p.router.transport.udp.UDPTransport;
|
||||||
import net.i2p.router.util.EventLog;
|
import net.i2p.router.util.EventLog;
|
||||||
import net.i2p.util.Addresses;
|
import net.i2p.util.Addresses;
|
||||||
@ -223,6 +224,47 @@ public class CommSystemFacadeImpl extends CommSystemFacade {
|
|||||||
_manager.externalAddressReceived(Transport.AddressSource.SOURCE_SSU, ip, port);
|
_manager.externalAddressReceived(Transport.AddressSource.SOURCE_SSU, ip, port);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pluggable transports. Not for NTCP or SSU.
|
||||||
|
*
|
||||||
|
* Do not call from transport constructor. Transport must be ready to be started.
|
||||||
|
*
|
||||||
|
* Following transport methods will be called:
|
||||||
|
* setListener()
|
||||||
|
* externalAddressReceived() (zero or more times, one for each known address)
|
||||||
|
* startListening();
|
||||||
|
*
|
||||||
|
* @since 0.9.16
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void registerTransport(Transport t) {
|
||||||
|
_manager.registerAndStart(t);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pluggable transports. Not for NTCP or SSU.
|
||||||
|
*
|
||||||
|
* Following transport methods will be called:
|
||||||
|
* setListener(null)
|
||||||
|
* stoptListening();
|
||||||
|
*
|
||||||
|
* @since 0.9.16
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void unregisterTransport(Transport t) {
|
||||||
|
_manager.stopAndUnregister(t);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hook for pluggable transport creation.
|
||||||
|
*
|
||||||
|
* @since 0.9.16
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public DHSessionKeyBuilder.Factory getDHFactory() {
|
||||||
|
return _manager.getDHFactory();
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* GeoIP stuff
|
* GeoIP stuff
|
||||||
*
|
*
|
||||||
|
@ -13,6 +13,7 @@ import java.io.Writer;
|
|||||||
import java.net.InetAddress;
|
import java.net.InetAddress;
|
||||||
import java.net.UnknownHostException;
|
import java.net.UnknownHostException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@ -44,6 +45,8 @@ public class TransportManager implements TransportEventListener {
|
|||||||
* If we want more than one transport with the same style we will have to change this.
|
* If we want more than one transport with the same style we will have to change this.
|
||||||
*/
|
*/
|
||||||
private final Map<String, Transport> _transports;
|
private final Map<String, Transport> _transports;
|
||||||
|
/** locking: this */
|
||||||
|
private final Map<String, Transport> _pluggableTransports;
|
||||||
private final RouterContext _context;
|
private final RouterContext _context;
|
||||||
private final UPnPManager _upnpManager;
|
private final UPnPManager _upnpManager;
|
||||||
private final DHSessionKeyBuilder.PrecalcRunner _dhThread;
|
private final DHSessionKeyBuilder.PrecalcRunner _dhThread;
|
||||||
@ -66,6 +69,7 @@ public class TransportManager implements TransportEventListener {
|
|||||||
_context.statManager().createRateStat("transport.bidFailNoTransports", "Could not attempt to bid on message, as none of the transports could attempt it", "Transport", new long[] { 60*1000, 10*60*1000, 60*60*1000 });
|
_context.statManager().createRateStat("transport.bidFailNoTransports", "Could not attempt to bid on message, as none of the transports could attempt it", "Transport", new long[] { 60*1000, 10*60*1000, 60*60*1000 });
|
||||||
_context.statManager().createRateStat("transport.bidFailAllTransports", "Could not attempt to bid on message, as all of the transports had failed", "Transport", new long[] { 60*1000, 10*60*1000, 60*60*1000 });
|
_context.statManager().createRateStat("transport.bidFailAllTransports", "Could not attempt to bid on message, as all of the transports had failed", "Transport", new long[] { 60*1000, 10*60*1000, 60*60*1000 });
|
||||||
_transports = new ConcurrentHashMap<String, Transport>(2);
|
_transports = new ConcurrentHashMap<String, Transport>(2);
|
||||||
|
_pluggableTransports = new HashMap<String, Transport>(2);
|
||||||
if (_context.getBooleanPropertyDefaultTrue(PROP_ENABLE_UPNP))
|
if (_context.getBooleanPropertyDefaultTrue(PROP_ENABLE_UPNP))
|
||||||
_upnpManager = new UPnPManager(context, this);
|
_upnpManager = new UPnPManager(context, this);
|
||||||
else
|
else
|
||||||
@ -73,15 +77,66 @@ public class TransportManager implements TransportEventListener {
|
|||||||
_dhThread = new DHSessionKeyBuilder.PrecalcRunner(context);
|
_dhThread = new DHSessionKeyBuilder.PrecalcRunner(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addTransport(Transport transport) {
|
/**
|
||||||
|
* Pluggable transports. Not for NTCP or SSU.
|
||||||
|
*
|
||||||
|
* @since 0.9.16
|
||||||
|
*/
|
||||||
|
synchronized void registerAndStart(Transport t) {
|
||||||
|
String style = t.getStyle();
|
||||||
|
if (style.equals(NTCPTransport.STYLE) || style.equals(UDPTransport.STYLE))
|
||||||
|
throw new IllegalArgumentException("Builtin transport");
|
||||||
|
if (_transports.containsKey(style) || _pluggableTransports.containsKey(style))
|
||||||
|
throw new IllegalStateException("Dup transport");
|
||||||
|
boolean shouldStart = !_transports.isEmpty();
|
||||||
|
_pluggableTransports.put(style, t);
|
||||||
|
addTransport(t);
|
||||||
|
t.setListener(this);
|
||||||
|
if (shouldStart) {
|
||||||
|
initializeAddress(t);
|
||||||
|
t.startListening();
|
||||||
|
_context.router().rebuildRouterInfo();
|
||||||
|
} // else will be started by configTransports() (unlikely)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Pluggable transports. Not for NTCP or SSU.
|
||||||
|
*
|
||||||
|
* @since 0.9.16
|
||||||
|
*/
|
||||||
|
synchronized void stopAndUnregister(Transport t) {
|
||||||
|
String style = t.getStyle();
|
||||||
|
if (style.equals(NTCPTransport.STYLE) || style.equals(UDPTransport.STYLE))
|
||||||
|
throw new IllegalArgumentException("Builtin transport");
|
||||||
|
t.setListener(null);
|
||||||
|
_pluggableTransports.remove(style);
|
||||||
|
removeTransport(t);
|
||||||
|
t.stopListening();
|
||||||
|
_context.router().rebuildRouterInfo();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hook for pluggable transport creation.
|
||||||
|
*
|
||||||
|
* @since 0.9.16
|
||||||
|
*/
|
||||||
|
DHSessionKeyBuilder.Factory getDHFactory() {
|
||||||
|
return _dhThread;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addTransport(Transport transport) {
|
||||||
if (transport == null) return;
|
if (transport == null) return;
|
||||||
_transports.put(transport.getStyle(), transport);
|
Transport old = _transports.put(transport.getStyle(), transport);
|
||||||
|
if (old != null && old != transport && _log.shouldLog(Log.WARN))
|
||||||
|
_log.warn("Replacing transport " + transport.getStyle());
|
||||||
transport.setListener(this);
|
transport.setListener(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void removeTransport(Transport transport) {
|
private void removeTransport(Transport transport) {
|
||||||
if (transport == null) return;
|
if (transport == null) return;
|
||||||
_transports.remove(transport.getStyle());
|
Transport old = _transports.remove(transport.getStyle());
|
||||||
|
if (old != null && _log.shouldLog(Log.WARN))
|
||||||
|
_log.warn("Removing transport " + transport.getStyle());
|
||||||
transport.setListener(null);
|
transport.setListener(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -174,7 +229,10 @@ public class TransportManager implements TransportEventListener {
|
|||||||
tp = getTransport(UDPTransport.STYLE);
|
tp = getTransport(UDPTransport.STYLE);
|
||||||
if (tp != null)
|
if (tp != null)
|
||||||
tps.add(tp);
|
tps.add(tp);
|
||||||
//for (Transport t : _transports.values()) {
|
// now add any others (pluggable)
|
||||||
|
for (Transport t : _pluggableTransports.values()) {
|
||||||
|
tps.add(t);
|
||||||
|
}
|
||||||
for (Transport t : tps) {
|
for (Transport t : tps) {
|
||||||
t.startListening();
|
t.startListening();
|
||||||
if (_log.shouldLog(Log.DEBUG))
|
if (_log.shouldLog(Log.DEBUG))
|
||||||
|
Reference in New Issue
Block a user