package net.i2p.client.streaming.impl;
import net.i2p.I2PAppContext;
import net.i2p.util.Log;
/**
* <p>Scheduler used once we've sent our SYN but it hasn't been ACKed yet.
* This connection may or may not be locally created.</p>
*
* <h2>Entry conditions:</h2>
* <ul>
* <li>Packets sent but none ACKed</li>
* </ul>
*
* <h2>Events:</h2>
* <ul>
* <li>Packets received (which may or may not ACK the ones sent)</li>
* <li>Message flush (explicitly, through a full buffer, or stream closure)</li>
* <li>Connection establishment timeout</li>
* <li>RESET received</li>
* </ul>
*
* <h2>Next states:</h2>
* <ul>
* <li>{@link SchedulerConnectedBulk connected} - after receiving an ACK</li>
* <li>{@link SchedulerClosing closing} - after both sending and receiving a CLOSE</li>
* <li>{@link SchedulerClosed closed} - after both sending and receiving ACKs on the CLOSE</li>
* <li>{@link SchedulerDead dead} - after sending or receiving a RESET</li>
* </ul>
*
*/
class SchedulerConnecting extends SchedulerImpl {
public SchedulerConnecting(I2PAppContext ctx) {
super(ctx);
}
public boolean accept(Connection con) {
if (con == null) return false;
boolean notYetConnected = (con.getIsConnected()) &&
//(con.getSendStreamId() == null) && // not null on recv
(con.getLastSendId() >= 0) &&
(con.getHighestAckedThrough() < 0) &&
(!con.getResetReceived());
return notYetConnected;
}
public void eventOccurred(Connection con) {
long waited = _context.clock().now() - con.getCreatedOn();
if ( (con.getOptions().getConnectTimeout() > 0) &&
(con.getOptions().getConnectTimeout() <= waited) ) {
con.setConnectionError("Timeout waiting for ack (waited " + waited + "ms)");
con.disconnect(false);
reschedule(0, con);
if (_log.shouldLog(Log.DEBUG))
_log.debug("waited too long: " + waited);
return;
} else {
// should we be doing a con.sendAvailable here?
if (con.getOptions().getConnectTimeout() > 0)
reschedule(con.getOptions().getConnectTimeout(), con);
}
/*
long timeTillSend = con.getNextSendTime() - _context.clock().now();
if ( (timeTillSend <= 0) && (con.getNextSendTime() > 0) ) {
if (_log.shouldLog(Log.DEBUG))
_log.debug("send next on " + con);
con.sendAvailable();
con.setNextSendTime(-1);
} else {
if (con.getNextSendTime() > 0) {
if (_log.shouldLog(Log.DEBUG))
_log.debug("time till send: " + timeTillSend + " on " + con);
reschedule(timeTillSend, con);
}
}
*/
}
}