SAMv3 : protocol better specified, and small changes in the code reflecting the new protocol

This commit is contained in:
mkvore-commit
2009-04-05 21:32:43 +00:00
parent 2cf5221620
commit 6b825fbe25
11 changed files with 180 additions and 121 deletions

View File

@ -23,7 +23,7 @@ sess = socket.socket(
sess.connect(("127.0.0.1",7656));
sess.send("HELLO VERSION MIN=3.0 MAX=3.0\n")
sys.stdout.write(sess.recv(1000))
sess.send("SESSION CREATE STYLE=DATAGRAM PORT="+str(port)+" ID="+name+" DESTINATION=EYUpJFeW9tiubXR0aOjvCJ~ndj3xN0Wn-ljuGdbpOEttPg7nj0VCTOQDJ~FAolzn9FIDdmR3VjM0OFFDT46Q5HN4vShXFE2VNC8e3~GjzxJfaJhijRC2R9oIOzsNlzKtInD2o9lh0PxPioNMCigwmgWuqlQHs4tjWeaYRAtooHxbrtuoCIhIdGfyVV-nAcPiyYbouKq3leETXE~4kBXm-LfWfyPtrv6OuDk3GBVVcthv19GYBmnl2YI8HpJjc-G-TvNkgYishjzIJyEW-Xrpy43R4ZBXlyQqnheGLlbOEY8NLDbyNHLRMMOGbcr~67SVE3Iw3RqQ3Dhrkq2FCaQwcDucfIUCCbOfCZgu0hlnCkS42xsUvegQeiwMxbdI~h9v7vcR3yFFOrHX6WQvIZSbFLKNGArGJcfmOJVLqw1wTC4AgYXjk3csVDPd-QWbMXOuodyBgrg27Ds2BBYTsVXWskoo6ASsMIQZ6jMfL7PkY9dPLCRParIyzb9aPmf~MntNAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABHNqwgkhJnBW4ymaRsdVmITAha-ff0UiALfKSlznqp5HcSewgMHbzQ0I01TQytFnW\n")
sess.send("SESSION CREATE STYLE=DATAGRAM PORT="+str(port)+" ID="+name+" DESTINATION=EYUpJFeW9tiubXR0aOjvCJ~ndj3xN0Wn-ljuGdbpOEttPg7nj0VCTOQDJ~FAolzn9FIDdmR3VjM0OFFDT46Q5HN4vShXFE2VNC8e3~GjzxJfaJhijRC2R9oIOzsNlzKtInD2o9lh0PxPioNMCigwmgWuqlQHs4tjWeaYRAtooHxbrtuoCIhIdGfyVV-nAcPiyYbouKq3leETXE~4kBXm-LfWfyPtrv6OuDk3GBVVcthv19GYBmnl2YI8HpJjc-G-TvNkgYishjzIJyEW-Xrpy43R4ZBXlyQqnheGLlbOEY8NLDbyNHLRMMOGbcr~67SVE3Iw3RqQ3Dhrkq2FCaQwcDucfIUCCbOfCZgu0hlnCkS42xsUvegQeiwMxbdI~h9v7vcR3yFFOrHX6WQvIZSbFLKNGArGJcfmOJVLqw1wTC4AgYXjk3csVDPd-QWbMXOuodyBgrg27Ds2BBYTsVXWskoo6ASsMIQZ6jMfL7PkY9dPLCRParIyzb9aPmf~MntNAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABHNqwgkhJnBW4ymaRsdVmITAha-ff0UiALfKSlznqp5HcSewgMHbzQ0I01TQytFnW outbound.nickname="+name+" inbound.nickname="+name+" outbound.length=0\n")
sys.stdout.write(sess.recv(10000))
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

View File

@ -26,6 +26,6 @@ port = 7655
host = "localhost"
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.bind(("", 0))
s.sendto(name+" tYhjbFlFL38WFuO5eCzTvE0UBr4RfaqWMKlekGeMoB-Ouz7nYaWfiS-9j3jMiZT7FH~pwdmoSREOs2ZbXK84sR59P~pPfeCMxnJrk57f3U9uKzXkesjkKWYco3YAGs-G8sw8Fu2FBx0Do57yBdA9~j8Zq6pMjmgPBXCLuXG3vo0Z8zUWCjApJyFY6OXYopHck9Fz9vKy7YhC6zXFHfEuNHVkAooduiLd~aCoGij0TW3lH2rTVU-lx-DUdi6edxQ5-RvDNkXfikvytoCpRkivbNVytjCJLk~7RNU4FpBD20wTZWNJmEG3OY3cjNjawJVFdNjtgczh9K7gZ7ad-NjVjZVhXEj1lU8mk~vAH-2QE5om8dstWUwWoNDwmVDlvIJNKzQmahG~VrpFexFHXO0n3fKIXcSgWGOHDExM8w9neCt7AxUjxPDtXXuYNW~bRwcfiL-C9~z4K9rmwiTPZX0lmsToSXTF28l7WAoj~TMT9kZAjQeFRRWU5oW5oxVuonVvAAAA\n"+message, (host, port))
s.sendto(name+" EYUpJFeW9tiubXR0aOjvCJ~ndj3xN0Wn-ljuGdbpOEttPg7nj0VCTOQDJ~FAolzn9FIDdmR3VjM0OFFDT46Q5HN4vShXFE2VNC8e3~GjzxJfaJhijRC2R9oIOzsNlzKtInD2o9lh0PxPioNMCigwmgWuqlQHs4tjWeaYRAtooHxbrtuoCIhIdGfyVV-nAcPiyYbouKq3leETXE~4kBXm-LfWfyPtrv6OuDk3GBVVcthv19GYBmnl2YI8HpJjc-G-TvNkgYishjzIJyEW-Xrpy43R4ZBXlyQqnheGLlbOEY8NLDbyNHLRMMOGbcr~67SVE3Iw3RqQ3Dhrkq2FCaQwcDucfIUCCbOfCZgu0hlnCkS42xsUvegQeiwMxbdI~h9v7vcR3yFFOrHX6WQvIZSbFLKNGArGJcfmOJVLqw1wTC4AgYXjk3csVDPd-QWbMXOuodyBgrg27Ds2BBYTsVXWskoo6ASsMIQZ6jMfL7PkY9dPLCRParIyzb9aPmf~MntNAAAA\n"+message, (host, port))
s.sendto("3.0 "+name+" tYhjbFlFL38WFuO5eCzTvE0UBr4RfaqWMKlekGeMoB-Ouz7nYaWfiS-9j3jMiZT7FH~pwdmoSREOs2ZbXK84sR59P~pPfeCMxnJrk57f3U9uKzXkesjkKWYco3YAGs-G8sw8Fu2FBx0Do57yBdA9~j8Zq6pMjmgPBXCLuXG3vo0Z8zUWCjApJyFY6OXYopHck9Fz9vKy7YhC6zXFHfEuNHVkAooduiLd~aCoGij0TW3lH2rTVU-lx-DUdi6edxQ5-RvDNkXfikvytoCpRkivbNVytjCJLk~7RNU4FpBD20wTZWNJmEG3OY3cjNjawJVFdNjtgczh9K7gZ7ad-NjVjZVhXEj1lU8mk~vAH-2QE5om8dstWUwWoNDwmVDlvIJNKzQmahG~VrpFexFHXO0n3fKIXcSgWGOHDExM8w9neCt7AxUjxPDtXXuYNW~bRwcfiL-C9~z4K9rmwiTPZX0lmsToSXTF28l7WAoj~TMT9kZAjQeFRRWU5oW5oxVuonVvAAAA\n"+message, (host, port))
s.sendto("3.0 "+name+" EYUpJFeW9tiubXR0aOjvCJ~ndj3xN0Wn-ljuGdbpOEttPg7nj0VCTOQDJ~FAolzn9FIDdmR3VjM0OFFDT46Q5HN4vShXFE2VNC8e3~GjzxJfaJhijRC2R9oIOzsNlzKtInD2o9lh0PxPioNMCigwmgWuqlQHs4tjWeaYRAtooHxbrtuoCIhIdGfyVV-nAcPiyYbouKq3leETXE~4kBXm-LfWfyPtrv6OuDk3GBVVcthv19GYBmnl2YI8HpJjc-G-TvNkgYishjzIJyEW-Xrpy43R4ZBXlyQqnheGLlbOEY8NLDbyNHLRMMOGbcr~67SVE3Iw3RqQ3Dhrkq2FCaQwcDucfIUCCbOfCZgu0hlnCkS42xsUvegQeiwMxbdI~h9v7vcR3yFFOrHX6WQvIZSbFLKNGArGJcfmOJVLqw1wTC4AgYXjk3csVDPd-QWbMXOuodyBgrg27Ds2BBYTsVXWskoo6ASsMIQZ6jMfL7PkY9dPLCRParIyzb9aPmf~MntNAAAA\n"+message, (host, port))

View File

@ -26,6 +26,6 @@ port = 7655
host = "localhost"
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.bind(("", 0))
s.sendto(name+" tYhjbFlFL38WFuO5eCzTvE0UBr4RfaqWMKlekGeMoB-Ouz7nYaWfiS-9j3jMiZT7FH~pwdmoSREOs2ZbXK84sR59P~pPfeCMxnJrk57f3U9uKzXkesjkKWYco3YAGs-G8sw8Fu2FBx0Do57yBdA9~j8Zq6pMjmgPBXCLuXG3vo0Z8zUWCjApJyFY6OXYopHck9Fz9vKy7YhC6zXFHfEuNHVkAooduiLd~aCoGij0TW3lH2rTVU-lx-DUdi6edxQ5-RvDNkXfikvytoCpRkivbNVytjCJLk~7RNU4FpBD20wTZWNJmEG3OY3cjNjawJVFdNjtgczh9K7gZ7ad-NjVjZVhXEj1lU8mk~vAH-2QE5om8dstWUwWoNDwmVDlvIJNKzQmahG~VrpFexFHXO0n3fKIXcSgWGOHDExM8w9neCt7AxUjxPDtXXuYNW~bRwcfiL-C9~z4K9rmwiTPZX0lmsToSXTF28l7WAoj~TMT9kZAjQeFRRWU5oW5oxVuonVvAAAA\n"+message, (host, port))
s.sendto(name+" EYUpJFeW9tiubXR0aOjvCJ~ndj3xN0Wn-ljuGdbpOEttPg7nj0VCTOQDJ~FAolzn9FIDdmR3VjM0OFFDT46Q5HN4vShXFE2VNC8e3~GjzxJfaJhijRC2R9oIOzsNlzKtInD2o9lh0PxPioNMCigwmgWuqlQHs4tjWeaYRAtooHxbrtuoCIhIdGfyVV-nAcPiyYbouKq3leETXE~4kBXm-LfWfyPtrv6OuDk3GBVVcthv19GYBmnl2YI8HpJjc-G-TvNkgYishjzIJyEW-Xrpy43R4ZBXlyQqnheGLlbOEY8NLDbyNHLRMMOGbcr~67SVE3Iw3RqQ3Dhrkq2FCaQwcDucfIUCCbOfCZgu0hlnCkS42xsUvegQeiwMxbdI~h9v7vcR3yFFOrHX6WQvIZSbFLKNGArGJcfmOJVLqw1wTC4AgYXjk3csVDPd-QWbMXOuodyBgrg27Ds2BBYTsVXWskoo6ASsMIQZ6jMfL7PkY9dPLCRParIyzb9aPmf~MntNAAAA\n"+message, (host, port))
s.sendto("3.0 "+name+" tYhjbFlFL38WFuO5eCzTvE0UBr4RfaqWMKlekGeMoB-Ouz7nYaWfiS-9j3jMiZT7FH~pwdmoSREOs2ZbXK84sR59P~pPfeCMxnJrk57f3U9uKzXkesjkKWYco3YAGs-G8sw8Fu2FBx0Do57yBdA9~j8Zq6pMjmgPBXCLuXG3vo0Z8zUWCjApJyFY6OXYopHck9Fz9vKy7YhC6zXFHfEuNHVkAooduiLd~aCoGij0TW3lH2rTVU-lx-DUdi6edxQ5-RvDNkXfikvytoCpRkivbNVytjCJLk~7RNU4FpBD20wTZWNJmEG3OY3cjNjawJVFdNjtgczh9K7gZ7ad-NjVjZVhXEj1lU8mk~vAH-2QE5om8dstWUwWoNDwmVDlvIJNKzQmahG~VrpFexFHXO0n3fKIXcSgWGOHDExM8w9neCt7AxUjxPDtXXuYNW~bRwcfiL-C9~z4K9rmwiTPZX0lmsToSXTF28l7WAoj~TMT9kZAjQeFRRWU5oW5oxVuonVvAAAA\n"+message, (host, port))
s.sendto("3.0 "+name+" EYUpJFeW9tiubXR0aOjvCJ~ndj3xN0Wn-ljuGdbpOEttPg7nj0VCTOQDJ~FAolzn9FIDdmR3VjM0OFFDT46Q5HN4vShXFE2VNC8e3~GjzxJfaJhijRC2R9oIOzsNlzKtInD2o9lh0PxPioNMCigwmgWuqlQHs4tjWeaYRAtooHxbrtuoCIhIdGfyVV-nAcPiyYbouKq3leETXE~4kBXm-LfWfyPtrv6OuDk3GBVVcthv19GYBmnl2YI8HpJjc-G-TvNkgYishjzIJyEW-Xrpy43R4ZBXlyQqnheGLlbOEY8NLDbyNHLRMMOGbcr~67SVE3Iw3RqQ3Dhrkq2FCaQwcDucfIUCCbOfCZgu0hlnCkS42xsUvegQeiwMxbdI~h9v7vcR3yFFOrHX6WQvIZSbFLKNGArGJcfmOJVLqw1wTC4AgYXjk3csVDPd-QWbMXOuodyBgrg27Ds2BBYTsVXWskoo6ASsMIQZ6jMfL7PkY9dPLCRParIyzb9aPmf~MntNAAAA\n"+message, (host, port))

View File

@ -55,4 +55,10 @@ while 1 :
chunk = sock.recv(100)
sys.stdout.write(chunk)
if not chunk : break
print "Forward socket closed"
l=0
while 1 :
chunk = sess.recv(100)
sys.stdout.write(chunk)
if not chunk : break

View File

@ -44,16 +44,18 @@ def accept() :
sock.send("HELLO VERSION MIN=3.0 MAX=3.0\n")
sys.stdout.write(sock.recv(1000))
sock.send("STREAM ACCEPT ID=" + name + silent+"\n")
print "STREAM ACCEPT ID="+name+silent+"\n"
print "STREAM ACCEPT ID="+name+silent
if (silent==" SILENT=false") :
sys.stdout.write( sock.recv(100) )
return sock
def echo( sock, lines ) :
l = 0
while lines==-1 or l<lines :
chunk = sock.recv(1000)
sys.stdout.write(chunk)
if lines!=-1 : l = l + 1
if not chunk : break
print chunk
sock.send(chunk)
print

View File

@ -280,33 +280,43 @@ public class SAMBridge implements Runnable {
+ s.socket().getInetAddress().toString() + ":"
+ s.socket().getPort());
try {
SAMHandler handler = SAMHandlerFactory.createSAMHandler(s, i2cpProps);
if (handler == null) {
if (_log.shouldLog(Log.DEBUG))
_log.debug("SAM handler has not been instantiated");
class HelloHandler implements Runnable {
SocketChannel s ;
SAMBridge parent ;
HelloHandler(SocketChannel s, SAMBridge parent) {
this.s = s ;
}
public void run() {
try {
s.close();
} catch (IOException e) {}
continue;
}
handler.setBridge(this);
handler.startHandling();
} catch (SAMException e) {
if (_log.shouldLog(Log.ERROR))
_log.error("SAM error: " + e.getMessage(), e);
try {
String reply = "HELLO REPLY RESULT=I2P_ERROR MESSAGE=\"" + e.getMessage() + "\"\n";
s.write(ByteBuffer.wrap(reply.getBytes("ISO-8859-1")));
} catch (IOException ioe) {
if (_log.shouldLog(Log.ERROR))
_log.error("SAM Error sending error reply", ioe);
}
try { s.close(); } catch (IOException ioe) {}
} catch (Exception ee) {
try { s.close(); } catch (IOException ioe) {}
_log.log(Log.CRIT, "Unexpected error handling SAM connection", ee);
}
SAMHandler handler = SAMHandlerFactory.createSAMHandler(s, i2cpProps);
if (handler == null) {
if (_log.shouldLog(Log.DEBUG))
_log.debug("SAM handler has not been instantiated");
try {
s.close();
} catch (IOException e) {}
return;
}
handler.setBridge(parent);
handler.startHandling();
} catch (SAMException e) {
if (_log.shouldLog(Log.ERROR))
_log.error("SAM error: " + e.getMessage(), e);
try {
String reply = "HELLO REPLY RESULT=I2P_ERROR MESSAGE=\"" + e.getMessage() + "\"\n";
s.write(ByteBuffer.wrap(reply.getBytes("ISO-8859-1")));
} catch (IOException ioe) {
if (_log.shouldLog(Log.ERROR))
_log.error("SAM Error sending error reply", ioe);
}
try { s.close(); } catch (IOException ioe) {}
} catch (Exception ee) {
try { s.close(); } catch (IOException ioe) {}
_log.log(Log.CRIT, "Unexpected error handling SAM connection", ee);
}
}
}
new I2PAppThread(new HelloHandler(s,this), "HelloHandler").start();
}
} catch (Exception e) {
if (_log.shouldLog(Log.ERROR))

View File

@ -84,11 +84,13 @@ public class SAMHandlerFactory {
}
String ver = chooseBestVersion(minVer, maxVer);
if (ver == null)
throw new SAMException("No version specified");
// Let's answer positively
try {
if (ver == null) {
s.write(ByteBuffer.wrap(("HELLO REPLY RESULT=NOVERSION\n").getBytes("ISO-8859-1")));
return null ;
}
// Let's answer positively
s.write(ByteBuffer.wrap(("HELLO REPLY RESULT=OK VERSION="
+ ver + "\n").getBytes("ISO-8859-1")));
} catch (UnsupportedEncodingException e) {

View File

@ -8,6 +8,7 @@ package net.i2p.sam;
*
*/
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Enumeration;
@ -19,8 +20,11 @@ import net.i2p.I2PException;
import net.i2p.client.I2PClient;
import net.i2p.client.I2PClientFactory;
import net.i2p.client.naming.NamingService;
import net.i2p.data.Base64;
import net.i2p.data.DataFormatException;
import net.i2p.data.Destination;
import net.i2p.data.PrivateKey;
import net.i2p.data.SigningPrivateKey;
import net.i2p.util.Log;
/**
@ -73,6 +77,22 @@ public class SAMUtils {
return false;
}
}
public static class InvalidDestination extends Exception {
static final long serialVersionUID = 0x1 ;
}
public static void checkPrivateDestination(String dest) throws InvalidDestination {
ByteArrayInputStream destKeyStream = new ByteArrayInputStream(Base64.decode(dest));
try {
new Destination().readBytes(destKeyStream);
new PrivateKey().readBytes(destKeyStream);
new SigningPrivateKey().readBytes(destKeyStream);
} catch (Exception e) {
throw new InvalidDestination();
}
}
/**
* Resolved the specified hostname.
@ -108,15 +128,18 @@ public class SAMUtils {
*
* @return the Destination for the specified hostname, or null if not found
*/
public static Destination getDest(String s)
public static Destination getDest(String s) throws DataFormatException
{
Destination d = new Destination() ;
try {
d.fromBase64(s);
return d ;
} catch (DataFormatException e) {
return lookupHost(s, null);
}
Destination d = new Destination() ;
try {
d.fromBase64(s);
} catch (DataFormatException e) {
d = lookupHost(s, null);
if ( d==null ) {
throw e ;
}
}
return d ;
}
/**

View File

@ -327,7 +327,7 @@ public class SAMv1Handler extends SAMHandler implements SAMRawReceiver, SAMDatag
return false;
}
Destination dest;
Destination dest = null ;
if (name.equals("ME")) {
if (getRawSession() != null) {
dest = getRawSession().getDestination();
@ -340,7 +340,10 @@ public class SAMv1Handler extends SAMHandler implements SAMRawReceiver, SAMDatag
return false;
}
} else {
dest = SAMUtils.getDest(name);
try {
dest = SAMUtils.getDest(name);
} catch (DataFormatException e) {
}
}
if (dest == null) {

View File

@ -32,7 +32,6 @@ import net.i2p.data.DataFormatException;
import net.i2p.data.DataHelper;
import net.i2p.data.Destination;
import net.i2p.util.Log;
import net.i2p.data.VerifiedDestination;
import net.i2p.util.I2PAppThread;
/**
@ -182,15 +181,18 @@ public class SAMv3Handler extends SAMv1Handler
String header = null ;
String nick ;
String dest ;
String version ;
try {
header = DataHelper.readLine(is).trim();
StringTokenizer tok = new StringTokenizer(header, " ");
if (tok.countTokens() != 2) {
if (tok.countTokens() != 3) {
// This is not a correct message, for sure
_log.debug("Error in message format");
return;
}
version = tok.nextToken();
if (!"3.0".equals(version)) return ;
nick = tok.nextToken();
dest = tok.nextToken();
@ -257,14 +259,30 @@ public class SAMv3Handler extends SAMv1Handler
{
static final long serialVersionUID = 0x1 ;
class ExistingId extends Exception {
static final long serialVersionUID = 0x1 ;
}
class ExistingDest extends Exception {
static final long serialVersionUID = 0x1 ;
}
HashMap<String, SessionRecord> map ;
public SessionsDB() {
map = new HashMap<String, SessionRecord>() ;
}
synchronized public boolean put( String nick, SessionRecord session )
synchronized public boolean put( String nick, SessionRecord session ) throws ExistingId, ExistingDest
{
if ( map.containsKey(nick) ) {
throw new ExistingId();
}
for ( SessionRecord r : map.values() ) {
if (r.getDest().equals(session.getDest())) {
throw new ExistingDest();
}
}
if ( !map.containsKey(nick) ) {
session.createThreadGroup("SAM session "+nick);
map.put(nick, session) ;
@ -455,16 +473,10 @@ public class SAMv3Handler extends SAMv1Handler
_log.debug("Custom destination specified [" + dest + "]");
}
boolean good_key = false ;
try {
good_key = (new VerifiedDestination(dest)).verifyCert(true);
} catch (DataFormatException e) {
good_key = false ;
}
if (!good_key)
{
_log.debug("Bad destination key");
return writeString("SESSION STATUS RESULT=I2P_ERROR MESSAGE=\"bad destination key\"\n");
SAMUtils.checkPrivateDestination(dest);
} catch ( SAMUtils.InvalidDestination e ) {
return writeString("SESSION STATUS RESULT=INVALID_KEY\n");
}
nick = props.getProperty("ID");
@ -489,12 +501,17 @@ public class SAMv3Handler extends SAMv1Handler
allProps.putAll(i2cpProps);
allProps.putAll(props);
if (! sSessionsHash.put( nick, new SessionRecord(dest, allProps, this) ) ) {
try {
sSessionsHash.put( nick, new SessionRecord(dest, allProps, this) ) ;
} catch (SessionsDB.ExistingId e) {
_log.debug("SESSION ID parameter already in use");
String n = nick ;
return writeString("SESSION STATUS RESULT=I2P_ERROR MESSAGE=\"ID "+n+" already in use\"\n");
return writeString("SESSION STATUS RESULT=DUPLICATED_ID\n");
} catch (SessionsDB.ExistingDest e) {
return writeString("SESSION STATUS RESULT=DUPLICATED_DEST\n");
}
// Create the session
if (style.equals("RAW")) {
@ -568,14 +585,19 @@ public class SAMv3Handler extends SAMv1Handler
if ( session != null )
{
_log.error ( "STREAM message received, but this session is a master session" );
writeString("STREAM STATUS RESULT=I2P_ERROR MESSAGE=\"master session cannot be used for streams");
try {
notifyStreamResult(true, "I2P_ERROR", "master session cannot be used for streams");
} catch (IOException e) {}
return false;
}
nick = props.getProperty("ID");
if (nick == null) {
_log.debug("SESSION ID parameter not specified");
writeString("STREAM STATUS RESULT=I2P_ERROR MESSAGE=\"ID not specified\"\n");
try {
notifyStreamResult(true, "I2P_ERROR", "ID not specified");
} catch (IOException e) {}
return false ;
}
props.remove("ID");
@ -584,7 +606,9 @@ public class SAMv3Handler extends SAMv1Handler
if ( rec==null ) {
_log.debug("STREAM SESSION ID does not exist");
writeString("STREAM STATUS RESULT=I2P_ERROR MESSAGE=\"STREAM SESSION ID does not exist\"\n");
try {
notifyStreamResult(true, "INVALID_ID", "STREAM SESSION ID does not exist");
} catch (IOException e) {}
return false ;
}
@ -592,7 +616,9 @@ public class SAMv3Handler extends SAMv1Handler
if (streamSession==null) {
_log.debug("specified ID is not a stream session");
writeString("STREAM STATUS RESULT=I2P_ERROR MESSAGE=\"specified ID is not a STREAM session\"\n");
try {
notifyStreamResult(true, "I2P_ERROR", "specified ID is not a STREAM session");
} catch (IOException e) {}
return false ;
}
@ -612,45 +638,49 @@ public class SAMv3Handler extends SAMv1Handler
{
_log.debug ( "Unrecognized RAW message opcode: \""
+ opcode + "\"" );
writeString("STREAM STATUS RESULT=I2P_ERROR MESSAGE=\"Unrecognized RAW message opcode: \""
+ opcode + "\"" );
try {
notifyStreamResult(true, "I2P_ERROR", "Unrecognized RAW message opcode: "+opcode );
} catch (IOException e) {}
return false;
}
}
protected boolean execStreamConnect( Properties props) {
if (props == null) {
_log.debug("No parameters specified in STREAM CONNECT message");
return false;
}
boolean verbose = props.getProperty("SILENT","false").equals("false");
String dest = props.getProperty("DESTINATION");
if (dest == null) {
_log.debug("Destination not specified in RAW SEND message");
return false;
}
props.remove("DESTINATION");
try {
if (props == null) {
notifyStreamResult(true,"I2P_ERROR","No parameters specified in STREAM CONNECT message");
_log.debug("No parameters specified in STREAM CONNECT message");
return false;
}
boolean verbose = props.getProperty("SILENT","false").equals("false");
String dest = props.getProperty("DESTINATION");
if (dest == null) {
notifyStreamResult(verbose, "I2P_ERROR", "Destination not specified in RAW SEND message");
_log.debug("Destination not specified in RAW SEND message");
return false;
}
props.remove("DESTINATION");
try {
streamSession.connect( this, dest, props );
return true ;
} catch (DataFormatException e) {
_log.debug("Invalid destination in STREAM CONNECT message");
if (verbose) notifyStreamAccept ( "INVALID_KEY" );
notifyStreamResult ( verbose, "INVALID_KEY", null );
} catch (ConnectException e) {
_log.debug("STREAM CONNECT failed: " + e.getMessage());
if (verbose) notifyStreamAccept ( "CONNECTION_REFUSED" );
notifyStreamResult ( verbose, "CONNECTION_REFUSED", null );
} catch (NoRouteToHostException e) {
_log.debug("STREAM CONNECT failed: " + e.getMessage());
if (verbose) notifyStreamAccept ( "CANT_REACH_PEER" );
notifyStreamResult ( verbose, "CANT_REACH_PEER", null );
} catch (InterruptedIOException e) {
_log.debug("STREAM CONNECT failed: " + e.getMessage());
if (verbose) notifyStreamAccept ( "TIMEOUT" );
notifyStreamResult ( verbose, "TIMEOUT", null );
} catch (I2PException e) {
_log.debug("STREAM CONNECT failed: " + e.getMessage());
if (verbose) notifyStreamAccept ( "I2P_ERROR" );
notifyStreamResult ( verbose, "I2P_ERROR", e.getMessage() );
}
} catch (IOException e) {
}
@ -661,11 +691,11 @@ public class SAMv3Handler extends SAMv1Handler
try {
try {
streamSession.startForwardingIncoming(props);
notifyStreamAccept("OK");
return true ;
notifyStreamResult( true, "OK", null );
return false ;
} catch (SAMException e) {
_log.debug("Forwarding STREAM connections failed: " + e.getMessage());
notifyStreamAccept ( "FORWARDER_FAILED" );
notifyStreamResult ( true, "I2P_ERROR", "Forwarding failed : " + e.getMessage() );
}
} catch (IOException e) {
}
@ -677,17 +707,18 @@ public class SAMv3Handler extends SAMv1Handler
boolean verbose = props.getProperty( "SILENT", "false").equals("false");
try {
try {
notifyStreamResult(verbose, "OK", null);
streamSession.accept(this, verbose);
return true ;
} catch (InterruptedIOException e) {
_log.debug("STREAM ACCEPT failed: " + e.getMessage());
if (verbose) notifyStreamAccept( "TIMEOUT" );
notifyStreamResult( verbose, "TIMEOUT", e.getMessage() );
} catch (I2PException e) {
_log.debug("STREAM ACCEPT failed: " + e.getMessage());
if (verbose) notifyStreamAccept ( "I2P_ERROR" );
notifyStreamResult ( verbose, "I2P_ERROR", e.getMessage() );
} catch (SAMException e) {
_log.debug("STREAM ACCEPT failed: " + e.getMessage());
if (verbose) notifyStreamAccept ( "ALREADY_ACCEPTING" );
notifyStreamResult ( verbose, "ALREADY_ACCEPTING", null );
}
} catch (IOException e) {
}
@ -695,33 +726,16 @@ public class SAMv3Handler extends SAMv1Handler
}
public void notifyStreamAccept(String status) throws IOException
public void notifyStreamResult(boolean verbose, String result, String message) throws IOException
{
if ( streamSession == null )
{
_log.error ( "BUG! Received stream connection, but session is null!" );
throw new NullPointerException ( "BUG! STREAM session is null!" );
}
if ( !writeString ( "STREAM STATUS RESULT="
+ status
+ "\n" ) )
{
throw new IOException ( "Error notifying connection to SAM client" );
}
}
public void notifyStreamOutgoingConnection(String result) throws IOException
{
if ( streamSession == null )
{
_log.error ( "BUG! Received stream connection, but session is null!" );
throw new NullPointerException ( "BUG! STREAM session is null!" );
}
if ( !writeString ( "STREAM STATUS RESULT="
+ result
+ "\n" ) )
if (!verbose) return ;
String out = "STREAM STATUS RESULT="+result;
if (message!=null)
out = out + " MESSAGE=\"" + message + "\"";
out = out + '\n';
if ( !writeString ( out ) )
{
throw new IOException ( "Error notifying connection to SAM client" );
}

View File

@ -77,7 +77,7 @@ public class SAMv3StreamSession extends SAMStreamSession implements SAMv3Handle
}
private void initSAMStreamSession(String login)
throws IOException, DataFormatException, SAMException{
throws IOException, DataFormatException, SAMException {
SAMv3Handler.SessionRecord rec = getDB().get(login);
String dest = rec.getDest() ;
@ -131,8 +131,7 @@ public class SAMv3StreamSession extends SAMStreamSession implements SAMv3Handle
public void connect ( SAMv3Handler handler, String dest, Properties props ) throws I2PException, ConnectException, NoRouteToHostException, DataFormatException, InterruptedIOException, IOException {
boolean verbose = (props.getProperty("SILENT", "false").equals("false"));
Destination d = new Destination();
d = SAMUtils.getDest(dest);
Destination d = SAMUtils.getDest(dest);
I2PSocketOptions opts = socketMgr.buildOptions(props);
if (props.getProperty(I2PSocketOptions.PROP_CONNECT_TIMEOUT) == null)
@ -148,7 +147,7 @@ public class SAMv3StreamSession extends SAMStreamSession implements SAMv3Handle
if ( rec==null ) throw new InterruptedIOException() ;
if (verbose) handler.notifyStreamOutgoingConnection("OK") ;
handler.notifyStreamResult(verbose, "OK", null) ;
handler.stealSocket() ;