propagate from branch 'i2p.i2p' (head 07028378508ab46278d193039b97c543d12ee22e)

to branch 'i2p.i2p.zzz.test2' (head 0074b91cb9fe0ed875457dc0bf1989df03fa9e9a)
This commit is contained in:
zzz
2015-05-30 11:16:00 +00:00
101 changed files with 28058 additions and 25253 deletions

View File

@ -257,7 +257,7 @@ public interface I2PSession {
/**
* Have we closed the session?
*
* @return true if the session is closed
* @return true if the session is closed, OR connect() has not been called yet
*/
public boolean isClosed();

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;
protected 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);
}
@ -609,7 +614,12 @@ public abstract class I2PSessionImpl implements I2PSession, I2CPMessageReader.I2
* Report abuse with regards to the given messageId
*/
public void reportAbuse(int msgId, int severity) throws I2PSessionException {
if (isClosed()) throw new I2PSessionException(getPrefix() + "Already closed");
synchronized (_stateLock) {
if (_state == State.CLOSED)
throw new I2PSessionException("Already closed");
if (_state == State.INIT)
throw new I2PSessionException("Not open, must call connect() first");
}
_producer.reportAbuse(this, msgId, severity);
}
@ -815,11 +825,11 @@ 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) {
return _state == State.CLOSED;
return _state == State.CLOSED || _state == State.INIT;
}
}
@ -830,9 +840,13 @@ public abstract class I2PSessionImpl implements I2PSession, I2CPMessageReader.I2
* @throws I2PSessionException if the message is malformed or there is an error writing it out
*/
void sendMessage(I2CPMessage message) throws I2PSessionException {
if (isClosed()) {
throw new I2PSessionException("Already closed");
} else if (_queue != null) {
synchronized (_stateLock) {
if (_state == State.CLOSED)
throw new I2PSessionException("Already closed");
if (_state == State.INIT)
throw new I2PSessionException("Not open, must call connect() first");
}
if (_queue != null) {
// internal
try {
if (!_queue.offer(message, MAX_SEND_WAIT))
@ -841,7 +855,8 @@ public abstract class I2PSessionImpl implements I2PSession, I2CPMessageReader.I2
throw new I2PSessionException("Interrupted", ie);
}
} else if (_writer == null) {
throw new I2PSessionException("Already closed");
// race here
throw new I2PSessionException("Already closed or not open");
} else {
_writer.addMessage(message);
}
@ -885,7 +900,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 +980,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

@ -247,7 +247,12 @@ class I2PSessionImpl2 extends I2PSessionImpl {
public boolean sendMessage(Destination dest, byte[] payload, int offset, int size, SessionKey keyUsed, Set tagsSent, long expires)
throws I2PSessionException {
if (_log.shouldLog(Log.DEBUG)) _log.debug("sending message");
if (isClosed()) throw new I2PSessionException("Already closed");
synchronized (_stateLock) {
if (_state == State.CLOSED)
throw new I2PSessionException("Already closed");
if (_state == State.INIT)
throw new I2PSessionException("Not open, must call connect() first");
}
updateActivity();
// Sadly there is no way to send something completely uncompressed in a backward-compatible way,

View File

@ -256,7 +256,12 @@ class I2PSessionMuxedImpl extends I2PSessionImpl2 {
* @since 0.9.14
*/
private byte[] prepPayload(byte[] payload, int offset, int size, int proto, int fromPort, int toPort) throws I2PSessionException {
if (isClosed()) throw new I2PSessionException("Already closed");
synchronized (_stateLock) {
if (_state == State.CLOSED)
throw new I2PSessionException("Already closed");
if (_state == State.INIT)
throw new I2PSessionException("Not open, must call connect() first");
}
updateActivity();
if (shouldCompress(size))

View File

@ -1491,10 +1491,12 @@ public class DataHelper {
return (ms / (60 * 1000)) + "m";
} else if (ms < 3 * 24 * 60 * 60 * 1000) {
return (ms / (60 * 60 * 1000)) + "h";
} else if (ms > 1000l * 24l * 60l * 60l * 1000l) {
return "n/a";
} else {
} else if (ms < 1000L * 24 * 60 * 60 * 1000) {
return (ms / (24 * 60 * 60 * 1000)) + "d";
} else if (ms < 1000L * 365 * 24 * 60 * 60 * 1000) {
return (ms / (365L * 24 * 60 * 60 * 1000)) + "y";
} else {
return "n/a";
}
}
@ -1537,11 +1539,14 @@ public class DataHelper {
// hours
// alternates: hrs, hr., hrs.
t = ngettext("1 hour", "{0} hours", (int) (ms / (60 * 60 * 1000)));
} else if (ams > 1000l * 24l * 60l * 60l * 1000l) {
return _("n/a");
} else {
} else if (ams < 1000L * 24 * 60 * 60 * 1000) {
// days
t = ngettext("1 day", "{0} days", (int) (ms / (24 * 60 * 60 * 1000)));
} else if (ams < 1000L * 365 * 24 * 60 * 60 * 1000) {
// years
t = ngettext("1 year", "{0} years", (int) (ms / (365L * 24 * 60 * 60 * 1000)));
} else {
return _("n/a");
}
// Replace minus sign to work around
// bug in Chrome (and IE?), line breaks at the minus sign
@ -1581,10 +1586,14 @@ public class DataHelper {
t = ngettext("1 min", "{0} min", (int) (ms / (60 * 1000)));
} else if (ams < 2 * 24 * 60 * 60 * 1000) {
t = ngettext("1 hour", "{0} hours", (int) (ms / (60 * 60 * 1000)));
} else if (ams > 1000l * 24l * 60l * 60l * 1000l) {
return _("n/a");
} else {
} else if (ams < 1000L * 24 * 60 * 60 * 1000) {
// days
t = ngettext("1 day", "{0} days", (int) (ms / (24 * 60 * 60 * 1000)));
} else if (ams < 1000L * 365 * 24 * 60 * 60 * 1000) {
// years
t = ngettext("1 year", "{0} years", (int) (ms / (365L * 24 * 60 * 60 * 1000)));
} else {
return _("n/a");
}
if (ms < 0)
t = t.replace("-", "&minus;");

View File

@ -375,40 +375,51 @@ public class ResettableGZIPInputStream extends InflaterInputStream {
/******
public static void main(String args[]) {
for (int i = 129; i < 64*1024; i++) {
if (!test(i)) return;
java.util.Random r = new java.util.Random();
for (int i = 129; i < 64*1024; i+= 17) {
byte[] b = new byte[i];
r.nextBytes(b);
if (!test(b)) return;
}
byte orig[] = "ho ho ho, merry christmas".getBytes();
try {
java.io.ByteArrayOutputStream baos = new java.io.ByteArrayOutputStream(64);
java.util.zip.GZIPOutputStream o = new java.util.zip.GZIPOutputStream(baos);
o.write(orig);
o.finish();
o.flush();
o.close();
byte compressed[] = baos.toByteArray();
ResettableGZIPInputStream i = new ResettableGZIPInputStream();
i.initialize(new ByteArrayInputStream(compressed));
byte readBuf[] = new byte[128];
int read = i.read(readBuf);
if (read != orig.length)
throw new RuntimeException("read=" + read);
for (int j = 0; j < read; j++)
if (readBuf[j] != orig[j])
throw new RuntimeException("wtf, j=" + j + " readBuf=" + readBuf[j] + " orig=" + orig[j]);
boolean ok = (-1 == i.read());
if (!ok) throw new RuntimeException("wtf, not EOF after the data?");
for (int k = 1; k < 1599; k++) {
byte orig[] = new byte[k];
r.nextBytes(orig);
java.io.ByteArrayOutputStream baos = new java.io.ByteArrayOutputStream(k+100);
java.util.zip.GZIPOutputStream o = new java.util.zip.GZIPOutputStream(baos);
o.write(orig);
o.finish();
o.flush();
o.close();
byte compressed[] = baos.toByteArray();
i.initialize(new java.io.ByteArrayInputStream(compressed));
byte readBuf[] = new byte[k];
int read = DataHelper.read(i, readBuf);
if (read != orig.length)
throw new RuntimeException("read=" + read + " expected " + orig.length);
for (int j = 0; j < read; j++) {
if (readBuf[j] != orig[j])
throw new RuntimeException("wtf, j=" + j + " readBuf=" + readBuf[j] + " orig=" + orig[j]);
}
boolean ok = (-1 == i.read());
if (!ok) throw new RuntimeException("wtf, not EOF after the data?");
//System.out.println("Match ok");
// try both closing and not
if ((k % 2) != 0)
i.close();
}
System.out.println("Match ok");
} catch (Exception e) {
e.printStackTrace();
}
}
private static boolean test(int size) {
byte b[] = new byte[size];
new java.util.Random().nextBytes(b);
private static boolean test(byte[] b) {
int size = b.length;
try {
java.io.ByteArrayOutputStream baos = new java.io.ByteArrayOutputStream(size);
java.util.zip.GZIPOutputStream o = new java.util.zip.GZIPOutputStream(baos);
@ -417,7 +428,7 @@ public class ResettableGZIPInputStream extends InflaterInputStream {
o.flush();
byte compressed[] = baos.toByteArray();
ResettableGZIPInputStream in = new ResettableGZIPInputStream(new ByteArrayInputStream(compressed));
ResettableGZIPInputStream in = new ResettableGZIPInputStream(new java.io.ByteArrayInputStream(compressed));
java.io.ByteArrayOutputStream baos2 = new java.io.ByteArrayOutputStream(size);
byte rbuf[] = new byte[512];
while (true) {
@ -433,7 +444,7 @@ public class ResettableGZIPInputStream extends InflaterInputStream {
if (!net.i2p.data.DataHelper.eq(rv, 0, b, 0, b.length)) {
throw new RuntimeException("foo, read=" + rv.length);
} else {
System.out.println("match, w00t @ " + size);
//System.out.println("match, w00t @ " + size);
return true;
}
} catch (Exception e) {