/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. 
 *
 *    Copyright 2017 (c) Stefan Profanter, fortiss GmbH
 *    Copyright 2017 (c) Fraunhofer IOSB (Author: Julius Pfrommer)
 */

#include "ua_server_internal.h"

#ifdef UA_ENABLE_DISCOVERY_MULTICAST

#ifndef UA_ENABLE_AMALGAMATION
#include "mdnsd/libmdnsd/xht.h"
#include "mdnsd/libmdnsd/sdtxt.h"
#endif

#ifdef _WIN32
/* inet_ntoa is deprecated on MSVC but used for compatibility */
# define _WINSOCK_DEPRECATED_NO_WARNINGS
# include <winsock2.h>
# include <iphlpapi.h>
# include <ws2tcpip.h>
#else
# include <sys/time.h> // for struct timeval
# include <netinet/in.h> // for struct ip_mreq
# include <ifaddrs.h>
# include <net/if.h> /* for IFF_RUNNING */
# include <netdb.h> // for recvfrom in cygwin
#endif

/* FIXME: Is this a required algorithm? Otherwise, reuse hashing for nodeids */
/* Generates a hash code for a string.
 * This function uses the ELF hashing algorithm as reprinted in
 * Andrew Binstock, "Hashing Rehashed," Dr. Dobb's Journal, April 1996.
 */
static int
mdns_hash_record(const char *s) {
    /* ELF hash uses unsigned chars and unsigned arithmetic for portability */
    const unsigned char *name = (const unsigned char *) s;
    unsigned long h = 0;
    while(*name) {
        h = (h << 4) + (unsigned long) (*name++);
        unsigned long g;
        if((g = (h & 0xF0000000UL)) != 0)
            h ^= (g >> 24);
        h &= ~g;
    }
    return (int) h;
}

static struct serverOnNetwork_list_entry *
mdns_record_add_or_get(UA_DiscoveryManager *dm, const char *record, const char *serverName,
                       size_t serverNameLen, UA_Boolean createNew) {
    int hashIdx = mdns_hash_record(record) % SERVER_ON_NETWORK_HASH_PRIME;
    struct serverOnNetwork_hash_entry *hash_entry = dm->serverOnNetworkHash[hashIdx];

    while(hash_entry) {
        size_t maxLen;
        if(serverNameLen > hash_entry->entry->serverOnNetwork.serverName.length)
            maxLen = hash_entry->entry->serverOnNetwork.serverName.length;
        else
            maxLen = serverNameLen;

        if(strncmp((char *) hash_entry->entry->serverOnNetwork.serverName.data,
                   serverName, maxLen) == 0)
            return hash_entry->entry;
        hash_entry = hash_entry->next;
    }

    if(!createNew)
        return NULL;

    /* not yet in list, create new one */
    /* todo: malloc may fail: return a statuscode */
    struct serverOnNetwork_list_entry *listEntry = (serverOnNetwork_list_entry*)
        UA_malloc(sizeof(struct serverOnNetwork_list_entry));
    listEntry->created = UA_DateTime_now();
    listEntry->pathTmp = NULL;
    listEntry->txtSet = false;
    listEntry->srvSet = false;
    UA_ServerOnNetwork_init(&listEntry->serverOnNetwork);
    listEntry->serverOnNetwork.recordId = dm->serverOnNetworkRecordIdCounter;
    listEntry->serverOnNetwork.serverName.length = serverNameLen;
    /* todo: malloc may fail: return a statuscode */
    listEntry->serverOnNetwork.serverName.data = (UA_Byte*)UA_malloc(serverNameLen);
    memcpy(listEntry->serverOnNetwork.serverName.data, serverName, serverNameLen);
    UA_atomic_addUInt32(&dm->serverOnNetworkRecordIdCounter, 1);
    if(dm->serverOnNetworkRecordIdCounter == 0)
        dm->serverOnNetworkRecordIdLastReset = UA_DateTime_now();

    /* add to hash */
    /* todo: malloc may fail: return a statuscode */
    struct serverOnNetwork_hash_entry *newHashEntry = (struct serverOnNetwork_hash_entry*)
        UA_malloc(sizeof(struct serverOnNetwork_hash_entry));
    newHashEntry->next = dm->serverOnNetworkHash[hashIdx];
    dm->serverOnNetworkHash[hashIdx] = newHashEntry;
    newHashEntry->entry = listEntry;

    LIST_INSERT_HEAD(&dm->serverOnNetwork, listEntry, pointers);

    return listEntry;
}

