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) {
}
}
}
}
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);
}
}
}
}
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");
}
Aggregations