Search in sources :

Example 1 with InternalSocket

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

the class I2PTunnelRunner method run.

@Override
public void run() {
    boolean i2pReset = false;
    boolean sockReset = false;
    InputStream in = null;
    OutputStream out = null;
    InputStream i2pin = null;
    OutputStream i2pout = null;
    StreamForwarder toI2P = null;
    StreamForwarder fromI2P = null;
    try {
        in = getSocketIn();
        // = new BufferedOutputStream(s.getOutputStream(), NETWORK_BUFFER_SIZE);
        out = getSocketOut();
        // unimplemented in streaming
        // i2ps.setSocketErrorListener(this);
        i2pin = i2ps.getInputStream();
        // new BufferedOutputStream(i2ps.getOutputStream(), MAX_PACKET_SIZE);
        i2pout = i2ps.getOutputStream();
        if (initialI2PData != null) {
            // why synchronize this? we could be in here a LONG time for large initial data
            // synchronized (slock) {
            // this does not increment totalSent
            i2pout.write(initialI2PData);
            // only flush if it fits in one message.
            if (initialI2PData.length <= 1730) {
                // Don't flush if POST, so we can get POST data into the initial packet
                if (initialI2PData.length < 5 || !DataHelper.eq(POST, 0, initialI2PData, 0, 5))
                    i2pout.flush();
            }
        // }
        }
        if (initialSocketData != null) {
            // this does not increment totalReceived
            out.write(initialSocketData);
        }
        if (_log.shouldLog(Log.DEBUG))
            _log.debug("Initial data " + (initialI2PData != null ? initialI2PData.length : 0) + " written to I2P, " + (initialSocketData != null ? initialSocketData.length : 0) + " written to the socket, starting forwarders");
        if (!(s instanceof InternalSocket))
            in = new BufferedInputStream(in, 2 * NETWORK_BUFFER_SIZE);
        toI2P = new StreamForwarder(in, i2pout, true);
        fromI2P = new StreamForwarder(i2pin, out, false);
        toI2P.start();
        // We are already a thread, so run the second one inline
        // fromI2P.start();
        fromI2P.run();
        synchronized (finishLock) {
            while (!finished) {
                finishLock.wait();
            }
        }
        if (_log.shouldLog(Log.DEBUG))
            _log.debug("At least one forwarder completed, closing and joining");
        // this task is useful for the httpclient
        if ((onTimeout != null || _onFail != null) && totalReceived <= 0) {
            if (_log.shouldLog(Log.DEBUG))
                _log.debug("runner has a timeout job, totalReceived = " + totalReceived + " totalSent = " + totalSent + " job = " + onTimeout);
            // HTTPClient never sets initialSocketData.
            if (_onFail != null) {
                Exception e = fromI2P.getFailure();
                if (e == null)
                    e = toI2P.getFailure();
                _onFail.onFail(e);
            } else {
                onTimeout.run();
            }
        } else {
            // Detect a reset on one side, and propagate to the other
            Exception e1 = fromI2P.getFailure();
            Exception e2 = toI2P.getFailure();
            Throwable c1 = e1 != null ? e1.getCause() : null;
            Throwable c2 = e2 != null ? e2.getCause() : null;
            if (c1 != null && c1 instanceof I2PSocketException) {
                I2PSocketException ise = (I2PSocketException) c1;
                int status = ise.getStatus();
                i2pReset = status == I2PSocketException.STATUS_CONNECTION_RESET;
            }
            if (!i2pReset && c2 != null && c2 instanceof I2PSocketException) {
                I2PSocketException ise = (I2PSocketException) c2;
                int status = ise.getStatus();
                i2pReset = status == I2PSocketException.STATUS_CONNECTION_RESET;
            }
            if (!i2pReset && e1 != null && e1 instanceof SocketException) {
                String msg = e1.getMessage();
                sockReset = msg != null && msg.contains("reset");
            }
            if (!sockReset && e2 != null && e2 instanceof SocketException) {
                String msg = e2.getMessage();
                sockReset = msg != null && msg.contains("reset");
            }
        }
    } catch (InterruptedException ex) {
        if (_log.shouldLog(Log.ERROR))
            _log.error("Interrupted", ex);
    } catch (SSLException she) {
        _log.error("SSL error", she);
    } catch (IOException ex) {
        if (_log.shouldLog(Log.DEBUG))
            _log.debug("Error forwarding", ex);
    } catch (IllegalStateException ise) {
        // at net.i2p.i2ptunnel.I2PTunnelRunner.run(I2PTunnelRunner.java:167)
        if (_log.shouldLog(Log.WARN))
            _log.warn("gnu?", ise);
    } catch (RuntimeException e) {
        if (_log.shouldLog(Log.ERROR))
            _log.error("Internal error", e);
    } finally {
        removeRef();
        if (i2pReset) {
            if (_log.shouldWarn())
                _log.warn("Got I2P reset, resetting socket");
            try {
                s.setSoLinger(true, 0);
            } catch (IOException ioe) {
            }
            try {
                s.close();
            } catch (IOException ioe) {
            }
            try {
                i2ps.close();
            } catch (IOException ioe) {
            }
        } else if (sockReset) {
            if (_log.shouldWarn())
                _log.warn("Got socket reset, resetting I2P socket");
            try {
                i2ps.reset();
            } catch (IOException ioe) {
            }
            try {
                s.close();
            } catch (IOException ioe) {
            }
        } else {
            // now one connection is dead - kill the other as well, after making sure we flush
            try {
                close(out, in, i2pout, i2pin, s, i2ps, toI2P, fromI2P);
            } catch (InterruptedException ie) {
            }
        }
    }
}
Also used : I2PSocketException(net.i2p.client.streaming.I2PSocketException) SocketException(java.net.SocketException) BufferedInputStream(java.io.BufferedInputStream) InputStream(java.io.InputStream) OutputStream(java.io.OutputStream) IOException(java.io.IOException) InterruptedIOException(java.io.InterruptedIOException) I2PSocketException(net.i2p.client.streaming.I2PSocketException) SSLException(javax.net.ssl.SSLException) IOException(java.io.IOException) InterruptedIOException(java.io.InterruptedIOException) I2PSocketException(net.i2p.client.streaming.I2PSocketException) SocketException(java.net.SocketException) SSLException(javax.net.ssl.SSLException) InternalSocket(net.i2p.util.InternalSocket) BufferedInputStream(java.io.BufferedInputStream)

