Search in sources :

Example 1 with OrderedProperties

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

the class SAMBridge method storeKeys.

/**
 * Store the current keys to disk in the location specified on creation.
 */
private void storeKeys() {
    synchronized (nameToPrivKeys) {
        File file = new File(persistFilename);
        // now in config dir but check base dir too...
        if (!file.exists() && !file.isAbsolute())
            file = new File(I2PAppContext.getGlobalContext().getConfigDir(), persistFilename);
        try {
            Properties props = new OrderedProperties();
            props.putAll(nameToPrivKeys);
            DataHelper.storeProps(props, file);
            if (_log.shouldInfo())
                _log.info("Saved " + nameToPrivKeys.size() + " private keys to " + file);
        } catch (IOException ioe) {
            _log.error("Error writing out the SAM keys to " + file, ioe);
        }
    }
}
Also used : OrderedProperties(net.i2p.util.OrderedProperties) IOException(java.io.IOException) OrderedProperties(net.i2p.util.OrderedProperties) Properties(java.util.Properties) File(java.io.File)

Example 2 with OrderedProperties

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

the class SnarkManager method migrateConfig.

/**
 *  Migrate the old flat config file to the new config dir
 *  containing the config file minus the per-torrent entries,
 *  the dht file, and 64 subdirs for per-torrent config files
 *  Caller must synch.
 *
 *  @return the new config directory, non-null
 *  @throws RuntimeException on creation fail
 *  @since 0.9.15
 */
private File migrateConfig(File oldFile) {
    File dir = new SecureDirectory(oldFile + CONFIG_DIR_SUFFIX);
    if ((!dir.exists()) && (!dir.mkdirs())) {
        _log.error("Error creating I2PSnark config dir " + dir);
        throw new RuntimeException("Error creating I2PSnark config dir " + dir);
    }
    // move the DHT file as-is
    String oldName = oldFile.toString();
    if (oldName.endsWith(CONFIG_FILE_SUFFIX)) {
        String oldDHT = oldName.replace(CONFIG_FILE_SUFFIX, KRPC.DHT_FILE_SUFFIX);
        File oldDHTFile = new File(oldDHT);
        if (oldDHTFile.exists()) {
            File newDHTFile = new File(dir, "i2psnark" + KRPC.DHT_FILE_SUFFIX);
            FileUtil.rename(oldDHTFile, newDHTFile);
        }
    }
    if (!oldFile.exists())
        return dir;
    Properties oldProps = new Properties();
    try {
        DataHelper.loadProps(oldProps, oldFile);
        // a good time to fix this ancient typo
        String auto = (String) oldProps.remove(PROP_OLD_AUTO_START);
        if (auto != null)
            oldProps.setProperty(PROP_AUTO_START, auto);
    } catch (IOException ioe) {
        _log.error("Error loading I2PSnark config " + oldFile, ioe);
        return dir;
    }
    // Gather the props for each torrent, removing them from config
    // old b64 of hash as key
    Map<String, Properties> configs = new HashMap<String, Properties>(16);
    for (Iterator<Map.Entry<Object, Object>> iter = oldProps.entrySet().iterator(); iter.hasNext(); ) {
        Map.Entry<Object, Object> e = iter.next();
        String k = (String) e.getKey();
        if (k.startsWith(PROP_META_PREFIX)) {
            iter.remove();
            String v = (String) e.getValue();
            try {
                k = k.substring(PROP_META_PREFIX.length());
                // length of b64 of 160 bit infohash
                String h = k.substring(0, 28);
                // skip '.'
                k = k.substring(29);
                Properties tprops = configs.get(h);
                if (tprops == null) {
                    tprops = new OrderedProperties();
                    configs.put(h, tprops);
                }
                if (k.equals(PROP_META_BITFIELD)) {
                    // old config was timestamp,bitfield; split them
                    int comma = v.indexOf(',');
                    if (comma > 0 && v.length() > comma + 1) {
                        tprops.put(PROP_META_STAMP, v.substring(0, comma));
                        tprops.put(PROP_META_BITFIELD, v.substring(comma + 1));
                    } else {
                        // timestamp only??
                        tprops.put(PROP_META_STAMP, v);
                    }
                } else {
                    tprops.put(k, v);
                }
            } catch (IndexOutOfBoundsException ioobe) {
                continue;
            }
        }
    }
    // Now make a config file for each torrent
    for (Map.Entry<String, Properties> e : configs.entrySet()) {
        String b64 = e.getKey();
        Properties props = e.getValue();
        if (props.isEmpty())
            continue;
        b64 = b64.replace('$', '=');
        byte[] ih = Base64.decode(b64);
        if (ih == null || ih.length != 20)
            continue;
        File cfg = configFile(dir, ih);
        if (!cfg.exists()) {
            File subdir = cfg.getParentFile();
            if (!subdir.exists())
                subdir.mkdirs();
            try {
                DataHelper.storeProps(props, cfg);
            } catch (IOException ioe) {
                _log.error("Error storing I2PSnark config " + cfg, ioe);
            }
        }
    }
    // now store in new location, minus the zmeta entries
    File newFile = new File(dir, CONFIG_FILE);
    Properties newProps = new OrderedProperties();
    newProps.putAll(oldProps);
    try {
        DataHelper.storeProps(newProps, newFile);
    } catch (IOException ioe) {
        _log.error("Error storing I2PSnark config " + newFile, ioe);
        return dir;
    }
    oldFile.delete();
    if (_log.shouldLog(Log.WARN))
        _log.warn("Config migrated from " + oldFile + " to " + dir);
    return dir;
}
Also used : ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) HashMap(java.util.HashMap) IOException(java.io.IOException) OrderedProperties(net.i2p.util.OrderedProperties) Properties(java.util.Properties) SecureDirectory(net.i2p.util.SecureDirectory) OrderedProperties(net.i2p.util.OrderedProperties) File(java.io.File) Map(java.util.Map) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) HashMap(java.util.HashMap)

