diff --git a/tap.c b/tap.c index f8314ef..11ac732 100644 --- a/tap.c +++ b/tap.c @@ -747,14 +747,26 @@ redo: return -ECONNRESET; } - while (n > (ssize_t)sizeof(uint32_t)) { - ssize_t len = ntohl(*(uint32_t *)p); + while (n > 0) { + ssize_t len; + + /* Force receiving at least a complete length descriptor to + * avoid an inconsistent stream. + */ + if (n < (ssize_t)sizeof(uint32_t)) { + rem = recv(c->fd_tap, p + n, + (ssize_t)sizeof(uint32_t) - n, 0); + if ((n += rem) != (ssize_t)sizeof(uint32_t)) + return 0; + } + + len = ntohl(*(uint32_t *)p); p += sizeof(uint32_t); n -= sizeof(uint32_t); /* At most one packet might not fit in a single read, and this - * needs to be blocking. + * also needs to be blocking. */ if (len > n) { rem = recv(c->fd_tap, p + n, len - n, 0);