Example 2 with InternalSocket

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

the class I2PTunnelOutproxyRunner method run.

@Override
public void run() {
    try {
        InputStream in = getSocketIn();
        OutputStream out = getSocketOut();
        InputStream i2pin = i2ps.getInputStream();
        OutputStream i2pout = i2ps.getOutputStream();
        if (initialI2PData != null) {
            i2pout.write(initialI2PData);
            i2pout.flush();
        }
        if (initialSocketData != null) {
            // this does not increment totalReceived
            out.write(initialSocketData);
        }
        if (_log.shouldLog(Log.DEBUG))
            _log.debug("Initial data " + (initialI2PData != null ? initialI2PData.length : 0) + " written to the outproxy, " + (initialSocketData != null ? initialSocketData.length : 0) + " written to the socket, starting forwarders");
        if (!(s instanceof InternalSocket))
            in = new BufferedInputStream(in, 2 * NETWORK_BUFFER_SIZE);
        Thread t1 = new StreamForwarder(in, i2pout, true);
        Thread t2 = new StreamForwarder(i2pin, out, false);
        // TODO can we run one of these inline and save a thread?
        t1.start();
        t2.start();
        synchronized (finishLock) {
            while (!finished) {
                finishLock.wait();
            }
        }
        if (_log.shouldLog(Log.DEBUG))
            _log.debug("At least one forwarder completed, closing and joining");
        // this task is useful for the httpclient
        if (onTimeout != null) {
            if (_log.shouldLog(Log.DEBUG))
                _log.debug("runner has a timeout job, totalReceived = " + totalReceived + " totalSent = " + totalSent + " job = " + onTimeout);
            // Run even if totalSent > 0, as that's probably POST data.
            if (totalReceived <= 0)
                onTimeout.onFail(null);
        }
        // now one connection is dead - kill the other as well, after making sure we flush
        close(out, in, i2pout, i2pin, s, i2ps, t1, t2);
    } catch (InterruptedException ex) {
        if (_log.shouldLog(Log.ERROR))
            _log.error("Interrupted", ex);
    } catch (SSLException she) {
        _log.error("SSL error", she);
    } catch (IOException ex) {
        if (_log.shouldLog(Log.DEBUG))
            _log.debug("Error forwarding", ex);
    } catch (IllegalStateException ise) {
        if (_log.shouldLog(Log.WARN))
            _log.warn("gnu?", ise);
    } catch (RuntimeException e) {
        if (_log.shouldLog(Log.ERROR))
            _log.error("Internal error", e);
    } finally {
        try {
            if (s != null)
                s.close();
        } catch (IOException ex) {
            if (_log.shouldLog(Log.WARN))
                _log.warn("Could not close java socket", ex);
        }
        if (i2ps != null) {
            try {
                i2ps.close();
            } catch (IOException ex) {
                if (_log.shouldLog(Log.WARN))
                    _log.warn("Could not close Socket", ex);
            }
        }
    }
}
Also used : InternalSocket(net.i2p.util.InternalSocket) BufferedInputStream(java.io.BufferedInputStream) BufferedInputStream(java.io.BufferedInputStream) InputStream(java.io.InputStream) OutputStream(java.io.OutputStream) IOException(java.io.IOException) InterruptedIOException(java.io.InterruptedIOException) SSLException(javax.net.ssl.SSLException) I2PAppThread(net.i2p.util.I2PAppThread)

