Search in sources :

Example 1 with RouterRestartException

use of net.i2p.client.streaming.RouterRestartException in project i2p.i2p by i2p.

the class ConnectionHandler method accept.

/**
 * Receive an incoming connection (built from a received SYN)
 * Non-SYN packets with a zero SendStreamID may also be queued here so
 * that they don't get thrown away while the SYN packet before it is queued.
 *
 * @param timeoutMs max amount of time to wait for a connection (if less
 *                  than 1ms, wait indefinitely)
 * @return connection received. Prior to 0.9.17, or null if there was a timeout or the
 *                  handler was shut down. As of 0.9.17, never null.
 * @throws RouterRestartException (extends I2PException) if the router is apparently restarting, since 0.9.34
 * @throws ConnectException since 0.9.17, returned null before;
 *                  if the I2PServerSocket is closed, or if interrupted.
 * @throws SocketTimeoutException since 0.9.17, returned null before;
 *                  if a timeout was previously set with setSoTimeout and the timeout has been reached.
 */
public Connection accept(long timeoutMs) throws RouterRestartException, ConnectException, SocketTimeoutException {
    if (_log.shouldLog(Log.DEBUG))
        _log.debug("Accept(" + timeoutMs + ") called");
    long expiration = timeoutMs + _context.clock().now();
    while (true) {
        if ((timeoutMs > 0) && (expiration < _context.clock().now()))
            throw new SocketTimeoutException("accept() timed out");
        if (!_active) {
            // fail all the ones we had queued up
            while (true) {
                // fails immediately if empty
                Packet packet = _synQueue.poll();
                if (packet == null || packet.getOptionalDelay() == PoisonPacket.POISON_MAX_DELAY_REQUEST)
                    break;
                sendReset(packet);
            }
            if (_restartPending)
                throw new RouterRestartException();
            throw new ConnectException("ServerSocket closed");
        }
        Packet syn = null;
        while (_active && syn == null) {
            if (_log.shouldLog(Log.DEBUG))
                _log.debug("Accept(" + timeoutMs + "): active=" + _active + " queue: " + _synQueue.size());
            if (timeoutMs <= 0) {
                try {
                    // waits forever
                    syn = _synQueue.take();
                } catch (InterruptedException ie) {
                    ConnectException ce = new ConnectException("Interrupted accept()");
                    ce.initCause(ie);
                    throw ce;
                }
            } else {
                long remaining = expiration - _context.clock().now();
                // and the thread simply waits until notified.
                if (remaining < 1)
                    break;
                try {
                    // waits the specified time max
                    syn = _synQueue.poll(remaining, TimeUnit.MILLISECONDS);
                } catch (InterruptedException ie) {
                    ConnectException ce = new ConnectException("Interrupted accept()");
                    ce.initCause(ie);
                    throw ce;
                }
                break;
            }
        }
        if (syn != null) {
            if (syn.getOptionalDelay() == PoisonPacket.POISON_MAX_DELAY_REQUEST) {
                if (_restartPending)
                    throw new RouterRestartException();
                throw new ConnectException("ServerSocket closed");
            }
            // Handle both SYN and non-SYN packets in the queue
            if (syn.isFlagSet(Packet.FLAG_SYNCHRONIZE)) {
                // We are single-threaded here, so this is
                // a good place to check for dup SYNs and drop them
                Destination from = syn.getOptionalFrom();
                if (from == null) {
                    if (_log.shouldLog(Log.WARN))
                        _log.warn("Dropping SYN packet with no FROM: " + syn);
                    // drop it
                    continue;
                }
                Connection oldcon = _manager.getConnectionByOutboundId(syn.getReceiveStreamId());
                if (oldcon != null) {
                    // only drop it on a destination match too
                    if (from.equals(oldcon.getRemotePeer())) {
                        if (_log.shouldLog(Log.WARN))
                            _log.warn("Dropping dup SYN: " + syn);
                        continue;
                    }
                }
                Connection con = _manager.receiveConnection(syn);
                if (con != null)
                    return con;
            } else {
                reReceivePacket(syn);
            // ... and keep looping
            }
        }
    // keep looping...
    }
}
Also used : Destination(net.i2p.data.Destination) SocketTimeoutException(java.net.SocketTimeoutException) RouterRestartException(net.i2p.client.streaming.RouterRestartException) ConnectException(java.net.ConnectException)

Example 2 with RouterRestartException

use of net.i2p.client.streaming.RouterRestartException in project i2p.i2p by i2p.

the class I2PTunnelServer method run.

/**
 *  If usePool is set, this starts the executor pool.
 *  Then, do the accept() loop, and either
 *  hands each I2P socket to the executor or runs it in-line.
 */