Example 3 with OrderedProperties

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

the class SnarkManager method locked_loadConfig.

/**
 * null to set initial defaults
 */
private void locked_loadConfig(String filename) {
    if (_config == null)
        _config = new OrderedProperties();
    if (filename != null) {
        File cfg = new File(filename);
        if (!cfg.isAbsolute())
            cfg = new File(_context.getConfigDir(), filename);
        _configDir = migrateConfig(cfg);
        _configFile = new File(_configDir, CONFIG_FILE);
        if (_configFile.exists()) {
            try {
                DataHelper.loadProps(_config, _configFile);
            } catch (IOException ioe) {
                _log.error("Error loading I2PSnark config " + _configFile, ioe);
            }
        }
    }
    // now add sane defaults
    if (!_config.containsKey(PROP_I2CP_HOST))
        _config.setProperty(PROP_I2CP_HOST, "127.0.0.1");
    if (!_config.containsKey(PROP_I2CP_PORT))
        _config.setProperty(PROP_I2CP_PORT, "7654");
    if (!_config.containsKey(PROP_I2CP_OPTS))
        _config.setProperty(PROP_I2CP_OPTS, "inbound.length=3 outbound.length=3" + " inbound.quantity=" + DEFAULT_TUNNEL_QUANTITY + " outbound.quantity=" + DEFAULT_TUNNEL_QUANTITY);
    // _config.setProperty(PROP_EEP_PORT, "4444");
    if (!_config.containsKey(PROP_UPLOADERS_TOTAL))
        _config.setProperty(PROP_UPLOADERS_TOTAL, "" + Snark.MAX_TOTAL_UPLOADERS);
    if (!_config.containsKey(PROP_DIR))
        _config.setProperty(PROP_DIR, _contextName);
    if (!_config.containsKey(PROP_AUTO_START))
        _config.setProperty(PROP_AUTO_START, DEFAULT_AUTO_START);
    if (!_config.containsKey(PROP_REFRESH_DELAY))
        _config.setProperty(PROP_REFRESH_DELAY, Integer.toString(DEFAULT_REFRESH_DELAY_SECS));
    if (!_config.containsKey(PROP_STARTUP_DELAY))
        _config.setProperty(PROP_STARTUP_DELAY, Integer.toString(DEFAULT_STARTUP_DELAY));
    if (!_config.containsKey(PROP_PAGE_SIZE))
        _config.setProperty(PROP_PAGE_SIZE, Integer.toString(DEFAULT_PAGE_SIZE));
    if (!_config.containsKey(PROP_THEME))
        _config.setProperty(PROP_THEME, DEFAULT_THEME);
    // _config.setProperty(PROP_USE_DHT, Boolean.toString(I2PSnarkUtil.DEFAULT_USE_DHT));
    if (!_config.containsKey(PROP_RATINGS))
        _config.setProperty(PROP_RATINGS, "true");
    if (!_config.containsKey(PROP_COMMENTS))
        _config.setProperty(PROP_COMMENTS, "true");
    if (!_config.containsKey(PROP_COMMENTS_NAME))
        _config.setProperty(PROP_COMMENTS_NAME, "");
    if (!_config.containsKey(PROP_COLLAPSE_PANELS))
        _config.setProperty(PROP_COLLAPSE_PANELS, Boolean.toString(I2PSnarkUtil.DEFAULT_COLLAPSE_PANELS));
    updateConfig();
}
Also used : OrderedProperties(net.i2p.util.OrderedProperties) IOException(java.io.IOException) File(java.io.File)

