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 net.i2p.data.Hash;
|
||||
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,
|
||||
@ -85,6 +87,24 @@ public abstract class CommSystemFacade implements Service {
|
||||
*/
|
||||
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),
|
||||
* but UNKNOWN must be last.
|
||||
|
@ -22,6 +22,7 @@ import net.i2p.data.router.RouterInfo;
|
||||
import net.i2p.router.CommSystemFacade;
|
||||
import net.i2p.router.OutNetMessage;
|
||||
import net.i2p.router.RouterContext;
|
||||
import net.i2p.router.transport.crypto.DHSessionKeyBuilder;
|
||||
import net.i2p.router.transport.udp.UDPTransport;
|
||||
import net.i2p.router.util.EventLog;
|
||||
import net.i2p.util.Addresses;
|
||||
@ -223,6 +224,47 @@ public class CommSystemFacadeImpl extends CommSystemFacade {
|
||||
_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
|
||||
*
|
||||
|
@ -13,6 +13,7 @@ import java.io.Writer;
|
||||
import java.net.InetAddress;
|
||||
import java.net.UnknownHostException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
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.
|
||||
*/
|
||||
private final Map<String, Transport> _transports;
|
||||
/** locking: this */
|
||||
private final Map<String, Transport> _pluggableTransports;
|
||||
private final RouterContext _context;
|
||||
private final UPnPManager _upnpManager;
|
||||
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.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);
|
||||
_pluggableTransports = new HashMap<String, Transport>(2);
|
||||
if (_context.getBooleanPropertyDefaultTrue(PROP_ENABLE_UPNP))
|
||||
_upnpManager = new UPnPManager(context, this);
|
||||
else
|
||||
@ -73,15 +77,66 @@ public class TransportManager implements TransportEventListener {
|
||||
_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;
|
||||
_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);
|
||||
}
|
||||
|
||||
public void removeTransport(Transport transport) {
|
||||
private void removeTransport(Transport transport) {
|
||||
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);
|
||||
}
|
||||
|
||||
@ -174,7 +229,10 @@ public class TransportManager implements TransportEventListener {
|
||||
tp = getTransport(UDPTransport.STYLE);
|
||||
if (tp != null)
|
||||
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) {
|
||||
t.startListening();
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
|
Reference in New Issue
Block a user