forked from I2P_Developers/i2p.i2p
SAM: Timeout for first command after HELLO
Better removal of command and opcode from properties Send error message if no NAME key in LOOKUP
This commit is contained in:
@@ -62,12 +62,10 @@ class SAMHandlerFactory {
|
|||||||
|
|
||||||
// Message format: HELLO VERSION [MIN=v1] [MAX=v2]
|
// Message format: HELLO VERSION [MIN=v1] [MAX=v2]
|
||||||
Properties props = SAMUtils.parseParams(line);
|
Properties props = SAMUtils.parseParams(line);
|
||||||
if (!"HELLO".equals(props.getProperty(SAMUtils.COMMAND)) ||
|
if (!"HELLO".equals(props.remove(SAMUtils.COMMAND)) ||
|
||||||
!"VERSION".equals(props.getProperty(SAMUtils.OPCODE))) {
|
!"VERSION".equals(props.remove(SAMUtils.OPCODE))) {
|
||||||
throw new SAMException("Must start with HELLO VERSION");
|
throw new SAMException("Must start with HELLO VERSION");
|
||||||
}
|
}
|
||||||
props.remove(SAMUtils.COMMAND);
|
|
||||||
props.remove(SAMUtils.OPCODE);
|
|
||||||
|
|
||||||
String minVer = props.getProperty("MIN");
|
String minVer = props.getProperty("MIN");
|
||||||
if (minVer == null) {
|
if (minVer == null) {
|
||||||
|
@@ -15,6 +15,8 @@ import java.io.IOException;
|
|||||||
import java.io.InterruptedIOException;
|
import java.io.InterruptedIOException;
|
||||||
import java.net.ConnectException;
|
import java.net.ConnectException;
|
||||||
import java.net.NoRouteToHostException;
|
import java.net.NoRouteToHostException;
|
||||||
|
import java.net.Socket;
|
||||||
|
import java.net.SocketTimeoutException;
|
||||||
import java.nio.channels.SocketChannel;
|
import java.nio.channels.SocketChannel;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
@@ -48,6 +50,7 @@ class SAMv1Handler extends SAMHandler implements SAMRawReceiver, SAMDatagramRece
|
|||||||
|
|
||||||
protected final long _id;
|
protected final long _id;
|
||||||
private static final AtomicLong __id = new AtomicLong();
|
private static final AtomicLong __id = new AtomicLong();
|
||||||
|
private static final int FIRST_READ_TIMEOUT = 60*1000;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new SAM version 1 handler. This constructor expects
|
* Create a new SAM version 1 handler. This constructor expects
|
||||||
@@ -105,6 +108,7 @@ class SAMv1Handler extends SAMHandler implements SAMRawReceiver, SAMDatagramRece
|
|||||||
_log.debug("SAM handling started");
|
_log.debug("SAM handling started");
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
boolean gotFirstLine = false;
|
||||||
while (true) {
|
while (true) {
|
||||||
if (shouldStop()) {
|
if (shouldStop()) {
|
||||||
if (_log.shouldLog(Log.DEBUG))
|
if (_log.shouldLog(Log.DEBUG))
|
||||||
@@ -122,33 +126,38 @@ class SAMv1Handler extends SAMHandler implements SAMRawReceiver, SAMDatagramRece
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
buf.setLength(0);
|
buf.setLength(0);
|
||||||
// TODO set timeout first time
|
// first time, set a timeout
|
||||||
ReadLine.readLine(clientSocketChannel.socket(), buf, 0);
|
try {
|
||||||
|
Socket sock = clientSocketChannel.socket();
|
||||||
|
ReadLine.readLine(sock, buf, gotFirstLine ? 0 : FIRST_READ_TIMEOUT);
|
||||||
|
sock.setSoTimeout(0);
|
||||||
|
} catch (SocketTimeoutException ste) {
|
||||||
|
writeString("SESSION STATUS RESULT=I2P_ERROR MESSAGE=\"command timeout, bye\"\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
msg = buf.toString();
|
msg = buf.toString();
|
||||||
|
|
||||||
if (_log.shouldLog(Log.DEBUG)) {
|
if (_log.shouldLog(Log.DEBUG)) {
|
||||||
_log.debug("New message received: [" + msg + ']');
|
_log.debug("New message received: [" + msg + ']');
|
||||||
}
|
}
|
||||||
props = SAMUtils.parseParams(msg);
|
props = SAMUtils.parseParams(msg);
|
||||||
domain = props.getProperty(SAMUtils.COMMAND);
|
domain = (String) props.remove(SAMUtils.COMMAND);
|
||||||
if (domain == null) {
|
if (domain == null) {
|
||||||
if (_log.shouldLog(Log.DEBUG))
|
if (_log.shouldLog(Log.DEBUG))
|
||||||
_log.debug("Ignoring newline");
|
_log.debug("Ignoring newline");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
opcode = props.getProperty(SAMUtils.OPCODE);
|
opcode = (String) props.remove(SAMUtils.OPCODE);
|
||||||
if (opcode == null) {
|
if (opcode == null) {
|
||||||
if (_log.shouldLog(Log.DEBUG))
|
if (_log.shouldLog(Log.DEBUG))
|
||||||
_log.debug("Error in message format");
|
_log.debug("Error in message format");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
props.remove(SAMUtils.COMMAND);
|
|
||||||
props.remove(SAMUtils.OPCODE);
|
|
||||||
if (_log.shouldLog(Log.DEBUG)) {
|
if (_log.shouldLog(Log.DEBUG)) {
|
||||||
_log.debug("Parsing (domain: \"" + domain
|
_log.debug("Parsing (domain: \"" + domain
|
||||||
+ "\"; opcode: \"" + opcode + "\")");
|
+ "\"; opcode: \"" + opcode + "\")");
|
||||||
}
|
}
|
||||||
|
gotFirstLine = true;
|
||||||
if (domain.equals("STREAM")) {
|
if (domain.equals("STREAM")) {
|
||||||
canContinue = execStreamMessage(opcode, props);
|
canContinue = execStreamMessage(opcode, props);
|
||||||
} else if (domain.equals("DATAGRAM")) {
|
} else if (domain.equals("DATAGRAM")) {
|
||||||
@@ -360,16 +369,11 @@ class SAMv1Handler extends SAMHandler implements SAMRawReceiver, SAMDatagramRece
|
|||||||
/* Parse and execute a NAMING message */
|
/* Parse and execute a NAMING message */
|
||||||
protected boolean execNamingMessage(String opcode, Properties props) {
|
protected boolean execNamingMessage(String opcode, Properties props) {
|
||||||
if (opcode.equals("LOOKUP")) {
|
if (opcode.equals("LOOKUP")) {
|
||||||
if (props.isEmpty()) {
|
|
||||||
_log.debug("No parameters specified in NAMING LOOKUP message");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
String name = props.getProperty("NAME");
|
String name = props.getProperty("NAME");
|
||||||
if (name == null) {
|
if (name == null) {
|
||||||
if (_log.shouldLog(Log.DEBUG))
|
if (_log.shouldLog(Log.DEBUG))
|
||||||
_log.debug("Name to resolve not specified in NAMING message");
|
_log.debug("Name to resolve not specified in NAMING message");
|
||||||
return false;
|
return writeString("NAMING REPLY RESULT=KEY_NOT_FOUND NAME=\"\" MESSAGE=\"Must specify NAME\"\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
Destination dest = null ;
|
Destination dest = null ;
|
||||||
|
@@ -54,6 +54,7 @@ class SAMv3Handler extends SAMv1Handler
|
|||||||
private volatile boolean streamForwardingSocket;
|
private volatile boolean streamForwardingSocket;
|
||||||
private final boolean sendPorts;
|
private final boolean sendPorts;
|
||||||
private long _lastPing;
|
private long _lastPing;
|
||||||
|
private static final int FIRST_READ_TIMEOUT = 60*1000;
|
||||||
private static final int READ_TIMEOUT = 3*60*1000;
|
private static final int READ_TIMEOUT = 3*60*1000;
|
||||||
|
|
||||||
interface Session {
|
interface Session {
|
||||||
@@ -272,6 +273,7 @@ class SAMv3Handler extends SAMv1Handler
|
|||||||
InputStream in = socket.getInputStream();
|
InputStream in = socket.getInputStream();
|
||||||
|
|
||||||
StringBuilder buf = new StringBuilder(1024);
|
StringBuilder buf = new StringBuilder(1024);
|
||||||
|
boolean gotFirstLine = false;
|
||||||
while (true) {
|
while (true) {
|
||||||
if (shouldStop()) {
|
if (shouldStop()) {
|
||||||
if (_log.shouldLog(Log.DEBUG))
|
if (_log.shouldLog(Log.DEBUG))
|
||||||
@@ -329,23 +331,28 @@ class SAMv3Handler extends SAMv1Handler
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
buf.setLength(0);
|
buf.setLength(0);
|
||||||
// TODO first time, set a timeout
|
// first time, set a timeout
|
||||||
ReadLine.readLine(socket, buf, 0);
|
try {
|
||||||
|
ReadLine.readLine(socket, buf, gotFirstLine ? 0 : FIRST_READ_TIMEOUT);
|
||||||
|
socket.setSoTimeout(0);
|
||||||
|
} catch (SocketTimeoutException ste) {
|
||||||
|
writeString("SESSION STATUS RESULT=I2P_ERROR MESSAGE=\"command timeout, bye\"\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
line = buf.toString();
|
line = buf.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_log.shouldLog(Log.DEBUG))
|
if (_log.shouldLog(Log.DEBUG))
|
||||||
_log.debug("New message received: [" + line + ']');
|
_log.debug("New message received: [" + line + ']');
|
||||||
props = SAMUtils.parseParams(line);
|
props = SAMUtils.parseParams(line);
|
||||||
domain = props.getProperty(SAMUtils.COMMAND);
|
domain = (String) props.remove(SAMUtils.COMMAND);
|
||||||
if (domain == null) {
|
if (domain == null) {
|
||||||
if (_log.shouldLog(Log.DEBUG))
|
if (_log.shouldLog(Log.DEBUG))
|
||||||
_log.debug("Ignoring newline");
|
_log.debug("Ignoring newline");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
opcode = props.getProperty(SAMUtils.OPCODE);
|
gotFirstLine = true;
|
||||||
props.remove(SAMUtils.COMMAND);
|
opcode = (String) props.remove(SAMUtils.OPCODE);
|
||||||
props.remove(SAMUtils.OPCODE);
|
|
||||||
if (_log.shouldLog(Log.DEBUG)) {
|
if (_log.shouldLog(Log.DEBUG)) {
|
||||||
_log.debug("Parsing (domain: \"" + domain
|
_log.debug("Parsing (domain: \"" + domain
|
||||||
+ "\"; opcode: \"" + opcode + "\")");
|
+ "\"; opcode: \"" + opcode + "\")");
|
||||||
|
Reference in New Issue
Block a user