#ifdef _WIN32

/* see http://stackoverflow.com/a/10838854/869402 */
static IP_ADAPTER_ADDRESSES *
getInterfaces(const UA_Server *server) {
    IP_ADAPTER_ADDRESSES* adapter_addresses = NULL;

    /* Start with a 16 KB buffer and resize if needed - multiple attempts in
     * case interfaces change while we are in the middle of querying them. */
    DWORD adapter_addresses_buffer_size = 16 * 1024;
    for(size_t attempts = 0; attempts != 3; ++attempts) {
        /* todo: malloc may fail: return a statuscode */
        adapter_addresses = (IP_ADAPTER_ADDRESSES*)UA_malloc(adapter_addresses_buffer_size);
        if(!adapter_addresses) {
            UA_LOG_ERROR(&server->config.logger, UA_LOGCATEGORY_SERVER,
                         "GetAdaptersAddresses out of memory");
            adapter_addresses = NULL;
            break;
        }
        DWORD error = GetAdaptersAddresses(AF_UNSPEC,
                                           GAA_FLAG_SKIP_ANYCAST |
                                           GAA_FLAG_SKIP_DNS_SERVER |
                                           GAA_FLAG_SKIP_FRIENDLY_NAME,
                                           NULL, adapter_addresses,
                                           &adapter_addresses_buffer_size);

        if(ERROR_SUCCESS == error) {
            break;
        } else if (ERROR_BUFFER_OVERFLOW == error) {
            /* Try again with the new size */
            UA_free(adapter_addresses);
            adapter_addresses = NULL;
            continue;
        }

        /* Unexpected error */
        UA_LOG_ERROR(&server->config.logger, UA_LOGCATEGORY_SERVER,
                     "GetAdaptersAddresses returned an unexpected error. "
                     "Not setting mDNS A records.");
        UA_free(adapter_addresses);
        adapter_addresses = NULL;
        break;
    }
    return adapter_addresses;
}

#endif /* _WIN32 */

static UA_Boolean
mdns_is_self_announce(const UA_Server *server, const struct serverOnNetwork_list_entry *entry) {
    for (size_t i=0; i<server->config.networkLayersSize; i++) {
        UA_ServerNetworkLayer *nl = &server->config.networkLayers[i];
        if(UA_String_equal(&entry->serverOnNetwork.discoveryUrl,
                           &nl->discoveryUrl))
            return true;
        // check discoveryUrl ignoring tailing slash
        if (((
                nl->discoveryUrl.length == entry->serverOnNetwork.discoveryUrl.length +1 &&
                nl->discoveryUrl.data[nl->discoveryUrl.length-1] == '/'
              ) || (
                entry->serverOnNetwork.discoveryUrl.length == nl->discoveryUrl.length +1 &&
                entry->serverOnNetwork.discoveryUrl.data[entry->serverOnNetwork.discoveryUrl.length-1] == '/'
              )
            ) &&
            memcmp(nl->discoveryUrl.data, entry->serverOnNetwork.discoveryUrl.data,
                    UA_MIN(nl->discoveryUrl.length, entry->serverOnNetwork.discoveryUrl.length)) == 0
        ) {
            return true;
        }
        if (nl->discoveryUrl.length == entry->serverOnNetwork.discoveryUrl.length +1 &&
            nl->discoveryUrl.data[nl->discoveryUrl.length-1] == '/' &&
            memcmp(nl->discoveryUrl.data, entry->serverOnNetwork.discoveryUrl.data, nl->discoveryUrl.length-1) == 0
                ) {
            return true;
        }
    }

    /* The discovery URL may also just contain the IP address, but in our
     * discovery URL we are using hostname thus previous check may not detect
     * the same URL. Therefore we also check if the name matches: */
    UA_String hostnameRemote = UA_STRING_NULL;
    UA_UInt16 portRemote = 4840;
    UA_String pathRemote = UA_STRING_NULL;
    UA_StatusCode retval =
        UA_parseEndpointUrl(&entry->serverOnNetwork.discoveryUrl,
                            &hostnameRemote, &portRemote, &pathRemote);
    if(retval != UA_STATUSCODE_GOOD) {
        /* skip invalid url */
        return false;
    }

#ifdef _WIN32
    IP_ADAPTER_ADDRESSES* adapter_addresses = getInterfaces(server);
    if(!adapter_addresses) {
        UA_LOG_ERROR(&server->config.logger, UA_LOGCATEGORY_SERVER,
                     "getifaddrs returned an unexpected error. Not setting mDNS A records.");
        return false;
    }
#else
    struct ifaddrs *ifaddr, *ifa;
    if(getifaddrs(&ifaddr) == -1) {
        UA_LOG_ERROR(&server->config.logger, UA_LOGCATEGORY_SERVER,
                     "getifaddrs returned an unexpected error. Not setting mDNS A records.");
        return false;
    }
#endif


    UA_Boolean isSelf = false;

    for (size_t i=0; i<server->config.networkLayersSize; i++) {
        UA_ServerNetworkLayer *nl = &server->config.networkLayers[i];

        UA_String hostnameSelf = UA_STRING_NULL;
        UA_UInt16 portSelf = 4840;
        UA_String pathSelf = UA_STRING_NULL;

        retval = UA_parseEndpointUrl(&nl->discoveryUrl, &hostnameSelf,
                                     &portSelf, &pathSelf);
        if(retval != UA_STATUSCODE_GOOD) {
            /* skip invalid url */
            continue;
        }
        if (portRemote != portSelf)
            continue;

#ifdef _WIN32
        /* Iterate through all of the adapters */
        IP_ADAPTER_ADDRESSES* adapter = adapter_addresses;
        for(; adapter != NULL; adapter = adapter->Next) {
            /* Skip loopback adapters */
            if(IF_TYPE_SOFTWARE_LOOPBACK == adapter->IfType)
                continue;

            /* Parse all IPv4 and IPv6 addresses */
            IP_ADAPTER_UNICAST_ADDRESS* address = adapter->FirstUnicastAddress;
            for(; NULL != address; address = address->Next) {
                int family = address->Address.lpSockaddr->sa_family;
                if(AF_INET == family) {
                    SOCKADDR_IN* ipv4 = (SOCKADDR_IN*)(address->Address.lpSockaddr); /* IPv4 */
                    char *ipStr = inet_ntoa(ipv4->sin_addr);
                    if(strncmp((const char*)hostnameRemote.data, ipStr,
                               hostnameRemote.length) == 0) {
                        isSelf = true;
                        break;
                    }
                } else if(AF_INET6 == family) {
                    /* IPv6 not implemented yet */
                }
            }
            if (isSelf)
                break;
        }
#else
        /* Walk through linked list, maintaining head pointer so we can free
         * list later */
        int n;
        for(ifa = ifaddr, n = 0; ifa != NULL; ifa = ifa->ifa_next, n++) {
            if(!ifa->ifa_addr)
                continue;

            if((strcmp("lo", ifa->ifa_name) == 0) ||
               !(ifa->ifa_flags & (IFF_RUNNING))||
               !(ifa->ifa_flags & (IFF_MULTICAST)))
                continue;

            /* IPv4 */
            if(ifa->ifa_addr->sa_family == AF_INET) {
                struct sockaddr_in* sa = (struct sockaddr_in*) ifa->ifa_addr;

                char *ipStr = inet_ntoa(sa->sin_addr);
                if(strncmp((const char*)hostnameRemote.data, ipStr,
                           hostnameRemote.length) == 0) {
                    isSelf = true;
                    break;
                }
            }

            /* IPv6 not implemented yet */
        }
#endif
        if (isSelf)
            break;
    }

#ifdef _WIN32
    /* Cleanup */
    UA_free(adapter_addresses);
    adapter_addresses = NULL;
#else
    /* Clean up */
    freeifaddrs(ifaddr);
#endif

    return isSelf;
}

