forked from I2P_Developers/i2p.i2p
Start new IPv6 branch
- Add new TransportUtil for getting/setting IPv6 config - Prep for supporting multiple RouterAddresses per-transport - RouterAddress hashCode/equals tweaks
This commit is contained in:
@@ -238,14 +238,18 @@ public class RouterAddress extends DataStructureImpl {
|
|||||||
DataHelper.writeProperties(out, _options);
|
DataHelper.writeProperties(out, _options);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Transport, IP, and port only.
|
||||||
|
* Never look at cost or other properties.
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object object) {
|
public boolean equals(Object object) {
|
||||||
if (object == this) return true;
|
if (object == this) return true;
|
||||||
if ((object == null) || !(object instanceof RouterAddress)) return false;
|
if ((object == null) || !(object instanceof RouterAddress)) return false;
|
||||||
RouterAddress addr = (RouterAddress) object;
|
RouterAddress addr = (RouterAddress) object;
|
||||||
// let's keep this fast as we are putting an address into the RouterInfo set frequently
|
|
||||||
return
|
return
|
||||||
_cost == addr._cost &&
|
getPort() == addr.getPort() &&
|
||||||
|
DataHelper.eq(getIP(), addr.getIP()) &&
|
||||||
DataHelper.eq(_transportStyle, addr._transportStyle);
|
DataHelper.eq(_transportStyle, addr._transportStyle);
|
||||||
//DataHelper.eq(_options, addr._options) &&
|
//DataHelper.eq(_options, addr._options) &&
|
||||||
//DataHelper.eq(_expiration, addr._expiration);
|
//DataHelper.eq(_expiration, addr._expiration);
|
||||||
@@ -253,13 +257,13 @@ public class RouterAddress extends DataStructureImpl {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Just use a few items for speed (expiration is always null).
|
* Just use a few items for speed (expiration is always null).
|
||||||
|
* Never look at cost or other properties.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
return DataHelper.hashCode(_transportStyle) ^
|
return DataHelper.hashCode(_transportStyle) ^
|
||||||
DataHelper.hashCode(getIP()) ^
|
DataHelper.hashCode(getIP()) ^
|
||||||
getPort() ^
|
getPort();
|
||||||
_cost;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -28,8 +28,8 @@ public abstract class CommSystemFacade implements Service {
|
|||||||
public void renderStatusHTML(Writer out, String urlBase, int sortFlags) throws IOException { }
|
public void renderStatusHTML(Writer out, String urlBase, int sortFlags) throws IOException { }
|
||||||
public void renderStatusHTML(Writer out) throws IOException { renderStatusHTML(out, null, 0); }
|
public void renderStatusHTML(Writer out) throws IOException { renderStatusHTML(out, null, 0); }
|
||||||
|
|
||||||
/** Create the set of RouterAddress structures based on the router's config */
|
/** Create the list of RouterAddress structures based on the router's config */
|
||||||
public Set<RouterAddress> createAddresses() { return Collections.EMPTY_SET; }
|
public List<RouterAddress> createAddresses() { return Collections.EMPTY_LIST; }
|
||||||
|
|
||||||
public int countActivePeers() { return 0; }
|
public int countActivePeers() { return 0; }
|
||||||
public int countActiveSendPeers() { return 0; }
|
public int countActiveSendPeers() { return 0; }
|
||||||
|
@@ -10,15 +10,14 @@ package net.i2p.router.transport;
|
|||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.Writer;
|
import java.io.Writer;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
import java.util.Set;
|
|
||||||
import java.util.Vector;
|
import java.util.Vector;
|
||||||
|
|
||||||
import net.i2p.data.Hash;
|
import net.i2p.data.Hash;
|
||||||
@@ -167,7 +166,7 @@ public class CommSystemFacadeImpl extends CommSystemFacade {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List getMostRecentErrorMessages() {
|
public List<String> getMostRecentErrorMessages() {
|
||||||
return _manager.getMostRecentErrorMessages();
|
return _manager.getMostRecentErrorMessages();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -190,26 +189,29 @@ public class CommSystemFacadeImpl extends CommSystemFacade {
|
|||||||
|
|
||||||
/** @return non-null, possibly empty */
|
/** @return non-null, possibly empty */
|
||||||
@Override
|
@Override
|
||||||
public Set<RouterAddress> createAddresses() {
|
public List<RouterAddress> createAddresses() {
|
||||||
// No, don't do this, it makes it almost impossible to build inbound tunnels
|
// No, don't do this, it makes it almost impossible to build inbound tunnels
|
||||||
//if (_context.router().isHidden())
|
//if (_context.router().isHidden())
|
||||||
// return Collections.EMPTY_SET;
|
// return Collections.EMPTY_SET;
|
||||||
Map<String, RouterAddress> addresses = _manager.getAddresses();
|
List<RouterAddress> addresses = new ArrayList(_manager.getAddresses());
|
||||||
|
|
||||||
|
Transport ntcp = _manager.getTransport(NTCPTransport.STYLE);
|
||||||
|
boolean hasNTCP = ntcp != null && ntcp.hasCurrentAddress();
|
||||||
|
|
||||||
boolean newCreated = false;
|
boolean newCreated = false;
|
||||||
|
if (!hasNTCP) {
|
||||||
if (!addresses.containsKey(NTCPTransport.STYLE)) {
|
|
||||||
RouterAddress addr = createNTCPAddress(_context);
|
RouterAddress addr = createNTCPAddress(_context);
|
||||||
if (_log.shouldLog(Log.INFO))
|
if (_log.shouldLog(Log.INFO))
|
||||||
_log.info("NTCP address: " + addr);
|
_log.info("NTCP address: " + addr);
|
||||||
if (addr != null) {
|
if (addr != null) {
|
||||||
addresses.put(NTCPTransport.STYLE, addr);
|
addresses.add(addr);
|
||||||
newCreated = true;
|
newCreated = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_log.shouldLog(Log.INFO))
|
if (_log.shouldLog(Log.INFO))
|
||||||
_log.info("Creating addresses: " + addresses + " isNew? " + newCreated, new Exception("creator"));
|
_log.info("Creating addresses: " + addresses + " isNew? " + newCreated, new Exception("creator"));
|
||||||
return new HashSet(addresses.values());
|
return addresses;
|
||||||
}
|
}
|
||||||
|
|
||||||
public final static String PROP_I2NP_NTCP_HOSTNAME = "i2np.ntcp.hostname";
|
public final static String PROP_I2NP_NTCP_HOSTNAME = "i2np.ntcp.hostname";
|
||||||
@@ -278,9 +280,20 @@ public class CommSystemFacadeImpl extends CommSystemFacade {
|
|||||||
NTCPTransport t = (NTCPTransport) _manager.getTransport(NTCPTransport.STYLE);
|
NTCPTransport t = (NTCPTransport) _manager.getTransport(NTCPTransport.STYLE);
|
||||||
if (t == null)
|
if (t == null)
|
||||||
return;
|
return;
|
||||||
RouterAddress oldAddr = t.getCurrentAddress();
|
|
||||||
|
//////// FIXME just take first IPv4 address for now
|
||||||
|
List<RouterAddress> oldAddrs = t.getCurrentAddresses();
|
||||||
|
RouterAddress oldAddr = null;
|
||||||
|
for (RouterAddress ra : oldAddrs) {
|
||||||
|
byte[] ipx = ra.getIP();
|
||||||
|
if (ipx != null && ipx.length == 4) {
|
||||||
|
oldAddr = ra;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
if (_log.shouldLog(Log.INFO))
|
if (_log.shouldLog(Log.INFO))
|
||||||
_log.info("Changing NTCP Address? was " + oldAddr);
|
_log.info("Changing NTCP Address? was " + oldAddr);
|
||||||
|
|
||||||
RouterAddress newAddr = new RouterAddress();
|
RouterAddress newAddr = new RouterAddress();
|
||||||
newAddr.setTransportStyle(NTCPTransport.STYLE);
|
newAddr.setTransportStyle(NTCPTransport.STYLE);
|
||||||
Properties newProps = new Properties();
|
Properties newProps = new Properties();
|
||||||
|
@@ -32,10 +32,29 @@ public interface Transport {
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public void send(OutNetMessage msg);
|
public void send(OutNetMessage msg);
|
||||||
public RouterAddress startListening();
|
public void startListening();
|
||||||
public void stopListening();
|
public void stopListening();
|
||||||
public RouterAddress getCurrentAddress();
|
|
||||||
public RouterAddress updateAddress();
|
/**
|
||||||
|
* What addresses are we currently listening to?
|
||||||
|
* Replaces getCurrentAddress()
|
||||||
|
* @return all addresses, non-null
|
||||||
|
* @since IPv6
|
||||||
|
*/
|
||||||
|
public List<RouterAddress> getCurrentAddresses();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Do we have any current address?
|
||||||
|
* @since IPv6
|
||||||
|
*/
|
||||||
|
public boolean hasCurrentAddress();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ask the transport to update its addresses based on current information and return them
|
||||||
|
* @return all addresses, non-null
|
||||||
|
*/
|
||||||
|
public List<RouterAddress> updateAddress();
|
||||||
|
|
||||||
public static final String SOURCE_UPNP = "upnp";
|
public static final String SOURCE_UPNP = "upnp";
|
||||||
public static final String SOURCE_INTERFACE = "local";
|
public static final String SOURCE_INTERFACE = "local";
|
||||||
public static final String SOURCE_CONFIG = "config"; // unused
|
public static final String SOURCE_CONFIG = "config"; // unused
|
||||||
@@ -51,7 +70,7 @@ public interface Transport {
|
|||||||
public boolean haveCapacity();
|
public boolean haveCapacity();
|
||||||
public boolean haveCapacity(int pct);
|
public boolean haveCapacity(int pct);
|
||||||
public Vector getClockSkews();
|
public Vector getClockSkews();
|
||||||
public List getMostRecentErrorMessages();
|
public List<String> getMostRecentErrorMessages();
|
||||||
|
|
||||||
public void renderStatusHTML(Writer out, String urlBase, int sortFlags) throws IOException;
|
public void renderStatusHTML(Writer out, String urlBase, int sortFlags) throws IOException;
|
||||||
public short getReachabilityStatus();
|
public short getReachabilityStatus();
|
||||||
|
@@ -10,7 +10,6 @@ package net.i2p.router.transport;
|
|||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.Writer;
|
import java.io.Writer;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
@@ -23,6 +22,7 @@ import java.util.Vector;
|
|||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.concurrent.ArrayBlockingQueue;
|
import java.util.concurrent.ArrayBlockingQueue;
|
||||||
import java.util.concurrent.BlockingQueue;
|
import java.util.concurrent.BlockingQueue;
|
||||||
|
import java.util.concurrent.CopyOnWriteArrayList;
|
||||||
|
|
||||||
import net.i2p.data.DataHelper;
|
import net.i2p.data.DataHelper;
|
||||||
import net.i2p.data.Hash;
|
import net.i2p.data.Hash;
|
||||||
@@ -50,7 +50,7 @@ import net.i2p.util.SimpleTimer;
|
|||||||
public abstract class TransportImpl implements Transport {
|
public abstract class TransportImpl implements Transport {
|
||||||
private final Log _log;
|
private final Log _log;
|
||||||
private TransportEventListener _listener;
|
private TransportEventListener _listener;
|
||||||
private RouterAddress _currentAddress;
|
protected final List<RouterAddress> _currentAddresses;
|
||||||
// Only used by NTCP. SSU does not use. See send() below.
|
// Only used by NTCP. SSU does not use. See send() below.
|
||||||
private final BlockingQueue<OutNetMessage> _sendPool;
|
private final BlockingQueue<OutNetMessage> _sendPool;
|
||||||
protected final RouterContext _context;
|
protected final RouterContext _context;
|
||||||
@@ -87,6 +87,8 @@ public abstract class TransportImpl implements Transport {
|
|||||||
_context.statManager().createRequiredRateStat("transport.sendProcessingTime", "Time to process and send a message (ms)", "Transport", new long[] { 60*1000l, 10*60*1000l, 60*60*1000l, 24*60*60*1000l });
|
_context.statManager().createRequiredRateStat("transport.sendProcessingTime", "Time to process and send a message (ms)", "Transport", new long[] { 60*1000l, 10*60*1000l, 60*60*1000l, 24*60*60*1000l });
|
||||||
//_context.statManager().createRateStat("transport.sendProcessingTime." + getStyle(), "Time to process and send a message (ms)", "Transport", new long[] { 60*1000l });
|
//_context.statManager().createRateStat("transport.sendProcessingTime." + getStyle(), "Time to process and send a message (ms)", "Transport", new long[] { 60*1000l });
|
||||||
_context.statManager().createRateStat("transport.expiredOnQueueLifetime", "How long a message that expires on our outbound queue is processed", "Transport", new long[] { 60*1000l, 10*60*1000l, 60*60*1000l, 24*60*60*1000l } );
|
_context.statManager().createRateStat("transport.expiredOnQueueLifetime", "How long a message that expires on our outbound queue is processed", "Transport", new long[] { 60*1000l, 10*60*1000l, 60*60*1000l, 24*60*60*1000l } );
|
||||||
|
|
||||||
|
_currentAddresses = new CopyOnWriteArrayList();
|
||||||
if (getStyle().equals("NTCP"))
|
if (getStyle().equals("NTCP"))
|
||||||
_sendPool = new ArrayBlockingQueue(8);
|
_sendPool = new ArrayBlockingQueue(8);
|
||||||
else
|
else
|
||||||
@@ -166,7 +168,7 @@ public abstract class TransportImpl implements Transport {
|
|||||||
*/
|
*/
|
||||||
public Vector getClockSkews() { return new Vector(); }
|
public Vector getClockSkews() { return new Vector(); }
|
||||||
|
|
||||||
public List getMostRecentErrorMessages() { return Collections.EMPTY_LIST; }
|
public List<String> getMostRecentErrorMessages() { return Collections.EMPTY_LIST; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Nonblocking call to pull the next outbound message
|
* Nonblocking call to pull the next outbound message
|
||||||
@@ -464,27 +466,61 @@ public abstract class TransportImpl implements Transport {
|
|||||||
/** Do we increase the advertised cost when approaching conn limits? */
|
/** Do we increase the advertised cost when approaching conn limits? */
|
||||||
public static final boolean ADJUST_COST = true;
|
public static final boolean ADJUST_COST = true;
|
||||||
|
|
||||||
/** What addresses are we currently listening to? */
|
/**
|
||||||
public RouterAddress getCurrentAddress() {
|
* What addresses are we currently listening to?
|
||||||
return _currentAddress;
|
* Replaces getCurrentAddress()
|
||||||
|
* @return all addresses, non-null
|
||||||
|
* @since IPv6
|
||||||
|
*/
|
||||||
|
public List<RouterAddress> getCurrentAddresses() {
|
||||||
|
return _currentAddresses;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Do we have any current address?
|
||||||
|
* @since IPv6
|
||||||
|
*/
|
||||||
|
public boolean hasCurrentAddress() {
|
||||||
|
return !_currentAddresses.isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Ask the transport to update its address based on current information and return it
|
* Ask the transport to update its address based on current information and return it
|
||||||
* Transports should override.
|
* Transports should override.
|
||||||
|
* @return all addresses, non-null
|
||||||
* @since 0.7.12
|
* @since 0.7.12
|
||||||
*/
|
*/
|
||||||
public RouterAddress updateAddress() {
|
public List<RouterAddress> updateAddress() {
|
||||||
return _currentAddress;
|
return _currentAddresses;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Replace any existing addresses for the current transport with the given
|
* Replace any existing addresses for the current transport
|
||||||
* one.
|
* with the same IP length (4 or 16) with the given one.
|
||||||
|
* TODO: Allow multiple addresses of the same length.
|
||||||
|
* Calls listener.transportAddressChanged()
|
||||||
|
*
|
||||||
|
* @param address null to remove all
|
||||||
*/
|
*/
|
||||||
protected void replaceAddress(RouterAddress address) {
|
protected void replaceAddress(RouterAddress address) {
|
||||||
// _log.error("Replacing address for " + getStyle() + " was " + _currentAddress + " now " + address);
|
if (_log.shouldLog(Log.WARN))
|
||||||
_currentAddress = address;
|
_log.warn("Replacing address with " + address);
|
||||||
|
if (address == null) {
|
||||||
|
_currentAddresses.clear();
|
||||||
|
} else {
|
||||||
|
byte[] ip = address.getIP();
|
||||||
|
if (ip == null) {
|
||||||
|
_log.error("WTF null ip for " + address);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
int len = ip.length;
|
||||||
|
for (RouterAddress ra : _currentAddresses) {
|
||||||
|
byte[] ipx = ra.getIP();
|
||||||
|
if (ipx != null && ipx.length == len)
|
||||||
|
_currentAddresses.remove(ra);
|
||||||
|
}
|
||||||
|
_currentAddresses.add(address);
|
||||||
|
}
|
||||||
if (_listener != null)
|
if (_listener != null)
|
||||||
_listener.transportAddressChanged();
|
_listener.transportAddressChanged();
|
||||||
}
|
}
|
||||||
|
@@ -14,6 +14,7 @@ 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.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@@ -248,7 +249,7 @@ public class TransportManager implements TransportEventListener {
|
|||||||
*/
|
*/
|
||||||
public boolean haveInboundCapacity(int pct) {
|
public boolean haveInboundCapacity(int pct) {
|
||||||
for (Transport t : _transports.values()) {
|
for (Transport t : _transports.values()) {
|
||||||
if (t.getCurrentAddress() != null && t.haveCapacity(pct))
|
if (t.hasCurrentAddress() && t.haveCapacity(pct))
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@@ -332,43 +333,67 @@ public class TransportManager implements TransportEventListener {
|
|||||||
/**
|
/**
|
||||||
* This forces a rebuild
|
* This forces a rebuild
|
||||||
*/
|
*/
|
||||||
public Map<String, RouterAddress> getAddresses() {
|
public List<RouterAddress> getAddresses() {
|
||||||
Map<String, RouterAddress> rv = new HashMap(_transports.size());
|
List<RouterAddress> rv = new ArrayList(4);
|
||||||
// do this first since SSU may force a NTCP change
|
// do this first since SSU may force a NTCP change
|
||||||
for (Transport t : _transports.values())
|
for (Transport t : _transports.values())
|
||||||
t.updateAddress();
|
t.updateAddress();
|
||||||
for (Transport t : _transports.values()) {
|
for (Transport t : _transports.values()) {
|
||||||
if (t.getCurrentAddress() != null)
|
rv.addAll(t.getCurrentAddresses());
|
||||||
rv.put(t.getStyle(), t.getCurrentAddress());
|
|
||||||
}
|
}
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @since IPv6
|
||||||
|
*/
|
||||||
|
static class Port {
|
||||||
|
public final String style;
|
||||||
|
public final int port;
|
||||||
|
|
||||||
|
public Port(String style, int port) {
|
||||||
|
this.style = style;
|
||||||
|
this.port = port;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return style.hashCode() ^ port;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (o == null)
|
||||||
|
return false;
|
||||||
|
if (! (o instanceof Port))
|
||||||
|
return false;
|
||||||
|
Port p = (Port) o;
|
||||||
|
return port == p.port && style.equals(p.style);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Include the published port, or the requested port, for each transport
|
* Include the published port, or the requested port, for each transport
|
||||||
* which we will pass along to UPnP
|
* which we will pass along to UPnP
|
||||||
*/
|
*/
|
||||||
private Map<String, Integer> getPorts() {
|
private Set<Port> getPorts() {
|
||||||
Map<String, Integer> rv = new HashMap(_transports.size());
|
Set<Port> rv = new HashSet(4);
|
||||||
for (Transport t : _transports.values()) {
|
for (Transport t : _transports.values()) {
|
||||||
int port = t.getRequestedPort();
|
int port = t.getRequestedPort();
|
||||||
if (t.getCurrentAddress() != null) {
|
for (RouterAddress ra : t.getCurrentAddresses()) {
|
||||||
String s = t.getCurrentAddress().getOption("port");
|
int p = ra.getPort();
|
||||||
if (s != null) {
|
if (p > 0)
|
||||||
try {
|
port = p;
|
||||||
port = Integer.parseInt(s);
|
// Use UDP port for NTCP too - see comment in NTCPTransport.getRequestedPort() for why this is here
|
||||||
} catch (NumberFormatException nfe) {}
|
if (t.getStyle().equals(NTCPTransport.STYLE) && port <= 0 &&
|
||||||
}
|
_context.getBooleanProperty(CommSystemFacadeImpl.PROP_I2NP_NTCP_AUTO_PORT)) {
|
||||||
|
Transport udp = getTransport(UDPTransport.STYLE);
|
||||||
|
if (udp != null)
|
||||||
|
port = t.getRequestedPort();
|
||||||
|
}
|
||||||
|
if (port > 0)
|
||||||
|
rv.add(new Port(t.getStyle(), port));
|
||||||
}
|
}
|
||||||
// Use UDP port for NTCP too - see comment in NTCPTransport.getRequestedPort() for why this is here
|
|
||||||
if (t.getStyle().equals(NTCPTransport.STYLE) && port <= 0 &&
|
|
||||||
_context.getBooleanProperty(CommSystemFacadeImpl.PROP_I2NP_NTCP_AUTO_PORT)) {
|
|
||||||
Transport udp = getTransport(UDPTransport.STYLE);
|
|
||||||
if (udp != null)
|
|
||||||
port = t.getRequestedPort();
|
|
||||||
}
|
|
||||||
if (port > 0)
|
|
||||||
rv.put(t.getStyle(), Integer.valueOf(port));
|
|
||||||
}
|
}
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
@@ -485,8 +510,8 @@ public class TransportManager implements TransportEventListener {
|
|||||||
_upnpManager.update(getPorts());
|
_upnpManager.update(getPorts());
|
||||||
}
|
}
|
||||||
|
|
||||||
public List getMostRecentErrorMessages() {
|
public List<String> getMostRecentErrorMessages() {
|
||||||
List rv = new ArrayList(16);
|
List<String> rv = new ArrayList(16);
|
||||||
for (Transport t : _transports.values()) {
|
for (Transport t : _transports.values()) {
|
||||||
rv.addAll(t.getMostRecentErrorMessages());
|
rv.addAll(t.getMostRecentErrorMessages());
|
||||||
}
|
}
|
||||||
@@ -510,11 +535,15 @@ public class TransportManager implements TransportEventListener {
|
|||||||
StringBuilder buf = new StringBuilder(4*1024);
|
StringBuilder buf = new StringBuilder(4*1024);
|
||||||
buf.append("<h3>").append(_("Router Transport Addresses")).append("</h3><pre>\n");
|
buf.append("<h3>").append(_("Router Transport Addresses")).append("</h3><pre>\n");
|
||||||
for (Transport t : _transports.values()) {
|
for (Transport t : _transports.values()) {
|
||||||
if (t.getCurrentAddress() != null)
|
if (t.hasCurrentAddress()) {
|
||||||
buf.append(t.getCurrentAddress());
|
for (RouterAddress ra : t.getCurrentAddresses()) {
|
||||||
else
|
buf.append(ra.toString());
|
||||||
|
buf.append("\n\n");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
buf.append(_("{0} is used for outbound connections only", t.getStyle()));
|
buf.append(_("{0} is used for outbound connections only", t.getStyle()));
|
||||||
buf.append("\n\n");
|
buf.append("\n\n");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
buf.append("</pre>\n");
|
buf.append("</pre>\n");
|
||||||
out.write(buf.toString());
|
out.write(buf.toString());
|
||||||
|
78
router/java/src/net/i2p/router/transport/TransportUtil.java
Normal file
78
router/java/src/net/i2p/router/transport/TransportUtil.java
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
package net.i2p.router.transport;
|
||||||
|
/*
|
||||||
|
* free (adj.): unencumbered; not under the control of others
|
||||||
|
* Written by jrandom in 2003 and released into the public domain
|
||||||
|
* with no warranty of any kind { either expressed or implied.
|
||||||
|
* It probably won't make your computer catch on fire { or eat
|
||||||
|
* your children { but it might. Use at your own risk.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import net.i2p.router.RouterContext;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @since IPv6
|
||||||
|
*/
|
||||||
|
public abstract class TransportUtil {
|
||||||
|
|
||||||
|
public static final String NTCP_IPV6_CONFIG = "i2np.ntcp.ipv6";
|
||||||
|
public static final String SSU_IPV6_CONFIG = "i2np.udp.ipv6";
|
||||||
|
|
||||||
|
public enum IPv6Config {
|
||||||
|
/** IPv6 disabled */
|
||||||
|
IPV6_DISABLED("false"),
|
||||||
|
|
||||||
|
/** lower priority than IPv4 */
|
||||||
|
IPV6_NOT_PREFERRED("preferIPv4"),
|
||||||
|
|
||||||
|
/** equal priority to IPv4 */
|
||||||
|
IPV6_ENABLED("enable"),
|
||||||
|
|
||||||
|
/** higher priority than IPv4 */
|
||||||
|
IPV6_PREFERRED("preferIPv6"),
|
||||||
|
|
||||||
|
/** IPv4 disabled */
|
||||||
|
IPV6_ONLY("only");
|
||||||
|
|
||||||
|
private final String cfgstr;
|
||||||
|
|
||||||
|
IPv6Config(String cfgstr) {
|
||||||
|
this.cfgstr = cfgstr;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toConfigString() {
|
||||||
|
return cfgstr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final Map<String, IPv6Config> BY_NAME = new HashMap<String, IPv6Config>();
|
||||||
|
|
||||||
|
static {
|
||||||
|
for (IPv6Config cfg : IPv6Config.values()) {
|
||||||
|
BY_NAME.put(cfg.toConfigString(), cfg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IPv6Config getIPv6Config(RouterContext ctx, String transportStyle) {
|
||||||
|
String cfg;
|
||||||
|
if (transportStyle.equals("NTCP"))
|
||||||
|
cfg = ctx.getProperty(NTCP_IPV6_CONFIG);
|
||||||
|
else if (transportStyle.equals("SSU"))
|
||||||
|
cfg = ctx.getProperty(SSU_IPV6_CONFIG);
|
||||||
|
else
|
||||||
|
return IPv6Config.IPV6_DISABLED;
|
||||||
|
return getIPv6Config(cfg);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IPv6Config getIPv6Config(String cfg) {
|
||||||
|
if (cfg == null)
|
||||||
|
return IPv6Config.IPV6_DISABLED;
|
||||||
|
IPv6Config c = BY_NAME.get(cfg);
|
||||||
|
if (c != null)
|
||||||
|
return c;
|
||||||
|
return IPv6Config.IPV6_DISABLED;
|
||||||
|
}
|
||||||
|
}
|
@@ -52,6 +52,7 @@ import org.freenetproject.ForwardPortStatus;
|
|||||||
*
|
*
|
||||||
* @see "http://www.upnp.org/"
|
* @see "http://www.upnp.org/"
|
||||||
* @see "http://en.wikipedia.org/wiki/Universal_Plug_and_Play"
|
* @see "http://en.wikipedia.org/wiki/Universal_Plug_and_Play"
|
||||||
|
* @since 0.7.4
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@@ -25,6 +25,7 @@ import org.freenetproject.ForwardPortStatus;
|
|||||||
* Bridge from the I2P RouterAddress data structure to
|
* Bridge from the I2P RouterAddress data structure to
|
||||||
* the freenet data structures
|
* the freenet data structures
|
||||||
*
|
*
|
||||||
|
* @since 0.7.4
|
||||||
* @author zzz
|
* @author zzz
|
||||||
*/
|
*/
|
||||||
class UPnPManager {
|
class UPnPManager {
|
||||||
@@ -106,7 +107,7 @@ class UPnPManager {
|
|||||||
* which can have multiple UPnP threads running at once, but
|
* which can have multiple UPnP threads running at once, but
|
||||||
* that should be ok.
|
* that should be ok.
|
||||||
*/
|
*/
|
||||||
public void update(Map<String, Integer> ports) {
|
public void update(Set<TransportManager.Port> ports) {
|
||||||
if (_log.shouldLog(Log.DEBUG))
|
if (_log.shouldLog(Log.DEBUG))
|
||||||
_log.debug("UPnP Update with " + ports.size() + " ports");
|
_log.debug("UPnP Update with " + ports.size() + " ports");
|
||||||
|
|
||||||
@@ -121,9 +122,9 @@ class UPnPManager {
|
|||||||
//}
|
//}
|
||||||
|
|
||||||
Set<ForwardPort> forwards = new HashSet(ports.size());
|
Set<ForwardPort> forwards = new HashSet(ports.size());
|
||||||
for (Map.Entry<String, Integer> entry : ports.entrySet()) {
|
for (TransportManager.Port entry : ports) {
|
||||||
String style = entry.getKey();
|
String style = entry.style;
|
||||||
int port = entry.getValue().intValue();
|
int port = entry.port;
|
||||||
int protocol = -1;
|
int protocol = -1;
|
||||||
if ("SSU".equals(style))
|
if ("SSU".equals(style))
|
||||||
protocol = ForwardPort.PROTOCOL_UDP_IPV4;
|
protocol = ForwardPort.PROTOCOL_UDP_IPV4;
|
||||||
|
@@ -458,30 +458,28 @@ public class NTCPTransport extends TransportImpl {
|
|||||||
* verify stopped with isAlive()
|
* verify stopped with isAlive()
|
||||||
* Unfortunately TransportManager doesn't do that, so we
|
* Unfortunately TransportManager doesn't do that, so we
|
||||||
* check here to prevent two pumpers.
|
* check here to prevent two pumpers.
|
||||||
* @return appears to be ignored by caller
|
|
||||||
*/
|
*/
|
||||||
public synchronized RouterAddress startListening() {
|
public synchronized void startListening() {
|
||||||
// try once again to prevent two pumpers which is fatal
|
// try once again to prevent two pumpers which is fatal
|
||||||
if (_pumper.isAlive())
|
if (_pumper.isAlive())
|
||||||
return _myAddress != null ? _myAddress.toRouterAddress() : null;
|
return;
|
||||||
if (_log.shouldLog(Log.WARN)) _log.warn("Starting ntcp transport listening");
|
if (_log.shouldLog(Log.WARN)) _log.warn("Starting ntcp transport listening");
|
||||||
|
|
||||||
startIt();
|
startIt();
|
||||||
configureLocalAddress();
|
configureLocalAddress();
|
||||||
return bindAddress();
|
bindAddress();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Only called by CSFI.
|
* Only called by CSFI.
|
||||||
* Caller should stop the transport first, then
|
* Caller should stop the transport first, then
|
||||||
* verify stopped with isAlive()
|
* verify stopped with isAlive()
|
||||||
* @return appears to be ignored by caller
|
|
||||||
*/
|
*/
|
||||||
public synchronized RouterAddress restartListening(RouterAddress addr) {
|
public synchronized void restartListening(RouterAddress addr) {
|
||||||
// try once again to prevent two pumpers which is fatal
|
// try once again to prevent two pumpers which is fatal
|
||||||
// we could just return null since the return value is ignored
|
// we could just return null since the return value is ignored
|
||||||
if (_pumper.isAlive())
|
if (_pumper.isAlive())
|
||||||
return _myAddress != null ? _myAddress.toRouterAddress() : null;
|
return;
|
||||||
if (_log.shouldLog(Log.WARN)) _log.warn("Restarting ntcp transport listening");
|
if (_log.shouldLog(Log.WARN)) _log.warn("Restarting ntcp transport listening");
|
||||||
|
|
||||||
startIt();
|
startIt();
|
||||||
@@ -489,7 +487,7 @@ public class NTCPTransport extends TransportImpl {
|
|||||||
_myAddress = null;
|
_myAddress = null;
|
||||||
else
|
else
|
||||||
_myAddress = new NTCPAddress(addr);
|
_myAddress = new NTCPAddress(addr);
|
||||||
return bindAddress();
|
bindAddress();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -1446,9 +1446,8 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority
|
|||||||
// we don't need the following, since we have our own queueing
|
// we don't need the following, since we have our own queueing
|
||||||
protected void outboundMessageReady() { throw new UnsupportedOperationException("Not used for UDP"); }
|
protected void outboundMessageReady() { throw new UnsupportedOperationException("Not used for UDP"); }
|
||||||
|
|
||||||
public RouterAddress startListening() {
|
public void startListening() {
|
||||||
startup();
|
startup();
|
||||||
return _externalAddress;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void stopListening() {
|
public void stopListening() {
|
||||||
@@ -1470,9 +1469,9 @@ public class UDPTransport extends TransportImpl implements TimedWeightedPriority
|
|||||||
* @since 0.7.12
|
* @since 0.7.12
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public RouterAddress updateAddress() {
|
public List<RouterAddress> updateAddress() {
|
||||||
rebuildExternalAddress(false);
|
rebuildExternalAddress(false);
|
||||||
return getCurrentAddress();
|
return getCurrentAddresses();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void rebuildExternalAddress() { rebuildExternalAddress(true); }
|
private void rebuildExternalAddress() { rebuildExternalAddress(true); }
|
||||||
|
Reference in New Issue
Block a user