Search in sources :

Example 16 with OrderedProperties

use of net.i2p.util.OrderedProperties 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()
}
Also used : RouterAddress(net.i2p.data.router.RouterAddress) OrderedProperties(net.i2p.util.OrderedProperties) Inet6Address(java.net.Inet6Address) InetAddress(java.net.InetAddress)

Example 17 with OrderedProperties

use of net.i2p.util.OrderedProperties 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;
}
Also used : UnknownHostException(java.net.UnknownHostException) InetSocketAddress(java.net.InetSocketAddress) RouterAddress(net.i2p.data.router.RouterAddress) OrderedProperties(net.i2p.util.OrderedProperties) IOException(java.io.IOException) InetAddress(java.net.InetAddress) ServerSocketChannel(java.nio.channels.ServerSocketChannel)

Example 18 with OrderedProperties

use of net.i2p.util.OrderedProperties in project i2p.i2p by i2p.

the class UDPTransport method locked_rebuildExternalAddress.

private RouterAddress locked_rebuildExternalAddress(String host, int port, boolean allowRebuildRouterInfo) {
    if (_log.shouldDebug())
        _log.debug("REA4 " + host + ':' + port);
    if (_context.router().isHidden())
        return null;
    OrderedProperties options = new OrderedProperties();
    boolean directIncluded;
    // DNS name assumed IPv4
    boolean isIPv6 = host != null && host.contains(":");
    boolean introducersRequired = (!isIPv6) && introducersRequired();
    if (!introducersRequired && allowDirectUDP() && port > 0 && host != null) {
        options.setProperty(UDPAddress.PROP_PORT, String.valueOf(port));
        options.setProperty(UDPAddress.PROP_HOST, host);
        directIncluded = true;
    } else {
        directIncluded = false;
    }
    boolean introducersIncluded = false;
    if (introducersRequired) {
        // intro manager now sorts introducers, so
        // deepEquals() below will not fail even with same introducers.
        // Was only a problem when we had very very few peers to pick from.
        RouterAddress current = getCurrentAddress(isIPv6);
        int found = _introManager.pickInbound(current, options, PUBLIC_RELAY_COUNT);
        if (found > 0) {
            if (_log.shouldLog(Log.INFO))
                _log.info("Direct? " + directIncluded + " reqd? " + introducersRequired + " picked introducers: " + found);
            _introducersSelectedOn = _context.clock().now();
            introducersIncluded = true;
        } else {
            if (_log.shouldLog(Log.WARN))
                _log.warn("Direct? " + directIncluded + " reqd? " + introducersRequired + " no introducers");
        }
    }
    // if we have explicit external addresses, they had better be reachable
    if (introducersRequired)
        options.setProperty(UDPAddress.PROP_CAPACITY, CAP_TESTING);
    else
        options.setProperty(UDPAddress.PROP_CAPACITY, CAP_TESTING_INTRO);
    // MTU since 0.9.2
    int mtu;
    if (host == null) {
        mtu = _mtu;
    } else {
        try {
            InetAddress ia = InetAddress.getByName(host);
            mtu = setMTU(ia);
        } catch (UnknownHostException uhe) {
            mtu = _mtu;
        }
    }
    if (mtu != PeerState.LARGE_MTU)
        options.setProperty(UDPAddress.PROP_MTU, Integer.toString(mtu));
    if (directIncluded || introducersIncluded) {
        // Note that peers won't connect to us without this - see EstablishmentManager
        if (_introKey != null)
            options.setProperty(UDPAddress.PROP_INTRO_KEY, _introKey.toBase64());
        // SSU seems to regulate at about 85%, so make it a little higher.
        // If this is too low, both NTCP and SSU always have incremented cost and
        // the whole mechanism is not helpful.
        int cost = DEFAULT_COST;
        if (ADJUST_COST && !haveCapacity(91))
            cost += CONGESTION_COST_ADJUSTMENT;
        if (introducersIncluded)
            cost += 2;
        if (isIPv6) {
            TransportUtil.IPv6Config config = getIPv6Config();
            if (config == IPV6_PREFERRED)
                cost--;
            else if (config == IPV6_NOT_PREFERRED)
                cost++;
        }
        RouterAddress addr = new RouterAddress(STYLE, options, cost);
        RouterAddress current = getCurrentAddress(isIPv6);
        boolean wantsRebuild = !addr.deepEquals(current);
        // save the external address, even if we didn't publish it
        if (port > 0 && host != null) {
            RouterAddress local;
            if (directIncluded) {
                local = addr;
            } else {
                OrderedProperties localOpts = new OrderedProperties();
                localOpts.setProperty(UDPAddress.PROP_PORT, String.valueOf(port));
                localOpts.setProperty(UDPAddress.PROP_HOST, host);
                local = new RouterAddress(STYLE, localOpts, cost);
            }
            replaceCurrentExternalAddress(local, isIPv6);
        }
        if (wantsRebuild) {
            if (_log.shouldLog(Log.INFO))
                _log.info("Address rebuilt: " + addr, new Exception());
            replaceAddress(addr);
            // via CSFI.createAddresses->TM.getAddresses()->updateAddress()->REA
            if (allowRebuildRouterInfo)
                _context.router().rebuildRouterInfo();
        } else {
            addr = null;
        }
        if (!isIPv6)
            _needsRebuild = false;
        return addr;
    } else {
        if (_log.shouldLog(Log.WARN))
            _log.warn("Wanted to rebuild my SSU address, but couldn't specify either the direct or indirect info (needs introducers? " + introducersRequired + ")", new Exception("source"));
        _needsRebuild = true;
        // save the external address, even if we didn't publish it
        if (port > 0 && host != null) {
            OrderedProperties localOpts = new OrderedProperties();
            localOpts.setProperty(UDPAddress.PROP_PORT, String.valueOf(port));
            localOpts.setProperty(UDPAddress.PROP_HOST, host);
            RouterAddress local = new RouterAddress(STYLE, localOpts, DEFAULT_COST);
            replaceCurrentExternalAddress(local, isIPv6);
        }
        if (hasCurrentAddress()) {
            // We must remove current address, otherwise the user will see
            // "firewalled with inbound NTCP enabled" warning in console.
            // Remove the IPv4 address only
            removeAddress(false);
            // via CSFI.createAddresses->TM.getAddresses()->updateAddress()->REA
            if (allowRebuildRouterInfo)
                _context.router().rebuildRouterInfo();
        }
        return null;
    }
}
Also used : IPv6Config(net.i2p.router.transport.TransportUtil.IPv6Config) TransportUtil(net.i2p.router.transport.TransportUtil) UnknownHostException(java.net.UnknownHostException) OrderedProperties(net.i2p.util.OrderedProperties) RouterAddress(net.i2p.data.router.RouterAddress) InetAddress(java.net.InetAddress) SocketException(java.net.SocketException) IOException(java.io.IOException) UnknownHostException(java.net.UnknownHostException)

