udp-bsd: Fix recv with small buffer on Windows
authorJakub Adam <jakub.adam@collabora.com>
Tue, 18 Dec 2018 09:36:53 +0000 (10:36 +0100)
committerJakub Adam <jakub.adam@collabora.com>
Tue, 18 Dec 2018 17:34:19 +0000 (18:34 +0100)
The underlying GSocket implementation on Windows returns an error when
the user-provided buffer isn't large enough to fit the whole datagram
received on a message-oriented socket.

When this occurs, in order to preserve identical behavior of udp-bsd
NiceSocket across platforms, we have to mute the error and set the
received message length to the size of the provided NiceInputMessage.
Any excess portion of the message gets discarded.

Fixed udp-bsd test on Windows.

GLib 2.48 is required in order to use G_IO_ERROR_MESSAGE_TOO_LARGE.

configure.ac
meson.build
socket/udp-bsd.c

index ddcc4e4..91aa946 100644 (file)
@@ -95,7 +95,7 @@ AC_CHECK_HEADERS([ifaddrs.h],
 AC_CHECK_TYPES([size_t, ssize_t])
 
 # Also put matching version in LIBNICE_CFLAGS
-GLIB_REQ=2.44
+GLIB_REQ=2.48
 
 LIBNICE_CFLAGS="-DGLIB_VERSION_MIN_REQUIRED=GLIB_VERSION_2_44 -DGLIB_VERSION_MAX_ALLOWED=GLIB_VERSION_2_44"
 
index a06cb4e..70c5b50 100644 (file)
@@ -18,7 +18,7 @@ endif
 soversion = 10
 libversion = '10.6.2'
 
-glib_req = '>= 2.44'
+glib_req = '>= 2.48'
 gnutls_req = '>= 2.12.0'
 gupnp_igd_req = '>= 0.2.4'
 gst_req = '>= 1.0.0'
index 0fa8dd7..6d55e15 100644 (file)
@@ -206,20 +206,22 @@ socket_recv_messages (NiceSocket *sock,
         recv_message->buffers, recv_message->n_buffers, NULL, NULL,
         &flags, NULL, &gerr);
 
-    recv_message->length = MAX (recvd, 0);
-
     if (recvd < 0) {
       /* Handle ECONNRESET here as if it were EWOULDBLOCK; see
        * https://phabricator.freedesktop.org/T121 */
       if (g_error_matches (gerr, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK) ||
           g_error_matches (gerr, G_IO_ERROR, G_IO_ERROR_CONNECTION_CLOSED))
         recvd = 0;
+      else if (g_error_matches (gerr, G_IO_ERROR, G_IO_ERROR_MESSAGE_TOO_LARGE))
+        recvd = input_message_get_size (recv_message);
       else
         error = TRUE;
 
       g_error_free (gerr);
     }
 
+    recv_message->length = MAX (recvd, 0);
+
     if (recvd > 0 && recv_message->from != NULL && gaddr != NULL) {
       union {
         struct sockaddr_storage storage;