VirtualBox

儲存庫 vbox 的更動 50129


忽略:
時間撮記:
2014-1-20 下午05:41:57 (11 年 以前)
作者:
vboxsync
訊息:

slirp_dns.c: replaces scanf based resolv.conf parsing with new parser.
RCPSF_IGNORE_IPV6 passed to parser, perhaps this should be changed for DNSProxy.

comments added about converting loopback to alias and back, storing the list of nameservers and domain names , perhaps don't need queue and list anymore.

位置:
trunk/src/VBox/Devices/Network/slirp
檔案:
修改 2 筆資料

圖例:

未更動
新增
刪除
  • trunk/src/VBox/Devices/Network/slirp/resolv_conf_parser.h

    r50088 r50129  
    2828#define RCPS_BUFFER_SIZE 256
    2929#define RCPS_IPVX_SIZE 47
     30
     31/**
     32 * RESOLV_CONF_FILE can be defined in external tests for verification of Slirp behaviour.
     33 */
     34#ifndef RESOLV_CONF_FILE
     35# ifndef RT_OS_OS2
     36#  define RESOLV_CONF_FILE "/etc/resolv.conf"
     37# else
     38#  define RESOLV_CONF_FILE "\\MPTN\\ETC\\RESOLV2"
     39# endif
     40#endif
     41
    3042/**
    3143 * In Slirp we don't need IPv6 for general case (only for dnsproxy mode
  • trunk/src/VBox/Devices/Network/slirp/slirp_dns.c

    r49436 r50129  
    152152#else /* !RT_OS_WINDOWS */
    153153
    154 static int RTFileGets(RTFILE File, void *pvBuf, size_t cbBufSize, size_t *pcbRead)
    155 {
    156     size_t cbRead;
    157     char bTest;
    158     int rc = VERR_NO_MEMORY;
    159     char *pu8Buf = (char *)pvBuf;
    160     *pcbRead = 0;
    161 
    162     while (   RT_SUCCESS(rc = RTFileRead(File, &bTest, 1, &cbRead))
    163            && (pu8Buf - (char *)pvBuf) < cbBufSize)
    164     {
    165         if (cbRead == 0)
    166             return VERR_EOF;
    167 
    168         if (bTest == '\r' || bTest == '\n')
    169         {
    170             *pu8Buf = 0;
    171             return VINF_SUCCESS;
    172         }
    173         *pu8Buf = bTest;
    174          pu8Buf++;
    175         (*pcbRead)++;
    176     }
    177     return rc;
    178 }
    179 
    180 static int slirpOpenResolvConfFile(PRTFILE pResolvConfFile)
    181 {
    182     int rc;
    183     char buff[512];
    184     char *etc = NULL;
    185     char *home = NULL;
    186     AssertPtrReturn(pResolvConfFile, VERR_INVALID_PARAMETER);
    187     LogFlowFuncEnter();
    188 # ifdef RT_OS_OS2
    189     /* Try various locations. */
    190     NOREF(home);
    191     etc = getenv("ETC");
    192     if (etc)
    193     {
    194         RTStrmPrintf(buff, sizeof(buff), "%s/RESOLV2", etc);
    195         rc = RTFileOpen(pResolvConfFile, buff, RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_NONE);
    196     }
    197     if (RT_FAILURE(rc))
    198     {
    199         RTStrmPrintf(buff, sizeof(buff), "%s/RESOLV2", _PATH_ETC);
    200         rc = RTFileOpen(pResolvConfFile, buff, RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_NONE);
    201     }
    202     if (RT_FAILURE(rc))
    203     {
    204         RTStrmPrintf(buff, sizeof(buff), "%s/resolv.conf", _PATH_ETC);
    205         rc = RTFileOpen(pResolvConfFile, buff, RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_NONE);
    206     }
    207 # else /* !RT_OS_OS2 */
    208 #  ifndef DEBUG_vvl
    209     rc = RTFileOpen(pResolvConfFile, "/etc/resolv.conf", RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_NONE);
    210 #  else
    211     NOREF(etc);
    212     home = getenv("HOME");
    213     RTStrPrintf(buff, sizeof(buff), "%s/resolv.conf", home);
    214     rc = RTFileOpen(pResolvConfFile, buff, RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_NONE);
    215     if (RT_SUCCESS(rc))
    216         Log(("NAT: DNS we're using %s\n", buff));
    217     else
    218     {
    219         rc = RTFileOpen(pResolvConfFile, "/etc/resolv.conf", RTFILE_O_READ | RTFILE_O_OPEN | RTFILE_O_DENY_NONE);
    220         Log(("NAT: DNS we're using %s\n", buff));
    221     }
    222 #  endif
    223 # endif /* !RT_OS_OS2 */
    224     LogFlowFuncLeaveRC(rc);
    225     return rc;
    226 }
     154#include "resolv_conf_parser.h"
     155
    227156static int get_dns_addr_domain(PNATState pData, const char **ppszDomain)
    228157{
    229     char buff[256];
    230     char buff2[256];
    231     RTFILE ResolvConfFile;
    232     int cNameserversFound = 0;
    233     bool fWarnTooManyDnsServers = false;
    234     struct in_addr tmp_addr;
     158    struct rcp_state st;
    235159    int rc;
    236     size_t bytes;
    237 
    238     rc = slirpOpenResolvConfFile(&ResolvConfFile);
    239     if (RT_FAILURE(rc))
    240     {
    241         LogRel(("NAT: there're some problems with accessing resolv.conf (or known analog), thus NAT switches to use host resolver mechanism\n"));
     160    unsigned i;
     161
     162    /* XXX: perhaps IPv6 shouldn't be ignored if we're using DNS proxy */
     163    st.rcps_flags = RCPSF_IGNORE_IPV6;
     164    rc = rcp_parse(&st, RESOLV_CONF_FILE);
     165
     166    /* for historical reasons: Slirp returns 0 and fall down to host resolver if wasn't able open resolv.conf file */
     167    if(rc == -1)
     168    {
    242169        pData->fUseHostResolver = 1;
    243         return VINF_SUCCESS;
    244     }
    245 
    246     if (ppszDomain)
    247         *ppszDomain = NULL;
    248 
    249     Log(("NAT: DNS Servers:\n"));
    250     while (    RT_SUCCESS(rc = RTFileGets(ResolvConfFile, buff, sizeof(buff), &bytes))
    251             && rc != VERR_EOF)
    252     {
    253         struct dns_entry *pDns = NULL;
    254         if (   cNameserversFound == 4
    255             && !fWarnTooManyDnsServers
    256             && sscanf(buff, "nameserver%*[ \t]%255s", buff2) == 1)
    257         {
    258             fWarnTooManyDnsServers = true;
    259             LogRel(("NAT: too many nameservers registered.\n"));
    260         }
    261         if (   sscanf(buff, "nameserver%*[ \t]%255s", buff2) == 1
    262             && cNameserversFound < 4) /* Unix doesn't accept more than 4 name servers*/
    263         {
    264             if (!inet_aton(buff2, &tmp_addr))
    265                 continue;
    266 
    267             /* localhost mask */
    268             pDns = RTMemAllocZ(sizeof (struct dns_entry));
    269             if (!pDns)
    270             {
    271                 Log(("can't alloc memory for DNS entry\n"));
    272                 return -1;
    273             }
    274 
    275             /* check */
    276             pDns->de_addr.s_addr = tmp_addr.s_addr;
    277             if ((pDns->de_addr.s_addr & RT_H2N_U32_C(IN_CLASSA_NET)) == RT_N2H_U32_C(INADDR_LOOPBACK & IN_CLASSA_NET))
    278             {
    279                 if ((pDns->de_addr.s_addr) == RT_N2H_U32_C(INADDR_LOOPBACK))
    280                     pDns->de_addr.s_addr = RT_H2N_U32(RT_N2H_U32(pData->special_addr.s_addr) | CTL_ALIAS);
    281                 else if (pData->fUseDnsProxy != 1)
    282                 {
    283                     /* Modern Ubuntu register 127.0.1.1 as DNS server */
    284                     LogRel(("NAT: DNS server %RTnaipv4 registration detected, switching to the DNS proxy.\n",
    285                             pDns->de_addr.s_addr));
    286                     pData->fUseDnsProxy = 1;
    287                     pData->fUseHostResolver = 0;
    288                 }
    289             }
    290             TAILQ_INSERT_HEAD(&pData->pDnsList, pDns, de_list);
    291             cNameserversFound++;
    292         }
    293         if (!strncmp(buff, "domain", 6) || !strncmp(buff, "search", 6))
    294         {
    295             char *tok;
    296             char *saveptr;
    297             struct dns_domain_entry *pDomain = NULL;
    298             int fFoundDomain = 0;
    299             tok = strtok_r(&buff[6], " \t\n", &saveptr);
    300             LIST_FOREACH(pDomain, &pData->pDomainList, dd_list)
    301             {
    302                 if (   tok != NULL
    303                     && strcmp(tok, pDomain->dd_pszDomain) == 0)
    304                 {
    305                     fFoundDomain = 1;
    306                     break;
    307                 }
    308             }
    309             if (tok != NULL && !fFoundDomain)
    310             {
    311                 pDomain = RTMemAllocZ(sizeof(struct dns_domain_entry));
    312                 if (!pDomain)
    313                 {
    314                     Log(("NAT: not enought memory to add domain list\n"));
    315                     return VERR_NO_MEMORY;
    316                 }
    317                 pDomain->dd_pszDomain = RTStrDup(tok);
    318                 Log(("NAT: adding domain name %s to search list\n", pDomain->dd_pszDomain));
    319                 LIST_INSERT_HEAD(&pData->pDomainList, pDomain, dd_list);
    320             }
    321         }
    322     }
    323     RTFileClose(ResolvConfFile);
    324     if (!cNameserversFound)
    325         return -1;
     170        return 0;
     171    }
     172
     173    /* for historical reasons: Slirp returns -1 if no nameservers were found */
     174    if (st.rcps_num_nameserver == 0)
     175        return -1;
     176
     177   
     178    /* XXX: We're composing the list, but we already knows
     179     * its size so we can allocate array instead (Linux guests
     180     * dont like >3 servers in the list anyway)
     181     * or use pre-allocated array in NATState.
     182     */
     183    for (i = 0; i != st.rcps_num_nameserver; ++i)
     184    {
     185        struct dns_entry *pDns;
     186        RTNETADDRU *address = &st.rcps_nameserver[i].uAddr;
     187        if (  (address->IPv4.u & RT_H2N_U32_C(IN_CLASSA_NET))
     188           == RT_N2H_U32_C(INADDR_LOOPBACK & IN_CLASSA_NET))
     189        {
     190            /**
     191             * XXX: Note shouldn't patch the address in case of using DNS proxy,
     192             * because DNS proxy we do revert it back actually.
     193             */
     194            if (address->IPv4.u == RT_N2H_U32_C(INADDR_LOOPBACK))
     195                address->IPv4.u = RT_H2N_U32(RT_N2H_U32(pData->special_addr.s_addr) | CTL_ALIAS);
     196            else if (pData->fUseDnsProxy == 0) {
     197                /* We detects that using some address in 127/8 network */
     198                LogRel(("NAT: DNS server %RTnaipv4 registration detected, switching to the DNS proxy.\n", address->IPv4));
     199                pData->fUseDnsProxy = 1;
     200                pData->fUseHostResolver = 0;
     201            }
     202        }
     203
     204        pDns = RTMemAllocZ(sizeof(struct dns_entry));
     205        if (pDns == NULL)
     206        {
     207            slirpReleaseDnsSettings(pData);
     208            return VERR_NO_MEMORY;
     209        }
     210
     211        pDns->de_addr.s_addr = address->IPv4.u;
     212        TAILQ_INSERT_HEAD(&pData->pDnsList, pDns, de_list);
     213    }
     214
     215    if (st.rcps_domain != 0)
     216    {
     217        struct dns_domain_entry *pDomain = RTMemAllocZ(sizeof(struct dns_domain_entry));
     218        if (pDomain == NULL)
     219        {
     220            slirpReleaseDnsSettings(pData);
     221            return -1;
     222        }
     223
     224        pDomain->dd_pszDomain = RTStrDup(st.rcps_domain);
     225        LogRel(("NAT: adding domain name %s\n", pDomain->dd_pszDomain));
     226        LIST_INSERT_HEAD(&pData->pDomainList, pDomain, dd_list);
     227    }
     228
     229    if (ppszDomain && st.rcps_domain != 0)
     230        *ppszDomain = RTStrDup(st.rcps_domain);
     231
    326232    return 0;
    327233}
注意: 瀏覽 TracChangeset 來幫助您使用更動檢視器

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