static void
mdns_record_remove(UA_Server *server, const char *record,
                   struct serverOnNetwork_list_entry *entry) {
    UA_DiscoveryManager *dm = &server->discoveryManager;

    /* remove from hash */
    int hashIdx = mdns_hash_record(record) % SERVER_ON_NETWORK_HASH_PRIME;
    struct serverOnNetwork_hash_entry *hash_entry = dm->serverOnNetworkHash[hashIdx];
    struct serverOnNetwork_hash_entry *prevEntry = hash_entry;
    while(hash_entry) {
        if(hash_entry->entry == entry) {
            if(dm->serverOnNetworkHash[hashIdx] == hash_entry)
                dm->serverOnNetworkHash[hashIdx] = hash_entry->next;
            else if(prevEntry)
                prevEntry->next = hash_entry->next;
            break;
        }
        prevEntry = hash_entry;
        hash_entry = hash_entry->next;
    }
    UA_free(hash_entry);

    if(dm->serverOnNetworkCallback && !mdns_is_self_announce(server, entry))
        dm->serverOnNetworkCallback(&entry->serverOnNetwork, false,
                                    entry->txtSet, dm->serverOnNetworkCallbackData);

    /* remove from list */
    LIST_REMOVE(entry, pointers);
    UA_ServerOnNetwork_deleteMembers(&entry->serverOnNetwork);
    if(entry->pathTmp)
        UA_free(entry->pathTmp);

#if UA_MULTITHREADING >= 200
    UA_atomic_subSize(&dm->serverOnNetworkSize, 1);
    entry->delayedCleanup.callback = NULL; /* Only free the structure */
    UA_WorkQueue_enqueueDelayed(&server->workQueue, &entry->delayedCleanup);
#else
    dm->serverOnNetworkSize--;
    UA_free(entry);
#endif
}

static void
mdns_append_path_to_url(UA_String *url, const char *path) {
    size_t pathLen = strlen(path);
    /* todo: malloc may fail: return a statuscode */
    char *newUrl = (char *)UA_malloc(url->length + pathLen);
    memcpy(newUrl, url->data, url->length);
    memcpy(newUrl + url->length, path, pathLen);
    url->length = url->length + pathLen;
    url->data = (UA_Byte *) newUrl;
}

static void
setTxt(UA_Server *server, const struct resource *r,
       struct serverOnNetwork_list_entry *entry) {
    entry->txtSet = true;
    xht_t *x = txt2sd(r->rdata, r->rdlength);
    char *path = (char *) xht_get(x, "path");
    char *caps = (char *) xht_get(x, "caps");

    size_t pathLen = path ? strlen(path) : 0;

    if(path && pathLen > 1) {
        if(!entry->srvSet) {
            /* txt arrived before SRV, thus cache path entry */
            if (!entry->pathTmp) {
                entry->pathTmp = (char*)UA_malloc(pathLen+1);
                if (!entry->pathTmp) {
                    UA_LOG_ERROR(&server->config.logger, UA_LOGCATEGORY_SERVER, "Cannot alloc memory for mDNS srv path");
                    return;
                }
                memcpy(&(entry->pathTmp), &path, pathLen);
                entry->pathTmp[pathLen] = '\0';
            }
        } else {
            /* SRV already there and discovery URL set. Add path to discovery URL */
            mdns_append_path_to_url(&entry->serverOnNetwork.discoveryUrl, path);
        }
    }

    if(caps && strlen(caps) > 0) {
        /* count comma in caps */
        size_t capsCount = 1;
        for(size_t i = 0; caps[i]; i++) {
            if(caps[i] == ',')
                capsCount++;
        }

        /* set capabilities */
        entry->serverOnNetwork.serverCapabilitiesSize = capsCount;
        entry->serverOnNetwork.serverCapabilities =
            (UA_String *) UA_Array_new(capsCount, &UA_TYPES[UA_TYPES_STRING]);

        for(size_t i = 0; i < capsCount; i++) {
            char *nextStr = strchr(caps, ',');
            size_t len = nextStr ? (size_t) (nextStr - caps) : strlen(caps);
            entry->serverOnNetwork.serverCapabilities[i].length = len;
            /* todo: malloc may fail: return a statuscode */
            entry->serverOnNetwork.serverCapabilities[i].data = (UA_Byte*)UA_malloc(len);
            memcpy(entry->serverOnNetwork.serverCapabilities[i].data, caps, len);
            if(nextStr)
                caps = nextStr + 1;
            else
                break;
        }
    }
    xht_free(x);
}

