// The peer has aborted our connection.
set_state(c, CLOSED);
errno = ECONNRESET;
+ buffer_clear(&c->sndbuf);
+ buffer_clear(&c->rcvbuf);
if(c->recv) {
c->recv(c, NULL, 0);
buffer_clear(&c->sndbuf);
buffer_clear(&c->rcvbuf);
- c->recv = NULL;
- c->poll = NULL;
-
switch(c->state) {
case CLOSED:
return true;
hdr.ack = c->rcv.nxt;
hdr.wnd = 0;
hdr.ctl = RST;
+ hdr.aux = 0;
print_packet(c, "send", &hdr, sizeof(hdr));
c->utcp->send(c->utcp, &hdr, sizeof(hdr));
c->reapable = true;
}
-// Closes all the opened connections
-void utcp_abort_all_connections(struct utcp *utcp) {
+// Resets all connections, but does not invalidate connection handles
+void utcp_reset_all_connections(struct utcp *utcp) {
if(!utcp) {
errno = EINVAL;
return;
continue;
}
- utcp_recv_t old_recv = c->recv;
- utcp_poll_t old_poll = c->poll;
+ reset_connection(c);
- utcp_abort(c);
-
- if(old_recv) {
+ if(c->recv) {
errno = 0;
- old_recv(c, NULL, 0);
+ c->recv(c, NULL, 0);
}
- if(old_poll && !c->reapable) {
+ if(c->poll && !c->reapable) {
errno = 0;
- old_poll(c, 0);
+ c->poll(c, 0);
}
}
if(timespec_isset(&c->conn_timeout) && timespec_lt(&c->conn_timeout, &now)) {
errno = ETIMEDOUT;
c->state = CLOSED;
+ buffer_clear(&c->sndbuf);
+ buffer_clear(&c->rcvbuf);
if(c->recv) {
c->recv(c, NULL, 0);
struct utcp_connection *c = utcp->connections[i];
if(!c->reapable) {
+ buffer_clear(&c->sndbuf);
+ buffer_clear(&c->rcvbuf);
+
if(c->recv) {
c->recv(c, NULL, 0);
}