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)
}
void utcp_set_mtu(struct utcp *utcp, uint16_t mtu) {
// TODO: handle overhead of the header
}
void utcp_set_mtu(struct utcp *utcp, uint16_t mtu) {
// TODO: handle overhead of the header
return buffer_free(&c->sndbuf);
else
return 0;
}
void utcp_set_sndbuf(struct utcp_connection *c, size_t size) {
return buffer_free(&c->sndbuf);
else
return 0;
}
void utcp_set_sndbuf(struct utcp_connection *c, size_t size) {
c->sndbuf.maxsize = size;
if(c->sndbuf.maxsize != size)
c->sndbuf.maxsize = -1;
}
bool utcp_get_nodelay(struct utcp_connection *c) {
c->sndbuf.maxsize = size;
if(c->sndbuf.maxsize != size)
c->sndbuf.maxsize = -1;
}
bool utcp_get_nodelay(struct utcp_connection *c) {