Index: gstudpnetutils.c
===================================================================
--- gstudpnetutils.c	(revision 33)
+++ gstudpnetutils.c	(working copy)
@@ -54,7 +54,86 @@
 
 #endif
 
+int gst_udp_socket_create  (GstUdpSocket *sock)
+{
+  int ret4, ret6;
+
+  if ((ret4 = socket  (AF_INET, SOCK_DGRAM, 0)) < 0)
+    return ret4;
+
+  if ((ret6 = socket  (AF_INET6, SOCK_DGRAM, 0)) < 0) {
+#if 0
+    if (errno != EAFNOSUPPORT) {
+      close(ret4);
+      return ret6;
+    }
+#endif
+  }
+  sock->sock4 = ret4;
+  sock->sock6 = ret6;
+
+  return 0;
+}
+
+int gst_udp_socket_close  (GstUdpSocket *sock)
+{
+  int ret4, ret6;
+
+  ret4 = CLOSE_SOCKET(sock->sock4);
+  sock->sock4 = -1;
+
+  if (sock->sock6 < 0)
+    return ret4;
+
+  ret6 = CLOSE_SOCKET(sock->sock6);
+  sock->sock6 = -1;
+
+  return (ret4 < 0) ? ret4 : ret6;
+}
+
 int
+gst_udp_socket_set_options  (const GstUdpSocket *sock, int level, int option, const void *option_value, size_t value_len)
+{
+  int ret;
+
+  ret = setsockopt (sock->sock4, level, option, option_value, value_len);
+  if (ret < 0 || sock->sock6 < 0)
+    return ret;
+  ret = setsockopt (sock->sock6, level, option, option_value, value_len);
+
+  return ret;
+}
+
+int
+gst_udp_socket_set_loop_ttl  (const GstUdpSocket *sock, gboolean loop, int ttl)
+{
+  int ret;
+
+  ret = gst_udp_set_loop_ttl  (sock->sock4, loop, ttl);
+  if (ret < 0 || sock->sock6 < 0)
+    return ret;
+  ret = gst_udp_set_loop_ttl  (sock->sock6, loop, ttl);
+
+  return ret;
+}
+
+int
+gst_udp_socket_set_tos  (const GstUdpSocket *sock, gint tos)
+{
+  int ret;
+
+  ret = setsockopt (sock->sock4, IPPROTO_IP, IP_TOS, &tos, sizeof (tos));
+#ifdef IPV6_TCLASS
+  if (ret < 0 || sock->sock6 < 0)
+    return ret;
+  ret = setsockopt (sock->sock6, IPPROTO_IPV6, IPV6_TCLASS, &tos,
+          sizeof (tos));
+#endif
+
+  return ret;
+}
+
+int
 gst_udp_get_addr (const char *hostname, int port, struct sockaddr_storage *addr)
 {
   struct addrinfo hints, *res, *nres;
Index: gstudpnetutils.h
===================================================================
--- gstudpnetutils.h	(revision 33)
+++ gstudpnetutils.h	(working copy)
@@ -71,6 +71,18 @@
 
 #endif
 
+typedef struct {
+  int sock4;
+  int sock6;
+
+} GstUdpSocket;
+
+int gst_udp_socket_create                (GstUdpSocket *sock);
+int gst_udp_socket_close                 (GstUdpSocket *sock);
+int gst_udp_socket_set_options           (const GstUdpSocket *sock, int level, int option, const void *option_value, size_t value_len);
+int gst_udp_socket_set_loop_ttl          (const GstUdpSocket *sock, gboolean loop, int ttl);
+int gst_udp_socket_set_tos               (const GstUdpSocket *sock, gint tos);
+
 int gst_udp_get_addr      (const char *hostname, int port, struct sockaddr_storage *addr);
 int gst_udp_is_multicast  (struct sockaddr_storage *addr);
 
Index: gstmultiudpsink.c
===================================================================
--- gstmultiudpsink.c	(revision 33)
+++ gstmultiudpsink.c	(working copy)
@@ -106,8 +106,7 @@
 
 #define CLOSE_IF_REQUESTED(udpctx)                                        \
   if ((!udpctx->externalfd) || (udpctx->externalfd && udpctx->closefd))   \
-    CLOSE_SOCKET(udpctx->sock);                                           \
-  udpctx->sock = -1;
+    gst_udp_socket_close(&udpctx->sock);
 
 static void gst_multiudpsink_base_init (gpointer g_class);
 static void gst_multiudpsink_class_init (GstMultiUDPSinkClass * klass);
@@ -332,7 +331,8 @@
   WSA_STARTUP (sink);
 
   sink->client_lock = g_mutex_new ();
-  sink->sock = -1;
+  sink->sock.sock4 = -1;
+  sink->sock.sock6 = -1;
   sink->sockfd = DEFAULT_SOCKFD;
   sink->closefd = DEFAULT_CLOSEFD;
   sink->externalfd = (sink->sockfd != -1);
@@ -488,7 +488,7 @@
   if (sink->qos_dscp < 0)
     return;
 
-  if (sink->sock < 0)
+  if (sink->sock.sock4 < 0)
     return;
 
   GST_DEBUG_OBJECT (sink, "setting TOS to %d", sink->qos_dscp);
@@ -496,15 +496,9 @@
   /* 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 (gst_udp_socket_set_tos (&sink->sock, 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,
-          sizeof (tos)) < 0) {
-    GST_ERROR_OBJECT (sink, "could not set TCLASS: %s", g_strerror (errno));
-  }
-#endif
 }
 
 static void
@@ -567,7 +561,8 @@
       g_value_set_boolean (value, udpsink->closefd);
       break;
     case PROP_SOCK:
-      g_value_set_int (value, udpsink->sock);
+      /* FIXME: should we add a PROP_SOCK6 ?? */
+      g_value_set_int (value, udpsink->sock.sock4);
       break;
     case PROP_CLIENTS:
       g_value_take_string (value,
@@ -601,28 +596,28 @@
   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)
-        goto no_socket;
+    /* create sender socket */
+    if (gst_udp_socket_create (&sink->sock) == -1)
+      goto no_socket;
 
     sink->externalfd = FALSE;
   } else {
     /* we use the configured socket */
-    sink->sock = sink->sockfd;
+    /* FIXME: need external socket for IP6 */
+    sink->sock.sock4 = sink->sockfd;
     sink->externalfd = TRUE;
   }
 
   bc_val = 1;
   if ((ret =
-          setsockopt (sink->sock, SOL_SOCKET, SO_BROADCAST, &bc_val,
-              sizeof (bc_val))) < 0)
+          gst_udp_socket_set_options (&sink->sock, 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_socket_set_loop_ttl (&sink->sock, sink->loop, sink->ttl);
   gst_multiudpsink_setup_qos_dscp (sink);
 
   /* look for multicast clients and join multicast groups approptiately */
@@ -667,11 +662,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->sock.sock6;
+  else
+    client->sock = &sink->sock.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,7 @@
 struct _GstMultiUDPSink {
   GstBaseSink parent;
 
-  int sock;
+  GstUdpSocket sock;
 
   GMutex        *client_lock;
   GList         *clients;
