slirp: check for ioctlsocket error and 0-length udp payload.
authorVic Lee <llyzs.vic@gmail.com>
Fri, 1 Mar 2019 06:48:09 +0000 (14:48 +0800)
committerSamuel Thibault <samuel.thibault@ens-lyon.org>
Wed, 6 Mar 2019 22:36:19 +0000 (23:36 +0100)
Sometimes sorecvfrom() is called from slirp.c because revents == G_IO_IN,
but there is 0 bytes available and recvfrom could be blocking indefinitely.
This is likely due to 0-length udp payload. This also adds an error
checking for ioctlsocket.

Signed-off-by: Vic Lee <llyzs.vic@gmail.com>
Message-Id: <20190301064809.3074-1-llyzs.vic@gmail.com>
Signed-off-by: Samuel Thibault <samuel.thibault@ens-lyon.org>
slirp/socket.c

index 4876ea3f315acb9d9ca0ef46f818080abdc3d40d..4dc5e2907d6cab1aef415026a89a7dc195d73be1 100644 (file)
@@ -529,6 +529,15 @@ sorecvfrom(struct socket *so)
           int n;
 #endif
 
+         if (ioctlsocket(so->s, FIONREAD, &n) != 0) {
+             DEBUG_MISC(" ioctlsocket errno = %d-%s\n",
+                        errno,strerror(errno));
+             return;
+         }
+         if (n == 0) {
+             return;
+         }
+
          m = m_get(so->slirp);
          if (!m) {
              return;
@@ -552,7 +561,6 @@ sorecvfrom(struct socket *so)
           */
          len = M_FREEROOM(m);
          /* if (so->so_fport != htons(53)) { */
-         ioctlsocket(so->s, FIONREAD, &n);
 
          if (n > len) {
            n = (m->m_data - m->m_dat) + m->m_len + n + 1;