debug(c, "accepted %p %p\n", c, recv, priv);
c->recv = recv;
c->priv = priv;
+ c->do_poll = true;
set_state(c, ESTABLISHED);
}
// There is no partial data in the send buffer, so stop the flush timer
stop_retransmit_timer(c);
}
+ } else if(left && !timespec_isset(&c->rtrx_timeout)) {
+ // We have partial data and we didn't start the flush timer yet
+ start_flush_timer(c);
}
}
buffer_clear(&c->rcvbuf);
// Handle whole frames
- while(left > 2) {
+ while(left >= 2) {
uint16_t framelen;
memcpy(&framelen, ptr, sizeof(framelen));
- if(left <= (size_t)framelen + 2) {
+ if(left < (size_t)framelen + 2) {
break;
}
c->snd.last++;
set_state(c, FIN_WAIT_1);
} else {
+ c->do_poll = true;
set_state(c, ESTABLISHED);
}
if(c->poll) {
if((c->state == ESTABLISHED || c->state == CLOSE_WAIT) && c->do_poll) {
c->do_poll = false;
- uint32_t len = buffer_free(&c->sndbuf);
+ uint32_t len = is_framed(c) ? min(buffer_free(&c->sndbuf), MAX_UNRELIABLE_SIZE) : buffer_free(&c->sndbuf);
if(len) {
c->poll(c, len);