debug(c, "accepted %p %p\n", c, recv, priv);
c->recv = recv;
c->priv = priv;
+ c->do_poll = true;
set_state(c, ESTABLISHED);
}
if(sent_packet) {
if(left) {
// We sent one packet but we have partial data left, (re)start the flush timer
+ if(!timespec_isset(&c->rtrx_timeout)) {
+ c->flush_needed = true;
+ }
+
start_flush_timer(c);
} else {
// 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
+ c->flush_needed = true;
+ 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);
void utcp_set_flush_timeout(struct utcp *utcp, int milliseconds) {
utcp->flush_timeout = milliseconds;
}
+
+bool utcp_get_flush_needed(struct utcp_connection *c) {
+ bool value = c->flush_needed;
+ c->flush_needed = false;
+ return value;
+}