VirtualBox

Changeset 61314 in vbox for trunk/src/VBox/Main/src-server


Ignore:
Timestamp:
May 31, 2016 1:19:41 AM (9 years ago)
Author:
vboxsync
Message:

Main/HostDnsService: Ignore "DhcpDomain" key since it's not stable.
Instead use GetAdaptersAddresses() to get the interfaces in the order
the system deems "correct" to harvest IP_ADAPTER_ADDRESSES::DnsSuffix
and use the first one.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Main/src-server/win/HostDnsServiceWin.cpp

    r60447 r61314  
    1515 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
    1616 */
     17
     18/*
     19 * XXX: need <winsock2.h> to reveal IP_ADAPTER_ADDRESSES in
     20 * <iptypes.h> and it must be included before <windows.h>, which is
     21 * pulled in by IPRT headers.
     22 */
     23#include <winsock2.h>
     24
    1725#include "../HostDnsService.h"
    1826
     
    2634#include <Windows.h>
    2735#include <windns.h>
     36#include <iptypes.h>
     37#include <iphlpapi.h>
    2838
    2939#include <algorithm>
     
    240250HRESULT HostDnsServiceWin::updateInfo()
    241251{
     252    HostDnsInformation info;
     253
    242254    LONG lrc;
     255    int rc;
    243256
    244257    std::string strDomain;
    245     std::string strDhcpDomain;
    246258    std::string strSearchList;  /* NB: comma separated, no spaces */
    247259
     260
     261    /*
     262     * We ignore "DhcpDomain" key here since it's not stable.  If
     263     * there are two active interfaces that use DHCP (in particular
     264     * when host uses OpenVPN) then DHCP ACKs will take turns updating
     265     * that key.  Instead we call GetAdaptersAddresses() below (which
     266     * is what ipconfig.exe seems to do).
     267     */
    248268    for (DWORD regIndex = 0; /**/; ++regIndex) {
    249269        char keyName[256];
     
    265285        if (lrc != ERROR_SUCCESS)
    266286        {
    267             LogRel(("HostDnsServiceWin: RegEnumValue error %d\n", (int)lrc));
     287            LogRel2(("HostDnsServiceWin: RegEnumValue error %d\n", (int)lrc));
    268288            return E_FAIL;
    269289        }
     
    278298        {
    279299            strDomain.assign(keyData, cbKeyData);
    280             Log2(("... Domain=\"%s\"\n", strDomain.c_str()));
     300            LogRel2(("HostDnsServiceWin: Domain=\"%s\"\n", strDomain.c_str()));
    281301        }
    282302        else if (RTStrICmp("DhcpDomain", keyName) == 0)
    283303        {
    284             strDhcpDomain.assign(keyData, cbKeyData);
    285             Log2(("... DhcpDomain=\"%s\"\n", strDhcpDomain.c_str()));
     304            std::string strDhcpDomain(keyData, cbKeyData);
     305            LogRel2(("HostDnsServiceWin: DhcpDomain=\"%s\"\n", strDhcpDomain.c_str()));
    286306        }
    287307        else if (RTStrICmp("SearchList", keyName) == 0)
    288308        {
    289309            strSearchList.assign(keyData, cbKeyData);
    290             Log2(("... SearchList=\"%s\"\n", strSearchList.c_str()));
    291         }
    292     }
    293 
    294     HostDnsInformation info;
     310            LogRel2(("HostDnsServiceWin: SearchList=\"%s\"\n", strSearchList.c_str()));
     311        }
     312    }
     313
     314    /* statically configured domain name */
     315    if (!strDomain.empty())
     316    {
     317        info.domain = strDomain;
     318        info.searchList.push_back(strDomain);
     319    }
     320
     321    /* statically configured search list */
     322    if (!strSearchList.empty())
     323    {
     324        vappend(info.searchList, strSearchList, ',');
     325    }
     326
    295327
    296328    /*
     
    318350            RTStrPrintf(szAddrStr, sizeof(szAddrStr), "%RTnaipv4", pIp4Array->AddrArray[i]);
    319351
    320             Log2((" server %d: %s\n", i+1,  szAddrStr));
     352            LogRel2(("HostDnsServiceWin: server %d: %s\n", i+1,  szAddrStr));
    321353            info.servers.push_back(szAddrStr);
    322354        }
     
    325357    }
    326358
    327     if (!strDomain.empty())
    328     {
    329         info.domain = strDomain;
    330 
    331         info.searchList.push_back(strDomain);
    332         if (!strDhcpDomain.empty() && strDhcpDomain != strDomain)
    333             info.searchList.push_back(strDhcpDomain);
    334     }
    335     else if (!strDhcpDomain.empty())
    336     {
    337         info.domain = strDhcpDomain;
    338         info.searchList.push_back(strDomain);
    339     }
    340 
    341     vappend(info.searchList, strSearchList, ',');
     359
     360    /**
     361     * DnsQueryConfig(DnsConfigSearchList, ...) is not implemented.
     362     * Call GetAdaptersAddresses() that orders the returned list
     363     * appropriately and collect IP_ADAPTER_ADDRESSES::DnsSuffix.
     364     */
     365    do {
     366        PIP_ADAPTER_ADDRESSES pAddrBuf = NULL;
     367        ULONG cbAddrBuf = 8 * 1024;
     368        bool fReallocated = false;
     369        ULONG err;
     370
     371        pAddrBuf = (PIP_ADAPTER_ADDRESSES) malloc(cbAddrBuf);
     372        if (pAddrBuf == NULL)
     373        {
     374            LogRel2(("HostDnsServiceWin: failed to allocate %zu bytes"
     375                     " of GetAdaptersAddresses buffer\n",
     376                     (size_t)cbAddrBuf));
     377            break;
     378        }
     379
     380        while (pAddrBuf != NULL)
     381        {
     382            ULONG cbAddrBufProvided = cbAddrBuf;
     383
     384            err = GetAdaptersAddresses(AF_UNSPEC,
     385                                         GAA_FLAG_SKIP_ANYCAST
     386                                       | GAA_FLAG_SKIP_MULTICAST,
     387                                       NULL,
     388                                       pAddrBuf, &cbAddrBuf);
     389            if (err == NO_ERROR)
     390            {
     391                break;
     392            }
     393            else if (err == ERROR_BUFFER_OVERFLOW)
     394            {
     395                LogRel2(("HostDnsServiceWin: provided GetAdaptersAddresses with %zu"
     396                         " but asked again for %zu bytes\n",
     397                         (size_t)cbAddrBufProvided, (size_t)cbAddrBuf));
     398
     399                if (RT_UNLIKELY(fReallocated)) /* what? again?! */
     400                {
     401                    LogRel2(("HostDnsServiceWin: ... not going to realloc again\n"));
     402                    free(pAddrBuf);
     403                    pAddrBuf = NULL;
     404                    break;
     405                }
     406
     407                PIP_ADAPTER_ADDRESSES pNewBuf = (PIP_ADAPTER_ADDRESSES) realloc(pAddrBuf, cbAddrBuf);
     408                if (pNewBuf == NULL)
     409                {
     410                    LogRel2(("HostDnsServiceWin: failed to reallocate %zu bytes\n", (size_t)cbAddrBuf));
     411                    free(pAddrBuf);
     412                    pAddrBuf = NULL;
     413                    break;
     414                }
     415
     416                /* try again */
     417                pAddrBuf = pNewBuf; /* cbAddrBuf already updated */
     418                fReallocated = true;
     419            }
     420            else
     421            {
     422                LogRel2(("HostDnsServiceWin: GetAdaptersAddresses error %d\n", err));
     423                free(pAddrBuf);
     424                pAddrBuf = NULL;
     425                break;
     426            }
     427        }
     428
     429        if (pAddrBuf == NULL)
     430            break;
     431
     432        for (PIP_ADAPTER_ADDRESSES pAdp = pAddrBuf; pAdp != NULL; pAdp = pAdp->Next)
     433        {
     434            LogRel2(("HostDnsServiceWin: %ls (status %u) ...\n",
     435                     pAdp->FriendlyName ? pAdp->FriendlyName : L"(null)",
     436                     pAdp->OperStatus));
     437
     438            if (pAdp->OperStatus != IfOperStatusUp)
     439                continue;
     440
     441            if (pAdp->DnsSuffix == NULL || *pAdp->DnsSuffix == L'\0')
     442                continue;
     443
     444            char *pszDnsSuffix = NULL;
     445            rc = RTUtf16ToUtf8Ex(pAdp->DnsSuffix, RTSTR_MAX,
     446                                 &pszDnsSuffix, 0, /* allocate */
     447                                 NULL);
     448            if (RT_FAILURE(rc))
     449            {
     450                LogRel2(("HostDnsServiceWin: failed to convert DNS suffix \"%ls\": %Rrc\n",
     451                        pAdp->DnsSuffix, rc));
     452                continue;
     453            }
     454
     455            AssertContinue(pszDnsSuffix != NULL);
     456            AssertContinue(*pszDnsSuffix != '\0');
     457            LogRel2(("HostDnsServiceWin: ... suffix = \"%s\"\n", pszDnsSuffix));
     458
     459            vappend(info.searchList, pszDnsSuffix);
     460            RTStrFree(pszDnsSuffix);
     461        }
     462
     463        free(pAddrBuf);
     464    } while (0);
     465
     466
     467    if (info.domain.empty() && !info.searchList.empty())
     468        info.domain = info.searchList[0];
     469
    342470    if (info.searchList.size() == 1)
    343471        info.searchList.clear();
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette