+/**
+ * Read a DNS response from the (unhindered) UDP-Socket
+ *
+ * @param cls socket to read from
+ * @param tc scheduler context (must be shutdown or read ready)
+ */
+static void
+read_response (void *cls,
+ const struct GNUNET_SCHEDULER_TaskContext *tc);
+
+
+/**
+ * Get a socket of the specified address family to send out a
+ * UDP DNS request to the Internet.
+ *
+ * @param af desired address family
+ * @return NULL on error (given AF not "supported")
+ */
+static struct GNUNET_NETWORK_Handle *
+get_request_socket (int af)
+{
+ struct RequestSocket *rs;
+ struct GNUNET_NETWORK_FDSet *rset;
+ static struct GNUNET_NETWORK_Handle *ret;
+
+ rs = &sockets[GNUNET_CRYPTO_random_u32 (GNUNET_CRYPTO_QUALITY_NONCE,
+ DNS_SOCKET_MAX)];
+ rs->timeout = GNUNET_TIME_relative_to_absolute (REQUEST_TIMEOUT);
+ switch (af)
+ {
+ case AF_INET:
+ if (NULL == rs->dnsout4)
+ rs->dnsout4 = open_socket (AF_INET);
+ ret = rs->dnsout4;
+ break;
+ case AF_INET6:
+ if (NULL == rs->dnsout6)
+ rs->dnsout6 = open_socket (AF_INET6);
+ ret = rs->dnsout6;
+ break;
+ default:
+ return NULL;
+ }
+ if (GNUNET_SCHEDULER_NO_TASK != rs->read_task)
+ {
+ GNUNET_SCHEDULER_cancel (rs->read_task);
+ rs->read_task = GNUNET_SCHEDULER_NO_TASK;
+ }
+ if ( (NULL == rs->dnsout4) &&
+ (NULL == rs->dnsout6) )
+ return NULL;
+ rset = GNUNET_NETWORK_fdset_create ();
+ if (NULL != rs->dnsout4)
+ GNUNET_NETWORK_fdset_set (rset, rs->dnsout4);
+ if (NULL != rs->dnsout6)
+ GNUNET_NETWORK_fdset_set (rset, rs->dnsout6);
+ rs->read_task = GNUNET_SCHEDULER_add_select (GNUNET_SCHEDULER_PRIORITY_DEFAULT,
+ REQUEST_TIMEOUT,
+ rset,
+ NULL,
+ &read_response, rs);
+ GNUNET_NETWORK_fdset_destroy (rset);
+ return ret;
+}
+
+