Index: gstmultiudpsink.c
===================================================================
--- gstmultiudpsink.c	(revision 33)
+++ gstmultiudpsink.c	(working copy)
@@ -93,9 +93,12 @@
   PROP_0,
   PROP_BYTES_TO_SERVE,
   PROP_BYTES_SERVED,
-  PROP_SOCKFD,
-  PROP_CLOSEFD,
-  PROP_SOCK,
+  PROP_SOCKFD4,
+  PROP_CLOSEFD4,
+  PROP_SOCK4,
+  PROP_SOCKFD6,
+  PROP_CLOSEFD6,
+  PROP_SOCK6,
   PROP_CLIENTS,
   PROP_AUTO_MULTICAST,
   PROP_TTL,
@@ -104,10 +107,13 @@
   PROP_LAST
 };
 
-#define CLOSE_IF_REQUESTED(udpctx)                                        \
-  if ((!udpctx->externalfd) || (udpctx->externalfd && udpctx->closefd))   \
-    CLOSE_SOCKET(udpctx->sock);                                           \
-  udpctx->sock = -1;
+#define CLOSE_IF_REQUESTED(udpctx)                                         \
+  if ((!udpctx->externalfd4) || (udpctx->externalfd4 && udpctx->closefd4)) \
+    CLOSE_SOCKET(udpctx->sock4);                                           \
+  udpctx->sock4 = -1;                                                      \
+  if ((!udpctx->externalfd6) || (udpctx->externalfd6 && udpctx->closefd6)) \
+    CLOSE_SOCKET(udpctx->sock6);                                           \
+  udpctx->sock6 = -1;
 
 static void gst_multiudpsink_base_init (gpointer g_class);
 static void gst_multiudpsink_class_init (GstMultiUDPSinkClass * klass);
@@ -280,18 +286,30 @@
       g_param_spec_uint64 ("bytes-served", "Bytes served",
           "Total number of bytes send to all clients", 0, G_MAXUINT64, 0,
           G_PARAM_READABLE));