/* [servername]-[hostname]._opcua-tcp._tcp.local. 86400 IN SRV 0 5 port [hostname]. */
static void
setSrv(UA_Server *server, const struct resource *r,
       struct serverOnNetwork_list_entry *entry) {
    entry->srvSet = true;


    /* The specification Part 12 says: The hostname maps onto the SRV record
     * target field. If the hostname is an IPAddress then it must be converted
     * to a domain name. If this cannot be done then LDS shall report an
     * error. */

    size_t srvNameLen = strlen(r->known.srv.name);
    if(srvNameLen > 0 && r->known.srv.name[srvNameLen - 1] == '.')
        /* cut off last dot */
        srvNameLen--;
    /* opc.tcp://[servername]:[port][path] */
    char *newUrl = (char*)UA_malloc(10 + srvNameLen + 8);
    if (!newUrl) {
        UA_LOG_ERROR(&server->config.logger, UA_LOGCATEGORY_SERVER, "Cannot allocate char for discovery url. Out of memory.");
        return;
    }
    UA_snprintf(newUrl, 10 + srvNameLen + 8, "opc.tcp://%.*s:%d", (int) srvNameLen,
             r->known.srv.name, r->known.srv.port);


    UA_LOG_INFO(&server->config.logger, UA_LOGCATEGORY_SERVER,
                "Multicast DNS: found server: %s", newUrl);
    entry->serverOnNetwork.discoveryUrl = UA_String_fromChars(newUrl);
    UA_free(newUrl);

    if(entry->pathTmp) {
        mdns_append_path_to_url(&entry->serverOnNetwork.discoveryUrl, entry->pathTmp);
        UA_free(entry->pathTmp);
    }
}

/* This will be called by the mDNS library on every record which is received */
void
mdns_record_received(const struct resource *r, void *data) {
    UA_Server *server = (UA_Server *) data;
    /* we only need SRV and TXT records */
    /* TODO: remove magic number */
    if((r->clazz != QCLASS_IN && r->clazz != QCLASS_IN + 32768) ||
       (r->type != QTYPE_SRV && r->type != QTYPE_TXT))
        return;

    /* we only handle '_opcua-tcp._tcp.' records */
    char *opcStr = strstr(r->name, "_opcua-tcp._tcp.");
    if(!opcStr)
        return;

    /* Compute the length of the servername */
    size_t servernameLen = (size_t) (opcStr - r->name);
    if(servernameLen == 0)
        return;
    servernameLen--; /* remove point */

    /* Get entry */
    struct serverOnNetwork_list_entry *entry =
            mdns_record_add_or_get(&server->discoveryManager, r->name, r->name,
                                   servernameLen, r->ttl > 0);
    if(!entry)
        return;

    /* Check that the ttl is positive */
    if(r->ttl == 0) {
        UA_LOG_INFO(&server->config.logger, UA_LOGCATEGORY_SERVER,
                    "Multicast DNS: remove server (TTL=0): %.*s",
                    (int)entry->serverOnNetwork.discoveryUrl.length,
                    entry->serverOnNetwork.discoveryUrl.data);
        mdns_record_remove(server, r->name, entry);
        return;
    }

    /* Update lastSeen */
    entry->lastSeen = UA_DateTime_nowMonotonic();

    /* TXT and SRV are already set */
    if(entry->txtSet && entry->srvSet) {
        // call callback for every mdns package we received.
        // This will also call the callback multiple times
        if (server->discoveryManager.serverOnNetworkCallback &&
            !mdns_is_self_announce(server, entry))
            server->discoveryManager.
                serverOnNetworkCallback(&entry->serverOnNetwork, true, entry->txtSet,
                                        server->discoveryManager.serverOnNetworkCallbackData);
        return;
    }

    /* Add the resources */
    if(r->type == QTYPE_TXT && !entry->txtSet)
        setTxt(server, r, entry);
    else if (r->type == QTYPE_SRV && !entry->srvSet)
        setSrv(server, r, entry);

    /* Call callback to announce a new server */
    if(entry->srvSet && server->discoveryManager.serverOnNetworkCallback &&
       !mdns_is_self_announce(server, entry))
        server->discoveryManager.
            serverOnNetworkCallback(&entry->serverOnNetwork, true, entry->txtSet,
                                    server->discoveryManager.serverOnNetworkCallbackData);
}

