// Don't send anything yet if the connection has not fully established yet
- if (c->state == SYN_SENT || c->state == SYN_RECEIVED)
+ if(c->state == SYN_SENT || c->state == SYN_RECEIVED) {
return len;
+ }
ack(c, false);
c->rcv.irs = hdr.seq;
c->rcv.nxt = hdr.seq;
+
if(c->shut_wr) {
c->snd.last++;
set_state(c, FIN_WAIT_1);
} else {
set_state(c, ESTABLISHED);
}
+
// TODO: notify application of this somehow.
break;
}
// Only process shutting down writes once.
- if (c->shut_wr)
+ if(c->shut_wr) {
return 0;
+ }
c->shut_wr = true;
return 0;
}
-int utcp_close(struct utcp_connection *c) {
- if(utcp_shutdown(c, SHUT_RDWR) && errno != ENOTCONN) {
- return -1;
+// Closes all the opened connections
+void utcp_abort_all_connections(struct utcp *utcp) {
+ if(!utcp) {
+ return;
}
- c->recv = NULL;
- c->poll = NULL;
- c->reapable = true;
- return 0;
+ for(int i = 0; i < utcp->nconnections; i++) {
+ struct utcp_connection *c = utcp->connections[i];
+
+ if(c->recv) {
+ errno = 0;
+ c->recv(c, NULL, 0);
+ }
+
+ if(utcp_reset_connection(c) != -1) {
+ c->reapable = false;
+ }
+ }
+
+ return;
}
-int utcp_abort(struct utcp_connection *c) {
+int utcp_reset_connection(struct utcp_connection *c) {
if(!c) {
errno = EFAULT;
return -1;
c->recv = NULL;
c->poll = NULL;
- c->reapable = true;
switch(c->state) {
case CLOSED:
return 0;
}
+int utcp_close(struct utcp_connection *c) {
+ if(utcp_shutdown(c, SHUT_RDWR) && errno != ENOTCONN) {
+ return -1;
+ }
+
+ c->recv = NULL;
+ c->poll = NULL;
+ c->reapable = true;
+ return 0;
+}
+
+int utcp_abort(struct utcp_connection *c) {
+ int utcp_reset_return;
+
+ utcp_reset_return = utcp_reset_connection(c);
+
+ if(utcp_reset_return != -1) {
+ c->reapable = true;
+ }
+
+ return utcp_reset_return;
+}
+
/* Handle timeouts.
* One call to this function will loop through all connections,
* checking if something needs to be resent or not.
}
size_t utcp_get_sndbuf_free(struct utcp_connection *c) {
- if (!c)
+ if(!c) {
return 0;
+ }
switch(c->state) {
case SYN_SENT:
extern void utcp_set_poll_cb(struct utcp_connection *connection, utcp_poll_t poll);
extern void utcp_set_accept_cb(struct utcp *utcp, utcp_accept_t accept, utcp_pre_accept_t pre_accept);
extern bool utcp_is_active(struct utcp *utcp);
+extern void utcp_abort_all_connections(struct utcp *utcp);
+extern int utcp_reset_connection(struct utcp_connection *c);
// Global socket options