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.
|
destinations, but their opening has to be requested by one of them.
|
||||||
Hereafter, CONNECT commands are used by the SAM client for such a
|
Hereafter, CONNECT commands are used by the SAM client for such a
|
||||||
request. FORWARD / ACCEPT commands are used by the SAM client when
|
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
|
SAM virtual streams : FORWARD
|
||||||
-----------------------------
|
-----------------------------
|
||||||
|
|
||||||
A client waits for an incoming connection request by :
|
A client can use a regular socket server and wait for connection requests
|
||||||
* opening a new socket with the SAM bridge
|
coming from I2P. For that, the client has to :
|
||||||
* passing the same HELLO handshake as above
|
* open a new socket with the SAM bridge
|
||||||
* sending the forward command :
|
* pass the same HELLO handshake as above
|
||||||
|
* send the forward command :
|
||||||
|
|
||||||
-> STREAM FORWARD
|
-> STREAM FORWARD
|
||||||
ID={$nickname}
|
ID={$nickname}
|
||||||
@ -242,7 +243,7 @@ A client waits for an incoming connection request by :
|
|||||||
[HOST={$host}]
|
[HOST={$host}]
|
||||||
[SILENCE={true,false}]
|
[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.
|
connection requests from the I2P network.
|
||||||
|
|
||||||
The SAM bridge answers with :
|
The SAM bridge answers with :
|
||||||
@ -257,16 +258,12 @@ The RESULT value may be one of:
|
|||||||
I2P_ERROR
|
I2P_ERROR
|
||||||
INVALID_ID
|
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
|
* {$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
|
SAM will forward connection requests. If not given, SAM takes the IP
|
||||||
of the socket that issued the forward command.
|
of the socket that issued the forward command.
|
||||||
|
|
||||||
* {$port} is the port number of the socket server to which SAM will
|
* {$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
|
When a connexion request arrives from I2P, the SAM bridge requests a
|
||||||
socket connexion from {$host}:{$port}. If it is accepted after no more
|
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
|
SAM repliable datagrams : sending a datagram
|
||||||
|
@ -42,8 +42,9 @@ public class SAMv1Handler extends SAMHandler implements SAMRawReceiver, SAMDatag
|
|||||||
protected SAMRawSession rawSession = null;
|
protected SAMRawSession rawSession = null;
|
||||||
protected SAMDatagramSession datagramSession = null;
|
protected SAMDatagramSession datagramSession = null;
|
||||||
protected SAMStreamSession streamSession = null;
|
protected SAMStreamSession streamSession = null;
|
||||||
protected SAMDatagramSession getDatagramSession() {return datagramSession ;}
|
|
||||||
protected SAMRawSession getRawSession() {return rawSession ;}
|
protected SAMRawSession getRawSession() {return rawSession ;}
|
||||||
|
protected SAMDatagramSession getDatagramSession() {return datagramSession ;}
|
||||||
|
protected SAMStreamSession getStreamSession() {return streamSession ;}
|
||||||
|
|
||||||
protected long _id;
|
protected long _id;
|
||||||
protected static volatile long __id = 0;
|
protected static volatile long __id = 0;
|
||||||
@ -331,8 +332,8 @@ public class SAMv1Handler extends SAMHandler implements SAMRawReceiver, SAMDatag
|
|||||||
if (name.equals("ME")) {
|
if (name.equals("ME")) {
|
||||||
if (getRawSession() != null) {
|
if (getRawSession() != null) {
|
||||||
dest = getRawSession().getDestination();
|
dest = getRawSession().getDestination();
|
||||||
} else if (streamSession != null) {
|
} else if (getStreamSession() != null) {
|
||||||
dest = streamSession.getDestination();
|
dest = getStreamSession().getDestination();
|
||||||
} else if (getDatagramSession() != null) {
|
} else if (getDatagramSession() != null) {
|
||||||
dest = getDatagramSession().getDestination();
|
dest = getDatagramSession().getDestination();
|
||||||
} else {
|
} else {
|
||||||
|
@ -61,10 +61,9 @@ public class SAMv3DatagramSession extends SAMDatagramSession implements SAMv3Han
|
|||||||
int port = Integer.parseInt(portStr);
|
int port = Integer.parseInt(portStr);
|
||||||
|
|
||||||
String host = props.getProperty("HOST");
|
String host = props.getProperty("HOST");
|
||||||
if ( host==null ) {
|
if ( host==null ) {
|
||||||
_log.debug("no host specified. Take from the client socket");
|
|
||||||
|
|
||||||
host = rec.getHandler().getClientIP();
|
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 );
|
private final static Log _log = new Log ( SAMv3Handler.class );
|
||||||
|
|
||||||
protected SAMv3StreamSession streamSession = null ;
|
|
||||||
protected SAMv3RawSession rawSession = null ;
|
protected SAMv3RawSession rawSession = null ;
|
||||||
protected SAMv3DatagramSession datagramSession = null ;
|
protected SAMv3DatagramSession datagramSession = null ;
|
||||||
|
protected SAMv3StreamSession streamSession = null ;
|
||||||
protected SAMDatagramSession getDatagramSession() {
|
|
||||||
return datagramSession ;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected SAMRawSession getRawSession() {
|
protected SAMRawSession getRawSession() {
|
||||||
return rawSession ;
|
return rawSession ;
|
||||||
}
|
}
|
||||||
|
protected SAMDatagramSession getDatagramSession() {
|
||||||
|
return datagramSession ;
|
||||||
|
}
|
||||||
|
protected SAMStreamSession getStreamSession() {
|
||||||
|
return streamSession ;
|
||||||
|
}
|
||||||
|
|
||||||
protected Session session = null ;
|
protected Session session = null ;
|
||||||
|
|
||||||
@ -321,6 +323,8 @@ public class SAMv3Handler extends SAMv1Handler
|
|||||||
|
|
||||||
boolean stolenSocket = false ;
|
boolean stolenSocket = false ;
|
||||||
|
|
||||||
|
boolean streamForwardingSocket = false ;
|
||||||
|
|
||||||
public void stealSocket()
|
public void stealSocket()
|
||||||
{
|
{
|
||||||
stolenSocket = true ;
|
stolenSocket = true ;
|
||||||
@ -412,6 +416,20 @@ public class SAMv3Handler extends SAMv1Handler
|
|||||||
_log.error("Error closing socket: " + e.getMessage());
|
_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();
|
die();
|
||||||
}
|
}
|
||||||
@ -690,9 +708,10 @@ public class SAMv3Handler extends SAMv1Handler
|
|||||||
protected boolean execStreamForwardIncoming( Properties props ) {
|
protected boolean execStreamForwardIncoming( Properties props ) {
|
||||||
try {
|
try {
|
||||||
try {
|
try {
|
||||||
|
streamForwardingSocket = true ;
|
||||||
streamSession.startForwardingIncoming(props);
|
streamSession.startForwardingIncoming(props);
|
||||||
notifyStreamResult( true, "OK", null );
|
notifyStreamResult( true, "OK", null );
|
||||||
return false ;
|
return true ;
|
||||||
} catch (SAMException e) {
|
} catch (SAMException e) {
|
||||||
_log.debug("Forwarding STREAM connections failed: " + e.getMessage());
|
_log.debug("Forwarding STREAM connections failed: " + e.getMessage());
|
||||||
notifyStreamResult ( true, "I2P_ERROR", "Forwarding 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");
|
String host = props.getProperty("HOST");
|
||||||
if ( host==null ) {
|
if ( host==null ) {
|
||||||
_log.debug("no host specified. Take from the client socket");
|
|
||||||
|
|
||||||
host = rec.getHandler().getClientIP();
|
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 toClient = handler.getClientSocket();
|
||||||
WritableByteChannel toI2P = Channels.newChannel(i2ps.getOutputStream());
|
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(fromClient,toI2P, "SAMPipeClientToI2P"), "SAMPipeClientToI2P"), "SAMPipeClientToI2P")).start();
|
||||||
(new Thread(rec.getThreadGroup(), new I2PAppThread(new Pipe(fromI2P,toClient), "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 toClient = handler.getClientSocket();
|
||||||
WritableByteChannel toI2P = Channels.newChannel(i2ps.getOutputStream());
|
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(fromClient,toI2P, "SAMPipeClientToI2P"), "SAMPipeClientToI2P"), "SAMPipeClientToI2P")).start();
|
||||||
(new Thread(rec.getThreadGroup(), new I2PAppThread(new Pipe(fromI2P,toClient), "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");
|
String host = props.getProperty("HOST");
|
||||||
if ( host==null ) {
|
if ( host==null ) {
|
||||||
_log.debug("no host specified. Take from the client socket");
|
|
||||||
|
|
||||||
host = rec.getHandler().getClientIP();
|
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);
|
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
|
public class SocketForwarder extends Thread
|
||||||
@ -310,9 +308,11 @@ public class SAMv3StreamSession extends SAMStreamSession implements SAMv3Handle
|
|||||||
ReadableByteChannel fromI2P = Channels.newChannel(i2ps.getInputStream());
|
ReadableByteChannel fromI2P = Channels.newChannel(i2ps.getInputStream());
|
||||||
WritableByteChannel toClient = clientServerSock ;
|
WritableByteChannel toClient = clientServerSock ;
|
||||||
WritableByteChannel toI2P = Channels.newChannel(i2ps.getOutputStream());
|
WritableByteChannel toI2P = Channels.newChannel(i2ps.getOutputStream());
|
||||||
new I2PAppThread(new Pipe(fromClient,toI2P), "SAMPipeClientToI2P").start();
|
I2PAppThread send = new I2PAppThread(new Pipe(fromClient,toI2P, "SAMPipeClientToI2P"), "SAMPipeClientToI2P");
|
||||||
new I2PAppThread(new Pipe(fromI2P,toClient), "SAMPipeClientToI2P").start();
|
I2PAppThread recv = new I2PAppThread(new Pipe(fromI2P,toClient, "SAMPipeI2PToClient"), "SAMPipeI2PToClient");
|
||||||
|
send.start();
|
||||||
|
recv.start();
|
||||||
|
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
try {
|
try {
|
||||||
clientServerSock.close();
|
clientServerSock.close();
|
||||||
@ -331,8 +331,9 @@ public class SAMv3StreamSession extends SAMStreamSession implements SAMv3Handle
|
|||||||
WritableByteChannel out ;
|
WritableByteChannel out ;
|
||||||
ByteBuffer buf ;
|
ByteBuffer buf ;
|
||||||
|
|
||||||
public Pipe(ReadableByteChannel in, WritableByteChannel out)
|
public Pipe(ReadableByteChannel in, WritableByteChannel out, String name)
|
||||||
{
|
{
|
||||||
|
super(name);
|
||||||
this.in = in ;
|
this.in = in ;
|
||||||
this.out = out ;
|
this.out = out ;
|
||||||
this.buf = ByteBuffer.allocate(BUFFER_SIZE) ;
|
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
|
* Close the stream session
|
||||||
|
Reference in New Issue
Block a user