*
*/
-#include "p2tp.h"
+#include "swift.h"
-using namespace p2tp;
+using namespace swift;
using namespace std;
tint Channel::MIN_DEV = 50*TINT_MSEC;
tint Channel::LEDBAT_TARGET = TINT_MSEC*25;
float Channel::LEDBAT_GAIN = 1.0/LEDBAT_TARGET;
tint Channel::LEDBAT_DELAY_BIN = TINT_SEC*30;
+tint Channel::MAX_POSSIBLE_RTT = TINT_SEC*10;
const char* Channel::SEND_CONTROL_MODES[] = {"keepalive", "pingpong",
- "slowstart", "standard_aimd", "ledbat"};
+ "slowstart", "standard_aimd", "ledbat", "closing"};
tint Channel::NextSendTime () {
+ TimeoutDataOut(); // precaution to know free cwnd
switch (send_control_) {
case KEEP_ALIVE_CONTROL: return KeepAliveNextSendTime();
case PING_PONG_CONTROL: return PingPongNextSendTime();
case SLOW_START_CONTROL: return SlowStartNextSendTime();
case AIMD_CONTROL: return AimdNextSendTime();
case LEDBAT_CONTROL: return LedbatNextSendTime();
+ case CLOSE_CONTROL: return TINT_NEVER;
default: assert(false);
}
}
tint Channel::SwitchSendControl (int control_mode) {
- dprintf("%s #%u sendctrl switch %s->%s\n",tintstr(),id,
+ dprintf("%s #%u sendctrl switch %s->%s\n",tintstr(),id(),
SEND_CONTROL_MODES[send_control_],SEND_CONTROL_MODES[control_mode]);
switch (control_mode) {
case KEEP_ALIVE_CONTROL:
- send_interval_ = max(TINT_SEC/10,rtt_avg_);
+ send_interval_ = rtt_avg_; //max(TINT_SEC/10,rtt_avg_);
dev_avg_ = max(TINT_SEC,rtt_avg_);
data_out_cap_ = bin64_t::ALL;
cwnd_ = 1;
break;
case LEDBAT_CONTROL:
break;
+ case CLOSE_CONTROL:
+ break;
default:
assert(false);
}
tint Channel::KeepAliveNextSendTime () {
if (sent_since_recv_>=3 && last_recv_time_<NOW-TINT_MIN)
- return TINT_NEVER;
+ return SwitchSendControl(CLOSE_CONTROL);
if (ack_rcvd_recent_)
return SwitchSendControl(SLOW_START_CONTROL);
if (data_in_.time!=TINT_NEVER)
return NOW;
- send_interval_ <<= 1;
+ if (last_send_time_==NOW)
+ send_interval_ <<= 1;
if (send_interval_>MAX_SEND_INTERVAL)
send_interval_ = MAX_SEND_INTERVAL;
return last_send_time_ + send_interval_;
//if (last_recv_time_<NOW-rtt_avg_*4)
// return SwitchSendControl(KEEP_ALIVE_CONTROL);
send_interval_ = rtt_avg_/cwnd_;
- if (send_interval_>std::max(rtt_avg_,TINT_SEC)*4)
+ if (send_interval_>max(rtt_avg_,TINT_SEC)*4)
return SwitchSendControl(KEEP_ALIVE_CONTROL);
if (data_out_.size()<cwnd_) {
- dprintf("%s #%u sendctrl next in %llius\n",tintstr(),id,send_interval_);
+ dprintf("%s #%u sendctrl next in %llius (cwnd %.2f, data_out %i)\n",
+ tintstr(),id_,send_interval_,cwnd_,(int)data_out_.size());
return last_data_out_time_ + send_interval_;
} else {
assert(data_out_.front().time!=TINT_NEVER);
if (last_loss_time_<NOW-rtt_avg_) {
cwnd_ *= ratio;
last_loss_time_ = NOW;
- dprintf("%s #%u sendctrl backoff %3.2f\n",tintstr(),id,cwnd_);
+ dprintf("%s #%u sendctrl backoff %3.2f\n",tintstr(),id_,cwnd_);
}
}
tint queueing_delay = owd_cur - owd_min;
tint off_target = LEDBAT_TARGET - queueing_delay;
cwnd_ += LEDBAT_GAIN * off_target / cwnd_;
+ if (cwnd_<1)
+ cwnd_ = 1;
+ if (owd_cur==TINT_NEVER || owd_min==TINT_NEVER)
+ cwnd_ = 1;
dprintf("%s #%u sendctrl ledbat %lli-%lli => %3.2f\n",
- tintstr(),id,owd_cur,owd_min,cwnd_);
+ tintstr(),id_,owd_cur,owd_min,cwnd_);
return CwndRateNextSendTime();
}