use of net.i2p.data.router.RouterAddress in project i2p.i2p by i2p.
the class NTCPTransport method createNTCPAddress.
/**
* This only creates an address if the hostname AND port are set in router.config,
* which should be rare.
* Otherwise, notifyReplaceAddress() below takes care of it.
* Note this is only called from startListening() via configureLocalAddress()
*
* TODO return a list of one or more
* TODO unlike in UDP rebuildExternalAddress(), this only runs once, at startup,
* so we won't pick up IP changes.
* TODO only returns non-null if port is configured
*
* @since IPv6 moved from CSFI
*/
private RouterAddress createNTCPAddress() {
int p = _context.getProperty(PROP_I2NP_NTCP_PORT, -1);
if (p <= 0 || p >= 64 * 1024)
return null;
String name = getConfiguredIP();
if (name == null)
return null;
OrderedProperties props = new OrderedProperties();
props.setProperty(RouterAddress.PROP_HOST, name);
props.setProperty(RouterAddress.PROP_PORT, Integer.toString(p));
int cost = getDefaultCost(false);
RouterAddress addr = new RouterAddress(STYLE, props, cost);
return addr;
}
use of net.i2p.data.router.RouterAddress in project i2p.i2p by i2p.
the class NTCPTransport method startListening.
/**
* Called by TransportManager.
* Caller should stop the transport first, then
* verify stopped with isAlive()
* Unfortunately TransportManager doesn't do that, so we
* check here to prevent two pumpers.
*/
public synchronized void startListening() {
// try once again to prevent two pumpers which is fatal
if (_pumper.isAlive())
return;
if (_log.shouldLog(Log.WARN))
_log.warn("Starting NTCP transport listening");
startIt();
RouterAddress addr = configureLocalAddress();
int port;
if (addr != null)
// probably not set
port = addr.getPort();
else
// received by externalAddressReceived() from TransportManager
port = _ssuPort;
RouterAddress myAddress = bindAddress(port);
if (myAddress != null) {
// fixed interface, or bound to the specified host
replaceAddress(myAddress);
} else if (addr != null) {
// specified host, bound to wildcard
replaceAddress(addr);
} else if (port > 0) {
// all detected interfaces
for (InetAddress ia : getSavedLocalAddresses()) {
OrderedProperties props = new OrderedProperties();
props.setProperty(RouterAddress.PROP_HOST, ia.getHostAddress());
props.setProperty(RouterAddress.PROP_PORT, Integer.toString(port));
int cost = getDefaultCost(ia instanceof Inet6Address);
myAddress = new RouterAddress(STYLE, props, cost);
replaceAddress(myAddress);
}
}
// TransportManager.startListening() calls router.rebuildRouterInfo()
}
use of net.i2p.data.router.RouterAddress in project i2p.i2p by i2p.
the class NTCPTransport method bindAddress.
/**
* Only does something if myPort > 0 and myPort != current bound port
* (or there's no current port, or the configured interface or hostname changed).
* If we are changing the bound port, this restarts everything, which takes a long time.
*
* call from synchronized method
*
* @param myPort does nothing if <= 0
* @return new address ONLY if bound to specific address, otherwise null
*/
private RouterAddress bindAddress(int port) {
RouterAddress myAddress = null;
if (port > 0) {
InetAddress bindToAddr = null;
String bindTo = _context.getProperty(PROP_BIND_INTERFACE);
if (bindTo == null) {
// If we are configured with a fixed IP address,
// AND it's one of our local interfaces,
// bind only to that.
bindTo = getFixedHost();
}
if (bindTo != null) {
try {
bindToAddr = InetAddress.getByName(bindTo);
} catch (UnknownHostException uhe) {
_log.error("Invalid NTCP bind interface specified [" + bindTo + "]", uhe);
// this can be implemented later, just updates some stats
// see udp/UDPTransport.java
// setReachabilityStatus(CommSystemFacade.STATUS_HOSED);
// return null;
// fall thru
}
}
try {
InetSocketAddress addr;
if (bindToAddr == null) {
addr = new InetSocketAddress(port);
} else {
addr = new InetSocketAddress(bindToAddr, port);
if (_log.shouldLog(Log.WARN))
_log.warn("Binding only to " + bindToAddr);
OrderedProperties props = new OrderedProperties();
props.setProperty(RouterAddress.PROP_HOST, bindTo);
props.setProperty(RouterAddress.PROP_PORT, Integer.toString(port));
int cost = getDefaultCost(false);
myAddress = new RouterAddress(STYLE, props, cost);
}
if (!_endpoints.isEmpty()) {
// require a restart.
if (_endpoints.contains(addr) || (bindToAddr != null && _endpoints.contains(new InetSocketAddress(port)))) {
if (_log.shouldLog(Log.WARN))
_log.warn("Already listening on " + addr);
return null;
}
// FIXME support multiple binds
// FIXME just close and unregister
stopWaitAndRestart();
}
if (!TransportUtil.isValidPort(port))
_log.error("Specified NTCP port is " + port + ", ports lower than 1024 not recommended");
ServerSocketChannel chan = ServerSocketChannel.open();
chan.configureBlocking(false);
chan.socket().bind(addr);
_endpoints.add(addr);
if (_log.shouldLog(Log.INFO))
_log.info("Listening on " + addr);
_pumper.register(chan);
} catch (IOException ioe) {
_log.error("Error listening", ioe);
myAddress = null;
}
} else {
if (_log.shouldLog(Log.INFO))
_log.info("Outbound NTCP connections only - no listener configured");
}
return myAddress;
}
use of net.i2p.data.router.RouterAddress in project i2p.i2p by i2p.
the class ConnectChecker method canConnect.
/**
* Can "from" connect to "to" based on published addresses?
*
* This is intended for tunnel candidates, where we already have
* the RI. Will not force RI lookups.
* Either from or to may be us.
*
* This is best effort, as we can't know for sure.
* Published addresses or introducers may have changed.
* Even if a can't connect to b, they may already be connected
* as b connected to a.
*
* @return true if we don't have either RI
* @since 0.9.34
*/
public boolean canConnect(Hash from, Hash to) {
Hash us = ctx.routerHash();
if (us == null)
return true;
boolean usf = from.equals(us);
if (usf && ctx.commSystem().isEstablished(to))
return true;
boolean ust = to.equals(us);
if (ust && ctx.commSystem().isEstablished(from))
return true;
RouterInfo rt = ctx.netDb().lookupRouterInfoLocally(to);
if (rt == null)
return true;
RouterInfo rf = ctx.netDb().lookupRouterInfoLocally(from);
if (rf == null)
return true;
int ct;
if (ust) {
// to us
ct = getInboundMask(rt);
} else {
Collection<RouterAddress> at = rt.getAddresses();
// assume nothing if hidden
if (at.isEmpty())
return false;
ct = getConnectMask(at);
}
int cf;
if (usf) {
// from us
cf = getOutboundMask(rf);
} else {
Collection<RouterAddress> a = rf.getAddresses();
if (a.isEmpty()) {
// assume IPv4 if hidden
cf = NTCP_V4 | SSU_V4;
} else {
cf = getConnectMask(a);
}
}
boolean rv = (ct & cf) != 0;
if (!rv && log.shouldWarn()) {
log.warn("Cannot connect: " + (usf ? "us" : from.toString()) + " with mask " + cf + "\nto " + (ust ? "us" : to.toString()) + " with mask " + ct);
}
return rv;
}
use of net.i2p.data.router.RouterAddress in project i2p.i2p by i2p.
the class ConnectChecker method getInboundMask.
/**
* Our inbound mask.
* For most cases, we use what we published, i.e. getConnectMask()
*
* @return bitmask for accepting connections
* @since 0.9.34
*/
public int getInboundMask(RouterInfo us) {
// to us
int ct = 0;
Status status = ctx.commSystem().getStatus();
switch(status) {
case OK:
case IPV4_UNKNOWN_IPV6_OK:
case IPV4_FIREWALLED_IPV6_OK:
case IPV4_SNAT_IPV6_OK:
case IPV4_SNAT_IPV6_UNKNOWN:
case IPV4_FIREWALLED_IPV6_UNKNOWN:
case IPV4_UNKNOWN_IPV6_FIREWALLED:
case IPV4_OK_IPV6_FIREWALLED:
case DIFFERENT:
case REJECT_UNSOLICITED:
// use what we published
Collection<RouterAddress> at = us.getAddresses();
if (at.isEmpty())
return 0;
ct = getConnectMask(at);
break;
case IPV4_DISABLED_IPV6_OK:
case IPV4_DISABLED_IPV6_UNKNOWN:
// maybe should return zero for this one?
case IPV4_DISABLED_IPV6_FIREWALLED:
// TODO look at force-firewalled settings per-transport
if (!isNTCPDisabled())
ct |= NTCP_V6;
if (!isSSUDisabled())
ct |= SSU_V6;
break;
case IPV4_OK_IPV6_UNKNOWN:
case DISCONNECTED:
case HOSED:
case UNKNOWN:
default:
if (!isNTCPDisabled())
ct |= NTCP_V4;
if (!isSSUDisabled())
ct |= SSU_V4;
break;
}
return ct;
}
Aggregations