/** * Since Java 7 or Android 2.3 (API 9), * which is the lowest Android we support anyway. * * Not guaranteed to be correct, e.g. FreeBSD: * https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=201446 * * @since 0.9.20 */ private static boolean isSNISupported() { return SystemVersion.isJava7() || SystemVersion.isAndroid(); }
/** * Get I2CP host from the config * @since 0.9.7 was in loadConfig() */ private String getHost() { if (_context.isRouterContext()) // just for logging return "[internal connection]"; else if (SystemVersion.isAndroid() && Boolean.parseBoolean(_options.getProperty(PROP_DOMAIN_SOCKET))) // just for logging return "[Domain socket connection]"; return _options.getProperty(I2PClient.PROP_TCP_HOST, "127.0.0.1"); }
/** * As of 0.9.31, only outputs UPnP status * * Warning - blocking, very slow, queries the active UPnP router, * will take many seconds if it has vanished. */ public void renderStatusHTML(Writer out, String urlBase, int sortFlags) throws IOException { if (SystemVersion.isAndroid()) { // newer androids crash w/ network on IO thread } else if (_upnpManager != null) { out.write(_upnpManager.renderStatusHTML()); } else { out.write("<h3 id=\"upnpstatus\"><a name=\"upnp\"></a>" + _t("UPnP is not enabled") + "</h3>\n"); } }
/** * Return a msg with the date stamp of the last duplicate * @since 0.9.3 */ private String dupMessage(int dupCount, LogRecord lastRecord, boolean reverse) { String arrows = reverse ? (SystemVersion.isAndroid() ? "vvv" : "↓↓↓") : "^^^"; return LogRecordFormatter.getWhen(_manager, lastRecord) + ' ' + arrows + ' ' + _t(dupCount, "1 similar message omitted", "{0} similar messages omitted") + ' ' + arrows + LogRecordFormatter.NL; }
/** * Set properties where the defaults must be different from those * in I2PAppContext. * * Unless we are explicitly disabling the timestamper, we want to use it. * We need this now as the new timestamper default is disabled (so we don't * have each I2PAppContext creating their own SNTP queries all the time) * * Set more PRNG buffers, as the default is now small for the I2PAppContext. * */ private static final Properties filterProps(Properties envProps) { if (envProps == null) envProps = new Properties(); if (envProps.getProperty("time.disabled") == null) envProps.setProperty("time.disabled", "false"); if (envProps.getProperty("prng.buffers") == null) { // How many of these 256 KB buffers do we need? // One clue: prng.bufferFillTime is ~10ms on my system, // and prng.bufferFillTime event count is ~30 per minute, // or about 2 seconds per buffer - so about 200x faster // to fill than to drain - so we don't need too many long maxMemory = SystemVersion.getMaxMemory(); long maxBuffs = (SystemVersion.isAndroid() || SystemVersion.isARM()) ? 4 : 8; long buffs = Math.min(maxBuffs, Math.max(2, maxMemory / (21 * 1024 * 1024))); envProps.setProperty("prng.buffers", Long.toString(buffs)); } return envProps; }
/** * Best guess if running from a Debian package * @since 0.9.35 */ private static boolean isDebianPackage(RouterContext ctx) { boolean isDebian = !SystemVersion.isWindows() && !SystemVersion.isMac() && !SystemVersion.isGentoo() && !SystemVersion.isAndroid() && System.getProperty("os.name").startsWith("Linux") && (new File("/etc/debian_version")).exists(); return isDebian && ctx.getBaseDir().getPath().equals("/usr/share/i2p") && ctx.getBooleanProperty("router.updateDisabled"); }
/** * Overridden to provide useful info to users on OOM, and to prevent * shutting down the whole JVM for what is most likely not a heap issue. * If the calling thread is an I2PThread an OOM would shut down the JVM. * Telling the user to increase the heap size may make the problem worse. * We may be able to continue without this thread, particularly in app context. * * @since 0.9.20 */ @Override public void start() { try { super.start(); } catch (OutOfMemoryError oom) { System.out.println("ERROR: Thread could not be started: " + getName()); if (!(SystemVersion.isWindows() || SystemVersion.isAndroid())) { System.out.println("Check ulimit -u, /etc/security/limits.conf, or /proc/sys/kernel/threads-max"); } oom.printStackTrace(); if (!(SystemVersion.isWindows() || SystemVersion.isAndroid())) throw new RuntimeException("Thread could not be started, " + "Check ulimit -u, /etc/security/limits.conf, or /proc/sys/kernel/threads-max", oom); throw new RuntimeException("Thread could not be started", oom); } }
public void run() { _write = true; // don't bother on Android final boolean shouldReadConfig = !SystemVersion.isAndroid(); try { while (_write) { flushRecords(); if (_write && shouldReadConfig) rereadConfig(); } } catch (RuntimeException e) { System.err.println("Error writing the log: " + e); e.printStackTrace(); } closeWriter(); }
/** * Won't be available on Android or on any builds not using our build.xml. * * @return 0 if unknown */ private static long getBuildTime(SimpleDateFormat fmt, String jar) { if (SystemVersion.isAndroid()) return 0; File f = new File(I2PAppContext.getGlobalContext().getBaseDir(), "lib"); f = new File(f, jar); Attributes atts = attributes(f); if (atts == null) return 0; String s = atts.getValue("Build-Date"); if (s == null) return 0; try { Date date = fmt.parse(s); if (date != null) { return date.getTime(); } } catch (ParseException pe) {} return 0; }
/** @since 0.8.2 */ private synchronized void startLogWriter() { // yeah, this doesn't always work, _writer should be volatile if (_writer != null) return; if (SystemVersion.isAndroid()) { try { Class<? extends LogWriter> clazz = Class.forName( "net.i2p.util.AndroidLogWriter" ).asSubclass(LogWriter.class); Constructor<? extends LogWriter> ctor = clazz.getDeclaredConstructor(LogManager.class); _writer = ctor.newInstance(this); } catch (ClassNotFoundException e) { } catch (InstantiationException e) { } catch (IllegalAccessException e) { } catch (InvocationTargetException e) { } catch (NoSuchMethodException e) { } } // Default writer if (_writer == null) _writer = new FileLogWriter(this); _writer.setFlushInterval(_flushInterval * 1000); // if you enable logging in I2PThread again, you MUST change this back to Thread Thread t = new I2PThread(_writer, "LogWriter"); t.setDaemon(true); t.start(); }
/** * Get I2CP port from the config * @since 0.9.7 was in loadConfig() */ private int getPort() { if (_context.isRouterContext() || (SystemVersion.isAndroid() && Boolean.parseBoolean(_options.getProperty(PROP_DOMAIN_SOCKET)))) // just for logging return 0; String portNum = _options.getProperty(I2PClient.PROP_TCP_PORT, LISTEN_PORT + ""); try { return Integer.parseInt(portNum); } catch (NumberFormatException nfe) { if (_log.shouldLog(Log.WARN)) _log.warn(getPrefix() + "Invalid port number specified, defaulting to " + LISTEN_PORT, nfe); return LISTEN_PORT; } }
/** * In I2PAppContext will instantiate if necessary and always return non-null. * As of 0.9.4, when in RouterContext, will return null (except in Android) * if the TCG has not yet been started by the router. * * @throws IllegalArgumentException if unable to load from i2ptunnel.config */ public static TunnelControllerGroup getInstance() { synchronized (TunnelControllerGroup.class) { if (_instance == null) { I2PAppContext ctx = I2PAppContext.getGlobalContext(); if (SystemVersion.isAndroid() || !ctx.isRouterContext()) { _instance = new TunnelControllerGroup(ctx, null, null); if (!SystemVersion.isAndroid()) _instance.startup(); } // else wait for the router to start it } return _instance; } }
/** I2P this is all static so have the UPnPManager call this */ public static void initialize(I2PAppContext ctx) { // don't keep static ref on android, just skip it if (SystemVersion.isAndroid()) return; _log = ctx.logManager().getLog(Debug.class); // org.cybergarage.util.Debug=DEBUG at startup enabled = _log.shouldLog(Log.DEBUG); }
/** * @since 0.9.24 */ public static void main(String[] args) { System.out.println("64 bit : " + is64Bit()); System.out.println("Java 6 : " + isJava6()); System.out.println("Java 7 : " + isJava7()); System.out.println("Java 8 : " + isJava8()); System.out.println("Java 9 : " + isJava9()); System.out.println("Java 10 : " + isJava10()); System.out.println("Java 11 : " + isJava11()); System.out.println("Android : " + isAndroid()); if (isAndroid()) System.out.println(" Version: " + getAndroidVersion()); System.out.println("Apache : " + isApache()); System.out.println("ARM : " + isARM()); System.out.println("Cores : " + getCores()); System.out.println("Gentoo : " + isGentoo()); System.out.println("GNU : " + isGNU()); System.out.println("Linux Svc: " + isLinuxService()); System.out.println("Mac : " + isMac()); System.out.println("Max mem : " + getMaxMemory()); System.out.println("OpenJDK : " + isOpenJDK()); System.out.println("Slow : " + isSlow()); System.out.println("Windows : " + isWindows()); System.out.println("Wrapper : " + hasWrapper()); System.out.println("x86 : " + isX86()); System.out.println("Zero JVM : " + isZeroVM()); } }
private ByteCache(int maxCachedEntries, int entrySize) { super(new ByteArrayFactory(entrySize), maxCachedEntries); _entrySize = entrySize; int stagger = SystemVersion.isAndroid() ? 0 : (entrySize % 777); SimpleTimer2.getInstance().addPeriodicEvent(new Cleanup(), CLEANUP_FREQUENCY + stagger); I2PAppContext.getGlobalContext().statManager().createRateStat("byteCache.memory." + entrySize, "Memory usage (B)", "Router", new long[] { 10*60*1000 }); }
private void runCurrentJob() { try { //_state = 18; _lastBegin = _context.clock().now(); _currentJob.runJob(); //_state = 19; } catch (OutOfMemoryError oom) { try { if (SystemVersion.isAndroid()) _context.router().shutdown(Router.EXIT_OOM); else fireOOM(oom); } catch (Throwable t) {} } catch (Throwable t) { //_state = 21; _log.log(Log.CRIT, "Error processing job [" + _currentJob.getName() + "] on thread " + _id + ": " + t.getMessage(), t); //if (_log.shouldLog(Log.ERROR)) // _log.error("The above job was enqueued by: ", _currentJob.getAddedBy()); } } }
private void writeRecord(LogRecord rec) { String val = LogRecordFormatter.formatRecord(_manager, rec, true); writeRecord(rec, val); // we always add to the console buffer, but only sometimes write to stdout _manager.getBuffer().add(val); if (rec.getPriority() >= Log.CRIT) _manager.getBuffer().addCritical(val); if (_manager.getDisplayOnScreenLevel() <= rec.getPriority()) { if (_manager.displayOnScreen()) { // wrapper and android logs already do time stamps, so reformat without the date if (_manager.getContext().hasWrapper() || SystemVersion.isAndroid()) System.out.print(LogRecordFormatter.formatRecord(_manager, rec, false)); else System.out.print(val); } } } }
public void runJob() { if (!SystemVersion.isAndroid()) getContext().jobQueue().addJob(new LoadClientAppsJob(getContext())); getContext().jobQueue().addJob(new LoadRouterInfoJob(getContext())); } }
/** @since 0.9.20 */ private void warn(long maxMemory, int KBps, long recMaxMem, int threshKBps) { if (SystemVersion.isAndroid()) return; String path = OOMListener.getWrapperConfigPath(_context); String msg = "Configured for " + DataHelper.formatSize(KBps *1024L) + "Bps share bandwidth but only " + DataHelper.formatSize(maxMemory) + "B available memory."; if (_context.hasWrapper()) { msg += " Recommend increasing wrapper.java.maxmemory in " + path; } else if (!SystemVersion.isWindows()) { msg += " Recommend increasing MAXMEMOPT in " + _context.getBaseDir() + File.separatorChar + "runplain.sh or /usr/bin/i2prouter-nowrapper"; } else { msg += " Recommend running the restartable version of I2P, and increasing wrapper.java.maxmemory in " + path; } // getMaxMemory() returns significantly lower than wrapper config, so add 10% msg += " to at least " + (recMaxMem * 11 / 10 / (1024*1024)) + " (MB)" + " if the actual share bandwidth exceeds " + DataHelper.formatSize(threshKBps * 1024L) + "Bps."; System.out.println("WARN: " + msg); _context.logManager().getLog(BloomFilterIVValidator.class).logAlways(Log.WARN, msg); } }
public void runJob() { // The netDb and the peer manager both take a long time to start up, // as they may have to read in ~1000 files or more each // So turn on the multiple job queues and start these two first. // These two (plus the current job) will consume 3 of the 4 runners, // leaving one for everything else, which allows us to start without // a huge job lag displayed on the console. getContext().jobQueue().allowParallelOperation(); startupDb(); getContext().jobQueue().addJob(new BootPeerManagerJob(getContext())); // start up the network comm system getContext().commSystem().startup(); getContext().tunnelManager().startup(); // start I2CP getContext().jobQueue().addJob(new StartAcceptingClientsJob(getContext())); if (!SystemVersion.isAndroid()) { Job j = new ReadConfigJob(getContext()); j.getTiming().setStartAfter(getContext().clock().now() + 2*60*1000); getContext().jobQueue().addJob(j); } ((RouterClock) getContext().clock()).addShiftListener(getContext().router()); }