Example 19 with OrderedProperties

use of net.i2p.util.OrderedProperties in project i2p.i2p by i2p.

the class PluginUpdateRunner method processFinal.

/**
 *  @param pubkey null OK for su3
 *  @since 0.9.15
 */
private void processFinal(File to, File appDir, String url, Properties props, String sudVersion, String pubkey, String signer) {
    boolean update = false;
    String appName = props.getProperty("name");
    String version = props.getProperty("version");
    if (appName == null || version == null || appName.length() <= 0 || version.length() <= 0 || appName.indexOf('<') >= 0 || appName.indexOf('>') >= 0 || version.indexOf('<') >= 0 || version.indexOf('>') >= 0 || appName.startsWith(".") || appName.indexOf('/') >= 0 || appName.indexOf('\\') >= 0) {
        to.delete();
        statusDone("<b>" + _t("Plugin from {0} has invalid name or version", url) + "</b>");
        return;
    }
    if (!version.equals(sudVersion)) {
        to.delete();
        statusDone("<b>" + _t("Plugin {0} has mismatched versions", appName) + "</b>");
        return;
    }
    // set so notifyComplete() will work
    _appName = appName;
    _newVersion = version;
    String minVersion = PluginStarter.stripHTML(props, "min-i2p-version");
    if (minVersion != null && VersionComparator.comp(CoreVersion.VERSION, minVersion) < 0) {
        to.delete();
        statusDone("<b>" + _t("This plugin requires I2P version {0} or higher", minVersion) + "</b>");
        return;
    }
    minVersion = PluginStarter.stripHTML(props, "min-java-version");
    if (minVersion != null && VersionComparator.comp(System.getProperty("java.version"), minVersion) < 0) {
        to.delete();
        statusDone("<b>" + _t("This plugin requires Java version {0} or higher", minVersion) + "</b>");
        return;
    }
    boolean wasRunning = false;
    File destDir = new SecureDirectory(appDir, appName);
    if (destDir.exists()) {
        if (Boolean.valueOf(props.getProperty("install-only")).booleanValue()) {
            to.delete();
            statusDone("<b>" + _t("Downloaded plugin is for new installs only, but the plugin is already installed", url) + "</b>");
            return;
        }
        // compare previous version
        File oldPropFile = new File(destDir, "plugin.config");
        Properties oldProps = new OrderedProperties();
        try {
            DataHelper.loadProps(oldProps, oldPropFile);
        } catch (IOException ioe) {
            to.delete();
            statusDone("<b>" + _t("Installed plugin does not contain the required configuration file", url) + "</b>");
            return;
        }
        String oldPubkey = oldProps.getProperty("key");
        String oldKeyName = oldProps.getProperty("signer");
        String oldAppName = oldProps.getProperty("name");
        if ((pubkey != null && !pubkey.equals(oldPubkey)) || (!signer.equals(oldKeyName)) || (!appName.equals(oldAppName))) {
            to.delete();
            statusDone("<b>" + _t("Signature of downloaded plugin does not match installed plugin") + "</b>");
            return;
        }
        String oldVersion = oldProps.getProperty("version");
        if (oldVersion == null || VersionComparator.comp(oldVersion, version) >= 0) {
            to.delete();
            statusDone("<b>" + _t("Downloaded plugin version {0} is not newer than installed plugin", version) + "</b>");
            return;
        }
        minVersion = PluginStarter.stripHTML(props, "min-installed-version");
        if (minVersion != null && VersionComparator.comp(minVersion, oldVersion) > 0) {
            to.delete();
            statusDone("<b>" + _t("Plugin update requires installed plugin version {0} or higher", minVersion) + "</b>");
            return;
        }
        String maxVersion = PluginStarter.stripHTML(props, "max-installed-version");
        if (maxVersion != null && VersionComparator.comp(maxVersion, oldVersion) < 0) {
            to.delete();
            statusDone("<b>" + _t("Plugin update requires installed plugin version {0} or lower", maxVersion) + "</b>");
            return;
        }
        oldVersion = RouterConsoleRunner.jettyVersion();
        minVersion = PluginStarter.stripHTML(props, "min-jetty-version");
        if (minVersion != null && VersionComparator.comp(minVersion, oldVersion) > 0) {
            to.delete();
            statusDone("<b>" + _t("Plugin requires Jetty version {0} or higher", minVersion) + "</b>");
            return;
        }
        String blacklistVersion = PluginStarter.jetty9Blacklist.get(appName);
        if (blacklistVersion != null && VersionComparator.comp(version, blacklistVersion) <= 0) {
            to.delete();
            statusDone("<b>" + _t("Plugin requires Jetty version {0} or lower", "8.9999") + "</b>");
            return;
        }
        maxVersion = PluginStarter.stripHTML(props, "max-jetty-version");
        if (maxVersion != null && VersionComparator.comp(maxVersion, oldVersion) < 0) {
            to.delete();
            statusDone("<b>" + _t("Plugin requires Jetty version {0} or lower", maxVersion) + "</b>");
            return;
        }
        // do we defer extraction and installation?
        if (Boolean.valueOf(props.getProperty("router-restart-required")).booleanValue()) {
            // Yup!
            try {
                if (!FileUtil.copy(to, (new SecureFile(new SecureFile(appDir.getCanonicalPath() + "/" + appName + "/" + ZIP).getCanonicalPath())), true, true)) {
                    to.delete();
                    statusDone("<b>" + _t("Cannot copy plugin to directory {0}", destDir.getAbsolutePath()) + "</b>");
                    return;
                }
            } catch (Throwable t) {
                to.delete();
                _log.error("Error copying plugin {0}", t);
                return;
            }
            // we don't need the original file anymore.
            to.delete();
            statusDone("<b>" + _t("Plugin will be installed on next restart.") + ' ' + appName + ' ' + version + "</b>");
            return;
        }
        if (PluginStarter.isPluginRunning(appName, _context)) {
            wasRunning = true;
            try {
                if (!PluginStarter.stopPlugin(_context, appName)) {
                // failed, ignore
                }
            } catch (Throwable e) {
                // no updateStatus() for this one
                _log.error("Error stopping plugin " + appName, e);
            }
        }
        update = true;
    } else {
        if (Boolean.valueOf(props.getProperty("update-only")).booleanValue()) {
            to.delete();
            statusDone("<b>" + _t("Plugin is for upgrades only, but the plugin is not installed") + ". " + appName + ' ' + version + "</b>");
            return;
        }
        if (!destDir.mkdir()) {
            to.delete();
            statusDone("<b>" + _t("Cannot create plugin directory {0}", destDir.getAbsolutePath()) + "</b>");
            return;
        }
    }
    // Finally, extract the zip to the plugin directory
    if (!FileUtil.extractZip(to, destDir, Log.WARN)) {
        to.delete();
        statusDone("<b>" + _t("Failed to install plugin in {0}", destDir.getAbsolutePath()) + "</b>");
        return;
    }
    _updated = true;
    to.delete();
    // install != update. Changing the user's settings like this is probabbly a bad idea.
    if (Boolean.valueOf(props.getProperty("dont-start-at-install")).booleanValue()) {
        statusDone("<b>" + _t("Plugin {0} installed", appName + ' ' + version) + "</b>");
        if (!update) {
            Properties pluginProps = PluginStarter.pluginProperties();
            pluginProps.setProperty(PluginStarter.PREFIX + appName + PluginStarter.ENABLED, "false");
            PluginStarter.storePluginProperties(pluginProps);
        }
    } else if (wasRunning || PluginStarter.isPluginEnabled(appName)) {
        // start everything unless it was disabled and not running before
        try {
            if (PluginStarter.startPlugin(_context, appName)) {
                String linkName = PluginStarter.stripHTML(props, "consoleLinkName_" + Messages.getLanguage(_context));
                if (linkName == null)
                    linkName = PluginStarter.stripHTML(props, "consoleLinkName");
                String linkURL = PluginStarter.stripHTML(props, "consoleLinkURL");
                String link;
                if (linkName != null && linkURL != null)
                    link = "<a target=\"_blank\" href=\"" + linkURL + "\"/>" + linkName + ' ' + version + "</a>";
                else
                    link = appName + ' ' + version;
                statusDone("<b>" + _t("Plugin {0} installed and started", link) + "</b>");
            } else
                statusDone("<b>" + _t("Plugin {0} installed but failed to start, check logs", appName + ' ' + version) + "</b>");
        } catch (Throwable e) {
            statusDone("<b>" + _t("Plugin {0} installed but failed to start", appName + ' ' + version) + ": " + e + "</b>");
            _log.error("Error starting plugin " + appName + ' ' + version, e);
        }
    } else {
        statusDone("<b>" + _t("Plugin {0} installed", appName + ' ' + version) + "</b>");
    }
}
Also used : SecureDirectory(net.i2p.util.SecureDirectory) SecureFile(net.i2p.util.SecureFile) OrderedProperties(net.i2p.util.OrderedProperties) IOException(java.io.IOException) OrderedProperties(net.i2p.util.OrderedProperties) Properties(java.util.Properties) SecureFile(net.i2p.util.SecureFile) SU3File(net.i2p.crypto.SU3File) File(java.io.File)