Example 4 with OrderedProperties

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

the class TunnelControllerGroup method saveConfig.

/**
 * Save the configuration of all known tunnels to the given file
 */
public synchronized void saveConfig(String configFile) throws IOException {
    File cfgFile = new File(configFile);
    if (!cfgFile.isAbsolute())
        cfgFile = new File(I2PAppContext.getGlobalContext().getConfigDir(), configFile);
    File parent = cfgFile.getParentFile();
    if ((parent != null) && (!parent.exists()))
        parent.mkdirs();
    Properties map = new OrderedProperties();
    _controllersLock.readLock().lock();
    try {
        for (int i = 0; i < _controllers.size(); i++) {
            TunnelController controller = _controllers.get(i);
            Properties cur = controller.getConfig("tunnel." + i + ".");
            map.putAll(cur);
        }
    } finally {
        _controllersLock.readLock().unlock();
    }
    DataHelper.storeProps(map, cfgFile);
}
Also used : OrderedProperties(net.i2p.util.OrderedProperties) OrderedProperties(net.i2p.util.OrderedProperties) Properties(java.util.Properties) File(java.io.File)

Example 5 with OrderedProperties

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

the class I2PSessionImpl method connect.

/**
 * Connect to the router and establish a session.  This call blocks until
 * a session is granted.
 *
 * Should be threadsafe, other threads will block until complete.
 * Disconnect / destroy from another thread may be called simultaneously and
 * will (should?) interrupt the connect.
 *
 * Connecting a primary session will not automatically connect subsessions.
 * Connecting a subsession will automatically connect the primary session
 * if not previously connected.
 *
 * @throws I2PSessionException if there is a configuration error or the router is
 *                             not reachable
 */
