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]
|
||||
Properties props = SAMUtils.parseParams(line);
|
||||
if (!"HELLO".equals(props.getProperty(SAMUtils.COMMAND)) ||
|
||||
!"VERSION".equals(props.getProperty(SAMUtils.OPCODE))) {
|
||||
if (!"HELLO".equals(props.remove(SAMUtils.COMMAND)) ||
|
||||
!"VERSION".equals(props.remove(SAMUtils.OPCODE))) {
|
||||
throw new SAMException("Must start with HELLO VERSION");
|
||||
}
|
||||
props.remove(SAMUtils.COMMAND);
|
||||
props.remove(SAMUtils.OPCODE);
|
||||
|
||||
String minVer = props.getProperty("MIN");
|
||||
if (minVer == null) {
|
||||
|
@ -15,6 +15,8 @@ import java.io.IOException;
|
||||
import java.io.InterruptedIOException;
|
||||
import java.net.ConnectException;
|
||||
import java.net.NoRouteToHostException;
|
||||
import java.net.Socket;
|
||||
import java.net.SocketTimeoutException;
|
||||
import java.nio.channels.SocketChannel;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.Properties;
|
||||
@ -48,6 +50,7 @@ class SAMv1Handler extends SAMHandler implements SAMRawReceiver, SAMDatagramRece
|
||||
|
||||
protected final long _id;
|
||||
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
|
||||
@ -105,6 +108,7 @@ class SAMv1Handler extends SAMHandler implements SAMRawReceiver, SAMDatagramRece
|
||||
_log.debug("SAM handling started");
|
||||
|
||||
try {
|
||||
boolean gotFirstLine = false;
|
||||
while (true) {
|
||||
if (shouldStop()) {
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
@ -122,33 +126,38 @@ class SAMv1Handler extends SAMHandler implements SAMRawReceiver, SAMDatagramRece
|
||||
break;
|
||||
}
|
||||
buf.setLength(0);
|
||||
// TODO set timeout first time
|
||||
ReadLine.readLine(clientSocketChannel.socket(), buf, 0);
|
||||
// first time, set a timeout
|
||||
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();
|
||||
|
||||
if (_log.shouldLog(Log.DEBUG)) {
|
||||
_log.debug("New message received: [" + msg + ']');
|
||||
}
|
||||
props = SAMUtils.parseParams(msg);
|
||||
domain = props.getProperty(SAMUtils.COMMAND);
|
||||
domain = (String) props.remove(SAMUtils.COMMAND);
|
||||
if (domain == null) {
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("Ignoring newline");
|
||||
continue;
|
||||
}
|
||||
opcode = props.getProperty(SAMUtils.OPCODE);
|
||||
opcode = (String) props.remove(SAMUtils.OPCODE);
|
||||
if (opcode == null) {
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("Error in message format");
|
||||
break;
|
||||
}
|
||||
props.remove(SAMUtils.COMMAND);
|
||||
props.remove(SAMUtils.OPCODE);
|
||||
if (_log.shouldLog(Log.DEBUG)) {
|
||||
_log.debug("Parsing (domain: \"" + domain
|
||||
+ "\"; opcode: \"" + opcode + "\")");
|
||||
}
|
||||
|
||||
gotFirstLine = true;
|
||||
if (domain.equals("STREAM")) {
|
||||
canContinue = execStreamMessage(opcode, props);
|
||||
} else if (domain.equals("DATAGRAM")) {
|
||||
@ -360,16 +369,11 @@ class SAMv1Handler extends SAMHandler implements SAMRawReceiver, SAMDatagramRece
|
||||
/* Parse and execute a NAMING message */
|
||||
protected boolean execNamingMessage(String opcode, Properties props) {
|
||||
if (opcode.equals("LOOKUP")) {
|
||||
if (props.isEmpty()) {
|
||||
_log.debug("No parameters specified in NAMING LOOKUP message");
|
||||
return false;
|
||||
}
|
||||
|
||||
String name = props.getProperty("NAME");
|
||||
if (name == null) {
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_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 ;
|
||||
|
@ -54,6 +54,7 @@ class SAMv3Handler extends SAMv1Handler
|
||||
private volatile boolean streamForwardingSocket;
|
||||
private final boolean sendPorts;
|
||||
private long _lastPing;
|
||||
private static final int FIRST_READ_TIMEOUT = 60*1000;
|
||||
private static final int READ_TIMEOUT = 3*60*1000;
|
||||
|
||||
interface Session {
|
||||
@ -272,6 +273,7 @@ class SAMv3Handler extends SAMv1Handler
|
||||
InputStream in = socket.getInputStream();
|
||||
|
||||
StringBuilder buf = new StringBuilder(1024);
|
||||
boolean gotFirstLine = false;
|
||||
while (true) {
|
||||
if (shouldStop()) {
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
@ -329,23 +331,28 @@ class SAMv3Handler extends SAMv1Handler
|
||||
}
|
||||
} else {
|
||||
buf.setLength(0);
|
||||
// TODO first time, set a timeout
|
||||
ReadLine.readLine(socket, buf, 0);
|
||||
// first time, set a timeout
|
||||
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();
|
||||
}
|
||||
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("New message received: [" + line + ']');
|
||||
props = SAMUtils.parseParams(line);
|
||||
domain = props.getProperty(SAMUtils.COMMAND);
|
||||
domain = (String) props.remove(SAMUtils.COMMAND);
|
||||
if (domain == null) {
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("Ignoring newline");
|
||||
continue;
|
||||
}
|
||||
opcode = props.getProperty(SAMUtils.OPCODE);
|
||||
props.remove(SAMUtils.COMMAND);
|
||||
props.remove(SAMUtils.OPCODE);
|
||||
gotFirstLine = true;
|
||||
opcode = (String) props.remove(SAMUtils.OPCODE);
|
||||
if (_log.shouldLog(Log.DEBUG)) {
|
||||
_log.debug("Parsing (domain: \"" + domain
|
||||
+ "\"; opcode: \"" + opcode + "\")");
|
||||
|
Reference in New Issue
Block a user