Example 20 with OrderedProperties

use of net.i2p.util.OrderedProperties in project i2p.i2p by i2p.

the class PluginUpdateRunner method getPluginConfig.

/**
 *  @since 0.9.15
 *  @return null on error
 */
private Properties getPluginConfig(File f, File to, String url) {
    File tempDir = new File(_context.getTempDir(), "tmp" + _context.random().nextInt() + "-unzip");
    if (!FileUtil.extractZip(to, tempDir, Log.ERROR)) {
        f.delete();
        to.delete();
        FileUtil.rmdir(tempDir, false);
        statusDone("<b>" + _t("Plugin from {0} is corrupt", url) + "</b>");
        return null;
    }
    File installProps = new File(tempDir, "plugin.config");
    Properties props = new OrderedProperties();
    try {
        DataHelper.loadProps(props, installProps);
    } catch (IOException ioe) {
        f.delete();
        to.delete();
        statusDone("<b>" + _t("Plugin from {0} does not contain the required configuration file", url) + "</b>");
        return null;
    } finally {
        // we don't need this anymore, we will unzip again
        FileUtil.rmdir(tempDir, false);
    }
    return props;
}
Also used : OrderedProperties(net.i2p.util.OrderedProperties) IOException(java.io.IOException) OrderedProperties(net.i2p.util.OrderedProperties) Properties(java.util.Properties) SecureFile(net.i2p.util.SecureFile) SU3File(net.i2p.crypto.SU3File) File(java.io.File)

Aggregations

OrderedProperties (net.i2p.util.OrderedProperties)34 Properties (java.util.Properties)20 IOException (java.io.IOException)16 File (java.io.File)12 Map (java.util.Map)8 RouterAddress (net.i2p.data.router.RouterAddress)6 UnknownHostException (java.net.UnknownHostException)5 InputStream (java.io.InputStream)4 HashMap (java.util.HashMap)4 InetAddress (java.net.InetAddress)3 ConcurrentHashMap (java.util.concurrent.ConcurrentHashMap)3 StructureTest (net.i2p.data.StructureTest)3 Test (org.junit.Test)3 BufferedInputStream (java.io.BufferedInputStream)2 ByteArrayOutputStream (java.io.ByteArrayOutputStream)2 FileInputStream (java.io.FileInputStream)2 OutputStream (java.io.OutputStream)2 Socket (java.net.Socket)2 GeneralSecurityException (java.security.GeneralSecurityException)2 I2PSessionException (net.i2p.client.I2PSessionException)2