Search in sources :

Example 11 with I2PSessionException

use of net.i2p.client.I2PSessionException in project i2p.i2p by i2p.

the class I2CPMessageProducer method sendMessage.

/**
 * Package up and send the payload to the router for delivery
 *
 * @param nonce 0 to 0xffffffff; if 0, the router will not reply with a MessageStatusMessage
 * @since 0.9.2
 */
public void sendMessage(I2PSessionImpl session, Destination dest, long nonce, byte[] payload, SendMessageOptions options) throws I2PSessionException {
    long expires = options.getTime();
    if (!updateBps(payload.length, expires))
        // drop the message... send fail notification?
        return;
    SendMessageMessage msg = new SendMessageExpiresMessage(options);
    msg.setDestination(dest);
    SessionId sid = session.getSessionId();
    if (sid == null) {
        _log.error(session.toString() + " send message w/o session", new Exception());
        return;
    }
    msg.setSessionId(sid);
    msg.setNonce(nonce);
    Payload data = createPayload(dest, payload, null, null, null, null);
    msg.setPayload(data);
    session.sendMessage(msg);
}
Also used : SendMessageMessage(net.i2p.data.i2cp.SendMessageMessage) SendMessageExpiresMessage(net.i2p.data.i2cp.SendMessageExpiresMessage) Payload(net.i2p.data.Payload) SessionId(net.i2p.data.i2cp.SessionId) DataFormatException(net.i2p.data.DataFormatException) I2PSessionException(net.i2p.client.I2PSessionException)

Example 12 with I2PSessionException

use of net.i2p.client.I2PSessionException in project i2p.i2p by i2p.

the class I2PSessionImpl method addSubsession.

/**
 *  Router must be connected or was connected... for now.
 *
 *  @return a new subsession, non-null
 *  @param privateKeyStream null for transient, if non-null must have same encryption keys as primary session
 *                          and different signing keys
 *  @param opts subsession options if any, may be null
 *  @since 0.9.21
 */
public I2PSession addSubsession(InputStream privateKeyStream, Properties opts) throws I2PSessionException {
    if (!_routerSupportsSubsessions)
        throw new I2PSessionException("Router does not support subsessions");
    SubSession sub;
    synchronized (_subsessionLock) {
        if (_subsessions.size() > _subsessionMap.size())
            throw new I2PSessionException("Subsession request already pending");
        sub = new SubSession(this, privateKeyStream, opts);
        for (SubSession ss : _subsessions) {
            if (ss.getDecryptionKey().equals(sub.getDecryptionKey()) && ss.getPrivateKey().equals(sub.getPrivateKey())) {
                throw new I2PSessionException("Dup subsession");
            }
        }
        _subsessions.add(sub);
    }
    synchronized (_stateLock) {
        if (_state == State.OPEN) {
            _producer.connect(sub);
        }
    // else will be called in connect()
    }
    return sub;
}
Also used : I2PSessionException(net.i2p.client.I2PSessionException)

Example 13 with I2PSessionException

use of net.i2p.client.I2PSessionException 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)

Example 14 with I2PSessionException

use of net.i2p.client.I2PSessionException in project i2p.i2p by i2p.

the class I2PSimpleSession method connect.

/**
 * Connect to the router and establish a session.  This call blocks until
 * a session is granted.
 *
 * NOT threadsafe, do not call from multiple threads.
 *
 * @throws I2PSessionException if there is a configuration error or the router is
 *                             not reachable
 */
