I2CP: Add an INIT state for session, so a newly created session

isn't treated as CLOSED and immediately replaced by i2ptunnel,
which caused dup shared clients in a race at startup
(possible related tickets #642, #650, #815, #1545)
This commit is contained in:
zzz
2015-05-23 16:07:49 +00:00
parent 33c4be5b2f
commit 195171f9ed
3 changed files with 19 additions and 8 deletions

View File

@ -125,6 +125,8 @@ public abstract class I2PSessionImpl implements I2PSession, I2CPMessageReader.I2
* @since 0.9.8
*/
protected enum State {
/** @since 0.9.20 */
INIT,
OPENING,
/** @since 0.9.11 */
GOTDATE,
@ -133,7 +135,7 @@ public abstract class I2PSessionImpl implements I2PSession, I2CPMessageReader.I2
CLOSED
}
private State _state = State.CLOSED;
private State _state = State.INIT;
protected final Object _stateLock = new Object();
/**
@ -434,6 +436,9 @@ public abstract class I2PSessionImpl implements I2PSession, I2CPMessageReader.I2
boolean loop = true;
while (loop) {
switch (_state) {
case INIT:
loop = false;
break;
case CLOSED:
if (wasOpening)
throw new I2PSessionException("connect by other thread failed");
@ -581,8 +586,8 @@ public abstract class I2PSessionImpl implements I2PSession, I2CPMessageReader.I2
synchronized(_stateLock) {
if (_state == State.GOTDATE)
break;
if (_state != State.OPENING)
throw new IOException("Socket closed");
if (_state != State.OPENING && _state != State.INIT)
throw new IOException("Socket closed, state=" + _state);
// InterruptedException caught by caller
_stateLock.wait(1000);
}
@ -815,7 +820,7 @@ public abstract class I2PSessionImpl implements I2PSession, I2CPMessageReader.I2
/**
* Has the session been closed (or not yet connected)?
* False when open and during transitions. Unsynchronized.
* False when open and during transitions. Synchronized.
*/
public boolean isClosed() {
synchronized (_stateLock) {
@ -885,7 +890,7 @@ public abstract class I2PSessionImpl implements I2PSession, I2CPMessageReader.I2
*/
public void destroySession(boolean sendDisconnect) {
synchronized(_stateLock) {
if (_state == State.CLOSING || _state == State.CLOSED)
if (_state == State.CLOSING || _state == State.CLOSED || _state == State.INIT)
return;
changeState(State.CLOSING);
}
@ -965,7 +970,7 @@ public abstract class I2PSessionImpl implements I2PSession, I2CPMessageReader.I2
protected void disconnect() {
State oldState;
synchronized(_stateLock) {
if (_state == State.CLOSING || _state == State.CLOSED)
if (_state == State.CLOSING || _state == State.CLOSED || _state == State.INIT)
return;
oldState = _state;
changeState(State.CLOSING);

View File

@ -1,3 +1,9 @@
2015-05-23 zzz
* I2CP: Add an INIT state for session, so a newly created session
isn't treated as CLOSED and immediately replaced by i2ptunnel,
which caused dup shared clients in a race at startup
(possible related tickets #642, #650, #815, #1545)
2015-05-21 kytv
* Updates to geoip.txt and geoipv6.dat.gz based on Maxmind GeoLite Country
database from 2015-05-06.
@ -26,7 +32,7 @@
2015-05-07 zzz
* SAM: Close datagram or raw session when underlying
I2P session closes (ticket #1563)
I2P session closes (tickets #1455, #1563)
* Update: Add support for su3-signed development builds (ticket #1381)
2015-05-06 zzz

View File

@ -18,7 +18,7 @@ public class RouterVersion {
/** deprecated */
public final static String ID = "Monotone";
public final static String VERSION = CoreVersion.VERSION;
public final static long BUILD = 27;
public final static long BUILD = 28;
/** for example "-test" */
public final static String EXTRA = "-rc";