SAM v3.3: Tests and fixes for REMOVE; don't close underlying I2PSession

- Don't remove a non-subsession with REMOVE
This commit is contained in:
zzz
2016-02-06 17:51:23 +00:00
parent edde533e1b
commit b6deae9b23
6 changed files with 43 additions and 11 deletions

View File

@ -186,11 +186,14 @@ class MasterSession extends SAMv3StreamSession implements SAMDatagramReceiver, S
* @return null for success, or error message * @return null for success, or error message
*/ */
public synchronized String remove(String nick, Properties props) { public synchronized String remove(String nick, Properties props) {
boolean ok = SAMv3Handler.sSessionsHash.del(nick); boolean ok;
SAMMessageSess sess = sessions.remove(nick); SAMMessageSess sess = sessions.remove(nick);
if (sess != null) { if (sess != null) {
ok = SAMv3Handler.sSessionsHash.del(nick);
sess.close(); sess.close();
// TODO if 0/0, add back this as listener? // TODO if 0/0, add back this as listener?
if (_log.shouldWarn())
_log.warn("removed " + sess + " proto " + sess.getListenProtocol() + " port " + sess.getListenPort());
} else { } else {
ok = false; ok = false;
} }

View File

@ -234,6 +234,7 @@ abstract class SAMMessageSession implements SAMMessageSess {
private class SAMMessageSessionHandler implements Runnable, I2PSessionMuxedListener { private class SAMMessageSessionHandler implements Runnable, I2PSessionMuxedListener {
private final I2PSession _session; private final I2PSession _session;
private final boolean _isOwnSession;
private final Object runningLock = new Object(); private final Object runningLock = new Object();
private volatile boolean stillRunning = true; private volatile boolean stillRunning = true;
@ -253,6 +254,7 @@ abstract class SAMMessageSession implements SAMMessageSess {
props.setProperty("inbound.nickname", "SAM UDP Client"); props.setProperty("inbound.nickname", "SAM UDP Client");
props.setProperty("outbound.nickname", "SAM UDP Client"); props.setProperty("outbound.nickname", "SAM UDP Client");
} }
_isOwnSession = true;
_session = client.createSession(destStream, props); _session = client.createSession(destStream, props);
if (_log.shouldLog(Log.DEBUG)) if (_log.shouldLog(Log.DEBUG))
@ -270,6 +272,7 @@ abstract class SAMMessageSession implements SAMMessageSess {
* @since 0.9.25 * @since 0.9.25
*/ */
public SAMMessageSessionHandler(I2PSession sess) throws I2PSessionException { public SAMMessageSessionHandler(I2PSession sess) throws I2PSessionException {
_isOwnSession = false;
_session = sess; _session = sess;
_session.addMuxedSessionListener(this, listenProtocol, listenPort); _session.addMuxedSessionListener(this, listenProtocol, listenPort);
} }
@ -312,14 +315,16 @@ abstract class SAMMessageSession implements SAMMessageSess {
shutDown(); shutDown();
session.removeListener(listenProtocol, listenPort); session.removeListener(listenProtocol, listenPort);
try { if (_isOwnSession) {
if (_log.shouldLog(Log.DEBUG)) try {
_log.debug("Destroying I2P session..."); if (_log.shouldLog(Log.DEBUG))
session.destroySession(); _log.debug("Destroying I2P session...");
if (_log.shouldLog(Log.DEBUG)) session.destroySession();
_log.debug("I2P session destroyed"); if (_log.shouldLog(Log.DEBUG))
} catch (I2PSessionException e) { _log.debug("I2P session destroyed");
_log.error("Error destroying I2P session", e); } catch (I2PSessionException e) {
_log.error("Error destroying I2P session", e);
}
} }
} }

View File

@ -68,6 +68,7 @@ class SAMStreamSession implements SAMMessageSess {
protected final boolean canCreate; protected final boolean canCreate;
private final int listenProtocol; private final int listenProtocol;
private final int listenPort; private final int listenPort;
protected final boolean _isOwnSession;
/** /**
* should we flush every time we get a STREAM SEND, or leave that up to * should we flush every time we get a STREAM SEND, or leave that up to
@ -158,6 +159,7 @@ class SAMStreamSession implements SAMMessageSess {
allprops.setProperty("outbound.nickname", "SAM TCP Client"); allprops.setProperty("outbound.nickname", "SAM TCP Client");
} }
_isOwnSession = true;
if (_log.shouldLog(Log.DEBUG)) if (_log.shouldLog(Log.DEBUG))
_log.debug("Creating I2PSocketManager..."); _log.debug("Creating I2PSocketManager...");
try { try {
@ -207,6 +209,7 @@ class SAMStreamSession implements SAMMessageSess {
canCreate = true; canCreate = true;
Properties allprops = (Properties) System.getProperties().clone(); Properties allprops = (Properties) System.getProperties().clone();
allprops.putAll(props); allprops.putAll(props);
_isOwnSession = false;
socketMgr = mgr; socketMgr = mgr;
socketMgr.addDisconnectListener(new DisconnectListener()); socketMgr.addDisconnectListener(new DisconnectListener());
forceFlush = Boolean.parseBoolean(allprops.getProperty(PROP_FORCE_FLUSH, DEFAULT_FORCE_FLUSH)); forceFlush = Boolean.parseBoolean(allprops.getProperty(PROP_FORCE_FLUSH, DEFAULT_FORCE_FLUSH));
@ -342,7 +345,8 @@ class SAMStreamSession implements SAMMessageSess {
} }
removeAllSocketHandlers(); removeAllSocketHandlers();
recv.stopStreamReceiving(); recv.stopStreamReceiving();
socketMgr.destroySocketManager(); if (_isOwnSession)
socketMgr.destroySocketManager();
} }
/** /**

View File

@ -536,9 +536,11 @@ class SAMv3StreamSession extends SAMStreamSession implements Session
/** /**
* Close the stream session * Close the stream session
* TODO Why do we override?
*/ */
@Override @Override
public void close() { public void close() {
socketMgr.destroySocketManager(); if (_isOwnSession)
socketMgr.destroySocketManager();
} }
} }

View File

@ -329,6 +329,16 @@ public class SAMStreamSend {
if (_log.shouldLog(Log.DEBUG)) if (_log.shouldLog(Log.DEBUG))
_log.debug("SESSION " + command + " reply found: " + ok); _log.debug("SESSION " + command + " reply found: " + ok);
if (masterMode) {
// do a bunch more
req = "SESSION ADD STYLE=STREAM FROM_PORT=99 ID=stream99\n";
samOut.write(req.getBytes("UTF-8"));
req = "SESSION ADD STYLE=STREAM FROM_PORT=98 ID=stream98\n";
samOut.write(req.getBytes("UTF-8"));
req = "SESSION REMOVE ID=stream99\n";
samOut.write(req.getBytes("UTF-8"));
samOut.flush();
}
req = "NAMING LOOKUP NAME=ME\n"; req = "NAMING LOOKUP NAME=ME\n";
samOut.write(req.getBytes("UTF-8")); samOut.write(req.getBytes("UTF-8"));
samOut.flush(); samOut.flush();

View File

@ -727,6 +727,14 @@ public class SAMStreamSink {
samOut.write(req.getBytes("UTF-8")); samOut.write(req.getBytes("UTF-8"));
req = "SESSION ADD STYLE=RAW PORT=9994 FROM_PORT=94 LISTEN_PROTOCOL=222 ID=raw94\n"; req = "SESSION ADD STYLE=RAW PORT=9994 FROM_PORT=94 LISTEN_PROTOCOL=222 ID=raw94\n";
samOut.write(req.getBytes("UTF-8")); samOut.write(req.getBytes("UTF-8"));
req = "SESSION REMOVE ID=stream99\n";
samOut.write(req.getBytes("UTF-8"));
req = "SESSION REMOVE ID=raw95\n";
samOut.write(req.getBytes("UTF-8"));
req = "SESSION REMOVE ID=notfound\n";
samOut.write(req.getBytes("UTF-8"));
req = "SESSION REMOVE ID=masterSink\n"; // shouldn't remove ourselves
samOut.write(req.getBytes("UTF-8"));
samOut.flush(); samOut.flush();
} }
req = "NAMING LOOKUP NAME=ME\n"; req = "NAMING LOOKUP NAME=ME\n";