]> git.meshlink.io Git - utcp/blobdiff - utcp.c
Handle the case where we reduce the buffer size below the amount currently used.
[utcp] / utcp.c
diff --git a/utcp.c b/utcp.c
index 9fa37b9f18671941da9b582e5157974df1dbe091..6279d925a781814eeb06710c406fa47063c2f052 100644 (file)
--- a/utcp.c
+++ b/utcp.c
@@ -74,6 +74,7 @@ static bool timespec_lt(const struct timespec *a, const struct timespec *b) {
 
 static void timespec_clear(struct timespec *a) {
        a->tv_sec = 0;
+       a->tv_nsec = 0;
 }
 
 static bool timespec_isset(const struct timespec *a) {
@@ -400,7 +401,7 @@ static void buffer_exit(struct buffer *buf) {
 }
 
 static uint32_t buffer_free(const struct buffer *buf) {
-       return buf->maxsize - buf->used;
+       return buf->maxsize > buf->used ? buf->maxsize - buf->used : 0;
 }
 
 // Connections are stored in a sorted list.
@@ -579,7 +580,7 @@ static void start_retransmit_timer(struct utcp_connection *c) {
                rto -= USEC_PER_SEC;
        }
 
-       c->rtrx_timeout.tv_nsec += c->rto * 1000;
+       c->rtrx_timeout.tv_nsec += rto * 1000;
 
        if(c->rtrx_timeout.tv_nsec >= NSEC_PER_SEC) {
                c->rtrx_timeout.tv_nsec -= NSEC_PER_SEC;
@@ -1045,8 +1046,14 @@ static void handle_out_of_order(struct utcp_connection *c, uint32_t offset, cons
        // Packet loss or reordering occured. Store the data in the buffer.
        ssize_t rxd = buffer_put_at(&c->rcvbuf, offset, data, len);
 
-       if(rxd < 0 || (size_t)rxd < len) {
-               abort();
+       if(rxd <= 0) {
+               debug(c, "packet outside receive buffer, dropping\n");
+               return;
+       }
+
+       if((size_t)rxd < len) {
+               debug(c, "packet partially outside receive buffer\n");
+               len = rxd;
        }
 
        // Make note of where we put it.
@@ -1168,10 +1175,6 @@ static void handle_incoming_data(struct utcp_connection *c, const struct hdr *hd
 
        uint32_t offset = seqdiff(hdr->seq, c->rcv.nxt);
 
-       if(offset + len > c->rcvbuf.maxsize) {
-               abort();
-       }
-
        if(offset) {
                handle_out_of_order(c, offset, data, len);
        } else {