forked from I2P_Developers/i2p.i2p
SAM:
Version handling (ticket #1318) - MAX param now optional - 1-digit versions now accepted for MIN and MAX - Use VersionComparator for version tests - Don't require a minor version of 0 - Fix empty properties check - Overrides - Prep for version 3.1 Throw exception on null option key (ticket #1325)
This commit is contained in:
@ -17,12 +17,14 @@ import java.util.StringTokenizer;
|
||||
|
||||
import net.i2p.data.DataHelper;
|
||||
import net.i2p.util.Log;
|
||||
import net.i2p.util.VersionComparator;
|
||||
|
||||
/**
|
||||
* SAM handler factory class.
|
||||
*/
|
||||
class SAMHandlerFactory {
|
||||
|
||||
private static final String VERSION = "3.0";
|
||||
|
||||
/**
|
||||
* Return the right SAM handler depending on the protocol version
|
||||
@ -66,9 +68,8 @@ class SAMHandlerFactory {
|
||||
}
|
||||
}
|
||||
|
||||
Properties props;
|
||||
props = SAMUtils.parseParams(tok);
|
||||
if (props == null) {
|
||||
Properties props = SAMUtils.parseParams(tok);
|
||||
if (props.isEmpty()) {
|
||||
throw new SAMException("No parameters in HELLO VERSION message");
|
||||
}
|
||||
|
||||
@ -79,7 +80,9 @@ class SAMHandlerFactory {
|
||||
|
||||
String maxVer = props.getProperty("MAX");
|
||||
if (maxVer == null) {
|
||||
throw new SAMException("Missing MAX parameter in HELLO VERSION message");
|
||||
//throw new SAMException("Missing MAX parameter in HELLO VERSION message");
|
||||
// MAX optional as of 0.9.14
|
||||
maxVer = "99.99";
|
||||
}
|
||||
|
||||
String ver = chooseBestVersion(minVer, maxVer);
|
||||
@ -119,30 +122,28 @@ class SAMHandlerFactory {
|
||||
return handler;
|
||||
}
|
||||
|
||||
/* Return the best version we can use, or null on failure */
|
||||
/*
|
||||
* @return "x.y" the best version we can use, or null on failure
|
||||
*/
|
||||
private static String chooseBestVersion(String minVer, String maxVer) {
|
||||
|
||||
int minMajor = getMajor(minVer), minMinor = getMinor(minVer);
|
||||
int maxMajor = getMajor(maxVer), maxMinor = getMinor(maxVer);
|
||||
|
||||
// Consistency checks
|
||||
if ((minMajor == -1) || (minMinor == -1)
|
||||
|| (maxMajor == -1) || (maxMinor == -1)) {
|
||||
return null;
|
||||
// in VersionComparator, "3" < "3.0" so
|
||||
// use comparisons carefully
|
||||
if (VersionComparator.comp("3.0", minVer) >= 0) {
|
||||
// Documentation said:
|
||||
// In order to force protocol version 3.0, the values of $min and $max
|
||||
// must be "3.0".
|
||||
int maxcomp = VersionComparator.comp("3", maxVer);
|
||||
if (maxcomp == 0 || maxVer.equals("3.0"))
|
||||
return "3.0"; // spoof version
|
||||
if (maxcomp < 0)
|
||||
return VERSION;
|
||||
}
|
||||
|
||||
if ((minMinor >= 10) || (maxMinor >= 10)) return null ;
|
||||
|
||||
float fminVer = minMajor + (float) minMinor / 10 ;
|
||||
float fmaxVer = maxMajor + (float) maxMinor / 10 ;
|
||||
|
||||
|
||||
if ( ( fminVer <= 3.0 ) && ( fmaxVer >= 3.0 ) ) return "3.0" ;
|
||||
|
||||
if ( ( fminVer <= 2.0 ) && ( fmaxVer >= 2.0 ) ) return "2.0" ;
|
||||
|
||||
if ( ( fminVer <= 1.0 ) && ( fmaxVer >= 1.0 ) ) return "1.0" ;
|
||||
|
||||
if (VersionComparator.comp("2.0", minVer) >= 0 &&
|
||||
VersionComparator.comp("2", maxVer) <= 0)
|
||||
return "2.0";
|
||||
if (VersionComparator.comp("1.0", minVer) >= 0 &&
|
||||
VersionComparator.comp("1", maxVer) <= 0)
|
||||
return "1.0";
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -159,26 +159,34 @@ class SAMUtils {
|
||||
* @param tok A StringTokenizer pointing to the SAM parameters
|
||||
*
|
||||
* @throws SAMException if the data was formatted incorrectly
|
||||
* @return Properties with the parsed SAM params
|
||||
* @return Properties with the parsed SAM params, never null
|
||||
*/
|
||||
public static Properties parseParams(StringTokenizer tok) throws SAMException {
|
||||
int pos, ntoks = tok.countTokens();
|
||||
String token, param;
|
||||
int ntoks = tok.countTokens();
|
||||
Properties props = new Properties();
|
||||
|
||||
StringBuilder value = new StringBuilder();
|
||||
for (int i = 0; i < ntoks; ++i) {
|
||||
token = tok.nextToken();
|
||||
String token = tok.nextToken();
|
||||
|
||||
pos = token.indexOf("=");
|
||||
if (pos == -1) {
|
||||
int pos = token.indexOf("=");
|
||||
if (pos <= 0) {
|
||||
//_log.debug("Error in params format");
|
||||
if (pos == 0) {
|
||||
throw new SAMException("No param specified [" + token + "]");
|
||||
} else {
|
||||
throw new SAMException("Bad formatting for param [" + token + "]");
|
||||
}
|
||||
param = token.substring(0, pos);
|
||||
}
|
||||
|
||||
String param = token.substring(0, pos);
|
||||
value.append(token.substring(pos+1));
|
||||
if (value.length() == 0)
|
||||
throw new SAMException("Empty value for param " + param);
|
||||
|
||||
// FIXME: The following code does not take into account that there
|
||||
// may have been multiple subsequent space chars in the input that
|
||||
// StringTokenizer treates as one.
|
||||
if (value.charAt(0) == '"') {
|
||||
while ( (i < ntoks) && (value.lastIndexOf("\"") <= 0) ) {
|
||||
value.append(' ').append(tok.nextToken());
|
||||
|
@ -86,7 +86,7 @@ class SAMv1Handler extends SAMHandler implements SAMRawReceiver, SAMDatagramRece
|
||||
}
|
||||
|
||||
public boolean verifVersion() {
|
||||
return ( verMajor == 1 && verMinor == 0 ) ;
|
||||
return (verMajor == 1);
|
||||
}
|
||||
|
||||
public void handle() {
|
||||
|
@ -55,9 +55,10 @@ class SAMv2Handler extends SAMv1Handler implements SAMRawReceiver, SAMDatagramRe
|
||||
super ( s, verMajor, verMinor, i2cpProps );
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean verifVersion()
|
||||
{
|
||||
return (verMajor == 2 && verMinor == 0) ;
|
||||
return (verMajor == 2);
|
||||
}
|
||||
|
||||
SAMStreamSession newSAMStreamSession(String destKeystream, String direction, Properties props )
|
||||
|
@ -88,9 +88,10 @@ class SAMv3Handler extends SAMv1Handler
|
||||
_log.debug("SAM version 3 handler instantiated");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean verifVersion()
|
||||
{
|
||||
return (verMajor == 3 && verMinor == 0) ;
|
||||
return (verMajor == 3);
|
||||
}
|
||||
|
||||
public static class DatagramServer {
|
||||
|
Reference in New Issue
Block a user