Example 3 with InternalSocket

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

the class EepGet method sendRequest.

/**
 *  @param timeout may be null
 */
protected void sendRequest(SocketTimeout timeout) throws IOException {
    if (_outputStream != null) {
    // We are reading into a stream supplied by a caller,
    // for which we cannot easily determine how much we've written.
    // Assume that _alreadyTransferred holds the right value
    // (we should never be restarted to work on an old stream).
    } else {
        File outFile = new File(_outputFile);
        if (outFile.exists())
            _alreadyTransferred = outFile.length();
    }
    String req = getRequest();
    if (_proxyIn != null)
        try {
            _proxyIn.close();
        } catch (IOException ioe) {
        }
    if (_proxyOut != null)
        try {
            _proxyOut.close();
        } catch (IOException ioe) {
        }
    if (_proxy != null)
        try {
            _proxy.close();
        } catch (IOException ioe) {
        }
    if (_shouldProxy) {
        _proxy = InternalSocket.getSocket(_proxyHost, _proxyPort);
    } else {
        try {
            URI url = new URI(_actualURL);
            if ("http".equals(url.getScheme())) {
                String host = url.getHost();
                if (host == null)
                    throw new MalformedURLException("URL is not supported:" + _actualURL);
                String hostlc = host.toLowerCase(Locale.US);
                if (hostlc.endsWith(".i2p"))
                    throw new UnknownHostException("I2P addresses must be proxied");
                if (hostlc.endsWith(".onion"))
                    throw new UnknownHostException("Tor addresses must be proxied");
                int port = url.getPort();
                if (port == -1)
                    port = 80;
                if (_fetchHeaderTimeout > 0) {
                    _proxy = new Socket();
                    _proxy.setSoTimeout(_fetchHeaderTimeout);
                    _proxy.connect(new InetSocketAddress(host, port), _fetchHeaderTimeout);
                } else {
                    _proxy = new Socket(host, port);
                }
            } else {
                throw new MalformedURLException("URL is not supported:" + _actualURL);
            }
        } catch (URISyntaxException use) {
            IOException ioe = new MalformedURLException("Request URL is invalid");
            ioe.initCause(use);
            throw ioe;
        }
    }
    _proxyIn = _proxy.getInputStream();
    if (!(_proxy instanceof InternalSocket))
        _proxyIn = new BufferedInputStream(_proxyIn);
    _proxyOut = _proxy.getOutputStream();
    if (timeout != null)
        timeout.setSocket(_proxy);
    _proxyOut.write(DataHelper.getUTF8(req));
    _proxyOut.flush();
    if (_log.shouldLog(Log.DEBUG))
        _log.debug("Request flushed");
}
Also used : InternalSocket(net.i2p.util.InternalSocket) MalformedURLException(java.net.MalformedURLException) UnknownHostException(java.net.UnknownHostException) BufferedInputStream(java.io.BufferedInputStream) InetSocketAddress(java.net.InetSocketAddress) IOException(java.io.IOException) URISyntaxException(java.net.URISyntaxException) File(java.io.File) URI(java.net.URI) Socket(java.net.Socket) InternalSocket(net.i2p.util.InternalSocket)

Aggregations

BufferedInputStream (java.io.BufferedInputStream)3 IOException (java.io.IOException)3 InternalSocket (net.i2p.util.InternalSocket)3 InputStream (java.io.InputStream)2 InterruptedIOException (java.io.InterruptedIOException)2 OutputStream (java.io.OutputStream)2 SSLException (javax.net.ssl.SSLException)2 File (java.io.File)1 InetSocketAddress (java.net.InetSocketAddress)1 MalformedURLException (java.net.MalformedURLException)1 Socket (java.net.Socket)1 SocketException (java.net.SocketException)1 URI (java.net.URI)1 URISyntaxException (java.net.URISyntaxException)1 UnknownHostException (java.net.UnknownHostException)1 I2PSocketException (net.i2p.client.streaming.I2PSocketException)1 I2PAppThread (net.i2p.util.I2PAppThread)1