void
mdns_create_txt(UA_Server *server, const char *fullServiceDomain, const char *path,
                const UA_String *capabilites, const size_t capabilitiesSize,
                void (*conflict)(char *host, int type, void *arg)) {
    mdns_record_t *r = mdnsd_unique(server->discoveryManager.mdnsDaemon, fullServiceDomain,
                                    QTYPE_TXT, 600, conflict, server);
    xht_t *h = xht_new(11);
    char *allocPath = NULL;
    if(!path || strlen(path) == 0) {
        xht_set(h, "path", "/");
    } else {
        /* path does not contain slash, so add it here */
        size_t pathLen = strlen(path);
        if(path[0] == '/') {
            allocPath = (char*)UA_malloc(pathLen+1);
            if (!allocPath) {
                UA_LOG_ERROR(&server->config.logger, UA_LOGCATEGORY_SERVER, "Cannot alloc memory for txt path");
                return;
            }
            memcpy(&allocPath, &path, pathLen);
            allocPath[pathLen] = '\0';
        } else {
            /* todo: malloc may fail: return a statuscode */
            allocPath = (char*)UA_malloc(pathLen + 2);
            allocPath[0] = '/';
            memcpy(allocPath + 1, path, pathLen);
            allocPath[pathLen + 1] = '\0';
        }
        xht_set(h, "path", allocPath);
    }

    /* calculate max string length: */
    size_t capsLen = 0;
    for(size_t i = 0; i < capabilitiesSize; i++) {
        /* add comma or last \0 */
        capsLen += capabilites[i].length + 1;
    }

    char *caps = NULL;
    if(capsLen) {
        /* freed when xht_free is called */
        /* todo: malloc may fail: return a statuscode */
        caps = (char*)UA_malloc(sizeof(char) * capsLen);
        size_t idx = 0;
        for(size_t i = 0; i < capabilitiesSize; i++) {
            memcpy(caps + idx, (const char *) capabilites[i].data, capabilites[i].length);
            idx += capabilites[i].length + 1;
            caps[idx - 1] = ',';
        }
        caps[idx - 1] = '\0';

        xht_set(h, "caps", caps);
    } else {
        xht_set(h, "caps", "NA");
    }

    int txtRecordLength;
    unsigned char *packet = sd2txt(h, &txtRecordLength);
    if(allocPath)
        UA_free(allocPath);
    if(caps)
        UA_free(caps);
    xht_free(h);
    mdnsd_set_raw(server->discoveryManager.mdnsDaemon, r, (char *) packet,
                  (unsigned short) txtRecordLength);
    UA_free(packet);
}

mdns_record_t *
mdns_find_record(mdns_daemon_t *mdnsDaemon, unsigned short type,
                 const char *host, const char *rdname) {
    mdns_record_t *r = mdnsd_get_published(mdnsDaemon, host);
    if(!r)
        return NULL;

    /* search for the record with the correct ptr hostname */
    while(r) {
        const mdns_answer_t *data = mdnsd_record_data(r);
        if(data->type == type && strcmp(data->rdname, rdname) == 0)
            return r;
        r = mdnsd_record_next(r);
    }
    return NULL;
}

/* set record in the given interface */
static void
mdns_set_address_record_if(UA_DiscoveryManager *dm, const char *fullServiceDomain,
                           const char *localDomain, char *addr, UA_UInt16 addr_len) {
    /* [servername]-[hostname]._opcua-tcp._tcp.local. A [ip]. */
    mdns_record_t *r = mdnsd_shared(dm->mdnsDaemon, fullServiceDomain, QTYPE_A, 600);
    mdnsd_set_raw(dm->mdnsDaemon, r, addr, addr_len);

    /* [hostname]. A [ip]. */
    r = mdnsd_shared(dm->mdnsDaemon, localDomain, QTYPE_A, 600);
    mdnsd_set_raw(dm->mdnsDaemon, r, addr, addr_len);
}

