aboutgitcodebugslistschat
path: root/tap.c
diff options
context:
space:
mode:
Diffstat (limited to 'tap.c')
-rw-r--r--tap.c18
1 files changed, 15 insertions, 3 deletions
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);