propagate from branch 'i2p.i2p' (head 1acb4077a56ccb4079538caa28648e27f0bf5b8b)

to branch 'i2p.i2p.zzz.ipv6' (head f87d396c445dc58e677a56d8ed69544c7f5ecab1)
This commit is contained in:
zzz
2013-06-14 14:46:08 +00:00
67 changed files with 3037 additions and 1193 deletions

View File

@ -38,7 +38,7 @@ import net.i2p.util.OrderedProperties;
* @author jrandom
*/
public class RouterAddress extends DataStructureImpl {
private int _cost;
private short _cost;
//private Date _expiration;
private String _transportStyle;
private final Properties _options;
@ -50,16 +50,30 @@ public class RouterAddress extends DataStructureImpl {
public static final String PROP_PORT = "port";
public RouterAddress() {
_cost = -1;
_options = new OrderedProperties();
}
/**
* For efficiency when created by a Transport.
* @param options not copied; do not reuse or modify
* @param cost 0-255
* @since IPv6
*/
public RouterAddress(String style, OrderedProperties options, int cost) {
_transportStyle = style;
_options = options;
if (cost < 0 || cost > 255)
throw new IllegalArgumentException();
_cost = (short) cost;
}
/**
* Retrieve the weighted cost of this address, relative to other methods of
* contacting this router. The value 0 means free and 255 means really expensive.
* No value above 255 is allowed.
*
* Unused before 0.7.12
* @return 0-255
*/
public int getCost() {
return _cost;
@ -67,12 +81,18 @@ public class RouterAddress extends DataStructureImpl {
/**
* Configure the weighted cost of using the address.
* No value above 255 is allowed.
* No value negative or above 255 is allowed.
*
* WARNING - do not change cost on a published address or it will break the RI sig.
* There is no check here.
* Rarely used, use 3-arg constructor.
*
* NTCP is set to 10 and SSU to 5 by default, unused before 0.7.12
*/
public void setCost(int cost) {
_cost = cost;
if (cost < 0 || cost > 255)
throw new IllegalArgumentException();
_cost = (short) cost;
}
/**
@ -113,6 +133,7 @@ public class RouterAddress extends DataStructureImpl {
* Configure the type of transport that must be used to communicate on this address
*
* @throws IllegalStateException if was already set
* @deprecated unused, use 3-arg constructor
*/
public void setTransportStyle(String transportStyle) {
if (_transportStyle != null)
@ -152,6 +173,7 @@ public class RouterAddress extends DataStructureImpl {
* Makes a copy.
* @param options non-null
* @throws IllegalStateException if was already set
* @deprecated unused, use 3-arg constructor
*/
public void setOptions(Properties options) {
if (!_options.isEmpty())
@ -171,7 +193,7 @@ public class RouterAddress extends DataStructureImpl {
if (_ip != null)
return _ip;
byte[] rv = null;
String host = _options.getProperty(PROP_HOST);
String host = getHost();
if (host != null) {
rv = Addresses.getIP(host);
if (rv != null &&
@ -183,6 +205,17 @@ public class RouterAddress extends DataStructureImpl {
return rv;
}
/**
* Convenience, same as getOption("host").
* Does no parsing, so faster than getIP().
*
* @return host string or null
* @since IPv6
*/
public String getHost() {
return _options.getProperty(PROP_HOST);
}
/**
* Caching version of Integer.parseInt(getOption("port"))
* Caches valid ports 1-65535 only.
@ -212,7 +245,7 @@ public class RouterAddress extends DataStructureImpl {
public void readBytes(InputStream in) throws DataFormatException, IOException {
if (_transportStyle != null)
throw new IllegalStateException();
_cost = (int) DataHelper.readLong(in, 1);
_cost = (short) DataHelper.readLong(in, 1);
//_expiration = DataHelper.readDate(in);
DataHelper.readDate(in);
_transportStyle = DataHelper.readString(in);
@ -229,8 +262,8 @@ public class RouterAddress extends DataStructureImpl {
* readin and the signature will fail.
*/
public void writeBytes(OutputStream out) throws DataFormatException, IOException {
if ((_cost < 0) || (_transportStyle == null))
throw new DataFormatException("Not enough data to write a router address");
if (_transportStyle == null)
throw new DataFormatException("uninitialized");
DataHelper.writeLong(out, 1, _cost);
//DataHelper.writeDate(out, _expiration);
DataHelper.writeDate(out, null);
@ -238,28 +271,44 @@ public class RouterAddress extends DataStructureImpl {
DataHelper.writeProperties(out, _options);
}
/**
* Transport, host, and port only.
* Never look at cost or other properties.
*/
@Override
public boolean equals(Object object) {
if (object == this) return true;
if ((object == null) || !(object instanceof RouterAddress)) return false;
RouterAddress addr = (RouterAddress) object;
// let's keep this fast as we are putting an address into the RouterInfo set frequently
return
_cost == addr._cost &&
getPort() == addr.getPort() &&
DataHelper.eq(getHost(), addr.getHost()) &&
DataHelper.eq(_transportStyle, addr._transportStyle);
//DataHelper.eq(_options, addr._options) &&
//DataHelper.eq(_expiration, addr._expiration);
}
/**
* Everything, including Transport, host, port, options, and cost
* @param addr may be null
* @since IPv6
*/
public boolean deepEquals(RouterAddress addr) {
return
equals(addr) &&
_cost == addr._cost &&
_options.equals(addr._options);
}
/**
* Just use a few items for speed (expiration is always null).
* Never look at cost or other properties.
*/
@Override
public int hashCode() {
return DataHelper.hashCode(_transportStyle) ^
DataHelper.hashCode(getIP()) ^
getPort() ^
_cost;
getPort();
}
/**
@ -271,10 +320,10 @@ public class RouterAddress extends DataStructureImpl {
public String toString() {
StringBuilder buf = new StringBuilder(128);
buf.append("[RouterAddress: ");
buf.append("\n\tTransportStyle: ").append(_transportStyle);
buf.append("\n\tType: ").append(_transportStyle);
buf.append("\n\tCost: ").append(_cost);
//buf.append("\n\tExpiration: ").append(_expiration);
buf.append("\n\tOptions: #: ").append(_options.size());
buf.append("\n\tOptions (").append(_options.size()).append("):");
for (Map.Entry e : _options.entrySet()) {
String key = (String) e.getKey();
String val = (String) e.getValue();

View File

@ -61,7 +61,7 @@ public class RouterInfo extends DatabaseEntry {
private final Properties _options;
private volatile boolean _validated;
private volatile boolean _isValid;
private volatile String _stringified;
//private volatile String _stringified;
private volatile byte _byteified[];
private volatile int _hashCode;
private volatile boolean _hashCodeInitialized;
@ -613,30 +613,34 @@ public class RouterInfo extends DatabaseEntry {
@Override
public String toString() {
if (_stringified != null) return _stringified;
StringBuilder buf = new StringBuilder(5*1024);
//if (_stringified != null) return _stringified;
StringBuilder buf = new StringBuilder(1024);
buf.append("[RouterInfo: ");
buf.append("\n\tIdentity: ").append(_identity);
buf.append("\n\tSignature: ").append(_signature);
buf.append("\n\tPublished on: ").append(new Date(_published));
buf.append("\n\tAddresses: #: ").append(_addresses.size());
for (RouterAddress addr : _addresses) {
buf.append("\n\t\tAddress: ").append(addr);
buf.append("\n\tPublished: ").append(new Date(_published));
if (_peers != null) {
buf.append("\n\tPeers (").append(_peers.size()).append("):");
for (Hash hash : _peers) {
buf.append("\n\t\tPeer hash: ").append(hash);
}
}
Set<Hash> peers = getPeers();
buf.append("\n\tPeers: #: ").append(peers.size());
for (Hash hash : peers) {
buf.append("\n\t\tPeer hash: ").append(hash);
}
buf.append("\n\tOptions: #: ").append(_options.size());
buf.append("\n\tOptions (").append(_options.size()).append("):");
for (Map.Entry e : _options.entrySet()) {
String key = (String) e.getKey();
String val = (String) e.getValue();
buf.append("\n\t\t[").append(key).append("] = [").append(val).append("]");
}
if (!_addresses.isEmpty()) {
buf.append("\n\tAddresses (").append(_addresses.size()).append("):");
for (RouterAddress addr : _addresses) {
buf.append("\n\t").append(addr);
}
}
buf.append("]");
_stringified = buf.toString();
return _stringified;
String rv = buf.toString();
//_stringified = rv;
return rv;
}
/**

View File

@ -34,7 +34,7 @@ public abstract class Addresses {
return !getAddresses(true, false, false).isEmpty();
}
/** @return the first non-local address it finds, or null */
/** @return the first non-local address IPv4 address it finds, or null */
public static String getAnyAddress() {
SortedSet<String> a = getAddresses();
if (!a.isEmpty())
@ -95,7 +95,7 @@ public abstract class Addresses {
haveIPv6 = true;
if (shouldInclude(allMyIps[i], includeSiteLocal,
includeLoopbackAndWildcard, includeIPv6))
rv.add(allMyIps[i].getHostAddress());
rv.add(stripScope(allMyIps[i].getHostAddress()));
}
}
} catch (UnknownHostException e) {}
@ -113,7 +113,7 @@ public abstract class Addresses {
haveIPv6 = true;
if (shouldInclude(addr, includeSiteLocal,
includeLoopbackAndWildcard, includeIPv6))
rv.add(addr.getHostAddress());
rv.add(stripScope(addr.getHostAddress()));
}
}
}
@ -128,6 +128,17 @@ public abstract class Addresses {
return rv;
}
/**
* Strip the trailing "%nn" from Inet6Address.getHostAddress()
* @since IPv6
*/
private static String stripScope(String ip) {
int pct = ip.indexOf("%");
if (pct > 0)
ip = ip.substring(0, pct);
return ip;
}
private static boolean shouldInclude(InetAddress ia, boolean includeSiteLocal,
boolean includeLoopbackAndWildcard, boolean includeIPv6) {
return