use of net.i2p.data.router.RouterInfo in project i2p.i2p by i2p.
the class TransientDataStore method put.
/**
* @param data must be validated before here
* @return success
*/
public boolean put(Hash key, DatabaseEntry data) {
if (data == null)
return false;
if (_log.shouldLog(Log.DEBUG))
_log.debug("Storing key " + key);
DatabaseEntry old = _data.putIfAbsent(key, data);
boolean rv = false;
if (data.getType() == DatabaseEntry.KEY_TYPE_ROUTERINFO) {
// Don't do this here so we don't reset it at router startup;
// the StoreMessageJob calls this
// _context.profileManager().heardAbout(key);
RouterInfo ri = (RouterInfo) data;
if (old != null) {
RouterInfo ori = (RouterInfo) old;
if (ri.getPublished() < ori.getPublished()) {
if (_log.shouldLog(Log.INFO))
_log.info("Almost clobbered an old router! " + key + ": [old published on " + new Date(ori.getPublished()) + " new on " + new Date(ri.getPublished()) + ']');
} else if (ri.getPublished() == ori.getPublished()) {
if (_log.shouldLog(Log.INFO))
_log.info("Duplicate " + key);
} else {
if (_log.shouldLog(Log.INFO))
_log.info("Updated the old router for " + key + ": [old published on " + new Date(ori.getPublished()) + " new on " + new Date(ri.getPublished()) + ']');
_data.put(key, data);
rv = true;
}
} else {
if (_log.shouldLog(Log.INFO))
_log.info("New router for " + key + ": published on " + new Date(ri.getPublished()));
rv = true;
}
} else if (data.getType() == DatabaseEntry.KEY_TYPE_LEASESET) {
LeaseSet ls = (LeaseSet) data;
if (old != null) {
LeaseSet ols = (LeaseSet) old;
if (ls.getEarliestLeaseDate() < ols.getEarliestLeaseDate()) {
if (_log.shouldLog(Log.INFO))
_log.info("Almost clobbered an old leaseSet! " + key + ": [old expires " + new Date(ols.getEarliestLeaseDate()) + " new on " + new Date(ls.getEarliestLeaseDate()) + ']');
} else if (ls.getEarliestLeaseDate() == ols.getEarliestLeaseDate()) {
if (_log.shouldLog(Log.INFO))
_log.info("Duplicate " + key);
} else {
if (_log.shouldLog(Log.INFO)) {
_log.info("Updated old leaseSet " + key + ": [old expires " + new Date(ols.getEarliestLeaseDate()) + " new on " + new Date(ls.getEarliestLeaseDate()) + ']');
if (_log.shouldLog(Log.DEBUG))
_log.debug("RAP? " + ls.getReceivedAsPublished() + " RAR? " + ls.getReceivedAsReply());
}
_data.put(key, data);
rv = true;
}
} else {
if (_log.shouldLog(Log.INFO)) {
_log.info("New leaseset for " + key + ": expires " + new Date(ls.getEarliestLeaseDate()));
if (_log.shouldLog(Log.DEBUG))
_log.debug("RAP? " + ls.getReceivedAsPublished() + " RAR? " + ls.getReceivedAsReply());
}
rv = true;
}
}
return rv;
}
use of net.i2p.data.router.RouterInfo in project i2p.i2p by i2p.
the class ReseedBundler method createZip.
/**
* Create a zip file with
* a random selection of 'count' router infos from configDir/netDb
* to 'toDir'. Skip your own router info, and old, hidden, unreachable, and
* introduced routers, and those from bad countries.
*
* The file will be in the temp directory. Caller must move or delete.
*/
public File createZip(int count) throws IOException {
Hash me = _context.routerHash();
int routerCount = 0;
int copied = 0;
long tooOld = System.currentTimeMillis() - 7 * 24 * 60 * 60 * 1000L;
List<RouterInfo> infos = new ArrayList<RouterInfo>(_context.netDb().getRouters());
// IP to router hash
Map<String, Hash> ipMap = new HashMap<String, Hash>(count);
List<RouterInfo> toWrite = new ArrayList<RouterInfo>(count);
Collections.shuffle(infos);
for (RouterInfo ri : infos) {
if (copied >= count)
break;
Hash key = ri.getIdentity().calculateHash();
if (key.equals(me)) {
continue;
}
if (ri.getPublished() < tooOld)
continue;
if (ri.getCapabilities().contains("U"))
continue;
if (ri.getCapabilities().contains("K"))
continue;
Collection<RouterAddress> addrs = ri.getAddresses();
if (addrs.isEmpty())
continue;
String name = getRouterInfoName(key);
boolean hasIntro = false;
boolean hasIPv4 = false;
boolean dupIP = false;
for (RouterAddress addr : addrs) {
if ("SSU".equals(addr.getTransportStyle()) && addr.getOption("ihost0") != null) {
hasIntro = true;
break;
}
String host = addr.getHost();
if (host != null && host.contains(".")) {
hasIPv4 = true;
Hash old = ipMap.put(host, key);
if (old != null && !old.equals(key)) {
dupIP = true;
break;
}
}
}
if (dupIP)
continue;
if (hasIntro)
continue;
if (!hasIPv4)
continue;
if (_context.commSystem().isInBadCountry(ri))
continue;
toWrite.add(ri);
copied++;
}
if (toWrite.isEmpty())
throw new IOException("No router infos to include. Reseed yourself first.");
if (toWrite.size() < Math.min(count, MINIMUM))
throw new IOException("Not enough router infos to include, wanted " + count + " but only found " + toWrite.size() + ". Please try again later.");
File rv = new File(_context.getTempDir(), "genreseed-" + _context.random().nextInt() + ".zip");
ZipOutputStream zip = null;
try {
zip = new ZipOutputStream(new FileOutputStream(rv));
for (RouterInfo ri : toWrite) {
String name = getRouterInfoName(ri.getIdentity().calculateHash());
ZipEntry entry = new ZipEntry(name);
entry.setTime(ri.getPublished());
zip.putNextEntry(entry);
ri.writeBytes(zip);
zip.closeEntry();
}
} catch (DataFormatException dfe) {
rv.delete();
IOException ioe = new IOException(dfe.getMessage());
ioe.initCause(dfe);
throw ioe;
} catch (IOException ioe) {
rv.delete();
throw ioe;
} finally {
if (zip != null) {
try {
zip.finish();
zip.close();
} catch (IOException ioe) {
rv.delete();
throw ioe;
}
}
}
return rv;
}
use of net.i2p.data.router.RouterInfo in project i2p.i2p by i2p.
the class RebuildRouterInfoJob method rebuildRouterInfo.
/**
* @param alreadyRunning unused
*/
void rebuildRouterInfo(boolean alreadyRunning) {
_log.debug("Rebuilding the new router info");
RouterInfo info = null;
File infoFile = new File(getContext().getRouterDir(), CreateRouterInfoJob.INFO_FILENAME);
File keyFile = new File(getContext().getRouterDir(), CreateRouterInfoJob.KEYS_FILENAME);
File keyFile2 = new File(getContext().getRouterDir(), CreateRouterInfoJob.KEYS2_FILENAME);
if (keyFile2.exists() || keyFile.exists()) {
// ok, no need to rebuild a brand new identity, just update what we can
RouterInfo oldinfo = getContext().router().getRouterInfo();
if (oldinfo == null) {
try {
KeyData kd = LoadRouterInfoJob.readKeyData(keyFile, keyFile2);
info = new RouterInfo();
info.setIdentity(kd.routerIdentity);
} catch (DataFormatException e) {
_log.log(Log.CRIT, "Error reading in the key data from " + keyFile.getAbsolutePath(), e);
keyFile.delete();
keyFile2.delete();
rebuildRouterInfo(alreadyRunning);
return;
} catch (IOException e) {
_log.log(Log.CRIT, "Error reading in the key data from " + keyFile.getAbsolutePath(), e);
keyFile.delete();
keyFile2.delete();
rebuildRouterInfo(alreadyRunning);
return;
}
} else {
// Make a new RI from the old identity, or else info.setAddresses() will throw an ISE
info = new RouterInfo(oldinfo);
}
try {
info.setAddresses(getContext().commSystem().createAddresses());
Properties stats = getContext().statPublisher().publishStatistics(info.getHash());
info.setOptions(stats);
// info.setPeers(new HashSet()); // this would have the trusted peers
info.setPublished(CreateRouterInfoJob.getCurrentPublishDate(getContext()));
info.sign(getContext().keyManager().getSigningPrivateKey());
} catch (DataFormatException dfe) {
_log.log(Log.CRIT, "Error rebuilding the new router info", dfe);
return;
}
if (!info.isValid()) {
_log.log(Log.CRIT, "RouterInfo we just built is invalid: " + info, new Exception());
return;
}
FileOutputStream fos = null;
synchronized (getContext().router().routerInfoFileLock) {
try {
fos = new SecureFileOutputStream(infoFile);
info.writeBytes(fos);
} catch (DataFormatException dfe) {
_log.log(Log.CRIT, "Error rebuilding the router information", dfe);
} catch (IOException ioe) {
_log.log(Log.CRIT, "Error writing out the rebuilt router information", ioe);
} finally {
if (fos != null)
try {
fos.close();
} catch (IOException ioe) {
}
}
}
} else {
_log.warn("Private key file " + keyFile.getAbsolutePath() + " deleted! Rebuilding a brand new router identity!");
// this proc writes the keys and info to the file as well as builds the latest and greatest info
CreateRouterInfoJob j = new CreateRouterInfoJob(getContext(), null);
synchronized (getContext().router().routerInfoFileLock) {
info = j.createRouterInfo();
}
}
// MessageHistory.initialize();
getContext().router().setRouterInfo(info);
_log.info("Router info rebuilt and stored at " + infoFile + " [" + info + "]");
}
use of net.i2p.data.router.RouterInfo in project i2p.i2p by i2p.
the class NetDbRenderer method renderStatusHTML.
/**
* @param mode 0: charts only; 1: full routerinfos; 2: abbreviated routerinfos
*/
public void renderStatusHTML(Writer out, int mode) throws IOException {
if (!_context.netDb().isInitialized()) {
out.write("<div id=\"notinitialized\">");
out.write(_t("Not initialized"));
out.write("</div>");
out.flush();
return;
}
Log log = _context.logManager().getLog(NetDbRenderer.class);
long start = System.currentTimeMillis();
boolean full = mode == 1;
boolean shortStats = mode == 2;
// this means show the router infos
boolean showStats = full || shortStats;
Hash us = _context.routerHash();
StringBuilder buf = new StringBuilder(8192);
if (showStats) {
RouterInfo ourInfo = _context.router().getRouterInfo();
renderRouterInfo(buf, ourInfo, true, true);
out.write(buf.toString());
buf.setLength(0);
}
ObjectCounter<String> versions = new ObjectCounter<String>();
ObjectCounter<String> countries = new ObjectCounter<String>();
int[] transportCount = new int[TNAMES.length];
Set<RouterInfo> routers = new TreeSet<RouterInfo>(new RouterInfoComparator());
routers.addAll(_context.netDb().getRouters());
for (RouterInfo ri : routers) {
Hash key = ri.getIdentity().getHash();
boolean isUs = key.equals(us);
if (!isUs) {
if (showStats) {
renderRouterInfo(buf, ri, false, full);
out.write(buf.toString());
buf.setLength(0);
}
String routerVersion = ri.getOption("router.version");
if (routerVersion != null)
versions.increment(routerVersion);
String country = _context.commSystem().getCountry(key);
if (country != null)
countries.increment(country);
transportCount[classifyTransports(ri)]++;
}
}
long end = System.currentTimeMillis();
if (log.shouldWarn())
log.warn("part 1 took " + (end - start));
start = end;
//
if (!showStats) {
// the summary table
buf.append("<table id=\"netdboverview\" border=\"0\" cellspacing=\"30\"><tr><th colspan=\"3\">").append(_t("Network Database Router Statistics")).append("</th></tr><tr><td style=\"vertical-align: top;\">");
// versions table
List<String> versionList = new ArrayList<String>(versions.objects());
if (!versionList.isEmpty()) {
Collections.sort(versionList, Collections.reverseOrder(new VersionComparator()));
buf.append("<table id=\"netdbversions\">\n");
buf.append("<tr><th>" + _t("Version") + "</th><th>" + _t("Count") + "</th></tr>\n");
for (String routerVersion : versionList) {
int num = versions.count(routerVersion);
String ver = DataHelper.stripHTML(routerVersion);
buf.append("<tr><td align=\"center\"><a href=\"/netdb?v=").append(ver).append("\">").append(ver);
buf.append("</a></td><td align=\"center\">").append(num).append("</td></tr>\n");
}
buf.append("</table>\n");
}
buf.append("</td><td style=\"vertical-align: top;\">");
out.write(buf.toString());
buf.setLength(0);
end = System.currentTimeMillis();
if (log.shouldWarn())
log.warn("part 2 took " + (end - start));
start = end;
// transports table
buf.append("<table id=\"netdbtransports\">\n");
buf.append("<tr><th align=\"left\">" + _t("Transports") + "</th><th>" + _t("Count") + "</th></tr>\n");
for (int i = 0; i < TNAMES.length; i++) {
int num = transportCount[i];
if (num > 0) {
buf.append("<tr><td>").append(_t(TNAMES[i]));
buf.append("</td><td align=\"center\">").append(num).append("</td></tr>\n");
}
}
buf.append("</table>\n");
buf.append("</td><td style=\"vertical-align: top;\">");
out.write(buf.toString());
buf.setLength(0);
end = System.currentTimeMillis();
if (log.shouldWarn())
log.warn("part 3 took " + (end - start));
start = end;
// country table
List<String> countryList = new ArrayList<String>(countries.objects());
if (!countryList.isEmpty()) {
Collections.sort(countryList, new CountryComparator());
buf.append("<table id=\"netdbcountrylist\">\n");
buf.append("<tr><th align=\"left\">" + _t("Country") + "</th><th>" + _t("Count") + "</th></tr>\n");
for (String country : countryList) {
int num = countries.count(country);
buf.append("<tr><td><a href=\"/netdb?c=").append(country).append("\">");
buf.append("<img height=\"11\" width=\"16\" alt=\"").append(country.toUpperCase(Locale.US)).append("\"");
buf.append(" src=\"/flags.jsp?c=").append(country).append("\">");
buf.append(getTranslatedCountry(country));
buf.append("</a></td><td align=\"center\">").append(num).append("</td></tr>\n");
}
buf.append("</table>\n");
}
buf.append("</td></tr></table>");
end = System.currentTimeMillis();
if (log.shouldWarn())
log.warn("part 4 took " + (end - start));
start = end;
//
// don't bother to reindent
//
}
// if !showStats
out.write(buf.toString());
out.flush();
}
use of net.i2p.data.router.RouterInfo in project i2p.i2p by i2p.
the class NetDbRenderer method renderRouterInfoHTML.
/**
* One String must be non-null
*
* @param routerPrefix may be null. "." for our router only
* @param version may be null
* @param country may be null
* @param family may be null
*/
public void renderRouterInfoHTML(Writer out, String routerPrefix, String version, String country, String family, String caps, String ip, String sybil, int port, SigType type, String mtu, String ipv6, String ssucaps, int cost) throws IOException {
StringBuilder buf = new StringBuilder(4 * 1024);
List<Hash> sybils = sybil != null ? new ArrayList<Hash>(128) : null;
if (".".equals(routerPrefix)) {
renderRouterInfo(buf, _context.router().getRouterInfo(), true, true);
} else {
boolean notFound = true;
Set<RouterInfo> routers = _context.netDb().getRouters();
int ipMode = 0;
if (ip != null) {
if (ip.endsWith("/24")) {
ipMode = 1;
} else if (ip.endsWith("/16")) {
ipMode = 2;
} else if (ip.endsWith("/8")) {
ipMode = 3;
}
for (int i = 0; i < ipMode; i++) {
int last = ip.substring(0, ip.length() - 1).lastIndexOf('.');
if (last > 0)
ip = ip.substring(0, last + 1);
}
}
for (RouterInfo ri : routers) {
Hash key = ri.getIdentity().getHash();
if ((routerPrefix != null && key.toBase64().startsWith(routerPrefix)) || (version != null && version.equals(ri.getVersion())) || (country != null && country.equals(_context.commSystem().getCountry(key))) || (family != null && family.equals(ri.getOption("family"))) || (caps != null && ri.getCapabilities().contains(caps)) || (type != null && type == ri.getIdentity().getSigType())) {
renderRouterInfo(buf, ri, false, true);
if (sybil != null)
sybils.add(key);
notFound = false;
} else if (ip != null) {
for (RouterAddress ra : ri.getAddresses()) {
if (ipMode == 0) {
if (ip.equals(ra.getHost())) {
renderRouterInfo(buf, ri, false, true);
if (sybil != null)
sybils.add(key);
notFound = false;
break;
}
} else {
String host = ra.getHost();
if (host != null && host.startsWith(ip)) {
renderRouterInfo(buf, ri, false, true);
if (sybil != null)
sybils.add(key);
notFound = false;
break;
}
}
}
} else if (port != 0) {
for (RouterAddress ra : ri.getAddresses()) {
if (port == ra.getPort()) {
renderRouterInfo(buf, ri, false, true);
if (sybil != null)
sybils.add(key);
notFound = false;
break;
}
}
} else if (mtu != null) {
for (RouterAddress ra : ri.getAddresses()) {
if (mtu.equals(ra.getOption("mtu"))) {
renderRouterInfo(buf, ri, false, true);
if (sybil != null)
sybils.add(key);
notFound = false;
break;
}
}
} else if (ipv6 != null) {
for (RouterAddress ra : ri.getAddresses()) {
String host = ra.getHost();
if (host != null && host.startsWith(ipv6)) {
renderRouterInfo(buf, ri, false, true);
if (sybil != null)
sybils.add(key);
notFound = false;
break;
}
}
} else if (ssucaps != null) {
for (RouterAddress ra : ri.getAddresses()) {
if (!"SSU".equals(ra.getTransportStyle()))
continue;
if (ssucaps.equals(ra.getOption("caps"))) {
renderRouterInfo(buf, ri, false, true);
if (sybil != null)
sybils.add(key);
notFound = false;
break;
}
}
} else if (cost != 0) {
for (RouterAddress ra : ri.getAddresses()) {
if (cost == ra.getCost()) {
renderRouterInfo(buf, ri, false, true);
if (sybil != null)
sybils.add(key);
notFound = false;
break;
}
}
}
}
if (notFound) {
buf.append("<div class=\"netdbnotfound\">");
buf.append(_t("Router")).append(' ');
if (routerPrefix != null)
buf.append(routerPrefix);
else if (version != null)
buf.append(version);
else if (country != null)
buf.append(country);
else if (family != null)
buf.append(_t("Family")).append(' ').append(family);
buf.append(' ').append(_t("not found in network database"));
buf.append("</div>");
}
}
out.write(buf.toString());
out.flush();
if (sybil != null)
SybilRenderer.renderSybilHTML(out, _context, sybils, sybil);
}
Aggregations