public void run() {
    i2pss = sockMgr.getServerSocket();
    if (_log.shouldLog(Log.WARN)) {
        if (_usePool)
            _log.warn("Starting executor with " + getHandlerCount() + " threads max");
        else
            _log.warn("Threads disabled, running blockingHandles inline");
    }
    if (_usePool) {
        _executor = new CustomThreadPoolExecutor(getHandlerCount(), "ServerHandler pool " + remoteHost + ':' + remotePort);
    }
    TunnelControllerGroup tcg = TunnelControllerGroup.getInstance();
    if (tcg != null) {
        _clientExecutor = tcg.getClientExecutor();
    } else {
        // Fallback in case TCG.getInstance() is null, never instantiated
        // and we were not started by TCG.
        // Maybe a plugin loaded before TCG? Should be rare.
        // Never shut down.
        _clientExecutor = new TunnelControllerGroup.CustomThreadPoolExecutor();
    }
    I2PSocket i2ps = null;
    while (open) {
        try {
            i2ps = null;
            I2PServerSocket ci2pss = i2pss;
            if (ci2pss == null)
                throw new I2PException("I2PServerSocket closed");
            // returns non-null as of 0.9.17
            i2ps = ci2pss.accept();
            if (_usePool) {
                try {
                    _executor.execute(new Handler(i2ps));
                } catch (RejectedExecutionException ree) {
                    try {
                        i2ps.reset();
                    } catch (IOException ioe) {
                    }
                    if (open)
                        _log.logAlways(Log.WARN, "ServerHandler queue full, dropping incoming connection to " + remoteHost + ':' + remotePort + "; increase server max threads or " + PROP_HANDLER_COUNT + "; current is " + getHandlerCount());
                }
            } else {
                // use only for standard servers that can't get slowlorissed! Not for http or irc
                blockingHandle(i2ps);
            }
        } catch (RouterRestartException rre) {
            // Delay and loop if router is soft restarting
            _log.logAlways(Log.WARN, "Waiting for router restart");
            if (i2ps != null)
                try {
                    i2ps.close();
                } catch (IOException ioe) {
                }
            try {
                Thread.sleep(2 * 60 * 1000);
            } catch (InterruptedException ie) {
            }
            // This should be the same as before, but we have to call getServerSocket()
            // so sockMgr will call ConnectionManager.setAllowIncomingConnections(true) again
            i2pss = sockMgr.getServerSocket();
        } catch (I2PException ipe) {
            if (_log.shouldLog(Log.ERROR))
                _log.error("Error accepting - KILLING THE TUNNEL SERVER", ipe);
            open = false;
            if (i2ps != null)
                try {
                    i2ps.close();
                } catch (IOException ioe) {
                }
            break;
        } catch (ConnectException ce) {
            if (_log.shouldLog(Log.ERROR))
                _log.error("Error accepting", ce);
            open = false;
            if (i2ps != null)
                try {
                    i2ps.close();
                } catch (IOException ioe) {
                }
            break;
        } catch (SocketTimeoutException ste) {
            // ignored, we never set the timeout
            if (i2ps != null)
                try {
                    i2ps.close();
                } catch (IOException ioe) {
                }
        } catch (RuntimeException e) {
            // streaming borkage
            if (_log.shouldLog(Log.ERROR))
                _log.error("Uncaught exception accepting", e);
            if (i2ps != null)
                try {
                    i2ps.close();
                } catch (IOException ioe) {
                }
            // not killing the server..
            try {
                Thread.sleep(500);
            } catch (InterruptedException ie) {
            }
        }
    }
    if (_executor != null && !_executor.isTerminating() && !_executor.isShutdown())
        _executor.shutdownNow();
}
Also used : I2PException(net.i2p.I2PException) I2PSocket(net.i2p.client.streaming.I2PSocket) RouterRestartException(net.i2p.client.streaming.RouterRestartException) IOException(java.io.IOException) I2PServerSocket(net.i2p.client.streaming.I2PServerSocket) RejectedExecutionException(java.util.concurrent.RejectedExecutionException) SocketTimeoutException(java.net.SocketTimeoutException) ConnectException(java.net.ConnectException)

Aggregations

ConnectException (java.net.ConnectException)2 SocketTimeoutException (java.net.SocketTimeoutException)2 RouterRestartException (net.i2p.client.streaming.RouterRestartException)2 IOException (java.io.IOException)1 RejectedExecutionException (java.util.concurrent.RejectedExecutionException)1 I2PException (net.i2p.I2PException)1 I2PServerSocket (net.i2p.client.streaming.I2PServerSocket)1 I2PSocket (net.i2p.client.streaming.I2PSocket)1 Destination (net.i2p.data.Destination)1