static inline void list_connections(struct utcp *utcp) {
debug("%p has %d connections:\n", utcp, utcp->nconnections);
for(int i = 0; i < utcp->nconnections; i++)
static inline void list_connections(struct utcp *utcp) {
debug("%p has %d connections:\n", utcp, utcp->nconnections);
for(int i = 0; i < utcp->nconnections; i++)
}
print_packet(c->utcp, "send", pkt, sizeof pkt->hdr + seglen);
}
print_packet(c->utcp, "send", pkt, sizeof pkt->hdr + seglen);
pkt->hdr.seq = c->snd.nxt;
pkt->hdr.ack = c->rcv.nxt;
pkt->hdr.ctl = SYN | ACK;
pkt->hdr.seq = c->snd.nxt;
pkt->hdr.ack = c->rcv.nxt;
pkt->hdr.ctl = SYN | ACK;
buffer_copy(&c->sndbuf, pkt->data, 0, len);
print_packet(c->utcp, "rtrx", pkt, sizeof pkt->hdr + len);
utcp->send(utcp, pkt, sizeof pkt->hdr + len);
break;
buffer_copy(&c->sndbuf, pkt->data, 0, len);
print_packet(c->utcp, "rtrx", pkt, sizeof pkt->hdr + len);
utcp->send(utcp, pkt, sizeof pkt->hdr + len);
break;
- debug("%p shutdown %d at %u\n", c ? c->utcp : NULL, dir, c->snd.last);
+ debug("%p shutdown %d at %u\n", c ? c->utcp : NULL, dir, c ? c->snd.last : 0);
- // TODO: handle dir
- // TODO: check that repeated calls with the same parameters should have no effect
+ if(!(dir == UTCP_SHUT_RD || dir == UTCP_SHUT_WR || dir == UTCP_SHUT_RDWR)) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ // TCP does not have a provision for stopping incoming packets.
+ // The best we can do is to just ignore them.
+ if(dir == UTCP_SHUT_RD || dir == UTCP_SHUT_RDWR)
+ c->recv = NULL;
+
+ // The rest of the code deals with shutting down writes.
+ if(dir == UTCP_SHUT_RD)
+ return 0;
struct utcp *utcp_init(utcp_accept_t accept, utcp_pre_accept_t pre_accept, utcp_send_t send, void *priv) {
struct utcp *utcp = calloc(1, sizeof *utcp);
if(!utcp)
struct utcp *utcp_init(utcp_accept_t accept, utcp_pre_accept_t pre_accept, utcp_send_t send, void *priv) {
struct utcp *utcp = calloc(1, sizeof *utcp);
if(!utcp)