/* Loop over network interfaces and run set_address_record on each */
#ifdef _WIN32

void mdns_set_address_record(UA_Server *server, const char *fullServiceDomain,
                             const char *localDomain) {
    IP_ADAPTER_ADDRESSES* adapter_addresses = getInterfaces(server);
    if(!adapter_addresses)
        return;

    /* Iterate through all of the adapters */
    IP_ADAPTER_ADDRESSES* adapter = adapter_addresses;
    for(; adapter != NULL; adapter = adapter->Next) {
        /* Skip loopback adapters */
        if(IF_TYPE_SOFTWARE_LOOPBACK == adapter->IfType)
            continue;

        /* Parse all IPv4 and IPv6 addresses */
        IP_ADAPTER_UNICAST_ADDRESS* address = adapter->FirstUnicastAddress;
        for(; NULL != address; address = address->Next) {
            int family = address->Address.lpSockaddr->sa_family;
            if(AF_INET == family) {
                SOCKADDR_IN* ipv4 = (SOCKADDR_IN*)(address->Address.lpSockaddr); /* IPv4 */
                mdns_set_address_record_if(&server->discoveryManager, fullServiceDomain,
                                           localDomain, (char *)&ipv4->sin_addr, 4);
            } else if(AF_INET6 == family) {
                /* IPv6 */
#if 0
                SOCKADDR_IN6* ipv6 = (SOCKADDR_IN6*)(address->Address.lpSockaddr);

                char str_buffer[INET6_ADDRSTRLEN] = {0};
                inet_ntop(AF_INET6, &(ipv6->sin6_addr), str_buffer, INET6_ADDRSTRLEN);

                std::string ipv6_str(str_buffer);

                /* Detect and skip non-external addresses */
                UA_Boolean is_link_local(false);
                UA_Boolean is_special_use(false);

                if(0 == ipv6_str.find("fe")) {
                    char c = ipv6_str[2];
                    if(c == '8' || c == '9' || c == 'a' || c == 'b')
                        is_link_local = true;
                } else if (0 == ipv6_str.find("2001:0:")) {
                    is_special_use = true;
                }

                if(!(is_link_local || is_special_use))
                    ipAddrs.mIpv6.push_back(ipv6_str);
#endif
            }
        }
    }

    /* Cleanup */
    UA_free(adapter_addresses);
    adapter_addresses = NULL;
}

#else /* _WIN32 */

void
mdns_set_address_record(UA_Server *server, const char *fullServiceDomain,
                        const char *localDomain) {
    struct ifaddrs *ifaddr, *ifa;
    if(getifaddrs(&ifaddr) == -1) {
        UA_LOG_ERROR(&server->config.logger, UA_LOGCATEGORY_SERVER,
                     "getifaddrs returned an unexpected error. Not setting mDNS A records.");
        return;
    }

    /* Walk through linked list, maintaining head pointer so we can free list later */
    int n;
    for(ifa = ifaddr, n = 0; ifa != NULL; ifa = ifa->ifa_next, n++) {
        if(!ifa->ifa_addr)
            continue;

        if((strcmp("lo", ifa->ifa_name) == 0) ||
           !(ifa->ifa_flags & (IFF_RUNNING))||
           !(ifa->ifa_flags & (IFF_MULTICAST)))
            continue;

        /* IPv4 */
        if(ifa->ifa_addr->sa_family == AF_INET) {
            struct sockaddr_in* sa = (struct sockaddr_in*) ifa->ifa_addr;
            mdns_set_address_record_if(&server->discoveryManager, fullServiceDomain,
                                       localDomain, (char*)&sa->sin_addr.s_addr, 4);
        }

        /* IPv6 not implemented yet */
    }

    /* Clean up */
    freeifaddrs(ifaddr);
}

#endif /* _WIN32 */

#endif /* UA_ENABLE_DISCOVERY_MULTICAST */
