X-Git-Url: http://git.meshlink.io/?a=blobdiff_plain;f=utcp.c;h=21fbea6c4eea4df28380098bdff43edb33441775;hb=a521d405a461b3384cd70daf95a2219d72db3eb1;hp=f46cdf7f649f0ee4ef77b0c8ebe0a673d5f24af0;hpb=0325c97f314cbab10cf9fce374598502e43341e6;p=utcp diff --git a/utcp.c b/utcp.c index f46cdf7..21fbea6 100644 --- a/utcp.c +++ b/utcp.c @@ -366,7 +366,7 @@ static void ack(struct utcp_connection *c, bool sendatleastone) { c->snd.nxt += seglen; left -= seglen; - if(c->state != ESTABLISHED && !left && seglen) { + if(c->state != ESTABLISHED && seglen && c->snd.nxt == c->snd.last) { switch(c->state) { case FIN_WAIT_1: case CLOSING: @@ -486,7 +486,6 @@ static void retransmit(struct utcp_connection *c) { pkt->hdr.ack = c->rcv.nxt; pkt->hdr.ctl = ACK; uint32_t len = seqdiff(c->snd.nxt, c->snd.una); - fprintf(stderr, "retransmit %u %u %u\n", pkt->hdr.seq, pkt->hdr.ack, len); if(c->state == FIN_WAIT_1) len--; if(len > utcp->mtu) @@ -782,7 +781,6 @@ ssize_t utcp_recv(struct utcp *utcp, const void *data, size_t len) { c->dupack++; if(c->dupack == 3) { debug("Triplicate ACK\n"); - fprintf(stderr, "Triplicate ACK\n"); //TODO: Resend one packet and go to fast recovery mode. See RFC 6582. //We do a very simple variant here; reset the nxt pointer to the last acknowledged packet from the peer. //This will cause us to start retransmitting, but at the same speed as the incoming ACKs arrive, @@ -956,7 +954,7 @@ reset: } int utcp_shutdown(struct utcp_connection *c, int dir) { - debug("%p shutdown %d\n", c ? c->utcp : NULL, dir); + debug("%p shutdown %d at %u\n", c ? c->utcp : NULL, dir, c->snd.last); if(!c) { errno = EFAULT; return -1; @@ -969,6 +967,7 @@ int utcp_shutdown(struct utcp_connection *c, int dir) { } // TODO: handle dir + // TODO: check that repeated calls with the same parameters should have no effect switch(c->state) { case CLOSED: @@ -1155,60 +1154,71 @@ void utcp_exit(struct utcp *utcp) { } uint16_t utcp_get_mtu(struct utcp *utcp) { - return utcp->mtu; + return utcp ? utcp->mtu : 0; } void utcp_set_mtu(struct utcp *utcp, uint16_t mtu) { // TODO: handle overhead of the header - utcp->mtu = mtu; + if(utcp) + utcp->mtu = mtu; } int utcp_get_user_timeout(struct utcp *u) { - return u->timeout; + return u ? u->timeout : 0; } void utcp_set_user_timeout(struct utcp *u, int timeout) { - u->timeout = timeout; + if(u) + u->timeout = timeout; } size_t utcp_get_sndbuf(struct utcp_connection *c) { - return c->sndbuf.maxsize; + return c ? c->sndbuf.maxsize : 0; } size_t utcp_get_sndbuf_free(struct utcp_connection *c) { - return buffer_free(&c->sndbuf); + if(c && (c->state == ESTABLISHED || c->state == CLOSE_WAIT)) + return buffer_free(&c->sndbuf); + else + return 0; } void utcp_set_sndbuf(struct utcp_connection *c, size_t size) { + if(!c) + return; c->sndbuf.maxsize = size; if(c->sndbuf.maxsize != size) c->sndbuf.maxsize = -1; } bool utcp_get_nodelay(struct utcp_connection *c) { - return c->nodelay; + return c ? c->nodelay : false; } void utcp_set_nodelay(struct utcp_connection *c, bool nodelay) { - c->nodelay = nodelay; + if(c) + c->nodelay = nodelay; } bool utcp_get_keepalive(struct utcp_connection *c) { - return c->keepalive; + return c ? c->keepalive : false; } void utcp_set_keepalive(struct utcp_connection *c, bool keepalive) { - c->keepalive = keepalive; + if(c) + c->keepalive = keepalive; } size_t utcp_get_outq(struct utcp_connection *c) { - return seqdiff(c->snd.nxt, c->snd.una); + return c ? seqdiff(c->snd.nxt, c->snd.una) : 0; } void utcp_set_recv_cb(struct utcp_connection *c, utcp_recv_t recv) { - c->recv = recv; + if(c) + c->recv = recv; } void utcp_set_poll_cb(struct utcp_connection *c, utcp_poll_t poll) { - c->poll = poll; + if(c) + c->poll = poll; }