propagate from branch 'i2p.i2p' (head 982dc8adf7d5c10608e572f285c2eb196d25a64e)
to branch 'i2p.i2p.sam3' (head a455f4d173b9c8c18698ed182407e152848dc8de)
This commit is contained in:
@ -135,7 +135,7 @@ Streams are bidirectional communication sockets between two I2P
|
||||
destinations, but their opening has to be requested by one of them.
|
||||
Hereafter, CONNECT commands are used by the SAM client for such a
|
||||
request. FORWARD / ACCEPT commands are used by the SAM client when
|
||||
it wants to listen to requests coming from other I2P destinations.
|
||||
he wants to listen to requests coming from other I2P destinations.
|
||||
|
||||
|
||||
-----------------------------
|
||||
@ -231,10 +231,11 @@ I2P destination peer, until one of the peer closes the socket.
|
||||
SAM virtual streams : FORWARD
|
||||
-----------------------------
|
||||
|
||||
A client waits for an incoming connection request by :
|
||||
* opening a new socket with the SAM bridge
|
||||
* passing the same HELLO handshake as above
|
||||
* sending the forward command :
|
||||
A client can use a regular socket server and wait for connection requests
|
||||
coming from I2P. For that, the client has to :
|
||||
* open a new socket with the SAM bridge
|
||||
* pass the same HELLO handshake as above
|
||||
* send the forward command :
|
||||
|
||||
-> STREAM FORWARD
|
||||
ID={$nickname}
|
||||
@ -242,7 +243,7 @@ A client waits for an incoming connection request by :
|
||||
[HOST={$host}]
|
||||
[SILENCE={true,false}]
|
||||
|
||||
This makes the session ${nickname} listen forever for incoming
|
||||
This makes the session ${nickname} listen for incoming
|
||||
connection requests from the I2P network.
|
||||
|
||||
The SAM bridge answers with :
|
||||
@ -257,16 +258,12 @@ The RESULT value may be one of:
|
||||
I2P_ERROR
|
||||
INVALID_ID
|
||||
|
||||
The socket is closed immediately after the message by the SAM
|
||||
bridge. If the result is OK, the SAM bridge starts waiting for
|
||||
incoming connection requests from other I2P peers.
|
||||
|
||||
* {$host} is the hostname or IP address of the socket server to which
|
||||
SAM will forward connection requests. If not given, SAM takes the IP
|
||||
of the socket that issued the forward command.
|
||||
|
||||
* {$port} is the port number of the socket server to which SAM will
|
||||
forward connection requests. Is is mandatory.
|
||||
forward connection requests. It is mandatory.
|
||||
|
||||
When a connexion request arrives from I2P, the SAM bridge requests a
|
||||
socket connexion from {$host}:{$port}. If it is accepted after no more
|
||||
@ -284,6 +281,11 @@ socket.
|
||||
|
||||
|
||||
|
||||
The I2P router will stop listening to incoming connection requests as
|
||||
soon as the "forwarding" socket is closed.
|
||||
|
||||
|
||||
|
||||
|
||||
----------------------------------------------------------------------
|
||||
SAM repliable datagrams : sending a datagram
|
||||
|
@ -42,8 +42,9 @@ public class SAMv1Handler extends SAMHandler implements SAMRawReceiver, SAMDatag
|
||||
protected SAMRawSession rawSession = null;
|
||||
protected SAMDatagramSession datagramSession = null;
|
||||
protected SAMStreamSession streamSession = null;
|
||||
protected SAMDatagramSession getDatagramSession() {return datagramSession ;}
|
||||
protected SAMRawSession getRawSession() {return rawSession ;}
|
||||
protected SAMDatagramSession getDatagramSession() {return datagramSession ;}
|
||||
protected SAMStreamSession getStreamSession() {return streamSession ;}
|
||||
|
||||
protected long _id;
|
||||
protected static volatile long __id = 0;
|
||||
@ -331,8 +332,8 @@ public class SAMv1Handler extends SAMHandler implements SAMRawReceiver, SAMDatag
|
||||
if (name.equals("ME")) {
|
||||
if (getRawSession() != null) {
|
||||
dest = getRawSession().getDestination();
|
||||
} else if (streamSession != null) {
|
||||
dest = streamSession.getDestination();
|
||||
} else if (getStreamSession() != null) {
|
||||
dest = getStreamSession().getDestination();
|
||||
} else if (getDatagramSession() != null) {
|
||||
dest = getDatagramSession().getDestination();
|
||||
} else {
|
||||
|
@ -61,10 +61,9 @@ public class SAMv3DatagramSession extends SAMDatagramSession implements SAMv3Han
|
||||
int port = Integer.parseInt(portStr);
|
||||
|
||||
String host = props.getProperty("HOST");
|
||||
if ( host==null ) {
|
||||
_log.debug("no host specified. Take from the client socket");
|
||||
|
||||
if ( host==null ) {
|
||||
host = rec.getHandler().getClientIP();
|
||||
_log.debug("no host specified. Taken from the client socket : " + host+':'+port);
|
||||
}
|
||||
|
||||
|
||||
|
@ -44,17 +44,19 @@ public class SAMv3Handler extends SAMv1Handler
|
||||
{
|
||||
private final static Log _log = new Log ( SAMv3Handler.class );
|
||||
|
||||
protected SAMv3StreamSession streamSession = null ;
|
||||
protected SAMv3RawSession rawSession = null ;
|
||||
protected SAMv3DatagramSession datagramSession = null ;
|
||||
|
||||
protected SAMDatagramSession getDatagramSession() {
|
||||
return datagramSession ;
|
||||
}
|
||||
protected SAMv3StreamSession streamSession = null ;
|
||||
|
||||
protected SAMRawSession getRawSession() {
|
||||
return rawSession ;
|
||||
}
|
||||
protected SAMDatagramSession getDatagramSession() {
|
||||
return datagramSession ;
|
||||
}
|
||||
protected SAMStreamSession getStreamSession() {
|
||||
return streamSession ;
|
||||
}
|
||||
|
||||
protected Session session = null ;
|
||||
|
||||
@ -321,6 +323,8 @@ public class SAMv3Handler extends SAMv1Handler
|
||||
|
||||
boolean stolenSocket = false ;
|
||||
|
||||
boolean streamForwardingSocket = false ;
|
||||
|
||||
public void stealSocket()
|
||||
{
|
||||
stolenSocket = true ;
|
||||
@ -412,6 +416,20 @@ public class SAMv3Handler extends SAMv1Handler
|
||||
_log.error("Error closing socket: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
if (streamForwardingSocket)
|
||||
{
|
||||
if (this.streamSession!=null) {
|
||||
try {
|
||||
this.streamSession.stopForwardingIncoming();
|
||||
} catch (SAMException e) {
|
||||
_log.error("Error while stopping forwarding connections: " + e.getMessage());
|
||||
} catch (InterruptedIOException e) {
|
||||
_log.error("Interrupted while stopping forwarding connections: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
die();
|
||||
}
|
||||
@ -690,9 +708,10 @@ public class SAMv3Handler extends SAMv1Handler
|
||||
protected boolean execStreamForwardIncoming( Properties props ) {
|
||||
try {
|
||||
try {
|
||||
streamForwardingSocket = true ;
|
||||
streamSession.startForwardingIncoming(props);
|
||||
notifyStreamResult( true, "OK", null );
|
||||
return false ;
|
||||
return true ;
|
||||
} catch (SAMException e) {
|
||||
_log.debug("Forwarding STREAM connections failed: " + e.getMessage());
|
||||
notifyStreamResult ( true, "I2P_ERROR", "Forwarding failed : " + e.getMessage() );
|
||||
|
@ -63,9 +63,9 @@ public class SAMv3RawSession extends SAMRawSession implements SAMv3Handler.Sess
|
||||
|
||||
String host = props.getProperty("HOST");
|
||||
if ( host==null ) {
|
||||
_log.debug("no host specified. Take from the client socket");
|
||||
|
||||
host = rec.getHandler().getClientIP();
|
||||
|
||||
_log.debug("no host specified. Taken from the client socket : " + host +':'+port);
|
||||
}
|
||||
|
||||
|
||||
|
@ -156,8 +156,8 @@ public class SAMv3StreamSession extends SAMStreamSession implements SAMv3Handle
|
||||
WritableByteChannel toClient = handler.getClientSocket();
|
||||
WritableByteChannel toI2P = Channels.newChannel(i2ps.getOutputStream());
|
||||
|
||||
(new Thread(rec.getThreadGroup(), new I2PAppThread(new Pipe(fromClient,toI2P), "SAMPipeClientToI2P"))).start();
|
||||
(new Thread(rec.getThreadGroup(), new I2PAppThread(new Pipe(fromI2P,toClient), "SAMPipeClientToI2P"))).start();
|
||||
(new Thread(rec.getThreadGroup(), new I2PAppThread(new Pipe(fromClient,toI2P, "SAMPipeClientToI2P"), "SAMPipeClientToI2P"), "SAMPipeClientToI2P")).start();
|
||||
(new Thread(rec.getThreadGroup(), new I2PAppThread(new Pipe(fromI2P,toClient, "SAMPipeI2PToClient"), "SAMPipeI2PToClient"), "SAMPipeI2PToClient")).start();
|
||||
|
||||
}
|
||||
|
||||
@ -209,8 +209,8 @@ public class SAMv3StreamSession extends SAMStreamSession implements SAMv3Handle
|
||||
WritableByteChannel toClient = handler.getClientSocket();
|
||||
WritableByteChannel toI2P = Channels.newChannel(i2ps.getOutputStream());
|
||||
|
||||
(new Thread(rec.getThreadGroup(), new I2PAppThread(new Pipe(fromClient,toI2P), "SAMPipeClientToI2P"))).start();
|
||||
(new Thread(rec.getThreadGroup(), new I2PAppThread(new Pipe(fromI2P,toClient), "SAMPipeClientToI2P"))).start();
|
||||
(new Thread(rec.getThreadGroup(), new I2PAppThread(new Pipe(fromClient,toI2P, "SAMPipeClientToI2P"), "SAMPipeClientToI2P"), "SAMPipeClientToI2P")).start();
|
||||
(new Thread(rec.getThreadGroup(), new I2PAppThread(new Pipe(fromI2P,toClient, "SAMPipeI2PToClient"), "SAMPipeI2PToClient"), "SAMPipeI2PToClient")).start();
|
||||
}
|
||||
|
||||
|
||||
@ -230,9 +230,8 @@ public class SAMv3StreamSession extends SAMStreamSession implements SAMv3Handle
|
||||
|
||||
String host = props.getProperty("HOST");
|
||||
if ( host==null ) {
|
||||
_log.debug("no host specified. Take from the client socket");
|
||||
|
||||
host = rec.getHandler().getClientIP();
|
||||
_log.debug("no host specified. Taken from the client socket : " + host +':'+port);
|
||||
}
|
||||
|
||||
|
||||
@ -246,8 +245,7 @@ public class SAMv3StreamSession extends SAMStreamSession implements SAMv3Handle
|
||||
}
|
||||
|
||||
SocketForwarder forwarder = new SocketForwarder(host, port, this, verbose);
|
||||
(new Thread(rec.getThreadGroup(), new I2PAppThread(forwarder, "SAMStreamForwarder"))).start();
|
||||
|
||||
(new Thread(rec.getThreadGroup(), new I2PAppThread(forwarder, "SAMStreamForwarder"), "SAMStreamForwarder")).start();
|
||||
}
|
||||
|
||||
public class SocketForwarder extends Thread
|
||||
@ -310,9 +308,11 @@ public class SAMv3StreamSession extends SAMStreamSession implements SAMv3Handle
|
||||
ReadableByteChannel fromI2P = Channels.newChannel(i2ps.getInputStream());
|
||||
WritableByteChannel toClient = clientServerSock ;
|
||||
WritableByteChannel toI2P = Channels.newChannel(i2ps.getOutputStream());
|
||||
new I2PAppThread(new Pipe(fromClient,toI2P), "SAMPipeClientToI2P").start();
|
||||
new I2PAppThread(new Pipe(fromI2P,toClient), "SAMPipeClientToI2P").start();
|
||||
|
||||
I2PAppThread send = new I2PAppThread(new Pipe(fromClient,toI2P, "SAMPipeClientToI2P"), "SAMPipeClientToI2P");
|
||||
I2PAppThread recv = new I2PAppThread(new Pipe(fromI2P,toClient, "SAMPipeI2PToClient"), "SAMPipeI2PToClient");
|
||||
send.start();
|
||||
recv.start();
|
||||
|
||||
} catch (IOException e) {
|
||||
try {
|
||||
clientServerSock.close();
|
||||
@ -331,8 +331,9 @@ public class SAMv3StreamSession extends SAMStreamSession implements SAMv3Handle
|
||||
WritableByteChannel out ;
|
||||
ByteBuffer buf ;
|
||||
|
||||
public Pipe(ReadableByteChannel in, WritableByteChannel out)
|
||||
public Pipe(ReadableByteChannel in, WritableByteChannel out, String name)
|
||||
{
|
||||
super(name);
|
||||
this.in = in ;
|
||||
this.out = out ;
|
||||
this.buf = ByteBuffer.allocate(BUFFER_SIZE) ;
|
||||
@ -368,7 +369,32 @@ public class SAMv3StreamSession extends SAMStreamSession implements SAMv3Handle
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @param props
|
||||
* @throws SAMException
|
||||
* @throws InterruptedIOException
|
||||
*/
|
||||
public void stopForwardingIncoming() throws SAMException, InterruptedIOException
|
||||
{
|
||||
SAMv3Handler.SessionRecord rec = SAMv3Handler.sSessionsHash.get(nick);
|
||||
|
||||
if ( rec==null ) throw new InterruptedIOException() ;
|
||||
|
||||
I2PServerSocket server = null ;
|
||||
synchronized( this.socketServerLock )
|
||||
{
|
||||
if (this.socketServer==null) {
|
||||
_log.debug("no socket server is defined for this destination");
|
||||
throw new SAMException("no socket server is defined for this destination");
|
||||
}
|
||||
server = this.socketServer ;
|
||||
this.socketServer = null ;
|
||||
}
|
||||
try {
|
||||
server.close();
|
||||
} catch ( I2PException e) {}
|
||||
}
|
||||
|
||||
/**
|
||||
* Close the stream session
|
||||
|
Reference in New Issue
Block a user