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

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

Transport: Hooks for pluggable transports (ticket #1170)

parent 1053bc8b
No related branches found
No related tags found
No related merge requests found
...@@ -14,6 +14,8 @@ import java.util.Collections; ...@@ -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 { ...@@ -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; ...@@ -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;
...@@ -222,6 +223,47 @@ public class CommSystemFacadeImpl extends CommSystemFacade { ...@@ -222,6 +223,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; ...@@ -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 { ...@@ -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,22 +69,74 @@ public class TransportManager implements TransportEventListener { ...@@ -66,22 +69,74 @@ 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
_upnpManager = null; _upnpManager = null;
_dhThread = new DHSessionKeyBuilder.PrecalcRunner(context); _dhThread = new DHSessionKeyBuilder.PrecalcRunner(context);
} }
/**
* 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;
}
public void addTransport(Transport transport) { 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 { ...@@ -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))
......
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