]> git.meshlink.io Git - utcp/blobdiff - utcp.c
Introduce utcp_connect_ex().
[utcp] / utcp.c
diff --git a/utcp.c b/utcp.c
index b0ba05428926ba1dd11c7b91c942d27d1fae97e7..8143e0e8eae20906e974d51e4635f34abd2fda87 100644 (file)
--- a/utcp.c
+++ b/utcp.c
@@ -142,9 +142,6 @@ static int32_t seqdiff(uint32_t a, uint32_t b) {
 
 // Store data into the buffer
 static ssize_t buffer_put_at(struct buffer *buf, size_t offset, const void *data, size_t len) {
-       if(buf->maxsize <= buf->used)
-               return 0;
-
        debug("buffer_put_at %lu %lu %lu\n", (unsigned long)buf->used, (unsigned long)offset, (unsigned long)len);
 
        size_t required = offset + len;
@@ -381,11 +378,14 @@ static void stop_retransmit_timer(struct utcp_connection *c) {
        debug("timeout cleared\n");
 }
 
-struct utcp_connection *utcp_connect(struct utcp *utcp, uint16_t dst, utcp_recv_t recv, void *priv) {
+struct utcp_connection *utcp_connect_ex(struct utcp *utcp, uint16_t dst, utcp_recv_t recv, void *priv, uint32_t flags) {
        struct utcp_connection *c = allocate_connection(utcp, 0, dst);
        if(!c)
                return NULL;
 
+       assert((flags & ~0xf) == 0);
+
+       c->flags = flags;
        c->recv = recv;
        c->priv = priv;
 
@@ -410,6 +410,10 @@ struct utcp_connection *utcp_connect(struct utcp *utcp, uint16_t dst, utcp_recv_
        return c;
 }
 
+struct utcp_connection *utcp_connect(struct utcp *utcp, uint16_t dst, utcp_recv_t recv, void *priv) {
+       return utcp_connect_ex(utcp, dst, recv, priv, UTCP_TCP);
+}
+
 void utcp_accept(struct utcp_connection *c, utcp_recv_t recv, void *priv) {
        if(c->reapable || c->state != SYN_RECEIVED) {
                debug("Error: accept() called on invalid connection %p in state %s\n", c, strstate[c->state]);
@@ -893,14 +897,15 @@ ssize_t utcp_recv(struct utcp *utcp, const void *data, size_t len) {
 
                // cut already accepted front overlapping
                if(rcv_offset < 0) {
-                       acceptable = rcv_offset + len >= 0;
+                       acceptable = len > -rcv_offset;
                        if(acceptable) {
                                data -= rcv_offset;
                                len += rcv_offset;
+                               hdr.seq -= rcv_offset;
                        }
+               } else {
+                       acceptable = seqdiff(hdr.seq, c->rcv.nxt) >= 0 && seqdiff(hdr.seq, c->rcv.nxt) + len <= c->rcvbuf.maxsize;
                }
-
-               acceptable = seqdiff(hdr.seq, c->rcv.nxt) >= 0 && seqdiff(hdr.seq, c->rcv.nxt) + len <= c->rcvbuf.maxsize;
        }
 
        if(!acceptable) {
@@ -908,9 +913,8 @@ ssize_t utcp_recv(struct utcp *utcp, const void *data, size_t len) {
                // Ignore unacceptable RST packets.
                if(hdr.ctl & RST)
                        return 0;
-               // Otherwise, send an ACK back in the hope things improve.
-               ack(c, true);
-               return 0;
+               // Otherwise, continue processing.
+               len = 0;
        }
 
        c->snd.wnd = hdr.wnd; // TODO: move below