i2ptunnel: Add timeout to header reads for CONNECT, HTTP, and SOCKS client proxies

Clean up SOCKS exceptions
This commit is contained in:
zzz
2017-11-23 17:44:03 +00:00
parent 2a2795827a
commit 6cd5f1d83b
9 changed files with 51 additions and 16 deletions

View File

@ -155,6 +155,7 @@ public class I2PTunnelConnectClient extends I2PTunnelHTTPClientBase implements R
Outproxy outproxy = null;
long requestId = __requestId.incrementAndGet();
try {
s.setSoTimeout(INITIAL_SO_TIMEOUT);
out = s.getOutputStream();
in = s.getInputStream();
String line, method = null, host = null, destination = null, restofline = null;
@ -283,6 +284,7 @@ public class I2PTunnelConnectClient extends I2PTunnelHTTPClientBase implements R
}
}
newRequest.append("\r\n"); // HTTP spec
s.setSoTimeout(0);
// do it
break;
}

View File

@ -393,6 +393,7 @@ public class I2PTunnelHTTPClient extends I2PTunnelHTTPClientBase implements Runn
boolean shout = false;
try {
s.setSoTimeout(INITIAL_SO_TIMEOUT);
out = s.getOutputStream();
InputReader reader = new InputReader(s.getInputStream());
String line, method = null, protocol = null, host = null, destination = null;
@ -1040,6 +1041,7 @@ public class I2PTunnelHTTPClient extends I2PTunnelHTTPClientBase implements Runn
}
}
newRequest.append("Connection: close\r\n\r\n");
s.setSoTimeout(0);
break;
} else {
newRequest.append(line).append("\r\n"); // HTTP spec

View File

@ -13,6 +13,7 @@ import java.io.Reader;
import java.io.UnsupportedEncodingException;
import java.io.Writer;
import java.net.Socket;
import java.net.SocketTimeoutException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
@ -61,6 +62,13 @@ public abstract class I2PTunnelHTTPClientBase extends I2PTunnelClientBase implem
private static final int MAX_NONCE_COUNT = 1024;
/** @since 0.9.11, moved to Base in 0.9.29 */
public static final String PROP_USE_OUTPROXY_PLUGIN = "i2ptunnel.useLocalOutproxy";
/**
* This is a standard soTimeout, not a total timeout.
* We have no slowloris protection on the client side.
* See I2PTunnelHTTPServer or SAM's ReadLine if we need that.
* @since 0.9.33
*/
protected static final int INITIAL_SO_TIMEOUT = 15*1000;
private static final String ERR_AUTH1 =
"HTTP/1.1 407 Proxy Authentication Required\r\n" +
@ -610,7 +618,9 @@ public abstract class I2PTunnelHTTPClientBase extends I2PTunnelClientBase implem
if (out == null)
return;
String header;
if (usingWWWProxy)
if (ex instanceof SocketTimeoutException)
header = I2PTunnelHTTPServer.ERR_REQUEST_TIMEOUT;
else if (usingWWWProxy)
header = getErrorPage(I2PAppContext.getGlobalContext(), "dnfp", ERR_DESTINATION_UNKNOWN);
else
header = getErrorPage(I2PAppContext.getGlobalContext(), "dnf", ERR_DESTINATION_UNKNOWN);

View File

@ -156,7 +156,8 @@ public class I2PTunnelHTTPServer extends I2PTunnelServer {
"<body><h2>431 Request header fields too large</h2>\n" +
"</body></html>";
private final static String ERR_REQUEST_TIMEOUT =
/** @since protected since 0.9.33 for I2PTunnelHTTPClientBase, was private */
protected final static String ERR_REQUEST_TIMEOUT =
"HTTP/1.1 408 Request timeout\r\n"+
"Content-Type: text/html; charset=iso-8859-1\r\n"+
"Cache-control: no-cache\r\n"+

View File

@ -7,6 +7,7 @@
package net.i2p.i2ptunnel.socks;
import java.net.Socket;
import java.net.SocketException;
import java.util.concurrent.atomic.AtomicInteger;
import net.i2p.client.streaming.I2PSocket;
@ -48,8 +49,14 @@ public class I2PSOCKSIRCTunnel extends I2PSOCKSTunnel {
protected void clientConnectionRun(Socket s) {
try {
//_log.error("SOCKS IRC Tunnel Start");
try {
s.setSoTimeout(INITIAL_SO_TIMEOUT);
} catch (SocketException ioe) {}
SOCKSServer serv = SOCKSServerFactory.createSOCKSServer(_context, s, getTunnel().getClientOptions());
Socket clientSock = serv.getClientSocket();
try {
s.setSoTimeout(0);
} catch (SocketException ioe) {}
I2PSocket destSock = serv.getDestinationI2PSocket(this);
StringBuffer expectedPong = new StringBuffer();
int id = __clientId.incrementAndGet();

View File

@ -7,6 +7,7 @@
package net.i2p.i2ptunnel.socks;
import java.net.Socket;
import java.net.SocketException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
@ -27,6 +28,14 @@ import net.i2p.util.Log;
public class I2PSOCKSTunnel extends I2PTunnelClientBase {
/**
* This is a standard soTimeout, not a total timeout.
* We have no slowloris protection on the client side.
* See I2PTunnelHTTPServer or SAM's ReadLine if we need that.
* @since 0.9.33
*/
protected static final int INITIAL_SO_TIMEOUT = 15*1000;
private HashMap<String, List<String>> proxies = null; // port# + "" or "default" -> hostname list
//public I2PSOCKSTunnel(int localPort, Logging l, boolean ownDest) {
@ -49,8 +58,14 @@ public class I2PSOCKSTunnel extends I2PTunnelClientBase {
protected void clientConnectionRun(Socket s) {
try {
try {
s.setSoTimeout(INITIAL_SO_TIMEOUT);
} catch (SocketException ioe) {}
SOCKSServer serv = SOCKSServerFactory.createSOCKSServer(_context, s, getTunnel().getClientOptions());
Socket clientSock = serv.getClientSocket();
try {
s.setSoTimeout(0);
} catch (SocketException ioe) {}
I2PSocket destSock = serv.getDestinationI2PSocket(this);
Thread t = new I2PTunnelRunner(clientSock, destSock, sockLock, null, null, mySockets,
(I2PTunnelRunner.FailCallback) null);

View File

@ -71,7 +71,7 @@ class SOCKS4aServer extends SOCKSServer {
manageRequest(in, out);
} catch (IOException e) {
throw new SOCKSException("Connection error (" + e.getMessage() + ")");
throw new SOCKSException("Connection error", e);
}
setupCompleted = true;
@ -150,7 +150,7 @@ class SOCKS4aServer extends SOCKSServer {
sendRequestReply(Reply.SUCCEEDED, InetAddress.getByName("127.0.0.1"), 1, out);
} catch (IOException e) {
throw new SOCKSException("Connection error (" + e.getMessage() + ")");
throw new SOCKSException("Connection error", e);
}
}
@ -201,7 +201,7 @@ class SOCKS4aServer extends SOCKSServer {
try {
out = new DataOutputStream(clientSock.getOutputStream());
} catch (IOException e) {
throw new SOCKSException("Connection error (" + e.getMessage() + ")");
throw new SOCKSException("Connection error", e);
}
// FIXME: here we should read our config file, select an
@ -286,19 +286,17 @@ class SOCKS4aServer extends SOCKSServer {
try {
sendRequestReply(Reply.CONNECTION_REFUSED, InetAddress.getByName("127.0.0.1"), 0, out);
} catch (IOException ioe) {}
throw new SOCKSException("Error in destination format");
throw new SOCKSException("Error in destination format", e);
} catch (IOException e) {
try {
sendRequestReply(Reply.CONNECTION_REFUSED, InetAddress.getByName("127.0.0.1"), 0, out);
} catch (IOException ioe) {}
throw new SOCKSException("Error connecting ("
+ e.getMessage() + ")");
throw new SOCKSException("Error connecting", e);
} catch (I2PException e) {
try {
sendRequestReply(Reply.CONNECTION_REFUSED, InetAddress.getByName("127.0.0.1"), 0, out);
} catch (IOException ioe) {}
throw new SOCKSException("Error connecting ("
+ e.getMessage() + ")");
throw new SOCKSException("Error connecting", e);
}
return destSock;

View File

@ -87,7 +87,7 @@ class SOCKS5Server extends SOCKSServer {
if (manageRequest(in, out) == Command.UDP_ASSOCIATE)
handleUDP(in, out);
} catch (IOException e) {
throw new SOCKSException("Connection error: " + e);
throw new SOCKSException("Connection error", e);
}
setupCompleted = true;
@ -267,7 +267,7 @@ class SOCKS5Server extends SOCKSServer {
sendRequestReply(Reply.SUCCEEDED, AddressType.IPV4, InetAddress.getByName("127.0.0.1"), null, 1, out);
} catch (IOException e) {
throw new SOCKSException("Connection error: " + e);
throw new SOCKSException("Connection error", e);
}
}
@ -360,7 +360,7 @@ class SOCKS5Server extends SOCKSServer {
try {
out = new DataOutputStream(clientSock.getOutputStream());
} catch (IOException e) {
throw new SOCKSException("Connection error: " + e);
throw new SOCKSException("Connection error", e);
}
// FIXME: here we should read our config file, select an
@ -457,14 +457,14 @@ class SOCKS5Server extends SOCKSServer {
try {
sendRequestReply(Reply.HOST_UNREACHABLE, AddressType.DOMAINNAME, null, "0.0.0.0", 0, out);
} catch (IOException ioe) {}
throw new SOCKSException("Error connecting: " + e);
throw new SOCKSException("Connection error", e);
} catch (I2PException e) {
if (_log.shouldLog(Log.WARN))
_log.warn("socks error", e);
try {
sendRequestReply(Reply.HOST_UNREACHABLE, AddressType.DOMAINNAME, null, "0.0.0.0", 0, out);
} catch (IOException ioe) {}
throw new SOCKSException("Error connecting: " + e);
throw new SOCKSException("Connection error", e);
}
return destSock;

View File

@ -73,7 +73,7 @@ class SOCKSServerFactory {
}
} catch (IOException e) {
//_log.debug("error reading SOCKS protocol version");
throw new SOCKSException("Connection error (" + e.getMessage() + ")");
throw new SOCKSException("Connection error", e);
}
return serv;