forked from I2P_Developers/i2p.i2p
Merge branch '399-sam-accept' into 'master'
SAM: Accept fixes (Gitlab #399) Closes #399 See merge request i2p-hackers/i2p.i2p!114
This commit is contained in:
@@ -28,7 +28,8 @@ public interface I2PServerSocket {
|
||||
* @return a connected I2PSocket OR NULL through 0.9.16; never null as of 0.9.17
|
||||
*
|
||||
* @throws I2PException if there is a problem with reading a new socket
|
||||
* from the data available (e.g. the I2PSession is closed)
|
||||
* from the data available (e.g. the I2PSession is closed);
|
||||
* as of 0.9.60, this may be an I2PSessionException which extends I2PException
|
||||
* @throws RouterRestartException (extends I2PException) if the router is apparently restarting, since 0.9.34
|
||||
* @throws ConnectException if the I2PServerSocket is closed, or if interrupted.
|
||||
* Not actually thrown through 0.9.16; thrown as of 0.9.17
|
||||
|
@@ -361,6 +361,13 @@ class SAMStreamSession implements SAMMessageSess {
|
||||
socketMgr.destroySocketManager();
|
||||
}
|
||||
|
||||
/**
|
||||
* Is the underlying streaming socket manager destroyed?
|
||||
*
|
||||
* @since 0.9.60
|
||||
*/
|
||||
public boolean isDestroyed() { return socketMgr.isDestroyed(); }
|
||||
|
||||
/**
|
||||
* Close a connection managed by the SAM STREAM session.
|
||||
*
|
||||
|
@@ -29,6 +29,7 @@ import net.i2p.I2PException;
|
||||
import net.i2p.client.I2PClient;
|
||||
import net.i2p.client.I2PSession;
|
||||
import net.i2p.client.I2PSessionException;
|
||||
import net.i2p.client.streaming.RouterRestartException;
|
||||
import net.i2p.crypto.SigType;
|
||||
import net.i2p.data.Base64;
|
||||
import net.i2p.data.DataFormatException;
|
||||
@@ -718,7 +719,8 @@ class SAMv3Handler extends SAMv1Handler
|
||||
return false ;
|
||||
}
|
||||
|
||||
streamSession = rec.getHandler().streamSession ;
|
||||
SAMv3Handler ctl = rec.getHandler();
|
||||
streamSession = ctl.streamSession;
|
||||
if (streamSession==null) {
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("specified ID is not a stream session");
|
||||
@@ -727,6 +729,16 @@ class SAMv3Handler extends SAMv1Handler
|
||||
} catch (IOException e) {}
|
||||
return false ;
|
||||
}
|
||||
if (streamSession.isDestroyed()) {
|
||||
if (_log.shouldDebug())
|
||||
_log.debug("Session manager is destroyed");
|
||||
try {
|
||||
notifyStreamResult(true, "I2P_ERROR", "Session is closed");
|
||||
} catch (IOException e) {}
|
||||
ctl.writeString(SESSION_ERROR, "Session is closed");
|
||||
ctl.stopHandling();
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( opcode.equals ( "CONNECT" ) )
|
||||
{
|
||||
@@ -734,7 +746,17 @@ class SAMv3Handler extends SAMv1Handler
|
||||
}
|
||||
else if ( opcode.equals ( "ACCEPT" ) )
|
||||
{
|
||||
return execStreamAccept ( props );
|
||||
try {
|
||||
return execStreamAccept(props);
|
||||
} catch (I2PSessionException ise) {
|
||||
ctl.writeString(SESSION_ERROR, ise.getMessage());
|
||||
ctl.stopHandling();
|
||||
return false;
|
||||
} catch (RouterRestartException rre) {
|
||||
ctl.writeString(SESSION_ERROR, "Router restart");
|
||||
ctl.stopHandling();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if ( opcode.equals ( "FORWARD") )
|
||||
{
|
||||
@@ -822,13 +844,18 @@ class SAMv3Handler extends SAMv1Handler
|
||||
return false ;
|
||||
}
|
||||
|
||||
private boolean execStreamAccept( Properties props )
|
||||
/**
|
||||
* @return success
|
||||
* @throws I2PSessionException if socket manager is destroyed while waiting
|
||||
*/
|
||||
private boolean execStreamAccept(Properties props) throws I2PSessionException, RouterRestartException
|
||||
{
|
||||
// Messages are NOT sent if SILENT=true,
|
||||
// The specs said that they were.
|
||||
boolean verbose = !Boolean.parseBoolean(props.getProperty("SILENT"));
|
||||
try {
|
||||
try {
|
||||
// execStreamSession() above checks if session is destroyed first
|
||||
notifyStreamResult(verbose, "OK", null);
|
||||
((SAMv3StreamSession)streamSession).accept(this, verbose);
|
||||
return true ;
|
||||
@@ -836,6 +863,21 @@ class SAMv3Handler extends SAMv1Handler
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("STREAM ACCEPT failed", e);
|
||||
notifyStreamResult( verbose, "TIMEOUT", e.getMessage() );
|
||||
} catch (I2PSessionException e) {
|
||||
// As of 0.9.60, this is thrown for a destroyed session.
|
||||
// Kill the SAM session.
|
||||
if (_log.shouldDebug())
|
||||
_log.debug("STREAM ACCEPT failed", e);
|
||||
notifyStreamResult (verbose, "I2P_ERROR", e.getMessage());
|
||||
// throw so caller can close control socket
|
||||
throw e;
|
||||
} catch (RouterRestartException e) {
|
||||
// Kill the SAM session.
|
||||
if (_log.shouldDebug())
|
||||
_log.debug("STREAM ACCEPT failed", e);
|
||||
notifyStreamResult (verbose, "I2P_ERROR", "Router restart");
|
||||
// throw so caller can close control socket
|
||||
throw e;
|
||||
} catch (I2PException e) {
|
||||
if (_log.shouldLog(Log.DEBUG))
|
||||
_log.debug("STREAM ACCEPT failed", e);
|
||||
|
@@ -372,7 +372,7 @@ public class I2PSocketManagerFull implements I2PSocketManager {
|
||||
* incoming connections on a subsession.
|
||||
*
|
||||
* @return connected I2PSocket, or null through 0.9.16, non-null as of 0.9.17
|
||||
* @throws I2PException if session is closed
|
||||
* @throws I2PException if session is closed; as of 0.9.60, this is an I2PSessionException which extends I2PException
|
||||
* @throws net.i2p.client.streaming.RouterRestartException (extends I2PException) if the router is apparently restarting, since 0.9.34
|
||||
* @throws ConnectException (since 0.9.17; I2PServerSocket interface always declared it)
|
||||
* @throws SocketTimeoutException if a timeout was previously set with setSoTimeout and the timeout has been reached.
|
||||
@@ -523,14 +523,20 @@ public class I2PSocketManagerFull implements I2PSocketManager {
|
||||
return _realServerSocket;
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws I2PException if session is closed; as of 0.9.60, this is an I2PSessionException which extends I2PException
|
||||
*/
|
||||
private void verifySession() throws I2PException {
|
||||
verifySession(_connectionManager.getSession());
|
||||
}
|
||||
|
||||
/** @since 0.9.21 */
|
||||
/**
|
||||
* @throws I2PException if session is closed; as of 0.9.60, this is an I2PSessionException which extends I2PException
|
||||
* @since 0.9.21
|
||||
*/
|
||||
private void verifySession(I2PSession session) throws I2PException {
|
||||
if (_isDestroyed.get())
|
||||
throw new I2PException("Session was closed");
|
||||
throw new I2PSessionException("Session was closed");
|
||||
if (!session.isClosed())
|
||||
return;
|
||||
session.connect();
|
||||
|
Reference in New Issue
Block a user