@Override
public void connect() throws I2PSessionException {
    changeState(State.OPENING);
    boolean success = false;
    try {
        // protect w/ closeSocket()
        synchronized (_stateLock) {
            // If we are in the router JVM, connect using the interal 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);
                _reader.startReading();
            } else {
                if (Boolean.parseBoolean(getOptions().getProperty(PROP_ENABLE_SSL))) {
                    try {
                        I2PSSLSocketFactory fact = new I2PSSLSocketFactory(_context, false, "certificates/i2cp");
                        _socket = fact.createSocket(_hostname, _portNum);
                    } catch (GeneralSecurityException gse) {
                        IOException ioe = new IOException("SSL Fail");
                        ioe.initCause(gse);
                        throw ioe;
                    }
                } else {
                    _socket = new Socket(_hostname, _portNum);
                }
                _socket.setKeepAlive(true);
                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);
                _reader.startReading();
            }
        }
        // must be out of synch block for writer to get unblocked
        if (!_context.isRouterContext()) {
            Properties opts = getOptions();
            // support the AuthMessage
            if ((!opts.containsKey(PROP_USER)) && (!opts.containsKey(PROP_PW))) {
                // auto-add auth if not set in the options
                String configUser = _context.getProperty(PROP_USER);
                String configPW = _context.getProperty(PROP_PW);
                if (configUser != null && configPW != null) {
                    opts.setProperty(PROP_USER, configUser);
                    opts.setProperty(PROP_PW, configPW);
                }
            }
            if (opts.containsKey(PROP_USER) && opts.containsKey(PROP_PW)) {
                Properties auth = new OrderedProperties();
                auth.setProperty(PROP_USER, opts.getProperty(PROP_USER));
                auth.setProperty(PROP_PW, opts.getProperty(PROP_PW));
                sendMessage_unchecked(new GetDateMessage(CoreVersion.VERSION, auth));
            } else {
                // we must now send a GetDate even in SimpleSession, or we won't know
                // what version we are talking with and cannot use HostLookup
                sendMessage_unchecked(new GetDateMessage(CoreVersion.VERSION));
            }
            waitForDate();
        }
        // we do not receive payload messages, so we do not need an AvailabilityNotifier
        // ... or an Idle timer, or a VerifyUsage
        success = true;
        if (_log.shouldLog(Log.INFO))
            _log.info(getPrefix() + " simple session connected");
    } 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 internal router binding";
        else if (SystemVersion.isAndroid() && Boolean.parseBoolean(getOptions().getProperty(PROP_DOMAIN_SOCKET)))
            msg = "Failed to bind to the router";
        else
            msg = "Cannot connect to the router on " + _hostname + ':' + _portNum;
        throw new I2PSessionException(getPrefix() + msg, ioe);
    } finally {
        changeState(success ? State.OPEN : State.CLOSED);
    }
}
Also used : 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) OutputStream(java.io.OutputStream) IOException(java.io.IOException) OrderedProperties(net.i2p.util.OrderedProperties) Properties(java.util.Properties) I2PSSLSocketFactory(net.i2p.util.I2PSSLSocketFactory) BufferedInputStream(java.io.BufferedInputStream) I2PSessionException(net.i2p.client.I2PSessionException) OrderedProperties(net.i2p.util.OrderedProperties) I2CPMessageReader(net.i2p.data.i2cp.I2CPMessageReader) QueuedI2CPMessageReader(net.i2p.internal.QueuedI2CPMessageReader) Socket(java.net.Socket) QueuedI2CPMessageReader(net.i2p.internal.QueuedI2CPMessageReader)

Example 15 with I2PSessionException

use of net.i2p.client.I2PSessionException in project i2p.i2p by i2p.

the class DisconnectMessageHandler method handleMessage.

public void handleMessage(I2CPMessage message, I2PSessionImpl session) {
    if (_log.shouldLog(Log.DEBUG))
        _log.debug("Handle message " + message);
    String reason = ((DisconnectMessage) message).getReason();
    session.propogateError(reason, new I2PSessionException("Disconnect Message received: " + reason));
    session.destroySession(false);
    if (reason.contains("restart")) {
        Thread t = new I2PAppThread(new Reconnector(session), "Reconnect " + session, true);
        t.start();
    }
}
Also used : DisconnectMessage(net.i2p.data.i2cp.DisconnectMessage) I2PSessionException(net.i2p.client.I2PSessionException) I2PAppThread(net.i2p.util.I2PAppThread) I2PAppThread(net.i2p.util.I2PAppThread)

Aggregations

I2PSessionException (net.i2p.client.I2PSessionException)44 IOException (java.io.IOException)18 DataFormatException (net.i2p.data.DataFormatException)15 Properties (java.util.Properties)13 I2PSession (net.i2p.client.I2PSession)11 Destination (net.i2p.data.Destination)11 SessionId (net.i2p.data.i2cp.SessionId)7 ByteArrayOutputStream (java.io.ByteArrayOutputStream)6 ByteArrayInputStream (java.io.ByteArrayInputStream)5 InterruptedIOException (java.io.InterruptedIOException)5 I2PException (net.i2p.I2PException)5 File (java.io.File)4 GeneralSecurityException (java.security.GeneralSecurityException)4 I2PClient (net.i2p.client.I2PClient)4 FileInputStream (java.io.FileInputStream)3 UnknownHostException (java.net.UnknownHostException)3 Payload (net.i2p.data.Payload)3 Log (net.i2p.util.Log)3 BufferedInputStream (java.io.BufferedInputStream)2 DataInputStream (java.io.DataInputStream)2