public void connect() throws I2PSessionException {
    synchronized (_stateLock) {
        boolean wasOpening = false;
        boolean loop = true;
        while (loop) {
            switch(_state) {
                case INIT:
                    loop = false;
                    break;
                case CLOSED:
                    if (wasOpening)
                        throw new I2PSessionException("connect by other thread failed");
                    loop = false;
                    break;
                case OPENING:
                case GOTDATE:
                    wasOpening = true;
                    try {
                        _stateLock.wait(10 * 1000);
                    } catch (InterruptedException ie) {
                        throw new I2PSessionException("Interrupted", ie);
                    }
                    break;
                case CLOSING:
                    throw new I2PSessionException("close in progress");
                case OPEN:
                    return;
            }
        }
        changeState(State.OPENING);
    }
    _availabilityNotifier.stopNotifying();
    if ((_options != null) && (I2PClient.PROP_RELIABILITY_GUARANTEED.equals(_options.getProperty(I2PClient.PROP_RELIABILITY, I2PClient.PROP_RELIABILITY_BEST_EFFORT)))) {
        if (_log.shouldLog(Log.ERROR))
            _log.error("I2CP guaranteed delivery mode has been removed, using best effort.");
    }
    boolean success = false;
    long startConnect = _context.clock().now();
    try {
        // protect w/ closeSocket()
        synchronized (_stateLock) {
            // If we are in the router JVM, connect using the internal queue
            if (_context.isRouterContext()) {
                // _socket and _writer remain null
                InternalClientManager mgr = _context.internalClientManager();
                if (mgr == null)
                    throw new I2PSessionException("Router is not ready for connections");
                // the following may throw an I2PSessionException
                _queue = mgr.connect();
                _reader = new QueuedI2CPMessageReader(_queue, this);
            } else {
                if (SystemVersion.isAndroid() && _options.getProperty(PROP_DOMAIN_SOCKET) != null) {
                    try {
                        Class<?> clazz = Class.forName("net.i2p.client.DomainSocketFactory");
                        Constructor<?> ctor = clazz.getDeclaredConstructor(I2PAppContext.class);
                        Object fact = ctor.newInstance(_context);
                        Method createSocket = clazz.getDeclaredMethod("createSocket", String.class);
                        try {
                            _socket = (Socket) createSocket.invoke(fact, _options.getProperty(PROP_DOMAIN_SOCKET));
                        } catch (InvocationTargetException e) {
                            throw new I2PSessionException("Cannot create domain socket", e);
                        }
                    } catch (ClassNotFoundException e) {
                        throw new I2PSessionException("Cannot load DomainSocketFactory", e);
                    } catch (NoSuchMethodException e) {
                        throw new I2PSessionException("Cannot load DomainSocketFactory", e);
                    } catch (InstantiationException e) {
                        throw new I2PSessionException("Cannot load DomainSocketFactory", e);
                    } catch (IllegalAccessException e) {
                        throw new I2PSessionException("Cannot load DomainSocketFactory", e);
                    } catch (InvocationTargetException e) {
                        throw new I2PSessionException("Cannot load DomainSocketFactory", e);
                    }
                } else if (Boolean.parseBoolean(_options.getProperty(PROP_ENABLE_SSL))) {
                    try {
                        I2PSSLSocketFactory fact = new I2PSSLSocketFactory(_context, false, "certificates/i2cp");
                        _socket = fact.createSocket(_hostname, _portNum);
                        _socket.setKeepAlive(true);
                    } catch (GeneralSecurityException gse) {
                        IOException ioe = new IOException("SSL Fail");
                        ioe.initCause(gse);
                        throw ioe;
                    }
                } else {
                    _socket = new Socket(_hostname, _portNum);
                    _socket.setKeepAlive(true);
                }
                // _socket.setSoTimeout(1000000); // Uhmmm we could really-really use a real timeout, and handle it.
                OutputStream out = _socket.getOutputStream();
                out.write(I2PClient.PROTOCOL_BYTE);
                out.flush();
                _writer = new ClientWriterRunner(out, this);
                _writer.startWriting();
                InputStream in = new BufferedInputStream(_socket.getInputStream(), BUF_SIZE);
                _reader = new I2CPMessageReader(in, this);
            }
        }
        if (_log.shouldLog(Log.DEBUG))
            _log.debug(getPrefix() + "before startReading");
        _reader.startReading();
        if (_log.shouldLog(Log.DEBUG))
            _log.debug(getPrefix() + "Before getDate");
        Properties auth = null;
        if ((!_context.isRouterContext()) && _options.containsKey(PROP_USER) && _options.containsKey(PROP_PW)) {
            // Only supported by routers 0.9.11 or higher, but we don't know the version yet.
            // Auth will also be sent in the SessionConfig.
            auth = new OrderedProperties();
            auth.setProperty(PROP_USER, _options.getProperty(PROP_USER));
            auth.setProperty(PROP_PW, _options.getProperty(PROP_PW));
        }
        sendMessage_unchecked(new GetDateMessage(CoreVersion.VERSION, auth));
        waitForDate();
        if (_log.shouldLog(Log.DEBUG))
            _log.debug(getPrefix() + "Before producer.connect()");
        _producer.connect(this);
        if (_log.shouldLog(Log.DEBUG))
            _log.debug(getPrefix() + "After producer.connect()");
        // wait until we have created a lease set
        int waitcount = 0;
        while (_leaseSet == null) {
            if (waitcount++ > 5 * 60) {
                throw new IOException("No tunnels built after waiting 5 minutes. Your network connection may be down, or there is severe network congestion.");
            }
            synchronized (_leaseSetWait) {
                // InterruptedException caught below
                _leaseSetWait.wait(1000);
            }
            // if we got a disconnect message while waiting
            if (isClosed())
                throw new IOException("Disconnected from router while waiting for tunnels");
        }
        if (_log.shouldLog(Log.INFO)) {
            long connected = _context.clock().now();
            _log.info(getPrefix() + "Lease set created with inbound tunnels after " + (connected - startConnect) + "ms - ready to participate in the network!");
        }
        Thread notifier = new I2PAppThread(_availabilityNotifier, "ClientNotifier " + getPrefix(), true);
        notifier.start();
        startIdleMonitor();
        startVerifyUsage();
        success = true;
        // now send CreateSessionMessages for all subsessions, one at a time, must wait for each response
        synchronized (_subsessionLock) {
            for (SubSession ss : _subsessions) {
                if (_log.shouldLog(Log.INFO))
                    _log.info(getPrefix() + "Connecting subsession " + ss);
                _producer.connect(ss);
            }
        }
    } catch (InterruptedException ie) {
        throw new I2PSessionException("Interrupted", ie);
    } catch (UnknownHostException uhe) {
        throw new I2PSessionException(getPrefix() + "Cannot connect to the router on " + _hostname + ':' + _portNum, uhe);
    } catch (IOException ioe) {
        // Generate the best error message as this will be logged
        String msg;
        if (_context.isRouterContext())
            msg = "Failed to build tunnels";
        else if (SystemVersion.isAndroid() && _options.getProperty(PROP_DOMAIN_SOCKET) != null)
            msg = "Failed to bind to the router on " + _options.getProperty(PROP_DOMAIN_SOCKET) + " and build tunnels";
        else
            msg = "Cannot connect to the router on " + _hostname + ':' + _portNum + " and build tunnels";
        throw new I2PSessionException(getPrefix() + msg, ioe);
    } finally {
        if (success) {
            changeState(State.OPEN);
        } else {
            _availabilityNotifier.stopNotifying();
            synchronized (_stateLock) {
                changeState(State.CLOSING);
                try {
                    _producer.disconnect(this);
                } catch (I2PSessionException ipe) {
                }
                closeSocket();
            }
        }
    }
}
Also used : OutputStream(java.io.OutputStream) OrderedProperties(net.i2p.util.OrderedProperties) Properties(java.util.Properties) I2PAppThread(net.i2p.util.I2PAppThread) BufferedInputStream(java.io.BufferedInputStream) OrderedProperties(net.i2p.util.OrderedProperties) QueuedI2CPMessageReader(net.i2p.internal.QueuedI2CPMessageReader) GetDateMessage(net.i2p.data.i2cp.GetDateMessage) InternalClientManager(net.i2p.internal.InternalClientManager) UnknownHostException(java.net.UnknownHostException) BufferedInputStream(java.io.BufferedInputStream) InputStream(java.io.InputStream) GeneralSecurityException(java.security.GeneralSecurityException) Method(java.lang.reflect.Method) IOException(java.io.IOException) InvocationTargetException(java.lang.reflect.InvocationTargetException) I2PAppThread(net.i2p.util.I2PAppThread) I2PSSLSocketFactory(net.i2p.util.I2PSSLSocketFactory) I2PSessionException(net.i2p.client.I2PSessionException) QueuedI2CPMessageReader(net.i2p.internal.QueuedI2CPMessageReader) I2CPMessageReader(net.i2p.data.i2cp.I2CPMessageReader) Socket(java.net.Socket)

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