+ done :
+
+ return ok;
+}
+
+
+static Boolean
+check_matching_resolvers(SCDynamicStoreRef *storeP,
+ dns_config_t *dns_config,
+ const char *fqdn,
+ SCNetworkConnectionFlags *flags,
+ Boolean *haveDNS)
+{
+ int i;
+ Boolean matched = FALSE;
+ const char *name = fqdn;
+
+ while (!matched && (name != NULL)) {
+ int len;
+
+ /*
+ * check if the provided name (or sub-component)
+ * matches one of our resolver configurations.
+ */
+ len = strlen(name);
+ for (i = 0; i < dns_config->n_resolver; i++) {
+ char *domain;
+ dns_resolver_t *resolver;
+
+ resolver = dns_config->resolver[i];
+ domain = resolver->domain;
+ if (domain != NULL && (len == strlen(domain))) {
+ if (strcasecmp(name, domain) == 0) {
+ Boolean ok;
+
+ /*
+ * if name matches domain
+ */
+ matched = TRUE;
+ ok = check_resolver_reachability(storeP, resolver, flags, haveDNS);
+ if (!ok) {
+ /* not today */
+ return FALSE;
+ }
+ }
+ }
+ }
+
+ if (!matched) {
+ /*
+ * we have not found a matching resolver, try
+ * a less qualified domain
+ */
+ name = strchr(name, '.');
+ if ((name != NULL) && (*name != '\0')) {
+ name++;
+ } else {
+ name = NULL;
+ }
+ }
+ }
+
+ return matched;
+}
+
+
+static dns_configuration_t *
+dns_configuration_retain()
+{
+ pthread_mutex_lock(&dns_lock);
+
+ if ((dns_configuration != NULL) && dns_token_valid) {
+ int check = 0;
+ uint32_t status;
+
+ /*
+ * check if the global [DNS] configuration snapshot needs
+ * to be updated
+ */
+ status = notify_check(dns_token, &check);
+ if (status != NOTIFY_STATUS_OK) {
+ SCLog(TRUE, LOG_INFO, CFSTR("notify_check() failed, status=%lu"), status);
+ }
+
+ if ((status != NOTIFY_STATUS_OK) || (check != 0)) {
+ /*
+ * if the snapshot needs to be refreshed
+ */
+ if (dns_configuration->refs == 0) {
+ dns_configuration_free(dns_configuration->config);
+ CFAllocatorDeallocate(NULL, dns_configuration);
+ }
+ dns_configuration = NULL;
+ }
+ }
+
+ if (dns_configuration == NULL) {
+ dns_config_t *new_config;