static void discoveryZeroconfWatcher_updateWatchedHosts()

in bundles/remote_services/discovery_zeroconf/src/discovery_zeroconf_watcher.c [795:871]


static void discoveryZeroconfWatcher_updateWatchedHosts(discovery_zeroconf_watcher_t *watcher, unsigned int *pNextWorkIntervalTime) {
    unsigned int nextWorkIntervalTime = *pNextWorkIntervalTime;
    //mark deleted hosts
    CELIX_STRING_HASH_MAP_ITERATE(watcher->watchedHosts, iter) {
        watched_host_entry_t *hostEntry = (watched_host_entry_t *)iter.value.ptrValue;
        hostEntry->markDeleted = true;
    }

    //add or mark hosts
    CELIX_STRING_HASH_MAP_ITERATE(watcher->watchedServices, iter) {
        watched_service_entry_t *svcEntry = (watched_service_entry_t *) iter.value.ptrValue;
        if (svcEntry->hostname != NULL && svcEntry->ifIndex != kDNSServiceInterfaceIndexLocalOnly) {
            celix_autofree watched_host_entry_t *hostEntry = discoveryZeroconfWatcher_getHostEntry(watcher, svcEntry->hostname, svcEntry->ifIndex);
            if (hostEntry != NULL) {
                hostEntry->markDeleted = false;
                celix_steal_ptr(hostEntry);
            } else {
                hostEntry = (watched_host_entry_t *)calloc(1, sizeof(*hostEntry));
                if (hostEntry == NULL) {
                    nextWorkIntervalTime = MIN(nextWorkIntervalTime, DZC_MAX_RETRY_INTERVAL);//retry after 5 seconds
                    celix_logHelper_error(watcher->logHelper, "Watcher: Failed to alloc host entry for %s.", svcEntry->instanceName);
                    continue;
                }
                celix_autoptr(celix_string_hash_map_t) ipAddresses = hostEntry->ipAddresses = celix_stringHashMap_create();
                if (ipAddresses == NULL) {
                    nextWorkIntervalTime = MIN(nextWorkIntervalTime, DZC_MAX_RETRY_INTERVAL);//retry after 5 seconds
                    celix_logHelper_error(watcher->logHelper, "Watcher: Failed to alloc ip address list for %s.", svcEntry->instanceName);
                    continue;
                }
                celix_autofree char *hostname = hostEntry->hostname = celix_utils_strdup(svcEntry->hostname);
                if (hostname == NULL) {
                    nextWorkIntervalTime = MIN(nextWorkIntervalTime, DZC_MAX_RETRY_INTERVAL);//retry after 5 seconds
                    celix_logHelper_error(watcher->logHelper, "Watcher: Failed to dup hostname for %s.", svcEntry->instanceName);
                    continue;
                }
                hostEntry->sdRef = NULL;
                hostEntry->logHelper = watcher->logHelper;
                hostEntry->resolved = false;
                hostEntry->ifIndex = svcEntry->ifIndex;
                hostEntry->resolvedCnt = 0;
                hostEntry->markDeleted = false;
                char key[256 + 10] = {0};//max hostname length is 255, ifIndex is int
                (void)snprintf(key, sizeof(key), "%s%d", svcEntry->hostname, svcEntry->ifIndex);
                if (celix_stringHashMap_put(watcher->watchedHosts, key, hostEntry) != CELIX_SUCCESS) {
                    nextWorkIntervalTime = MIN(nextWorkIntervalTime, DZC_MAX_RETRY_INTERVAL);//retry after 5 seconds
                    celix_logHelper_logTssErrors(watcher->logHelper, CELIX_LOG_LEVEL_ERROR);
                    celix_logHelper_error(watcher->logHelper, "Watcher: Failed to add host entry for %s.", svcEntry->instanceName);
                    continue;
                }
                celix_steal_ptr(hostname);
                celix_steal_ptr(ipAddresses);
                celix_steal_ptr(hostEntry);
            }
        }
    }

    //delete hosts
    celix_string_hash_map_iterator_t iter = celix_stringHashMap_begin(watcher->watchedHosts);
    while (!celix_stringHashMapIterator_isEnd(&iter)) {
        watched_host_entry_t *hostEntry = (watched_host_entry_t *)iter.value.ptrValue;
        if (hostEntry->markDeleted) {
            celix_logHelper_trace(watcher->logHelper, "Watcher: Stop to resolve host %s on %d.", hostEntry->hostname, hostEntry->ifIndex);
            celix_stringHashMapIterator_remove(&iter);
            if (hostEntry->sdRef) {
                DNSServiceRefDeallocate(hostEntry->sdRef);
            }
            celix_stringHashMap_destroy(hostEntry->ipAddresses);
            free(hostEntry->hostname);
            free(hostEntry);
        } else {
            celix_stringHashMapIterator_next(&iter);
        }
    }

    *pNextWorkIntervalTime = nextWorkIntervalTime;
    return;
}