-  g_object_class_install_property (gobject_class, PROP_SOCKFD,
-      g_param_spec_int ("sockfd", "Socket Handle",
+  g_object_class_install_property (gobject_class, PROP_SOCKFD4,
+      g_param_spec_int ("sockfd4", "Socket Handle for IP4",
           "Socket to use for UDP sending. (-1 == allocate)",
           -1, G_MAXINT, DEFAULT_SOCKFD, G_PARAM_READWRITE));
-  g_object_class_install_property (gobject_class, PROP_CLOSEFD,
-      g_param_spec_boolean ("closefd", "Close sockfd",
-          "Close sockfd if passed as property on state change",
+  g_object_class_install_property (gobject_class, PROP_CLOSEFD4,
+      g_param_spec_boolean ("closefd4", "Close sockfd4",
+          "Close sockfd4 if passed as property on state change",
           DEFAULT_CLOSEFD, G_PARAM_READWRITE));
-  g_object_class_install_property (gobject_class, PROP_SOCK,
-      g_param_spec_int ("sock", "Socket Handle",
+  g_object_class_install_property (gobject_class, PROP_SOCK4,
+      g_param_spec_int ("sock4", "Socket Handle for IP4",
           "Socket currently in use for UDP sending. (-1 == no socket)",
           -1, G_MAXINT, DEFAULT_SOCK, G_PARAM_READABLE));
+  g_object_class_install_property (gobject_class, PROP_SOCKFD6,
+      g_param_spec_int ("sockfd6", "Socket Handle for IP6",
+          "Socket to use for UDP sending. (-1 == allocate)",
+          -1, G_MAXINT, DEFAULT_SOCKFD, G_PARAM_READWRITE));
+  g_object_class_install_property (gobject_class, PROP_CLOSEFD6,
+      g_param_spec_boolean ("closefd6", "Close sockfd6",
+          "Close sockfd4 if passed as property on state change",
+          DEFAULT_CLOSEFD, G_PARAM_READWRITE));
+  g_object_class_install_property (gobject_class, PROP_SOCK6,
+      g_param_spec_int ("sock6", "Socket Handle for IP6",
+          "Socket currently in use for UDP sending. (-1 == no socket)",
+          -1, G_MAXINT, DEFAULT_SOCK, G_PARAM_READABLE));
   g_object_class_install_property (gobject_class, PROP_CLIENTS,
       g_param_spec_string ("clients", "Clients",
           "A comma separated list of host:port pairs with destinations",
@@ -332,10 +350,14 @@
   WSA_STARTUP (sink);
 
   sink->client_lock = g_mutex_new ();
-  sink->sock = -1;
-  sink->sockfd = DEFAULT_SOCKFD;
-  sink->closefd = DEFAULT_CLOSEFD;
-  sink->externalfd = (sink->sockfd != -1);
+  sink->sock4 = -1;
+  sink->sock6 = -1;
+  sink->sockfd4 = DEFAULT_SOCKFD;
+  sink->sockfd6 = DEFAULT_SOCKFD;
+  sink->closefd4 = DEFAULT_CLOSEFD;
+  sink->closefd6 = DEFAULT_CLOSEFD;
+  sink->externalfd4 = (sink->sockfd4 != -1);
+  sink->externalfd6 = (sink->sockfd6 != -1);
   sink->auto_multicast = DEFAULT_AUTO_MULTICAST;
   sink->ttl = DEFAULT_TTL;
   sink->loop = DEFAULT_LOOP;
@@ -488,7 +510,7 @@
   if (sink->qos_dscp < 0)
     return;
 
-  if (sink->sock < 0)
+  if (sink->sock4 < 0)
     return;
 
   GST_DEBUG_OBJECT (sink, "setting TOS to %d", sink->qos_dscp);
@@ -496,11 +518,14 @@
   /* Extract and shift 6 bits of DSFIELD */
   tos = (sink->qos_dscp & 0x3f) << 2;
 
-  if (setsockopt (sink->sock, IPPROTO_IP, IP_TOS, &tos, sizeof (tos)) < 0) {
+  if (setsockopt (sink->sock4, IPPROTO_IP, IP_TOS, &tos, sizeof (tos)) < 0) {
     GST_ERROR_OBJECT (sink, "could not set TOS: %s", g_strerror (errno));
   }
 #ifdef IPV6_TCLASS
-  if (setsockopt (sink->sock, IPPROTO_IPV6, IPV6_TCLASS, &tos,
+  if (sink->sock6 < 0)
+    return;
+
+  if (setsockopt (sink->sock6, IPPROTO_IPV6, IPV6_TCLASS, &tos,
           sizeof (tos)) < 0) {
     GST_ERROR_OBJECT (sink, "could not set TCLASS: %s", g_strerror (errno));
   }
@@ -516,13 +541,20 @@
   udpsink = GST_MULTIUDPSINK (object);
 
   switch (prop_id) {
-    case PROP_SOCKFD:
-      udpsink->sockfd = g_value_get_int (value);
-      GST_DEBUG_OBJECT (udpsink, "setting SOCKFD to %d", udpsink->sockfd);
+    case PROP_SOCKFD4:
+      udpsink->sockfd4 = g_value_get_int (value);
+      GST_DEBUG_OBJECT (udpsink, "setting SOCKFD4 to %d", udpsink->sockfd4);
       break;
-    case PROP_CLOSEFD:
-      udpsink->closefd = g_value_get_boolean (value);
+    case PROP_CLOSEFD4:
+      udpsink->closefd4 = g_value_get_boolean (value);
       break;
+    case PROP_SOCKFD6:
+      udpsink->sockfd6 = g_value_get_int (value);
+      GST_DEBUG_OBJECT (udpsink, "setting SOCKFD6 to %d", udpsink->sockfd6);
+      break;
+    case PROP_CLOSEFD6:
+      udpsink->closefd6 = g_value_get_boolean (value);
+      break;
     case PROP_CLIENTS:
       gst_multiudpsink_set_clients_string (udpsink, g_value_get_string (value));
       break;
@@ -560,15 +592,24 @@
     case PROP_BYTES_SERVED:
       g_value_set_uint64 (value, udpsink->bytes_served);
       break;
-    case PROP_SOCKFD:
-      g_value_set_int (value, udpsink->sockfd);
+    case PROP_SOCKFD4:
+      g_value_set_int (value, udpsink->sockfd4);
       break;
-    case PROP_CLOSEFD:
-      g_value_set_boolean (value, udpsink->closefd);
+    case PROP_CLOSEFD4:
+      g_value_set_boolean (value, udpsink->closefd4);
       break;
-    case PROP_SOCK:
-      g_value_set_int (value, udpsink->sock);
+    case PROP_SOCK4:
+      g_value_set_int (value, udpsink->sock4);
       break;
+    case PROP_SOCKFD6:
+      g_value_set_int (value, udpsink->sockfd6);
+      break;
+    case PROP_CLOSEFD6:
+      g_value_set_boolean (value, udpsink->closefd6);
+      break;
+    case PROP_SOCK6:
+      g_value_set_int (value, udpsink->sock6);
+      break;
     case PROP_CLIENTS:
       g_value_take_string (value,
           gst_multiudpsink_get_clients_string (udpsink));
@@ -600,29 +641,54 @@
   GList *clients;
   GstUDPClient *client;
 
-  if (sink->sockfd == -1) {
-    /* create sender socket try IP6, fall back to IP4 */
-    if ((sink->sock = socket (AF_INET6, SOCK_DGRAM, 0)) == -1)
-      if ((sink->sock = socket (AF_INET, SOCK_DGRAM, 0)) == -1)
+  if (sink->sockfd4 == -1) {
+    /* create sender socket for IP4 */
+    if ((sink->sock4 = socket (AF_INET, SOCK_DGRAM, 0)) < 0)
+      goto no_socket;
+
+    sink->externalfd4 = FALSE;
+  } else {
+    /* we use the configured socket */
+    sink->sock4 = sink->sockfd4;
+    sink->externalfd4 = TRUE;
+  }
+
+  if (sink->sockfd6 == -1) {
+    /* create sender socket for IP6 */
+    if ((sink->sock6 = socket (AF_INET6, SOCK_DGRAM, 0)) < 0) {
+#if 0
+      if (errno != EAFNOSUPPORT) {
+        close(sink->sock4);
+        sink->sock4 = -1;
         goto no_socket;
+      }
+#endif
+    }
 
-    sink->externalfd = FALSE;
+    sink->externalfd6 = FALSE;
   } else {
     /* we use the configured socket */
-    sink->sock = sink->sockfd;
-    sink->externalfd = TRUE;
+    sink->sock6 = sink->sockfd6;
+    sink->externalfd6 = TRUE;
   }
 
   bc_val = 1;
   if ((ret =
-          setsockopt (sink->sock, SOL_SOCKET, SO_BROADCAST, &bc_val,
-              sizeof (bc_val))) < 0)
+          setsockopt (sink->sock4, SOL_SOCKET, SO_BROADCAST,
+              &bc_val, sizeof (bc_val))) < 0)
     goto no_broadcast;
 
+  if (sink->sock6 != -1 && (ret =
+          setsockopt (sink->sock6, SOL_SOCKET, SO_BROADCAST,
+              &bc_val, sizeof (bc_val))) < 0)
+    goto no_broadcast;
+
   sink->bytes_to_serve = 0;
   sink->bytes_served = 0;
 
-  gst_udp_set_loop_ttl (sink->sock, sink->loop, sink->ttl);
+  gst_udp_set_loop_ttl (sink->sock4, sink->loop, sink->ttl);
+  if (sink->sock6 != -1)
+    gst_udp_set_loop_ttl (sink->sock6, sink->loop, sink->ttl);
   gst_multiudpsink_setup_qos_dscp (sink);
 
   /* look for multicast clients and join multicast groups approptiately */
@@ -667,11 +733,16 @@
   client = g_new0 (GstUDPClient, 1);
   client->host = g_strdup (host);
   client->port = port;
-  client->sock = &sink->sock;
 
   if (gst_udp_get_addr (host, port, &client->theiraddr) < 0)
     goto getaddrinfo_error;
 
+  /* point the client to correct socket family */
+  if (client->theiraddr.ss_family == AF_INET6)
+    client->sock = &sink->sock6;
+  else
+    client->sock = &sink->sock4;
+
   g_get_current_time (&now);
   client->connect_time = GST_TIMEVAL_TO_TIME (now);
 
Index: gstmultiudpsink.h
===================================================================
--- gstmultiudpsink.h	(revision 33)
+++ gstmultiudpsink.h	(working copy)
@@ -57,7 +57,8 @@
 struct _GstMultiUDPSink {
   GstBaseSink parent;
 
-  int sock;
+  int sock4;
+  int sock6;
 
   GMutex        *client_lock;
   GList         *clients;
@@ -65,10 +66,13 @@
   /* properties */
   guint64        bytes_to_serve;
   guint64        bytes_served;
-  int            sockfd;
-  gboolean       closefd;
+  int            sockfd4;
+  int            sockfd6;
+  gboolean       closefd4;
+  gboolean       closefd6;
 
-  gboolean       externalfd;
+  gboolean       externalfd4;
+  gboolean       externalfd6;
 
   gboolean       auto_multicast;
   gint           ttl;
